跳到正文

有效的工具描述

你在Agent 循环》中写第一篇工具描述时,用了两个部分:WHEN TO USE和WHEN NOT TO USE。这足以让路由用三个工具运行起来。

再加一个工具。再加五分之一。添加子 Agent、编辑、写作和待办事项。模型又开始模糊了。它会为read应该句柄的内容挑选bash,或者跳过grep,进入一个探索性的read循环,打开二十个文件。

修复方法和之前一样。我们只是需要更多。

学习成果

你Harness中的每个工具都有五个部分的描述契约(WHEN到USE,WHEN NOT到USE,DO NOT USE FOR,USAGE,EXAMPLES),模型会正确地穿越模糊提示词。

快速路径

  1. 将每个工具的描述扩展为5个部分
  2. 添加USAGE用于参数指导,添加EXAMPLES用于具体调用
  3. 保留双重负片(WHEN NOT TO USE并做 NOT USE FOR),因为没有它,每个模型都会漏回去 bash

动手练习 2.1

index.ts重构每个工具的描述,以充分利用完整契约。

要求:

  1. 每个描述都以一行简要的工具功能和输出格式的总结开头
  2. WHEN USE 列出 2-4 个具体场景,使用关键词,模型将在提示词中看到
  3. WHEN NOT TO USE 按名称重定向到其他工具
  4. DO NOT USE FOR会重复负面引导作为硬边界
  5. USAGE解释了参数约束和默认值
  6. EXAMPLES显示了2-3个具体调用,输入

实现提示:

  • WHEN NOT TO USE 是软的(“prefer X”)。DO NOT USE FOR很难(“永远不要用这个做Y”)。你想要两者都想要
  • 当描述薄弱时,模型默认会对所有内容bash。重复的负方是反力
  • USAGE在参数具有模型无法从schema推断的约束(如大写、默认值、编码)时才值得使用。

为什么要用双重负片

你可能会把WHEN NOT TO USE和 DO NOT USE FOR并排对比,觉得它们说的是重复的。他们确实如此。这正是重点。

在我们的测试中:

  • Haiku读WHEN NOT是“TO USE”,但在歧义下忽略了它
  • Sonnet 会遵守 WHEN NOT TO USE,但加入 DO NOT USE FOR 的强化约束后效果更好
  • Opus 句柄都很好,重复也无害

我们测试过的每个模型都倾向于描述薄弱时bash。我们调用这种撞击引力,那种普遍的吸引力,指向最通用的工具。说一次“不要用这个搜索”并不总是足够。说两遍几乎总是有问题。

完整契约

以下是每个部分在 grep 上的应用:

ts
const grep = tool({
  description: `Search file contents using regex. Returns matching lines with file paths.

WHEN TO USE: finding patterns across multiple files, locating function definitions,
  searching for imports, finding TODOs or error messages.

WHEN NOT TO USE: reading a known file (use read instead).
  Running commands (use bash instead).

DO NOT USE FOR: reading files (use read), listing directories (use bash),
  modifying files (use edit).

USAGE: pattern is a regex string. glob filters by file extension.
  Results are capped at 50 matches.

EXAMPLES:
  - Find all TODO comments: pattern "TODO" glob "*.ts"
  - Find function definitions: pattern "function \\w+" glob "*.ts"
  - Find imports of a package: pattern "from 'express'" glob "*.ts"`,
  // ... inputSchema and execute unchanged
});

以下是read的同样处理:

ts
const read = tool({
  description: `Read a file from the project. Returns numbered lines.

WHEN TO USE: viewing file contents, checking configurations, reading source code,
  examining specific lines with offset/limit.

WHEN NOT TO USE: searching for patterns across files (use grep instead).
  Running commands (use bash instead).

DO NOT USE FOR: searching code (use grep), executing commands (use bash),
  modifying files (use edit or write).

USAGE: path is relative to working directory. offset and limit are optional.
  Output is capped at 500 lines.`,
  // ... rest unchanged
});

bash

