定位失败、重试与取消发生的位置
用阶段与结构化证据区分故障,避免把所有异常归因模型或盲目重试。
定位失败、重试与取消发生的位置
同一条“任务失败”提示,可能来自鉴权拒绝、网络连接、响应解析、工具业务或界面状态。先按发生边界分类,才能选择下一项检查,而不是给所有失败加一次重试。
错误分类描述当前证据,并不宣称已经找到根因。例如工具内请求返回 401,工具层失败是事实,凭据是否配置错误还需要沿工具子调用继续查证。
本系列的独立示例位于仓库 columns/coding-agent/examples/debugging-observability/,固定使用 pi-agent-core、pi-ai、pi-schema、pi-telemetry 1.5.0。先在该目录执行 npm install,下文命令也从该目录运行。示例不需要模型密钥,不读取个人配置。
用结构化证据分类
src/failure.ts 接受当前阶段、状态码、错误码和取消状态,不解析任意报错文本来做权限或重试决定。
export type FailureKind =
| "cancelled"
| "auth"
| "rate-limit"
| "transport"
| "tool"
| "decode"
| "resource"
| "unknown"
export interface FailureEvidence {
aborted?: boolean
status?: number
code?: string
stage?: "request" | "decode" | "tool" | "resource"
}
// 这是教学分类规则,不猜测任意错误文本,不自动决定重试或权限。
export function classify(evidence: FailureEvidence): FailureKind {
if (evidence.aborted) {
return "cancelled"
}
if (evidence.stage === "tool") {
return "tool"
}
if (evidence.stage === "resource") {
return "resource"
}
if (evidence.status === 401 || evidence.status === 403) {
return "auth"
}
if (evidence.status === 429) {
return "rate-limit"
}
if (evidence.stage === "decode") {
return "decode"
}
if (
evidence.stage === "request" &&
["ENOTFOUND", "ECONNRESET", "ETIMEDOUT"].includes(evidence.code ?? "")
) {
return "transport"
}
return "unknown"
}阶段优先级是教学规则:明确处在工具内部时先归工具,再沿子调用追踪;主动取消与普通失败分开。无法判断就保留 unknown,不把所有 5xx、超时或字符串“network”自动归为某个根因。
错误链可能还包含嵌套 cause,生产采集应以深度和字段白名单读取,保留可用结构码,避免默认导出完整 stack、请求体或服务端回显。助手消息 diagnostics、资源 diagnostic 和工具 isError 也不是同一种结构,应先在各自边界提取。
把重试当作多次尝试观察
一项任务重试三次,通常需要一个逻辑任务身份与三个尝试身份。统计任务失败率时,不能把成功前两次失败当成三个失败任务;统计请求成本时,也不能只看最终成功的一次。两种口径服务不同问题。
结束事件为什么容易误判
coding-agent 的一次底层 agent_end 后可能还有自动重试、压缩恢复、steering 或 follow-up。需要判断会话是否收束,应观察 agent_settled,并结合其中的取消信息。
底层 Agent 示例没有这些完整宿主流程,lesson_run_end 只表示等待 prompt 返回。后续把示例接入 coding-agent 时,应适配真实事件,不能在看见 agent_end 时自己伪造一个 settled。
取消并不撤销已经发生的事
AbortSignal 表达取消意图,真正的文件、网络、子进程实现必须处理它。工具在取消前可能已经写文件或请求服务,进程结束也不意味着副作用已回滚。
诊断记录应区分“用户发出取消”“底层确认终止”“外部效果已核对”。不要把取消记为普通模型错误,也不要向用户显示未经确认的“已恢复原状”。
把分类结果变成可执行的排查顺序
先确认任务与尝试身份,再找最后一个有证据的成功边界,检查下一个边界的输入、输出或缺失事件。错误只说明某一层没完成时,继续向下取证,而不是给它加一个更宽泛的标签。
运行 npm test 会覆盖取消、鉴权、限流、网络结构码、解析、资源和未知分支。它验证的是分类规则,不验证真实 DNS、Provider 重试或宿主压缩恢复;这些需要专门的集成场景。
依据与版本
本地官方快照为 8efd314fa,相关包标记 1.3.0;配套代码另按已发布的 1.5.0 类型和运行行为核验。主分支文档持续变化,不能混作同一版本。