<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://kerryleung.github.io/blogs/feed.xml" rel="self" type="application/atom+xml" /><link href="https://kerryleung.github.io/blogs/" rel="alternate" type="text/html" hreflang="en" /><updated>2026-07-18T04:37:36+00:00</updated><id>https://kerryleung.github.io/blogs/feed.xml</id><title type="html">Note for learning</title><subtitle>learn practice and sharing</subtitle><author><name>KL</name></author><entry xml:lang="en"><title type="html">Once AI Makes Code Migration Fast, Quality Assurance Matters More, Not Less</title><link href="https://kerryleung.github.io/blogs/2026/07/18/ai-code-migration-quality-en/" rel="alternate" type="text/html" title="Once AI Makes Code Migration Fast, Quality Assurance Matters More, Not Less" /><published>2026-07-18T00:00:00+00:00</published><updated>2026-07-18T00:00:00+00:00</updated><id>https://kerryleung.github.io/blogs/2026/07/18/ai-code-migration-quality-en</id><content type="html" xml:base="https://kerryleung.github.io/blogs/2026/07/18/ai-code-migration-quality-en/"><![CDATA[<blockquote>
  <p>The faster AI writes code, the less an engineer can afford to focus on the code itself. The scarce skill is shifting from “getting every line right” to “designing a system that keeps producing correct code”: constrain generation with rules, validate the rules with a small experiment, let adversarial agents actively hunt for problems, and let the compiler and tests act as the judge. This is my write-up and reflection after reading Anthropic’s “How Anthropic runs large-scale code migrations with Claude Code.”</p>
</blockquote>

<p>I recently read a piece Anthropic published: “How Anthropic runs large-scale code migrations with Claude Code.”</p>

<p>The article describes how they used Claude Code and many AI agents to run several large code migrations, including:</p>

<ul>
  <li>Migrating a large chunk of Bun from Zig to Rust in under two weeks, producing about 1 million lines of code (across 1,448 files);</li>
  <li>Getting Bun’s existing test suite to 100% passing in CI before merge;</li>
  <li>Migrating an internal Python project into about 165,000 lines of TypeScript over a single weekend;</li>
  <li>Using hundreds of agents, 8 phase gates, and 3 rounds of adversarial review, diffing the outputs of the old and new systems line by line.</li>
</ul>

<p>The article is short, but its density of practices — around rule-writing, task decomposition, quality verification, adversarial review, and cost control — is very high.</p>

<h2 id="first-my-own-take">First, my own take</h2>

<p>I’ve done several small-to-medium software service migrations myself, usually in the tens of thousands of lines.</p>

<p>Once you’ve done a few of these, you realize very clearly: code migration is far more than “translating old code into new code.”</p>

<p>The genuinely hard problems usually include:</p>

<ul>
  <li>How do you finish a migration while the product keeps shipping features?</li>
  <li>How do you avoid implementing the same new feature twice — once in the old system and once in the new?</li>
  <li>How do you split the migration so multiple developers can work in parallel?</li>
  <li>How do you keep the migrated system from developing serious quality problems?</li>
  <li>How do you decide the new system has truly reached feature parity with the old one?</li>
</ul>

<p>The challenges behind these questions aren’t purely about coding ability — they’re about project management, architecture, task decomposition, test planning, and risk control.</p>

<p>As AI’s coding ability grows stronger, migration speed really can improve by an order of magnitude. But at the same time, the quality-assurance problem can be amplified even further.</p>

<p>When AI can generate tens or hundreds of thousands of lines in a short time, a human can no longer review the whole thing file by file, pull request by pull request.</p>

<p>At that point, the question an engineer must solve shifts from:</p>

<blockquote>
  <p>Is every line the AI wrote correct?</p>
</blockquote>

<p>to:</p>

<blockquote>
  <p>How do I keep the AI from drifting?
How do I build an objective verification mechanism?
How do I make errors get discovered, classified, and fixed automatically?
How do I use AI to run the old-vs-new comparison testing better?</p>
</blockquote>

<p>Ordinary engineers rarely get to take part in a million-line language migration. The Bun migration Anthropic disclosed here cost roughly $165,000 at API pricing alone, consuming 5.9 billion uncached input tokens and 690 million output tokens.</p>

<p>So this is not just a product-marketing piece — it can also be read as a very expensive large-scale AI engineering experiment report.</p>

<p>And it genuinely contains many practices you can apply directly to everyday development.</p>

<h2 id="1-ai-didnt-change-coding-speed--it-changed-the-economics-of-migration-projects">1. AI didn’t change coding speed — it changed the economics of migration projects</h2>

<p>In the past, a large language migration usually meant a multi-year project.</p>

<p>The team had to maintain two codebases for a long time:</p>

<ul>
  <li>The old system kept carrying production traffic;</li>
  <li>The new system kept filling in features;</li>
  <li>New features might have to be built on both sides at once;</li>
  <li>Even at the end, the two might only reach 90% feature parity.</li>
</ul>

<p>If the migration failed, the team ended up not with a better system, but with two systems to maintain.</p>

<p>So in the past, only a truly severe problem was enough to justify a large language migration — for example:</p>

<ul>
  <li>The original language ecosystem was gradually declining;</li>
  <li>There were long-standing memory-safety problems;</li>
  <li>Build speed was seriously hurting release velocity;</li>
  <li>Some architectural bottleneck could no longer be worked around.</li>
</ul>

<p>AI agents changed this cost model.</p>

<p>Anthropic offers an interesting judgment in the article:</p>

<blockquote>
  <p>Now the worst case of a failed migration might just be deleting the branch and doing it again.</p>
</blockquote>

<p>This does not mean code migration has become cheap.</p>

<p>The Bun migration still cost about $165,000 at API pricing. But compared with projects that used to run for years and burn millions of dollars of engineering resources, the cost of trial and error has dropped dramatically.</p>

<p>Worth noting: even this <em>successful</em> Bun migration saw 19 regressions surface after merge (all since fixed). That’s exactly the point of this piece — once migration gets fast, regression and quality verification don’t become optional; they become more critical.</p>

<p>So some problems that “weren’t worth migrating” before may now be worth recalculating the ROI on.</p>

<p>For example, an internal Python tool at Anthropic used to be built per platform — roughly 8 minutes each — for a total wait of about 30 minutes across the build matrix. After migrating to TypeScript, compile time dropped to about two seconds, startup got 6x faster, and a whole separate deployment pipeline could be retired.</p>

<p>AI doesn’t just make migration faster — it lowers the bar for a company to re-evaluate its technical debt.</p>

<h2 id="2-the-single-most-important-sentence-in-the-article">2. The single most important sentence in the article</h2>

<p>Anthropic states a core idea in the article:</p>

<blockquote>
  <p>You don’t fix the code. You fix the process (loop) that produced the code.</p>
</blockquote>

<p>This one line can almost summarize the entire AI migration methodology.</p>

<p>In traditional development, when an engineer finds a bug, they usually edit the corresponding file.</p>

<p>But in a large-scale agent migration, if dozens of files exhibit the same class of error, editing them one by one does not solve the real problem.</p>

<p>What actually needs to change might be:</p>

<ul>
  <li>An incomplete migration rule;</li>
  <li>A missing constraint in the prompt;</li>
  <li>An unreasonable task split;</li>
  <li>A review agent that doesn’t cover a certain class of risk;</li>
  <li>A test judge that can’t recognize a certain class of error;</li>
  <li>A work queue that doesn’t correctly record failure state.</li>
</ul>

<p>The right move is not to have an engineer hand-edit dozens of files, but to:</p>

<ol>
  <li>Find the shared rule that produced this class of error;</li>
  <li>Fix the rule or the workflow;</li>
  <li>Regenerate the affected code;</li>
  <li>Verify again through tests and review.</li>
</ol>

<p>This is one of the biggest differences between agent engineering and traditional coding.</p>

<p>The engineer’s focus starts to shift from “producing code directly” to “designing a system that can keep producing correct code.”</p>

<h2 id="3-anthropics-six-step-method-for-large-scale-code-migration">3. Anthropic’s six-step method for large-scale code migration</h2>

<h3 id="prerequisite-first-build-a-reliable-judge">Prerequisite: first build a reliable judge</h3>

<p>Before the real migration, you first need a “judge” that can evaluate both the old and the new system.</p>

<p>That judge might be:</p>

<ul>
  <li>An automated test suite;</li>
  <li>A compiler;</li>
  <li>An old-vs-new output comparison tool;</li>
  <li>API contract tests;</li>
  <li>Replay of real business scenarios;</li>
  <li>Performance and resource-usage benchmarks.</li>
</ul>

<p>A good judge must satisfy two conditions:</p>

<p>First, it passes normally on the old system.</p>

<p>Second, when the system is deliberately broken, it must be able to detect the problem.</p>

<p>The article puts it bluntly:</p>

<blockquote>
  <p>A judge that can’t detect failure isn’t a judge.</p>
</blockquote>

<p>In reality, many old projects have tests that rely on internal functions or language features and can’t be reused directly in the new language.</p>

<p>So you first have to classify the tests:</p>

<ul>
  <li>Which can be run through external interfaces;</li>
  <li>Which depend on internal implementation;</li>
  <li>Which need to be reworked into cross-language tests;</li>
  <li>Whether the rewritten tests weakened the original assertions.</li>
</ul>

<p>Lacking a complete test suite doesn’t mean you can’t migrate.</p>

<p>The Python-to-TypeScript project built only seven real business scenarios, then ran them on both the old and new systems and diffed the output of every command.</p>

<p>The point here isn’t how many tests you have — it’s that you must establish an objective standard both sides accept.</p>

<p>The old system itself is the new system’s most important ground truth.</p>

<h3 id="step-1-build-the-rulebook-dependency-graph-and-difference-list">Step 1: build the rulebook, dependency graph, and difference list</h3>

<p>This is the most important — and most engineer-time-consuming — phase of the whole migration.</p>

<p><strong>1. The rulebook</strong></p>

<p>The rulebook tells all migration agents:</p>

<ul>
  <li>How types should convert;</li>
  <li>How error handling should be implemented;</li>
  <li>How memory and resources should be managed;</li>
  <li>What patterns to use for logging, config, and dependency injection;</li>
  <li>Which old-language idioms must not be copied directly;</li>
  <li>Which architecture must stay consistent;</li>
  <li>Which parts are allowed to be redesigned.</li>
</ul>

<p>If the goal is to preserve the existing structure, the rulebook may mostly be a set of language and type mapping rules.</p>

<p>If the migration also involves architectural refactoring, the rulebook is closer to a full design document.</p>

<p>It’s not an ordinary prompt — it’s an engineering spec every agent must obey.</p>

<p><strong>2. The dependency graph</strong></p>

<p>Large-scale migration needs heavy parallelism.</p>

<p>But parallelism requires knowing:</p>

<ul>
  <li>Which files can be migrated independently;</li>
  <li>Which modules must be handled together;</li>
  <li>Which low-level dependencies should be done first;</li>
  <li>Which circular dependencies must be broken up in advance.</li>
</ul>

<p>So Anthropic first uses a deterministic script to analyze code dependencies, then has an agent review and fix the dependency graph.</p>

<p>There’s an important principle here:</p>

<blockquote>
  <p>Don’t leave to the model’s guessing what a deterministic program can do.</p>
</blockquote>

<p><strong>3. The difference list</strong></p>

<p>There are inevitable semantic differences between the old and new languages. For example:</p>

<ul>
  <li>One core difference from Zig to Rust is memory ownership;</li>
  <li>One core difference from Python to TypeScript is interfaces and type contracts;</li>
  <li>Implicit behavior in a dynamic language must be declared explicitly in a static one;</li>
  <li>Circular dependencies the old system allowed may not compile in the new one.</li>
</ul>

<p>These problems can’t be solved by simple syntax substitution and must go into the difference list ahead of time.</p>

<p>The rulebook defines the default approach; the difference list records the cases the default rules don’t cover.</p>

<h3 id="step-2-first-run-a-small-throwaway-experiment">Step 2: first run a small, throwaway experiment</h3>

<p>I think this is one of the most worth-learning practices in the whole article.</p>

<p>Anthropic doesn’t migrate all the code the moment the rules are done. Instead, it first picks a small set of representative files and runs a small-scale migration experiment.</p>

<p>In the Bun migration, they set up:</p>

<ul>
  <li>One agent that migrated three files strictly by the rulebook;</li>
  <li>One agent that migrated the same files the way a “senior Rust engineer” would;</li>
  <li>A third agent that compared the two results and generated new migration rules.</li>
</ul>

<p>From this experiment alone, they caught two serious problems ahead of time.</p>

<p>If those problems hadn’t been exposed at the small scale but had instead spread across all 1,448 files, the cost of fixing them later would have been enormous.</p>

<p>Even more counterintuitive:</p>

<blockquote>
  <p>The code the experiment produces should be thrown away.</p>
</blockquote>

<p>Because the point of this phase isn’t to make migration progress — it’s to validate the migration rules.</p>

<p>This is a lot like a spike, PoC, or pilot in everyday development, except AI makes such experiments much cheaper.</p>

<p>Exposing rule problems with a little code first, then running massively in parallel, is more reliable than chasing migration progress from the start.</p>

<h3 id="step-3-massively-parallel-migration">Step 3: massively parallel migration</h3>

<p>Only after the rules are validated does the real full-code migration begin.</p>

<p>Anthropic’s basic loop is:</p>

<blockquote>
  <p>Implement → Review → Fix</p>
</blockquote>

<p>Multiple implementation agents work on different files or modules in parallel.</p>

<p>To control cost, high-throughput implementation work can go to smaller, cheaper models; complex rule design, architectural judgment, and code review go to stronger models.</p>

<p>The migration queue is managed by a script, not by the agent’s own memory. For example:</p>

<ul>
  <li>Check whether the target file already exists;</li>
  <li>Automatically compute the files not yet migrated;</li>
  <li>Split tasks by dependency order;</li>
  <li>Assign tasks to new agents;</li>
  <li>Resume from on-disk state after a failure.</li>
</ul>

<p>Designed this way, the migration naturally supports pause and resume.</p>

<p>Wherever an agent can’t decide how to migrate, it marks it uniformly:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>// TODO(port): &lt;reason&gt;
</code></pre></div></div>

<p>After that, compiler errors, smoke-test crashes, and test failures automatically become the next batch of fix tasks.</p>

<p>The queue doesn’t need long-term manual maintenance, because the failures themselves keep generating new tasks.</p>

<h3 id="step-4-compile-and-fix-by-error-pattern">Step 4: compile, and fix by error pattern</h3>

<p>Once the initial migration is done, the compilation phase begins.</p>

<p>Here you have to decide where to place the compiler based on the project’s characteristics.</p>

<p>TypeScript compiles fast, so it can sit inside each agent’s loop.</p>

<p>A full build of a large Rust project can take minutes, so the Bun migration didn’t have each agent run compilation independently. Instead, a unified orchestration script ran the full build, then handed the error list out to multiple fix agents.</p>

<p>This design also reflects cost control. If every agent repeatedly ran the full build, it would waste huge amounts of CPU, time, tokens, context, and CI resources.</p>

<p>So they set up a single build daemon.</p>

<p>Only this process can rebuild the program. Other agents only submit patches, and the build daemon batches the patches, does a unified build, and re-runs the relevant tests.</p>

<p>Essentially, it centralizes the most expensive operation instead of letting a swarm of agents repeat it.</p>

<h3 id="step-5-run-smoke-tests-cluster-problems-by-root-cause">Step 5: run smoke tests, cluster problems by root cause</h3>

<p>Passing compilation doesn’t mean the program runs. Next you run smoke tests to find:</p>

<ul>
  <li>Startup failures;</li>
  <li>Runtime crashes;</li>
  <li>Config-loading errors;</li>
  <li>Resource-initialization issues;</li>
  <li>Module-boundary errors;</li>
  <li>Abnormal external-dependency calls.</li>
</ul>

<p>Here, too, you can’t look at a single error at a time.</p>

<p>If dozens of crashes come from the same root cause, you should fix the upstream rule or architecture, not have dozens of agents submit ad-hoc patches separately.</p>

<p>Anthropic’s approach is to cluster problems by root cause first, then have adversarial review agents check the classification and the fix plan.</p>

<h3 id="step-6-compare-old-vs-new-system-behavior">Step 6: compare old-vs-new system behavior</h3>

<p>The final step is confirming the old and new systems truly behave the same.</p>

<p>By now, the new code has been translated, compiled, smoke-tested, and had its basic problems fixed. But to prove the migration succeeded, you still need to compare real behavior.</p>

<p>Anthropic splits the test tasks up. Each failing test is handled by an independent fix agent that looks at, all at once:</p>

<ul>
  <li>The old code;</li>
  <li>The new code;</li>
  <li>The test input;</li>
  <li>The actual output;</li>
  <li>The expected behavior.</li>
</ul>

<p>After the fix, an adversarial review agent checks the change.</p>

