Zsh Codex 代码解析三

243 阅读3分钟

Zsh Codex 代码解析三

前言

在前面的文章中,我在 MacOS 中使用了 Zsh Codex 插件来实现 AI 命令自动补全。

我对这个AI实现的小工具的实现过程非常感兴趣,它的代码也写得非常清晰。

因此,接下来的文章,将一步步对 Zsh Codex 的代码进行解析,更好地理解其工作原理。

仓库地址:github.com/tom-doerr/z…

services.py

这篇文章,我们来分析服务层,这个服务层就只有一个文件,services/service.py

这个文件有将近300行代码,我们分两个部分来分析,非AI调用和AI调用部分。

这次,我们分析AI调用部分,代码中的 AI 实现有 OpenAIClientGoogleGenAIClientGroqClientMistralClientAmazonBedrock

由于大部分的大模型调用都是兼容 OpenAIAPI 的,因此我们直接以 OpenAIClient 为例进行分析。

class OpenAIClient(BaseClient):

    api_type = "openai"
    default_model = os.getenv("OPENAI_DEFAULT_MODEL", "gpt-4o-mini")

    def __init__(self, config: dict):
        try:
            from openai import OpenAI
        except ImportError:
            print(
                "OpenAI library is not installed. Please install it using 'pip install openai'"
            )
            sys.exit(1)

        self.config = config
        self.config["model"] = self.config.get("model", self.default_model)
        self.client = OpenAI(
            api_key=self.config["api_key"],
            base_url=self.config.get("base_url", "https://api.openai.com/v1"),
            organization=self.config.get("organization"),
        )

    def get_completion(self, full_command: str) -> str:
        response = self.client.chat.completions.create(
            model=self.config["model"],
            messages=[
                {"role": "system", "content": self.system_prompt},
                {"role": "user", "content": full_command},
            ],
            temperature=float(self.config.get("temperature", 1.0)),
        )
        return response.choices[0].message.content

这段代码定义了一个名为 OpenAIClient 的类,它继承自 BaseClient 类,用于与 OpenAIAPI 进行交互,以获取命令的补全建议。

1、类属性

  • api_type:指定客户端的类型为 "openai"。
  • default_model:从环境变量 OPENAI_DEFAULT_MODEL 中获取默认的模型名称,如果未设置,则使用 "gpt-4o-mini"。

2、构造函数 init

  • 尝试导入 openai 库,如果导入失败,则打印错误信息并退出程序。
  • 将传入的配置字典 config 赋值给 self.config
  • 如果配置中没有指定模型名称,则使用默认模型名称。
  • 创建一个 OpenAI 实例,并传入 API 密钥、基础 URL 和组织 ID(如果有的话)。

3、方法 get_completion

  • 使用 self.client.chat.completions.create 方法向 OpenAI API 发送请求,请求补全命令。
  • 请求中包含系统提示(self.system_prompt)和用户输入的命令(full_command)。
  • 可以通过配置中的 temperature 参数调整生成结果的随机性。
  • 返回 API 响应中第一个选择的消息内容,即补全后的命令。

提示词分析

还记得上篇文章中的 BaseClient 基类吗?这里调用的 self.system_prompt 就是继承自这个基类。

我们将它单独拎出来看看:

You are a zsh shell expert, please help me complete the following command, you should only output the completed command, no need to include any other explanation. Do not put completed command in a code block.

这是一个用于帮助用户补全命令的提示词:

您是 zsh shell 专家,请帮我完成以下命令,您应该只输出完成的命令,无需包含任何其他说明。不要将完成的命令放在代码块中。

可以看到,这份提示词是比较简陋的,而且是英文,那么国内使用的话,肯定是中文更加方便。

并且,一些特殊的需求也可以在提示词中修改,让它更加地方便使用。

下一篇,我们来对源码进行修改,来尝试实现一些趣味的功能。

总结

在本篇文章中,我们分析了 Zsh Codex 插件的服务层代码,重点关注了 AI 调用部分的实现。

通过对 OpenAIClient 类的分析,我们了解了如何与 OpenAI API 进行交互,以获取命令的补全建议。

同时,我们还对提示词进行了分析,这份简陋的英文提示词也给我们留下了调整和优化的空间。

在后续的文章中,我们将继续深入 Zsh Codex 插件的源码修改整活。

– 欢迎点赞、关注、转发、收藏【我码玄黄】,各大平台同名。