Phases exercised: P5 · P7 · P11 · P13 · P14 · P15 · P17
问题
大规模代码迁移是 2026 年编码 Agent 最干净的生产应用之一。判据显而易见(迁移后测试套件会通过吗?),回报是真实的(一次 Java 8 机群迁移是人力规模的项目),基准是公开的(MigrationBench 的 50 仓库子集)。Moderne 的 OpenRewrite 负责确定性那一侧。Agent 层负责 OpenRewrite 配方处理不了的一切:含糊的重写、构建系统漂移、长尾语法、传递依赖断裂。
你会构建一个 Agent:输入一个 Java 8 仓库(或 Python 2 仓库),输出一个 CI 全绿的迁移分支。你会测量通过率、测试覆盖率保持情况、每仓库成本,并建立失败分类法。与纯确定性基线的并排对比,会告诉你 Agent 的价值到底在哪里。
概念
pipeline 分两层。确定性底座(Java 用 OpenRewrite,Python 用 libcst)安全地完成大部分机械式重写:import、方法签名、空安全改写、try-with-resources、废弃 API 替换。它速度快,产生的 diff 可审计。Agent 层(基于 Claude Opus 4.7 和 GPT-5.4-Codex 的 OpenAI Agents SDK 或 LangGraph)处理配方无能为力的情况:构建文件升级(Maven/Gradle/pyproject)、传递依赖冲突、测试抖动、自定义注解。
每个仓库分到一个预装目标运行时的 Daytona 沙箱。Agent 反复迭代:跑构建、分类失败、施加修复、重跑。硬性上限:每仓库 30 分钟、8 美元、20 个 Agent 轮次。如果所有测试通过且覆盖率变化不为负,分支就开 PR。否则仓库连同证据归入某个失败类别。
失败分类法才是交付物。50 个仓库里,坏在哪里?传递依赖?自定义注解?构建工具版本?与迁移无关的测试抖动?每个类别给出计数和一个范例 diff。后续写配方的人可以瞄准前三类。
架构
target repo
|
v
OpenRewrite / libcst deterministic recipes
(safe, fast, auditable, ~70-80% of fixes)
|
v
Daytona sandbox per branch
|
v
agent loop (Claude Opus 4.7 / GPT-5.4-Codex):
- run build -> capture failures
- classify failures (build, test, lint)
- apply fix (patch or retry recipe)
- rerun
- budget: 30 min, $8, 20 turns
|
v
test + coverage delta gate
|
v (passed)
open PR
|
v (failed)
file under failure class + attach repro技术栈
- 确定性底座:OpenRewrite(Java)或 libcst(Python)
- Agent:基于 Claude Opus 4.7 + GPT-5.4-Codex 的 OpenAI Agents SDK 或 LangGraph
- 沙箱:逐分支的 Daytona devcontainer,预装目标运行时(Java 17 / Python 3.12)
- 构建系统:Maven、Gradle、uv(Python)
- 基准:Amazon MigrationBench 的 50 仓库子集(Java 8 到 17)、Google App Engine 的 Py2 到 Py3 仓库
- 测试框架:并行运行器,Java 用 Jacoco、Python 用 coverage.py 统计覆盖率
- 可观测性:Langfuse + 每仓库一个 trace 包,包含每个 diff 片段
- 仪表盘:失败分类仪表盘,带逐类计数和范例 diff
构建它
- 配方阶段。 先跑 OpenRewrite(Java)或 libcst(Python)配方。抓住那 70-80% 机械式的迁移。作为「recipe」提交。
- 构建试跑。 Daytona 沙箱:安装目标运行时,跑构建。如果绿了,直接跳到测试。如果红了,交给 Agent。
- Agent 循环。 用带工具的 LangGraph:
run_build、read_file、edit_file、run_test、git_diff。Agent 对失败分类(依赖、语法、测试、构建工具),并施加针对性修复。然后重跑。
- 预算上限。 每仓库 30 分钟墙钟时间、8 美元成本、20 个 Agent 轮次。任何一项超限都立即停止,并把当前 diff 归入「budget_exhausted」。
- 测试 + 覆盖率门禁。 构建转绿后,跑测试套件。与基准仓库比较覆盖率。如果覆盖率下降超过 2%,归入「coverage_regression」。
- 开 PR。 成功时推送分支,开 PR,附上 diff,以及哪些配方被应用、哪些提交由 Agent 编写。
- 失败分类法。 对每个失败的仓库打上类别标签:
dep_upgrade_required、build_tool_drift、custom_annotation、test_flake、syntax_edge_case、budget_exhausted。构建仪表盘。
- 50 仓库跑批。 在 MigrationBench 子集上执行。报告逐类通过率、每仓库成本、覆盖率保持情况,以及与纯确定性基线的对比。
使用它
$ migrate legacy-java-service --target java17
[recipe] 27 rewrites applied (JUnit 4->5, HashMap initializer, try-with-resources)
[build] FAIL: cannot find symbol sun.misc.BASE64Encoder
[agent] turn 1 classify: removed_jdk_api
[agent] turn 2 apply: sun.misc.BASE64Encoder -> java.util.Base64
[build] OK
[tests] 412/412 passing; coverage 84.1% -> 84.3%
[pr] opened #1841 cost=$3.20 turns=4交付它
outputs/skill-migration-agent.md 是交付物。给定一个仓库,它先执行确定性配方,再跑 Agent 循环,产出一个可合并的绿色迁移分支;做不到时,就把仓库归入某个分类类别。
| 权重 | 标准 | 衡量方式 |
|---|---|---|
| 25 | MigrationBench 通过率 | 50 仓库子集的 pass@1 |
| 20 | 测试覆盖率保持 | 相对 base 的平均覆盖率变化 |
| 20 | 每个迁移仓库的成本 | 通过运行上的 $/repo |
| 20 | Agent / 确定性工具集成 | OpenRewrite 处理的修复与 Agent 编写的修复比例 |
| 15 | 失败分析报告 | 分类法完整度与范例 |
| 100 |
练习
- 只跑 OpenRewrite(不用 Agent)执行迁移 pipeline。对比通过率与完整 pipeline。找出只有 Agent 能补齐差异的那些案例。
- 实现「lint 干净」检查:迁移后跑风格 linter(Java 用 spotless,Python 用 ruff)。如果出现新的 lint 错误就让 PR 失败。测量「覆盖率保持但风格回退」的比例。
- 加一个「最小 diff」优化器:Agent 的分支通过测试后,用第二遍修剪不必要的改动。报告 diff 体积缩减。
- 扩展到第三种迁移:Node 18 到 Node 22。复用沙箱封装;把配方层换成自定义 codemod。
- 把首次构建转绿时间(TTFGB)当作 UX 指标测量。目标:p50 在 10 分钟以内。
关键术语
| 术语 | 常见说法 | 实际含义 |
|---|---|---|
| Deterministic substrate | 「配方引擎」 | OpenRewrite / libcst:带安全保证的声明式 AST 重写 |
| Codemod | 「代码修改程序」 | 机械地改写源码的重写规则 |
| Build drift | 「工具版本偏移」 | Maven / Gradle / uv 在大版本之间的细微行为差异 |
| Failure class | 「分类桶」 | 仓库未能迁移的标注原因:依赖、语法、测试、构建工具、预算 |
| Coverage delta | 「覆盖率保持」 | 从基准分支到迁移分支的测试覆盖率百分比变化 |
| Agent turn | 「工具调用轮」 | Agent 循环中的一次 计划 -> 行动 -> 观察 周期 |
| Budget exhaustion | 「撞到上限」 | 仓库耗尽了 30 分钟 / 8 美元 / 20 轮的限制仍未通过 |
延伸阅读
- Amazon MigrationBench —— 2026 年的标准基准
- Moderne.io OpenRewrite 平台 —— 确定性底座参考
- OpenRewrite 文档 —— 配方编写
- Grit.io —— 另一种 codemod DSL
- OpenAI 沙箱化迁移 cookbook —— Agents SDK 参考
- Google App Engine Py2 到 Py3 迁移器 —— 另一种迁移基准
- libcst —— Python 确定性底座
- Daytona 沙箱 —— 逐分支沙箱参考