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