<p>The Python-to-TypeScript migration also used seven real usage scenarios to call both systems, then diffed the output item by item.</p>

<p>After that, Claude autonomously designed an end-to-end test suite and ran, fixed, and re-ran it for four nights in a row, surfacing edge cases that a hand-written scenario list would struggle to anticipate.</p>

<p>This is exactly where I think AI is well suited to shine:</p>

<p>not just having AI generate business code, but having AI:</p>

<ul>
  <li>Analyze the old system’s behavior;</li>
  <li>Generate comparison tests;</li>
  <li>Look for edge scenarios;</li>
  <li>Classify failing results;</li>
  <li>Propose fixes;</li>
  <li>Then call deterministic tools to verify.</li>
</ul>

<h2 id="4-the-four-engineering-practices-most-worth-learning">4. The four engineering practices most worth learning</h2>

<h3 id="41-human-time-should-be-invested-up-front">4.1 Human time should be invested up front</h3>

<p>AI can generate code fast, but migration rules, architectural boundaries, and verification standards still require heavy engineer time.</p>

<p>Anthropic’s conclusion:</p>

<blockquote>
  <p>Human effort should be front-loaded as much as possible.</p>
</blockquote>

<p>The parts that cost engineers the most time are:</p>

<ul>
  <li>Writing the rules;</li>
  <li>Identifying language and architecture differences;</li>
  <li>Building the test judge;</li>
  <li>Designing the task queue;</li>
  <li>Running the small-scale stress test.</li>
</ul>

<p>Once these are done, the rest is mostly letting the task queue converge.</p>

<p>This is exactly the opposite of how many people use coding agents.</p>

<p>Many people first have AI generate a lot of code, then slowly patch in rules after problems appear. But for large tasks, the more sensible order is:</p>

<blockquote>
  <p>Spend time defining the system first, then let AI execute fast.</p>
</blockquote>

<h3 id="42-review-must-be-adversarial">4.2 Review must be adversarial</h3>

<p>The article repeatedly mentions adversarial review.</p>

<p>An implementation agent’s goal is to finish the task.</p>

<p>A review agent’s goal should not be to help the implementation agent prove itself right — it should actively hunt for:</p>

<ul>
  <li>Rule violations;</li>
  <li>Hidden assumptions;</li>
  <li>Uncovered edge conditions;</li>
  <li>Behavior changes;</li>
  <li>Type and interface inconsistencies;</li>
  <li>Weakened tests;</li>
  <li>Temporary hacks treated as final implementations.</li>
</ul>

<p>Anthropic has two review agents check the same result in mutually independent contexts. If they disagree, a third agent decides.</p>

<p>This kind of mechanism suits not just code migration but also everyday work: architecture design reviews, data migrations, API refactors, database upgrades, framework upgrades, large code cleanups, security reviews, and test-plan reviews.</p>

<p>Not every agent should play “collaborator.” Some agents should be explicitly designed as skeptics, opponents, and breakers.</p>

<h3 id="43-review-the-process-outcomes-not-every-line-of-code">4.3 Review the process outcomes, not every line of code</h3>

<p>Facing a million lines of AI-generated code, no human can review it line by line. What engineers should really watch is:</p>

<ul>
  <li>Which errors keep recurring;</li>
  <li>Which rule produces the most problems;</li>
  <li>Which class of module has the highest failure rate;</li>
  <li>Which phase consumes the most tokens;</li>
  <li>Which tests never converge;</li>
  <li>Which agents keep violating the same constraint;</li>
  <li>Which tasks should go to a stronger model;</li>
  <li>Which judgments could be turned into deterministic scripts.</li>
</ul>

<p>In other words: you no longer just review the code — you review the loop that generates the code.</p>

<p>This doesn’t mean code review is unimportant; it means human attention should focus on high-risk code and systemic problems. Ordinary, repetitive, bulk code relies more on compilers, static checks, tests, diffs, contracts, adversarial agents, and automated gates.</p>

<h3 id="44-cost-management-is-architecture-design">4.4 Cost management is architecture design</h3>

<p>The article discusses cost control in many places. For example:</p>

<ul>
  <li>Use smaller models for bulk implementation;</li>
  <li>Use stronger models for rule-writing and final review;</li>
  <li>Avoid having each agent repeatedly run an expensive build;</li>
  <li>Use a single build daemon to batch patches;</li>
  <li>Place the compiler in the right spot;</li>
  <li>Make tasks pausable and resumable;</li>
  <li>Only regenerate the files affected by a rule change;</li>
  <li>Hand mechanical judgments to scripts, not the language model.</li>
</ul>

<p>This shows that in a large-scale agent system, model choice, task queue, build pipeline, and verification mechanism can no longer be considered separately.</p>

<p>Together they determine the project’s completion speed, token cost, infrastructure cost, error-convergence speed, and final quality.</p>

<p>Cost optimization for AI agents isn’t just “switch to a cheaper model” — it’s redesigning the entire execution pipeline.</p>

<h2 id="5-how-to-apply-these-practices-to-everyday-projects">5. How to apply these practices to everyday projects</h2>

<p>Most engineers won’t migrate a million lines, but this method still applies to ordinary development.</p>

<p>For a Java version upgrade, a Spring Boot upgrade, a database migration, an API refactor, or a front-end framework migration, you can use a similar flow:</p>

<p><strong>First, build a rules file.</strong> Make explicit: which patterns must be replaced; which interfaces must not change; which directories may not be modified; which compatibility behaviors must be preserved; which exception-handling styles must be unified; and what conditions require stopping and reporting.</p>

<p><strong>Second, build an old-vs-new comparison tool.</strong> For the same input, call both systems and compare: return values, error codes, logs, database changes, message output, performance, and memory and resource usage.</p>

<p><strong>Third, run a throwaway experiment first.</strong> Pick a few representative modules to migrate. Don’t rush to keep the code — use the experiment to find out whether the rules are complete, whether the agent understands the task, whether the tests can catch errors, whether the module split is reasonable, and whether the prompt is ambiguous.</p>

<p><strong>Fourth, have different agents play different roles.</strong> At minimum distinguish: implementation agent, rule-review agent, code-review agent, test-design agent, behavior-comparison agent, and risk-review agent.</p>

<p><strong>Fifth, fix the rule that produces the errors.</strong> When multiple modules show the same problem, don’t fix them one by one. First decide whether to change the rule, change the prompt, change the task split, add tests, add static checks, or change the model division of labor.</p>

<p>This may be the most important mindset shift when using coding agents at scale.</p>

<h2 id="closing">Closing</h2>

<p>AI agents are making some once-high-risk, long-cycle engineering projects feasible again.</p>

<p>But the biggest takeaway for me isn’t “Claude can generate a million lines in two weeks.”</p>

<p>What’s really worth noting is how Anthropic designed a complete engineering control system around AI’s uncertainty:</p>

<ul>
  <li>Constrain generation with rules;</li>
  <li>Validate the rules with a small experiment;</li>
  <li>Execute in parallel with many agents;</li>
  <li>Actively hunt for problems with adversarial agents;</li>
  <li>Use the compiler, tests, and diffs as the judge;</li>
  <li>Guarantee recoverable flow with a unified task queue;</li>
  <li>Control cost with models of different tiers;</li>
  <li>Fix the process — not just the code — when systemic problems appear.</li>
</ul>

<p>The faster AI writes code, the less an engineer can afford to focus on the code alone.</p>

<p>The more important skill for future engineers may be:</p>

<blockquote>
  <p>Designing constraints, building judges, organizing agents, and constructing an engineering loop that keeps finding and fixing errors.</p>
</blockquote>

<p>For any engineer using Claude Code, Codex, Cursor, or another coding agent, I strongly recommend reading the original. Even without an immediate large-migration need, it’s worth seeing how Anthropic designs prompts, rules, reviews, tests, and agent workflows.</p>

<p>These methods apply not only to language migration, but also to everyday refactoring, architecture upgrades, and complex feature development.</p>

<p><strong>Original:</strong> <a href="https://claude.com/blog/ai-code-migration">How Anthropic runs large-scale code migrations with Claude Code</a> (authored by / copyright Anthropic; this post is my write-up and personal reflection).</p>]]></content><author><name>KL</name></author><category term="AI" /><category term="LLM" /><category term="agent" /><summary type="html"><![CDATA[The faster AI writes code, the less an engineer can afford to focus on the code itself. The scarce skill is shifting from “getting every line right” to “designing a system that keeps producing correct code”: constrain generation with rules, validate the rules with a small experiment, let adversarial agents actively hunt for problems, and let the compiler and tests act as the judge. This is my write-up and reflection after reading Anthropic’s “How Anthropic runs large-scale code migrations with Claude Code.”]]></summary></entry><entry xml:lang="zh"><title type="html">AI 让代码迁移变快之后，质量保障反而更重要了</title><link href="https://kerryleung.github.io/blogs/2026/07/18/ai-code-migration-quality/" rel="alternate" type="text/html" title="AI 让代码迁移变快之后，质量保障反而更重要了" /><published>2026-07-18T00:00:00+00:00</published><updated>2026-07-18T00:00:00+00:00</updated><id>https://kerryleung.github.io/blogs/2026/07/18/ai-code-migration-quality</id><content type="html" xml:base="https://kerryleung.github.io/blogs/2026/07/18/ai-code-migration-quality/"><![CDATA[<blockquote>
  <p>AI 写代码的速度越快，工程师越不能只关注代码本身。真正稀缺的能力，正在从“写对每一行代码”转向“设计一套能持续生产正确代码的系统”：用规则约束生成、用小规模实验验证规则、用对抗性 Agent 主动找问题、用编译器和测试当裁判。这篇是我读 Anthropic《How Anthropic runs large-scale code migrations with Claude Code》后的整理与思考。</p>
</blockquote>

<p>最近读了 Anthropic 发布的一篇文章：《How Anthropic runs large-scale code migrations with Claude Code》。</p>

<p>文章分享了他们如何利用 Claude Code 和多个 AI Agent，完成多次大型代码迁移。其中包括：</p>

<ul>
  <li>在不到两周内，将 Bun 的大量代码从 Zig 迁移到 Rust，最终生成约 100 万行代码（共 1448 个文件）；</li>
  <li>在合并前，让 Bun 原有测试套件在 CI 中达到 100% 通过；</li>
  <li>将一个内部 Python 项目在一个周末内迁移为约 16.5 万行 TypeScript；</li>
  <li>使用数百个 Agent、8 个阶段门禁、3 轮对抗性审查，并逐条对比新旧系统的输出结果。</li>
</ul>

<p>文章篇幅不长，但里面关于规则制定、任务拆分、质量验证、对抗审查和成本控制的实践，信息密度非常高。</p>

<h2 id="先说说我的个人感受">先说说我的个人感受</h2>

<p>我自己做过多次中小型软件服务迁移，代码规模通常在几万行左右。</p>

<p>做过这类项目之后，会很清楚地意识到：代码迁移远远不是“把旧代码翻译成新代码”这么简单。</p>

<p>真正困难的问题通常包括：</p>

<ul>
  <li>如何在产品持续迭代的过程中完成迁移？</li>
  <li>如何避免同一个新功能在旧系统和新系统中分别实现一遍？</li>
  <li>如何拆分迁移任务，让多个开发者能够并行工作？</li>
  <li>如何保证迁移后的系统不出现严重质量问题？</li>
  <li>如何判断新系统已经真正达到旧系统的功能完整度？</li>
</ul>

<p>这些问题背后涉及的其实不是单纯的编码能力，而是项目管理、架构设计、任务拆解、测试计划和风险控制。</p>

<p>随着 AI 编程能力越来越强，代码迁移的速度确实可能获得数量级的提升。但与此同时，质量保障问题反而可能被进一步放大。</p>

<p>当 AI 可以在短时间内生成几万甚至几十万行代码时，人已经不可能逐个文件、逐个 Pull Request 地进行完整审查。</p>

<p>这时，工程师需要解决的问题就从：</p>

<blockquote>
  <p>AI 写的每一行代码是否正确？</p>
</blockquote>

<p>转变为：</p>

<blockquote>
  <p>如何约束 AI 不跑偏？
如何建立客观的验证机制？
如何让错误能够被自动发现、分类和修复？
如何利用 AI 更好地完成新旧系统的对比测试？</p>
</blockquote>

<p>普通工程师很少有机会参与百万行代码级别的语言迁移。Anthropic 这次公开的 Bun 迁移，仅按照 API 价格计算，就消耗了大约 16.5 万美元，使用了 59 亿个未缓存输入 Token 和 6.9 亿个输出 Token。</p>

<p>因此，这不仅是一篇产品宣传文章，也可以看作一份非常昂贵的大规模 AI 工程实验报告。</p>

<p>而且，里面确实有不少可以直接应用到日常开发工作的实践。</p>

<h2 id="一ai-改变的不是编码速度而是迁移项目的经济模型">一、AI 改变的不是编码速度，而是迁移项目的经济模型</h2>

<p>过去，大型语言迁移通常意味着持续数年的项目。</p>

<p>团队需要长期维护两套代码：</p>

<ul>
  <li>旧系统继续承载线上业务；</li>
  <li>新系统不断补齐功能；</li>
  <li>新功能可能需要同时在两边开发；</li>
  <li>迁移到最后仍然可能只有 90% 的功能一致性。</li>
</ul>

<p>如果迁移失败，团队得到的可能不是一个更好的系统，而是两套都需要维护的系统。</p>

<p>因此，过去只有非常严重的问题，才足以推动一次大型语言迁移，例如：</p>

<ul>
  <li>原有语言生态逐渐衰退；</li>
  <li>长期存在内存安全问题；</li>
  <li>构建速度严重影响发布效率；</li>
  <li>某个架构瓶颈已经无法继续绕过。</li>
</ul>

<p>AI Agent 改变了这个成本模型。</p>

<p>Anthropic 在文章中给出了一个很有意思的判断：</p>

<blockquote>
  <p>现在迁移失败的最坏结果，可能只是删除分支，然后重新再做一次。</p>
</blockquote>

<p>这并不意味着代码迁移已经变得便宜。</p>

<p>Bun 的迁移按照 API 定价仍然花费约 16.5 万美元。但相比过去可能持续数年、消耗数百万美元工程资源的项目，试错成本已经显著降低。</p>

<p>值得一提的是，即便是这次成功的 Bun 迁移，合并后仍然出现了 19 个回归问题（目前已全部修复）。这恰好印证了本文的判断：迁移变快之后，回归和质量验证不是变得可有可无，而是变得更加关键。</p>

<p>因此，一些过去“不值得迁移”的问题，现在可能已经值得重新计算投入产出比。</p>

<p>例如，Anthropic 内部的一个 Python 工具，过去需要针对不同平台分别构建，每个平台大约 8 分钟，完整构建矩阵大约需要等待 30 分钟。迁移到 TypeScript 后，编译时间缩短到约两秒，启动速度提升了六倍，同时还可以下线一套独立的部署流程。</p>

<p>AI 不只是让迁移变快，也降低了企业重新评估技术债的门槛。</p>

<h2 id="二整篇文章最重要的一句话">二、整篇文章最重要的一句话</h2>

<p>Anthropic 在文章中提出了一个核心观点：</p>

<blockquote>
  <p>You don’t fix the code. You fix the process (loop) that produced the code.</p>
</blockquote>

<p>翻译过来就是：</p>

<blockquote>
  <p>不要只修复代码，而要修复生成这些代码的流程（循环）。</p>
</blockquote>

<p>这句话几乎可以概括整套 AI 迁移方法。</p>

<p>在传统开发中，当工程师发现一个 Bug，通常会修改对应的文件。</p>

<p>但在大规模 Agent 迁移中，如果几十个文件都出现了同一类错误，逐个修改文件并不能解决真正的问题。</p>

<p>真正需要修改的可能是：</p>

<ul>
  <li>迁移规则不完整；</li>
  <li>Prompt 中缺少约束；</li>
  <li>任务划分方式不合理；</li>
  <li>审查 Agent 没有覆盖某类风险；</li>
  <li>测试裁判无法识别某类错误；</li>
  <li>工作队列没有正确记录失败状态。</li>
</ul>

<p>正确的做法不是让工程师手动修改几十个文件，而是：</p>

<ol>
  <li>找出产生这类错误的共同规则；</li>
  <li>修改规则或工作流程；</li>
  <li>重新生成受影响的代码；</li>
  <li>再次通过测试和审查验证。</li>
</ol>

<p>这也是 Agent 工程和传统编码最大的区别之一。</p>

<p>工程师的工作重点，开始从“直接生产代码”，转向“设计能够持续生产正确代码的系统”。</p>

<h2 id="三anthropic-的大型代码迁移六步法">三、Anthropic 的大型代码迁移六步法</h2>

<h3 id="前置条件先建立一个可靠的裁判">前置条件：先建立一个可靠的裁判</h3>

<p>正式迁移之前，首先需要建立一个能够同时评价旧系统和新系统的“裁判”。</p>

