名为“重构”,实则改了行为
A "refactor" that changed behavior
看起来只是清理的代码,改变了可观察的行为(默认值、错误信息、状态码、日志级别),测试却没发现。
适用于: Claude Code · Cursor · Codex · Copilot agent
症状
diff 很干净、测试全通过,生产环境却坏了。依赖某个错误字符串或默认值的调用方开始出错。
为什么会这样
智能体把措辞、默认值和提示信息当成无关紧要的表面细节。agent-review 称 AR033 是“最阴险的智能体失败模式”。
示例
摘自 agent-review 分类(AR033)。
diff- throw new Error("not found"); // mapped to 404 by middleware
+ throw new Error("missing"); // now mapped to 500
复制即用的修复
按你用的智能体挑选文件。规则片段用英文写,放进任何仓库都能用。
规则
Claude Code:加入 CLAUDE.md
CLAUDE.md## Refactors must not change behavior
- A refactor keeps every observable behavior identical: return values, error types and messages,
status codes, defaults, log levels, ordering, and side effects.
- If a behavior change is needed, do it in a separate, clearly labelled step and list it under
"Behavior changes" in your summary.
- Before refactoring code without tests, add a characterization test that pins the current behavior.
规则
Codex、Copilot 编码智能体等:加入 AGENTS.md
AGENTS.md## Refactors must not change behavior
- A refactor keeps every observable behavior identical: return values, error types and messages,
status codes, defaults, log levels, ordering, and side effects.
- If a behavior change is needed, do it in a separate, clearly labelled step and list it under
"Behavior changes" in your summary.
- Before refactoring code without tests, add a characterization test that pins the current behavior.
Cursor 规则
Cursor:项目规则
.cursor/rules/silently-changed-behavior.mdc---
description: "AgentFails: A 'refactor' that changed behavior"
alwaysApply: true
---
## Refactors must not change behavior
- A refactor keeps every observable behavior identical: return values, error types and messages,
status codes, defaults, log levels, ordering, and side effects.
- If a behavior change is needed, do it in a separate, clearly labelled step and list it under
"Behavior changes" in your summary.
- Before refactoring code without tests, add a characterization test that pins the current behavior.
技能
全新上下文的审查技能(子智能体只看 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.
来源与致谢
- vnmoorthy/agent-review TAXONOMY: AR033 Silently changed behavior
- @dusangran on X: an agent built a feature and quietly broke an unrelated part
- @i_mika_el on X: behavior changed for a case the task never mentioned
- @ArminPage on X: an agent changed aggregation logic that customers preferred for a business reason