ARTICLE DETAIL

资讯详情

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

遗留代码库如何玩转 AI Agent?资深架构师揭秘“棕地 Agent 工程”的 7 大反直觉法则

遗留代码库如何玩转 AI Agent?资深架构师揭秘“棕地 Agent 工程”的 7 大反直觉法则 目录1. 引言当 AI Agent 遇到“老旧代码库”2. 核心洞察一划定代码“红黄绿分区”人类必须掌握控制权3. 核心洞察二只写代码“说不出”的上下文与“持久化研究文档”4. 核心洞察三重构前必须用“特征测试”锁死当前行为5. 核心洞察四拒绝“半吊子迁移”警惕“迁移盲区”6. 核心洞察五把重复纠错转化为“环境脚手架”7. 核心洞察六利用 Agent 的低成本并行尝试多种方案8. 核心洞察七先建立审查与验证机制最后再考虑并行放大9. 结语Ambiguity 终有对价1. 引言当 AI Agent 遇到“老旧代码库”在全新构建的“绿地项目”Greenfield中AI Agent 的表现往往令人惊艳几句提示词就能快速搭建起完备的微服务或优雅的前端界面。然而当我们将这些自主 AgentAutonomous Agents未经监管地直接丢进企业级“棕地代码库”Brownfield时现实却往往演变为一场技术灾难——生成看似能运行但架构糟糕的代码配套着脆弱不堪的单元测试悄无声息地破坏了隐藏的业务逻辑。所谓“棕地系统”指的是那些已经运转多年、积累了大量历史债务的代码库。在这样的系统中代码树本身早已无法完全代表系统的真实行为团队的隐性知识Tribal Knowledge、临时修补的胶水代码、遗留服务以及跨部门的隐性依赖全都在代码树之外生长。事实上在一个缺乏完善测试的系统里一旦 Agent 生成了并非由人类逐行思考决定的代码你就已经身处棕地环境之中了。为了解决这一难题知名技术专家 Addy Osmani 提出了“棕地 Agent 工程”Brownfield Agentic Engineering的技术框架。该框架的核心目标在于让隐藏的约束显性化并让低成本的代码变更变得安全可靠。本文将深度拆解这一框架的 7 大核心洞察帮助架构师与技术 Leader 在老旧代码库中安全高效地释放 AI Agent 的潜力。2. 核心洞察一划定代码“红黄绿分区”人类必须掌握控制权在进入遗留代码库之前首要任务是明确“哪些代码可以碰哪些代码绝对不能盲目修改”。我们需要在系统内部划定清晰的安全区域Zones绿区Green Zone隔离性良好、具备高测试覆盖率且采用现代规范的代码模块例如近年来新建的独立微服务或边缘模块。Agent 可以在此区域内以紧凑的循环Tight Loop自主工作。黄区Yellow Zone代码质量参差不齐。Agent 在修改此类区域的代码前必须优先编写特征测试Characterization Tests。红区Red Zone涉及身份验证Auth、计费Billing、权限Permissions、薪酬Payroll等高风险敏感领域或缺乏测试古老核心模块。此类区域严禁 Agent 无监督重写必须由人类工程师进行结对编程Pair-Programming或暂时禁止修改。人类画地图而不是 Agent如果由 Agent 选择它会从最吓人的文件开始因为最吓人的文件有着最有趣的名字。将分区落地的关键在于将其转化为严格的三个操作规则人类掌握地图绘制权Agent 绝对不能自主选择操作入口。如果放任自由Agent 会倾向于挑选最复杂、名称最吸睛的盘根错节之物。区域升级必须凭凭证Earned黄区不会自动变为绿区。只有当特征测试成功建立且模块负责人Module Owner审查并批准了 Agent 的首批变更后该区域才能升级为绿区。分区规则决定允许的操作动词Verbs绿区对应“自主循环”黄区对应“测试先行”红区则对应“人类结对或禁止无监督执行”。3. 核心洞察二只写代码“说不出”的上下文与“持久化研究文档”许多团队在引入 Agent 时习惯于将大量的 Markdown 文档塞满 Prompt 或上下文窗口Context Window试图把代码库的架构重新描述一遍。然而这是一种极大的资源浪费——当前的 LLM 已经非常擅长自行解析代码结构、推理调用关系和推导系统地图。我们需要提供给 Agent 的恰恰是静态代码分析工具无法获取的信息特定业务或团队的独特上下文与隐性约定解释“系统为什么被设计成这样”的历史权衡Trade-offs未被静态分析工具或 Linter 硬性强制的规范特定领域的业务规则与外部约束违背直觉的古老实现背后的历史原因。写下代码本身说不出的东西别的什么都不用写。为了防止 Agent 在探索老旧代码库时陷入无意义的重复考古团队必须引入持久化研究文档Durable Research Artifact机制。在针对黄区或红区展开具体代码修改前应先运行一个只读Read-OnlyPass命令 Agent 输出一份简短的理解备忘录Comprehension Memo。该备忘录需明确标出系统入口点、模块所有人、上游调用方、既有抽象、测试覆盖状况、生产环境信号以及未决疑问且每一项声明都必须精确引用具体的代码文件、Issue 编号、责任人记录或监控仪表盘。如果探索过程没有沉淀为这种持久化文档一旦上下文会话结束或发生压缩下一个 Agent 就会重新支付昂贵的“代码考古”成本。4. 核心洞察三重构前必须用“特征测试”锁死当前行为在遗留系统中重构的最大风险在于“修复”了某些看起来很丑陋、但实际上业务正在依赖的奇葩行为。特征测试Characterization Tests是一种自动化测试其目的不是验证代码逻辑在理论上是否“正确”而是锚定并锁定系统当前的实际行为包含那些丑陋的边缘情况。在实践中必须严格遵循一个铁律严禁让 Agent 在同一个 Session会话中既编写特征测试又编写重构代码。如果由同一个会话完成Agent 极易生成一套看似全绿、实则仅仅是在验证它自己刚发明的新逻辑的无效测试。正确的做法是先在单独的 Pass 中或由人类锁定现有行为然后再交由 Agent 进行代码重构。当面对缺乏单元测试、但又极其重要的核心入口例如大型电商首页或核心结算页时传统的单元测试往往力不从心。此时可以参考Netflix 在 GraphQL 架构切流中的实践在生产环境进行流量重放与影子流量Shadow Traffic对比通过 Diff 两个路径的 Payload 输出在确认完全一致后再进行切流。对于只有生产流量才能真正“理解”的古老核心入口不要靠猜影子流量比对就是最终极的特征测试裁决器Oracle。5. 核心洞察四拒绝“半吊子迁移”警惕“迁移盲区”对 AI Agent 破坏力最大的莫过于“只完成了一半的架构迁移”。如果一个代码库中有 40 个文件使用老方法12 个文件使用新方法中间还夹杂着一个同时兼容两者的 Shim 适配层Agent 就会面临极其混乱的矛盾范式Contradictory Precedent从而不断生成新旧混杂的代码。一次真正的迁移必须以“旧依赖被证明完全移除、旧路径被彻底删除”为结束标志。如果把清理旧代码留给未来的技术债 Ticket那么这次迁移单元就是失败的。权威基准测试 SWE Refactor Bench 的研究揭示了一个残酷的事实在 520 次 Agent 迁移尝试中仅有 28 次成功通过了迁移审计、行为测试与独立验证。这种“看似测试全绿实则新代码依然在偷偷调用遗留实现”的现象被定义为“迁移盲区”Migration Blindness。为了避免“迁移盲区”架构师必须控制迁移单元的粒度。一项针对 VB6 到 C# 迁移的受控研究表明对于简单功能系统的行为等价率可达 92%但对于复杂功能这一数字会陡降至 47%。 这证明了变更单元的尺寸是决定迁移成败的核心杠杆。正如 Stripe 在没有 Agent 参与的情况下通过精心设计的 Codemods 工具将 370 万行代码平滑迁移至 TypeScript 一样对于大规模机械化迁移应该用 Agent 去辅助编写和校验 Codemod 脚本而将 Agent 本身聚焦于处理规则之外的例外队列Exception Queue。6. 核心洞察五把重复纠错转化为“环境脚手架”在 Code Review 过程中如果你发现自己对 Agent 生成的代码提出了两次相同的修改意见这就表明系统缺少相应的自动化脚手架。为了精准设计系统我们需要区分围绕 Agent 的四层结构指令Instructions记录关于代码库的特殊事实Prose 形式技能Skills打包可复用的操作流程如验证 Schema 变更、爆炸半径检查插件Plugins提供受控访问权限的工具如查询所有者目录、事故归档库或监控仪表盘脚手架Harness包裹在 Agent 周围的整体运行环境包含上下文、工具链、权限控制、自动化断言、日志与恢复机制。每一次重复的纠错都是脚手架缺失的一部分。当出现重复纠错时不要只是在提示词文本中多加一句自然语言警告而是应该将其硬化Harden为 Linter 规则、Git Hook、强类型定义、自动化测试或 Agent Skill。自然语言提示词容易被忽略或在上下文压缩中遗失但 CI 检查和类型系统不需要记忆。久而久之脚手架会成为团队防止“在同一个坑里跌倒两次”的坚固防线。7. 核心洞察六利用 Agent 的低成本并行尝试多种方案AI Agent 的引入彻底改变了技术探索与架构重构的成本结构。在过去尝试用新语言或新框架重写系统需要付出巨大的工程师工时团队通常只能 gamble 在单一技术选型上。如今架构师可以利用低成本的 Token指令 Agent同时并行构建多种 competing 的重构方案让 Agent 分别用不同框架或语言实现同一套业务逻辑将所有候选实现放入既有的自动化测试集中进行断言并对各个方案进行性能基准测试Performance Profiling最后基于客观的数据证据选择最优解。然而在使用 Agent 进行大规模迁移时必须保持对业界案例的理性认知Bun 的 Zig 到 Rust 移植案例Bun 在 11 天内完成了 53.5 万行代码的移植运行了约 50 个工作流。但其成功的关键在于工程团队在 Agent 运行前花费了大量时间编写了精细的语言映射指南Porting Guide并设立了“每个生成单元配备两个对抗性审查员Adversarial Reviewers”以及“既有全量测试集作为 Merge Gate”的严苛流程。Shopify 的 App 重构对比Shopify 在 12 周内将消费端 AppShop从 React Native 迁移至原生 Swift 和 Kotlin但其规模庞大得多的商家端 AppMerchant App由于包含数百个屏幕和深度的底层平台集成依然属于典型的棕地难题必须采用更长的周期和更严密的卡点。Asana 的 Enzyme 清理案例Asana 宣称仅花费了约$12,000的模型与算力成本就在两周内清空了积压多年的 Enzyme 遗留代码。但必须强调的是这 $12,000 仅仅是模型调用的 API 账单绝不能等同于替代了其原本估算的 5 年人工作业成本。它是供应商报告的生成成本忽略了人类工程师在前期搭建脚手架、准备测试集以及全程审阅的高昂精力投入。8. 核心洞察七先建立审查与验证机制最后再考虑并行放大当下很多团队急于推行“软件工厂”Software Factories同时开启数十个并发运行的 Agent Loop。然而未经审慎设计的并行化只会成倍放大资深工程师的 Code Review 瓶颈。当大量的生成代码涌向 Pull Request 队列时人类工程师的精力会被严重分散最终要么导致审阅队列严重积压要么演变为形式主义的“盖章式批准”Rubber-stamp Approvals。因此团队必须坚持“先验证后并行”的顺序。为了拯救人类审查者Agent 生成的 PR 结构必须被标准化优先呈报结构化摘要而不是让工程师直接阅读海量的代码 Diff变更意图Intent用一句话说明为什么要进行此修改变更的不变量Changed Invariants明确标出哪些系统约束被保持哪些被打破测试结果等价性比对Parity Mismatches展示新旧路径在测试或影子流量下的比对数据回滚方案Rollback Route提供明确的单向撤回路径。此外必须明确隔离与安全边界Git Worktree 仅能隔离代码变更并不能隔离网络访问或系统凭证。对于无人值守Unattended且接触不受信内容的 Agent必须提供独立的沙箱环境Sandbox与严格限制作用域的 API 凭证。只有建立起这样的自动化轨制才能实现真正的规模化——正如Spotify 基于 Backstage 平台轨制如今每月能够平滑合并650 个以上的 Agent PR。9. 结语Ambiguity 终有对价AI Agent 并不能凭空消除软件开发中的复杂性也无法直接抹去企业内部累积多年的组织壁垒与技术债务。但 Agent 的出现带来了一个根本性的改变它为系统中的模糊性Ambiguity、部落知识Tribal Knowledge和测试缺失标上了明确且可见的价格。过去这些隐性成本散落在新人入职培训、冗长的 Code Review 以及突发的线上故障排查中而现在每一次失败的 Agent 运行和重复的纠错提示都在用真金白银的 Token 和时间成本将它们量化。在推进棕地 Agent 工程时架构师应当建立明确的度量指标不仅要追踪交付周期更要追踪Review 耗时、人类干预次数、线上逃逸缺陷率、回滚率以及残存的遗留依赖数量。如果一个 PR 显示测试全绿但生产环境的所有流量依然在走老旧路径那这不过是无意义的数字繁荣。面对即将到来的 Agentic 时代不妨深刻反思当下一个 Agent 需要重构你最核心的业务模块时你的代码库留给它的是一个深不见底的技术陷阱还是一套坚固可靠的环境脚手架作者道一云低代码作者想说喜欢本文请点点关注~
返回列表