
Code Agent 的工具粒度怎么选Hello-Agents Extra09 踩坑经验中的万能工具与过度原子化取舍【免费下载链接】hello-agents 《从零开始构建智能体》——从零开始的智能体原理与实践教程项目地址: https://gitcode.com/datawhalechina/hello-agents如果你在基于 Hello-Agents 做自己的 Code Agent本仓库共创项目里就有一个可运行的参考实现 YYHDBL-HelloCodeAgentCli第一个会卡住你的工程决策是给模型一个能写管道、重定向的万能终端工具还是把列目录、按名找文件、搜内容、读行范围全拆成独立工具Hello-Agents 的 Extra09 踩坑经验记录了作者在这两个方向上各踩一次坑的完整过程并给出了频率 × 确定性的判断框架。本文结合该经验和仓库里的真实代码帮你把工具粒度定下来并说明参考实现目前处于哪个阶段、怎么验证你的配置是否生效。两个极端各坏在哪里极端 A万能工具——错误被管道吞掉系统不可诊断Extra09 第二章记录了一次真实的管道命令事故。Agent 收到需求搜一下process_data函数的定义后自己组合了一条命令rg -n def process_data src/ | grep -v test | sed -n 1,50p执行结果是空的。Agent 连着重试三轮换目录、模糊匹配、find | xargs grep最后告诉用户函数不存在。但手动进仓库一看函数就在src/utils/helpers.py第 42 行。把命令拷到终端单独跑rg直接报错path src/ does not exist——启动 Agent 时的工作目录不是项目根目录而管道把上游错误吞掉了Agent 只看到一个空字符串。作者归纳的根因有三点多步骤被塞进一个 Action中间状态全丢观察信号只有终态真的没找到和查找过程出错了混在一起模型无法针对具体某一步纠错重试靠的是猜。结论是给模型自由组合命令的能力不是在提升能力上限而是在放大不确定性。极端 B过度原子化——决策负担压垮模型意识到万能工具有问题后作者走向另一个极端工具列表变成这样ListDir、ListDirRecursive、FindByName、FindByPattern、SearchExact、SearchRegex、SearchFuzzy、ReadLines、ReadOffset、ReadFull……问题随之出现模型开始选工具困难。都是找文件精确匹配、通配符还是正则有一次让它找所有测试文件它先调ListDirRecursive列出全部文件又想用SearchRegex过滤发现那是搜内容不是搜文件名再调回ListDirRecursive最后才选对Glob——本来一步的事用了四步。Schema 噪声淹没上下文。十几个工具的参数描述、类型定义、约束条件加起来就是几千 token模型还没开始解决任务注意力先消耗在读说明书上长 schema 还会让模型选择性失明。维护成本爆炸。FindByName和FindByPattern有 80% 逻辑重复因为是两个独立工具要维护两份代码。Extra09 的判断是过度封装和过度拆分都会把系统推向不稳定只是一个坏在执行期万能工具一个坏在决策期过度原子化。判断标准频率 × 确定性作者在 Extra09 第三章给自己定的判断框架只有两个维度高频、强确定动作必须原子化一步完成不可再分中频、带副作用动作必须受控关键操作加保险低频、弱确定动作保留弹性但放到兜底层明确禁止什么而非允许什么。按这个框架工具体系形成三层结构层级代表工具设计目标典型约束高频原子层LS / Glob / Grep / Read一步一证据便于纠错输入输出强约束中频受控层Write / Edit / MultiEdit改动可验证、可回滚读后写 乐观锁低频兜底层Bash处理非常规需求明确禁区不走主链这套分层配套的三个关键机制值得在二次开发时直接照抄思路1. 统一响应协议。所有工具无论频率高低都返回统一格式的 JSON状态码只有success/partial/error三种。模型据此能区分确实没有和出错了例如 Glob 搜不到文件与路径不存在是两种不同结果以下为文档示例{ status: success, data: {paths: []}, text: No files matching *.xyz found }{ status: error, error: {code: NOT_FOUND, message: Path src/ does not exist} }2. 读后写 乐观锁。中频层的硬规则是不 Read 就不能改ToolRegistry维护读缓存文件没被 Read 过时 Edit/Write 直接返回错误File not read. You must read before editing.Read 过之后文件若被外部修改Edit 对比file_mtime_ms和file_size_bytes不匹配则返回CONFLICT模型必须重新 Read 再改。3. 兜底层的禁区清单。Bash 不删但核心约束是一条禁止做高频动作能做的事BASH_DISABLED_PATTERNS [ # 禁止读/搜/列这些有专门工具 r\bls\b, r\bcat\b, r\bhead\b, r\btail\b, r\bgrep\b, r\bfind\b, r\brg\b, # 禁止交互 r\bvim?\b, r\bnano\b, r\btop\b, r\bssh\b, # 禁止网络默认 r\bcurl\b, r\bwget\b, # 危险命令黑名单 r\brm\s-rf\b, r\bsudo\b, r\bsu\b, r\bmkfs\b, r\bfdisk\b ]模型试图用 Bash 跑ls时会收到Use LS tool instead of Bash for listing directories.被强制拉回原子工具主链路。此外还有两个机制ToolRegistry把每个工具的参数定义汇总成 JSON Schema 统一提供给模型registry.get_openai_tools()工具连续 3 次失败会触发熔断临时禁用、300 秒后恢复防止模型在坏工具上死循环。原子化之后还有一个容易忽略的细节数量要控制。高频动作合并成少数稳定入口——比如按名找文件最终合并成单个Glob参数只有pattern和path**递归等复杂度藏在实现层Grep 内部可以优先用rg、不可用时回退 Python 实现但对外接口保持稳定。schema 总量要控制在模型可承受范围内不要让读说明书消耗太多注意力。参考实现HelloCodeAgentCli 目前处于哪个阶段先说清楚现状避免拿 Extra09 的目标设计去对不存在的代码YYHDBL-HelloCodeAgentCli 的 README 在未来规划里明确列着未完成的勾选框——细分终端命令工具将 Terminal Tool 拆分为原子性的命令工具。也就是说这个开源仓库当前仍是一个 terminal 万能工具 安全限制的阶段对应上面的极端 A 的改进版而三层结构是作者重构后的目标设计。你二次开发时的参照物是两样仓库里的 terminal 安全约束代码加上 Extra09 第三、四章的拆法。准备与启动按 顶层 README环境要求 Python 3.10macOS / Linux / Windows。克隆仓库后创建虚拟环境、安装依赖README 写的是pip install -r requirements.txt但目录中实际文件名为requirement.txt两处命名不一致以仓库内实际文件为准创建.env配置 LLM# LLM 配置必需 LLM_BASE_URLhttps://api.deepseek.com LLM_MODELdeepseek-chat DEEPSEEK_API_KEYsk-xxxxxxxxxxxx注意变量命名存在文档冲突顶层 README 用LLM_MODEL而 code_agent/README.md 写的是LLM_MODEL_ID且依赖文件一个叫requirements.txt、一个叫requirements-mvp.txt。按哪份 README 配置请以实际代码中读取的环境变量为准本文不替文档做裁定。启动 CLIpython -m code_agent.hello_code_cli --repo .--repo指定目标代码库默认当前目录其他可选参数有--model、--api-key、--base-url、--max-steps最大推理步数默认 15、--debug。工具注册与启动验证主逻辑在 code_agent.pyterminal 工具的初始化是这么写的self.terminal_tool TerminalTool( workspacestr(self.paths.repo_root), timeout60, confirm_dangerousTrue, default_shell_modeTrue, ) self.registry ToolRegistry() self.registry.register_tool(self.terminal_tool)注意default_shell_modeTrue这一版默认放开管道等 shell 语义作者自述体验更像 Claude Code安全靠后面的限制层兜底。所有工具terminal、note、plan、todo、context_fetch都通过ToolRegistry注册registry.py 里每次注册会打印✅ 工具 {name} 已注册。同名重注册则打印覆盖警告——启动后先在终端看到这几个注册输出是最直接的工具挂载成功验证。执行层execute_tool对模型输出做了多层 JSON 容错数组包裹单对象、尾部多括号、正则提取首个完整对象等解析不出结构化参数时返回错误工具 {name} 需要结构化参数。请使用 JSON 形式传参例如tool[{param:value}]。如果模型反复收到这条错误问题通常在提示词里的调用示例而不是执行器。terminal 工具的安全边界terminal_tool.py 是当前万能工具阶段的核心二次开发时最值得读的就是它。它的分层约束白名单ALLOWED_COMMANDS只放行ls/cat/head/tail/find/grep/rg/sed/wc/sort等只读与文本处理命令外加git子命令再限死为status/diff和mkdir受路径沙箱约束。非白名单命令直接返回❌ 不允许的命令: {base_command}并附上允许列表。两种执行模式argv 模式shellFalse不支持管道和 shell 模式shellTrue支持管道。shell 模式下管道免确认但重定向/dev/null除外、命令替换$(...)、反引号、rm/chmod、git reset --hard会命中危险检测未带allow_dangeroustrue时返回❌ 该命令包含写盘/子命令替换/高风险操作需用户确认后再执行带了allow_dangerous且开启confirm_dangerous时还会交互式问一次y/n。路径沙箱cd出工作区返回❌ 不允许访问工作目录外的路径即使放行了rm/chmod参数里的路径也必须在 workspace 内。超时与输出上限CLI 侧配置为 60 秒超时、10MB 输出上限config.py 中terminal_timeout: 60、terminal_max_output_size: 10 * 1024 * 1024、terminal_confirm_dangerous: True也可用环境变量CODE_AGENT_TERMINAL_TIMEOUT等覆盖。运行一个任务并验证返回启动后给一个搜索类任务顶层 README 里的示例是帮我分析 src/main.py 的入口函数观察 ReAct 轨迹中的Action: terminal[...]及其 Observation。判断工具粒度配置是否合理看两点失败是否可定位。argv 模式下工具会把 stderr 合并进结果并标记返回码⚠️ 命令返回码: {n}、[stderr]段成功无输出时返回✅ 命令执行成功无输出超时返回❌ 命令执行超时超过 60 秒——每一类失败都有不同文本开发者能区分没搜到和命令没跑成。这正是 Extra09 反复强调的诊断性对比一下shell 管道模式下上游报错会被下游吞成空输出模型只会基于空结果瞎猜。模型是否被迫走抄近道。提示词层在 tools.md 里给每个工具写了何时用 / 何时不用terminal 明确标注何时不用写文件用补丁大范围全库扫描除非用户要求危险命令rm/chmod/git reset --hard并要求写/改文件必须走*** Begin Patch ... *** End Patch补丁格式而非重定向写盘。如果你的模型频繁绕过这些约定先查 Trace 里工具描述是否清晰再考虑收紧shell_modeExtra09 第四章的结论是先记录、后优化改提示词坚持单变量改动。什么时候该拆什么时候不该拆把两边的证据合起来取舍原则可以收敛成一张操作清单该拆原子化每天调用几十次的高频动作列目录、找文件、搜内容、读文件。Extra09 的诊断判据是失败可归因——Glob 返回空数组说明文件确实不存在返回NOT_FOUND说明路径错了Grep 超时说明搜索范围太大模型可以按错误码决定下一步而不是赌运气重试。该控加保险涉及文件修改的中频动作。标配是读后写检查 乐观锁 MultiEdit保证同文件多点修改的原子性要么全成功要么全失败避免半改状态。该留但限死兜底跑pytest tests/、pip install -r requirements.txt、git status这类原子工具覆盖不到的低频需求留给 Bash/terminal但禁区清单必须写在工具里代码层拦截而不是只写在提示词里模型可能忘。需要提醒的边界本文引用的三层结构、BASH_DISABLED_PATTERNS、乐观锁注入等实现来自 Extra09 作者重构后的项目其重构仓库在本仓库之外HelloCodeAgentCli 当前代码里尚未包含这些原子工具仓库中能直接核对的是 terminal 白名单/确认机制、ToolRegistry的注册与执行协议、tools.md 的工具使用提示词以及拆分原子工具还挂在 README 未来规划里这一事实。想跟进这条演进路径可以直接对照 README 的未来规划清单——细分终端命令工具、改写 Note Tool、改写记忆系统就是作者自述的下一步。【免费下载链接】hello-agents 《从零开始构建智能体》——从零开始的智能体原理与实践教程项目地址: https://gitcode.com/datawhalechina/hello-agents创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考