ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

AI Agent改造遗留系统:棕地工程的7条反直觉法则

AI Agent改造遗留系统:棕地工程的7条反直觉法则 这几年只要聊到 AI Agent大家默认讲的是“绿地工程”一个新项目、一套新技术栈、一个可以随便折腾的环境。但我大部分时间干的其实是“棕地工程”——在那些跑了十年以上、文档过期、模块纠缠不清、连原作者都说不清某些逻辑的遗留代码库里做改造。把 AI Agent 弄进这种系统里远不是接个大模型、配几个工具那么简单。我踩了不少坑也被 Agent 坑过才慢慢总结出几条反直觉的法则。这篇博文就是想把“棕地 Agent 工程”的真实玩法讲清楚它是什么、为什么难、怎么落地、有哪些坑必须避开。我不会给一个漂亮的 Demo 演示也不会只讲理论。我会按实际做过的架构方案、踩过的坑、最后沉淀下来的 7 条反直觉法则来写。适合谁看主要是系统架构师、后端技术负责人、在遗留系统里挣扎的开发同学。如果你正准备给老系统引入 Agent或者已经被老板要求“给老代码配上 AI 助手”这篇文章值得你花十分钟读完再动手。1. 为什么“绿地 Agent”经验到了“棕地”就失灵1.1 绿地与棕地的本质差异“绿地工程”就像在一块空地上盖新楼地基、管线、结构都可以按最新标准设计。Agent 在这种环境里干活天然占便宜代码量小、模块边界清晰、文档可以随代码同步生成大模型本身也见过大量类似的最佳实践所以随便搭一个框架就能跑出不错的效果。但“棕地工程”是在一栋老楼里做改造。地基是二十年前打的承重墙不能动水管电线早就被装修过几轮你连哪条线是通的都要现查。遗留代码库就是这样用着老掉牙的技术栈模块之间既有直接调用又有消息队列绕来绕去的间接依赖还有各种藏在配置文件里的魔法值。你让 Agent 在这栋楼里干活它面对的不是“怎么实现新功能”而是“怎么在理解一团乱麻的情况下做对一次小改动”。我见过很多团队把绿地那套经验直接搬过来给 Agent 配上写文件、跑命令、调接口的权限让它自主完成需求。结果呢在一个只有两万行的新项目里它表现很好到了几十万行的老系统里Agent 开始在错误的地方加代码或者把原本能跑的配置改坏。原因不在于大模型变笨了而是棕地的“信息噪音”把 Agent 淹没了。1.2 遗留代码库的三个“隐性杀手”先说第一个上下文炸弹。大模型的上下文窗口再大也不可能装下一个几十万行的代码库。哪怕你硬塞进去超出一定规模后模型对细节的注意力会严重下降经常“记不住”之前读到的关键函数。这个问题在工程上不是靠换一个更大窗口的模型能解决的而是要靠信息筛选架构来解决。第二个是隐含契约。遗留系统最坑的地方在于很多行为规则根本不在文档里而是在历史 bug 修复的补丁里。比如某个字段不能为空不是因为数据库约束而是因为二十年前某次上线发现空值会引发严重问题后来人靠“约定俗成”把它写进了代码注释。Agent 不知道这些约定它会按照“标准做法”把校验逻辑“优化”掉然后触发线上事故。第三个是工具链碎片化。老系统往往混着多种技术栈一部分 Java、一部分 Python 脚本、一部分存储过程、一部分当年的老框架。Agent 要干活必须能操作这些不同的工具链但它们的构建方式、运行方式、日志格式完全不一致。一个只会在统一环境下跑命令的 Agent在棕地里寸步难行。所以你看棕地 Agent 工程的核心问题不是“模型够不够聪明”而是“你能不能把老系统的混乱变成 Agent 可以理解的结构”。下面这 7 条反直觉法则就是围绕这个核心展开的。2. 法则一先画“代码地图”再谈 Agent 改造2.1 反直觉点Agent 最大的价值不是写代码而是读代码一提到“AI Agent 改造遗留系统”绝大多数人的第一反应是“让 Agent 帮我改代码”。但我在实际操作中有一条完全反直觉的经验初期让 Agent 写代码价值极低让 Agent 大量地“读代码”价值极高。遗留系统最大的成本是认知负担。新入职的工程师光是为了搞清楚“某个订单状态在哪里被改变、哪些调用链会影响它”往往要花一到两周。而大模型读代码的速度比人快几个量级它缺的只是信息检索结构。如果你能把代码库组织成一份“地图”Agent 就能像老员工一样精准定位问题而不是像新人一样瞎逛。我所谓的“代码地图”不是画一张架构图那么简单而是三层东西符号与调用索引把类、函数、变量、接口调用、依赖关系全部结构化相当于给代码库建了一个数据库。模块语义摘要对每个模块用自然语言描述“这个模块做什么、依赖什么、被谁依赖、常见坑是什么”让 Agent 不必每次从头读所有源码。演进过程中的“常识沉淀”把团队长期积累的约定、架构决策、已知陷阱写进地图附注相当于代码库的“维基百科”。不要小看这三层很多团队连第一层都没做好。没有索引Agent 每次提问都要全库扫描既慢又费 token而且扫描出来的结果经常是垃圾。2.2 实操用索引、图谱和摘要建地图具体怎么建我按实际做过的流程说一遍。第一步先用代码分析工具我们当时用了基于 tree-sitter 的解析方案你也可以用开源的代码知识图谱工具把代码库解析成一棵语法树提取所有关键符号、函数签名、类型定义、跨模块引用关系。注意这一步的目标不是“正确理解”而是“建立准确的索引数据”所以宁可多提取也不要漏。第二步把符号索引导入图数据库或者结构化存储构建调用图谱。有了图谱Agent 就能回答“这个函数被谁调用”“这条调用链上有哪些分支”这类问题。这一步我之前在项目里就是拿现成的开源组件改的重点在于把不同语言的分析结果统一成同一种数据模型方便后续 Agent 使用。第三步生成模块摘要。这一步我强烈建议不要全部交给大模型一次“读完”而是分层次先按顶层模块、再按子模块、再按关键文件逐级汇总。每一层只读当前层的源码和依赖关系生成一段不超过几百字的摘要然后把摘要连同下层模块的摘要链接一起存起来。2.3 经验地图要长在 CI 里不是一次性文档我见过有人把代码地图做成了 Word 文档画了几天图发出去没人看下次重构之后就过期了。这是典型的“一次性地图”思维没用。正确的做法是让代码地图成为持续构建的一部分每次代码合并后自动更新符号索引、调用图谱、模块摘要并检查摘要与代码之间的偏差。我们不要求摘要做到完全实时但至少要让某个模块被大幅修改时系统会标记“该模块摘要可能过期”提醒人或者 Agent 重新刷新。我当时在一个老系统上先花了两周把这个地图基建搭起来之后再接 Agent整个团队的检索效率明显提升。Agent 定位一个需求相关代码的时间从“经常找不到”变成“几乎一次命中”。注意地图不是给 Agent 一个人用的。团队新人也靠它快速上手代码评审时也能快速判断模块影响范围。这是一笔对人和 Agent 都划算的投资绝对不要把地图做成“只有 Agent 能查”的黑盒。3. 法则二把上下文窗口当成“稀缺资源”而不是超大内存3.1 为什么全量塞进上下文必翻车很多人纠结“ai agent token 是什么意思”本质上是没理解 token 是 Agent 的预算不是内存条。大模型处理输入、输出都要消耗 token。你在上下文里塞了大量无关代码模型确实“能看”但它会花大量注意力在无关内容上导致真正需要关注的逻辑被稀释。我在早期做过一次测试让 Agent 在一个 50 万行的老系统里改一个接口我把整个模块的源码都塞进上下文。结果它过渡关注了一些调用频率不高的边缘分支把主流程改出了一个边界条件错误。后来换成“按需检索 分层摘要”同样的问题一次就对了。所以我给团队的硬性要求是每个任务的上下文只能包含“完成该任务所需的最小信息集”。上下文窗口再大也要按稀缺资源来规划。3.2 检索优先架构问题分解、按需取用、分层摘要那怎么做到“最小信息集”我的架构是三段式第一段问题分解。Agent 接到任务后不直接读代码而是先把任务拆成若干子问题。比如“给订单新增一个取消原因字段”拆成“找到订单表结构定义”“找到创建订单的入口服务”“找到订单状态流转的校验逻辑”“找到所有涉及订单字段写入的地方”。第二段按需检索。每个子问题通过代码库检索接口基于第一步建好的索引和图谱获取相关代码片段。注意这里不是让 Agent 自己用浏览器去搜而是预先封装好几个检索工具按符号名搜索、按调用链查询、按关键词搜索、按模块摘要读取。Agent 每调用一次工具就拿回一小块精炼的信息。第三段分层摘要。对于必须理解整体逻辑的大模块不让 Agent 直接读全部代码而是先读模块摘要再按需往下钻取子模块摘要最后才是具体函数源码。这个“先总后分”的顺序很关键能极大降低 token 消耗和理解偏差。3.3 token 预算与成本控制的一些参考值给你一组我实际用过的参考值不是标准答案但能帮你心里有个底单任务总 token 预算控制在模型最大上下文的一半以内。比如模型支持 128K 上下文就让单任务最高消耗 64K留出余量给输出。每次检索返回的代码片段不超过 30~50 行强制按函数或方法级别粒度返回避免一次拉回一整个文件。模块摘要单份控制在 500 字以内超过就进一步拆分。日志、错误堆栈、测试输出等辅助信息按行截断只保留最相关的部分。这组数值看起来保守但实际用下来效果很好任务成功率上升、响应速度变快、token 成本下降。说白了棕地系统里的信息本来就乱你主动做“信息瘦身”比让模型自己从乱麻里扒线头要靠谱得多。4. 法则三工具不是越多越好而是“权限越小越好”4.1 反直觉点给 Agent 的每一个工具都是攻击面很多 Agent 框架默认会给你配一堆工具读写文件、执行命令、调用 HTTP 接口、发消息。看起来功能很强但在遗留系统里这是灾难的根源。你给 Agent 的工具越多它在真实系统里能触碰的东西就越多一旦它基于错误理解执行了破坏性操作后果无法预料。我有个比较极端的观点给 Agent 的每个工具都是攻击面。棕地工程里你不仅要防黑客也要防 Agent 自己造成的“内部事故”。Agent 没有恶意但它会在信息不足时“补全”自己的理解而它一旦拥有写权限那点“补全”就可能变成线上 bug。4.2 最小权限工具集设计在我们实际的棕地 Agent 系统里工具集被我砍到只剩 6 个代码检索按符号、调用链、关键词查询代码这是只读的最安全也最常用。文档与摘要查询读取模块摘要、架构记录、团队沉淀的常识。单测执行只允许跑指定的测试文件或测试类不允许执行任意命令。日志查询按时间、服务、关键字查日志只读。生成 diff 文件Agent 可以改代码但修改只允许产出本地 diff不允许直接写入主干分支。创建 Pull Request所有改动必须通过 PR 提交且 PR 创建后必须等待人工审批Agent 不能自我批准。注意我没有给 Agent 线上配置修改、数据库写入、全局文件替换、部署命令等工具的权限。哪怕某些时候它“需要”也不给。需要的时候怎么办让人来做或者走另外一套经过严格审批的发布流程。这是底线。4.3 工具命名与描述Agent 的“盲人摸象”效应还有一个容易被忽略的细节工具的描述怎么写直接影响 Agent 能不能正确使用。你想想Agent 是“盲人摸象”它看不到整个系统只能通过工具描述来理解每个工具的用途。如果工具描述写得含糊比如“执行命令”它会在不确定时尝试各种奇奇怪怪的命令如果描述写得具体比如“运行指定目录下的单元测试适用于验证模块行为”它就会在合适的时候调用。我见过一个很典型的案例我们给 Agent 配了一个“读取数据库 schema”的工具描述里没写清楚“只读、连接到预发布库、禁止生产环境”结果 Agent 在某个任务里直接连上了生产库的只读副本虽然没造成破坏但把团队吓了一跳。后来我把所有工具描述统一加上了边界条件“适用于 XX 情况禁止用于 XX 情况”Agent 的误用率立刻降下来了。所以工具设计不是“配齐功能”而是“定义边界”。边界越清晰Agent 越安全人也越放心让它干活。5. 法则四不要全自动要“人在环上”5.1 全自动等于事故放大器很多 Agent 产品喜欢强调“全自动完成任务”听起来很酷但在棕地工程里“全自动”等于“事故放大器”。遗留代码库的信息不完备、隐含契约多、工具链复杂Agent 在任何一个环节的错误理解都会被“全自动”这个放大器放大成线上故障。我自己就经历过一次早期搭建 Agent 时给了它比较宽的自主权限它自己读代码、自己改、自己跑测试、自己提交。头几次看着挺顺利直到有一次它“优化”了一段老代码把异常捕获的顺序改错了导致某个报错被吞掉线上出现了诡异的数据不一致。虽然影响不大但已经足够让人冒冷汗。那次之后我把 Agent 的自主度从“全自动”降到了“人在环上”而效果反而变得更好原因是人的介入不是“拖后腿”而是提供了 Agent 无法获取的隐性知识。人看一眼方案的 diff就能立刻反应出“这个改动会不会影响某个老逻辑”Agent 做不到这一点。5.2 关键节点的四种人工审批点那具体在哪些节点强制人工介入我总结为四个检查点第一个是方案设计点Agent 在执行任何改动前先产出一份“计划书”包括改哪些文件、为什么改、预期影响是什么。人在这一步看方向对不对。第二个是核心模块修改点如果 Agent 要动的代码位于核心调用链上必须停下来等人审。这不是不信任 Agent而是核心模块的风险收益比不支持“先改了再看”。第三个是批量重构点涉及全局重命名、多文件同步修改、接口签名变更这类跨模块操作必须人工确认全局影响面。第四个是合并前审查点Agent 生成 diff 并创建 PR 后必须由人做代码评审评审通过才能合并。这四个检查点并不复杂但它把 Agent 的工作模式从“无人驾驶”改成了“高级实习生”。你要接受一个事实棕地工程里人机协作的效率永远高于 Agent 单干因为“人”本身就携带了大量未文档化的上下文。5.3 如何设计“机器干活、人看门”的协作流具体协作流我是这么设计的Agent 收到任务后先提出计划等待“计划确认”事件。人确认后Agent 开始准备改动生成 diff。diff 生成后自动关联到对应的代码评审系统同时触发测试流水线。人在评审界面看 diff、看测试结果、看 Agent 的推理过程摘要决定 approve 还是驳回。驳回时返回原因Agent 根据反馈修改后重新提交。这套流程跑顺之后团队对 Agent 的信任度会逐步提升。更重要的是每一次人的驳回意见都被沉淀成“反馈数据”后续可以用这些反馈持续优化 Agent 的提示词和工具使用策略。棕地工程里的 Agent 不是一次配好就完事它是一个需要人机互相磨合的系统。6. 法则五补测试基建比写 Agent 本身更优先6.1 没有快速反馈Agent 就是盲人开车我特别想把这条法则放在靠前的位置因为太多团队栽在这里。他们花了大量精力把 Agent 调得能写代码却没有一个能快速告诉 Agent“你改坏没有”的机制结果 Agent 越改越离谱。打个比方Agent 就像一个驾驶员测试基建是仪表盘。没有仪表盘驾驶员只能凭感觉开开得再快也迟早翻车。在遗留系统里测试覆盖率普遍偏低很多模块的逻辑是“靠线上运行验证”的根本没有自动化可依赖。这时候让 Agent 放开手脚改代码就是盲人开车。6.2 给 Agent 配“测试跑鞋”特征测试与契约测试那怎么补不是让你一夜之间把整个老系统的单元测试补到 90%这不现实。我推荐的路径是先补两类“高杠杆”的测试第一类是特征测试也叫“行为锁定测试”。把现有系统的关键行为用测试固定下来比如“当输入 XX 时输出必须是 YY”“当订单状态为已取消时不能再执行发货操作”。这类测试不需要覆盖所有分支只需要覆盖核心业务流程和最容易出错的边界条件目的是防止 Agent 改动时破坏已有行为。第二类是契约测试。遗留系统最怕“改了 A 模块B 模块静默出错”。契约测试专门验证模块间接口的兼容性比如“A 调用 B 时参数格式必须满足 B 的预期”。有了契约测试Agent 修改 A 模块时如果破坏了 B 的接口预期测试立刻报红Agent 就能在合并前发现问题。我当时在一个 Java 老系统里做这件事花了大概三周给 5 条核心业务链路补齐了特征测试给 20 多个跨模块接口补齐了契约测试。效果立竿见影Agent 改动后引入回归 bug 的数量大幅下降团队对 Agent 产出的信任度也上来了。6.3 先把 CI 的反馈时间打下来补了测试还不够反馈速度也必须跟上。如果一次测试跑四十分钟Agent 每改一次就要等四十分钟迭代效率会非常低而且 Agent 的“耐心”也会迅速耗光。我建议把 CI 反馈时间压缩到 10 分钟以内不行就拆分测试执行层级快速层运行与本次改动相关的测试子集3 分钟内出结果。完整层合并前运行全量核心测试10~15 分钟出结果。深度层部署到预发布环境后运行全量集成测试允许 30 分钟以上。这样 Agent 在开发期主要依赖快速层快速发现错误人的评审则依赖完整层保证最终质量。测试基建补齐之后Agent 才真正开始变得“好用”。注意不要在没有测试反馈的情况下让 Agent 大规模改代码。我自己在这上面栽过跟头所以现在每个 Agent 打交道的老系统第一优先级永远是“先给仪表盘通电”。7. 法则六变更要可观测、可回滚、可审计7.1 反直觉点Agent 的每次动作都要留痕这条法则听起来像废话但实际做到的人很少。很多团队让 Agent 跑起来之后根本不记录它做了哪些操作只在出问题时翻看代码 diff然后又得靠人肉推理“Agent 到底改了什么、为什么改”。在棕地工程里你必须把 Agent 当成一个“需要审计的自动化流程”而不是一个“聪明的助手”。每次动作都要留下痕它访问了哪些文件、调用了哪些工具、生成了哪些中间结论、修改了哪些代码、运行了哪些测试、谁批准的、谁驳回的。我们当时给 Agent 设计了完整的操作日志系统每一次工具调用都会自动记录时间、调用者、调用参数、返回结果摘要、关联任务 ID。这套日志在后来的复盘和故障排查里价值巨大。有一次线上出现了一个诡异问题就是因为 Agent 在一周前“顺手”修改了一个配置文件当时所有人都在忙别的没细看一周后才暴露。要不是有操作日志我们可能得排查好几个小时才能定位到那次改动。7.2 操作日志、Diff 追踪、一键回滚要实现可观测、可回滚、可审计我在架构上做了三件事第一操作日志全量落库至少保留 90 天方便追溯。每条日志不仅是“调用了工具”还会带上 Agent 当时的任务 ID 和“推理摘要”这样你能知道它为什么调用这个工具而不仅仅是它调用了什么。第二每次 Agent 改动必须独立分支、独立 diff绝对不允许直接在主干上改。这样任何一个改动都可以单独回滚而不影响其他并行的工作。我们还做了一个“一键回滚”脚本输入 PR 号自动把合并的改动还原成之前的版本同时保留回滚日志。第三引入一个“守护进程”概念。它不是控制 Agent而是实时监控 Agent 的行为如果测试失败、diff 改动量异常大、或者修改了敏感文件列表比如数据库迁移脚本、鉴权相关代码守护进程会主动暂停 Agent 并通知人类介入。这个守护进程用的是很简单的规则引擎但实际效果非常好相当于给 Agent 装了一个“安全气囊”。7.3 灰度与金丝雀让 Agent 先改一个模块最后一条实践是灰度思维。我强烈建议不要一上来就让 Agent 在整个系统里到处跑而是先选一个模块作为“金丝雀”。让 Agent 在这个模块上反复练手验证日志完整、回滚顺畅、人工评审效率足够高之后再逐步扩展到其他模块。我记得我们是先选了一个低风险的外部接口模块试运行了两周等团队完全适应了 Agent 的工作节奏才开始让它参与核心流程的辅助工作。这个节奏控制很重要它让团队有时间建立信任也让 Agent 有机会在真实数据中积累“经验”。8. 法则七先从“低风险高价值”的角落下手8.1 反直觉点不要从核心模块开始大部分团队引入 Agent 时都会下意识地“选最难的模块做试点”觉得只要核心模块能跑通其他都简单。但棕地工程恰恰相反一定要从“低风险、高价值”的角落下手。原因很简单核心模块是风险高地任何一次失误都可能造成线上事故这会直接摧毁团队对 Agent 的信任。而边缘模块即使出了问题影响面也很小团队有充足的空间去调试、去磨合、去建立信心。另外边缘模块往往也是“重复劳动”的重灾区比如配置文件管理、日志分析、文档生成、测试补全这些工作非常适合 Agent 分担。先在这些地方跑出成绩用真实的收益说服团队再逐步向核心模块渗透阻力会小很多。8.2 选型矩阵风险、价值、测试覆盖怎么判断哪些角落适合 Agent 先上手我一般用一个简单的二维矩阵第一个维度是“风险等级”模块的影响面有多大、有多少下游依赖、出问题后波及多广。核心业务链路、资金相关模块风险高内部工具脚本、非核心查询接口风险低。第二个维度是“自动化收益”这个工作是否需要大量重复劳动、是否能被自然语言描述清楚、是否在现有团队中属于高痛苦区。日志初步归类、代码位置查询、重复性测试补全收益高需要大量业务判断、跨团队协调的工作收益低但也不能简单自动化。再把测试覆盖作为第三个参考维度测试覆盖高的模块Agent 改动后能快速得到反馈适合多改测试覆盖低又没有补测条件的模块先不碰。我当时选试点时就是拿这三个维度给系统的所有模块打了一遍分最后挑了一个内部报表数据接口模块。它影响面小、逻辑相对标准、测试覆盖凑合而且团队长期觉得它的日常维护很枯燥。Agent 上线后只用了两周就完成了模块里几个长期延期的清理任务团队立刻真香了。8.3 典型案例文档生成、错误归类、配置迁移、测试补全落到具体场景我见过最成功的四类棕地 Agent 应用是第一文档生成与知识库问答把老系统散落在注释、wiki、邮件里的知识点收集起来用 Agent 建立可查询的知识库新人问“这个模块怎么改”Agent 能给出代码路径和历史背景。这个场景风险极小价值却极大。第二错误日志归类与根因初筛老系统每天的日志海量运维团队看不过来的。Agent 自动把日志里的错误聚成几类并标注“可能与哪个模块、哪次变更有关”人只需要看 Agent 给的报告再决定是否深入排查。第三老代码配置迁移比如把老式 XML 配置文件批量转换成新式 YAML或者把硬编码的配置项抽取到配置中心。这种工作规律性强Agent 按规则执行再由人批量审查效率是纯人肉翻倍的。第四自动补测试针对历史遗留的“零测试模块”Agent 先阅读模块逻辑再根据输入输出样本生成特征测试。人只做审核和修正。这件事放在以前团队可能永远排不上期但 Agent 可以持续不断地“磨”很快就能把核心路径的测试覆盖率拉起来。这四个方向的共同点是不涉及核心业务逻辑的创造性改动更多是“看懂系统、整理信息、批量执行规则”。把 Agent 放在这个定位上它在棕地工程里的成功率会高得多。9. 实践案例一个真实遗留系统的 Agent 落地过程9.1 场景设定说一个我做过的真实项目。系统是一个运行了十年的订单管理系统技术栈极其混搭主服务是 Java 老框架配了一堆 XML 配置周边有 Python 脚本做定时任务数据库里还跑着大量存储过程前端是老式模板渲染。团队维护了一年多最大的痛点是“没人敢改订单状态相关的逻辑”一改就出线上问题新人上手周期长达一个月。我们当时的目标很克制不是让 Agent 直接替代开发而是先把它变成一个“带路党”帮团队读懂代码、定位逻辑、补测试后面再逐步让它承担一些低风险的修改任务。9.2 阶段一知识抽取与地图建设前两周团队把系统里的符号索引和调用图谱搭了起来。这一步比较机械但也发现了很多有意思的信息有些模块看起来没人调用实际上被存储过程间接引用着有些接口在代码里被标记为废弃却仍是线上请求的主路径。我们把模块摘要分成三层顶层按业务域订单、支付、库存、客户中层按系统服务底层按关键类。每一层摘要都写了“常见陷阱”比如“订单金额更新必须走 service不能直接改表”“支付回调的幂等键是 orderNo 加 eventType”。两周后地图基本能回答这些问题“订单状态的完整流转是什么”“改这个字段会影响哪些下游”“这个接口还有没有在用”。这些以前靠老员工口口相传的知识第一次变成了系统性的资产。9.3 阶段二只读 Agent 做问答与定位地图建好后我们接入了只读 Agent让团队用自然语言提问题。效果最明显的是新人以前定位一个需求涉及的代码要花两三天现在直接问 Agent “创建订单后如果支付失败订单会进入哪个状态”Agent 回答出完整调用链并给出代码位置新人只需要人工验证一遍。这个阶段我们刻意没有开放任何写权限Agent 只做检索、摘要、定位。好处是团队没有心理负担用得很舒服积累了大量“问题—答案”日志。这些日志后来成了优化 Agent 提示词和工具描述的重要语料。9.4 阶段三受限写权限 Agent 做测试补全和重构辅助读懂系统之后我们开始把 Agent 的权限扩大到“生成 diff”但只允许它做两类事情补测试和辅助重构。补测试的核心是挑选两个长期没测试的模块让 Agent 基于地图摘要和已有代码生成单元测试和契约测试。Agent 生成的初版测试质量大概七八十分人审后修正一些边界条件就合入了。三周后这两个模块的测试覆盖率从不到 10% 拉到了 60% 以上团队明显感到“改代码没那么慌了”。辅助重构的任务更保守比如把老代码里重复的日期解析逻辑抽取成公共工具类。Agent 提出方案、人确认、Agent 生成 diff、人评审合并。整个过程非常稳没有出现一次线上问题。9.5 阶段四人机协作的日常运维系统运转三个月后Agent 的位置基本固定了日常日志初筛、需求影响面分析、测试补全、低风险重构辅助。团队不再用“会不会被 Agent 替代”的心态去看它而是把它当成一个“记忆力极好、干活极快、但必须时不时盯着的高级实习生”。特别值得一提的是日志初筛功能Agent 每天自动扫一遍生产日志把错误按模式归类并标注可能相关联的代码位置团队每天早上花十分钟看报告就行。以前这项工作要一个人花两小时现在被完全省出来了。9.6 避坑与复盘回头看有几个坑值得一提。第一个坑是初期想直接让 Agent 干“重构核心订单链路”我们讨论后放弃了这个决定后来被证明非常明智。如果一开始就在超高风险的模块上翻车整个项目很可能被叫停。第二个坑是 Agent 生成测试时偶尔会“伪造预期”。它会根据现有代码的行为去倒推测试断言哪怕这些行为本身是 bug。所以人工审核测试绝对不能省至少要看一遍断言是否符合业务预期。第三个坑是地图的持续维护。一旦代码库做了大改动摘要不会自动更新Agent 拿到旧摘要时会产生误导。我们后来在 CI 里强制要求涉及模块的 PR 合并时必须同时更新对应摘要否则合并流程会被阻止。10. 常见问题速查与经验备忘10.1 常见问题速查表问题现象可能原因排查思路解决方案Agent 总是定位不到正确代码代码地图的索引不全或摘要过期检查符号索引覆盖范围、模块摘要更新时间重建索引把地图更新挂进 CIAgent 频繁修改无关文件上下文信息过载注意力被分散查看任务日志中的检索记录收紧 token 预算缩小检索粒度Agent 生成的测试断言不符合业务模型从已有代码倒推行为未理解业务约束审查测试中的边界条件关键测试必须人工审核地图中补充业务约束说明Agent 在核心模块上改动引发风险未设置关键路径人工审批点查看哪些审批点被跳过启用全部四个检查点核心模块改动必须人工确认反馈速度太慢Agent 迭代效率低CI 全量链路太长分析测试执行耗时分布拆分快速层/完整层/深度层测试某次 Agent 改动引发线上问题无法定位操作日志缺失无独立 diff查看是否有合并记录和回滚记录建立全量操作日志和独立分支机制一键回滚团队不敢让 Agent 参与修改前期信任未建立复盘以往的 Agent 事故和成功案例从低风险高价值场景试点用真实收益逐步建立信任10.2 实操经验备忘清单最后整理几条我在多个遗留系统项目里反复用到的经验备忘你可以直接抄作业第一永远先建代码地图。不管你的 Agent 是简单还是复杂地图都是它理解系统的地基。地图没有建好之前不要急着给 Agent 开放写权限。第二把 token 预算当成工程约束来管理。不是所有信息都值得塞进上下文每次任务都要问一句“Agent 真正需要的最小信息集是什么”。第三给 Agent 的工具做减法。宁可让它少干点事也不能让它拥有过度权限。每条工具描述写清楚使用边界。第四人是系统的一部分。设计人机协作流明确人在关键节点的责任而不是把所有工作扔给 Agent。第五从低风险场景开始积累信任。先用文档问答、日志归类、测试补全这类“安全活”练手有了成绩再逐步扩大范围。第六所有 Agent 动作都要可审计。日志、独立分支、回滚脚本这不是可选项是棕地工程的安全底线。第七给 Agent 配“仪表盘”先补测试反馈机制再让 Agent 大规模行动。没有反馈就没有安全。我个人在做这些项目的过程中最大的体会是棕地 Agent 工程的问题从来不是“模型强不强”而是“你的系统有没有准备好让 Agent 安全地干活”。准备好地图、边界、测试、审计、人机协作这些底座Agent 就是极高效率的助手准备不好它就是一头在瓷器店里横冲直撞的牛。希望这几条反直觉的法则能让你少踩一些我踩过的坑。
返回列表