先聊一个挺扎心的现象:过去两三年,凡是说“用AI写代码”的演示,基本都停在同一个画面——人往对话框里丢一句需求,大模型噼里啪啦吐出一坨代码,然后大家鼓掌。可真到了要把它放进项目里跑、要它扛住真实业务复杂度的时候,这坨代码多半在第一轮代码评审就翻车了。不是AI写得不对,是我们用AI的方式本身就有问题。
我自己做了一段时间的智能体开发,前后试过单智能体硬刚需求、多智能体平铺协作、工作流编排挂外部工具,最后绕了一大圈,落回一个看起来没那么“炫”但真正能出活的方案:层级化智能体驱动的自底向上软件开发范式。说白了,就是把开发这件事拆成决策、协调、执行几个层级,让每个智能体只干自己最擅长的那一层,然后从最底层的代码单元开始往上叠,叠一层验一层。它不那么像科幻片里的AI程序员,倒更像一支管理得井井有条的远程开发团队。
这篇文章我把自己踩过的坑、试过的配置、最后沉淀下来的套路完整写出来,从架构设计讲到消息契约,再到真实的运行日志和问题排查。无论你是想用智能体做自动化开发,还是想给自己团队搭一套AI辅助流程,都能直接抄作业。
1. 先想清楚:我们到底在用什么范式写软件
1.1 单智能体开发的最大问题不是笨,是没有上下文约束
很多人一开始上手智能体开发,第一反应都是“把我整个需求丢给一个Agent,让它从头写到尾”。我最早也这么干,为了让Agent“理解全局”,我会把需求文档、现有代码结构、设计约束全塞进它的上下文里,最长的一次光提示词就写了四千多字。
结果呢?前两轮还行,到第三轮开始,它开始自己编造不存在的接口,第四轮它把已经写好的模块逻辑推翻重来,第五轮它还在重复调用同一个工具直到报错。问题的根子不在于模型能力,而在于一个智能体同时扮演了架构师、产品经理、开发、测试四个角色,它自己的上下文根本装不下这么大的状态空间。人干四份活都会混乱,何况一个大模型。
后来我开始尝试把任务拆开,让多个智能体并行协作,那又掉进另一个坑:平铺的多智能体没有主次,A改了一个接口签名,B还在按旧签名写调用方,改到后面大家各说各话,代码直接碎成一地。缺少层级和约束,等于没有“组织”。
1.2 自顶向下和自底向上,在智能体时代的本质区别
传统软件工程里,主流的思路是自顶向下:先有需求分析,再画架构图,然后定接口,最后才落到代码。这个过程假设了一个前提——在最顶层做决策的人是靠谱的,他能一次把全局设计想明白。
但智能体不是人。让一个大模型直接做顶层架构决策,它很容易给出“听起来很合理、实际上没法落地”的方案,因为顶层设计需要对整个系统有完整的、全局的认知,而这恰恰是大模型的短板。反过来,让大模型写一个具体函数、补一个单元测试、修一个类型错误,它的表现反而极其稳定。
这就是自底向上的底层逻辑:不要指望智能体一次想明白全局,而是让它在最底层、上下文最聚焦的地方,产出确定性最高的小单元,再用这些小单元一层层向上堆积,每堆积一层就做一次验证和收敛。全局的正确性不是靠“想”出来的,是靠“验”出来的。
2. 层级化智能体架构:决策、协调、执行三层怎么分工
2.1 决策层:管目标、管边界、管验收标准
我把这套范式里的智能体按职责分成三层:决策层、协调层、执行层。
决策层是整套系统的“大脑”,但它的职责不是写代码,而是做三件事:把模糊的业务需求翻译成明确的任务边界;定义每个阶段的可验收标准;确定不可触碰的技术约束。这些约束包括“必须兼容Java 11”“不能引入额外的中间件依赖”“错误提示必须中英双语”之类。决策层不需要关心具体怎么实现,它只需要把“做什么”和“做到什么程度算完”讲清楚。
为什么把这层单独拎出来?因为验收标准是智能体协作里最难统一的东西。如果你不给执行层一个明确的“完成定义”,它永远会在自我感觉良好时停下来,交出一份你根本没法用的代码。决策层的产出是一份结构化的任务书,我习惯用JSON格式下发,里面包含目标描述、范围、约束、验收清单四块。
2.2 协调层:拆任务、派活、收结果
协调层是这套架构里最容易被忽略、但最关键的一层。它的职责是:把决策层的任务书拆解成可执行的小任务;为每个小任务匹配合适的执行层智能体;监控执行进度,处理执行失败后的重试和回退逻辑;把执行层的产物整理汇总,回传给决策层做验收。
你可以把它理解成项目经理。我见过很多人在做多智能体系统时完全跳过这一层,结果决策层直接指挥十几个执行Agent,每个Agent拿到的上下文都是一大坨,谁也不清楚自己到底该干什么。加了协调层之后,每个执行Agent拿到的任务书被严格裁剪到“只跟这个子任务相关”的范围,上下文干净了,输出质量立刻上了一个台阶。
协调层的拆解策略我一般用两种:按模块拆和按依赖顺序拆。按模块拆适合功能相对独立的场景,比如一个后台管理系统,用户模块、订单模块、权限模块可以并行开发;按依赖顺序拆适合有严格上下游关系的场景,比如先有DTO和Mapper,才能写Service,然后才是Controller。多数项目里,两种策略会混用。
2.3 执行层:聚焦到单文件、单函数、单测试
执行层是整个架构里真正处于“一线”的智能体,每个执行Agent只干一件事:写一个类、改一个方法、补一个测试、修一个Bug。它的上下文里只有四样东西:当前任务书、相关文件内容、编码规范片段、它自己的完成自查清单。
很多人会担心:把任务切得这么碎,执行层智能体看不到全局,写出来的代码会不会跟整体架构脱节?答案是:会,但这恰恰是协调层和决策层的活儿,不需要执行层操心。执行层的Code Review、接口对齐、架构一致性检查,全部由上一层在收集产物时自动完成。这种分层让执行层的Prompt变得极其简单稳定,我把自己的执行层Prompt写下来之后,几乎没怎么再改过——因为任务边界足够清晰,模型不需要猜测任何东西。
2.4 层间通信:用“任务书+产物+状态”的契约,而不是闲聊
层级之间通信,最大的忌讳是让智能体像聊天一样自由发挥。一旦允许A智能体对B智能体说“我觉得你上次写的那个函数有点问题,你能看看吗”,上下文管道就会迅速失控,系统行为变得完全不可预测。
我的做法是把层间通信的数据结构固定死:下行固定是任务书,上行固定是产物包和状态标记。任务书包含任务ID、目标描述、验收清单、依赖文件、约束;产物包包含改动文件列表、关键代码摘要、测试结果、遗留问题。所有智能体都按这个契约收数据、产数据,模型没有自由发挥的空间,反而整个系统变得非常稳。做智能体开发一段时间你会发现,系统的上限由模型能力决定,系统下限的稳定性则取决于消息契约设计得有多死板。
3. 自底向上开发流程:从一行代码到完整功能
3.1 第一步:让执行层先从“不会错”的最小单元开始
自底向上的第一个动作,是选一个足够小、足够独立、而且验证成本极低的单元作为起点。我常用的起点是:数据库表结构对应的实体类、接口的DTO定义、配置文件的解析器、工具函数的纯函数实现。这些单元有一个共同特征:它的正确性几乎不依赖外部系统,单测就能完全覆盖。
为什么从这种单元开始?因为自底向上范式的核心不是“从底层往上写代码”,而是“从验证成本最低的层次开始积累确定性”。如果你一上来就让执行层写Controller,那它依赖Service,Service依赖Mapper,Mapper依赖数据库表结构——任何一个环节没定下来,Controller写出来就是空中楼阁。反过来,先把最底层、最独立的单元写好并测试通过,在上面每一层写代码时,脚下都是已经验证过的坚实地面。
我自己的案例是写一个用户注册模块。第一批任务书我下给执行层的不是“写用户注册”,而是“写UserEntity实体类”“写UserMapper接口”“写CreateUserRequest的字段校验注解”。三个任务并行,互不干扰,每个任务都附带对应的单测要求。20分钟后,三个单元全部通过测试,地基就打好了。
3.2 第二步:下层产物成为上层的“事实上下文”
自底向上和传统的“分层架构开发”最大的区别,在于对上层智能体输入的处理方式。在传统方式里,上层开发拿到的只是接口文档或者设计图;在我这套范式里,执行层写上层代码时,看到的永远是真代码,而不是接口描述。
比如开发UserService时,协调层会把已经通过的UserEntity和UserMapper的真实源码直接塞进执行层的任务书里。这么做的好处是,大模型不再“脑补”实体类有哪些字段、Mapper有哪些方法,它看着真实代码写代码,幻觉概率大幅下降。有一次我做过对比,让Agent基于接口文档写Service,一次通过率大概六成,而让它基于真实源码写Service,一次通过率能到九成以上。
同时,每一层的验收都会跑上一层已经写好的测试。协调层会用一条命令统一跑全套测试,一旦发现回归,立刻回退到对应执行层重新修复。这样从底往上搭,每搭一层,整个项目的可运行性和可验证性都在增加,而不是等到全写完再统一调试——后者是传统开发最痛苦的环节,可执行性在这里被降到了最低。
3.3 第三步:每一层的“完成”都必须有机器验证
自底向上这套范式能不能成立,关键看一件事:你能不能给每一层都定义一个机器可验证的“完成”信号。如果某一层的产物只能靠人肉眼去看、靠人凭感觉判断“应该差不多吧”,那智能体的工作就没法收口,上一层的输入也会变成脏数据。
我的经验是把“完成验证”分成三级:第一级是编译和静态检查,比如mvn compile、eslint这类,确保代码语法和风格基本合规;第二级是单元测试,确保功能行为符合预期;第三级是接口契约检查,确保这层暴露的方法能被上层按预定的签名调用。三层验证全部通过,一个层级才算真正完成,它的产物才允许向上流动。
写代码时让执行层自己补测试,经常会出现一个问题:Agent为了让自己写的代码通过测试,会写出跟实现逻辑完全一致的测试,这叫“同源测试”,测了等于没测。我的对策是,在协调层把“测试编写任务”单独拆出来,让一个执行Agent写实现代码,另一个执行Agent只负责写测试,两个Agent互相看不到对方的详细设计。这样测试就真正变成了对实现的黑盒验证。
3.4 一个完整的自底向上链路长什么样
把上面几步串起来,一套完整的链路是这样的。决策层收到需求“实现用户注册,支持邮箱和手机号两种方式”,先产出任务书,定义好验收标准、字段约束、接口风格;协调层把任务书拆成三个批次:第一批实体和Mapper,第二批校验和Service,第三批Controller和注册流程联调;每个批次内部先并行让执行层产出代码,收码后统一跑测试、跑契约检查,通过后进入下一批次。
最后一个批次的联调完成后,协调层把所有批次的产物汇总成一个完整功能包,返回给决策层做最终验收。决策层此时可以动用一个专门做代码审查的智能体,或者直接调用静态代码分析工具,把几个关键指标跑一遍:圈复杂度、重复代码率、未覆盖分支数。全部达标,这个功能模块才算交付。我从任务下达到拿到可运行的完整模块,一般控制在2到3小时以内,最核心的收益是,过程中的每一个中间步骤都是可回滚的、可验证的,而不是等到最后才发现方向错了。
4. 实操实录:搭一套能跑通的三级智能体流水线
4.1 框架选型:不一定用重平台,组合工具也能起效果
很多人一提到搭智能体,第一反应是去上Dify、Coze、MaxKB这些平台。这些平台确实能减少重复造轮子,尤其你如果只需要固定的工作流编排,用它们很快。但我这套范式更强调智能体之间的动态消息契约和按任务的灵活调度,所以我更习惯用代码框架自行控制逻辑。目前我常用的组合是:Python写调度胶水层、langchain或agno这类框架提供Agent封装、底层的模型按层级分别接不同的大模型接口。
具体配置上,我的经验是不同层级用不同倾向的模型,而不是全链路用一个最强的模型当冤大头。决策层我用推理能力最强、上下文最宽的模型,因为它要做目标翻译和全局约束;协调层我用兼顾推理和速度的模型,它需要频繁做任务拆解和状态判断,速度太慢会拖垮整个流水线;执行层反而用性价比高的中档模型就够了,因为执行层的任务足够聚焦,上下文很短,中档模型在短任务上的表现跟旗舰模型的差距并不大,但成本可能差出好几倍。
4.2 执行层智能体的Prompt:越短越有用
执行层Prompt我固定成一段不到两百字的模板,大概长这样:
你是一名后端开发工程师。现在给你一个开发任务: - 项目语言框架:{language_framework} - 需要修改/创建的文件:{file_list} - 任务目标:{task_description} - 约束条件:{constraints} - 完成定义:{definition_of_done} 请严格完成上述任务,不要修改与任务无关的代码。 完成后输出: - 修改/新增的文件清单 - 每个文件的关键改动说明 - 你执行了哪些验证命令及结果注意这个Prompt刻意没有放“请你仔细思考”“请一步一步分析”这类话术,也没有放进太多示例。因为任务本身足够聚焦,模型不需要被激励去展示推理过程。反而如果你把示例放多了,它会去模仿示例的风格而不是满足当前任务的要求。这一点是我反复调试后最大的体会:执行层的Prompt要像工单,不要像教学材料。
4.3 协调层的拆解逻辑:把“写代码”变成“验收队列”
协调层是整个流水线里最需要“写代码”的部分,它不是一个纯Prompt能解决的问题。我给它定义了一个内部状态机,每个任务有六个状态:待拆解、已拆解、待执行、执行中、待验收、已完成(或失败回退)。
拆解策略我写成了一个规则引擎,按依赖顺序决定批次。伪代码类似这样:
def decompose(task_spec): # 先找出所有底层无依赖的单元任务 base_tasks = [t for t in task_spec.modules if not t.dependencies] # 再找依赖第一层产出的任务 dependent_tasks = [] for t in task_spec.modules: if t.dependencies and all(d in base_tasks for d in t.dependencies): # 该任务的依赖已全部满足,可进入下一批次 dependent_tasks.append(t) # 重复迭代,直到所有模块都被分配批次 batches = [] while base_tasks: batches.append(base_tasks) base_tasks = next_level_tasks return batches这个逻辑写得不复杂,但足够让协调层在没有人为干预的情况下,按依赖关系跑完整个项目。每个批次完成后,协调层会调用测试命令,并把产物打包成下一个批次的“事实上下文”。有人在第一次看到我的协调层代码时觉得太朴素,但我想说的是,多智能体系统的复杂不应该体现在代码技巧上,而应该体现在状态管理的清晰上。
4.4 决策层的关键:把隐性的“常识”变成显性约束
决策层最常见的翻车,是它把所有约束都藏在自然语言里,导致下游智能体“自以为懂了但实际理解不一致”。比如你说“登录要安全”,A执行Agent会做成密码加密传输,B执行Agent会做成验证码校验,C执行Agent可能直接加了个短信接口——都是“安全”,但完全不同。
我的对策是,决策层在产出任务书之前,必须通过一轮“约束补全”交互:把所有涉及安全、性能、可维护性的要求,一律转译成可测试的量化指标。安全改为“密码必须用bcrypt哈希存储”;性能改为“注册接口P95响应时间不超过300ms”;可维护性改为“新增逻辑不得增加超过3个顶层依赖”。这些约束一写死,执行层的偏差空间就大大收窄了。
这个约束补全环节我自己是用一个单独的Agent来跑的,它的Prompt就一句话:“把下面需求中用词模糊的约束,全部改写成可通过代码或测试验证的硬性指标。”实测下来,这一小步能显著降低后续的返工率,很值得加进你的流水线里。
5. 踩坑记录:多智能体协作里最要命的十个问题
5.1 常见问题速查表
我把这套范式从搭出来到现在遇到的问题整理成了一个速查表,先放出来给各位,后面几个典型问题再展开讲。
| 现象 | 根因 | 解决方案 |
|---|---|---|
| 执行层开始“自由发挥” | 任务书约束不足,模糊词太多 | 决策层增加约束补全环节 |
| 两个执行Agent产出重复代码 | 协调层拆解时任务边界重叠 | 拆解规则里增加文件归属唯一性检查 |
| 上层Agent看到旧版本的底层代码 | 产物传递链路没有版本管理 | 协调层记录每个产物的commit hash |
| 测试永远通过但功能是错的 | 同源测试,实现和测试同人编写 | 测试编写和执行分给不同Agent |
| 上下文越跑越长,开销暴涨 | 层间消息契约含非必要信息 | 层间只传任务书和产物包,不传日志 |
| 一个Agent卡死,整条流水线停摆 | 缺少超时和熔断机制 | 协调层给每个执行任务设置超时上限 |
| 修了一个Bug,引发两个新Bug | 没有回滚边界,修复扩散到无关代码 | 限制执行层只允许修改指定文件 |
| 模型“假装”跑过测试 | 验证命令输出被模型截断加工 | 协调层独立执行验证命令,不信任模型自报 |
| 多智能体并行时互相覆盖文件 | 没有文件锁或工作区隔离 | 每个执行Agent分配独立分支 |
| 上层验收通过,合并后整体挂掉 | 只在单模块验,没做集成验证 | 每完成一个批次跑一次全量集成测试 |
5.2 上下文污染是隐形杀手
所谓上下文污染,指的是下层执行Agent往上层传产物时,不小心带上了一大堆无关内容,导致上层Agent的上下文被噪声填满。最常见的场景是,执行Agent在产物包后面附带了一整段冗长的调试日志,协调层原封不动打包上传,决策层的模型就开始被这些日志吸引了注意力,输出质量明显下降。
我后来强制要求执行Agent按固定JSON模板输出产物,模板里只有“文件清单”“关键改动”“验证结果”“遗留问题”四个字段,任何多余内容都不允许出现在产物里。甚至为了保险,协调层在处理产物包时会做一次字段级裁剪,代码文件只保留diff部分而不是全文。这个细节对成本影响也很明显,上下文变短之后token开销至少降了三分之一。
5.3 死循环和级联失效怎么破
多智能体系统里最噩梦的场景是:A执行Agent发现B的代码有问题,协调层把B召回来修改,B改完后A又发现新的问题,于是又召回B……如此反复,任务永远收不了口。这种问题在单智能体里不存在,但在多智能体协作里极其常见。
我的处理方式是在协调层加一个“返工次数上限”,每个任务最多允许被踢回修复三次。三次之后如果还不过,这个任务会被标记为失败,并自动上报到决策层,由决策层决定是降低验收标准、更换执行Agent,还是回退整个批次。别小看这个硬限制,加上它之后,我们整个流程从最坏情况“无限死循环”变成了最坏情况“一个批次失败重来”,可靠性完全不在一个量级。
还有一次遇到的级联失效是这样的:协调层把某个基础工具的版本升级了,导致所有依赖它的执行Agent在编译时集体报错。后来我在每个批次结束后加了集成测试兜底,就能第一时间发现这类“单个改动引发连锁崩溃”的问题。
5.4 调试多智能体系统:先看状态机,再翻日志
智能体系统的调试和传统程序完全是两种思路。传统程序出错,你打断点看变量就行;智能体系统出错,往往是“每个环节都看着没问题,但合起来就是不对”,很难通过单点排查找到根因。
我的惯例是第一件事看协调层的状态机流转记录。我让协调层每做一次状态切换,就把“谁、在什么时间、由于什么原因、从什么状态切到什么状态”记成一条结构化日志。排查问题时,先沿着状态流转记录找到最早的异常切换,再去翻对应的执行Agent产物包。这么做的道理很简单:状态机记录的是“系统级的行为”,而日志是“个体级的行为”,多智能体问题绝大多数出在个体交互的衔接上,而不是个体的能力上。
写在最后:这套范式对我最大的改变是什么
跑通这套层级化自底向上的范式之后,我对智能体开发这件事的看法变了不少。以前总觉得AI写的代码能不能用,取决于模型有多聪明;现在觉得,真正决定下限的,是我们有没有把任务边界、验收标准、消息契约这些工程问题处理干净。很多人做智能体开发,模型调来调去、Prompt精雕细琢,效果还是不稳,问题往往不出在“AI不懂”,而出在“我们根本没把需求讲清楚”。
我自己现在接到任何新需求,第一反应不再是写一段妙手偶得的Prompt,而是把需求拆成层级、定义好验收、设计好流程。这个习惯加持下,同一个模型跑出来的产出质量比之前用单智能体硬刚时高出一大截。如果你也在搭智能体应用,我建议你也试试这套思路——不一定要完全照搬我的代码,但从决策、协调、执行三层去重新审视一下你的系统,大概率会有不一样的收获。