<p>这个裁判可能是：</p>

<ul>
  <li>自动化测试套件；</li>
  <li>编译器；</li>
  <li>新旧系统输出对比工具；</li>
  <li>API 契约测试；</li>
  <li>真实业务场景回放；</li>
  <li>性能与资源使用基准测试。</li>
</ul>

<p>一个好的裁判必须满足两个条件：</p>

<p>第一，它能够在旧系统上正常通过。</p>

<p>第二，当系统被故意破坏时，它必须能够发现问题。</p>

<p>文章中的说法很直接：</p>

<blockquote>
  <p>无法发现故障的裁判，就不是真正的裁判。</p>
</blockquote>

<p>现实中，很多旧项目的测试依赖内部函数或语言特性，无法直接复用到新的语言中。</p>

<p>这时需要先对测试进行分类：</p>

<ul>
  <li>哪些测试可以通过外部接口执行；</li>
  <li>哪些测试依赖内部实现；</li>
  <li>哪些测试需要改造成跨语言测试；</li>
  <li>改写后的测试是否削弱了原有断言。</li>
</ul>

<p>如果没有完整测试套件，也不代表无法迁移。</p>

<p>Python 到 TypeScript 的项目只构建了七个真实业务场景，然后同时在新旧系统中执行，对每条命令的输出进行 Diff。</p>

<p>这里的关键不是一定要有多少测试，而是必须建立一个双方都认可的客观标准。</p>

<p>旧系统本身，就是新系统最重要的 Ground Truth。</p>

<h3 id="第一步建立规则手册依赖图和差异清单">第一步：建立规则手册、依赖图和差异清单</h3>

<p>这是整个迁移过程中最重要、也最消耗工程师时间的阶段。</p>

<p><strong>1. 规则手册</strong></p>

<p>规则手册用于告诉所有迁移 Agent：</p>

<ul>
  <li>类型应该如何转换；</li>
  <li>错误处理应该如何实现；</li>
  <li>内存和资源应该如何管理；</li>
  <li>日志、配置和依赖注入应该使用什么模式；</li>
  <li>哪些旧语言习惯不能直接复制；</li>
  <li>哪些架构必须保持一致；</li>
  <li>哪些部分允许重新设计。</li>
</ul>

<p>如果迁移目标是保持原有结构，规则手册可能主要是一组语言和类型的映射规则。</p>

<p>如果迁移同时涉及架构重构，规则手册就更接近一份完整的设计文档。</p>

<p>它不是一个普通 Prompt，而是所有 Agent 必须遵守的工程规范。</p>

<p><strong>2. 依赖图</strong></p>

<p>大规模迁移需要高度并行。</p>

<p>但并行的前提是知道：</p>

<ul>
  <li>哪些文件可以独立迁移；</li>
  <li>哪些模块必须一起处理；</li>
  <li>哪些底层依赖应该优先完成；</li>
  <li>哪些循环依赖需要提前拆解。</li>
</ul>

<p>因此，Anthropic 会先利用确定性脚本分析代码依赖，再由 Agent 审查和修复依赖图。</p>

<p>这里有一个很重要的原则：</p>

<blockquote>
  <p>能用确定性程序完成的事情，不要完全交给模型猜测。</p>
</blockquote>

<p><strong>3. 差异清单</strong></p>

<p>旧语言和新语言之间必然存在语义差异。例如：</p>

<ul>
  <li>Zig 到 Rust 的核心差异之一是内存所有权；</li>
  <li>Python 到 TypeScript 的核心差异之一是接口和类型契约；</li>
  <li>动态语言中的隐式行为，在静态语言中必须被显式声明；</li>
  <li>旧系统允许的循环依赖，新系统可能无法编译。</li>
</ul>

<p>这些无法通过简单语法替换解决的问题，需要提前放入差异清单。</p>

<p>规则手册定义默认做法，差异清单记录默认规则无法覆盖的情况。</p>

<h3 id="第二步先做一次可以丢弃的小规模实验">第二步：先做一次可以丢弃的小规模实验</h3>

<p>我认为这是整篇文章里最值得学习的实践之一。</p>

<p>Anthropic 不会在规则完成后立即迁移全部代码，而是先选择少量具有代表性的文件，进行一次小规模迁移实验。</p>

<p>Bun 的迁移中，他们安排：</p>

<ul>
  <li>一个 Agent 严格按照规则手册迁移三个文件；</li>
  <li>一个 Agent 按照“资深 Rust 工程师”的方式迁移同样的文件；</li>
  <li>第三个 Agent 比较两份结果，并生成新的迁移规则。</li>
</ul>

<p>仅仅通过这次实验，他们就提前发现了两个严重问题。</p>

<p>如果这些问题没有在小规模阶段暴露，而是直接扩散到全部 1448 个文件，后面的修复成本会非常高。</p>

<p>更加反直觉的是：</p>

<blockquote>
  <p>实验产生的代码应该直接丢弃。</p>
</blockquote>

<p>因为这个阶段的目的不是完成迁移进度，而是验证迁移规则。</p>

<p>这和日常开发中的 Spike、PoC 或试点项目很像，但 AI 让这种实验的成本变得更低。</p>

<p>先用少量代码暴露规则问题，再大规模并行执行，比一开始追求迁移进度更可靠。</p>

<h3 id="第三步大规模并行迁移">第三步：大规模并行迁移</h3>

<p>规则经过验证后，才开始真正迁移全部代码。</p>

<p>Anthropic 使用的基本循环是：</p>

<blockquote>
  <p>Implement → Review → Fix
实现 → 审查 → 修复</p>
</blockquote>

<p>多个实现 Agent 并行处理不同文件或模块。</p>

<p>为了控制成本，高吞吐量的实现工作可以交给较小、较便宜的模型；复杂规则设计、架构判断和代码审查，则交给能力更强的模型。</p>

<p>迁移队列由脚本管理，而不是依赖 Agent 自己记忆。例如：</p>

<ul>
  <li>检查目标文件是否已经存在；</li>
  <li>自动计算还未迁移的文件；</li>
  <li>按照依赖关系切分任务；</li>
  <li>将任务分配给新的 Agent；</li>
  <li>失败后可以从磁盘状态继续执行。</li>
</ul>

<p>这样设计后，迁移过程天然可以暂停和恢复。</p>

<p>Agent 无法确定如何迁移的地方，则统一标记：</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>// TODO(port): &lt;reason&gt;
</code></pre></div></div>

<p>之后，编译器错误、Smoke Test 崩溃和测试失败，会自动成为下一批修复任务。</p>

<p>队列不需要人工长期维护，因为失败本身就在不断生成新的任务。</p>

<h3 id="第四步编译并按错误模式修复">第四步：编译，并按错误模式修复</h3>

<p>代码完成初步迁移后，开始进入编译阶段。</p>

<p>这里需要根据项目特点决定编译器放在什么位置。</p>

<p>TypeScript 编译速度较快，可以放入每个 Agent 的执行循环。</p>

<p>Rust 大型项目的完整编译可能需要几分钟，因此 Bun 的迁移没有让每个 Agent 独立运行编译，而是由统一的编排脚本执行完整构建，再把错误列表分配给多个修复 Agent。</p>

<p>这个设计也体现了成本控制。如果每个 Agent 都重复执行完整构建，会浪费大量 CPU、时间、Token、上下文和 CI 资源。</p>

<p>因此，他们设置了一个统一的 Build Daemon。</p>

<p>只有这个进程可以重新构建程序。其他 Agent 只负责提交补丁，由 Build Daemon 对补丁进行批量合并、统一构建并重新执行相关测试。</p>

<p>它本质上是把最昂贵的操作集中管理，而不是让大量 Agent 重复执行。</p>

<h3 id="第五步运行-smoke-test按根因归类问题">第五步：运行 Smoke Test，按根因归类问题</h3>

<p>通过编译不代表程序能够正常运行。接下来需要执行 Smoke Test，发现：</p>

<ul>
  <li>启动失败；</li>
  <li>Runtime Crash；</li>
  <li>配置加载错误；</li>
  <li>资源初始化问题；</li>
  <li>模块边界错误；</li>
  <li>外部依赖调用异常。</li>
</ul>

<p>这里同样不能只看单个错误。</p>

<p>如果几十个崩溃来自同一个根因，就应该修改上游规则或架构，而不是让几十个 Agent 分别提交临时补丁。</p>

<p>Anthropic 的做法是先按根因对问题进行聚类，再由对抗性审查 Agent 检查问题分类和修复方案。</p>

<h3 id="第六步进行新旧系统行为对比">第六步：进行新旧系统行为对比</h3>

<p>最后一步，是确认新旧系统的行为真正一致。</p>

<p>此时，新代码已经完成翻译、编译、Smoke Test 和基本问题修复。但要证明迁移成功，仍然需要对比真实行为。</p>

<p>Anthropic 会将测试任务拆分执行。每个失败测试由独立的修复 Agent 同时查看：</p>

<ul>
  <li>旧代码；</li>
  <li>新代码；</li>
  <li>测试输入；</li>
  <li>实际输出；</li>
  <li>预期行为。</li>
</ul>

<p>修复之后，再由对抗性审查 Agent 检查修改。</p>

<p>Python 到 TypeScript 的迁移，还使用七个真实使用场景分别调用两个系统，然后对输出逐项进行 Diff。</p>

<p>之后，Claude 又自动设计了一套端到端测试，连续四个晚上运行、修复并重新执行，从而发现了一些人工场景列表很难提前想到的边缘问题。</p>

<p>这也是我认为 AI 非常适合发挥能力的地方：</p>

<p>不是只让 AI 生成业务代码，而是让 AI：</p>

<ul>
  <li>分析旧系统行为；</li>
  <li>生成对比测试；</li>
  <li>寻找边界场景；</li>
  <li>对失败结果进行分类；</li>
  <li>提出修复方案；</li>
  <li>再调用确定性工具进行验证。</li>
</ul>

<h2 id="四最值得学习的四个工程实践">四、最值得学习的四个工程实践</h2>

<h3 id="1-人的时间应该前置投入">1. 人的时间应该前置投入</h3>

<p>AI 可以快速生成代码，但迁移规则、架构边界和验证标准仍然需要工程师投入大量时间。</p>

<p>Anthropic 的结论是：</p>

<blockquote>
  <p>人工投入应该尽量前置。</p>
</blockquote>

<p>最花费工程师时间的部分是：</p>

<ul>
  <li>制定规则；</li>
  <li>识别语言和架构差异；</li>
  <li>建立测试裁判；</li>
  <li>设计任务队列；</li>
  <li>完成小规模压力测试。</li>
</ul>

<p>一旦这些工作完成，后面的过程主要是让任务队列不断收敛。</p>

<p>这和很多人使用 Coding Agent 的习惯恰好相反。</p>

<p>很多人会先让 AI 大量生成代码，发现问题后再慢慢补规则。但对于大型任务，更合理的顺序是：</p>

<blockquote>
  <p>先花时间定义系统，再让 AI 快速执行。</p>
</blockquote>

<h3 id="2-审查必须具有对抗性">2. 审查必须具有对抗性</h3>

<p>文章中多次提到 Adversarial Review，也就是对抗性审查。</p>

<p>实现 Agent 的目标是完成任务。</p>

<p>审查 Agent 的目标不应该是帮助实现 Agent 证明自己正确，而应该主动寻找：</p>

<ul>
  <li>违反规则的地方；</li>
  <li>隐含假设；</li>
  <li>未覆盖的边界条件；</li>
  <li>行为变化；</li>
  <li>类型和接口不一致；</li>
  <li>测试被弱化的问题；</li>
  <li>临时方案被当成最终实现的问题。</li>
</ul>

<p>Anthropic 会让两个审查 Agent 在相互独立的上下文中检查同一份结果。如果两者意见不一致，再交给第三个 Agent 判断。</p>

<p>这类机制不只适合代码迁移，也很适合日常工作中的：架构设计评审、数据迁移、API 重构、数据库升级、框架升级、大型代码清理、安全审查、测试计划评审。</p>

<p>Agent 不应该全部扮演“协作者”。有些 Agent 应该被明确设计成怀疑者、反对者和破坏者。</p>

<h3 id="3-审查流程结果而不是逐行审查代码">3. 审查流程结果，而不是逐行审查代码</h3>

<p>面对百万行 AI 生成代码，人不可能逐行审查。工程师真正应该关注的是：</p>

<ul>
  <li>哪些错误反复出现；</li>
  <li>哪条规则产生了最多问题；</li>
  <li>哪类模块失败率最高；</li>
  <li>哪个阶段消耗最多 Token；</li>
  <li>哪些测试长期无法收敛；</li>
  <li>哪些 Agent 经常违反相同约束；</li>
  <li>哪些任务应该交给更强的模型；</li>
  <li>哪些判断可以改成确定性脚本。</li>
</ul>

<p>也就是说，不再只审查代码，而是审查生成代码的 Loop。</p>

<p>这并不代表代码审查不重要，而是人的注意力应该集中在高风险代码和系统性问题上。普通、重复、大批量的代码，则更多依靠编译器、静态检查、测试、Diff、契约、对抗性 Agent 和自动化门禁。</p>

<h3 id="4-成本管理本身就是架构设计">4. 成本管理本身就是架构设计</h3>

<p>文章很多地方都在讨论如何控制成本。例如：</p>

<ul>
  <li>大批量实现使用较小模型；</li>
  <li>规则制定和最终审查使用较强模型；</li>
  <li>避免每个 Agent 重复执行昂贵构建；</li>
  <li>使用统一 Build Daemon 批量处理补丁；</li>
  <li>将编译器放在适合的位置；</li>
  <li>让任务可以暂停和恢复；</li>
  <li>只重新生成受规则变化影响的文件；</li>
  <li>把机械性判断交给脚本，而不是语言模型。</li>
</ul>

<p>这说明在大规模 Agent 系统中，模型选择、任务队列、构建流程和验证机制已经不能分开考虑。</p>

<p>它们共同决定了：项目的完成速度、Token 成本、基础设施成本、错误收敛速度和最终质量。</p>

<p>AI Agent 的成本优化，不只是“换一个便宜模型”，而是重新设计整个执行流程。</p>

<h2 id="五这些实践如何应用到日常项目">五、这些实践如何应用到日常项目</h2>

<p>大多数工程师不会迁移百万行代码，但这套方法仍然可以应用到普通开发中。</p>

<p>例如进行 Java 版本升级、Spring Boot 升级、数据库迁移、API 重构或前端框架迁移时，可以采用类似流程：</p>

<p><strong>第一，先建立规则文件。</strong> 明确：哪些模式必须替换；哪些接口不能改变；哪些目录不允许修改；哪些兼容行为必须保留；哪些异常处理方式需要统一；什么情况必须停止并报告。</p>

<p><strong>第二，建立新旧系统对比工具。</strong> 相同输入分别调用新旧系统，比较：返回值、错误码、日志、数据库变更、消息输出、性能、内存和资源使用。</p>

<p><strong>第三，先做一次可丢弃实验。</strong> 选择几个典型模块进行迁移。不要急着保留代码，而是通过实验发现：规则是否完整；Agent 是否理解任务；测试是否能够发现错误；模块拆分是否合理；Prompt 是否存在歧义。</p>

<p><strong>第四，让不同 Agent 扮演不同角色。</strong> 至少区分：实现 Agent、规则审查 Agent、代码审查 Agent、测试设计 Agent、行为对比 Agent、风险审查 Agent。</p>

<p><strong>第五，修复产生错误的规则。</strong> 当多个模块出现相同问题时，不要逐个修改。先判断是否应该：修改规则、修改 Prompt、修改任务拆分、增加测试、增加静态检查、改变模型分工。</p>

<p>这可能才是大规模使用 Coding Agent 时最重要的思维变化。</p>

<h2 id="写在最后">写在最后</h2>

<p>AI Agent 正在让一些过去风险极高、周期极长的工程项目重新变得可行。</p>

<p>但文章给我的最大启发，并不是“Claude 可以在两周内生成百万行代码”。</p>

<p>真正值得关注的是，Anthropic 如何围绕 AI 的不确定性，设计了一套完整的工程控制系统：</p>

<ul>
  <li>用规则约束生成；</li>
  <li>用小规模实验验证规则；</li>
  <li>用多个 Agent 并行执行；</li>
  <li>用对抗性 Agent 主动寻找问题；</li>
  <li>用编译器、测试和 Diff 充当裁判；</li>
  <li>用统一任务队列保证流程可以恢复；</li>
  <li>用不同等级的模型控制成本；</li>
  <li>发现系统性问题后修改流程，而不是只修改代码。</li>
</ul>

<p>AI 写代码的速度越快，工程师越不能只关注代码本身。</p>

<p>未来工程师更重要的能力，可能是：</p>

<blockquote>
  <p>设计约束、建立裁判、组织 Agent，并构建一个能够持续发现和修复错误的工程闭环。</p>
</blockquote>

