Codex 教程
按顺序阅读,循序渐进掌握相关 AI 工具与实战方法。
工具(tool)是 Agent 用来干活的函数:它有名称、说明、参数和输出格式,模型看到这些定义后在生成回复时决定何时调用。在 dsh 里,工具通过 ctx.tools.register 注册到工具注册表。这篇用 defineTool 写出第一个工具 greet,并让模型真的调用它。
defineTool 是定义工具的 DSL,接收一个描述工具全部信息的对象:
| 字段 | 作用 |
|---|---|
| name | 工具名,模型用它发起调用 |
| description | 工具说明,告诉模型什么时候用 |
| parameters | 入参 schema,defineTool 据此推导并校验 args |
| output.schema | 返回值 schema,声明 execute 返回的规范值类型 |
| output.render | 结果格式化,把规范值转成面向模型的内容 |
| execute | 工具实现,真正执行逻辑,返回规范值 |
把 scratch-plugin/src/my-plugin.ts 替换为以下内容:
// 文件路径:scratch-plugin/src/my-plugin.ts
import type { Context } from '@deepseek-ai/cordis'
import { defineTool } from '@deepseek-ai/dsh-tools'
export const name = 'greet-tool'
// 需要 tools 服务:注册工具的前提
export const inject = ['tools']
export function apply(ctx: Context) {
ctx.tools.register(defineTool({
// 工具名:模型会以这个名字发起调用
name: 'greet',
// 工具说明:告诉模型什么时候用
description: 'Greet someone by name.',
// 入参 schema:defineTool 会推导并校验 args
parameters: {
name: { type: 'string', required: true, description: 'The name to greet' },
},
output: {
// 规范值类型:execute 的返回值
schema: { type: 'string' },
// render:把规范值转成面向模型的内容
render: (_args, value) => [{ type: 'text', text: value }],
},
// 工具实现:返回规范值,这里是字符串
async execute(args) {
return `Hello, ${args.name}!`
},
}))
}
几个要点:inject 让 Cordis 等待工具注册表就绪;defineTool 根据 parameters 推导并校验 args;execute 返回 output.schema 声明的规范值(canonical value),再由 output.render 转成面向模型的内容——同一规范值可通过不同 render 变成不同格式,两者是解耦的。
如果开发命令没在运行,重新启动:
pnpm dsh web --patch ./scratch-plugin/cordis.yml
打开 http://127.0.0.1:3080,输入「Use the greet tool to greet RUNOOB.」,模型就会调用 greet 并收到 Hello, RUNOOB! 这一工具结果。
工具的 name、description、parameters、output 会自动组装进模型提示词,模型「知道」有这个工具,就会在合适的时候调用——你不需要手写函数签名给模型看,schema 就是模型看到的接口。想写更复杂的工具(嵌套 schema、后台工作、策略钩子),可查阅官方工具编写参考。
本文根据 runoob 公开教程的核心信息进行原创整理与改写,原文地址:DeepSeek Harness 定义第一个工具。具体细节以 DeepSeek Harness 官方文档为准。