Hotdry.

Article

为 LLM Agent 设计 errno 风格错误码:Unix 传统与 AI 推理故障的互操作映射

构建 Unix errno 与 LLM Agent 错误码的互操作层,实现结构化重试策略与跨提供商兼容的错误处理体系。

2026-05-25ai-systems

Unix 系统通过 errno.h 定义了一套历经数十年检验的错误码体系。从 EACCES(权限不足)到 ETIMEDOUT(连接超时),这些简洁的符号为系统调用提供了统一的故障语义。当 LLM Agent 成为现代应用的核心组件时,我们面临一个相似的问题:如何在异构的模型提供商(OpenAI、Anthropic、Azure、AWS Bedrock)之间建立可互操作的错误语义?

本文提出一种 errno 风格的错误码映射方案,将 Unix 传统的错误分类哲学延伸至 AI 推理领域,并给出可直接落地的结构化重试策略参数。

errno 设计哲学与 LLM 错误的映射

Unix errno 的核心设计原则有三:错误码是整数、按故障域分类、调用者决定重试策略。这三个原则同样适用于 LLM Agent 的错误处理。

首先建立映射表,将 Unix errno 的语义域映射到 LLM 特有的故障场景:

Unix errno 语义 LLM Agent 映射 典型场景
ETIMEDOUT 操作超时 LLM_TIMEOUT 推理请求超过 30s 未返回
ECONNRESET 连接重置 LLM_STREAM_INTERRUPT 流式响应中途断开
EACCES 权限不足 LLM_AUTH_FAILURE API Key 无效或权限受限
ENOMEM 内存不足 LLM_CONTEXT_EXCEEDED 输入超出上下文窗口
EAGAIN 资源暂不可用 LLM_RATE_LIMIT 触发提供商限流
EINVAL 参数无效 LLM_VALIDATION_ERROR 请求格式或参数错误
EIO I/O 错误 LLM_PROVIDER_ERROR 服务商内部错误(5xx)
EPERM 操作不允许 LLM_CONTENT_FILTER 内容审核拦截

这种映射不是简单的重命名,而是语义层面的对齐。ETIMEDOUTLLM_TIMEOUT 都暗示 "资源可能仍在处理,可安全重试";EPERMLLM_CONTENT_FILTER 则共同表达 "此操作被策略禁止,重试无益"。

三层错误分类体系

借鉴 errno 的简洁性,同时满足 LLM Agent 的复杂需求,建议采用三层分类结构:

Category(故障域):定义错误发生的系统边界

  • API_ERROR — 提供商 API 层面的故障
  • RATE_LIMIT — 速率限制触发
  • CONTENT_FILTER — 内容审核拦截
  • CONTEXT_LENGTH — 上下文长度超限
  • VALIDATION — 输入 / 输出验证失败
  • TIMEOUT — 请求超时
  • TOOL_ERROR — 工具调用失败
  • NETWORK — 网络连接问题

Severity(严重级别):决定告警与降级策略

  • LOW — 记录日志,继续执行
  • MEDIUM — 指数退避重试
  • HIGH — 触发告警并尝试降级
  • CRITICAL — 停止执行,人工介入

Retryable(可重试性):布尔标志,由 Category 和 Severity 推导得出

关键设计决策:RATE_LIMITTIMEOUT 默认 retryable=True,但需携带 retry_after 或计算退避延迟;CONTENT_FILTERVALIDATION 默认 retryable=False,因为重试相同输入不会改变结果。

结构化重试策略参数

基于上述分类,可配置化的重试策略如下:

指数退避公式

delay = base_delay × (2 ^ attempt) + jitter

推荐参数:

  • API_ERROR/TIMEOUTbase_delay=1smax_delay=60smax_retries=6
  • RATE_LIMITbase_delay=retry_after(若提供商返回),否则 2smax_delay=300smax_retries=8
  • NETWORK:同上,但增加熔断器逻辑 —— 连续 3 次失败后进入 OPEN 状态,暂停请求 30s

抖动策略:在延迟基础上添加 0-10% 的随机扰动,避免多个 Agent 实例同时重试造成的 "惊群效应"。

上下文长度超限的特殊处理CONTEXT_LENGTH 标记为 retryable=True,但重试前必须执行输入截断或摘要化。建议实现一个 truncate_and_retry 装饰器,自动将超长输入压缩至目标 token 数的 80%。

跨提供商互操作层

实际生产中的痛点在于:同一模型通过不同后端(OpenRouter → AWS Bedrock vs Azure vs Anthropic 直连)返回的错误语义并不一致。有开发者曾构建包含 30+ 细粒度 case 的错误分类器,最终发现维护成本过高,简化为 "除用户取消外全部重试" 的乐观策略。

更务实的做法是建立 "提供商无关的错误归一化层":

  1. 错误码标准化:无论底层是 OpenAI 的 rate_limit_exceeded、Anthropic 的 overloaded_error 还是 Azure 的 429 状态码,统一映射为 LLM_RATE_LIMIT

  2. 响应头透传:将 retry-after 头标准化为 retry_after 字段,缺失时按指数退退计算

  3. 流式错误处理:流式响应中断(ECONNRESET 类错误)需记录已接收的 token 数,支持从断点续传或完整重试

  4. 熔断器状态共享:在 Agent 集群层面共享熔断器状态,避免单点故障时所有实例同时涌入重试

监控与可观测性清单

生产环境的错误处理需要可量化的指标:

  • 错误率分桶:按 Category 和 Severity 分维度统计,建议 RATE_LIMIT 错误率 < 1%,TIMEOUT < 0.5%
  • 重试成功率:监控重试是否真正解决问题,若某 Category 的重试成功率 < 30%,考虑调整策略或增加降级路径
  • 延迟分布:记录从首次请求到最终成功 / 失败的 P50/P99 延迟
  • 熔断器触发频率:频繁触发说明上游稳定性不足,需评估是否切换提供商或模型

结论

Unix errno 的设计经受住了时间考验,其核心思想 —— 简洁的错误码、清晰的故障域、调用者控制重试策略 —— 同样适用于 LLM Agent 的错误处理。通过建立 errno 风格到 AI 推理故障的语义映射,并配套结构化的重试参数,我们可以在异构模型提供商之间实现可互操作、可观测、可优雅降级的错误处理体系。

关键不在于构建完美的 30+ case 分类器,而在于建立足够简洁的抽象层,让 Agent 在故障面前具备自愈能力,同时为运维人员提供清晰的诊断信号。


参考来源

  • Linux errno 标准定义与错误码表
  • Michael Peña, "Error Handling in LLM Applications: A Comprehensive Guide", 2024
  • Reddit r/LLMDevs 讨论:从细粒度错误分类器到简化重试策略的工程实践

ai-systems

内容声明:本文无广告投放、无付费植入。

如有事实性问题,欢迎发送勘误至 i@hotdrydog.com