这一节只讲相对 S01 新增的内容:
从一个 bash 工具,扩展成多个专用工具,并用分发映射统一执行。
safe_path():限制文件操作只能发生在工作区内。run_read():读取文件。run_write():写入文件。run_edit():替换文件中的一段文本。run_glob():按 glob 模式查找文件。TOOL_HANDLERS:把工具名映射到 Python 函数。S01 只有一个 bash 工具,什么都靠命令完成。
这一节拆成多个工具:
bash
read_file
write_file
edit_file
glob
好处是:
每个工具都是一个字典:
{
"name": "read_file",
"description": "读取文件内容。",
"input_schema": {
"type": "object",
"properties": {
"path": {"type": "string"},
"limit": {"type": "integer"}
},
"required": ["path"]
}
}
可以理解成:
工具名:read_file
参数:
path: string,必填
limit: integer,可选
safe_path(p)safe_path() 的作用是防止模型读写工作区外面的文件。
path = (WORKDIR / p).resolve()
它会把用户传进来的相对路径变成绝对路径。
然后检查:
path.is_relative_to(WORKDIR)
意思是:这个路径必须还在当前项目目录里面。
TOOL_HANDLERSTOOL_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)
Agent 的工具系统不是写死在循环里的。
更好的结构是:
模型选择工具名
程序用 TOOL_HANDLERS 找到函数
程序把 input 参数传进去
函数返回执行结果
这样后面新增工具时,Agent Loop 不需要大改。