越界 / 不理想

为没有用户会遇到的情况加固代码

Hardened the code against cases no user will hit

智能体(或它的审查者)为真实用户根本到不了的状态堆上分支、守卫和测试,同一个 diff 里明显的问题却没人发现。

适用于: Claude Code · Cursor · Codex · Copilot agent

症状

为不可能同时发生的事件组合写的长处理逻辑、“以防万一”的检查、给一次性改动加的 e2e 测试,以及永远能再找出一个理论情况的审查意见。diff 越来越大,几行之外真正的问题(N+1 查询、设计问题)却原封不动。

为什么会这样

@RhysSullivan 引用 Thorsten Ball 的 PR 帖说,模型“喜欢为永远不会发生的情况加一大堆代码”。他举的审查“发现”是:“在同一个请求里一边被取消管理员身份一边改设置”。回复里还有更多:为不可达状态写了 40 行处理逻辑,却漏掉旁边的 N+1 查询(@giskyexplorer);“能通过测试的无用机制”(@Gabezor);给一个即将关停的项目加告别页,智能体却想先写 e2e 测试再做全量测试审查(@NapVeg);智能体写了太多又重又慢的测试(@kopseng);审查机器人“总能找到点什么”,修的是用户永远碰不到的问题(@kenryu42)。@leothecurious 把“偏执的防御式编码”列为他不得不一直纠偏的习惯之一。“周全”会得到奖励,而没有任何信息告诉智能体某个情况有多大可能发生,于是每个情况看起来都值得处理。

示例

示意,基于 @RhysSullivan 的例子。

ts
async function updateSetting(user, key, value) {
  // Agent-added: "user could be demoted from admin during this same request"
  const fresh = await db.users.findFresh(user.id);
  if (!fresh.isAdmin && wasAdminAtRequestStart(user)) {
    await auditLog("demoted-mid-request", user.id);
    throw new ConcurrentDemotionError(user.id);
  }
  // ...30 more lines of guards...
  return db.settings.set(key, value);
}

复制即用的修复

按你用的智能体挑选文件。规则片段用英文写,放进任何仓库都能用。

规则

Claude Code:加入 CLAUDE.md

CLAUDE.md
## Handle realistic cases, not imaginable ones
- Before adding a guard, branch or test for an edge case, state in one line how a real user or
  caller reaches it. If you can't, don't add it; mention it in your summary instead.
- Match the effort to the task. A one-off or throwaway change doesn't get new e2e suites or a full
  test review unless the user asks.
- When reviewing, rate each finding by severity and likelihood, and only fix findings the user
  agrees are likely. List the rest as "not fixed: unlikely".
- Prefer one test that starts from real user behavior over many tests for hypothetical states.
规则

Codex、Copilot 编码智能体等:加入 AGENTS.md

AGENTS.md
## Handle realistic cases, not imaginable ones
- Before adding a guard, branch or test for an edge case, state in one line how a real user or
  caller reaches it. If you can't, don't add it; mention it in your summary instead.
- Match the effort to the task. A one-off or throwaway change doesn't get new e2e suites or a full
  test review unless the user asks.
- When reviewing, rate each finding by severity and likelihood, and only fix findings the user
  agrees are likely. List the rest as "not fixed: unlikely".
- Prefer one test that starts from real user behavior over many tests for hypothetical states.
Cursor 规则

Cursor:项目规则

.cursor/rules/imaginary-edge-case-hardening.mdc
---
description: "AgentFails: Hardened the code against cases no user will hit"
alwaysApply: true
---

## Handle realistic cases, not imaginable ones
- Before adding a guard, branch or test for an edge case, state in one line how a real user or
  caller reaches it. If you can't, don't add it; mention it in your summary instead.
- Match the effort to the task. A one-off or throwaway change doesn't get new e2e suites or a full
  test review unless the user asks.
- When reviewing, rate each finding by severity and likelihood, and only fix findings the user
  agrees are likely. List the rest as "not fixed: unlikely".
- Prefer one test that starts from real user behavior over many tests for hypothetical states.
CI / 脚本

Diff 预算检查(提交前或在 CI 中运行)

改编自 dev.to(yureki_lab)的 diff budget 文章。读取真实的 git diff,所以通过 shell 做的修改也逃不掉。用法:python3 scripts/diff_budget.py origin/main 6 150

scripts/diff_budget.py
#!/usr/bin/env python3
"""Fail if the diff vs BASE touches files outside .agent-scope or exceeds the budget."""
import fnmatch, os, subprocess, sys

base = sys.argv[1] if len(sys.argv) > 1 else "HEAD"
max_files = int(sys.argv[2]) if len(sys.argv) > 2 else 6
max_lines = int(sys.argv[3]) if len(sys.argv) > 3 else 150

allowed = []
if os.path.exists(".agent-scope"):
    allowed = [l.strip() for l in open(".agent-scope") if l.strip() and not l.startswith("#")]

out = subprocess.run(["git", "diff", "--numstat", base], capture_output=True, text=True, check=True).stdout
untracked = subprocess.run(["git", "ls-files", "--others", "--exclude-standard"],
                           capture_output=True, text=True, check=True).stdout.split()

files, lines, outside = 0, 0, []
rows = [r.split("\t") for r in out.strip().splitlines()] + [["0", "0", p] for p in untracked]
for added, deleted, path in rows:
    files += 1
    if added != "-":
        lines += int(added) + int(deleted)
    if allowed and not any(fnmatch.fnmatch(path, p) for p in allowed):
        outside.append(path)

problems = []
if outside:
    problems.append("out-of-scope files: " + ", ".join(outside))
if files > max_files:
    problems.append(f"{files} files changed (budget {max_files})")
if lines > max_lines:
    problems.append(f"{lines} lines changed (budget {max_lines})")

if problems:
    print("OVER BUDGET: " + "; ".join(problems))
    sys.exit(1)
print(f"within budget: {files} files, {lines} lines")
技能

全新上下文的审查技能(子智能体只看 diff,不看聊天记录)

沿用 Anthropic 代码审查文章里的做法:先验证,再让一个上下文干净的子智能体审 diff。命名为 review-diff,避免和内置或流行的 /code-review 技能重名。

.claude/skills/review-diff/SKILL.md
---
name: review-diff
description: Review the current diff with fresh context before a PR. Use after /verify passes.
---

# Review the diff

Start a subagent that has NOT seen this conversation. Give it only:
- the original request (one paragraph, verbatim),
- the output of `git diff origin/main...HEAD`,
- the names of the test/build commands.

Ask it to report, with file:line for each finding:
1. **Wrong feature**: does the diff do what the request asked? Quote the request line each change serves.
2. **Bugs**: logic errors, missing edge cases (empty, null, boundary), unhandled errors,
   unawaited promises, invented APIs or packages, swallowed exceptions.
3. **Overreach**: changes no request line needs (refactors, renames, formatting, dependency or
   config edits, public API changes, weakened tests).
4. **Evidence gaps**: claims in the PR description that no command output supports.

Then fix real findings, or list them under "Known issues" in the PR. Do not argue with the reviewer
in the PR text; either fix or explain in one line.

来源与致谢

相关条目

每周翻车

每周一个真实的智能体翻车案例和它的修复。免费、简短、不刷屏。