先说结论:我是带着踩「又一个 agent 框架」的心情去的,结果被一篇 PR 复盘按住了。
no_human 这项目,通稿和实测之间的落差是负的。实测比宣传好看。🙃
一句话说它是干什么的:本地跑,MIT,用你自己的 Claude 凭据,编排器把工单推到「已评审的 pull request」为止,从不自动合并。「已评审」到「合并」那一下,必须人来按。
这年头打着 agentic 旗号的东西,卖点清一色是「你不用管了」。它反过来,把「你必须按那个按钮」写进设计里。
这个边界,先记一功。
但我真正想聊的不是这个。
是 PR #229。
issue #114 第三阶段,原计划给编码者加个符号服务器,跳定义、找引用、悬停看类型。作者没直接建,先写了个脚本,量一量导航到底划不划算。
阈值事前登记在 15%。数字还没出来就定好,防的就是后面照着结果调参。
第一次跑:27.6%,判定 PROCEED。看着这功能值得做。
然后他注意到了 .md——整份语料里按读取量最大的扩展名。而没有任何符号调用能回答一个关于 README 的问题!
把语言限定到符号服务器真正支持的白名单,同一份语料,读数掉到 10.4% 和 13.7%。
判定反转。
这还只是第一层。更深的一层在这儿:脚本把最强的信号类别定义成 SYMBOL_QUERY_TOOLS = {Grep, Search}。
可 no_human 的编码者从来不发出这两个调用。它走 Bash。
车队数据库的真实计数:
Bash 115,776
Read 35,557
Edit 18,425
Write 3,010
Grep 0
Glob 0
Search 0
含 grep/rg/ag/ack 的 Bash 调用 50,459
脚本以为自己最强的那个信号类别,结构上是空的。
它就在这个空类别上,自信地渲染出了一个 HALT。
上个月我差点信了一个结构类似的数字。不展开了,这毛病我有。
修复是按二进制从 shell 命令里把搜索抽出来,每个二进制配各自的选项表。-r 在 grep 里不取值,在 ripgrep 里是 --replace,一张表糊弄不过去。
零值一律按失败关闭:一个有读取却没有搜索的语料,NoSearchChannel 直接拒绝。缺失的通道是仪器的缺口,不能当成关于代理的证据。
修完之后 symbol_lookup 从 0 升到读取量的 15.6%,HALT 反转为 PROCEED。原本结构上为空的那一类,成了最大的单一贡献者。
而且修完之后输出还挂着警告:结果变不稳健了。6000 字符处重判得 PROCEED,24000 字符处得 HALT。
这个警告我认!
一个把自身不稳健写在脸上的脚本,比一个递给你一个漂亮数字的脚本可信得多。
文章里那条原则是「如果验证机制位于代理的写入面之内,它就不是验证机制」。我补半句:如果验证机制自己的仪器没人验过,那它也不是验证机制。就这么简单。
顺手再过两个具体的。
PR #164 有个设计决定我很喜欢:沉默表示「没有运行」,不表示「干净」。检查器没装、崩了、输出解析不出来,全是 ran=False,渲染成空;只有真正跑完并且确实没问题,才渲染 net-new 为 0。
这两件事在别的工具里通常被压成同一个绿色的 0。那个绿色骗过我,不止一次 😑
另一个是 PR #221 的措辞事故。原提示词写的是「你对 X 的编辑引入了 N 个诊断」。维护者两下就把这句打翻。
第一下,mypy <file> 会跟随 import。让 app.py 前后 md5 完全相同、lib.py 新增一个错误,钩子照样告诉你 app.py 这次的编辑引入了它。
第二下,Bash 不在 _EDIT_TOOLS 里。sed -i、patch、ruff --fix、black 全部不可见,它们弄坏的东西,会在下一次 Edit 的时候被算到那次编辑头上。
最后改成「N 个位于 X 之上或从 X 可达的诊断,它们在该文件上次被检查时未被报告」。两种可能的误导方式,直接写在编码者能看到的那段文本里。干净。
把丑话说在前面:这次我确实没什么营销话术可踩。
唯一有落差的地方还写在它自己的 changelog 里。0.2.1 到 0.2.3,打包的桌面应用能打开 PR,但落不了地。合并门禁把冻结的二进制当成 Python 解释器调用,于是每一次 nh approve、连带面板上那个 Approve,都在测试步骤上失败。
能开 PR 却不能落 PR 的流水线,不叫 90% 可用。
它对唯一需要人的那一步失效了。而那一步,恰恰是它整个设计的立足点。
还有两条局限得说清楚,不然容易当信仰用。
评审者本身就是一个模型。项目给了自己的确认运行数字:19 个预埋缺陷召回 15 个,10 个对照的特异度是 7。有用的门禁,不是证明,误报属于常规,你得预留分流的成本。
另外「不同模型」是默认值,不是不变量。你把评审者和实现者配成同一个模型,整个设计依赖的那个属性就安静地没了。
这个坑特别安静!安静到不会有人报错。
锐评评分卡:这钱花得冤不冤?本地跑、MIT、不托管、用你自己的 Claude 凭据——严格说没有「这钱」两个字,你要算的是自己那份配额账。
值不值得现在跟:手上的活是范围清楚的 bug 修复、测试缺口、跨仓库的重复性维护,值得。工单是「把架构重构一下」这种,项目文档自己就写了不适合,它会给你一个结构化的升级加一个具体问题。
那不是它不行,是它不肯演。
最后一件事。作者自己说,自建代理工具的人应该把复现门偷走,那东西只是个二十行的概念。我同意。
但抄之前先回答一个问题:你的编码者是用 Grep 检索的,还是用 Bash 检索的。
这个想不清楚,那二十行白抄。