<p>对于正在使用 Claude Code、Codex、Cursor 或其他 Coding Agent 的工程师，我非常推荐阅读原文。即使暂时没有大型代码迁移需求，也可以看看 Anthropic 如何设计 Prompt、Rule、Review、Test 和 Agent Workflow。</p>

<p>这些方法不仅适用于语言迁移，对日常的软件重构、架构升级和复杂功能开发同样很有参考价值。</p>

<p><strong>原文：</strong> <a href="https://claude.com/blog/ai-code-migration">How Anthropic runs large-scale code migrations with Claude Code</a>（作者 / 版权归 Anthropic；本文为读后整理与个人思考）</p>]]></content><author><name>KL</name></author><category term="AI" /><category term="LLM" /><category term="agent" /><summary type="html"><![CDATA[AI 写代码的速度越快，工程师越不能只关注代码本身。真正稀缺的能力，正在从“写对每一行代码”转向“设计一套能持续生产正确代码的系统”：用规则约束生成、用小规模实验验证规则、用对抗性 Agent 主动找问题、用编译器和测试当裁判。这篇是我读 Anthropic《How Anthropic runs large-scale code migrations with Claude Code》后的整理与思考。]]></summary></entry><entry xml:lang="en"><title type="html">Knowledge Management for Coding Agents: Stop Stuffing Context, Build a Compounding Workflow</title><link href="https://kerryleung.github.io/blogs/2026/07/02/coding-agent-knowledge-routing-en/" rel="alternate" type="text/html" title="Knowledge Management for Coding Agents: Stop Stuffing Context, Build a Compounding Workflow" /><published>2026-07-02T00:00:00+00:00</published><updated>2026-07-02T00:00:00+00:00</updated><id>https://kerryleung.github.io/blogs/2026/07/02/coding-agent-knowledge-routing-en</id><content type="html" xml:base="https://kerryleung.github.io/blogs/2026/07/02/coding-agent-knowledge-routing-en/"><![CDATA[<blockquote>
  <p>In the Coding Agent era, the core of knowledge management is not “remember more.” It is “load on demand.” What matters is not context size, but context routing: load the right knowledge at the right stage, make every judgment evidence-backed, and gradually turn repeated experience into automated checks. This is a key step from prompt engineering to agent system engineering.</p>
</blockquote>

<p>I have been thinking about a question: how should knowledge be managed in a Coding Agent development workflow?</p>

<p>When many teams start using agents, their first instinct is to give the agent more context: more docs, more memory, more rules, more historical cases.</p>

<p>But the result is not always better. An agent is not a human. More context does not automatically make it smarter. It can create new problems:</p>

<ul>
  <li>It reads stale information</li>
  <li>It gets misled by old cases</li>
  <li>It wastes tokens on irrelevant documents</li>
  <li>It treats “something happened before” as “this must be happening now”</li>
  <li>It emits review comments that sound plausible but lack evidence</li>
</ul>

<p>So knowledge management for Coding Agents should not only be organized by topic, such as “metrics docs,” “security docs,” or “test docs.”</p>

<p>The more important dimension is access pattern:</p>

<ul>
  <li>When should this knowledge be loaded?</li>
  <li>What decision does it support?</li>
  <li>If we do not load it, will the current task suffer?</li>
</ul>

<p>In other words, the core question is not “what do we know?” It is “what does this task need loaded to support judgment?”</p>

<h2 id="1-the-core-pattern-index--route--body">1. The core pattern: Index → Route → Body</h2>

<p>The pattern I like is:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Index → Route → Body
</code></pre></div></div>

<p>That means: read the index first, route second, and only then load the necessary body.</p>

<p>An agent should not read the whole knowledge base at startup. A better approach is:</p>

<ol>
  <li><strong>Index</strong>: by default, load only small indexes, summaries, and trigger conditions.</li>
  <li><strong>Route</strong>: classify by task type, changed files, and impact area.</li>
  <li><strong>Body</strong>: load the full document only when routing hits.</li>
</ol>

<p>Take a <code class="language-plaintext highlighter-rouge">team-code-review</code> review loop as an example. It can parse the PR, get changed files, then classify the change:</p>

<ul>
  <li>domain model change</li>
  <li>metric change</li>
  <li>locale formatting change</li>
  <li>access control change</li>
  <li>test-only change</li>
  <li>CI/config change</li>
</ul>

<p>If the PR touches locale formatting files, load the locale spec.<br />
If the PR touches a shared metric, load shared metric rules and relevant lessons.<br />
If it only changes test config, do not load the locale spec.</p>

<p>This distinction matters.</p>

<p>A low-quality loop says: “I give the agent every document and hope it can figure it out.”</p>

<p>A sustainable loop says: “I ask the agent to classify first, then only load the knowledge needed for the current judgment.”</p>

<p><strong>The first merely piles up context. The second builds a reusable engineering system.</strong></p>

<h2 id="2-knowledge-should-be-layered">2. Knowledge should be layered</h2>

<p>In a Coding Agent workflow, I tend to separate knowledge into several layers. Each layer should have its own loading moment instead of entering the global prompt by default.</p>

<h2 id="3-contracts--invariants-what-must-never-break">3. Contracts / Invariants: what must never break</h2>

<p>This is the most important layer, and often the earliest one to load.</p>

<p>It answers the question: what must not be broken?</p>

<p>For example:</p>

<ul>
  <li>access control</li>
  <li>public field name</li>
  <li>API contract</li>
  <li>schema</li>
  <li>module boundary</li>
  <li>data ownership</li>
  <li>cross-system interpretation rules</li>
</ul>

<p>If a PR changes access-control metadata, the review loop must load the access-control contract before reviewing.</p>

<p>If this kind of issue is wrong, the impact is usually not a local bug. It is a broken system boundary.</p>

<p>But if the PR does not touch these boundaries at all, there is no need to load them.</p>

<p><strong>Invariants should be loaded early, but only when the relevant boundary is touched.</strong></p>

<h2 id="4-maps--indexes-where-to-find-information">4. Maps / Indexes: where to find information</h2>

<p>A map is not supposed to explain every detail. Its job is to help the agent route.</p>

<p>A good map should be small enough to scan quickly.</p>

<p>For example:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>If files under shared_metrics/ change,
load the shared metric rule,
and run the metric validation path.
</code></pre></div></div>

<p>That is much better than:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Here is everything we know about metrics.
</code></pre></div></div>

<p>The first is an executable routing rule. The second is an information pile.</p>

<p><strong>A map is not the knowledge body. A map is the routing table that keeps the agent from reading the wrong documents.</strong></p>

<h2 id="5-specs-what-correct-behavior-means">5. Specs: what correct behavior means</h2>

<p>A spec is the correctness oracle.</p>

<p>When a PR claims to change a behavior, the agent should not judge correctness from memory. It should load the corresponding spec.</p>

<p>If a PR changes date formatting behavior, the review loop should load the formatting spec and check:</p>

<ul>
  <li>whether the new format matches the spec</li>
  <li>whether every affected surface is covered</li>
  <li>whether tests prove the output change is expected</li>
</ul>

<p>If the spec does not define the expected behavior, the agent should not invent a standard.</p>

<p>A better finding is:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>The expected behavior is not defined. Add a spec before treating this as correct.
</code></pre></div></div>

<p>That is more engineering-oriented than judging from experience.</p>

<h2 id="6-procedures--skills-how-this-task-should-be-done">6. Procedures / Skills: how this task should be done</h2>

<p>A procedure answers: how should this kind of task be performed in this project?</p>

<p>For example, the main code review command should not contain every review checklist. It is better suited for orchestration.</p>

<p>Specific checklists can be split into skills:</p>

<ul>
  <li>domain field review skill</li>
  <li>formatting review skill</li>
  <li>security/access review skill</li>
  <li>test adequacy review skill</li>
  <li>PR comment posting skill</li>
</ul>

<p>This keeps the main workflow light, while domain-specific gotchas live inside the corresponding skill.</p>

<p><strong>The main workflow owns orchestration. Skills own procedural detail.</strong></p>

<p>That is a key part of making agent workflows maintainable.</p>

<h2 id="7-adrs-why-this-design-exists">7. ADRs: why this design exists</h2>

<p>The value of ADRs is that they stop agents from “fixing” an intentional design.</p>

<p>Many times, when an agent sees complex code, it instinctively wants to simplify it. Sometimes that is right. But sometimes the complexity is intentional: compatibility, cross-system contracts, performance constraints, or migration strategy.</p>

<p>So ADRs should be triggered when a PR touches:</p>

<ul>
  <li>established module boundary</li>
  <li>long-lived naming convention</li>
  <li>cross-system contract</li>
  <li>known tradeoff</li>
  <li>compatibility decision</li>
</ul>

<p>ADRs should not be loaded every time. They should be hit through an index and loaded when related areas change.</p>

<p>Otherwise, the agent can get distracted by historical design discussions in irrelevant situations.</p>

<h2 id="8-plans-temporary-scaffolding-not-permanent-context">8. Plans: temporary scaffolding, not permanent context</h2>

<p>Plans are useful, but they are temporary scaffolding.</p>

<p>They fit:</p>

<ul>
  <li>stacked PRs</li>
  <li>phased migrations</li>
  <li>active refactors</li>
  <li>multi-stage rollouts</li>
</ul>

<p>But a plan should not stay in the default context forever.</p>

<p>Once the work is complete, durable knowledge should move elsewhere:</p>

<ul>
  <li>stable behavior → spec</li>
  <li>design rationale → ADR</li>
  <li>repeated failure → lesson / gotcha</li>
  <li>automatically verifiable issue → test / CI check</li>
</ul>

<p>A simple rule:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Plans expire.
Specs and ADRs survive.
</code></pre></div></div>

<p><strong>A plan is scaffolding, not the building.</strong></p>

<h2 id="9-lessons--rules-only-triggerable-lessons-are-valuable">9. Lessons / Rules: only triggerable lessons are valuable</h2>

<p>The most common problem with lessons is that they are too generic.</p>

<p>A bad lesson:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Be careful with metrics.
</code></pre></div></div>

<p>A good lesson:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>When a PR hides a shared metric,
check whether that metric is reused by multiple surfaces before approving.
</code></pre></div></div>

<p>A good lesson has a trigger.</p>

<p>In a review loop, the agent should scan lesson headers first, not load every lesson body. If changed files hit a trigger, then load the full content. If not, skip it.</p>

<p>That preserves team memory without polluting the context window.</p>

<h2 id="10-gotchas-local-traps-belong-in-local-procedures">10. Gotchas: local traps belong in local procedures</h2>

<p>A gotcha is a small trap inside a specific procedure.</p>

<p>For example:</p>

<ul>
  <li>special rules for legacy field comparison</li>
  <li>workaround for a PR comment posting API</li>
  <li>historical compatibility behavior of a formatter</li>
  <li>boundary cases a certain test category must cover</li>
</ul>

<p>If only one skill uses a gotcha, put it inside that skill instead of the global prompt.</p>

<p>The rule is:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>If only one procedure needs it,
keep it inside that procedure.
</code></pre></div></div>

<p>That keeps the global prompt from becoming bloated.</p>

<h2 id="11-case-records-historical-cases-are-evidence-not-default-context">11. Case Records: historical cases are evidence, not default context</h2>

<p>A case record captures one specific historical run:</p>

<ul>
  <li>state</li>
  <li>validation logs</li>
  <li>subagent outputs</li>
  <li>review payload</li>
  <li>final decision</li>
  <li>postmortem notes</li>
</ul>

<p>Its value is audit, dispute review, and issue tracing.</p>

<p>But it should not become default context for every review.</p>

<p>For example, the last PR’s review report should not influence the next PR by default, unless the current task is explicitly resuming the same PR or directly references that historical case.</p>

<p><strong>Historical cases are evidence, not standing knowledge.</strong></p>

<h2 id="12-automated-checks-the-best-knowledge-eventually-becomes-code">12. Automated Checks: the best knowledge eventually becomes code</h2>

<p>The end state of knowledge management is not a longer prompt.</p>

<p>The best knowledge should eventually become executable checks:</p>

<ul>
  <li>shell check</li>
  <li>lint rule</li>
  <li>unit test</li>
  <li>integration test</li>
  <li>CI gate</li>
  <li>review script</li>
  <li>validation job</li>
</ul>

<p>A lesson is only a reminder:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Remember to check X.
</code></pre></div></div>

<p>A test is a guarantee:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>X cannot regress silently.
</code></pre></div></div>

<p>If the agent manually checks the same issue every time, that knowledge has not finished maturing. It should be upgraded into an automated check.</p>

<h2 id="13-the-lead-agent-is-not-a-summarizer-but-a-judge">13. The Lead Agent is not a summarizer, but a judge</h2>

<p>In a multi-agent review loop, subagents can expand coverage.</p>

<p>For example, one subagent can use an external review tool, another can use internal project review skills, and a third can focus on test coverage.</p>

<p>But the lead agent must not merely merge the results.</p>

<p>It must:</p>

<ul>
  <li>verify every reported issue</li>
  <li>require a runnable reproduction</li>
  <li>reject findings without evidence</li>
  <li>distinguish project-wide baseline failures from PR-specific regressions</li>
  <li>judge severity</li>
  <li>request confirmation before posting comments</li>
  <li>suggest knowledge updates after the review</li>
</ul>

<p>Subagents produce candidates.</p>

<p>The lead agent should produce evidence-backed findings.</p>

<p>This is critical. Otherwise, multi-agent review easily becomes “several agents producing noise together.”</p>

<h2 id="14-a-sustainable-knowledge-loop">14. A sustainable knowledge loop</h2>

<p>The real value of a Coding Agent workflow is not that it reviews one PR for you. It is that it can keep compounding knowledge.</p>

<p>The ideal loop looks like this:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>incident
  → distilled lesson
  → routed skill gotcha or review rule
  → automated check
  → less prose in the prompt
</code></pre></div></div>

<p>In practice:</p>

<ol>
  <li>An incident or review issue appears</li>
  <li>A human distills it into a lesson</li>
  <li>The lesson is placed into the right skill or rule</li>
  <li>If it repeats, it becomes an automated check</li>
  <li>The prompt becomes shorter because the judgment has been systematized</li>
</ol>

<p>That is the key to agent loop compounding.</p>

<p>Do not make the agent remember everything. Make it:</p>

<ul>
  <li>load the right knowledge at the right time</li>
  <li>judge from evidence</li>
  <li>convert repeated human experience into executable checks</li>
</ul>

<h2 id="15-my-take">15. My take</h2>

<p>Many AI Coding practices are still stuck at “give the agent more context.”</p>

<p>But from an engineering-system point of view, the real issue is not context size. It is context routing.</p>

<p>An agent should not feel like a junior engineer buried under documents. It should behave like an engineering system with process, indexes, and verification.</p>

<p>I increasingly think that high-quality coding agent workflows will compete on three things, not only model capability:</p>

<ul>
  <li>knowledge layering</li>
  <li>on-demand loading</li>
  <li>automated verification</li>
</ul>

<p>The model generates candidates. The workflow constrains the path. The verification mechanism proves the result.</p>

<p>Without these structures, a stronger agent may simply produce more uncertain output faster.</p>

<p>With these structures, an agent can move from a one-off tool to a compounding engineering system.</p>

<h2 id="16-summary">16. Summary</h2>

<p>The goal of knowledge management for Coding Agents is not to make them remember everything.</p>

<p>The goal is:</p>

<ul>
  <li>load the right knowledge at the right stage</li>
  <li>make every judgment evidence-backed</li>
  <li>gradually turn repeated experience into automated checks</li>
</ul>

<p>This is a key step from prompt engineering to agent system engineering.</p>

<p><strong>A mature agent workflow is not a very long prompt. It is a system that routes, verifies, and learns.</strong></p>]]></content><author><name>KL</name></author><category term="AI" /><category term="LLM" /><category term="agent" /><summary type="html"><![CDATA[In the Coding Agent era, the core of knowledge management is not “remember more.” It is “load on demand.” What matters is not context size, but context routing: load the right knowledge at the right stage, make every judgment evidence-backed, and gradually turn repeated experience into automated checks. This is a key step from prompt engineering to agent system engineering.]]></summary></entry><entry xml:lang="zh"><title type="html">Coding Agent 的知识管理：不是塞更多上下文，而是构建可复利的工作流</title><link href="https://kerryleung.github.io/blogs/2026/07/02/coding-agent-knowledge-routing/" rel="alternate" type="text/html" title="Coding Agent 的知识管理：不是塞更多上下文，而是构建可复利的工作流" /><published>2026-07-02T00:00:00+00:00</published><updated>2026-07-02T00:00:00+00:00</updated><id>https://kerryleung.github.io/blogs/2026/07/02/coding-agent-knowledge-routing</id><content type="html" xml:base="https://kerryleung.github.io/blogs/2026/07/02/coding-agent-knowledge-routing/"><![CDATA[<blockquote>
  <p>Coding Agent 时代，知识管理的核心不是“记住更多”，而是“按需加载”。真正重要的不是 context size，而是 context routing：让正确的知识，在正确的阶段，被正确加载；让每个判断都有证据；让重复经验逐步变成自动化检查。这也是从 prompt engineering 走向 agent system engineering 的关键一步。</p>
