90% 出码率是怎么来的?我们如何把研发任务组织成可运行的自动化链路
90% 出码率,不是因为 AI 已经可以直接“理解需求”,而是因为需求在进入执行前,先被组织成了系统可以接住的任务。
真正开始成立的,也不是一次更成功的 AI Coding,而是一条从多源输入、任务表达、执行编排到验证闭环的自动化链路。
如果说上一篇回答的是“链路开始成立了吗”,那这一篇要回答的,是“这条链路到底是怎么被搭起来的”。
上一篇里《出码率到 90% 之后,我们真正验证了什么?端到端自动化的第一次真实落地》,我先把结果亮了出来:在部分真实 B 端 Web / 移动端研发场景中,这条端到端自动化链路的阶段性出码率,达到了 90%。
上一篇回答的是:我们真正验证了什么。验证的不是某个模型能不能生成一段代码,也不是某次 AI Coding 演示是否足够惊艳,而是一条面向真实业务研发的自动化链路,是否已经开始成立。
但比 90% 这个数字本身更值得继续往下追问的是:这件事,到底是怎么做到的?
这两年,业界开始越来越多地讨论 SDD(Spec-Driven Development),也出现了一些基于 spec 思想的工具和框架。但在今天的语境下,SDD 更像一组仍在演化中的实践,而不是一个边界已经完全清晰的统一范式。所以这篇文章不准备先陷入概念争论,也不打算重复展开我之前在 RDD 文章里对“表示”问题的讨论《为什么 Spec 不是终点,而只是中间产物?软件研发正在从 Spec 驱动,走向表示驱动(RDD)》。相比于先给出一个抽象定义,我更想回到一个更具体的问题:在真实研发任务里,一条端到端自动化链路,到底是如何被搭起来的?
只从结果回看,这件事很容易被想象成一个更直接的过程:把 PRD、设计稿、接口文档一并交给 AI,然后等它把代码写出来。但真实研发里,事情根本不是这么发生的。一个任务从来不是一份单独文档,它总是散落在 PRD、设计稿、接口定义、代码仓库、团队规范、历史实现,甚至某些默认共识之中。对人来说,这些信息可以在脑中临时拼起来;但对系统来说,它们并不能直接进入执行。
这条链路真正跑起来之后,一个此前已经不断被验证的判断变得更清楚了:90% 出码率背后最关键的,不是 prompt 写得更长了,也不是模型突然“理解了需求”,而是任务在进入执行之前,先被组织成了系统可以承接、装配、推进,并能够被持续修正的对象。
这一篇,想拆开的就是这个过程。
一、90% 出码率,不是把需求直接交给 AI#
如果只看结果,很容易产生一种联想:既然已经能做到 90% 的阶段性出码率,那是不是意味着,现在只要把需求交给 AI,它就能直接完成研发任务?
但一旦把问题理解成“把需求直接交给 AI”,整条链路中真正起作用的组织过程就会被省略掉。
在开放式演示里,这种联想并不难成立。给定一段描述、一张设计图,模型写出一个页面、一个组件、一个交互 demo,看起来已经足够像“开发完成”。但真实业务研发不是这样。真实研发任务并不是一个脱离上下文的生成问题,它总是嵌在具体的业务流程、项目结构、团队规范和既有实现之中。很多时候,难点甚至不在“怎么写这段代码”,而在“到底应该在哪写、依赖谁写、按什么约束写、什么算写对了”。
也就是说,90% 出码率,不是“AI 已经能够直接理解需求”,而是“任务在进入执行前,已经被组织过了”。
如果忽略了这层组织动作,整件事看起来就会被简化成一种单点能力提升:模型更强了,所以它突然能做需求了。但真实发生的并不是这种跳跃。真正的变化在于,我们不再把“需求”理解成一段交给模型的话,而是开始把它当成一个需要被整理、约束、表达和承接的系统对象。
过去,很多 AI Coding 场景其实依赖的是“高手手工组织上下文”的能力。谁更熟悉业务,谁更懂仓库,谁更知道该补什么信息,谁就更容易把结果做出来。这种方式当然能跑出效果,甚至在某些阶段非常有效。但它也有一个明显问题:它很难复用,也很难沉淀。每次成功都更像一次高度依赖个人经验的人工 orchestration,而不是一条可重复运行、可持续优化、可团队复用的链路。
所以,问题从来不是“有没有 AI 帮你写代码”,而是:在真实业务研发里,一个任务有没有先被组织成系统能够接住的形态。
只有先把这件事想清楚,后面的多源输入、输入治理、任务表达、执行编排、自动化验证,才会真正获得自己的位置。否则,后面所有机制看起来都只像是在“多做一层”,而不是在解决真正的问题。
接下来,先看最基础、也最容易被低估的一层:真实研发里的“需求”,到底是什么。
二、真实研发里的“需求”,其实是一组多源输入#
“把需求交给 AI”这句话很顺口,但它其实会制造一种错觉:好像现实里真的存在一份足够完整、足够清晰、足够稳定的“需求”,只要把它喂给系统,执行就自然开始了。
但真正把任务放进自动化链路之后,我们会发现,“需求”这个词其实过于省事了。因为在企业研发现场,它很少是一份可以独立完成开发的文档。更准确地说,它通常是一组分布在不同载体里的输入,只是平时由人把它们在脑中拼了起来,所以我们才习惯把这一整组东西,笼统地叫作“需求”。
这里讨论的,也仍然是当前较常见的企业研发流程:需求、设计、接口、仓库上下文与团队规范分散存在,任务需要在既有协作结构中进入自动化链路。至于当需求定义、设计表达与工程执行进一步融合后,这条链路是否会继续向上游延伸,是另一个值得单独展开的问题。本文先不处理那个更远的问题,而是先回到当前已经被真实验证过的链路起点。
最显眼的一层当然是 PRD。它提供的是业务目标、核心流程、规则变化、页面范围,以及任务为什么要做、做到什么程度。但 PRD 通常只能解决“想做什么”,很难天然覆盖“具体怎么做”。很多真正会影响执行质量的东西,比如异常状态、边界条件、交互细节、与现有模块的衔接方式,往往并不完整地存在于 PRD 里。
设计稿补的是另一层。它让页面结构、交互状态、视觉层级和一些用户操作路径变得更明确。很多时候,一个功能到底是弹窗、抽屉、内嵌区域,列表为空时展示什么状态,操作成功后是局部刷新还是整页跳转,这些都不太可能只靠 PRD 被完整表达出来。对前端任务来说,设计稿往往不是“附加材料”,而是任务理解本身的一部分。
再往下,是 API 文档、数据结构定义以及更底层的接口约束。一个需求在业务层面是否成立,最后总要落到数据怎么取、字段怎么映射、状态怎么流转、提交动作如何收敛。没有这些信息,很多任务在表面上看已经足够清楚,但一进入执行阶段,就会立刻暴露出“其实还不知道该怎么落地”。
但即使 PRD、设计稿、API 文档都齐了,任务仍然不完整。因为真实落地并不发生在抽象空间里,而是发生在具体代码仓库中。Repo 本身就是输入的一部分。目录结构怎么组织,已有页面是怎么实现的,表单、表格、上传组件、状态管理、网络请求、埋点方式分别遵循什么约定,这些不会写在需求文档里,却会直接决定“这段代码应该怎样被写出来”。
再往后,还有两类经常被低估、但实际非常关键的输入。
一类是团队规范。它看起来不像需求的一部分,但很多时候,真正影响生成结果稳定性的,恰恰是这些默认规则:命名方式、交互约束、公共组件复用要求、提交规范、目录分层、埋点口径、可维护性要求……这些对人来说是“常识”,对系统来说却不是。只要没有被显式带入,它们就随时会丢失。
另一类是历史实现。很多业务任务并不是第一次出现,它们通常在仓库里已经有了类似页面、类似交互、类似处理逻辑。历史实现不是“参考资料”那么简单,它提供的往往是一种沉淀过的默认模式:这个业务通常怎么做,这个模块以前怎么接,这个组件在团队里通常以什么方式被使用。很多时候,AI 之所以能补齐 PRD 没写出的细节,依赖的并不是它“猜得更准”,而是它拿到了真实项目里的这些先例。
所以,回头看,真实研发里的“需求”根本不是单一文本,而是一组多源输入的组合体。
PRD 决定目标,设计稿决定交互,API 决定边界,Repo 决定落点,团队规范决定约束,历史实现决定默认模式。平时是人把这些东西整合在一起,所以我们会误以为“需求”是一份天然完整的对象;但当执行者换成系统,这个误解就会立刻暴露出来。
也正因为如此,真正的问题从来不是“PRD 是否写得够长”,而是:这些输入能不能在进入执行前,被统一组织起来。
如果不能,那么它们再多,也只是资料;
如果能,那么它们才会开始变成任务。
三、为什么原始需求不能直接进入执行阶段#
即使已经拿到了 PRD、设计稿、接口文档和代码仓库,这些输入也仍然不能直接进入执行阶段。
这件事在一开始其实很容易被低估。因为从人的视角看,这些材料往往已经“差不多够了”。一个有经验的研发同学,看完 PRD,再扫一眼设计稿和现有实现,通常很快就能在脑中形成一个大致判断:这个需求要改哪些页面、可能会影响哪些状态、需要补哪些交互、有哪些地方要小心一点。也正因为人类很擅长在不完整信息中快速形成工作判断,我们才会误以为:只要把这些原始输入都给到系统,执行就应该自然开始了。
但系统并不是这样工作的。对人来说,这些输入是“可参考”的;对系统来说,它们还远远不是“可承接”的。
最直接的问题,是不完整。
PRD 通常只覆盖主目标、主流程和核心规则,但很少天然覆盖所有会影响落地的细节。很多真正决定执行质量的内容,恰恰是那些不在主流程里的东西:异常状态怎么处理,空态怎么展示,已有列表条件是否要联动变化,操作成功后是局部刷新还是重新拉取,页面间状态如何同步,边界输入如何兜底。这些内容对一个有经验的人来说,往往可以边做边补;但对一个自动化执行系统来说,只要这些信息没有进入任务本身,它就不得不猜。
第二个问题,是不一致。
真实项目里的不同输入,并不总是处在同一个时间点上。PRD 可能是上周定的,设计稿可能昨天刚改过,接口文档可能还没更新完,仓库里的现有实现又可能保留着更早版本的逻辑。很多时候,这些输入彼此之间并不是完全对齐的。对人来说,这种不一致往往会在沟通、经验和临场判断中被消化掉;但对系统来说,不一致不会自动消失。只要没有明确地告诉它“以什么为准”“哪里已经变化”“哪些地方只是历史遗留”,执行就会天然建立在模糊前提上。
第三个问题,是不显式。
很多真正关键的信息,根本不写在文档里。它们往往藏在团队默认共识、仓库惯例和历史实现中。比如某类页面必须复用已有组件,某类提交流程要带特定埋点,某些模块改动时不能碰公共逻辑,某些字段虽然接口可写但业务上不应该写,某个交互在团队里一直遵循固定处理方式。这些信息对团队成员来说是“知道的”,但对系统来说,知道这件事本身并不会自然发生。只要没有被显式带入,这些约束就等于不存在。
第四个问题,是不可传递。
这可能是最容易被忽略的一层。即使前面那些信息都存在,也不等于它们能够稳定地传给执行系统。PRD、设计稿、Repo 经验、团队规范和历史模式,并不是天然组织在一起的:有的在文档里,有的在仓库里,有的在团队约定里,有的在老代码里。对一个人来说,这些输入还可以靠阅读、经验和上下文切换被临时拼接起来;但对系统来说,分散存在的信息并不会自动汇聚成一个可执行任务。信息存在,不等于任务已经形成;资料很多,也不等于系统已经知道该如何接手。
所以,原始需求不能直接进入执行阶段,不是因为模型还不够强,也不是因为上下文还不够长,而是因为:它还没有被组织成一个可以被系统稳定承接的任务对象。
这也是为什么,端到端自动化真正的困难,并不只是“模型能不能写代码”,而是:在代码生成开始之前,任务是否已经从分散输入,进入了可执行状态。
如果这一层没有成立,那么后面的执行就只能依赖猜测、补全和运气;
如果这一层成立了,自动化链路才真正有了起点。
也正因为如此,下一步真正需要解决的问题,不是继续堆更多输入,而是先处理这些输入:哪些已经足够,哪些还缺,哪些约束必须显式化,哪些不确定项不能被默默跳过。
这就是输入治理要解决的事情。
四、输入治理,不是在补文档,而是在让任务进入可执行状态#
“输入治理”这个词,听起来很容易让人想到另一类事情:整理资料、清洗文档、补齐字段、做一套更规范的输入模板。好像它本质上是在做文档层面的规范化工作。
但在这条链路里,输入治理并不是一个偏流程管理的动作。它更接近一种工程上的任务就绪化过程。
换句话说,它解决的不是“资料够不够整齐”,而是:一个任务能不能在当前状态下,真正进入执行。
更具体一点看,输入治理真正处理的,主要是三件事。
第一类,是检查完备性。
不是所有拿到手的需求,都已经具备直接执行的条件。很多时候,问题不在于资料有没有,而在于决定执行的关键信息是否已经存在。这个需求的改动范围有没有被说清?影响的是单页还是跨页面联动?依赖的是现有接口还是新能力?设计稿里有没有覆盖关键状态?现有仓库里有没有相似实现可以参考?哪些地方是已经明确的,哪些地方其实还停留在模糊表述里?这些问题如果不在执行前被看见,到了后面就一定会以另一种方式重新暴露出来。
所以,输入治理做的第一件事,不是“把已有资料转一遍”,而是判断:当前输入是否已经足够支撑任务执行。
第二类,是显式化边界和约束。
很多需求之所以在人工协作里能被顺利完成,不是因为需求天然完整,而是因为团队成员会自动补上很多隐含条件。但当执行者换成系统,这些依靠经验默认成立的边界,就必须被提前写出来。改动范围到底落在哪几个模块?哪些公共逻辑不能动?要遵循哪套组件体系?哪些交互模式必须保持一致?哪些历史实现是可以复用的,哪些只是表面相似、实际不能照搬?这些约束如果继续停留在“默认知道”的状态里,执行就不会稳定。
所以,输入治理不是简单地把“想做什么”转成另一种说法,而是把那些原本隐藏在经验里的执行条件,提前推到台面上。
第三类,是保留不确定项。
这一步很容易被误解。很多人会觉得,治理的目标就是把所有模糊内容都补全、都澄清、都消灭掉。可真实研发并不是这样。很多任务在进入执行前,本来就带着一定程度的不确定性。有些问题需要进一步确认,有些边界在不同输入之间仍然存在冲突,有些细节暂时只能基于现有上下文给出最合理的推断。在这种情况下,更稳的做法不是假装一切都已经清楚,而是把这些不确定项显式地保留下来。
这点非常重要。因为对系统来说,最危险的状态不是“不知道”,而是在不知道的情况下继续假装知道。把 uncertainties 留在任务对象里,至少意味着链路知道哪里还没有完全收敛,而不是把这些空白悄悄交给模型自己补。
也就是说,输入治理的目标从来不是“让文档更完整”,而是“让执行条件更明确”。它不只是对资料做整理,而是在为后面的任务表达准备一个更稳定的起点。
到了这一步,一些原本散落在不同地方的信息,才开始第一次具备被表达为任务对象的可能。范围会变得更清楚,约束会变得更显式,不确定项也不会再被默默吞掉。后面无论是任务表达、上下文装配,还是执行编排,消耗的都不再是最原始的输入,而是这一轮治理之后留下来的结果。
所以,输入治理并不是链路前面那层“看起来有点繁琐的准备工作”。恰恰相反,它是把任务从“人能大概理解”推进到“系统可以稳定承接”的第一道门。
如果没有这一步,后面的 Task IR 很容易退化成另一份更长的描述;
只有先有输入治理,任务表达才不会只是重写需求,而会真正变成执行前的中间对象。
下一步要解决的,也正是这个问题:
当输入已经被治理过之后,它最终要以什么样的形式,进入执行系统?
这就是 Task IR 出现的位置。
五、Task IR 不是另一份需求文档,而是执行前的任务对象#
走到输入治理这一步,链路里其实会出现一个新的问题:那些已经被梳理过、约束过、补足过、标记过不确定项的信息,最终要以什么形式进入执行系统?
如果这里不再往前走,而是回到最原始的 PRD、设计稿,或者临时拼出一段更长的 prompt,那么前面那一整轮治理的结果,很快又会重新散掉。范围会重新变模糊,约束会重新退回隐含状态,不确定项也会重新被吞进一句“模型自己会补全”的期待里。这样一来,输入治理虽然做了,但它并没有形成一个真正可以被后续环节稳定消费的对象。
Task IR 的位置,也正是在这里开始变得清晰。
它不是为了把需求“再写一遍”,也不是为了把原始输入换一种更技术化的说法重新包装起来。它的真正作用,是把多源输入经过治理之后留下来的结果,组织成一个执行系统真正能够接住的任务对象。
这一点非常重要。因为它决定了 Task IR 不是文档意义上的“副本”,而是链路意义上的“中间层”。
PRD 解决的是业务意图,设计稿解决的是交互表达,Repo 和团队规范解决的是落地约束,输入治理解决的是任务就绪化;而 Task IR 解决的,是如何把这一切汇聚成一个可以被继续传递、装配、执行和验证的对象。它不再只是“供人阅读”的材料,而开始变成“供系统承接”的对象。
也正因为如此,Task IR 最关键的价值,并不在于它长什么样,而在于它固定了什么。
它会把任务的范围固定下来。
哪些页面、哪些模块、哪些状态属于当前任务,哪些不属于,不再需要在执行时临时猜。
它会把约束固定下来。
哪些实现路径可用,哪些边界不能碰,哪些规范必须遵守,不再停留在默认共识里。
它会把验收要求提前带入。
什么算任务完成,哪些行为是必须满足的,不必等到最后交付时再回头判断。
它也会把不确定项保留下来。
不是所有空白都要在前面强行补满,而是让链路知道:这里仍然存在需要继续判断、继续澄清或继续观测的部分。
如果借用业界更熟悉的话语,这里面承接的,其实也是 SDD 中常见的一些核心关切,比如范围、约束、验收条件,以及需要继续澄清的问题。不同的是,我们并没有停在 specification 被阅读和理解的层面,而是把这些连同更完整的任务信息——例如交互模型、实现提示、依赖项、上下文线索等——进一步组织成了执行系统可以直接消费的任务对象。
所以,Task IR 不是一份“写得更完整的需求文档”,而是一个把任务边界、执行条件、验收目标和未决问题一起托住的中间对象。到这一步,任务才第一次真正从“分散输入”变成“系统对象”。
这也是它和 prompt 的根本区别。
Prompt 更像是一次性交互中的表达手段。它强调的是:在当前上下文里,怎样把意思说给模型听。
Task IR 不是为了“说给模型听”,而是为了“交给系统承接”。它不是一段临时话术,而是一层可以被继续传递、继续装配、继续复用、继续验证的任务表示。
换句话说,prompt 关心的是这一轮怎么说;
而 Task IR 关心的是,这个任务能不能在链路里被稳定地接住。
这也是为什么,在前面没有输入治理的情况下,Task IR 很容易退化成另一份更长的需求说明;但在输入已经被治理过之后,它才会真正获得自己的位置:不再只是“描述任务”,而是“固定任务”。
当然,走到这里,事情还没有结束。
因为任务被表达出来,并不等于执行已经开始。
Task IR 只是让任务第一次被稳定地表达出来,它还没有回答另一个同样关键的问题:这个任务接下来要进入哪个项目上下文、调用哪些能力、依赖哪些历史经验,以什么样的方式,真正进入执行系统?
这就是它后面还必须经过的一层:上下文装配与能力路由。
六、任务进入执行前,还要经过上下文装配与能力路由#
Task IR 解决的是任务如何被表达出来,但它并不是执行的终点。
很多时候,讲到这里很容易给人一种印象:好像任务一旦被表示清楚,系统就会自动开始工作。但真实情况并不是这样。任务被表达出来,只意味着链路终于拿到了一个稳定对象;它还不意味着执行条件已经准备好了。
因为执行从来不是在抽象空间里发生的。一个任务最终总要进入某个具体的 repo、某个具体的模块、某套具体的项目约束、某种具体的能力体系中。也就是说,Task IR 并不是被“直接执行”的,它还需要先被装配到一个真实可运行的执行环境里。
这就是上下文装配存在的原因。
所谓装配,首先不是简单地“再加点上下文”。
它真正要做的,是把任务放回它应该发生的环境里。
这个任务属于哪个仓库?
应该落到哪个模块、哪个页面、哪类组件体系中?
现有代码里有没有相似实现可作为直接参考?
这个业务在当前项目里是否已经存在默认处理模式?
哪些公共能力应该复用,哪些局部逻辑应该隔离?
哪些团队规范需要被强绑定,而不是只作为背景提示存在?
这些信息看起来像“附加材料”,但对执行系统来说,它们并不是附加的。它们本身就是执行条件的一部分。
也正因为如此,仓库上下文、模块上下文、项目知识、历史实现、团队规范,这些内容在这里的作用,已经不再只是“帮助理解”,而是在共同定义:这个任务到底要如何被做出来。
这时候,“能力路由”也开始进入链路。
因为真实任务所依赖的,并不只是一个通用模型的语言能力。很多能力本身就是项目特定的:如何读取项目经验、如何查询某类知识、如何遵循既有通信协议、如何按照团队约定组织子任务、如何在某类场景下调用特定技能。这些能力不会天然存在于模型里,它们需要被显式接入,也需要在执行前被正确路由到任务上。
所以,这一层真正解决的问题,不是“如何把上下文塞得更长”,而是:如何让正确的上下文和正确的能力,在正确的时机进入任务。
这也是为什么,进入执行阶段的,不会只是一个“裸”的 Task IR。
真正进入执行的,永远是一个组合对象:它既包含被治理和表达过的任务,也包含真实项目里的上下文条件,还包含任务在当前阶段需要调动的能力路径。
换句话说,系统接手的从来不是一句需求,也不是一个抽象表示,而是:
Task IR + 项目上下文 + 能力路由
只有这个组合成立,执行才真正有了落脚点。
这一步其实也解释了,为什么很多看起来“同样清楚”的需求,在不同项目里的可执行性会完全不同。因为决定执行质量的,不只是任务本身是否明确,还包括它能否被放进一个足够真实的上下文里,能否拿到它真正依赖的那些项目能力。
所以,上下文装配并不是一层辅助动作,能力路由也不是为了让链路“更高级”。
它们本质上都在解决同一个问题:让任务不只是被表达出来,而是被放进一个可以真正开始工作的系统环境里。
但即使走到这里,链路仍然还差最后一层关键推进。
因为任务被表达了,也被装配进环境了,并不等于它就能稳定跑起来。
真实自动化链路面临的下一个问题是:任务如何被持续推进,多个子任务如何协同,长链路中的上下文如何被管理,执行中出现偏差时又如何继续修正。
这就不再只是“任务对象”的问题,而开始进入“执行系统”本身。
七、真正让链路跑起来的,不只是表示,而是执行系统本身#
如果说前面的多源输入、输入治理、Task IR、上下文装配,解决的是“任务如何被接住”,那么接下来的问题就是:任务如何被持续推进。
这一步之所以重要,是因为真实研发任务从来不是“一次生成”就结束的。它天然带着阶段性:有些部分要先理解再拆解,有些部分要先查询再决策,有些部分要先改动代码再检查结果,有些地方还会在执行过程中不断暴露新的依赖和新的偏差。也就是说,任务一旦真正进入执行,就不再只是“把输入交给模型”,而是变成了一条要持续推进的过程。
这也是为什么,只靠任务表示本身,并不足以让链路稳定运行。
Task IR 可以把任务托住,上下文装配可以把任务放回真实环境,但系统仍然需要回答一组更具体的问题:当前应该先做什么,再做什么;哪些部分可以并行,哪些必须串行;一个子任务完成之后,结果如何被传回主链路;某一步如果失败,是应该重试、改写,还是切换路径;当链路变长之后,谁来负责保持全局目标不丢失。
这些问题,一旦不再由人临场处理,就必须由执行系统本身来承接。
所以,执行真正开始之后,任务面对的往往不是一个“单 Agent 一把做完”的过程,而是一组被编排过的执行动作。主 Agent 负责理解全局目标、控制整体推进;子 Agent 或子任务节点负责承接某一段具体工作;中间的结果需要被传递、汇总、回收;整个过程中还要尽量避免主链路被长上下文持续吞噬。这时候,系统解决的已经不再是“需求怎么表达”,而是“复杂任务如何在执行中被拆开、被协同、被继续推进”。
这也是为什么,主 Agent、子 Agent、Agent team 这些结构,在真实链路里并不是为了让系统“显得更高级”。
它们真正解决的,是两个更现实的问题。
第一个问题,是分工。
一个真实任务往往同时包含理解、查询、生成、修正、验证等不同类型的动作。如果全都塞进一个统一上下文里让单个 Agent 处理,链路很快就会变得又重又乱。分工之后,不同子任务可以在更明确的目标和更受控的上下文中运行。
第二个问题,是上下文控制。
长链路任务最容易出现的,不是局部代码写不出来,而是主链路不断被细节拖垮。子任务越多,试错越多,历史上下文越长,主 Agent 越容易在一堆中间状态里逐渐失去清晰的全局控制。把执行拆到更合理的层级,本质上是在保护主链路,让系统不至于在执行过程中被自己的上下文吞掉。
也正因为如此,中间的通信方式会变得重要。
当任务不再由一个人或一个单体上下文直接做完,而是要在多个执行单元之间流动时,系统就需要一种更稳定的任务传递方式。哪些信息必须传,哪些信息可以省略,子任务返回的结果应该长什么样,失败时应该怎样把状态带回来,这些事情如果没有相对稳定的协议,链路很快就会从“执行系统”退化成“混乱的多轮对话”。
所以,通信协议的价值并不在于形式感,而在于它让任务在不同执行单元之间传递时,不会不断失真。它让系统知道:什么是当前目标,什么是阶段结果,什么是待处理项,什么是失败原因,什么是下一步决策的依据。
走到这里,其实就能更清楚地看见:一条自动化链路之所以能真正跑起来,靠的并不是“某一次生成成功了”,而是系统已经开始具备了一种持续推进任务的能力。它知道怎样把任务拆开,怎样让不同执行单元各自承接局部工作,怎样在长链路中保住全局目标,又怎样在中间结果不断涌现的情况下继续往前走。
**换句话说,表示解决的是“任务如何被接住”;
**而执行系统解决的是“任务如何被继续跑下去”。
到这一步,链路才开始真正摆脱“单次 AI Coding 成功案例”的状态,进入更接近系统化执行的阶段。
但即使如此,事情还没有真正闭合。
因为任务能被推进,并不等于系统知道自己是否正在朝正确方向推进。
它可以跑,但未必知道自己跑得对不对;
它可以继续生成,但未必知道什么时候应该停止、什么时候应该修正。
到这里,链路已经不再缺“执行”,而开始缺“收敛”。自动化验证也正是在这个位置,真正进入主链路。
八、自动化验证不是末尾补验,而是执行闭环的一部分#
如果说前面的任务表示和执行编排,解决的是“任务如何被接住并开始推进”,那么自动化验证解决的,就是:系统如何知道自己做得对不对,以及什么时候该继续修正、什么时候该停下来。
这一点,在很多讨论里其实容易被放到最后。验证经常被理解成一种交付前的补充动作:代码已经写完了,再跑一下检查、做一下测试、看一下结果是否可用。
但在真实自动化链路里,验证不是最后再补的一层,它从一开始就在影响执行过程。
因为没有验证信号,执行系统其实只能生成,不能收敛。
它可以不断地产出代码,不断地尝试修复,不断地继续往前推,但如果系统不知道什么算“完成”、什么算“偏离”、什么算“已经应该停止”,那这条链路就很难真正稳定下来。它看起来在跑,实际上却始终缺少一个把任务往正确方向拉回来的反馈机制。
这也是为什么,前面在 Task IR 里,验收要求必须被提前带进来。
如果 acceptance 只留在最后交付时再看,那么执行阶段就会天然失去目标锚点。系统可能知道自己要改哪个页面、要写哪些逻辑、要遵循哪些约束,但它仍然不知道:到底做到什么程度才算任务成立。只有当“完成条件”在前面就已经进入任务对象,执行过程中的每一次推进、每一次修正,才有可能朝着一个稳定目标收敛,而不是在局部合理和整体正确之间来回漂移。
当然,这里所说的自动化验证,并不意味着在当前阶段就已经先搭完了一整套完备的评估与测试平台。真实实践不会这样开始。更现实的做法,是先让链路具备一批最基础、最关键的验证信号。
例如,任务完成之后能否基本跑通,关键流程是否满足要求,某些核心状态与交互是否符合预期,部分重要的黑盒结果是否成立。这些验证信号未必覆盖一切,但它们已经足以改变执行系统的性质:系统不再只是“写出一版结果”,而是开始拥有最基本的自我检查与自我修正能力。
这也是自动化验证在链路里最关键的价值。
它不是为了证明“系统曾经有一次做对了”,而是为了让系统在偏离时,知道自己偏离了;在失败时,知道失败发生在哪里;在局部不满足要求时,知道应该回到哪一步继续修正。
所以,一条自动化链路真正稳定下来的方式,不是“一次性赌对”,而是进入一种更接近闭环的状态:
执行。
检查。
修正。
再检查。
这时候,验证信号不再是结果页上的附属说明,而成了执行 loop 的输入。
也正因为如此,自动化链路并不意味着系统必须无休止地自我修复。恰恰相反,成熟一点的链路会逐渐知道边界:哪些问题还在当前验证能力可覆盖的范围内,可以继续自动修正;哪些问题已经超出了现有上下文、现有能力或现有判断条件,应该及时停下来,转回人工介入。
这一点同样很重要。因为真正成熟的自动化,并不是假设系统永远不需要人,而是系统开始知道:在什么地方可以自己继续推进,在什么地方应该把控制权交还出来。
当然,这里关于验证本身还可以继续往下展开——例如更基础的可运行性检查、黑盒测试、评估口径、回放验证、自动化判定的覆盖边界等等。但这些已经是下一层问题了。对于当前这篇文章来说,更重要的是先把一个基本判断说清楚:
自动化验证并不是链路最后补上的一层,而是这条链路之所以能够稳定推进、持续修正并最终收敛的重要原因。
如果没有它,前面的表示、装配、编排都仍然可能停留在“系统会跑”;
只有把验证真正带进主链路,自动化才开始从“能运行”走向“能闭环”。
结尾#
回头看,我们做到 90% 出码率,真正依赖的并不是把需求直接交给 AI,而是把研发任务从分散输入,一步步组织成了系统可以承接、装配、推进,并在验证信号中持续修正的对象。
这条链路真正成立的过程,也不是某个单点能力的突然跃迁。它更像是一层一层地把原本散落在人脑、经验和协作过程中的东西,重新外化出来:多源输入被重新看见,输入治理开始处理任务就绪化,Task IR 托住了任务边界,上下文装配把任务放回真实环境,执行系统负责持续推进,而自动化验证则把链路真正拉进闭环。到这里,我们面对的,已经不再是“AI 能不能写一段代码”,而是“一条真实自动化链路如何被组织、被推进、被验证”。
当然,讲清一条链路是如何成立的,并不等于它已经没有边界。多模态输入的消费能力、跨团队依赖带来的不确定性、复杂需求中的验证难度,以及系统何时应继续自动推进、何时应切换为人工接管,这些问题都还远没有彻底解决。但这恰恰说明,问题已经开始从“单点生成”转向“系统执行”。
接下来更值得展开的,已经不只是“任务如何被表达”,而是这条链路如何进一步沉淀为 Skills 驱动的工作流,以及项目知识如何被组织成可以持续复用的系统能力。这部分,放到下一篇继续展开。
至于 90% 这件事如何被更可信地验证,我们也会在后面的 Benchmark 文章里单独展开。