资讯动态

AI Agent 如何接管构建-测试-修复循环?一份可落地的实践指南

发布时间:2026/9/26 20:58:17 来源:尧图企业网站定制
干这行的都懂一个画面CI 又红了三行代码改完重新提交等构建、等测试、再发现问题、再来一轮。人肉跑这个循环轻则磨耐心重则压垮排期。过去大半年我一直在折腾一件事——让 AI Agent 自己接管构建→测试→修复→循环这条链路。听起来像自动化测试的 Plus 版?其实不是,它更像把一个初级开发者的活儿包给了一个永不睡觉的实习生,而这个实习生现在已经能独立把一整个开发闭环跑完了。这篇就把我的思路、踩过的坑、以及一套可以直接抄的落地做法完整讲清楚。先说清楚目标读者:你不是研究 Agent 理论的学者,而是一个真正要交付代码的工程师、技术负责人或测试开发。你需要知道的是——AI Agent 到底是什么、它和 DeepSeek 这类大模型是什么关系、闭环里的每一步该怎么设计、会遇到什么鬼问题。看完你能直接动手搭一个最小可用版本。1. 整体思路拆解:这不是简单串四个步骤构建→测试→修复→循环表面上就是四个词,很多人第一反应是这不就是 CI/CD 加了个 AI 修复吗。真做起来,你会发现难点不在单个环节,而在环节之间的信息传递和决策机制。1.1 为什么闭环必须闭环,而不是一条直线开发流程天然是个循环:有失败才有修复,修复完了要重新验证,验证又产生新失败。人肉做这件事,靠的是经验判断——哪个报错是格式化问题,哪个是逻辑缺陷,哪个是环境抽风。这些判断看似简单,真要交给 Agent 做,就得把判断依据拆成机器能读的形式。我见过不少团队搭的半成品:Agent 跑一遍测试,把报错丢给大模型,生成一段代码,应用上去,结束。这不是闭环,这是单次修复。真正能用的闭环,至少包含三个状态判断:测试全绿,流程正常结束测试有失败,但失败类型已知,进入修复流程修复导致的回归比原失败还多,需要回滚并换策略这三个状态要由 Agent 自己判断,而不是靠人盯着日志。这就是闭环和自动修复脚本的区别。闭环的本质是有状态、有决策、有退出条件的运行机制,不是一段 if-else 能糊弄过去的。1.2 Agent、LLM、AI 模型的关系,这里一次性说破很多人在热搜里看到ai agent 和 llm 和 ai模型 有什么区别,其实三者的关系特别像:AI 模型:大脑的神经元层,类似 GPT 系列这种基础能力。LLM(大语言模型):通用语言理解和生成能力的具体化,DeepSeek、GPT-4 这些都属于 LLM。它擅长的是对话、推理、补全,但它本身不会动手。AI Agent:不只是大脑,它是一整套系统——有感知(读取日志)、有决策(调用哪个大模型)、有行动(执行脚本、改代码)、有记忆(记住上一轮哪里失败过)。用大白话说,DeepSeek 是那个聪明但坐在那儿不动的顾问,Agent 是腿脚麻利,知道问顾问、也知道动手改文件的执行者。想用 AI 跑开发闭环,光有大模型远远不够,得有一个编排层,把工具调用、代码修改、测试执行串起来。这个编排层就是 Agent。2. 核心环节拆解:把构建、测试、修复、循环每个动作打磨到位很多人搭闭环的时候,卡在最基本的问题上:构建该构建到什么程度?测试失败信息怎么喂给模型?修复改到什么程度算完?下面一个环节一个环节说。2.1 构建环节:不只是跑一遍编译构建在闭环里担任的角色是确认基线状态。代码能不能编译、依赖能不能解析、产物能不能生成,这些是修复的前提。构建失败和测试失败处理策略完全不同:构建失败,通常是环境问题或依赖问题,比如 Jenkins 里的缓存目录异常、Maven 仓库缺包、Node modules 版本错乱。这种修复不能靠改业务代码,得靠运维手段。测试失败,才是代码逻辑问题,才是 Agent 修复的主战场。所以闭环设计的第一条铁律:构建失败单独一个通道,测试失败单独一个通道。两个通道的提示词、工具完全不同。你让 Agent 拿构建日志去改业务代码,十有八九改出一堆无关改动。实操中构建环节的常见坑,我也踩过:使用 Maven 或者 Gradle 构建时,本地仓库和 CI 仓库不一致,导致本地构建通过、远程构建失败。这种事排查起来特别费劲,Agent 如果没有环境指纹(比如把依赖锁文件和环境变量都采集进去),根本没法定位。我的做法是在构建步骤前采集一份环境快照,包含关键依赖版本和系统信息,一起喂给 Agent。这样它不仅能知道失败在哪,还能知道环境差在哪。2.2 测试环节:让 Agent 学会看失败测试环节是整个闭环的信息源头,也是做得最粗糙的一道工序。很多人直接把 JUnit 或者 pytest 的 output 文本丢给大模型,以为它能读懂,其实不然。原始的测试日志又长又杂,大量堆栈信息混在一起,模型很容易被误导。我在测试环节做得最值的一件事:写了一个失败信息压缩器,把原始测试输出转成一个结构化摘要,包含:失败的测试名,比如test_user_login_success失败类型,比如AssertionError还是TypeError关键堆栈前三行测试涉及的业务模块,从测试路径或注解里提取同一测试上一次通过时的状态对比(如果存在历史记录)为什么要做压缩?因为大模型上下文窗口有限,给太多噪声会让它抓不住重点。特别是早期模型,你给它一屏报错,它可能把一个无关紧要的库调用当成根因。把失败摘要控制在200字以内,修复准确率提升明显。测试的另一个要点是分类。不是你写的每个测试失败都需要修代码,还有几种情况:测试本身写得不稳定(flaky test),重跑就能过测试用例和产品变更不同步,需要改测试而不是改代码数据污染,测试状态没隔离干净我在闭环里设计了一个重试检测机制:失败后先自动重跑一次,如果同样失败,才进入修复逻辑。别小看这个机制,光这一条就能省掉 Agent 大量无效修复。2.3 修复环节:生成补丁前先做病灶定位修复是闭环里最容易翻车的环节。很多初创团队直接把报错日志丢给大模型,让它给个修复,然后 Agent 拿到代码就开始改。结果经常是:改了个表面问题,真正的问题还在改了这个测试,另一个测试挂掉(回归)修改范围失控,触碰了大量和问题无关的代码过去几个月的实践告诉我,修复环节必须拆成两步:病灶定位 → 精准手术。病灶定位阶段,Agent 要做的是判断这个问题是出在哪个文件、哪个函数、哪一段逻辑。这个判断不能只靠测试报错信息,得结合代码结构。我在设计里会先让 Agent 跑一次代码搜索,找出失败测试涉及的主函数,再结合报错堆栈定位到具体行。定位准了,才轮到生成补丁。精准手术阶段,我给 Agent 设置了三条硬约束:一次只改一个根因,不要顺手重构别的改动范围严格限定在病灶函数内部,除非定位到接口层生成结果必须是统一的代码风格,避免引入格式噪声这三条约束对代码修复效果影响极大。没有约束时,Agent 容易好心办坏事;加了约束以后,生成的补丁明显收敛,回归率大幅下降。2.4 循环环节:退出条件比循环本身更重要循环本身不难,一个 while 循环而已。难的是定义什么时候停。如果退出条件不清,Agent 会无限修复下去,越修越离谱,最后把一句话的改动变成十处乱改。我在设计里用了三重退出条件:条件一:所有测试通过,自然结束条件二:同一根因连续修复两次仍然失败,触发人工介入条件三:单轮修复引入的新失败数量超过原失败数量,回滚并触发降级策略(比如换成不同的模型,或者换一套提示词)还有安全阀。实际操作中,我给闭环加了最大循环次数和超时时间。宁可流程失败,也不能让 Agent 无限跑下来,否则就是个失控的算力黑洞。这个道理和异常处理一样:循环可以由 Agent 决策,但兜底必须由人来定。3. 从零到一落地:一个最小可用的 AI Agent 闭环实现思路说完了,下面是最受关注的部分——具体怎么搭。这个最小实现不需要烧钱,也不用复杂框架,一台开发机加一个大模型 API 就够了。我以 Python pytest 为例,但思路完全能平移到你自己的技术栈。3.1 技术选型:搭建骨架的四块积木我当时选型遵循一个原则:能少依赖就少依赖。Agent 闭环的核心编排逻辑完全可以自己写,没必要一上来就上重型 Agent 框架。四块积木分别是:代码仓库:用 Git 管理,每个修复补丁独立分支,方便回滚构建/测试工具:我用 pytest Jenkins 做演示,实际可以换成你任何已有工具LLM 接口:我用的是兼容 OpenAI 接口的模型服务,DeepSeek 这类模型都能直接接编排层:自己写一个 200 行左右的 Python 控制脚本,负责串起整个流程别小看这种土办法。框架能帮你做的事,自己写脚本也能胜任;而框架束缚你的地方,自己写脚本却可以灵活避开。尤其是调试 Agent 行为时,自己掌握编排逻辑会省很多事。3.2 核心实现:控制循环的四个关键函数整个编排脚本我拆成了四个函数,和标题四个步骤一一对应。需要注意,真正的闭环不是直线调一遍,而是像下面这样滚动判断:第一步,构建函数:拉取最新代码,执行构建命令,返回构建产物状态。如果构建失败,读取构建日志中的依赖阶段报错,直接走环境修复通道;只有构建通过才进入测试。第二步,测试执行与摘要函数:运行 pytest,把结果转换为测试摘要结构。这个结构包括通过数、失败数、失败用例详情。它是后续修复的输入,所以格式必须固定,方便大模型解析。第三步,修复函数:把失败摘要和对应源码片段拼接成 prompt,调用 LLM 生成 patch,然后应用 patch、重新构建、重新测试。这是闭环的执行核心。第四步,循环控制函数:根据测试结果判断是否继续回圈、终止、回滚,并维护一个修复历史列表,记录每一轮的根因和修改内容,防止 Agent 重复修同一个问题。把四个函数串一起的伪代码大概是这样的:while attempts max_attempts: build_status build(repo) if not build_status[ok]: fix_environment(build_status[logs]) continue test_result run_tests_with_summary(repo) if test_result[failed_count] 0: print(全绿收工) break if is_same_root_cause(test_result, history): print(同一根因重复修复失败交人工) break patch generate_patch(test_result, source_context) apply_patch(patch) register_fix(history, test_result, patch) attempts 1这个循环写得比实际项目要简洁,但核心逻辑就是这样。加一个历史记录,修复效果直接上一个台阶。3.3 提示词设计:把失败上下文喂给模型的正确姿势给模型写修复提示词,很多人犯的错是把它的角色定义成代码专家然后就完事了。我试过,效果一般。真正好用的是结构化上下文 明确任务。我现在用的格式固定成四段:第一段,角色与规则:告诉模型你是一个修复代码缺陷的工程师,只修改根因,不重构无关代码,输出格式为统一 patch。第二段,失败摘要:把测试环节生成的压缩摘要原样放进去,这是模型做判断的主要依据。第三段,相关源码:只放病灶函数及直接调用方的代码,其余代码一律不放。这样做是控制 token,也是避免干扰模型判断。第四段,输出要求:明确要求给出完整 diff,并解释修改理由,不超过 200 字。这样组合下来的提示词,修复准确率比单纯丢报错高出不少。把上下文喂进模型,比把上下文甩给模型,差别在执行效果上非常明显。3.4 一次实际运行实录:从报错到全绿的完整链路拿一个我跑过的真实案例来复盘。那是一个常见 Web 项目,Jenkins 构建输出有大量警告但能通过,pytest 出现 3 个失败测试。系统第一个循环运行,测试摘要显示,三个失败分别来自用户模块两个、订单模块一个。Agent 在病灶定位阶段发现,用户模块的两个失败其实指向同一个根因:登录接口改了入参没同步改测试;订单模块的失败则是测试数据依赖不清理导致的偶发失败。修复策略因此分化:用户模块生成 patch 更新测试;订单模块没有动生产代码,而是补了数据清理逻辑并重跑验证。第二轮循环下来,三个测试全绿,整个流程耗时约4分钟。相比之下,人工处理同样的问题,保守估计需要一上午,还得来回盯日志。4. 常见问题与排查技巧实录:这里全是我踩过的坑写这篇的时候我特意回头翻了翻自己过去几个月的修复记录,发现踩过的坑基本都集中在四个方向。这几个问题,如果你照着我上面这套逻辑去实现,八成也会遇到,提前把话说透。4.1 日志编码与截断问题第一次跑通闭环的版本,Agent 经常报错无法识别日志内容。排查下来发现,不是模型傻,是构建日志里有大量非 UTF-8 编码字符,加上长日志被控制台截断,喂给模型的信息根本没到位。解决办法是标准化日志采集。在进入修复通道前,我用脚本统一把日志转成 UTF-8,并按规则裁剪到模型上下文窗口的安全范围。宁可少给,也不能给乱码。还有一次是 Windows 下路径分隔符变成了反斜杠,模型解析路径时直接崩溃。后来我在采集阶段就把路径统一处理成正斜杠,问题消失。4.2 过度修复与回归修复这是整个实践里最头疼的问题,没有之一。Agent 定位到一个 bug 后,经常顺手把旁边一段代码也优化了。比如明明只需要改一个判断条件,它会把注释、变量命名、缩进全动一遍。结果就是主测试过了,连带的责任测试挂了一片。我这里还专门做过实验:同样的问题,不加改动范围约束,修复后引发回归的概率大约 40%;加了约束之后,回归率降到 12% 左右。别轻视 Agent 的顺手,它动起手来比勤快的同事还夸张。预防措施就一条,在修复通道里加改动边界校验:以 Git diff 形式输出 patch 前,先对比改动文件数和改动行数。一旦改动行数超过阈值(比如 50 行),强制拆分或拒绝直接应用,提示 Agent 缩小范围。这个阈值我在不同项目里调过,定在 30~80 行之间效果最好,看项目复杂度。4.3 无限循环防不胜防循环控制函数设计得再好,还是有拦不住的时候。有一次 Agent 修了一个并发问题,生成的补丁解决了原有的竞态条件,却又引入了一个新的死锁。三个测试里两个没过,其中一个是新引入的失败。因为根因对象变了,历史记录里没有匹配到同源信息,于是循环继续。结果就是那一次流程硬生生跑了 7 轮,直到触发我设的最大次数上限才算停。事后复盘,我发现问题出在历史记录设计得太简单,只记录了根因标签,没记录哪些测试曾经通过、现在失败的回归指纹。后来我给历史记录加了回归指纹这个字段,一旦发现某个测试从绿色变红色,立刻触发回滚而不是继续修复,效果立竿见影。4.4 闭环运行小工具与状态信息速查最后分享几个我用到的排查小工具。构建环节如果出现依赖相关报错,mvn dependency:tree或者gradle dependencies能快速看出依赖冲突。测试环节,JUnit 和 pytest 都支持只跑失败用例的参数,反馈速度会快很多。定位代码归属时,git log -L可以按函数逐行查看历史变更,这对 Agent 判断这次修改破坏了哪个行为特别有用。下面这个表把几个高频问题、根因、解决方案汇总出来,方便你直接对照:现象常见根因处理建议构建在本地通过但在 CI 失败本地与 CI 的依赖版本不一致构建前采集环境快照,把依赖锁文件一并喂给 Agent测试失败但重跑通过flaky test,状态未隔离失败后增加一次重跑校验,不直接把偶发失败交给修复Agent 修复导致回归修改范围过大加改动边界校验,超过阈值强制不收同一个失败反复出现历史记录缺少根因指纹在历史记录中增加根因标签 失败用例 修复补丁三元组模型返回内容不可解析上下文被截断或编码异常标准化日志采集,按窗口裁剪,路径统一正斜杠等你把这些都跑顺了,还会发现一个新境界:Agent 修完一个测试,你根本不需要再看一眼日志它能自己确认全绿、提交补丁、甚至发起合并请求。这个过程中你头顶着一层薄汗,手指悬在回滚键上——但我实测下来,这层焦虑正在一天天变薄。以后我再折腾的方向,大概是给这个闭环加上解释能力,让 Agent 每次修复完都写一段人话总结,然后让这些总结沉淀成一个知识库,供下一次修复直接引用。这会让整个系统越来越聪明,而不是每次从零起步。如果你也在做类似的事,欢迎带着你的失败案例来交流——毕竟在 AI Agent 这块,真正让人进步的从来不是那些漂亮跑通的 demo,而是那些没跑通的坑。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