Kimi Code CLI 插件系统实战:用 plugin.json 打造轻量级自定义工具

📅 发布时间:2026/9/15 20:00:02
Kimi Code CLI 插件系统实战:用 plugin.json 打造轻量级自定义工具
Kimi Code CLI 插件系统实战用 plugin.json 打造轻量级自定义工具【免费下载链接】kimi-cliKimi Code CLI is your next CLI agent.项目地址: https://gitcode.com/GitHub_Trending/ki/kimi-cliKimi Code CLI 的插件Plugin系统允许你通过一个包含plugin.json的目录为 CLI Agent 注入可执行的自定义工具从而扩展 AI 的能力边界。本文以官方文档 docs/zh/customization/plugins.md 为骨架结合仓库中 plugin 模块源码、CLI 命令实现 与 示例插件 展开帮助你从安装、声明、凭证注入到工具脚本编写完整掌握插件的开发与使用闭环。插件是什么一个插件就是一个包含plugin.json文件的目录。插件可以声明多个「工具」Tools每个工具是一个可执行命令Python、TypeScript、Shell 脚本等AI 可以调用这些工具来完成特定任务。例如你可以创建一个插件来封装内部 API 的调用脚本提供项目特定的代码生成工具集成专有服务或数据库查询与需要持续运行的 MCP 服务器不同插件是轻量级的本地工具包适合封装项目特定的脚本和实用程序。两者是互补的扩展机制机制适用场景MCP需要持续运行的服务、复杂的工具编排、跨进程通信插件简单的脚本封装、项目特定的工具、快速原型开发插件与 Agent Skills 的核心区别在于Skills通过SKILL.md提供知识性指导AI 读取后遵循其中的规范Plugins通过plugin.json声明可执行工具AI 可以直接调用工具获取结果从源码结构看插件机制由三部分构成plugin/__init__.py负责plugin.json的解析校验与凭证注入plugin/manager.py负责安装/卸载/列出plugin/tool.py负责把声明包装成可被 Agent 调用的PluginTool基于 kosong 的CallableTool基类见 plugin/init.py 与 plugin/tool.py。注意插件系统目前处于Beta 阶段具体实现细节和配置定义可能会在未来版本中调整请谨慎在生产环境中使用并关注后续更新。安装插件使用kimi plugin命令管理插件对应实现见 cli/plugin.py。从本地目录安装kimi plugin install /path/to/my-plugin从 ZIP 文件安装# 本地 ZIP 文件 kimi plugin install my-plugin.zip # 远程 ZIP 链接含 GitHub/GitLab 归档下载链接 kimi plugin install https://example.com/my-plugin.zip kimi plugin install https://github.com/user/repo/archive/refs/heads/main.zipZIP 的解析逻辑会先检查归档内成员路径是否逃逸临时目录防止 zip-slip 攻击再在解压根目录及一层子目录中寻找plugin.json见 cli/plugin.py。从 Git 仓库安装# 安装根目录的插件 kimi plugin install https://github.com/user/repo.git # 安装子目录中的插件多插件仓库 kimi plugin install https://github.com/user/repo.git/plugins/my-plugin # 指定分支使用浏览器 URL 格式 kimi plugin install https://github.com/user/repo/tree/develop/plugins/my-pluginGit URL 的解析由_parse_git_url完成它能在.git边界处拆分出克隆地址与子路径也能识别 GitHub/GitLab 短链接取前两段为 owner/repo其余为子路径还会剥离浏览器复制 URL 中的tree/{branch}/与 GitLab 的-/tree/{branch}/前缀并提取分支名见 cli/plugin.py。多插件仓库当 Git 仓库根目录没有plugin.json时Kimi Code CLI 会扫描根目录及其直接子目录列出可用的插件供你选择提示形如Error: No plugin.json at repository root. Available plugins: - my-plugin - other-plugin Use: kimi plugin install url/plugin-name管理命令# 列出已安装插件 kimi plugin list # 查看插件详情 kimi plugin info my-plugin # 移除插件 kimi plugin remove my-plugin其中list会区分installed由宿主安装、写入过 runtime 信息与not configured两种状态info会展示插件名称、版本、描述、配置文件、inject 映射以及安装时的宿主host与版本见 cli/plugin.py。创建插件创建插件只需要三步创建一个目录编写plugin.json文件实现工具脚本目录结构my-plugin/ ├── plugin.json # 插件配置必需 ├── config.json # 插件配置可选用于凭证注入 └── scripts/ # 工具脚本 ├── greet.py └── calc.tsplugin.json格式{ name: my-plugin, version: 1.0.0, description: My custom plugin for project X, config_file: config.json, inject: { api_key: api_key, endpoint: base_url }, tools: [ { name: greet, description: Generate a greeting message, command: [python3, scripts/greet.py], parameters: { type: object, properties: { name: { type: string, description: Name to greet } }, required: [name] } } ] }字段说明字段说明是否必填name插件名称只能使用小写字母、数字和连字符是version插件版本语义化版本格式是description插件描述否config_file配置文件路径用于凭证注入否inject凭证注入映射键为目标路径值为源变量名否tools工具列表否工具字段说明字段说明是否必填name工具名称是description工具描述是command执行命令字符串数组是parametersJSON Schema 格式的参数定义否源码中的校验逻辑plugin/init.py会强制执行两条规则name与version缺失直接报错一旦声明了inject就必须同时提供config_file否则抛出PluginError。解析结果通过 pydantic 的PluginSpec/PluginToolSpec模型验证parameters的默认值为空对象{type: object, properties: {}}。凭证注入如果插件需要调用 LLM API可以通过inject配置自动获取 Kimi Code CLI 的凭证配置。inject配置示例{ config_file: config.json, inject: { llm.api_key: api_key, llm.endpoint: base_url } }支持的注入变量变量名说明api_keyLLM 提供商的 API 密钥支持 OAuth token 和静态 API keybase_urlLLM API 的基础 URLconfig.json模板{ llm: { api_key: , endpoint: } }注入的底层机制在 plugin/init.py 的inject_config中实现它把inject的键视为点号分隔的嵌套路径由_set_nested逐层创建中间字典把宿主提供的凭证值写入config.json对应位置同时对config_file做路径逃逸检查确保它不能越出插件目录。宿主凭证由collect_host_valuesplugin/manager.py从当前默认模型对应的 Provider 解析而来静态 API key 直接读取OAuth 场景则通过OAuthManager.resolve_api_key解析出有效 token。凭证的更新链路分为三个层面安装时将当前配置的 API 密钥和 base URL 注入到指定的配置文件中应用启动时Kimi Code CLI 会遍历~/.kimi/plugins/下所有插件对声明了injectconfig_file的插件重新注入最新凭证见 app.py 中调用的refresh_plugin_configsplugin/manager.py工具运行时PluginTool._build_env会在每次调用时从当前配置重新读取最新凭证如刷新后的 OAuth token以环境变量形式传给子进程见 plugin/tool.py。提示一般情况下不需要为了更新凭证而重新安装插件切换 LLM 提供商或重新授权后重启 Kimi Code CLI 即可自动刷新配置文件中的凭证插件工具在实际运行时也会通过环境变量获得当前有效的凭证。只有在修改了插件本身的配置结构例如config_file或inject映射时才需要重新安装插件。关于 inject 键名inject中的键名如llm.api_key也会被用作环境变量名传递给插件工具子进程。由于这些名称包含点号在某些运行环境中访问可能不便例如 POSIX shell 中$llm.api_key是无效的。你可以通过字典/映射方式访问Node.js:process.env[llm.api_key]Python:os.environ[llm.api_key]如果希望使用更友好的环境变量名建议在插件中使用大写下划线格式如LLM_API_KEY并相应调整配置文件结构。工具脚本规范工具脚本通过标准输入接收参数标准输出返回结果。运行时由PluginTool.__call__以子进程方式执行声明好的command工作目录为插件根目录参数序列化为 JSON 写入 stdinstdout 整体作为工具结果返回见 plugin/tool.py。输入格式脚本从stdin接收 JSON 对象{ name: World }输出格式脚本向stdout输出的内容会作为字符串返回给 Agent。如果需要结构化输出建议输出 JSON 文本{ content: Hello, World! }Python 示例#!/usr/bin/env python3 import json import sys params json.load(sys.stdin) name params.get(name, Guest) result {content: fHello, {name}!} print(json.dumps(result))TypeScript 示例#!/usr/bin/env tsx import * as readline from readline; const rl readline.createInterface({ input: process.stdin, output: process.stdout, terminal: false, }); let input ; rl.on(line, (line) { input line; }); rl.on(close, () { const params JSON.parse(input); const name params.name || Guest; console.log(JSON.stringify({ content: Hello, ${name}! })); });运行约束来自 plugin/tool.py 的实现事实单次工具调用有120 秒超时超时后子进程会被 kill返回Timeout错误进程退出码非 0 时工具调用失败错误信息取 stderr为空时回退到 stdout 或退出码stderr 非空但退出码为 0 时仅记录 debug 日志不视为失败stdout 输出会先解码 UTF-8非法字节用替换符处理再去除首尾空白如果运行环境配置了审批机制执行插件工具前会先发起审批请求被拒绝则返回ToolRejectedErrorplugin/tool.py。完整示例仓库的 examples/sample-plugin/ 是一个开箱即用的参考实现同时包含一个 Python 工具与一个 TypeScript 工具{ name: sample-plugin, version: 1.0.0, description: Sample plugin demonstrating Skills Tools, tools: [ { name: py_greet, description: Generate a greeting message (Python tool), command: [python3, scripts/greet.py], parameters: { type: object, properties: { name: { type: string, description: Name to greet }, lang: { type: string, enum: [en, zh, ja], description: Language } }, required: [name] } }, { name: ts_calc, description: Evaluate a math expression (TypeScript tool), command: [npx, tsx, scripts/calc.ts], parameters: { type: object, properties: { expression: { type: string, description: Math expression to evaluate } }, required: [expression] } } ] }对应的两个脚本分别位于 scripts/greet.py 与 scripts/calc.ts。greet.py按lang参数输出英/中/日三种语言的问候calc.ts通过正则白名单^[\d\s\-*/.()]$过滤表达式后求值非法输入直接写 stderr 并以非零码退出——这正是前面「退出码非 0 即失败」协议的典型用法。该插件还附带 SKILL.md展示了「Skills 提供使用指导、Plugins 提供可执行工具」的组合用法Skill 告诉 Agent「greet Alice in Chinese 应调用 py_greet(nameAlice, langzh)」而实际执行交给插件工具完成。这也印证了两种扩展机制在实战中往往是配合使用的。插件安装位置与生命周期插件统一安装在~/.kimi/plugins/目录下由get_plugins_dir()基于 share 目录计算见 plugin/manager.py。每个插件是一个独立的子目录包含完整的plugin.json和脚本文件。安装过程install_pluginplugin/manager.py有几个值得注意的实现细节两阶段安装先把源目录拷贝到插件目录内的临时 staging 目录依次完成凭证注入与 runtime 写入再整体 rename 到最终位置。升级失败时旧安装不会被破坏runtime 元数据安装成功后会往plugin.json写入runtime字段记录宿主名称kimi-code与宿主版本用于kimi plugin list/info展示安装状态名称安全校验插件名会被解析为绝对路径并校验必须位于插件目录内防止路径穿越。启动后Kimi Code CLI 会在加载 Agent 工具集时扫描~/.kimi/plugins/把每个插件声明的工具包装为PluginTool注册进工具列表见 soul/agent.py 与load_plugin_toolsplugin/tool.pyAgent 即可像调用内置工具一样调用它们。如果你需要更深地验证插件机制的行为可以参考仓库测试 tests/core/test_plugin.py 与 tests/core/test_plugin_manager.py其中覆盖了解析校验、注入、安装等路径的断言。结语插件系统为 Kimi Code CLI 提供了一条从「脚本封装」到「Agent 可调用工具」的最短路径一个目录、一份plugin.json、若干遵循 stdin/stdout 协议的脚本即可完成一次能力扩展。配合inject凭证注入、启动时凭证刷新、运行时环境变量传递三层机制插件既能在安装时拿到宿主配置也能在 OAuth token 刷新后继续使用最新凭证无需反复重装。对于需要持续运行或复杂编排的场景可以进一步参考 MCP 扩展机制与插件形成互补。【免费下载链接】kimi-cliKimi Code CLI is your next CLI agent.项目地址: https://gitcode.com/GitHub_Trending/ki/kimi-cli创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考