17.2 实验二:为 CLI 工具添加 Tool Use 能力

模型: claude-opus-4-6 (anthropic/claude-opus-4-6) 生成日期: 2026-02-18


上一节我们实现了一个能与 LLM 进行流式对话的 CLI 工具。但纯粹的对话并不能完成实际的编程任务——AI 需要能够读取文件编辑代码执行命令。这就是 Tool Use(工具调用)的作用。

本节将为 CLI 工具添加三个核心工具:文件读取(Read)、文件写入(Write)和命令执行(Bash),直接对应 OpenCode 第 5 章分析的 tool/read.tstool/write.tstool/bash.ts

17.2.1 目标

实现三个工具并集成到对话流程中,使 AI 能够:

  1. 读取本地文件内容

  2. 创建或覆盖文件

  3. 执行 Shell 命令

更重要的是,实现Agentic Loop(Agent 循环)——AI 调用工具 → 我们执行工具 → 将结果返回给 AI → AI 继续思考——直到 AI 认为任务完成。

衍生解释——Function Calling / Tool Use

Function Calling(函数调用)是现代 LLM 的核心能力之一。它允许 LLM 在生成文本的过程中"决定"调用一个预定义的函数,而不是直接输出文本。流程如下:

  1. 开发者向 LLM 描述可用的工具(名称、参数、用途)

  2. 用户发送请求,LLM 判断需要调用哪个工具,输出工具名称和参数

  3. 开发者接收工具调用请求,在本地执行工具

  4. 将执行结果返回给 LLM

  5. LLM 基于结果继续生成回复(可能再次调用工具)

这个机制使 LLM 从"只会说话"进化为"能做事"的 Agent。

17.2.2 实现步骤

步骤一:定义工具 Schema

使用 Zod 定义工具的参数结构。这与 OpenCode 中 tool/tool.tsTool.define() 机制一致:

注意 description 字段的重要性——LLM 通过阅读这些描述来决定何时使用哪个工具。描述越清晰准确,LLM 的工具选择就越正确。这与 OpenCode 中每个工具的 .txt 描述文件(如 tool/read.txt)的作用完全一致。

步骤二:集成到 streamText

将工具传递给 streamTexttools 参数:

maxSteps 参数是 Vercel AI SDK 对 Agentic Loop 的内置支持——它允许 LLM 在一次 streamText 调用中多次调用工具,SDK 自动处理"调用工具 → 获取结果 → 继续生成"的循环。

步骤三:实现 Agentic Loop

完整的对话函数需要处理工具调用事件:

步骤四:测试

Last updated