原来 Claude Code 最厉害的工具,一行代码都不写

Claude Code 最厉害的工具,一行代码都不写

上周帮同事看一个 bug,他用某个 Agent 改了一个 Vue 组件的 if 条件。打开 git diff 一看,整个文件被重写了------import 重新排序,单引号全变双引号,两个不相关的注释被删掉了。实际有用的改动就一行,但 diff 有 87 行。Review 的时候根本看不出他到底改了什么。

后来我自己用 Claude Code 改了一个类似的条件。同样的任务,它的 diff 只有 3 行:旧条件删掉,新条件加上,完事。周围的代码一个字没碰。

我当时觉得这可能是模型性格差异------有的模型比较谨慎,有的比较奔放。但后来我把几个主流 Coding Agent(Pi、Codex、DSH、opencode)的工具定义全拆了一遍,才发现这不是性格问题,是工具设计问题。

Claude Code 的工具集里藏着一批不写代码的工具------它们不改文件、不跑命令,做的事情是约束 Agent 自己的行为。有的让 Agent 在执行前必须停下来出方案,有的强制它改代码前必须先引用旧内容,有的给无所不能的 Shell 套上权限锁链。

这批工具,才是 Claude Code 和其他 Agent 拉开差距的地方。

两类工具:做事的 vs 管事的

Claude Code 的工具列表(官方参考,数量随版本变化)按功能分,就是一堆"读、写、执行"。但换一个角度------按作用对象分------会看到一个完全不同的结构:

作用于代码和环境 作用于 Agent 自己
例子 ReadGrepEditBash PlanModeAskUserQuestionPermissionWorktree
做了什么 让模型能完成任务 让模型约束自己的行为
别的框架有吗 都有 几乎没有

右边那一列才是 Claude Code 可控性的真正来源。

Pi 只有 4 个工具(read、bash、edit、write),全是左边那一列------给模型工具,让它自己干。opencode 在 Prompt 里写"You MUST iterate and keep going until the problem is solved"------不解决不罢休,但也没有任何"停下来想一想"的机制。Claude Code 的思路不同:给模型工具的同时,给它装刹车------有些操作必须先读后写,有些操作必须等人批准,有些操作根本不让它做。

下面挑三个最值得说的设计,每个背后是一个独立的判断。

一、PlanMode 不是"建议",是断路器

EnterPlanMode 这个工具什么都不做。它不改代码、不读文件、不跑命令。它只做一件事:让 Agent 停下来,切到只读模式,出完方案等人批准了再动手。

问题来了:这事为什么不能在 Prompt 里说一句"复杂任务请先规划"?

因为 Prompt 是建议,Tool 是机制。

模型在上下文短的时候可能遵守 Prompt 里的"请先规划"。但上下文一长、任务一复杂,Prompt 约束最先被模型丢掉。而 Tool 调用是显式的、可被 Harness 拦截的------模型调用 EnterPlanMode,Harness 就切换状态;在 ExitPlanMode 拿到用户批准之前,写操作直接不执行。

本质上,PlanMode 是一个断路器------Agent 自己决定合上开关,Harness 负责在条件满足前不让电流通过。这个设计把"什么时候该谨慎"的决策留给了模型,把"怎么执行谨慎"的控制权交给了 Harness。

其他 Coding Agent Harness 很少这么做。我对比过几家主流的 System Prompt 和工具定义:Pi 只有 4 个工具 154 行 Prompt,完全没有"规划"的概念;Codex 10 个工具,也没有显式的规划工具;opencode 在 Prompt 里写"You MUST iterate"让模型死磕到底,但没有任何机制让它先停下来规划。PlanMode 做成 Tool 这件事,我目前只看到 Claude Code 一家在做。

二、Edit 的 old_string:不是查找替换,是安全机制

Edit 工具的接口很简单:给一段旧内容、一段新内容,匹配上了就替换。

但如果你仔细想,这个设计解决的不是"怎么改文件",而是"怎么防止模型乱改文件"。

Agent 改代码有两条路:

整文件重写 局部精确替换
做法 模型输出整个文件的新版本 只提供要改的那一小段
风险 改一个 if 可能顺手重排 import、改缩进、丢注释 改动范围天然最小
diff 一大片,review 困难 干净,一眼能看出改了什么
前置要求 不需要精确读取旧内容 必须先读到真实的旧内容

Edit 强制走了第二条路。模型不能凭空生成新内容------它必须先把真实的旧内容填进 old_string,这意味着必须先 Read。如果文件已经被改了、old_string 匹配不上,Edit 直接报错中止,而不是静默覆盖。

这个设计把"先读后改"的认知流程焊死在了工具的接口契约里。不靠模型自觉,靠接口强制。

你可能会问:Bash 不是能执行 sed 吗?为什么不直接用 Bash 改文件?

能,但 Claude Code 的 System Prompt 明确引导模型优先用 Edit。因为 Bash 改文件没有 old_string 这种"你必须先知道旧内容才能改"的约束------sed -i 's/old/new/' 不需要知道上下文,匹配上就替换,不管那个 old 是不是你以为的那个 old。

Edit 的 old_string 本质上是一个乐观锁:我先读到了什么,我就只改什么。 世界变了(文件被别人改了),我就停下来。

对比另外两家就很清楚。Codex 用的是 apply_patch------模型生成自由格式的 patch 文本,Harness 去 apply。patch 可以包含任何改动,模型不需要先精确引用旧内容,它可以"描述"要改什么而不是"引用"旧内容。Pi 用 edits[] 数组------一次调用可以同时改多个不重叠的位置,效率更高,但也意味着一次出错影响面更大。

