代码评审技能adversarial-review让Claude和Codex互怼抬杠!


本文介绍智能体代码审核系统adversarial-review的工作流程。从加载原则到召唤评审员,从合成判决到最终裁决,揭秘了Claude和Codex如何互相找茬、程序员如何在痛苦中成长的全过程。让你笑着理解这个既折磨人又必要的神奇系统。

大家好,我是一个程序员,一个被代码折磨得快要秃头的程序员。但是今天我要告诉你们一个更可怕的事情——现在连AI都开始内卷了,而且卷得比我们人类还要凶。

事情是这样的,最近我们团队搞了个骚操作,让不同型号的AI互相审核代码。这就像让你家的大黄狗去监督隔壁老王的猫抓老鼠,场面一度十分混乱。这个系统有个装逼的名字,叫做"adversarial-review",翻译过来就是"互相找茬审核系统"。

安装这个技能很简单:

adversarial-review
$ npx skills add https://github.com/poteto/noodle --skill adversarial-review


想象一下,你写了一行代码,然后有两个AI,一个是Claude,一个是Codex,它们开始像在辩论赛一样互相攻击你的代码。这不是科幻电影,这是我们每天都在经历的魔幻现实。

Claude会说:"哥们,你这代码写的什么玩意儿?",Codex会反驳:"不不不,你懂个锤子,这代码明明写得很有创意。"然后它们俩就吵起来了,而我只能像个被家长训话的孩子一样,在旁边瑟瑟发抖。

这个系统的工作流程是这样的:首先,它会加载一堆所谓的"大脑原则",就像我们人类的道德准则,只不过AI的准则是用代码写的。然后它会确定你要审核什么内容,接着它会召唤对面的AI来当评审员,最后它会整理出一个判决书,告诉你代码能不能通过。

这个过程听起来很正经,但实际上就像是在玩狼人杀。你不知道哪个AI是好人,哪个AI在故意找茬,最后出来的结果可能让你怀疑人生。

最骚的是,这个系统明确规定,评审员必须用对面AI的命令行界面来运行,不能用任何内部代理机制。这就好比两个人吵架,必须用对方的母语骂人,谁先用翻译软件谁就输了。这操作简直绝了,我怀疑设计这个系统的人是不是小时候被同学欺负过,长大了要让AI也尝尝互相伤害的滋味。

第一步:加载原则,AI的道德经

首先,这个系统会去读一个叫做"brain/principles.md"的文件。这个文件就像是AI的《论语》,记录了它们做人的基本原则。但是它还不满足于只读这一个文件,它还要顺着里面的每一个链接,把所有相关的原则文件都读一遍。

这就像你去图书馆借一本书,结果图书管理员说:"这本书不行,你得把这本书里提到的所有书都看完才能借。"我当场就想骂人,这哪是看书啊,这是在查三代啊。

这些原则文件里都写了些什么呢?有一些是关于代码应该怎么写的,比如变量命名要规范,函数不能太长,注释要写清楚。还有一些是关于逻辑的,比如代码要符合业务需求,要考虑到边界情况,要有错误处理机制。

听起来很合理对吧?但是当这些原则被不同的AI解读的时候,就会变得特别魔幻。就像我们人类读法律条文,法官读出来的是一回事,律师读出来的是另一回事,普通人读出来的就是"我太难了"。

Claude可能觉得某个原则的意思是代码必须写注释,Codex可能觉得同一个原则的意思是代码要自解释,不需要注释。然后它们就开始互怼,而我就在旁边看戏,顺便祈祷不要波及到我。

这个加载原则的过程,就像是给每个AI发了一本圣经,然后让它们各自解读,最后互相指责对方是异端。这种操作放在中世纪是要烧死人的,现在放在AI身上,它们只会死机重启。

最搞笑的是,这些原则文件还是用Wiki链接连在一起的,也就是说AI不仅要读原则,还要读原则的注释,读注释的注释,读注释的注释的注释。这就像一个无限套娃,你永远不知道底在哪里。

但是没办法,谁让这是系统设计的硬性规定呢?就像你不能跳过老板的邮件不看,AI也不能跳过任何一个原则不读。否则后面审核的时候,人家就会说:"你这个评审不符合某某原则,无效,重来。"