ts
const bash = tool({
  description: `Execute a shell command in the working directory.

WHEN TO USE: running build commands, installing packages, running tests,
  git operations, directory listings.

WHEN NOT TO USE: reading file contents (use read instead).
  Searching for patterns (use grep instead).

DO NOT USE FOR: reading files (use read), searching code (use grep).

USAGE: command is a single shell string. Commands not in the safe-prefix
  allowlist are blocked and return a clear error message.

EXAMPLES:
  - List files: command "ls -la"
  - Check git status: command "git status"
  - Run a test suite: command "npm test"`,
  // ... rest unchanged
});

为什么每个部分都值得被认可

部分作用
首行工具的功能,以及它返回的
WHEN到USE提示词会用到的具体场景和关键词
WHEN NOT到USE柔性引导到正确工具
一定要NOT USE FOR再次强调的硬边界
USAGEschema无法捕捉的约束(大写、默认值、编码)
EXAMPLES模型模式匹配的具体调用

描述会越来越长。没关系。工具描述存放在系统提示词中,SDK在回合间缓存。你已经付了一次token。

动手试试

每个工具形状运行一个提示词,并验证路由:

bash
bun run index.ts . "Find all TODO comments in this project"
bun run index.ts . "Read the package.json"
bun run index.ts . "List all files in this directory"

你应该看看:

  • TODO 提示词调用 grep
  • package.json 提示词调用 read
  • 列表文件ls提示词调用 bash
bash
npx tsc --noEmit

**注意:每个形状用一个提示词来验证**

选一个提示词能恰好指向一个工具。搜索形状表示grep,文件形状表示read,壳形状表示bash。混合提示词(比如“显示我 package.json 内容”)有时会用 cat 路由到 readbash,这不是路由 bug,而是模糊的提示词。

提交

bash
git add index.ts
git commit -m "feat(tools): expand descriptions to full 5-section contract"

完成标准

  • [ ] 这三种工具都有包含全部5个部分的描述
  • [ ] TODO搜索提示词grep
  • [ ] 文件读取后提示词路由到read
  • [ ] 壳牌列表提示词bash的路由
  • [ ] npx tsc --noEmit

**注意:找到最薄弱的环节**

选你写的描述开始脱衣。放开EXAMPLES。NOT USE FOR掉落DO。放下USAGE。每试一次后,进行三次测试提示词。路由在什么时候会中断?它最先断在哪里?第一个被翻转的模型就是你找到的那个地板。

参考实现

ts
const read = tool({
  description: `Read a file from the project. Returns numbered lines.

WHEN TO USE: viewing file contents, checking configurations, reading source code,
  examining specific lines with offset/limit.

WHEN NOT TO USE: searching for patterns across files (use grep instead).
  Running commands (use bash instead).

DO NOT USE FOR: searching code (use grep), executing commands (use bash),
  modifying files (use edit or write).

USAGE: path is relative to working directory. offset and limit are optional.
  Output is capped at 500 lines.`,
  // ... inputSchema and execute from Module 1
});

const grep = tool({
  description: `Search file contents using regex. Returns matching lines with file paths.

WHEN TO USE: finding patterns across multiple files, locating function definitions,
  searching for imports, finding TODOs or error messages.

WHEN NOT TO USE: reading a known file (use read instead).
  Running commands (use bash instead).

DO NOT USE FOR: reading files (use read), listing directories (use bash),
  modifying files (use edit).

USAGE: pattern is a regex string. glob filters by file extension.
  Results are capped at 50 matches.

EXAMPLES:
  - Find all TODO comments: pattern "TODO" glob "*.ts"
  - Find function definitions: pattern "function \\w+" glob "*.ts"
  - Find imports of a package: pattern "from 'express'" glob "*.ts"`,
  // ... inputSchema and execute from Module 1
});

const bash = tool({
  description: `Execute a shell command in the working directory.

WHEN TO USE: running build commands, installing packages, running tests,
  git operations, directory listings.

WHEN NOT TO USE: reading file contents (use read instead).
  Searching for patterns (use grep instead).

DO NOT USE FOR: reading files (use read), searching code (use grep).

USAGE: command is a single shell string. Commands not in the safe-prefix
  allowlist are blocked and return a clear error message.

EXAMPLES:
  - List files: command "ls -la"
  - Check git status: command "git status"
  - Run a test suite: command "npm test"`,
  // ... inputSchema and execute from Module 1
});

非官方简体中文翻译 · 原课程来自 Vercel Academy