</blockquote>

<p>最近在思考一个问题：Coding Agent 的开发流程里，知识应该怎么管理？</p>

<p>很多团队在使用 agent 时，第一反应是给它更多上下文：更多文档、更多 memory、更多规则、更多历史案例。</p>

<p>但实际效果不一定更好。因为 agent 不是人。上下文给得越多，它不一定越聪明，反而可能出现几个问题：</p>

<ul>
  <li>读到过期信息</li>
  <li>被历史 case 误导</li>
  <li>在无关文档里浪费大量 token</li>
  <li>把“曾经发生过的问题”当成“当前一定存在的问题”</li>
  <li>最后输出一堆看似合理、但证据不足的 review comment</li>
</ul>

<p>所以，Coding Agent 的知识管理，不应该只按 topic 分类，比如“metrics 文档”“security 文档”“test 文档”。</p>

<p>更关键的是按 access pattern 管理：</p>

<ul>
  <li>什么时候加载这类知识？</li>
  <li>它支持 agent 做什么决策？</li>
  <li>如果不加载，会不会影响当前任务判断？</li>
</ul>

<p>换句话说，核心问题不是“我们知道什么”，而是“当前这个任务，需要加载什么知识来支持判断”。</p>

<h2 id="一核心模式index--route--body">一、核心模式：Index → Route → Body</h2>

<p>我比较认同的模式是：</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Index → Route → Body
</code></pre></div></div>

<p>也就是：先看索引，再做路由，最后只加载必要正文。</p>

<p>Agent 不应该一上来就把整个知识库读一遍。更合理的做法是：</p>

<ol>
  <li><strong>Index</strong>：默认只加载小型索引、摘要、触发条件。</li>
  <li><strong>Route</strong>：根据任务类型、变更文件、影响范围做分类。</li>
  <li><strong>Body</strong>：只有当路由命中时，才加载完整文档。</li>
</ol>

<p>以一个 <code class="language-plaintext highlighter-rouge">team-code-review</code> 这样的 review loop 为例，它可以先解析 PR，拿到 changed files，然后判断这次改动属于哪类：</p>

<ul>
  <li>domain model change</li>
  <li>metric change</li>
  <li>locale formatting change</li>
  <li>access control change</li>
  <li>test-only change</li>
  <li>CI/config change</li>
</ul>

<p>如果 PR 改的是 locale formatting 文件，就加载 locale spec。<br />
如果 PR 改的是 shared metric，就加载 shared metric 相关规则和历史 lesson。<br />
如果只是 test config 调整，就不需要加载 locale spec。</p>

<p>这个区别非常重要。</p>

<p>一个低质量 loop 是：“我把所有文档都塞给 agent，希望它自己判断。”</p>

<p>一个可持续进化的 loop 是：“我让 agent 先分类，再只加载当前判断所需的知识。”</p>

<p><strong>前者只是堆上下文，后者才是在构建一个可复用的工程系统。</strong></p>

<h2 id="二知识应该分层管理">二、知识应该分层管理</h2>

<p>在 Coding Agent workflow 里，我倾向于把知识分成几类。每一类知识都应该有自己的加载时机，而不是默认进入全局 prompt。</p>

<h2 id="三contracts--invariants什么绝对不能破坏">三、Contracts / Invariants：什么绝对不能破坏</h2>

<p>这是最重要、也应该最早加载的一层。</p>

<p>它回答的问题是：什么东西不能被破坏？</p>

<p>比如：</p>

<ul>
  <li>权限控制</li>
  <li>public field name</li>
  <li>API contract</li>
  <li>schema</li>
  <li>module boundary</li>
  <li>data ownership</li>
  <li>跨系统数据解释规则</li>
</ul>

<p>如果一个 PR 改了 access-control metadata，review loop 必须在 review 前加载 access-control contract。</p>

<p>因为这类问题一旦出错，影响通常不是局部 bug，而是系统边界被破坏。</p>

<p>但如果当前 PR 完全不涉及这些边界，就没有必要加载。</p>

<p><strong>不变量应该被早加载，但只在相关边界被触碰时加载。</strong></p>

<h2 id="四maps--indexes应该去哪里找信息">四、Maps / Indexes：应该去哪里找信息</h2>

<p>Map 的作用不是解释所有细节，而是帮助 agent 路由。</p>

<p>好的 map 应该足够小，能被快速扫描。</p>

<p>比如：</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>如果 shared_metrics/ 目录下的文件发生变化，
加载 shared metric rule，
并执行 metric validation path。
</code></pre></div></div>

<p>这比下面这种写法好很多：</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>这里是我们关于 metrics 的全部知识。
</code></pre></div></div>

<p>前者是可执行的路由规则。后者只是信息堆积。</p>

<p><strong>Map 不是知识正文，Map 是让 agent 少读错文档的路由表。</strong></p>

<h2 id="五specs什么才是正确行为">五、Specs：什么才是正确行为</h2>

<p>Spec 是 correctness oracle。</p>

<p>当一个 PR 声称修改了某个行为，agent 不应该凭记忆判断这个行为是否正确，而应该加载对应 spec。</p>

<p>比如 PR 改了 date formatting 行为，review loop 应该加载 formatting spec，然后检查：</p>

<ul>
  <li>新格式是否符合 spec</li>
  <li>所有受影响 surface 是否都覆盖</li>
  <li>测试是否证明输出变化符合预期</li>
</ul>

<p>如果 spec 里没有定义预期行为，agent 不应该自己编一个标准。</p>

<p>更合理的 finding 是：</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>当前 expected behavior 没有被定义，建议补充 spec。
</code></pre></div></div>

<p>这比“凭经验判断对错”更工程化。</p>

<h2 id="六procedures--skills这个任务应该怎么做">六、Procedures / Skills：这个任务应该怎么做</h2>

<p>Procedure 回答的是：在这个项目里，这类任务应该怎么执行？</p>

<p>比如 code review 主命令不应该包含所有 review checklist。它更适合负责 orchestration。</p>

<p>具体 checklist 可以拆到不同 skill：</p>

<ul>
  <li>domain field review skill</li>
  <li>formatting review skill</li>
  <li>security/access review skill</li>
  <li>test adequacy review skill</li>
  <li>PR comment posting skill</li>
</ul>

<p>这样主流程保持轻量，具体领域的 gotchas 也可以放在对应 skill 里。</p>

<p><strong>主流程管编排，skill 管过程细节。</strong></p>

<p>这其实也是 agent workflow 可维护性的关键。</p>

<h2 id="七adrs为什么这里是这样设计的">七、ADRs：为什么这里是这样设计的</h2>

<p>ADR 的价值在于避免 agent “修复”一个 intentional design。</p>

<p>很多时候，agent 看到复杂代码，会本能地想简化。这有时是对的，但有时这个复杂度是历史兼容、跨系统契约、性能约束或迁移策略下的有意选择。</p>

<p>所以当 PR 触碰这些内容时，应该触发 ADR：</p>

<ul>
  <li>established module boundary</li>
  <li>long-lived naming convention</li>
  <li>cross-system contract</li>
  <li>known tradeoff</li>
  <li>compatibility decision</li>
</ul>

<p>ADR 不应该每次都加载。它应该通过索引命中，在相关区域发生变化时再加载。</p>

<p>否则 agent 很容易在无关场景里被历史设计讨论干扰。</p>

<h2 id="八plans临时计划不应该永久化">八、Plans：临时计划，不应该永久化</h2>

<p>Plan 很有用，但它是临时脚手架。</p>

<p>它适合用在：</p>

<ul>
  <li>stacked PR</li>
  <li>phased migration</li>
  <li>active refactoring</li>
  <li>多阶段上线</li>
</ul>

<p>但 plan 不应该长期留在默认上下文里。</p>

<p>一旦工作完成，里面的 durable knowledge 应该沉淀到不同地方：</p>

<ul>
  <li>稳定行为 → spec</li>
  <li>设计原因 → ADR</li>
  <li>反复踩坑 → lesson / gotcha</li>
  <li>可自动验证的问题 → test / CI check</li>
</ul>

<p>一个简单原则是：</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Plans expire.
Specs and ADRs survive.
</code></pre></div></div>

<p><strong>Plan 是脚手架，不是建筑本身。</strong></p>

<h2 id="九lessons--rules只有可触发才有价值">九、Lessons / Rules：只有可触发，才有价值</h2>

<p>Lesson 最常见的问题是太泛。</p>

<p>不好的 lesson：</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Be careful with metrics.
</code></pre></div></div>

<p>好的 lesson：</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>When a PR hides a shared metric,
check whether that metric is reused by multiple surfaces before approving.
</code></pre></div></div>

<p>好的 lesson 一定有 trigger。</p>

<p>在 review loop 里，agent 应该先扫描 lesson header，而不是加载所有 lesson body。如果 changed files 命中了 trigger，再加载完整内容。如果没命中，就跳过。</p>

<p>这样既保留了团队记忆，又不会污染上下文窗口。</p>

<h2 id="十gotchas局部陷阱放在局部流程里">十、Gotchas：局部陷阱放在局部流程里</h2>

<p>Gotcha 是某个 procedure 内部的小陷阱。</p>

<p>比如：</p>

<ul>
  <li>legacy field comparison 的特殊规则</li>
  <li>PR comment posting API 的 workaround</li>
  <li>某个 formatter 的历史兼容行为</li>
  <li>某类测试 case 必须覆盖的边界条件</li>
</ul>

<p>如果一个 gotcha 只在某个 skill 中使用，就应该放在这个 skill 里，而不是放到全局 prompt。</p>

<p>原则是：</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>If only one procedure needs it,
keep it inside that procedure.
</code></pre></div></div>

<p>这样可以避免全局 prompt 越来越臃肿。</p>

<h2 id="十一case-records历史案例是证据不是默认上下文">十一、Case Records：历史案例是证据，不是默认上下文</h2>

<p>Case record 记录的是一次具体历史运行：</p>

<ul>
  <li>state</li>
  <li>validation logs</li>
  <li>subagent outputs</li>
  <li>review payload</li>
  <li>final decision</li>
  <li>postmortem notes</li>
</ul>

<p>它的价值在于审计、争议复盘、问题追踪。</p>

<p>但它不应该成为每次 review 默认加载的上下文。</p>

<p>比如上一次 PR 的 review report，不应该默认影响下一次 PR。除非当前任务明确是在 resume 同一个 PR，或者当前问题直接引用了那个历史 case。</p>

<p><strong>历史案例是 evidence，不是 standing knowledge。</strong></p>

<h2 id="十二automated-checks最好的知识最终应该变成代码">十二、Automated Checks：最好的知识最终应该变成代码</h2>

<p>知识管理的终点，不是让 prompt 越写越长。</p>

<p>真正好的知识，最后应该沉淀成可执行检查：</p>

<ul>
  <li>shell check</li>
  <li>lint rule</li>
  <li>unit test</li>
  <li>integration test</li>
  <li>CI gate</li>
  <li>review script</li>
  <li>validation job</li>
</ul>

<p>Lesson 只是提醒：</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Remember to check X.
</code></pre></div></div>

<p>Test 才是保障：</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>X cannot regress silently.
</code></pre></div></div>

<p>如果 agent 每次都在人工检查同一个问题，那说明这个知识还没有沉淀完成。它应该被升级成自动化检查。</p>

<h2 id="十三lead-agent-的角色不是汇总而是裁判">十三、Lead Agent 的角色：不是汇总，而是裁判</h2>

<p>在 multi-agent review loop 里，subagents 可以扩大覆盖面。</p>

<p>比如一个 subagent 使用外部 review 工具，另一个 subagent 使用项目内部 review skill，第三个 subagent 专门看测试覆盖。</p>

<p>但最终 lead agent 不能只是合并结果。</p>

<p>它必须负责：</p>

<ul>
  <li>验证每一个 reported issue</li>
  <li>要求可运行的 reproduction</li>
  <li>拒绝没有证据的 finding</li>
  <li>区分 project-wide baseline failure 和 PR-specific regression</li>
  <li>判断 severity</li>
  <li>在发 comment 前请求确认</li>
  <li>review 结束后提出知识更新建议</li>
</ul>

<p>Subagent 生成的是 candidates。</p>

<p>Lead agent 产出的应该是 evidence-backed findings。</p>

<p>这点非常关键。否则 multi-agent review 很容易变成“多个 agent 一起制造噪音”。</p>

<h2 id="十四一个可持续进化的知识闭环">十四、一个可持续进化的知识闭环</h2>

<p>我认为 Coding Agent workflow 真正有价值的地方，不是一次性帮你 review 一个 PR，而是它可以把知识持续沉淀下来。</p>

<p>比较理想的闭环是：</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>incident
  → distilled lesson
  → routed skill gotcha or review rule
  → automated check
  → less prose in the prompt
</code></pre></div></div>

<p>也就是：</p>

<ol>
  <li>线上问题或 review 问题暴露出来</li>
  <li>人把它提炼成 lesson</li>
  <li>lesson 被放到正确的 skill 或 rule 里</li>
  <li>如果反复出现，就升级成自动化检查</li>
  <li>最后 prompt 反而变短，因为判断被系统化了</li>
</ol>

<p>这才是 agent loop compound 的关键。</p>

<p>不是让 agent 记住所有东西，而是让它：</p>

<ul>
  <li>在正确时间加载正确知识</li>
  <li>基于证据做判断</li>
  <li>把重复的人类经验转化为可执行检查</li>
</ul>

<h2 id="十五我的思考">十五、我的思考</h2>

<p>现在很多 AI Coding 实践还停留在“给 agent 更多上下文”的阶段。</p>

<p>但从工程系统角度看，真正重要的不是 context size，而是 context routing。</p>

<p>Agent 不应该像一个被塞满文档的新人。它更应该像一个有流程、有索引、有验证机制的工程系统。</p>

<p>我越来越觉得，未来高质量的 coding agent workflow，核心竞争力不只是模型能力，而是三件事：</p>

<ul>
  <li>知识分层</li>
  <li>按需加载</li>
  <li>自动验证</li>
</ul>

<p>模型负责生成候选方案。Workflow 负责约束路径。验证机制负责证明结果。</p>

<p>如果没有这些结构，agent 越强，可能只是更快地产生更多不确定输出。</p>

<p>如果有这些结构，agent 才能从一次性工具，变成可以持续复利的工程系统。</p>

<h2 id="十六总结">十六、总结</h2>

<p>Coding Agent 的知识管理，目标不是让它记住一切。</p>

<p>目标是：</p>

<ul>
  <li>让正确的知识，在正确的阶段，被正确加载</li>
  <li>让每个判断都有证据</li>
  <li>让重复经验逐步变成自动化检查</li>
</ul>

<p>这也是从 prompt engineering 走向 agent system engineering 的关键一步。</p>

<p><strong>真正成熟的 agent workflow，不是一个很长的 prompt，而是一个会路由、会验证、会沉淀的系统。</strong></p>]]></content><author><name>KL</name></author><category term="AI" /><category term="LLM" /><category term="agent" /><summary type="html"><![CDATA[Coding Agent 时代，知识管理的核心不是“记住更多”，而是“按需加载”。真正重要的不是 context size，而是 context routing：让正确的知识，在正确的阶段，被正确加载；让每个判断都有证据；让重复经验逐步变成自动化检查。这也是从 prompt engineering 走向 agent system engineering 的关键一步。]]></summary></entry><entry xml:lang="en"><title type="html">A 149K-Star AI Coding Gem: Skills</title><link href="https://kerryleung.github.io/blogs/2026/06/28/ai-coding-skills-workflow-en/" rel="alternate" type="text/html" title="A 149K-Star AI Coding Gem: Skills" /><published>2026-06-28T00:00:00+00:00</published><updated>2026-06-28T00:00:00+00:00</updated><id>https://kerryleung.github.io/blogs/2026/06/28/ai-coding-skills-workflow-en</id><content type="html" xml:base="https://kerryleung.github.io/blogs/2026/06/28/ai-coding-skills-workflow-en/"><![CDATA[<blockquote>
  <p>I recently came across an interesting open-source project: <a href="https://github.com/mattpocock/skills">Skills</a>. As of 2026-06-28, the GitHub API showed 149,182 stars. Its author, Matt Pocock, is well known in the frontend and TypeScript world. But what interests me most about this repo is not a specific prompt. It is that the repo turns strong engineering workflows into reusable Agent Skills.</p>
</blockquote>

<p>Today I want to focus on one Skill that I think is especially worth studying: <a href="https://github.com/mattpocock/skills/blob/main/skills/engineering/improve-codebase-architecture/SKILL.md">improve-codebase-architecture</a>.</p>

<h2 id="1-what-this-skill-does">1. What this Skill does</h2>

