终端审查 AI 代码:按函数确定优先级
文章结合开源工具 Klaub,提出按函数阅读改动、用确定性排序安排审查顺序,并要求智能体解释实现选择。工作流针对多文件 AI 改动难以快速抓住重点的问题。
AI 深度解读
Claude Code 或 Codex 一次改完十二个文件,写代码省下的时间,很可能又花在读 git diff 上。作者做的终端工具 Klaub,试图把这件事拆开处理:按函数读变更,用固定规则安排阅读顺序,再让 Agent 解释技术选择、补充执行流程。
它最有价值的主张,是把审查注意力放回具体行为:哪些接口变了,谁会调用它,错误有没有被忽略,权限检查是否缺了一层。但规则评分和 Agent 自述都不能替你下结论,这也是理解这套工作流的前提。
先读哪个函数,比先看哪个文件更重要
作者认为,AI 代码审查的困难之一,是变更缺少足够清楚的说明。同事提交的 PR 通常有描述、历史记录,也有人可以追问;Agent 留下的往往是一段你已经粗略扫过的聊天记录。
原文引用 Sonar 的 2026 State of Code 调查:超过 1,100 名开发者中,96% 没有完全信任 AI 生成代码,只有 48% 表示提交前总会验证,38% 认为审查 AI 代码比审查同事代码更费力。作者也承认,Sonar 销售代码验证产品,而且这些是受访者自报数据,因此只能作为信号,不能当成审查成本的精确测量。
Klaub 的切入点是改变阅读单位。Agent 把一个函数从头改到尾,行级 diff 容易变成大片红绿色;把修改前后的完整函数放在一起,更容易看清输入、分支和返回值之间的关系。
接着,它解析仓库,匹配两个版本里的符号,把发生变化的函数、类和文件排进 P0 到 P3 的队列。Python、JavaScript、TypeScript(包括 TSX)、Rust、Go 和 Java 支持完整语义分析;其他文件按整文件展示,并进行文本比较。
示例仓库里,一个支付函数获得 83 分,被排到 P0:
- 公共符号声明发生变化,加 25 分。
- 外部入口,也就是路由,可以到达它,加 20 分。
- 涉及支付敏感区域,加 15 分。
- 丢弃错误,而且被标记为此次变更新引入的问题,加 15 分。
- 没找到关联测试,加 8 分。
按 w 可以查看评分依据。这里没有模型参与,同一份变更会得到相同队列。
这个分数决定先读哪里,不代表问题有多严重。
P3 里仍可能藏着重要问题。按 i 可以查看函数的「契约」:修改前后的参数、服务的路由、抛出的异常、直接调用者,以及能够到达它的入口。这里的契约可以理解为:别人怎样使用这段代码,它又向别人承诺了什么。
调用链的每一跳还会标记为 resolved、heuristic 或 unresolved,分别表示已解析、启发式推断和未解析。没有找到调用路径,不能据此断言没有代码依赖它。
让 Agent 解释选择,重点追问它省略了什么
diff 擅长展示代码增加或删除了什么,却不容易回答:为什么换存储格式,为什么吞掉异常,为什么这次只检查登录状态?
Klaub 的 Decisions 窗口让 Agent 把这些选择整理成 JSON。文件不存在时,工具把请求放进 Agent 输入框,由用户按 Enter 发送。
每张决策卡需要交代上下文、选择、理由、替代方案及其取舍、影响,以及需要审查者回答的问题。它还区分:这是提交信息、注释或测试中明确写出的决定,还是根据 diff 推断出来的决定。后者尤其适合追问,因为此前可能没人解释过。
作者的示例仓库列出了五项决策,其中两项需要停下来检查。第一,支付服务调用失败后,异常被捕获并忽略,订单可能像支付成功一样保存。第二,新端点允许列出任意用户的订单,只检查调用者是否登录,没有检查调用者是不是订单所属用户。
这两类问题都和「缺少检查」有关,单看新增了哪些行,确实容易漏掉。
审查时,a 表示批准,d 表示拒绝,c 用于评论,方向键切换卡片。结束后,拒绝和评论过的项目可以汇总成一条简短指令交回 Agent。
不过,Klaub 验证的是文件格式、引用以及它是否对应当前代码快照。校验失败或属于其他代码状态的内容不会展示,通过校验也不等于决策说明符合事实。
Agent 在解释自己的工作,可能漏掉选择,也可能给出听起来合理的理由。决策卡适合带着你找证据,不能代替证据。
在当前代码旁边追问,执行图也要逐步核对
要把 Agent 和阅读窗口放在一起,可以通过 Klaub 启动它:
klaub wrap claude # or: klaub wrap codex
关键是 wrap:它启动独立会话,并在旁边放置阅读窗口。Shift+→ 切到阅读器,Shift+← 返回 Agent。
在阅读器任意界面按 t,工具会把当前对象的说明放进 Agent 输入框。内容可能包括变更单元、修改方式、屏幕上的代码行和 git diff,也可能是整张决策卡或流程图步骤。用户切过去补上问题,再按 Enter。
输入内容会要求 Agent 在收到问题前不要修改或运行任何东西。工具通过 bracketed paste 发送单行文本,自己不按 Enter。普通发送会先展示目标和确切文本;t 默认跳过确认,可通过 ask_agent_confirms = true 开启确认。这是输入交接机制,不能理解为对 Agent 执行能力的强制隔离。
Flow 窗口则用图展示执行路径,每个步骤一个框,标出变更涉及的步骤和解析确定程度。用户可以用自然语言指定关注点、选择从高层组件到具体函数的细节程度,也可以要求贯穿前端与存储。
图仍由用户自己的 Agent 写成文件,保存后显示。Agent 描述的路径被当作假设;如果步骤引用了索引中不存在的符号,工具会展示差异。符号存在,也仍需核对调用关系和实际条件。
安装与首次审查使用下面这组命令:
brew install myrk-kale/tap/klaub
cd my-project
klaub review
最后一行默认打开相对 HEAD 的变更,优先显示排序靠前的项目;按 ? 查看快捷键。也可以使用 cargo install klaub --locked,README 还提供发行归档和安装脚本。工具采用 MIT 许可证,支持 macOS、Linux,需要 Git 在 PATH 中,目前不支持 Windows。
目标 Agent 包括 Claude Code、Codex CLI 和 Aider;任何交互式终端程序都可以通过 klaub wrap 启动,klaub review 也能脱离 Agent 单独使用。
我的判断
我赞成把「阅读顺序」单独做成可解释的工具。公共接口变化、入口可达性、敏感区域和错误处理,都是有依据的关注点。规则固定,也方便团队讨论某条加分是否合理。
但原文没有给出与普通 diff、IDE 审查或第二个模型审查的耗时和检出率对照。完整函数更好读、风险队列更省力,目前仍是作者的经验判断。演示里的 83 分也不能推广为所有项目通用的风险尺度。
固定规则能识别的范围同样有限。原文列举了吞掉错误、动态文本构造查询、代码中的秘密信息、循环内 I/O、动态代码执行、unsafe 块和关闭证书检查。涉及业务意图的问题,仍需要理解产品的人判断。
Klaub 自身不发送网络请求,没有遥测,也不需要账号;审查记录与回答保存在仓库的 .klaub/ 下。模型只参与决策说明和流程图生成,调用的是用户选择的 Agent。因此,工具本地运行,不代表整套工作流一定离线,Agent 怎样处理代码要另算。
第二个模型、规则队列和测试可以组合使用:前者提供另一种判断,队列安排注意力,测试验证具体行为。原文没有证据支持用其中一种取代其他方式。
能拿来做什么
- 审查 Agent 修改的 JavaScript、TypeScript 或 TSX 时,可以先看完整函数的输入、异常和返回值,再沿直接调用者与入口核对影响范围,尤其关注公共签名变化。
- 对涉及订单、支付或用户数据的 Node 接口,可以要求 Agent 写清错误如何传播、调用者能访问谁的数据,并把解释逐项对应到代码和测试。
- 在终端里边读边追问时,可以用
klaub wrap claude或klaub wrap codex保留当前审查上下文,提问时明确指出要解释的分支或缺失检查。 - 首次试用时,可以拿一份熟悉的 Git 变更检查队列是否符合项目实际,并核对
.klaub/的记录和 Agent 的数据处理方式,再决定是否纳入日常流程。