代码讲解.md 2.5 KB

S02 Tool Use 代码讲解

这一节只讲相对 S01 新增的内容:

从一个 bash 工具,扩展成多个专用工具,并用分发映射统一执行。


1. 本节新增内容

  • safe_path():限制文件操作只能发生在工作区内。
  • run_read():读取文件。
  • run_write():写入文件。
  • run_edit():替换文件中的一段文本。
  • run_glob():按 glob 模式查找文件。
  • TOOL_HANDLERS:把工具名映射到 Python 函数。

2. 为什么要拆工具

S01 只有一个 bash 工具,什么都靠命令完成。

这一节拆成多个工具:

bash
read_file
write_file
edit_file
glob

好处是:

  • 模型更清楚每个工具应该怎么用。
  • 程序更容易做权限控制。
  • 日志里更容易看出 Agent 在做什么。
  • 读写文件不用都藏在 shell 命令里。

3. Tool Schema 数据结构

每个工具都是一个字典:

{
    "name": "read_file",
    "description": "读取文件内容。",
    "input_schema": {
        "type": "object",
        "properties": {
            "path": {"type": "string"},
            "limit": {"type": "integer"}
        },
        "required": ["path"]
    }
}

可以理解成:

工具名:read_file
参数:
  path: string,必填
  limit: integer,可选

4. safe_path(p)

safe_path() 的作用是防止模型读写工作区外面的文件。

path = (WORKDIR / p).resolve()

它会把用户传进来的相对路径变成绝对路径。

然后检查:

path.is_relative_to(WORKDIR)

意思是:这个路径必须还在当前项目目录里面。


5. TOOL_HANDLERS

TOOL_HANDLERS 是工具分发器:

TOOL_HANDLERS = {
    "bash": run_bash,
    "read_file": run_read,
    "write_file": run_write,
    "edit_file": run_edit,
    "glob": run_glob,
}

模型返回:

block.name = "read_file"
block.input = {"path": "README.md"}

程序就可以这样执行:

handler = TOOL_HANDLERS.get(block.name)
output = handler(**block.input)

**block.input 的意思是把字典拆成函数参数:

{"path": "README.md", "limit": 20}

会变成:

run_read(path="README.md", limit=20)

6. 本节课堂重点

Agent 的工具系统不是写死在循环里的。

更好的结构是:

模型选择工具名
程序用 TOOL_HANDLERS 找到函数
程序把 input 参数传进去
函数返回执行结果

这样后面新增工具时,Agent Loop 不需要大改。