一份合约,所有模型:AI编码代理的操作标准
本文介绍了一种为AI编码代理制定操作标准的方法,将模型的行为规范(如沟通方式、完成证明、分析深度)与能力分离。作者通过一个名为“操作标准”的文档,将顶级模型的行为模式移植到低端模型,显著缩小了可见质量差距。文章详细阐述了标准的核心支柱、双重加载机制、安全完成门控以及分层配置策略,并强调了验证运行时加载正确性的重要性。
2026年7月13日 · 14分钟阅读
我想分享我最近做的一项工程,它改变了我对AI编码代理的思考方式。起初只是随口问了一个天真的问题:“我能不能让Sonnet和Opus像前沿模型那样表现?”结果却得到了比问题本身更有价值的答案。
简而言之:你无法让一个较小的模型变得和较大模型一样强大。这是权重决定的,没有提示词能移动权重。但能力并不是区分优秀代理回合和平庸代理回合的唯一因素。另一半是“行为规范”:代理如何沟通、何时停止、如何证明其工作、在决定前分析多深。而行为规范是完全可移植的。你可以一次性写下来,作为系统提示层应用,然后每个模型层级——无论是昂贵的还是便宜的——都开始按照同一份合约运作。
本文即阐述这一论点并给出蓝图。所有内容都可适应你自己的技术栈;我会指出可复用模式所在,以及我的具体细节仅供示意。
问题陈述
我运行着一个相当庞大的代码库:一个基于区块链的金融协议、二十多个后端微服务、几个Next.js前端、智能合约以及一个Kubernetes集群。我主要通过Claude Code配合一组专门的子代理完成工作。在任何一天,一个架构代理运行在最强大的模型上,一个实现代理运行在中档模型上,一个快速研究代理运行在小型模型上。三种不同的智能,同一个代码库,同一套标准。
摩擦从来不是便宜模型笨。而是便宜模型的行为方式不同。它会宣布任务“完成”而不运行测试。它会在最终消息中先抛出一堆实现细节而不是答案。它会仅凭一次grep就做出更改,而不追踪影响范围。它会中途停止,问一个本可以自己解决的问题。昂贵的模型默认做对了这些事;便宜的则需要被告知。
很长一段时间,我把这视为使用便宜模型的不可避免代价。那是错误的框架。我想要的行为不是智能。它们是行为准则。而行为准则可以被指定。
核心思想:行为规范不是能力
这个区分是整个论点,所以让我精确表述。
能力是模型能搞定的东西:困难的推理、新颖的综合、在脑海中持有大型问题的能力。它存在于权重中。提示词无法添加它。任何向你推销“让GPT-3.5和GPT-5一样聪明的系统提示”的人,都是在卖虚无。
行为规范是模型如何围绕其拥有的能力来行事:沟通合约、完成的标准、端到端追踪变更后再承诺的纪律、不停止的规则。这些都不是智能。它们全部可以用文本指定。而且关键在于,当一个有能力的模型已经做对了这些事,那是因为它被训练成这样,这意味着同样的行为可以被教导给能力较弱的模型,从而缩小大部分可见的质量差距,尽管底层智能差距依然存在。
所以目标从来不是“让小型模型变聪明”。而是:让每个模型,无论其层级,都遵守一份操作合约。一个中档模型的回合,如果以结果开头,用证据支持每个完成声明,在决定前追踪,并且不提前停止,那么从每个外部可观察的指标来看,就是前沿标准的回合。你之所以使用真正更大的模型,是因为任务的正确性上限需要额外能力,而不是为了基本的专业行为——那些你可以标准化。
写下标准
这一切的核心是一个我称之为“操作标准”的单一文档。它大约有十几个部分,将合约编码为可强制执行的行为而非感觉。支撑支柱如下:
结果先行。最终消息是读者对工作的第一眼:它开头给出答案,然后支持它。可读性优于简洁:你通过删除不改变读者下一步行动的细节来缩短内容,绝不压缩成片段和箭头链。读者需要的一切都在最后那条消息里。
用工件证明完成。没有“应该能用”,没有“看起来不错”。每一个完成/修复/通过声明都带有提交哈希、测试输出、退出代码或文件列表。编排器在信任完成声明之前,自己重新运行验收命令。它不代理的话。
深度优先决策,绝不凭直觉。在决定之前,追踪跨领域变更经过其触及的每一层:模式、数据访问、领域、应用、API合约、每个前端、异步管道、链、迁移、测试。绿标类型检查对运行时或合约涟漪毫无证明力。
不提前停止。对于跟随请求的可逆操作,请继续。在结束一个回合之前,重新阅读最后一段:如果它是一个计划、一个问题或一个“我下一步做X”的承诺,现在就做那个工作。只有当任务完成或确实被用户阻塞时才停止。
做最简单有效的事。没有未请求的功能、重构或抽象;没有对不可能状态的防御性验证,同时在关键路径上使用带类型的错误进行安全失败,如资金和面向用户的显示。
披露每一个诚实的发现,不设上限。绝不为了整洁而修剪长尾的注意事项。一个总是报告“大约两个”发现的报告,本身就是披露不足。
这里我想强调一点,供任何采用此方法的人参考:我并不是凭感觉发明这些片段。行为暗示、确切措辞——吸引模型走向这种行为——来自于模型供应商自己发布的迁移和提示指南。前沿模型默认表现出这些行为;供应商记录了确切的措辞以将其灌输给不这样做的模型。我提取了那些措辞并组织成一份合约。这种基础正是它实际有效的原因,而不仅仅是读起来不错。当你构建你自己的时,从你的供应商指南中获取片段,而不是从博客文章的意见(包括本篇)。
两个渠道,使其不可跳过
一个没人加载的标准就是装饰。我通过两种方式应用它,使其无论是否有人记得选择加入都存在:
启动时,作为追加的系统提示文件。一个轻量包装脚本在系统提示中已经包含完整行为规范启动代理,并由其分叉的所有子代理继承。
会话中,作为始终加载的规则。框架自动加载一个小的规则文件,其中包含不可协商的核心,并指向完整行为规范。因此,即使一个会话以普通方式启动,仍然根据合约运行。
会话内的小规则故意很小:完整行为规范位于启动层,位于始终加载的上下文预算之外。这样永久成本低,同时保证核心存在。
使我谦卑的教训:验证框架实际加载的内容
这是我最感激抓住的发现,因为它是那种悄悄使整个系统变成安慰剂的东西。
我有二十个编写精美的子代理角色定义。它们已经存在了几个月。它们在我的配置中被引用。我相信它们正在被调度。当我实际检查运行中代理的可用子代理类型列表时,没有一个在那里。运行时只显示内置的通用代理。
角色文件使用一种自定义的元数据格式,代理框架从未将其解析为代理定义。它们实际上是文档。我的编排一直在悄悄回退到通用代理,并通过将角色上下文粘贴到提示中来补偿。它工作得足够好,以至于我从未注意到声明的专家并不真实。
修复是机械性的:将每个角色文件标准化为框架的实际原生格式,有效的frontmatter,包含名称、描述、工具允许列表和模型层级,这样框架就能将每一个发现为一级可调度代理。我编写了一个确定性脚本统一对所有20个文件进行处理,验证每个文件都可解析,并对照运行时确认这些代理现在出现了。
可转移的教训比bug更大:框架的真相是运行时实际加载的内容,而不是你的配置声称的。一个声明的代理、一个连接的钩子、一个作用域规则:在你看到运行时确认之前,它们都不是真实的。把“它在配置里”当作假设,而运行时自己报告的已加载内容是唯一能关闭它的证据。我现在验证发现的方式与验证通过测试的方式相同:看输出,而不是意图。
安全执行:不会锁死会话的完成门
提示中的行为规范是指导。有时你需要一个机制。我最强大的一个构建是完成门:一个在代理试图完成时触发的钩子,强制它在回合真正结束前重新检查“完成”声明是否基于真实证据。
能够阻塞完成的钩子在编写时确实危险,因为朴素版本会创建无限循环:钩子阻塞停止,模型继续,再次尝试停止,钩子再次阻塞,如此循环。一个构建糟糕的门不会惹恼你。它锁死会话。所以这里的工程几乎完全关于安全,三个不变性值得直接窃取:
默认不活动。除非环境标志打开,否则门什么都不做。它出厂时连线但关闭,所以永远不会惊吓现有工作流。你为长期自主运行启用它,其中提前完成是真正风险。
防循环。框架告诉停止钩子它是否已在此回合触发。门读取该标志并拒绝第二次阻塞。它最多干预一次,然后让回合结束。这一项检查就是有用门和无限循环的区别。
故障安全。任何异常、任何畸形输入、任何意外:门干净退出并让停止继续。门中的bug降级为无操作,决不会导致会话卡住。在位于每个回合关键路径的工具上,故障安全不是可选的。
我在将其接入之前,从shell测试了所有三个属性:标志未设置时不活动,启用时阻塞恰好一次,在已触发标志下从不再次阻塞,对垃圾输入干净退出。你没有进行对抗性测试的安全机制是责任,而不是保障。
分层配置:全局行为规范,本地专家
一旦标准在一个项目中奏效,明显的问题是:它适用于我工作的所有地方,还是仅此一处?正确划定范围实际上是一个真正的架构决策,而不是细节。
代理框架通常有(至少)两个配置层:项目层,仅在你工作于该项目内时加载;用户层,在每个会话中全局加载。错误做法是把所有东西塞进一个层里。正确做法是按影响范围拆分:
行为规范是通用的,所以属于用户层。操作标准适用于任何代码库;行为不是项目特定的。我将其放在用户级别,使得机器上的每个会话,无论在哪个目录,都按照合约运行。我通过将全局副本链接回主仓库中的版本化副本,保持单一事实源,确保永不漂移。
专家代理是领域特定的,所以留在项目层。我的二十个代理知道这个协议的服务、链、命名空间。把它们全局化会在无关项目中暴露协议特定的代理,在那里它们最多是噪音,最坏情况是主动错误。
(原文末尾因成本控制被截断)