系列教程
41 节
Codex 教程
按顺序阅读,循序渐进掌握相关 AI 工具与实战方法。
从「ChatGPT (Codex) 教程」开始
前面的插件都能独立运行,但多数插件要用到别人的能力:工具注册表、LLM、Agent。这篇讲两件事:如何声明依赖,以及框架如何保证依赖就绪后才执行 apply。
服务是一个插件向其他插件公开的命名能力。Harness 中 tools、llm、agents 都是内置服务,挂载在 ctx 上:
| 内置服务 | 是什么 | 典型用法 |
|---|---|---|
| ctx.tools | 工具运行时(ToolRuntime) | 注册 / 调用工具 |
| ctx.llm | 大语言模型服务(LLM) | 注册适配器、发起模型请求 |
| ctx.agents | 智能体服务(Agent) | 管理子智能体 |
插件需要某个服务,就把它写进 inject 数组。框架会确保这些服务全部就绪后才加载你的插件——这是框架的保证,不需要你在代码里做任何等待:
// 文件路径:scratch-plugin/src/my-tool-plugin.ts
import type { Context } from '@deepseek-ai/cordis'
export const name = 'my-tool-plugin'
// 声明依赖:需要 tools 服务
export const inject = ['tools']
export function apply(ctx: Context) {
// 走到这里时,ctx.tools 一定已就绪
ctx.tools.register(/* ... */)
}
如果某个服务还没准备好,插件不会执行,它的 Fiber 会停在 PENDING 状态(「已声明,但所需依赖未就绪」)等服务出现。服务一直不来,插件就一直等——不报错,也不会执行 apply。
inject 声明的是必需依赖:服务缺席时插件不加载。如果某个服务可用可不用,就别写 inject,改在使用处用 ctx.get() 查询:
// 可选依赖:省略 inject,用 ctx.get() 查询
import type { Context } from '@deepseek-ai/cordis'
export function apply(ctx: Context) {
// metrics 服务可能在也可能不在
const metrics = ctx.get('metrics')
// 可选链:不存在就跳过,不报错
metrics?.record('plugin_loaded', 1)
}
运行期间如果必需服务消失(比如提供方被卸载),会发生两件事:第一,依赖它的插件自动 dispose(释放资源);第二,服务重新出现时插件自动重新加载。这保证了插件永远不会调用一个已不存在的服务。这条规则与自动清理机制配合——卸载会触发前面讲过的 disposer。
用 inject 声明必需服务,框架保证就绪后才执行 apply;可选服务用 ctx.get() 查询,配合可选链安全跳过。