三种设计,三种对模型能力的信任度:

  • Pi:信任模型能一次改对多个位置,给批量能力
  • Codex:信任模型能生成正确的 patch,给自由格式
  • Claude Code:不信任模型凭空生成改动,要求它必须先读、再引用、再改

三、Bash:能力无限,所以必须受限

Bash 是 Claude Code 工具集里最矛盾的。

没有它,Agent 连测试都跑不了------Git、npm、编译器、数据库客户端,所有环境能力都通过 Bash 暴露。但有了它,Agent 理论上可以做任何事:curl 发数据到外部、npm install 执行 postinstall 脚本、git commit 触发 pre-commit hook。

Bash 的能力边界是整个操作系统,但安全边界必须远小于此。

各家 Harness 对这个矛盾的处理方式差异极大。Pi 的 Bash 只有 2 个参数(command + timeout),没有权限控制、没有审批、没有沙箱------完全的 YOLO 模式,信任模型也信任用户。DSH(DeepSeek Harness)走到了另一个极端:Bash 工具有 7 个参数,每个调用必须声明 sandbox_permissionsworkspace-write 还是 danger-full-access)和一句 justification 解释为什么要执行,被拒绝了可以升级权限重试。

Claude Code 站在中间------不像 Pi 那么放飞,也不像 DSH 那么重。它的防线是三层叠加:

  1. 命令分级 :常见只读命令(lsgit statuscat)自动放行;写操作和未知命令弹确认
  2. 执行链审查 :不只看命令本身,还看管道、子命令、alias、脚本调用------git commit 看起来只读,但 pre-commit hook 可能执行任意脚本
  3. 沙箱兜底:部分部署环境下 Bash 运行在受限沙箱中

但这些防线都不完美。精心构造的命令可以绕过静态检查。Bash 的安全性最终依赖的是:模型判断力 + 用户警觉性 + Harness 兜底,三者缺一不可。

这也是 Claude Code 在 Bash 上最大的 trade-off:给模型一个无所不能的工具,但用所有其他机制来限制它什么时候用、怎么用。 给一个受限的 Edit + 一个受审的 Bash,而不是给一个无所不能的 FileEditor。

工具设计救不了的事

写到这里容易给人一种印象:工具设计够好,Agent 就可控了。

不是。

工具设计解决的是结构性约束 ------哪些操作必须先读、哪些必须等人批准、哪些互相隔离。它解决不了模型在约束内的决策质量

实际踩过的坑:

  • 模型该 Grep 搜内容的时候用了 Glob 搜文件名,搜不到
  • 模型跳过 Read 直接 Edit,old_string 不匹配失败,再 Read 再 Edit,绕了一圈
  • 开了三个子 Agent 并行,三个结论互相矛盾,主 Agent 不知道怎么仲裁

这些问题不是工具设计的锅,是模型推理能力的边界。Claude Code 选择了"20+ 工具 + 分层约束"的路线,给了模型更大的灵活性,也给了更大的犯错空间。

一句话概括这个 trade-off:工具架构决定了可控性的上限,模型能力决定了下限。 底层模型够强时,这套架构能释放出远超简单工具集的效果;模型在决策点上犯糊涂时,再好的工具分层也兜不住。

附:完整工具速查

层次 工具 作用
感知 Glob Grep Read LSP 按路径 / 内容 / 语义查找和读取,零副作用
行动 Edit NotebookEdit Bash Monitor 修改文件、执行命令、监听进程
控制 AskUserQuestion EnterPlanMode ExitPlanMode Skill 约束 Agent 行为:询问、规划审批、复用流程
编排 Agent Task* TodoWrite TaskStop/Output 子 Agent 委托、任务状态管理
隔离 EnterWorktree ExitWorktree Git worktree 隔离并行修改
扩展 MCP 资源读写、SendMessage ListAgents 外部资源、Agent 间通信
交付 Artifact SendUserFile PushNotification 产物发布、文件交付、推送
定时 Cron* ScheduleWakeup 会话内定时与唤醒
其他 ReportFindings SendFeedback RemoteTrigger ShareOnboardingGuide EndConversation 审查报告、反馈、远程例程、会话控制

参考资料

相关推荐
老孙讲技术2 小时前
把园区几百路摄像头收进值班台账:bindDevice 入账与 listDeviceDetailsByPage 翻页
后端·物联网·音视频开发
parade岁月2 小时前
为了给表格加虚拟滚动而选了 vxe-table?也可以考虑下这个
前端·vue.js
用户7813667114452 小时前
emplace_back vs push_back 详解
后端
老孙讲技术2 小时前
把没网没电的户外点位接进出画值班台:unBindDeviceInfo 核 SIMCard 与 bindDeviceLive
后端·物联网·音视频开发
打呵欠的猫2 小时前
一个 Hook 让 AI 每次写文件前自动检查编码规范,违规代码再也提交不进来
前端·ai编程·代码规范
万物智能2 小时前
硬件调试三板斧—【万物智能之开源鸿蒙OpenHarmony系统实战开发系列教程】
后端·架构
恋猫de小郭2 小时前
Android 17 + OkHttp 5.5.0 ,全新 ECH 下你的 HTTPS 域名可以请求时被安全隐藏
android·前端·flutter
后除3 小时前
从零到一: 创建一个 TypeScript 7 项目
前端·webpack·typescript
lerhxx3 小时前
我用 R3F 手搓了一个能走进去的 3D 迷宫简历(上):从选型架构到迷宫生成算法
前端·javascript·three.js