<p>In short, it asks an agent to run an architecture diagnosis over a codebase.</p>

<p>It does not simply tell the model, “give me some refactoring ideas.” Instead, it defines a concrete process:</p>

<ul>
  <li>Read <code class="language-plaintext highlighter-rouge">CONTEXT.md</code> and ADRs to understand domain language and existing decisions</li>
  <li>Use a fixed architecture vocabulary: module, interface, depth, seam, adapter, locality, and leverage</li>
  <li>Look for high comprehension cost, shallow modules, leaking coupling, and hard-to-test areas</li>
  <li>Render candidates into an HTML report</li>
  <li>For every candidate, include files, problem, solution, benefits, before/after diagrams, and recommendation strength</li>
  <li>After the user picks one candidate, enter a grilling loop to clarify the design</li>
</ul>

<p>The value is that it does not hand “architecture review” to one free-form reasoning pass. It breaks the review into steps that can be repeated.</p>

<h2 id="2-why-it-is-representative">2. Why it is representative</h2>

<p>I think this Skill points to an important direction in AI Coding:</p>

<p><strong>A good Agent Skill is not really Prompt Engineering. It is Workflow Engineering.</strong></p>

<p>A rough prompt might look like this:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Please analyze this project's architecture and suggest refactors.
</code></pre></div></div>

<p>A more mature workflow defines the sequence:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Collect Context
    ↓
Understand Domain Language
    ↓
Inspect Architecture Friction
    ↓
Generate Candidates
    ↓
Visualize Tradeoffs
    ↓
Grill One Decision
    ↓
Record Context / ADR
</code></pre></div></div>

<p>The first relies on the model improvising. The second encodes the order, checkpoints, and decision constraints of an experienced engineer.</p>

<p>That is why I find it more valuable than “a good architecture-analysis prompt.”</p>

<h2 id="3-clear-goals-reduce-agent-drift">3. Clear goals reduce agent drift</h2>

<p>Many agent failures are not caused by weak model capability. They come from fuzzy goals.</p>

<p><code class="language-plaintext highlighter-rouge">improve-codebase-architecture</code> has a very specific target: scan a codebase for deepening opportunities, output a readable visual HTML report, then let the user choose one candidate for deeper discussion.</p>

<p>Two constraints matter:</p>

<ol>
  <li><strong>Only propose candidates first. Do not change code immediately.</strong></li>
  <li><strong>Only after the user chooses one does the design interview begin.</strong></li>
</ol>

<p>That keeps the agent from sliding from “discover problems” into “refactor a bunch of files.” Architecture work is especially vulnerable to this kind of scope drift: the problem has not been aligned, but the solution is already being implemented.</p>

<h2 id="4-context-determines-output-quality">4. Context determines output quality</h2>

<p>This Skill starts by reading <code class="language-plaintext highlighter-rouge">CONTEXT.md</code> and ADRs. That detail matters.</p>

<p>Code tells the agent what the system currently looks like, but many key decisions do not live in code:</p>

<ul>
  <li>Why are the module boundaries shaped this way?</li>
  <li>Why was this technical approach chosen?</li>
  <li>Why was another approach rejected?</li>
  <li>Which tradeoffs were accepted intentionally?</li>
</ul>

<p>If that knowledge only lives in people’s heads, agents will repeatedly suggest ideas that have already been rejected.</p>

<p>So I increasingly believe this:</p>

<p><strong>An agent’s ceiling is largely determined by the quality of its context.</strong></p>

<p>More context is not automatically better. The context needs to be complete, accurate, and structured. <code class="language-plaintext highlighter-rouge">CONTEXT.md</code> captures domain language. ADRs capture historical decisions. Together, they give the agent a more realistic engineering environment.</p>

<h2 id="5-decisions-need-review">5. Decisions need review</h2>

<p>The most interesting part of this Skill is that the architecture report is not the end.</p>

<p>After the report is generated, the user chooses a candidate and the agent enters <code class="language-plaintext highlighter-rouge">/grilling</code>: it walks through constraints, dependencies, the shape of the module, what should sit behind the seam, and which tests should survive.</p>

<p>That is very close to how we make important design decisions in real engineering work:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Propose a solution
   ↓
Put it under pressure
   ↓
Expose hidden assumptions
   ↓
Adjust boundaries and tradeoffs
   ↓
Only then make a decision
</code></pre></div></div>

<p>Code review matters. Agent decision review matters too. A single reasoning pass can easily confuse “sounds reasonable” with “actually fits this system.” A grilling or critique loop forces the agent to surface assumptions and inspect them one by one.</p>

<h2 id="6-results-must-be-verifiable">6. Results must be verifiable</h2>

<p>If a Skill only emits advice, its value is limited.</p>

<p><code class="language-plaintext highlighter-rouge">improve-codebase-architecture</code> requires an HTML report, and each candidate must include concrete files, problem, solution, benefits, and before/after diagrams. That makes the output inspectable:</p>

<ul>
  <li>Does this problem really exist?</li>
  <li>Are the files accurate?</li>
  <li>Does the solution solve the problem, or just rename it?</li>
  <li>Is the benefit large enough?</li>
  <li>Is there a simpler option?</li>
</ul>

<p>I would pair this kind of architecture analysis with <code class="language-plaintext highlighter-rouge">/grilling</code> and ADRs to form a complete loop:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Generate report
   ↓
Choose candidate
   ↓
Grill the decision
   ↓
Refine the proposal
   ↓
Record ADR / update domain context
</code></pre></div></div>

<p>The next time an agent enters the repo, it does not have to rediscover the same history.</p>

<h2 id="7-practical-suggestions-you-can-use-immediately">7. Practical suggestions you can use immediately</h2>

<p>If you are exploring AI Coding, I would not only run the Skill. I would study it as a workflow design example.</p>

<p><strong>1. Write an entry goal for complex tasks.</strong></p>

<p>Do not just write “help me refactor this.” A better goal is: “only scan and produce candidate architecture issues; do not edit code; every candidate must include files, problem, solution, risk, and recommendation strength.”</p>

<p><strong>2. Prepare a <code class="language-plaintext highlighter-rouge">CONTEXT.md</code> for the project.</strong></p>

<p>Write down the core domain concepts. Make it clear which words are business concepts and which are merely implementation details.</p>

<p><strong>3. Keep writing ADRs.</strong></p>

<p>For every important architecture choice, record why you chose it, why you rejected the alternatives, and which tradeoffs you knowingly accepted. ADRs are not only for past readers. They give future humans and agents decision context.</p>

<p><strong>4. Run a grilling loop for important proposals.</strong></p>

<p>Ask the agent to do more than produce an answer. Make it accept pressure: what did it miss, which assumptions lack evidence, is the benefit large enough, and is there a simpler solution?</p>

<p><strong>5. Turn outputs into inspectable artifacts.</strong></p>

<p>Reports, tables, diffs, ADRs, and issue lists are easier to review and collaborate on than a free-form block of prose.</p>

<h2 id="8-a-few-other-skills-worth-reading">8. A few other Skills worth reading</h2>

<p>Besides <code class="language-plaintext highlighter-rouge">improve-codebase-architecture</code>, I would also look at these related Skills in the repo:</p>

<ul>
  <li><a href="https://github.com/mattpocock/skills/blob/main/skills/engineering/grill-with-docs/SKILL.md"><code class="language-plaintext highlighter-rouge">grill-with-docs</code></a>: grill a proposal while also building domain language and ADRs.</li>
  <li><a href="https://github.com/mattpocock/skills/blob/main/skills/engineering/to-prd/SKILL.md"><code class="language-plaintext highlighter-rouge">to-prd</code></a>: turn the current discussion into a PRD.</li>
  <li><a href="https://github.com/mattpocock/skills/blob/main/skills/engineering/to-issues/SKILL.md"><code class="language-plaintext highlighter-rouge">to-issues</code></a>: break a plan into independently executable issues.</li>
  <li><a href="https://github.com/mattpocock/skills/blob/main/skills/engineering/tdd/SKILL.md"><code class="language-plaintext highlighter-rouge">tdd</code></a>: turn the red-green-refactor loop into an agent workflow.</li>
</ul>

<p>Together, these Skills show the same direction: make agents less like better chatbots, and more like reliable executors of engineering workflows.</p>

<h2 id="9-my-take">9. My take</h2>

<p>I increasingly feel that the dividing line in AI Coding is not only model capability. It is whether you can design strong workflows.</p>

<p>We used to keep a lot of engineering judgment in our heads: clarify the requirement first, inspect the architecture with context, review important decisions, verify before refactoring, and write down historical tradeoffs in ADRs.</p>

<p>Now these practices can be encoded as Skills.</p>

<p>In other words:</p>

<p><strong>The thing worth saving is not the prompt. It is the workflow.</strong></p>

<p>The future difference between engineers may not be only who writes code faster. It may be who can package good engineering practice into repeatable, composable, reviewable workflows.</p>

<h2 id="10-summary">10. Summary</h2>

<p>The valuable part of <code class="language-plaintext highlighter-rouge">improve-codebase-architecture</code> is not only that it can generate an architecture report. It is that it simulates the full architecture-review process of a senior engineer:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Read context
   ↓
Use shared language to find architecture friction
   ↓
Produce an inspectable report
   ↓
Choose one candidate
   ↓
Question and refine the design
   ↓
Preserve the decision as long-term context
</code></pre></div></div>

<p>If you are exploring AI Coding, I recommend reading the implementation of this Skill, not just running it. The truly valuable part is hidden in the workflow design.</p>

<p>Source repo: <a href="https://github.com/mattpocock/skills">mattpocock/skills</a><br />
Recommended reading: <a href="https://github.com/mattpocock/skills/blob/main/skills/engineering/improve-codebase-architecture/SKILL.md">improve-codebase-architecture/SKILL.md</a></p>]]></content><author><name>KL</name></author><category term="AI" /><category term="LLM" /><category term="agent" /><category term="open_source" /><summary type="html"><![CDATA[I recently came across an interesting open-source project: Skills. As of 2026-06-28, the GitHub API showed 149,182 stars. Its author, Matt Pocock, is well known in the frontend and TypeScript world. But what interests me most about this repo is not a specific prompt. It is that the repo turns strong engineering workflows into reusable Agent Skills.]]></summary></entry><entry xml:lang="zh"><title type="html">推荐一个 149K Star 的 AI Coding 宝藏仓库：Skills</title><link href="https://kerryleung.github.io/blogs/2026/06/28/ai-coding-skills-workflow/" rel="alternate" type="text/html" title="推荐一个 149K Star 的 AI Coding 宝藏仓库：Skills" /><published>2026-06-28T00:00:00+00:00</published><updated>2026-06-28T00:00:00+00:00</updated><id>https://kerryleung.github.io/blogs/2026/06/28/ai-coding-skills-workflow</id><content type="html" xml:base="https://kerryleung.github.io/blogs/2026/06/28/ai-coding-skills-workflow/"><![CDATA[<blockquote>
  <p>最近看到一个很有意思的开源项目：<a href="https://github.com/mattpocock/skills">Skills</a>。截至 2026-06-28，我通过 GitHub API 查到它已经有 149,182 stars。作者 Matt Pocock 在前端和 TypeScript 圈很有影响力，但这个仓库让我更感兴趣的地方，不是某个具体 prompt，而是它把优秀工程师的工作流程沉淀成了一套套可复用的 Agent Skill。</p>
</blockquote>

<p>今天重点推荐其中一个我觉得很值得学习的 Skill：<a href="https://github.com/mattpocock/skills/blob/main/skills/engineering/improve-codebase-architecture/SKILL.md">improve-codebase-architecture</a>。</p>

<h2 id="一这个-skill-是做什么的">一、这个 Skill 是做什么的</h2>

<p>简单说，它会让 Agent 对一个代码仓库做一次架构诊断。</p>

<p>它不是上来就让模型“给我一些重构建议”，而是先规定了明确流程：</p>

<ul>
  <li>读取项目里的 <code class="language-plaintext highlighter-rouge">CONTEXT.md</code> 和 ADR，理解已有领域语言和历史决策</li>
  <li>用一套固定架构词汇分析模块、接口、深度、接缝、适配器、局部性和杠杆</li>
  <li>找出理解成本高、模块过浅、耦合泄漏、测试困难的地方</li>
  <li>把候选问题渲染成一份 HTML 报告</li>
  <li>每个候选项都要包含涉及文件、问题、方案、收益、before/after 图和推荐强度</li>
  <li>用户选中一个候选项后，再进入 grilling loop，把设计树继续问清楚</li>
</ul>

<p>这个流程的价值在于：它没有把“架构评审”交给一次自由发挥的推理，而是把评审拆成了可以重复执行的步骤。</p>

<h2 id="二为什么它有代表性">二、为什么它有代表性</h2>

<p>我觉得这个 Skill 代表了 AI Coding 里一个很重要的方向：</p>

<p><strong>优秀的 Agent Skill，本质上不是 Prompt Engineering，而是 Workflow Engineering。</strong></p>

<p>一个粗糙的 prompt 可能是：</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>请帮我分析这个项目的架构，并给出重构建议。
</code></pre></div></div>

<p>而一个更成熟的 workflow 会规定：</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Collect Context
    ↓
Understand Domain Language
    ↓
Inspect Architecture Friction
    ↓
Generate Candidates
    ↓
Visualize Tradeoffs
    ↓
Grill One Decision
    ↓
Record Context / ADR
</code></pre></div></div>

<p>前者依赖模型临场发挥，后者把资深工程师的工作顺序、检查点和决策约束都写进了流程。</p>

<p>这也是为什么我觉得它比“一个好用的架构分析 prompt”更值得学习。</p>

<h2 id="三目标清晰agent-才不容易漂移">三、目标清晰，Agent 才不容易漂移</h2>

<p>很多 Agent 失败，并不是模型能力不够，而是目标定义过于模糊。</p>

<p><code class="language-plaintext highlighter-rouge">improve-codebase-architecture</code> 的目标很具体：扫描代码库里的 deepening opportunities，输出一份可读的可视化 HTML 报告，然后让用户选择一个候选项继续深入。</p>

<p>注意这里有两个关键约束：</p>

<ol>
  <li><strong>先只提出候选，不直接改代码。</strong></li>
  <li><strong>用户选择后，才进入下一轮设计追问。</strong></li>
</ol>

<p>这让 Agent 不会从“发现问题”一路滑到“顺手重构一堆文件”。架构工作最怕这种边界漂移：问题还没对齐，方案已经开始落地。</p>

<h2 id="四上下文决定输出质量">四、上下文决定输出质量</h2>

<p>这个 Skill 开始前会读 <code class="language-plaintext highlighter-rouge">CONTEXT.md</code> 和 ADR。这个细节很关键。</p>

<p>代码只能告诉 Agent 当前系统“长什么样”，但很多关键决策并不在代码里：</p>

<ul>
  <li>为什么模块边界这样划分？</li>
  <li>为什么选择这个技术方案？</li>
  <li>为什么放弃另一个方案？</li>
  <li>哪些 tradeoff 是当时有意接受的？</li>
</ul>

<p>这些信息如果只存在人的脑子里，Agent 很容易反复给出已经被否定过的建议。</p>

<p>所以我越来越认同一点：</p>

<p><strong>Agent 的能力上限，很大程度上取决于上下文质量。</strong></p>

<p>上下文不是越多越好，而是要完整、准确、结构化。<code class="language-plaintext highlighter-rouge">CONTEXT.md</code> 负责领域语言，ADR 负责历史决策，它们共同给 Agent 一个更接近真实工程现场的判断环境。</p>

<h2 id="五决策一定需要评审">五、决策一定需要评审</h2>

<p>这个 Skill 最有意思的地方，是它没有把架构报告当成终点。</p>

<p>报告生成后，它会让用户选择一个候选项，然后进入 <code class="language-plaintext highlighter-rouge">/grilling</code>：围绕约束、依赖、模块形状、接缝后面应该藏什么、哪些测试应该保留，继续一层层追问。</p>

<p>这其实很接近我们日常做重要设计时的过程：</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>先提出方案
   ↓
再被严格追问
   ↓
暴露隐藏假设
   ↓
修正边界和取舍
   ↓
最后才形成决策
</code></pre></div></div>

<p>代码评审重要，Agent 的决策评审同样重要。单次推理很容易把“看起来合理”误当成“真的适合当前系统”。通过 grilling 或类似的 critique loop，可以让 Agent 把自己的假设摊开，再逐个检查。</p>

<h2 id="六结果必须可验证">六、结果必须可验证</h2>

<p>如果一个 Skill 只输出一段建议，它的价值其实有限。</p>

<p><code class="language-plaintext highlighter-rouge">improve-codebase-architecture</code> 强制输出 HTML 报告，并要求每个候选项都包含具体文件、问题、方案、收益和 before/after diagram。这让结果至少可以被人检查：</p>

