Tool Use — 多加一个工具,只加一行

"加一个工具, 只加一个 handler" — 循环不用动, 新工具注册进 dispatch map 就行。

Github 原文:shareAI-lab/learn-claude-code

只有 bash 一个工具

我记得早在别的文章里我提到过,Claude code 最早其实是就是Claude 模型搭配一个 Bash 工具(文章是哪一篇我不记得了,哈哈哈)。但是,随着希望做的更加复杂,CC 现在早已经不是只有一个工具这么简单了。

你可能会说,一个强大的模型搭配无所不能的 Bash 不是一样可以力大砖飞?但之所以 Harness 如此重要,就是因为更高的效率和空间,更多的工具并不是臃肿,而是为了更好的侠侣,更少的错误,毕竟大家都知道多说多错:)

全局视角:工具分发

Tool Use — 多加一个工具,只加一行

如果你对比上一篇文章的流程图会发现,上一篇文章的流程是完全保留的(LLM 调用、stop_reason 判断、消息追加)。唯一的变动在工具执行那 1 行:run_bash() 替换为 TOOL_HANDLERS[block.name]() 查表分发。

给 Agent 加一个工具只需要做两件事:

  1. 定义工具:在 TOOLS 数组里加一条描述

  2. 注册处理函数:在 TOOL_HANDLERS 字典里加一个映射

原理解释

从 1 个工具到 5 个工具

之前只有一个 bash 工具,现在一下子拓展到了 5 个,那么就有问题了,AI 怎么知道要用哪个呢?其实从代码结构我们就能知道了:

TOOLS = [
    {"name": "bash",       "description": "Run a shell command.", ...},
    {"name": "read_file",  "description": "Read file contents.",  ...},
    {"name": "write_file", "description": "Write content to file.", ...},
    {"name": "edit_file",  "description": "Replace text in file once.", ...},
    {"name": "glob",       "description": "Find files by pattern.", ...},
]

我们不去研究工具的实现函数等技术问题,但就从这里就可以知道,工具也采用的之前介绍 Skill 一样的渐进式披露,只展示名称和描述,让 AI 知道遇到问题该用哪个工具,然后再去看如何用。

多个工具调用

就是模型可一次返回多个 tool_use,教学版按原始顺序逐个执行,不过按照原文说的,CC 在这里的处理是比较复杂的,按照原始顺序切成连续 batch,在 batch 内并发安全的工具并行调用,而不是我们理解的串流按照顺序一个一个的调用。这里不需要理解技术逻辑,反正只需要知道这个简单的是可以做串流,复杂的、高级的 Agent 为了节约时间,会做并行。

但这里需要额外注意一种情况,我们不妨举个例子,假如说我们有这样的一个流程:

  1. 搜索用户仓库

  2. 读取 README

  3. 搜索 issue

  4. 读取 issue #123

  5. 修改代码

这里其实很显然我们能发现如果直接分成 5 个来并行是有问题的——后面的步骤没法和第一步并行,因为他们依赖于第一步。

所以 CC 是怎么处理的?他是这么处理的,做成了混合的形式,有串流又有并流,这就是“batch 内并发,batch 间顺序”。也就是说,先在一个 batch 中执行第一步,完成后在另一个 batch 中执行第二步和第三步,完成后在依次在 batch 中依次执行 4、5 步。

如果你觉得这里难以理解,我们不妨用一个漫画来表达清楚。

Tool Use — 多加一个工具,只加一行