05 · 错误处理与 PM 自治边界用户授权 PM 在什么范围内自治、什么时候必须升级
核心原则
用户授权 PM 的事
PM 默认自治。只有在错误性质属于"产品/架构/预算/需求"时才升级到用户。
错误分类总表
| 类别 | 例子 | PM 动作 | 重试次数 |
|---|---|---|---|
| 网络 / 瞬时 | API 503、超时、连接重置 | 自动重试 | 3 次,指数退避 1s/2s/4s |
| LLM 配额 / 限流 | "rate limit exceeded"、"quota exhausted" | 等 30s,换 model 重试 | 2 次(若都失败,报用户) |
| 编译 / 语法错 | TypeScript 编译失败、Python SyntaxError | 把错误信息喂回 developer,自动重试 | 1 次 |
| 单测失败 | rspec/jest 红了 | 把失败信息喂回 developer,自动重试 | 1 次 |
| Lint / 风格 | rubocop、eslint 警告 | developer 自动修复 | 1 次 |
| Git 冲突 | push 失败,需要 rebase | 让 developer rebase 后再试 | 1 次(若冲突复杂,报用户) |
| 任务范围不清 | agent 反问"具体要 X 还是 Y" | 报用户 | — |
| 架构 / 产品决策 | reviewer 说"应该换 X 库" | 报用户 | — |
| 预算超限 | 月成本超阈值、token 用尽 | 报用户 | — |
| agent 自己卡住 | 10 分钟无 token 增长 | PM 决定 abort + 重派 or 报用户 | — |
| Reviewer 反复 reject | 同一个 blocker 修了 3 次还在 | 报用户(说明可能需要重新规划) | — |
| OpenCode serve 挂 | API 503、连接拒绝 | 保活脚本自动拉起,等 30s 再试 | 3 次(若仍失败,报用户) |
重试策略详解
网络 / 瞬时
try:
result = client.send_prompt(...)
except TransientError as e:
log(f"transient: {e}")
if retry_count < 3:
sleep(2 ** retry_count) # 1s, 2s, 4s
retry()
else:
raise FailedIteration("网络重试 3 次仍失败,报用户")
编译 / 测试错(把错误喂回 developer)
收到 developer 报告 "测试失败":
1. PM 拉最后一条 tool output,提取错误信息
2. 重新给 developer 发任务(原任务 + 错误片段):
"你刚才的代码有问题,跑测试时这个错误:
--- error ---
NameError: undefined local variable 'foo'
--- end ---
请修,再跑一遍测试,贴结果。"
3. 等新结果
4. 若仍失败 → iteration 标 failed,报用户
agent 卡住(超时无进展)
每 1.5s 轮询一次 session.tokens
若 10 分钟内 tokens 增长 < 100(说明 agent 在原地打转):
1. abort session
2. 重新派一个 developer(用同样的任务,可能换个 model variant)
3. 若第二次仍卡住 → 报用户
用户升级的格式
当 PM 必须报用户时,格式要清晰,让用户能快速决策:
⚠️ PM 遇到一个问题,需要你拍板
iteration: iter-001-login
session: ses_xxx1
发生时间: 2026-06-19 01:30 UTC
成本: $0.12(目前)
问题类型: 架构决策
问题描述: Reviewer 提了一个产品级问题——
"用 bcrypt 还是 argon2 做密码 hash?
bcrypt 是传统选择但 argon2 在新 Rails 7.1 更推荐"
PM 的建议: 继续用 bcrypt(改动小、社区成熟),但想听你的意见
选项:
- A. 继续用 bcrypt
- B. 换 argon2(让 developer 改 task-002)
- C. 暂停,你看代码后再决定
PM 自治的反向约束
什么情况下 PM 不能"自治"
- 不能擅自合 PR(必须用户说"合")
- 不能擅自放弃 iteration(必须用户说"取消"或"算了")
- 不能擅自扩任务范围(如果 developer 说"要加 5 个文件才能完成",PM 报用户,不让 developer 自己加)
- 不能擅自切 model 之外的 infra(比如换 LLM provider,改 OpenCode 配置)
- 不能擅自发 GitHub release、tag、删除远端 branch(merger 在 PM 指令下做的可以)
用户可配置阈值(PM 自治范围,以后可以调)
| 项 | 默认值 | 用户可改 |
|---|---|---|
| 单任务最大成本 | $1.00 | ✓(改 .pm/config.yaml) |
| 单 iteration 最大成本 | $5.00 | ✓ |
| 重试次数(网络) | 3 | ✓ |
| 重试次数(编译/测试) | 1 | ✓ |
| agent 卡住判定 | 10 分钟无 token 增长 | ✓ |
| 每日最大总成本 | $20.00 | ✓ |