AIClaude CodeEngineering

连Claude Code都搞不定的巨型代码库,我们靠一个"自愈循环"给盘活了

宇琪··原文链接
收录于 2026/7/13 10:14:30

这是一篇 ServiceTitan 首席 AI 工程师 David Stein 在 QCon 的分享整理(经 InfoQ 编辑),讲的是工程团队最熟悉又最头疼的话题:代码迁移

问题背景:遗留代码迁移就是翻一座山

ServiceTitan 是面向承包商和技工行业的端到端技术平台,大量应用跟报表指标相关。其报告系统背后是典型的遗留代码——几十万行、5 到 10 年前写的、文档不全、原作者早已离职、单元测试覆盖率堪忧。要把这些庞然大物搬到新的抽象层(基于数据湖仓的 DBT MetricFlow + Semantic Layer),传统路径是成百上千张 Jira 工单、数百个工程师周、横跨数个季度甚至数年。更糟糕的是,迁移项目"必须走完全程"——不可能做到 25% 就收手,一旦卡在半路就进退两难。ServiceTitan 此前已经有过不止一次失败的迁移尝试。

ServiceTitan 报告指标迁移项目概览

为什么"直接扔给 AI"行不通

2025 年的默认思路是"能不能直接问 AI"。但 David 的结论很直接:你不能直接让 Cursor 或 Claude Code 把整个遗留代码库迁移到你描述的新架构中,我确实试过,结果非常糟糕。 原因和一个工程师无法独自完成这件事一样——任务太大了。LLM 会幻觉、会误解任务、会发明新指标而不是迁移旧的,做了五个就停下,而且那五个还是错的。

关键洞察是一个老生常谈但被反转了时间线的原则:把问题分解成可以逐个验证的小步骤。 高级工程师每天都在做任务拆解,新变化在于——你可以在初期多投入精力把验证做到极致严格,让每个增量步骤都能被精确验证,从而把原本几百步的苦差事压缩到更短的时间窗口内。

迁移一个指标的完整上下文与步骤

"组装线"模式:三步走

David 把这套方法命名为"组装线"(assembly line),核心三步:

  1. 任务分解到"石子"粒度——不要问"怎么搬走整座山",而要精确知道"怎么从山上搬走一块石子"。通过实验证明一个 agent 确实能独立完成这个子任务,粒度不合适就迭代调整。

  2. 为每个子任务建立程序化的验证器——这是最关键的一步。要有一个能明确判断"通过/失败"的脚本、环境或平台。ServiceTitan 构建了一个小型模拟器,能用新指标平台生成与后端报表系统相同的报告,从而逐字段、逐分布地比对数据。David 坦言反思:以前把任务分配给高级工程师时,为什么没坚持用这么严格的验证?

  3. 自动化执行——把标准化的上下文获取、提示词和验证机制做到极致后,把任务分配给 agent。

组装线架构:任务分解、验证、自动化执行

一个值得注意的工程细节:ServiceTitan 在这次迁移中完全没有使用 MCP(Model Context Protocol),而是在 CLI 层面工作——给 agent 配备 SnowSQL 等 CLI 工具和 staging Snowflake 的真实数据访问凭证,让它能直接查看指标底层表中的数据长什么样。经验是:你不能只告诉 AI"把公式重写一遍"而不提供数据实际样貌的上下文,它写不出正确代码,就像人类一样。

CLI 工具链:给 agent 配备与工程师相同的上下文获取能力

项目还维护了两个关键文本文件:

  • migration_goals.txt——定义"完成"的标准,包括整体迁移成功条件和每个步骤的进度,用工具能检测到的状态来描述。
  • migration_tasks.txt——任务的详细拆解,分阶段组织,agent 每完成一个指标就在文件中标记为已完成。

migration_goals.txt 与 migration_tasks.txt 的协作机制

自愈循环:验证器驱动的飞轮

整个方法的核心引擎是自愈循环:agent 用提供的工具获取上下文 → 编写代码 → 运行验证器检查 → 不满足则查看不匹配细节并重试,循环往复。

自愈循环:上下文获取 + 验证器共同驱动

但 David 强调了最大的教训:如果验证器不够好,事情会以惊人的速度失控。 验证器失效是最可怕的场景——agent 会长时间运行、任务一个接一个地跑,最终产出一堆"看起来合理但实际上是垃圾"的东西,浪费一整天甚至一整周的计算资源。在迁移几百个指标的过程中,验证器被多次改进。很多遗留系统天生不容易被观测(时序问题、数据对齐问题),这些以前只是"锦上添花"的可观测性能力,现在变成了"生死攸关"的必要条件。

