ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

learn-claude-code s02 工具分发:给 Agent 加一个工具,只需加一行代码

learn-claude-code s02 工具分发:给 Agent 加一个工具,只需加一行代码 learn-claude-code s02 工具分发给 Agent 加一个工具只需加一行代码【免费下载链接】learn-claude-codeBash is all you need - A nano claude code–like 「agent harness」, built from 0 to 1项目地址: https://gitcode.com/GitHub_Trending/an/learn-claude-code本文基于 learn-claude-code 课程第 s02 章Tool Use文档与配套源码展开讲解如何在一个已有的 Agent 循环上通过“工具定义数组 分发映射表”两个数据结构把工具集从 1 个 bash 扩展到 5 个专用工具读、写、改、glob。读完后你将掌握如何为 LLM Agent 编写带 JSON Schema 的工具定义、如何用一张TOOL_HANDLERS字典完成工具调用分发、如何用safe_path约束文件类工具的活动范围以及模型一次返回多个 tool_use 时的执行顺序约定。为什么只靠 Bash 不够s01Agent Loop阶段的 Agent 只有一个工具bash。它想读文件得拼cat path/to/file想写文件得拼echo ... file.py想改文件得拼sed。文档指出的核心问题是模型脑子里想的是“读这个文件”却必须把意图翻译成一条 shell 命令——这层额外的翻译既浪费 token又容易出错引号转义、特殊字符、shell 方言差异。s02 的解法就是课程标题所概括的Add a tool, add just one handler—— 循环保持不变把新工具注册进分发表就完事。本章属于整个课程 Harness 层的Tool Dispatch工具分发环节主题是“扩展模型能够触及的范围”。从 1 个工具到 5 个工具工具定义层s01 中工具定义只有一个 bashTOOLS [{name: bash, ...}] def run_bash(command): ...s02 将其扩展为 5 个工具每个工具都是“一份 JSON 定义 一个独立的实现函数”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., ...}, ]完整的工具定义在 s02_tool_use/code.py 中每一项都是标准的 Anthropic Messages API 工具格式namedescriptioninput_schema。以read_file为例{name: read_file, description: Read file contents., input_schema: {type: object, properties: {path: {type: string}, limit: {type: integer}}, required: [path]}},结合源码可以看到每个工具的实现细节与边界行为工具实现函数参数源码中的关键行为bashrun_bashcommand必填危险命令黑名单rm -rf /、sudo、shutdown、reboot、 /dev/直接拦截subprocess.run超时 120sstdoutstderr 合并后截断到 50000 字符read_filerun_readpath必填、limit可选超过limit行时追加... (N more lines)提示避免大文件撑爆上下文write_filerun_writepath、content均必填自动mkdir(parentsTrue, exist_okTrue)创建父目录返回Wrote N bytes to pathedit_filerun_editpath、old_text、new_text均必填用text.replace(old_text, new_text, 1)精确替换一次old_text不存在时返回Error: text not found in {path}而非静默成功globrun_globpattern必填用glob.glob(pattern, root_dirWORKDIR)限定搜索根目录并对每个匹配结果二次校验是否仍在工作区内无匹配返回(no matches)注意两个实现层面的设计取舍所有工具失败时都返回字符串错误Error: ...而不是抛异常。异常若直接向上抛会打断agent_loop返回错误字符串则能让模型“看到”失败信息并自行修正重试——这是 Agent 工具设计的常见范式。run_bash只做了极轻量的危险命令拦截从 s01 原样继承真正的权限门控留到了 s03 Permission 章节。文档在结尾明确提示文件类工具有safe_path保护但 bash 基本不设防rm -rf /依然会被执行只被那行黑名单挡住字面匹配。工具分发TOOL_HANDLERS 映射表s02 唯一的结构性新增是一张分发映射表s02_tool_use/code.pyTOOL_HANDLERS { bash: run_bash, read_file: run_read, write_file: run_write, edit_file: run_edit, glob: run_glob, }Agent 循环里原来硬编码的run_bash()调用被替换成一次字典查表agent_loop# s01: output run_bash(block.input[command]) # s02: output TOOL_HANDLERSblock.name def agent_loop(messages: list): while True: response client.messages.create( modelMODEL, systemSYSTEM, messagesmessages, toolsTOOLS, max_tokens8000, ) messages.append({role: assistant, content: response.content}) if response.stop_reason ! tool_use: return results [] for block in response.content: if block.type tool_use: print(f\033[33m {block.name}\033[0m) handler TOOL_HANDLERS.get(block.name) output handler(**block.input) if handler else fUnknown: {block.name} print(str(output)[:200]) results.append({type: tool_result, tool_use_id: block.id, content: output}) messages.append({role: user, content: results})对照 s01_agent_loop/code.py 中的原始循环可以逐行确认文档的说法“循环一个字都没改”while True、client.messages.create、stop_reason判断、assistant 消息追加、tool_result 回传全部原样保留差异仅在两处——执行语句从run_bash(block.input[command])变为TOOL_HANDLERS.get(block.name)查表后再以handler(**block.input)调用参数按模型返回的block.input字典解包传入用.get()而非[]索引查不到 handler 时返回Unknown: {name}字符串保证即使模型幻觉出一个不存在的工具名循环也能带着错误信息继续而不是崩溃。因此“给 Agent 加工具”的成本被压缩成固定两步在TOOLS数组里加一个条目告诉模型能做什么在TOOL_HANDLERS里加一行映射告诉运行时怎么执行。循环本身对工具数量零感知。路径安全safe_path 约束文件类工具s02 相比 s01 的另一项实质变化是给文件类工具加上了工作区边界校验s02_tool_use/code.pydef safe_path(p: str) - Path: path (WORKDIR / p).resolve() if not path.is_relative_to(WORKDIR): raise ValueError(fPath escapes workspace: {p}) return path其原理值得展开模型给出的路径是相对WORKDIR拼接后再resolve()解析..与符号链接然后用is_relative_to(WORKDIR)断言解析结果必须仍在工作区内。这样../../etc/passwd、指向工作区外的符号链接等逃逸手段都会在拼接阶段被ValueError拦下再由run_read等函数外层的except转成Error: Path escapes workspace: ...返回给模型。从源码结构看该保护只覆盖read_file/write_file/edit_file以及glob的结果校验run_glob中每个匹配都再次检查is_relative_to(WORKDIR)run_bash不受此约束——这正是文档在 “Whats Next” 中引向 s03 Permission 的动机在工具执行前插入一道“这个操作安全吗需要用户批准吗”的关卡。多个工具调用一次响应顺序执行文档指出一个实际观察到的行为模式模型经常在单次响应中返回多个tool_use块例如“读 a.py 和 b.py再列出所有 .py 文件”。源码中的处理逻辑是遍历response.content中所有type tool_use的块按它们在response.content中的原始顺序逐一执行把每个结果以{type: tool_result, tool_use_id: block.id, content: output}的格式收集进results最后作为一条user消息整体回传。这里有两个可验证的细节每个tool_result通过tool_use_id与对应的tool_use块一一绑定模型回看历史时能明确区分“哪个调用产生了哪个结果”执行是串行且保序的多个工具之间没有并行、没有乱序——这一点可以用文档给出的验证 prompt 实测确认。动手验证运行前提参考 根 README 的 Quick Startcd learn-claude-code pip install -r requirements.txt cp .env.example .env # 配置 ANTHROPIC_API_KEY另需 MODEL_ID 环境变量见 code.py 中 os.environ[MODEL_ID] python s02_tool_use/code.py进入交互式 REPLs02 提示符输入q退出后文档建议用以下四个 prompt 观察工具分发行为Read the file README.md and tell me what this project is aboutCreate a file called test.py that prints hello, then read it backFind all Python files in this directoryRead both README.md and requirements.txt, then create a summary file观察要点模型什么时候只调用一个工具什么时候一次调用多个多个工具调用是否按正确顺序执行控制台会打印每个工具名黄色 read_file和输出前 200 字符便于逐次核对。s01 → s02 变更清单文档给出的对比表完整继承如下组件之前s01之后s02工具数量1bash5read、write、edit、glob工具执行硬编码run_bash()TOOL_HANDLERS分发查表路径安全无safe_path校验仅文件类工具Agent 循环while Truestop_reason判断与 s01 完全一致概念速查表概念一句话解释TOOL_HANDLERS工具名 → 处理函数的字典加工具 加一行映射工具定义TOOLS用 JSON Schema 告诉模型“我能做什么”多工具调用模型可能一次返回多个tool_use按原始顺序逐一执行循环不变s01 的while True循环一行未改对照阅读12 课旧版实现仓库中另有一条 legacy 12 课轨道对应实现是 agents/s02_tool_use.py。它与本章s02_tool_use/code.py的差异可用于理解同一模式的演进旧版只有 4 个工具没有glob且分发映射用的是 lambda 适配层agents/s02_tool_use.pyTOOL_HANDLERS { bash: lambda **kw: run_bash(kw[command]), read_file: lambda **kw: run_read(kw[path], kw.get(limit)), ... }新版改为直接绑定函数、以handler(**block.input)解包调用少了一层 lambda 中转。两条实现的分发思想完全一致印证了本章的核心结论“循环一点没变我只是加了工具”。小结与下一步s02 用最小改动回答了 Agent 工程中一个高频问题——如何以 O(1) 的成本扩展工具集工具定义层TOOLS负责模型侧的能力声明分发表TOOL_HANDLERS负责运行时的路由两者加在一起就是全部增量Agent 循环对工具数量保持无感知。文件类工具经safe_path被约束在工作区内但 bash 通道依然敞开这正是下一章 s03 Permission 的入口在工具执行前加一道安全检查与用户批准的关卡。【免费下载链接】learn-claude-codeBash is all you need - A nano claude code–like 「agent harness」, built from 0 to 1项目地址: https://gitcode.com/GitHub_Trending/an/learn-claude-code创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表