Zsh Codex 代码解析三
前言
在前面的文章中,我在 MacOS 中使用了 Zsh Codex 插件来实现 AI 命令自动补全。
我对这个AI实现的小工具的实现过程非常感兴趣,它的代码也写得非常清晰。
因此,接下来的文章,将一步步对 Zsh Codex 的代码进行解析,更好地理解其工作原理。
services.py
这篇文章,我们来分析服务层,这个服务层就只有一个文件,services/service.py。
这个文件有将近300行代码,我们分两个部分来分析,非AI调用和AI调用部分。
这次,我们分析AI调用部分,代码中的 AI 实现有 OpenAIClient、GoogleGenAIClient、GroqClient、MistralClient 和 AmazonBedrock。
由于大部分的大模型调用都是兼容 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 类,用于与 OpenAI 的 API 进行交互,以获取命令的补全建议。
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 方法向
OpenAIAPI 发送请求,请求补全命令。 - 请求中包含系统提示(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 插件的源码修改整活。
– 欢迎点赞、关注、转发、收藏【我码玄黄】,各大平台同名。