验证器失效场景:产出看似合理实则错误的代码

像《百战小旅鼠》一样管理 AI

David 用 90 年代游戏《百战小旅鼠》(Lemmings)做类比:小旅鼠笨得要命,但你只要在它们的行进路线上放好路障,就能确保它们全都到达目的地。这就是组装线架构的本质。LLM 不需要像人类工程师那么聪明——关键不在于智商多高,而在于你构建的自愈工作流。最坏的情况是 LLM 不理解任务导致无法推进,但这是一个可控的迭代过程(优化上下文呈现方式),而不是不可控的赌博。

百战小旅鼠类比:给 agent 画好路线图,放好路障

实际操作中,他们在 Cursor 里运行流程,不再简单说"做这个",而是说:"熟悉一下 migration_goalsmigration_tasks,然后实现阶段 2.3。"Cursor 会自己生成待办列表,分解出若干子任务完成指标迁移。前 10、20、30 个任务反复重做、打磨验证脚本和上下文,之后放手让它在几周内跑完几乎所有剩余任务。

在 Cursor 中运行:简化指令,复杂性隐藏在验证步骤背后

结果与常见翻车场景

最终结果:85% 的迁移工作由 AI 自主完成,剩余 15% 的复杂案例需要工程师介入,项目周期从几个季度压缩到几周。

常见翻车场景及应对:

  • Agent 误报成功:跑完报告"完成",验证脚本一查逻辑根本不对。解决:把验证工具做得极其扎实——项目中大部分工程精力花在让模拟验证脚本跑得完美上。
  • Agent 卡住不动:通常因为找不到合适的测试数据覆盖指标背后的微妙逻辑。应对:找"黄金清单"(包含优质测试数据的 ID、数据密度已知的时间范围),写进 migration_goals 上下文文件——把"部落知识"(tribal knowledge)文档化。
  • 中途发现架构设计不好想推倒重来:在过去的 Jira 工单模式下意味着巨大的时间成本和士气打击,但"旅鼠们不在乎"——改好规则重新跑一遍就行。

完整工作流总览与最终成果

Q&A 要点

  • 最短路径:现阶段仍需认真拆解任务、搭建可靠验证器、定义清晰目标,不存在更简单的捷径。长期来看,未来工具(Cursor/Claude Code)可能自动分析遗留代码、构建验证器,届时结构化设计的工作量会大幅减少。
  • 安全性与隐私:严密监控 + 只给 staging 数据,绝不给生产数据库密钥或删除权限。Cursor 等工具的安全隔离能力仍在成熟中。

My Take

这篇文章对 Rainsho 这样的资深前端工程师有几个直接可借鉴的点:

1. 验证器优先于模型能力。 文章最有价值的洞察不是"AI 能迁移代码",而是"验证器是整个飞轮的生死攸关条件"。这跟前端工程化里的思路完全一致——你写不出好的单测和 e2e 断言,就不可能信任 agent 的产出。David 自己反思"以前给高级工程师分配任务时为什么没坚持这么严格的验证",这其实是在说:agent 暴露了我们工程实践中一直存在的验证债务。 React 组件迁移、API 层重构、样式系统迁移,哪个不是同样的道理?

2. "石子粒度"比模型选择更重要。 很多人纠结用 Claude 还是 GPT,但 David 的数据说明:用去年的短上下文模型 + 正确的工作流,效果远好过用最强模型 + 错误的工作流。任务分解的粒度是可实验、可迭代的工程决策,而不是玄学。

3. CLI > MCP 的务实选择值得注意。 在 MCP 炒作火热的当下,ServiceTitan 选择在 CLI 层面工作且效果良好,是一个清醒的信号。对于前端场景,这意味着你完全可以用现有的 CLI 工具链(tsc、eslint、playwright、storybook)构建 agent 上下文,而不必等 MCP 生态成熟。

4. 局限性要清醒。 15% 的复杂案例仍需人工,且这 15% 往往是最难的部分。文章对此着墨不多,但这是评估"能不能用这套方法"时的关键决策点。另外,验证器本身的建设成本不低——David 说"大部分工程精力花在让模拟验证脚本跑得完美上",这说明前期投入并不小,适合规模化迁移(几百个同类任务)的场景,零散的小迁移未必划算。

评分:
暂无0 人评分)