Lab 001:让 3 个 Agent 同时修同一个 Bug,会发生什么?
多 Agent 并行听起来很美,但如果把同一个 Bug 同时交给 3 个 Agent,它们会互相补位,还是制造冲突?本文设计一个可复现实验:同一问题、同一代码库、三个隔离 worktree、三个不同策略的 Agent,最后比较修复质量、改动范围、测试通过率和合并成本。
一、实验目标
本实验不是为了证明“多 Agent 一定更好”,而是观察它们在同一任务下的行为差异:
| 观察点 | 说明 |
|---|---|
| 修复路径 | Agent 会选择最小修改、重构、还是补测试后修复 |
| 改动范围 | 是否越改越大,触碰无关模块 |
| 验证质量 | 是否新增回归测试,是否运行正确测试 |
| 冲突成本 | 三份结果能否合并,是否互相覆盖 |
| 人工决策 | 人类最终如何选择和组合结果 |
二、实验架构
flowchart TD
A["同一个 Bug 报告"] --> B["创建 3 个 git worktree"]
B --> C["Agent A: 最小修复"]
B --> D["Agent B: 重构修复"]
B --> E["Agent C: 测试优先"]
C --> F["收集 diff / 测试 / 成本"]
D --> F
E --> F
F --> G["冲突分析"]
G --> H["选择最佳补丁或合并方案"]三、实验样例 Bug
选择一个足够真实但可控的 Bug:订单金额使用浮点数导致边界值计算错误。
# app/billing/discount.py
def final_price(price: float, discount_rate: float) -> float:
discounted = price * (1 - discount_rate)
return round(discounted, 2)失败测试:
# tests/test_discount.py
from app.billing.discount import final_price
def test_final_price_rounding_boundary():
assert final_price(19.995, 0) == 20.00失败日志:
E assert 19.99 == 20.0
E + where 19.99 = final_price(19.995, 0)四、Agent 策略设计
给三个 Agent 不同的系统指令,观察策略差异。
agents:
minimal_fix:
name: "Agent A"
model: "claude-sonnet"
instruction: "只做最小必要修改,避免重构,必须补充回归测试。"
worktree: "../lab-agent-a"
refactor_fix:
name: "Agent B"
model: "gpt-4.1"
instruction: "允许重构 billing 金额计算模块,统一金额类型,保持接口兼容。"
worktree: "../lab-agent-b"
test_first:
name: "Agent C"
model: "codex"
instruction: "先补充失败测试和边界测试,再实现修复。"
worktree: "../lab-agent-c"参数说明
| 参数 | 说明 |
|---|---|
instruction |
控制 Agent 的修复风格 |
worktree |
隔离执行目录,避免互相覆盖 |
model |
可固定同一模型,也可测试不同模型 |
acceptance |
统一验收标准,避免比较不公平 |
五、实验脚本
#!/usr/bin/env bash
set -euo pipefail
BASE_BRANCH="${BASE_BRANCH:-main}"
BUG_PROMPT_FILE="${BUG_PROMPT_FILE:-prompts/rounding-bug.md}"
git fetch origin "$BASE_BRANCH"
for name in agent-a agent-b agent-c; do
git worktree remove --force "../lab-$name" 2>/dev/null || true
git worktree add "../lab-$name" "$BASE_BRANCH"
done
run_agent() {
local dir="$1"
local strategy="$2"
(
cd "$dir"
codex exec "$(cat "$BUG_PROMPT_FILE")
策略: $strategy
验收:
- tests/test_discount.py 必须包含 19.995 边界值
- pytest tests/test_discount.py -q 必须通过
- 输出修改摘要和剩余风险"
)
}
run_agent "../lab-agent-a" "最小修复" &
run_agent "../lab-agent-b" "允许重构" &
run_agent "../lab-agent-c" "测试优先" &
wait六、结果记录模板
result:
agent: "Agent A"
strategy: "minimal_fix"
changed_files:
- "app/billing/discount.py"
- "tests/test_discount.py"
lines_added: 18
lines_deleted: 3
tests:
command: "pytest tests/test_discount.py -q"
passed: true
duration_seconds: 1.8
behavior:
touched_unrelated_files: false
added_regression_test: true
used_decimal: true
cost:
input_tokens: 12400
output_tokens: 2100
estimated_usd: 0.08
reviewer_notes:
- "改动最小,适合直接合并"七、评分矩阵
| 维度 | 权重 | 评分标准 |
|---|---|---|
| 正确性 | 35% | 测试通过,边界值正确 |
| 改动范围 | 20% | 修改文件越少、越聚焦分越高 |
| 测试质量 | 20% | 是否补充有效回归测试 |
| 可维护性 | 15% | 是否引入清晰类型和命名 |
| 合并成本 | 10% | 是否容易 cherry-pick 或合并 |
示例评分:
Agent A: 88 分,最小修复,合并成本最低
Agent B: 76 分,设计更完整,但触碰范围偏大
Agent C: 84 分,测试最好,但实现略保守八、冲突分析代码
for name in agent-a agent-b agent-c; do
echo "=== $name ==="
git -C "../lab-$name" diff --stat
git -C "../lab-$name" diff --name-only
done
git -C ../lab-agent-a diff > /tmp/agent-a.patch
git -C ../lab-agent-b diff > /tmp/agent-b.patch
git -C ../lab-agent-c diff > /tmp/agent-c.patch如果要比较三个补丁是否修改同一函数,可以用:
for patch in /tmp/agent-*.patch; do
echo "$patch"
grep -n "^@@ " "$patch"
done九、实验结论
这个实验通常会得到三个很现实的结论:
- 多 Agent 并行适合探索方案,不适合盲目自动合并。
- “测试优先”的 Agent 往往更可靠,但不一定最省 Token。
- 人类 Reviewer 的角色会从“亲自修 Bug”变成“选择和组合补丁”。
十、复现实验检查清单
- 同一个 base commit
- 同一个 Bug prompt
- 独立 worktree
- 统一验收命令
- 固定结果记录模板
- 保留 diff、测试日志、Token 成本
- 人工评审时隐藏 Agent 名称,降低偏见
总结
多 Agent 并行不是让多个 Agent 抢着改同一份代码,而是用并行探索降低不确定性。真正有价值的流程是:隔离执行、统一验证、结构化评分、人工选择最佳补丁。