# S02 Tool Use 代码讲解 这一节只讲相对 S01 新增的内容: **从一个 bash 工具,扩展成多个专用工具,并用分发映射统一执行。** --- ## 1. 本节新增内容 - `safe_path()`:限制文件操作只能发生在工作区内。 - `run_read()`:读取文件。 - `run_write()`:写入文件。 - `run_edit()`:替换文件中的一段文本。 - `run_glob()`:按 glob 模式查找文件。 - `TOOL_HANDLERS`:把工具名映射到 Python 函数。 --- ## 2. 为什么要拆工具 S01 只有一个 `bash` 工具,什么都靠命令完成。 这一节拆成多个工具: ```python bash read_file write_file edit_file glob ``` 好处是: - 模型更清楚每个工具应该怎么用。 - 程序更容易做权限控制。 - 日志里更容易看出 Agent 在做什么。 - 读写文件不用都藏在 shell 命令里。 --- ## 3. Tool Schema 数据结构 每个工具都是一个字典: ```python { "name": "read_file", "description": "读取文件内容。", "input_schema": { "type": "object", "properties": { "path": {"type": "string"}, "limit": {"type": "integer"} }, "required": ["path"] } } ``` 可以理解成: ```python 工具名:read_file 参数: path: string,必填 limit: integer,可选 ``` --- ## 4. `safe_path(p)` `safe_path()` 的作用是防止模型读写工作区外面的文件。 ```python path = (WORKDIR / p).resolve() ``` 它会把用户传进来的相对路径变成绝对路径。 然后检查: ```python path.is_relative_to(WORKDIR) ``` 意思是:这个路径必须还在当前项目目录里面。 --- ## 5. `TOOL_HANDLERS` `TOOL_HANDLERS` 是工具分发器: ```python TOOL_HANDLERS = { "bash": run_bash, "read_file": run_read, "write_file": run_write, "edit_file": run_edit, "glob": run_glob, } ``` 模型返回: ```python block.name = "read_file" block.input = {"path": "README.md"} ``` 程序就可以这样执行: ```python handler = TOOL_HANDLERS.get(block.name) output = handler(**block.input) ``` `**block.input` 的意思是把字典拆成函数参数: ```python {"path": "README.md", "limit": 20} ``` 会变成: ```python run_read(path="README.md", limit=20) ``` --- ## 6. 本节课堂重点 Agent 的工具系统不是写死在循环里的。 更好的结构是: ```python 模型选择工具名 程序用 TOOL_HANDLERS 找到函数 程序把 input 参数传进去 函数返回执行结果 ``` 这样后面新增工具时,Agent Loop 不需要大改。