<ul>
  <li>这个问题是否真的存在？</li>
  <li>涉及文件是否准确？</li>
  <li>方案有没有解决问题，还是只是在换名字？</li>
  <li>收益是否足够大？</li>
  <li>是否存在更简单的做法？</li>
</ul>

<p>我会建议把这类架构分析和 <code class="language-plaintext highlighter-rouge">/grilling</code>、ADR 一起使用，形成一个完整闭环：</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>生成报告
   ↓
选择候选项
   ↓
严格追问
   ↓
修正方案
   ↓
记录 ADR / 更新领域上下文
</code></pre></div></div>

<p>这样下一次 Agent 再进入这个仓库时，它不需要重新猜一遍历史背景。</p>

<h2 id="七几个拿来就能用的实践建议">七、几个拿来就能用的实践建议</h2>

<p>如果你也在探索 AI Coding，我建议不只是运行这个仓库里的 Skill，而是把它当成 workflow 设计样本来学。</p>

<p><strong>1. 给复杂任务写入口目标。</strong></p>

<p>不要只写“帮我重构一下”。更好的目标是：“只扫描并产出候选架构问题，不改代码；每个候选项必须包含文件、问题、方案、风险和推荐强度。”</p>

<p><strong>2. 为项目准备一个 <code class="language-plaintext highlighter-rouge">CONTEXT.md</code>。</strong></p>

<p>把领域里的核心概念写进去。哪些词是业务概念，哪些词只是代码实现细节，要让 Agent 分得清。</p>

<p><strong>3. 坚持写 ADR。</strong></p>

<p>只要做了重要架构选择，就记录：为什么选它、为什么不选别的、已知 tradeoff 是什么。ADR 不是给过去的人看的，是给未来的人类和 Agent 提供决策上下文。</p>

<p><strong>4. 重要方案都跑一轮 grilling。</strong></p>

<p>让 Agent 不只是给答案，还要接受追问：遗漏了什么？哪些假设没有证据？收益是否足够大？有没有更简单方案？</p>

<p><strong>5. 把输出改成可检查的 artifact。</strong></p>

<p>报告、表格、diff、ADR、issue 列表，都比一段自由文本更适合复盘和协作。</p>

<h2 id="八另外几个值得看的-skill">八、另外几个值得看的 Skill</h2>

<p>除了 <code class="language-plaintext highlighter-rouge">improve-codebase-architecture</code>，我也建议顺手看一下这个仓库里的几个相关 Skill：</p>

<ul>
  <li><a href="https://github.com/mattpocock/skills/blob/main/skills/engineering/grill-with-docs/SKILL.md"><code class="language-plaintext highlighter-rouge">grill-with-docs</code></a>：在追问方案的同时沉淀领域语言和 ADR。</li>
  <li><a href="https://github.com/mattpocock/skills/blob/main/skills/engineering/to-prd/SKILL.md"><code class="language-plaintext highlighter-rouge">to-prd</code></a>：把当前讨论整理成 PRD。</li>
  <li><a href="https://github.com/mattpocock/skills/blob/main/skills/engineering/to-issues/SKILL.md"><code class="language-plaintext highlighter-rouge">to-issues</code></a>：把计划拆成可以独立执行的 issues。</li>
  <li><a href="https://github.com/mattpocock/skills/blob/main/skills/engineering/tdd/SKILL.md"><code class="language-plaintext highlighter-rouge">tdd</code></a>：把红绿重构循环固化成 Agent 工作方式。</li>
</ul>

<p>这些 Skill 共同体现了同一个方向：不是让 Agent “更会聊天”，而是让 Agent 更稳定地执行工程流程。</p>

<h2 id="九我的思考">九、我的思考</h2>

<p>最近越来越感觉，AI Coding 的分水岭不只是模型能力，而是你能不能设计出好的工作流。</p>

<p>过去我们把很多工程经验放在脑子里：需求要先问清楚、架构要先看上下文、重要决策要被 review、重构前要有验证、历史取舍要写 ADR。</p>

<p>现在这些经验可以被写成 Skill。</p>

<p>换句话说：</p>

<p><strong>真正值得沉淀的不是 Prompt，而是 Workflow。</strong></p>

<p>未来工程师之间的差异，可能不只是“谁写代码更快”，而是谁更会把优秀工程实践封装成可重复、可组合、可审查的工作流。</p>

<h2 id="十总结">十、总结</h2>

<p><code class="language-plaintext highlighter-rouge">improve-codebase-architecture</code> 值得学习的地方，不只是它能帮你生成一份架构诊断报告，而是它模拟了一位资深工程师完成架构评审的完整过程：</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>读上下文
   ↓
用统一语言识别架构摩擦
   ↓
产出可检查报告
   ↓
选择候选方案
   ↓
继续追问和修正
   ↓
沉淀为长期上下文
</code></pre></div></div>

<p>如果你正在探索 AI Coding，我会推荐认真阅读这个 Skill 的实现过程，而不只是直接运行它。因为真正有价值的部分，藏在 workflow 设计里。</p>

<p>原仓库：<a href="https://github.com/mattpocock/skills">mattpocock/skills</a><br />
推荐阅读：<a href="https://github.com/mattpocock/skills/blob/main/skills/engineering/improve-codebase-architecture/SKILL.md">improve-codebase-architecture/SKILL.md</a></p>]]></content><author><name>KL</name></author><category term="AI" /><category term="LLM" /><category term="agent" /><category term="open_source" /><summary type="html"><![CDATA[最近看到一个很有意思的开源项目：Skills。截至 2026-06-28，我通过 GitHub API 查到它已经有 149,182 stars。作者 Matt Pocock 在前端和 TypeScript 圈很有影响力，但这个仓库让我更感兴趣的地方，不是某个具体 prompt，而是它把优秀工程师的工作流程沉淀成了一套套可复用的 Agent Skill。]]></summary></entry><entry xml:lang="en"><title type="html">A New Agent-Harness Practice: Claude Code Dynamic Workflows</title><link href="https://kerryleung.github.io/blogs/2026/06/22/claude-dynamic-workflows-en/" rel="alternate" type="text/html" title="A New Agent-Harness Practice: Claude Code Dynamic Workflows" /><published>2026-06-22T00:00:00+00:00</published><updated>2026-06-22T00:00:00+00:00</updated><id>https://kerryleung.github.io/blogs/2026/06/22/claude-dynamic-workflows-en</id><content type="html" xml:base="https://kerryleung.github.io/blogs/2026/06/22/claude-dynamic-workflows-en/"><![CDATA[<blockquote>
  <p>Anthropic recently shipped Claude Code Dynamic Workflows: instead of a single agent working in one context, Claude Code can write a bespoke harness for the task at hand — a JavaScript workflow that orchestrates multiple subagents. After reading the post and trying it, my main takeaway is this: the things we used to write into prompts (“please check carefully”, “don’t skip the tests”) are turning into structured execution flows. This is a feature walkthrough plus my own thoughts. Source: <a href="https://claude.com/blog/a-harness-for-every-task-dynamic-workflows-in-claude-code">A harness for every task: Dynamic Workflows in Claude Code</a>.</p>
</blockquote>

<h2 id="1-what-dynamic-workflows-are">1. What Dynamic Workflows are</h2>

<p>In one line: <strong>Claude Code can write its own harness on the fly, custom-built for the task.</strong> It runs a JavaScript workflow whose special functions spawn and coordinate subagents, rather than cramming everything into a single context window.</p>

<p>Those subagents can have their own context windows and focused, isolated goals; you can decide which model each one uses, and even whether each runs in its own worktree. The workflow is plain JavaScript (JSON, Math, Array, and so on) and supports resuming after an interruption.</p>

<p>The post lists six core orchestration patterns:</p>

<ul>
  <li><strong>Classify-and-act</strong>: route tasks to different agents based on a classification.</li>
  <li><strong>Fan-out-and-synthesize</strong>: split a task into many smaller steps, run an agent on each, then synthesize the results.</li>
  <li><strong>Adversarial verification</strong>: for each spawned agent, run a separate agent to adversarially verify its output.</li>
  <li><strong>Generate-and-filter</strong>: generate many candidates on a topic, then filter them by a rubric.</li>
  <li><strong>Tournament</strong>: have N agents attempt the same task with different approaches and compete; pick the best.</li>
  <li><strong>Loop until done</strong>: keep spawning agents until a stop condition is met.</li>
</ul>

<h2 id="2-what-its-trying-to-solve">2. What it’s trying to solve</h2>

<p>Plain coding tasks are already a strong suit for Claude Code, but as a task gets complex and the chain gets long, a single context starts to strain: everything is crammed into one window and detail overflows or gets lost. Against that backdrop, the post explicitly names three single-context failure modes:</p>

<ul>
  <li><strong>Agentic laziness</strong>: on a complex, multi-part task, Claude stops partway and declares the job done after partial progress.</li>
  <li><strong>Self-preferential bias</strong>: when asked to verify its own output, it tends to prefer its own results — writing and grading its own work has a built-in bias.</li>
  <li><strong>Goal drift</strong>: across many turns and compactions, fidelity to the original objective, boundary conditions, and special requirements gradually erodes.</li>
</ul>

<p>Dynamic Workflows are designed to push these down using multiple independent contexts and a structured flow.</p>

<h2 id="3-where-it-fits">3. Where it fits</h2>

<p>It suits complex, high-value, long-chain tasks rather than simple code edits. The directions the post recommends, plus scenarios of my own:</p>

<ul>
  <li>Large-scale migrations / refactors</li>
  <li>Deep research and fact-checking (technical docs, multi-perspective review of business/technical proposals)</li>
  <li>Sorting, ranking, and rubric-based selection</li>
  <li>Enforcing one rule across a large body of output (security review, PR risk assessment)</li>
  <li>Root-cause investigation of production issues</li>
  <li>Large-scale triage: tickets, logs, incident records, résumés</li>
  <li>Summarizing common corrections from past sessions</li>
  <li>Lightweight model evaluation</li>
</ul>

<p>In short: <strong>whenever a task needs decomposition, parallelism, verification, and synthesis, Dynamic Workflows have room to work.</strong></p>

<h2 id="4-what-it-changes">4. What it changes</h2>

<p>The biggest shift, I think, is this: <strong>AI coding is moving from prompt-driven to workflow-driven.</strong></p>

<p>We used to mostly write prompts — “check step by step”, “don’t skip tests”, “please review this.” Those are really repeated pleas to the same single context. Dynamic Workflows turn those requests into a more stable execution structure: plan first, then decompose, run multiple agents in parallel, cross-verify with independent agents, synthesize at the end, and loop if the condition isn’t met.</p>

<p>That makes the AI feel less like a single assistant and more like a small engineering team you can assemble on demand.</p>

<h2 id="5-my-own-thoughts">5. My own thoughts</h2>

<p>After a quick trial, my sense is that the agent’s built-in harness ability has gone up another level.</p>

<p>Its most immediate value is relieving context-window pressure on complex tasks: hand different subtasks to different agents with their own isolated contexts, instead of cramming all the information into one window.</p>

<p>More importantly, quality. <strong>Letting the context that did the work also grade it is unreliable; only a separate, independent context escapes the self-certification bias.</strong> One agent implements, another reviews against a checklist, a third synthesizes the verdict — that is exactly the point of the adversarial-verification pattern.</p>

<p>What I think is most worth exploring next is the <strong>Dynamic Workflows + Skills</strong> combination: distill a team’s recurring processes into skills — schema-change checks, SQL review, migration checklist, release notes, regression tests, incident analysis, PR-review rubric — then use Dynamic Workflows to chain those skills into a more automated, reusable engineering flow. This may be the key step in an AI assistant evolving from “help me write code” to “help me manage complex engineering tasks.”</p>

<h2 id="6-summary">6. Summary</h2>

<p>Dynamic Workflows aren’t meant to replace the ordinary way of using Claude Code — they give complex tasks stronger organization. For simple tasks, plain Claude Code is enough; for complex ones, especially those that need decomposition, parallelism, verification, and iterative progress, reach for Dynamic Workflows.</p>

<p>I’d recommend trying it against your own real work — the real value isn’t just understanding the feature, but finding the usage that fits your team’s and your own development flow. Source: <a href="https://claude.com/blog/a-harness-for-every-task-dynamic-workflows-in-claude-code">https://claude.com/blog/a-harness-for-every-task-dynamic-workflows-in-claude-code</a></p>]]></content><author><name>KL</name></author><category term="AI" /><category term="LLM" /><category term="agent" /><summary type="html"><![CDATA[Anthropic recently shipped Claude Code Dynamic Workflows: instead of a single agent working in one context, Claude Code can write a bespoke harness for the task at hand — a JavaScript workflow that orchestrates multiple subagents. After reading the post and trying it, my main takeaway is this: the things we used to write into prompts (“please check carefully”, “don’t skip the tests”) are turning into structured execution flows. This is a feature walkthrough plus my own thoughts. Source: A harness for every task: Dynamic Workflows in Claude Code.]]></summary></entry><entry xml:lang="zh"><title type="html">Agent Harness 新实践：Claude Code 动态工作流</title><link href="https://kerryleung.github.io/blogs/2026/06/22/claude-dynamic-workflows/" rel="alternate" type="text/html" title="Agent Harness 新实践：Claude Code 动态工作流" /><published>2026-06-22T00:00:00+00:00</published><updated>2026-06-22T00:00:00+00:00</updated><id>https://kerryleung.github.io/blogs/2026/06/22/claude-dynamic-workflows</id><content type="html" xml:base="https://kerryleung.github.io/blogs/2026/06/22/claude-dynamic-workflows/"><![CDATA[<blockquote>
  <p>Anthropic 最近发布了 Claude Code Dynamic Workflows：Claude Code 不再只是单个 agent 在一个上下文里干活，而是可以为当前任务临时写一套专属 harness——一个 JavaScript workflow，用来调度多个子 agent 协作。我读完原文又试了一下，最大的体会是：过去写进 prompt 里的那些”请仔细检查”“别漏测试”，正在变成结构化的执行流程。本文是一篇功能梳理 + 我自己的思考。原文：<a href="https://claude.com/blog/a-harness-for-every-task-dynamic-workflows-in-claude-code">A harness for every task: Dynamic Workflows in Claude Code</a>。</p>
</blockquote>

<h2 id="一dynamic-workflows-是什么">一、Dynamic Workflows 是什么</h2>

<p>核心一句话：<strong>Claude Code 可以为任务即时生成自己的 harness。</strong> 它执行一个 JavaScript workflow，文件里有一组特殊函数，用来 spawn 并协调多个子 agent，而不是把所有事情塞进单一上下文窗口。</p>

<p>这些子 agent 可以有各自独立的上下文窗口和聚焦的目标，还可以指定各自使用的模型，甚至运行在各自独立的 worktree 中；workflow 本身就是普通 JavaScript（可以用 JSON、Math、Array 等），并支持中断后恢复。</p>

<p>原文给出六个典型编排模式：</p>

<ul>
  <li><strong>Classify-and-act</strong>：先按分类把任务路由到不同 agent。</li>
  <li><strong>Fan-out-and-synthesize</strong>：把任务拆成很多小步，每步跑一个 agent，再统一合成结果。</li>
  <li><strong>Adversarial verification</strong>：每 spawn 一个 agent，就再 spawn 一个独立 agent 去”对抗式”验证它的产出。</li>
  <li><strong>Generate-and-filter</strong>：先就某个主题生成大量候选，再按 rubric 筛选。</li>
  <li><strong>Tournament</strong>：让多个 agent 用不同思路同时解同一道题，互相竞争，选出最优。</li>
  <li><strong>Loop until done</strong>：持续 spawn agent，直到满足某个停止条件。</li>
</ul>

<h2 id="二它想解决什么问题">二、它想解决什么问题</h2>

<p>传统 Claude Code 处理普通编码任务已经很强，但任务一复杂、链路一长，单上下文就开始吃力：信息全挤在一个窗口里，容易溢出或丢细节。在这个大背景下，原文明确点名了单上下文的三个失败模式：</p>

<ul>
  <li><strong>Agentic laziness</strong>：在复杂的多步任务里，Claude 做到一半就宣布”完成了”，留下没做完的部分。</li>
  <li><strong>Self-preferential bias</strong>：当你让它验证自己的产出时，它倾向于认可自己的结果——自己写、自己检查，天然有偏向。</li>
  <li><strong>Goal drift</strong>：多轮交互、多次压缩之后，对原始目标、边界条件和特殊要求的”保真度”逐渐流失。</li>
</ul>

<p>Dynamic Workflows 的设计目标，就是用多个独立上下文和结构化流程把这几类问题压下去。</p>

<h2 id="三适合什么场景">三、适合什么场景</h2>

<p>它更适合复杂、高价值、长链路的任务，而不是简单的代码改动。原文推荐的方向，加上我自己想到的场景：</p>

