跳转到内容

第 8 课:自定义工具开发

学习用 defineTool() 为 Pi Agent SDK 增加业务工具,掌握 schema、返回格式和错误处理的工程边界。

自定义工具是 agent harness 和真实工程系统之间的受控接口。模型只能看到工具名、描述和参数 schema;运行时负责校验参数、执行工具、把结果和错误重新包装成模型可以继续推理的上下文。

什么时候应该写一个专用工具,而不是让模型直接使用通用命令工具?

  • 工具名和描述决定模型什么时候会调用它。
  • 参数 schema 决定模型能传什么输入。
  • execute 决定真实副作用和返回格式。
  • 工具结果必须足够结构化,方便模型继续推理和宿主审计。

下面不是完整源码,而是把本课主线压缩成可以在文档里直接阅读的关键形状。读者即使不打开本地源码,也应该能看出运行时如何组织职责。

const runTests = defineTool({
name: "run_tests",
description: "Run the approved project test suite and return a structured summary.",
parameters: { suite: enumOf(["unit", "typecheck"]) },
async execute(args) {
const result = await approvedRunner.run(args.suite);
return { exitCode: result.code, summary: result.summary };
},
});
  • 专用工具把权限收窄到“允许的测试套件”,比开放命令工具更可控。
  • 返回结构里保留 exitCodesummary,既能让模型继续推理,也能让 trace 审计。
  • 工具不要吞掉错误;失败也应该变成结构化 tool result。

设计一个只允许执行固定检查项的 run_tests 工具,写出参数、返回值和错误策略。

  • 能写出工具名、描述、schema 和 execute 的边界。
  • 能说明专用工具和通用命令工具的取舍。
  • 能设计可审计的工具返回结构。
  1. 实践题:基于本课的省略版源码,补出一个最小实现草图,要求写清输入、输出、副作用和错误处理。
  2. 思考题:本课机制如果只靠 prompt 约束,而不放进 harness 或 runtime,会出现什么工程风险?