Code Agent 要稳定提升代码生成质量,关键不是简单增加更多角色,而是把“生成代码、独立设计测试、真实执行并反馈”拆成职责清晰的闭环。AgentCoder 的核心做法是让编程智能体负责初稿与修复,让测试设计智能体只依据需求构造测试,再由测试执行智能体在本地环境运行代码;失败信息回到编程智能体后进入下一轮,直到测试通过或耗尽迭代预算。这样的协作把语言模型的主观判断转化为可执行反馈,也减少了同一个上下文同时写代码和自证正确所产生的偏差。
多智能体并不天然优于单智能体。真正有价值的是职责分离后,每个角色拥有不同输入、输出和判断依据,并由确定性的执行环境连接起来。对代码生成任务而言,可以把协作接口压缩为需求、候选代码、测试集合和执行报告四种对象,避免智能体之间进行冗长而无结构的讨论。
编程智能体接收完整需求,先澄清输入输出、约束和异常行为,再选择算法、形成实现并输出候选代码。首次生成之后,它不应每轮都推翻全部方案,而应读取结构化失败报告,判断问题属于语法错误、运行时错误、断言失败、超时还是资源消耗异常,再针对失败点修改。这样可以保留已经通过验证的部分,降低无关改动带来的回归风险。
编程智能体的输出还应满足机器可处理的契约。例如,代码与解释分离,入口函数、语言版本和依赖声明明确,禁止在代码块外混入会破坏执行的文本。如果任务允许多个文件,还应提供固定的文件清单和内容映射。执行器只有拿到稳定格式,才能自动建立临时环境并准确返回错误位置。
测试设计智能体依据需求而不是候选实现生成测试,这是整个方案的重要设计。若同一个模型在同一上下文里先写实现再写测试,它很容易沿用实现中的错误假设,让测试只覆盖代码已经处理的路径。独立测试角色看不到完整实现,可以从规格出发检查正常输入、边界输入和较大规模输入,从而形成更客观的验收条件。
测试集合至少应覆盖三层。基础用例验证主要功能和典型路径;边界用例处理空集合、零值、重复值、极端大小、非法格式等容易遗漏的条件;规模用例观察算法在较大输入下是否仍能结束并满足性能约束。并非每个题目都需要巨大数据,规模测试必须根据题目限制设置,否则测试自身可能成为噪声或造成不必要的资源消耗。
测试执行智能体与前两个角色不同,它的核心能力不是继续推理,而是在隔离环境中实际运行候选代码和测试。它收集退出码、标准输出、标准错误、断言差异、耗时与资源状态,再把结果整理成编程智能体能够使用的报告。真实执行能发现纯文本审查容易漏掉的语法、类型、导入、边界和运行时问题。
执行器应该尽量保持确定性。相同代码、测试和环境配置应得到相同结果;网络、系统时间、随机数和文件访问需要禁用、固定或显式注入。对于不可信代码,还要设置进程隔离、超时、内存限制、只读文件系统和最小权限。论文中的实验主要面向代码生成基准,实现工程化 Code Agent 时不能把“本地执行”误解为可以直接在开发者主机上无限制运行模型输出。
一次完整迭代可以表示为:需求同时进入编程与测试设计角色,二者分别产生代码和测试;执行角色组合二者并运行;全部通过则返回候选代码,失败则生成反馈并要求编程角色修复。后续轮次复用测试集合,并在发现规格盲点时追加测试。循环必须设置最大轮数、时间预算或 Token 预算,不能只以“直到成功”为停止条件。
requirement = normalize(user_request)
code = programmer.generate(requirement)
tests = test_designer.generate(requirement)
for round in range(MAX_ROUNDS):
report = executor.run(code, tests)
if report.all_passed:
return code, report
code = programmer.refine(
requirement=requirement,
current_code=code,
failure_report=report.compact()
)
return failure("iteration budget exhausted", code, report)
这里的关键不是循环本身,而是反馈的质量。只返回“测试失败”几乎没有帮助;只把整个终端日志原样塞回上下文,又会引入大量噪声。更有效的反馈应包含失败测试标识、输入摘要、期望值与实际值、异常类型、相关堆栈片段、执行耗时,以及哪些测试已经通过。对于输出很长的情况,应保留首尾和定位信息,并对重复日志折叠。
修复后应重新运行全部测试,而不是只运行上一轮失败的测试。失败用例适合提供快速反馈,但全量回归才能确认修改没有破坏此前正确的行为。如果测试设计角色在后续轮次新增用例,也要为测试变化记录版本,避免编程角色面对不断移动却无法追踪的验收目标。
AgentCoder 采用三个简单角色,而不是模拟完整软件公司的大量职位。论文强调的差异点在于有效测试和较小的通信开销:编程与测试生成相互独立,执行器用真实运行结果连接双方。由此可以推断,Code Agent 的竞争力更多来自反馈是否可靠、上下文是否干净以及闭环成本是否可控,而不是角色名称是否丰富。
如果需求只是补全一个短函数,规划、架构、评审、产品和项目管理等多个角色可能只会重复转述同一任务。每增加一个智能体,都会增加提示词、上下文同步、冲突处理和失败恢复成本。只有当角色拥有独立信息源、不同工具权限或明确验收责任时,拆分才有意义。测试设计角色拥有独立规格视角,执行角色拥有真实运行环境,因此这两种拆分具有可验证的功能差异。
反过来,角色也不必绑定不同模型。工程系统可以使用同一个底层模型,通过隔离上下文、不同系统指令和不同工具权限实现角色分工;也可以让强模型负责需求理解和修复,让成本更低的模型生成候选测试,再由非模型程序执行。选择依据应是正确率、延迟和成本,而不是形式上的“多模型”。
首先要把自然语言需求规范化。至少提取函数签名、输入类型、输出语义、异常策略、性能限制和允许依赖。含糊项不能由不同角色各自猜测;可以由入口层形成统一假设,并把假设同时发送给编程与测试设计角色。否则一方把空输入视为返回空结果,另一方却期待抛出异常,反馈循环就会修复一个并不存在的代码缺陷。
其次,为中间产物定义结构化格式。候选代码应带语言、入口和文件信息;测试应带名称、类别、输入、预期结果和超时;执行报告应带状态、失败阶段和精简诊断。结构化数据便于校验、缓存和重放,也能防止某个智能体用自然语言指令影响另一个角色的系统边界。
{
"status": "assertion_failed",
"test_id": "edge-empty-input",
"expected": "[]",
"actual": "exception: IndexError",
"duration_ms": 18,
"location": "solution.py:12"
}
再次,保留每轮变更轨迹。系统应记录代码摘要、测试版本、失败类别和修复说明,但不必把全部历史在每轮重新发送给模型。可以只提供当前代码、最新失败和少量稳定约束,把完整记录留给审计与故障恢复。当同一失败连续出现、错误数量增加或修改在两个状态间往复时,应提前终止并交给人工,而不是机械耗尽预算。
最后,设置分层验收。生成阶段的合成测试用于快速纠错,项目已有单元测试用于检查兼容性,静态分析、类型检查和安全扫描用于覆盖测试之外的风险。若代码将进入真实仓库,还需要在干净工作区执行构建和受影响测试,并展示差异供开发者审批。智能体生成的测试不能替代项目维护者定义的验收标准。
测试全部通过只说明代码满足当前测试集合,不能证明实现对所有输入都正确。测试设计智能体也可能误解需求、生成错误断言或遗漏关键分支。一旦错误测试被当作唯一真相,编程智能体甚至会把正确代码修改成迎合错误断言的实现。因此,系统要区分“代码失败”和“测试可疑”:测试无法执行、预期值相互矛盾、测试依赖未声明行为时,应先复核测试,而不是直接要求改代码。
还要防止候选代码影响测试基础设施。不可信实现可能读取测试文件、篡改结果、长时间占用资源或通过环境侧信道获取预期值。测试与代码应位于权限隔离的路径,执行器负责注入测试并在结束后销毁环境;判定结果的逻辑不能由候选代码控制。涉及密钥、网络和真实用户数据的环境不应向生成代码开放。
论文报告的 HumanEval、MBPP 及其增强版本结果说明该架构在特定代码生成基准上有明显效果,但这些指标不能直接外推到大型仓库改造、并发系统、界面交互或长期维护任务。基准题通常边界清晰、入口固定,而真实项目还包含依赖解析、跨文件影响、非功能需求和组织规范。落地时应先用自己的任务集测量一次成功率、迭代次数、回归率、延迟和成本。
评估不能只看最终通过率。至少需要同时观察首次生成通过率、迭代后通过率、平均修复轮数、测试误判率、全量回归失败率、单任务 Token 与执行成本,以及超时和人工接管比例。若迭代后通过率提高,但测试经常给出错误预期或成本成倍增长,系统仍不适合生产使用。
消融评估也很重要。可以分别关闭独立测试设计、真实执行或迭代修复,比较质量与成本变化;也可以让编程角色同时生成测试,再与独立测试角色比较。只有这种对照才能判断提升来自角色分离、更多采样、额外 Token,还是执行反馈本身。论文同样通过不同角色组合与迭代次数分析各部分贡献,这比只展示一个最佳结果更能说明机制。
实际建设时,可以先实现一个最小版本:一个编程提示模板、一个独立测试提示模板、一个受限执行器和最多三轮修复。选取一组有明确规格与现有测试的内部任务离线评估,确认日志结构、停止条件和安全隔离可靠,再逐步接入仓库检索、静态分析或代码评审。不要一开始就增加大量角色和长链路编排。
当任务扩大到仓库级修改时,新的角色仍应围绕独立能力增加。例如检索角色负责定位相关文件并提供带证据的上下文,评审角色检查补丁是否违反项目约束,但最终反馈仍要尽可能落到编译、测试、类型检查或静态规则等可验证信号。无法验证的意见应标记为建议,不能与执行失败混为一谈。
因此,编程、测试与反馈智能体协作的真正优化路径,是让生成与验收相互独立,让执行环境提供客观证据,再以有限预算进行针对性修复。三角色只是一个清晰的最小结构;决定效果的,是规格是否一致、测试是否有效、反馈是否精确、执行是否安全,以及系统能否在证据不足时停止并请求人工判断。