逐个工具调用,看清 AI 到底改了什么
发布于 2026年7月9日 · 5 分钟
Cockpit 现在会在每次碰文件的工具调用后给项目打快照。打开任意一条回复,像读 git 历史一样读它的变更:一次 Edit、Write、Bash 或 MCP 调用一个条目,每条都是真实的磁盘 diff——按执行顺序排列。
一轮 Agent 对话结束,回复说"完成了——重构了模块、更新了调用方、修好了测试"。十五个工具调用刷过去了。现在只剩一个真正要紧的问题:到底改了什么?
在此之前,诚实的回答是"大概知道"。你可以逐个展开工具调用去读参数,但有几个真实存在的盲区:
- Bash 是隐形的。 一条
sed -i、一个代码生成器、一次会改文件的npm install——工具调用只给你看命令,从不给你看它造成的文件变更。MCP 工具和 Task 子代理同理。 - 参数不等于磁盘真相。 AI 对同一个文件连改三次时,在脑子里回放
old_string → new_string的结果,和磁盘上实际落下的内容会有出入。 git status给的是总和,不是过程。 一轮长对话结束,你拿到的是一坨摊平的大 diff——这个改动是按什么顺序搭出来的、哪一步引入了哪一行,全都没了。
一次工具调用 = 一个 commit
Cockpit 现在会在每次碰文件的工具调用之后给项目拍快照,所有引擎都覆盖——Claude、Codex、DeepSeek、Kimi、Ollama。点开任意回复上的文件变更图标,你会得到一条 git 历史式的时间线:
- 左边:时序。 一次调用一个条目,按执行顺序排列——
[Write] nebula/codes.py、[Bash] npm run build,各带短 hash 和时间。 - 右边:真实 diff。 带每文件 +/− 行数的文件树、左右分栏对比、可折叠未变更段的精简模式。你看到的就是磁盘上发生的——包括 Bash 干的一切。
这是"相信我,我改好了"和能够回放编辑过程之间的差别:先写了新模块,然后逐个改接入方,最后动测试。如果是第 7 步开始跑偏,你能直接看到那一步——它是独立的,而不是被搅进 400 行的最终 diff 里。
为什么这能降低 review 成本
审 AI 的产出正在变成真正的工作量。贵在两点:体量(一句话能产出一大坨 diff)和意图丢失(摊平的 diff 藏起了每一块改动为什么存在)。按调用切分的快照攻的是第二点:
- 每一步都小而自明——工具调用有明确的目的,它的 diff 要么对得上,要么对不上。
- 时序本身携带意图。"这个 import 是哪来的?"看它出现在哪一步就有答案。
- 没人认领的改动会现形:同一时间窗内另一个会话或外部进程改的文件,会带上同期变更标记,而不是悄悄混进来。
提交前你仍然会在 Explorer 的变更 tab 里审最终状态。但当哪里看着不对时,你手里现在有中间帧,而不只有最后一帧。
零配置、全本地、自动清理
没有任何需要配置的东西:
- 快照存在
~/.cockpit/snapshots/下的影子 git 仓库里——项目自己的.git完全不被触碰,.gitignore照常生效(另有.env*、密钥等敏感文件的内置排除)。 - 一切都在你自己的机器上,不上传任何东西。
- 历史会自己保持苗条:每个项目保留 7 天,30 天不活跃整仓移除,超大文件跳过。13 GB 的 monorepo 实测只占约 74 MB 影子存储;之后每次快照约 80 ms。
- 历史会话同样可用——重新打开上周的对话,diff 还在(保留期内)。
升级到最新版本,让 Agent 改点什么,然后点回复上的文件变更图标。细节见文档。