第二步:确定范围和意图,你到底想干嘛

接下来,系统要搞清楚两个问题:你要审核什么?你想达到什么目的?

第一个问题比较简单,就是看你最近改了哪些代码,引用了哪些计划,或者用户说了什么。这就像是警察破案,先看案发现场有什么线索。

第二个问题就有意思了,它要确定作者的意图。注意,这里的意图不是指作者的意图是不是正确,而是指作者想通过这次修改达到什么目的。系统明确说了,评审员只审核代码能不能实现意图,不审核意图本身对不对。

这就好比你说你想减肥,评审员只审核你有没有按照减肥计划去做,不审核你为什么要减肥。就算你是为了参加大胃王比赛而减肥,评审员也不管,只要你按照计划做了,他们就给你点赞。

这个设计其实挺聪明的,因为如果让AI去审核意图对不对,那就没完没了了。AI可能会说:"你为什么要改这个代码?你为什么要用这个算法?你为什么要用这个变量名?"最后你被问得怀疑人生,觉得自己根本不配当程序员。

确定完意图之后,系统还要评估修改的大小。这个评估机制简直比银行审核贷款还严格:

如果修改小于50行代码,涉及1到2个文件,那就是小修改,只需要一个评审员,角色是"怀疑者"。这个怀疑者的任务就是找茬,看你的代码有什么问题。

如果修改在50到200行之间,涉及3到5个文件,那就是中等修改,需要两个评审员,一个是怀疑者,一个是架构师。架构师会从整体架构的角度看你的代码有没有问题。

如果修改超过200行,或者涉及5个以上文件,那就是大修改,需要三个评审员,分别是怀疑者、架构师和极简主义者。极简主义者会看你的代码有没有写得太复杂,能不能简化。

这个分级制度让我想起了看病,小病看门诊,大病看专家,危重病看会诊。只不过这里的病人是代码,医生是AI,而且这些医生还特别喜欢互相拆台。

第三步:召唤评审员,AI大战一触即发

这一步是整个流程中最精彩的部分,也是最容易翻车的地方。系统会创建一个临时目录,用来存放评审员的输出文件。然后它会判断自己是哪个模型,如果是Claude,就召唤Codex的评审员;如果是Codex,就召唤Claude的评审员。

这个"召唤"的过程不是简单地让另一个模型看看代码就行了,而是要用对方的命令行界面来运行。具体来说:

如果你用的是Claude(Anthropic公司开发的AI助手),就要召唤Codex(OpenAI开发的代码模型)的评审员,通过"codex exec"命令运行。

如果你用的是Codex,就要召唤Claude的评审员,通过"claude -p"命令运行。

每个评审员都会收到一个提示,这个提示里包含了:作者的意图、评审员要使用的视角、相关的原则文件内容、要审核的代码。然后评审员要做的就是:找到真正的问题,而不是验证代码没问题;要具体,引用文件、行号和具体的失败场景;给每个问题评级:高(阻止发布)、中(应该修复)、低(值得注意)。

这些评审员会被同时召唤,就像在玩多人游戏一样,大家一起开黑,一起输出。最后每个评审员都会生成一个文件,怀疑者的输出存到skeptic.md,架构师的存到architect.md,极简主义者的存到minimalist.md。

这个过程就像是在组织一场辩论赛,正方是写代码的程序员,反方是三个评审员。而且这三个评审员各有各的立场,怀疑者就是来找茬的,看什么都不顺眼;架构师只看大局,细节不管;极简主义者恨不得你一行代码写完所有功能。

最搞笑的是,这些评审员还是对面模型的,也就是说Claude评审Codex写的代码,Codex评审Claude写的代码。这就像让苹果的用户去批评安卓的手机,让安卓的用户去评价苹果的电脑,场面一度非常欢乐。

而且评审员们是同时工作的,这就像三个人同时在骂你,你都不知道先回应谁。等你把所有的批评意见收集起来一看,可能会发现它们互相矛盾。怀疑者说这个函数太长了,极简主义者说这个函数太短了,架构师说这个函数的位置不对。你站在原地,不知道自己到底该听谁的。

第四步:验证和合成判决,AI法官登场

等到所有评审员都输出完毕之后,系统就要开始干活了。首先,它会检查每个评审员的输出文件是否存在,内容是否为空。如果有任何评审员缺席,它会在最终判决中记录这个失败,而不是悄悄地忽略。