<ul>
  <li>大规模迁移 / 重构</li>
  <li>深度调研与事实核查（技术文档、商业/技术方案多视角评审）</li>
  <li>排序、排名、按 rubric 选优</li>
  <li>在大量产出上统一执行某条规则（如安全审查、PR 风险评估）</li>
  <li>线上问题 root cause 分析</li>
  <li>大规模 triage：批量处理工单、日志、incident 记录、简历</li>
  <li>从历史 session 中总结常见纠正点</li>
  <li>轻量级的模型评测</li>
</ul>

<p>一句话：<strong>只要一个任务需要拆解、并行、验证、合成，Dynamic Workflows 就有发挥空间。</strong></p>

<h2 id="四它改变了什么">四、它改变了什么</h2>

<p>我觉得最大的变化是：<strong>AI Coding 正在从 prompt 驱动，走向 workflow 驱动。</strong></p>

<p>过去我们更多是在写 prompt——”请一步步检查”“请别漏测试”“请帮我 review”。这些其实是对着同一个上下文反复叮嘱。Dynamic Workflows 把这些要求变成更稳定的执行结构：先规划、再拆解、多 agent 并行执行、独立 agent 交叉验证、最后统一合成、不满足条件就继续循环。</p>

<p>这让 AI 更像一个可以临时组建的小型工程团队，而不是单个助手。</p>

<h2 id="五我自己的思考">五、我自己的思考</h2>

<p>简单试用后，我的感受是 agent 内置的 harness 能力又上了一个台阶。</p>

<p>它最直接的价值是缓解复杂任务里的上下文窗口压力：不同子任务交给不同 agent、用各自独立的上下文完成，不需要把所有信息都挤在同一个窗口里。</p>

<p>更关键的是质量。<strong>让做这件事的上下文同时去给它打分，是不可靠的；换一个独立上下文来审查，才跳得出自我背书的偏向。</strong> 一个 agent 负责实现，另一个按 checklist 审查，第三个汇总结论——这正是 adversarial verification 模式的意义。</p>

<p>我觉得后续最值得探索的，是 <strong>Dynamic Workflows + Skills 的组合</strong>：把团队的常见流程沉淀成 skill——schema 变更检查、SQL review、migration checklist、release note、regression test、incident analysis、PR review rubric——再用 Dynamic Workflows 把这些 skill 串成一套更自动化、更可复用的工程流程。这可能是 AI 助手从”帮我写代码”进化到”帮我管理复杂工程任务”的关键一步。</p>

<h2 id="六总结">六、总结</h2>

<p>Dynamic Workflows 不是要取代普通的 Claude Code 用法，而是为复杂任务提供更强的组织能力。简单任务，直接用 Claude Code 就够了；复杂任务，尤其是需要拆解、并行、验证、循环推进的任务，再考虑上 Dynamic Workflows。</p>

<p>推荐结合自己的真实工作场景实践一下——真正有价值的，不只是看懂这个功能，而是找到适合自己团队和个人开发流程的用法。原文：<a href="https://claude.com/blog/a-harness-for-every-task-dynamic-workflows-in-claude-code">https://claude.com/blog/a-harness-for-every-task-dynamic-workflows-in-claude-code</a></p>]]></content><author><name>KL</name></author><category term="AI" /><category term="LLM" /><category term="agent" /><summary type="html"><![CDATA[Anthropic 最近发布了 Claude Code Dynamic Workflows：Claude Code 不再只是单个 agent 在一个上下文里干活，而是可以为当前任务临时写一套专属 harness——一个 JavaScript workflow，用来调度多个子 agent 协作。我读完原文又试了一下，最大的体会是：过去写进 prompt 里的那些”请仔细检查”“别漏测试”，正在变成结构化的执行流程。本文是一篇功能梳理 + 我自己的思考。原文：A harness for every task: Dynamic Workflows in Claude Code。]]></summary></entry><entry xml:lang="en"><title type="html">When Agents Write 99% of the Code, Where Did the Engineer’s Moat Go?</title><link href="https://kerryleung.github.io/blogs/2026/06/22/engineer-edge-when-code-gets-cheap-en/" rel="alternate" type="text/html" title="When Agents Write 99% of the Code, Where Did the Engineer’s Moat Go?" /><published>2026-06-22T00:00:00+00:00</published><updated>2026-06-22T00:00:00+00:00</updated><id>https://kerryleung.github.io/blogs/2026/06/22/engineer-edge-when-code-gets-cheap-en</id><content type="html" xml:base="https://kerryleung.github.io/blogs/2026/06/22/engineer-edge-when-code-gets-cheap-en/"><![CDATA[<blockquote>
  <p>Ten years as a software engineer, and I’ve never met a technical shift that aimed straight at the <em>profession</em> itself the way agent coding does — and it all happened in the last three months. I recently read Augment’s “How we hire AI-native engineers now,” which redefines the human role as moving “from author to architect and editor.” The line that stung: pure coding ability is no longer the primary thing that differentiates engineering talent. This is my own reflection after reading it — not a retelling. The original is worth reading yourself.</p>
</blockquote>

<h2 id="a-question-that-stung-a-little">A question that stung a little</h2>

<p>Augment’s piece (by Alex Ding, Alyah Sablan, Chris Marty, and Vinay Perneti) opens with a blunt question: <strong>how do you hire engineers when agents write 99% of the code?</strong> Link at the bottom — I really recommend the original.</p>

<p>What stung was personal: the core capital I’ve built over ten years is exactly the thing getting commoditized — “writing code fast and correctly.” So my reflexive anxiety isn’t “I can’t write code anymore.” It’s the harder one — <strong>what’s left of my differentiation?</strong></p>

<p>Underneath sit two things that were bundled together for a decade and are now splitting apart: <em>being good at writing code</em>, and <em>being good at deciding what to write and steering a human-plus-agent system to the right outcome.</em> Inside the phrase “he’s a good engineer,” those two always felt like one thing; only when code gets cheap do you see that one is depreciating and the other appreciating.</p>

<p><strong>When the cost of producing code drops toward zero, the most expensive mistake becomes building the wrong thing — and your moat moves with it, from “how fast you write” to “how right you choose.”</strong></p>

<h2 id="the-map-augment-draws">The map Augment draws</h2>

<p>The article has a “traditional vs AI-native engineering” table that I think is its sharpest part (paraphrasing their framework):</p>

<table>
  <thead>
    <tr>
      <th>Traditional</th>
      <th>AI-native</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Writing code</td>
      <td>Specifying intent, evaluating tradeoffs</td>
    </tr>
    <tr>
      <td>Implementing solutions</td>
      <td>Orchestrating agents</td>
    </tr>
    <tr>
      <td>Solving problems</td>
      <td>Choosing the right problems</td>
    </tr>
    <tr>
      <td>Individual output</td>
      <td>System-level outcomes</td>
    </tr>
  </tbody>
</table>

<p>From there they derive <strong>six dimensions of AI-native engineering</strong>, each with a core question:</p>

<ol>
  <li><strong>Product &amp; Outcome Taste</strong> — Are we building the right thing?</li>
  <li><strong>System &amp; Architectural Judgment</strong> — Will this survive production?</li>
  <li><strong>Agent Leverage</strong> — Can you turn AI into real engineering throughput?</li>
  <li><strong>Communication &amp; Collaboration</strong> — Can you communicate intent clearly and collaborate across perspectives?</li>
  <li><strong>Ownership &amp; Leadership</strong> — Do you drive outcomes, not just tasks?</li>
  <li><strong>Learning Velocity &amp; Experimental Mindset</strong> — Can you evolve as fast as the tools?</li>
</ol>

<p>Notice what’s missing from the list: <strong>“pure coding ability” doesn’t appear as a standalone dimension.</strong> Not because it’s unimportant, but because it’s no longer the thing that separates one engineer from another. They also name four talent profiles (AI-native systems / product / applied-AI / early-professional engineers), each weighting the six dimensions differently — details in the original.</p>

<h2 id="three-takeaways-for-me">Three takeaways for me</h2>

<p>For a working engineer, the useful thing about reading someone’s hiring rubric is translating it into “where do I invest next.” Mine:</p>

<p><strong>1. Move skill investment from “coding speed” to things that compound.</strong> Capital invested narrowly in “fast and correct” is now a depreciating asset; capital in judgment, product taste, agent orchestration, and learning velocity compounds. This isn’t a one-time tradeoff — it’s a revaluation of career capital, charged with interest, by the year.</p>

<p><strong>2. “Agent leverage” is a delegation skill.</strong> The article has an analogy I like: using agents is like managing a report who’s astonishingly fast and occasionally, very confidently, wrong. Shaping a problem so it can execute well, pulling it back when it drifts, and verifying its output — that’s a different muscle from writing code.</p>

<p><strong>3. Don’t declare “coding doesn’t matter” across the board.</strong> Where the hard part <em>is</em> the code — novel algorithms, performance-critical kernels, areas agents are still weak — raw coding ability remains a differentiator. Commoditization advances unevenly; this split hasn’t reached every corner.</p>

<h2 id="closing">Closing</h2>

<p>I’m not pessimistic. This isn’t an “engineers are out of a job” story — it’s a “the craft is moving up the abstraction stack” story. Just as high-level languages once commoditized assembly skill and the value moved up a rung, agent coding is the next rung. What gets commoditized was never “the engineer” — it’s the most automatable layer of the engineer’s work.</p>

<p>Augment says it themselves: nobody has this fully figured out yet, but hiring is already changing whether the interview process has caught up or not. As a ten-year engineer still actively learning and adapting to the new tools, I’m sharing this in that spirit.</p>

<blockquote>
  <p>Original (read it): <a href="https://www.augmentcode.com/blog/how-we-hire-ai-native-engineers-now">How we hire AI-native engineers now — Augment Code</a></p>
</blockquote>]]></content><author><name>KL</name></author><category term="AI" /><category term="职业发展" /><category term="agent" /><summary type="html"><![CDATA[Ten years as a software engineer, and I’ve never met a technical shift that aimed straight at the profession itself the way agent coding does — and it all happened in the last three months. I recently read Augment’s “How we hire AI-native engineers now,” which redefines the human role as moving “from author to architect and editor.” The line that stung: pure coding ability is no longer the primary thing that differentiates engineering talent. This is my own reflection after reading it — not a retelling. The original is worth reading yourself.]]></summary></entry><entry xml:lang="zh"><title type="html">当 agent 写掉 99% 的代码，工程师的护城河挪去哪了</title><link href="https://kerryleung.github.io/blogs/2026/06/22/engineer-edge-when-code-gets-cheap/" rel="alternate" type="text/html" title="当 agent 写掉 99% 的代码，工程师的护城河挪去哪了" /><published>2026-06-22T00:00:00+00:00</published><updated>2026-06-22T00:00:00+00:00</updated><id>https://kerryleung.github.io/blogs/2026/06/22/engineer-edge-when-code-gets-cheap</id><content type="html" xml:base="https://kerryleung.github.io/blogs/2026/06/22/engineer-edge-when-code-gets-cheap/"><![CDATA[<blockquote>
  <p>做了十年软件工程师，我从没遇到过哪次技术变革像现在的 agent coding 这样，直接冲着「职业」本身来——而且就发生在过去三个月内。最近读到 Augment 那篇《我们现在如何招聘 AI 原生工程师》，它把人的角色重新定义为「从作者转向架构师和编辑者」。它真正刺到我的是一句话：纯粹的编码能力，已经不再是区分工程人才的首要因素。这篇是我读完之后的个人思考——不是复述原文，原文值得你自己读。</p>
</blockquote>

<h2 id="一个让我有点被刺到的问题">一个让我有点被刺到的问题</h2>

<p>Augment 这篇文章（作者 Alex Ding、Alyah Sablan、Chris Marty、Vinay Perneti）开篇就抛出一个问题：<strong>当 agent 写掉 99% 的代码，你该怎么招工程师？</strong> 原文链接放在文末，强烈建议读原版。</p>

<p>我被刺到的点很私人：我这十年攒下的核心资本，恰好就是那个正在被商品化的东西——「写代码写得又快又对」。所以我下意识的焦虑，不是「我不会写代码了」，而是更难回答的那个——<strong>我的差异化到底还剩什么？</strong></p>

<p>这背后是两件过去十年被捆在一起、现在正在分叉的事：<em>擅长写代码</em>，和<em>擅长决定该写什么、并把人加 agent 这套系统 driving 到正确结果</em>。在「他是个好工程师」这句话里，这两者一直感觉是一回事；只有当代码变得便宜，你才看出来——一个在贬值，一个在升值。</p>

<p><strong>当写代码的成本趋零，最贵的错误就变成了「构建了错误的东西」——你的护城河也跟着从「写得多快」挪到了「选得多对」。</strong></p>

<h2 id="augment-给的那张坐标">Augment 给的那张坐标</h2>

<p>文章里有一张「传统工程 vs AI 原生工程」的对照表，我觉得是全文最锋利的部分（以下为我对原文框架的转述）：</p>

<table>
  <thead>
    <tr>
      <th>传统工程</th>
      <th>AI 原生工程</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>编写代码</td>
      <td>明确意图、评估权衡</td>
    </tr>
    <tr>
      <td>实现解决方案</td>
      <td>编排智能体</td>
    </tr>
    <tr>
      <td>解决问题</td>
      <td>选择正确的问题</td>
    </tr>
    <tr>
      <td>个人产出</td>
      <td>系统级结果</td>
    </tr>
  </tbody>
</table>

<p>顺着这个方向，他们从第一性原理梳理出 <strong>AI 原生工程的六个维度</strong>，每个维度对应一个核心问题：</p>

<ol>
  <li><strong>产品与结果品味</strong> —— 我们在构建正确的东西吗？</li>
  <li><strong>系统与架构判断</strong> —— 这东西能在生产环境里活下来吗？</li>
  <li><strong>智能体杠杆</strong> —— 你能把 AI 转化为真正的工程产能吗？</li>
  <li><strong>沟通与协作</strong> —— 你能否清晰传达意图、跨视角协作？</li>
  <li><strong>主人翁精神与领导力</strong> —— 你推动的是结果，还是只是任务？</li>
  <li><strong>学习速度与实验心态</strong> —— 你能像工具演进那样快地进化自己吗？</li>
</ol>

<p>注意这张表里缺了什么：<strong>「纯粹编码能力」没有作为一个独立维度出现。</strong> 不是不重要，而是不再是把人和人区分开的那一项。他们还给出了四类人才画像（AI 原生系统 / 产品 / 应用 AI / 早期职业工程师），每类对这六维的权重不同——细节在原文里，这里不展开。</p>

<h2 id="我自己的三点收获">我自己的三点收获</h2>

<p>读别人的招聘标准，对一个在职工程师真正有用的，是把它翻译成「我接下来往哪投入」。我的三点：</p>

<p><strong>1. 把技能投资从「编码速度」挪向会复利的地方。</strong> 窄投在「写得快、写得对」上的能力，现在是贬值资产；投在判断力、产品品味、agent 编排、学习速度上的能力会复利。这不是一次性的取舍，而是一笔按年计息的职业资本重估。</p>

<p><strong>2. 「智能体杠杆」就是一种委派能力。</strong> 原文有个比喻我很喜欢：用 agent 像是管一个快得惊人、但偶尔会非常自信地出错的下属。把问题组织成它能高效执行的形状、在它偏航时拉回来、并验证它的产出——这和写代码是两套肌肉。</p>

<p><strong>3. 别一刀切地宣布「编码不重要」。</strong> 在难点就在代码本身的地方——新算法、性能关键内核、agent 还很弱的领域——纯编码能力仍然是差异化因素。商品化是不均匀推进的，这道分叉还没烧到每个角落。</p>

<h2 id="收尾与君共勉">收尾：与君共勉</h2>

<p>我不悲观。这不是「工程师要失业了」的故事，而是「这门手艺正在沿抽象层级往上挪」的故事——就像当年高级语言商品化了汇编技能，价值往上挪了一级，agent coding 不过是下一级台阶。被商品化的从来不是「工程师」，而是工程师工作里最容易被自动化的那一层。</p>

<p>Augment 自己也说了：目前还没有人把这件事完全想明白，但招聘已经在变，不管面试流程跟没跟上。作为一个还在积极学习、适应新工具的十年工程师，我把这篇分享出来，与君共勉。</p>

<blockquote>
  <p>原文（强烈建议读原版）：<a href="https://www.augmentcode.com/blog/how-we-hire-ai-native-engineers-now">How we hire AI-native engineers now — Augment Code</a></p>
</blockquote>]]></content><author><name>KL</name></author><category term="AI" /><category term="职业发展" /><category term="agent" /><summary type="html"><![CDATA[做了十年软件工程师，我从没遇到过哪次技术变革像现在的 agent coding 这样，直接冲着「职业」本身来——而且就发生在过去三个月内。最近读到 Augment 那篇《我们现在如何招聘 AI 原生工程师》，它把人的角色重新定义为「从作者转向架构师和编辑者」。它真正刺到我的是一句话：纯粹的编码能力，已经不再是区分工程人才的首要因素。这篇是我读完之后的个人思考——不是复述原文，原文值得你自己读。]]></summary></entry></feed>