AI 智能體 PR 如何設定差異預算:行數、檔案數與波及範圍
Diff budgets for AI PRs: lines, files, and blast radius
作者提出在提示詞中為 AI 智能體的 PR 設定差異預算,以行數、檔案數和允許修改範圍限制改動。示例上限為 8 個檔案、250 行,超出時須停止並説明原因,再用 git diff --stat 和檔案數核對改動。
I stopped arguing with agents about “keep the PR small.” Small is mushy. What works is a diff budget — hard numbers for lines, files, and blast radius — written into the prompt before the model starts typing.
Green CI on a 1,200-line agent PR is not a win. It’s a review hostage situation.
Why agents blow past “small”
Models don’t feel review pain. Given a feature ask, they’ll happily:
- Touch every file that might be related
- Rewrite tests “for clarity” while fixing the bug
- Drive-by format / rename / import-sort half the package
- Open shared UI primitives because “the Button was almost right”
You said small. They optimized for complete. Completeness without a budget looks like a megadiff.
The three budgets I actually use
I put all three in the prompt. Soft limits get ignored; hard stops get obeyed more often.
-
Lines — max changed lines (insertions + deletions), e.g.
≤ 200for a bugfix,≤ 400for a feature slice -
Files — max paths touched, e.g.
≤ 8(tests count) -
Blast radius — allowed directories / globs, e.g. only
src/features/checkout/**+ colocated tests
Miss any one and reviewers lose the thread. A 150-line change across 25 files is still painful. A 300-line change inside one feature folder is often fine.
Paste this into the prompt
## Diff budget (HARD — stop if you would exceed)
- Max files: 8 (including tests / stories)
- Max lines: 250 (git diff --stat total)
- Blast radius: ONLY src/features/checkout/** and **/checkout*.test.*
- Do NOT edit: src/components/ui/**, shared hooks, CI, package.json, lockfiles
If the task needs more: STOP. List what you’d need and why.
Do not “almost finish” outside the fence.
Prefer a follow-up PR over expanding scope.
That STOP clause matters. Without it, agents treat the budget as a suggestion and keep going.
How I pick the numbers
Rough defaults I reuse on frontend work:
| Kind of change | Files | Lines | Typical fence |
|---|---|---|---|
| Bug fix / copy / a11y | 1–4 | ≤ 120 | One component + test/story |
| Small feature slice | 3–8 | ≤ 250 | Feature folder only |
| Refactor (rename/extract) | 2–6 | ≤ 200 | One intent, no behavior change |
| Migration / codegen | separate rules | — | Often file-count heavy; budget by intent, not vanity lines |
If the real work can’t fit, I split the ask before prompting — not after reviewing a monster.
Measure, don’t vibe
After the agent stops, I run:
git diff --stat
git diff --name-only | wc -l
If --stat or the file count is over budget, I don’t deep-review. I send it back:
Over budget: 14 files / 480 lines. Fence was
checkout/**, max 8 / 250. Split into (1) UI state (2) API wiring — or justify the overrun in one paragraph.
Agents respond well to concrete overruns. “Too big” does nothing. Numbers do.
Blast radius beats line count
Line budgets alone miss the scary cases:
- One-line changes in
auth,payments, andi18nconfig - Touching design-system primitives for a page-level tweak
- Editing both app code and generated GraphQL types “while here”
So I always name allowed globs and forbidden areas. When the agent needs a shared Button change, I want a stop + a note — maybe that becomes PR #2 with its own reviewers.
Pair budgets with one intent
A diff budget without one intent still fails. “Fix checkout + clean hooks + update Storybook” will thrash inside the numbers by doing three half-jobs.
Prompt shape I like:
- One sentence intent
- Diff budget block
- Acceptance checks (tests / story / manual path)
- Explicit non-goals
Example non-goals: no renames, no dependency bumps, no “improve types” outside touched signatures.
What I do when overrun is legitimate
Sometimes 12 files is correct (rename across the feature). Then I:
- Raise the file budget and freeze line budget for behavior
- Or require one commit per concern inside the PR
- Or stack two PRs: mechanical rename first, behavior second
I still write the new budget into the prompt. “Unlimited because rename” is how you get rename + rewrite.
Tiny checklist before I hit send
- [ ] Intent is one sentence
- [ ] File max + line max + path fence are numbers/globs, not adjectives
- [ ] Forbidden paths listed
- [ ] STOP-and-report rule present
- [ ] How I’ll measure (
git diff --stat) stated up front
What I stopped doing
- Saying “keep it reviewable” with no numbers
- Accepting “I had to touch Button” without a separate PR
- Reviewing over-budget diffs hoping the important hunks would jump out
- Letting test rewrites eat half the line budget on a one-line product fix
Diff budgets turn “please be careful” into something the agent can fail against. Lines, files, blast radius — pick all three, put them in the prompt, and send the PR back when the meter trips. Review time stays scarce; the model’s typing speed doesn’t get a blank check.
來源:DEV Community · dev.to