这就像开董事会,如果有一个董事没来,会议记录上必须写上某某董事缺席,不能假装这个人不存在。这种严谨的态度,让我想起了我们公司的考勤制度,迟到一分钟都要写检讨。

检查完文件之后,系统就要开始阅读每个评审员的输出,然后剔除重复的意见。这一步特别重要,因为三个评审员可能会提出相同的问题,如果重复记录,就会显得问题特别多,程序员可能会当场崩溃。

剔除重复之后,系统会生成一个判决书,格式如下:

首先,重申作者的意图,让大家回忆一下一开始想干什么。

然后,给出最终的判决:PASS(通过)、CONTESTED(有争议)、REJECT(拒绝)。

通过的标准是没有高严重度的问题。有争议的标准是有高严重度的问题,但是评审员之间意见不一致。拒绝的标准是有高严重度的问题,而且评审员们一致认为有问题。

接下来,列出所有的发现,按严重度排序,高优先的先列出来。每条发现都要包括:问题的描述(附上文件和行号)、是哪个评审员提出的、违反了哪条原则、建议怎么改。

最后,还要列出1到3个评审员认为没问题的地方,肯定一下写代码的人做得好的地方。

这个判决书的格式,简直比法院的判决书还规范。我怀疑设计这个系统的人是不是当过法官,或者至少看过很多法律文书。每个细节都考虑到了,连肯定成绩的部分都有,简直是人性化的典范。

最妙的是这个判决逻辑,它考虑到了评审员之间的分歧。如果评审员们意见一致说代码不行,那就真的不行;如果评审员们有分歧,那就说明代码有争议,需要进一步讨论;如果大家都觉得没问题,那就通过了。

这个逻辑比很多公司的评审制度都合理。现实中经常出现的情况是,领导说不行,大家都不敢反对,最后明明没问题的项目也被毙了。而这个系统至少给了程序员一个申诉的机会,毕竟评审员之间也有分歧。

第五步:做出判决,人类的最终裁决

最后一步,也是最关键的一步,就是人类的最终裁决。系统明确说了,在综合了评审员的意见之后,你要运用自己的判断,决定接受哪些意见,拒绝哪些意见。

为什么要有这一步?因为评审员们是故意设计成爱找茬的,它们提出的意见不一定都有道理。有些可能是误判,有些可能过度解读,有些可能把风格问题当成了实质问题。

这就像你去相亲,七大姑八大姨给你提了一堆意见,说这个人学历不够高,那个人工作不够好,还有一个人长得不够帅。但是最后要不要和谁在一起,还是得你自己拿主意。你不能因为大姨说这个人不行,你就真的不考虑了,说不定这个人就是你的真命天子呢。

所以在这个步骤里,你要根据作者的意图和大脑原则,决定每条意见是接受还是拒绝,并且给出理由。这个理由要简洁明了,一句话就够了。

比如,如果有个评审员说:"这个变量名太短了,看不懂",你可以拒绝这个意见,理由就是:"这个变量是循环计数器,用i是行业惯例,没问题。"

如果有个评审员说:"这个函数没有错误处理",你可以接受这个意见,理由就是:"确实需要加try-catch,防止程序崩溃。"

最后,把这些判断追加到判决书后面,形成完整的评审报告。这个报告既包含了AI的意见,也包含了人类的判断,是一个集体智慧的结晶。

这个设计让我想起了古代皇帝批奏折,大臣们先提出意见,然后皇帝批个"准"或者"不准"。只不过这里的皇帝是程序员,大臣是AI,奏折是代码,批阅的工具不是毛笔,而是键盘。

实战演练:一个代码审核的完整流程

好了,理论讲完了,我们来看一个实际的例子,感受一下这个流程有多么魔幻。

假设我用Claude写了一段代码,功能是计算两个数的和。代码很简单:


def add(a, b)
  return a + b
end

我提交代码的时候说,我的意图是写一个简单的加法函数。根据规则,这个修改很小,只需要一个怀疑者评审员。因为我是Claude,所以要召唤Codex的怀疑者。

Codex的怀疑者收到我的代码和意图之后,开始评审。它的视角是怀疑一切,所以它开始找茬:

"这个函数没有类型检查,如果传入的是字符串,会直接拼接而不是相加。严重度:高。违反原则:'永远假设用户会传入错误的数据类型'。建议:添加类型检查,如果不是数字,抛出异常。"

我收到这个意见,觉得有道理,确实应该加类型检查。于是我把代码改成:


def add(a, b)
  raise "参数必须是数字" unless a.is_a?(Numeric) && b.is_a?(Numeric)
  return a + b
end

然后我提交新版本,这次修改稍微大了一点,需要两个评审员:怀疑者和架构师。

怀疑者(这次是Claude的怀疑者,因为我是Codex)说:"这个函数现在有类型检查了,很好。但是异常信息没有指明哪个参数有问题,用户不知道怎么改。建议:分别检查每个参数,给出具体提示。"

架构师(也是Claude的)说:"这个函数功能单一,位置合理,没问题。但是考虑到扩展性,未来可能需要支持更多运算,建议把加法逻辑封装成类,方便扩展。"

我收到意见,觉得怀疑者的意见很对,架构师的意见过度设计了。于是我决定接受怀疑者的意见,拒绝架构师的意见。我的判决是:

接受怀疑者的意见,添加具体的错误信息;拒绝架构师的建议,因为目前只需要加法功能,过度设计会增加复杂度。

最后我再次修改代码,变成:


def add(a, b)
  raise "第一个参数必须是数字" unless a.is_a?(Numeric)
  raise "第二个参数必须是数字" unless b.is_a?(Numeric)
  return a + b
end

提交之后,系统再次审核,这次所有评审员都觉得没问题,终于通过了。

整个过程下来,我改了三版代码,被两个AI轮番轰炸,最后写出了一行比我命都长的加法函数。但是不得不承认,这代码确实比一开始健壮多了。这就是adversarial-review的力量,让你在被折磨中成长,在被打击中进步。

为什么这套系统既痛苦又必要

说到这里,你可能会问,为什么要搞这么复杂的审核系统?直接让程序员自己写好代码不就行了?

问得好。这个问题的答案,和我们为什么要写单元测试、为什么要做代码评审是一样的:因为人类会犯错,而且经常犯错。

研究表明,程序员每写10行代码,平均会犯1个错误。也就是说,一个1000行的项目,里面可能有100个bug。这些bug有些是小事,有些可能导致系统崩溃,数据丢失,甚至造成经济损失。

而AI审核员,特别是不同模型的AI审核员,可以帮我们发现很多人类发现不了的问题。因为它们看待代码的视角和人类不同,它们不会累,不会困,不会因为和程序员关系好就放水。

更重要的是,不同模型的AI互相审核,可以避免单一模型的偏见。就像我们找律师打官司,不会只找一个律师,而是会找几个律师一起讨论,因为每个律师的看法可能不同,综合考虑才能得到最全面的意见。

Claude可能更注重代码的逻辑性和可读性,Codex可能更注重代码的性能和效率。让它们互相审核,可以取长补短,让代码既好读又好用。

当然,这个过程对程序员来说是很痛苦的。想象一下,你辛辛苦苦写了一天的代码,结果被三个AI轮番轰炸,说你这里不行那里不对。这种打击感,比你女朋友说你胖还要难受。但是当你按照它们的意见修改完代码,上线运行了一个月都没有出bug,你就会感谢这些AI的毒舌。

就像健身一样,过程痛苦,结果美好。adversarial-review就是代码界的健身房,它让你在汗水中成长,在痛苦中进步。每次审核都是一次锻炼,每次修改都是一次增肌。最后你写出来的代码,就像健身练出来的肌肉,结实耐用,经得起考验。

所以,如果你是一个程序员,不要害怕这个审核系统,要拥抱它。把它想象成一个免费的私人教练,专门帮你提升代码质量。虽然它说话难听,虽然它爱找茬,但是它的目的是好的,是为了让你写出更好的代码。

最后,用一句话总结这个系统的精髓:AI审核员就像你妈,永远觉得你做的不够好,但是永远是为了你好。接受它的意见,修改你的代码,然后看着你的程序一天比一天健壮,这种感觉,比吃了蜜还甜。

英文Slug: ai-code-review-adversarial-process-humorous-explanation