4.4 错误处理与故障恢复

在智能体运行时,会遇到多种类型的错误,包括工具执行失败、API 调用超时、输出解析错误等。本节介绍如何对这些错误进行分类、设计恢复策略,以及 OpenClaw 的“错误即观察”模式。

4.4.1 错误的分类与应对策略

智能体循环中可能遇到的错误分为几类,每类需要不同的处理策略:

1. 工具执行错误: 工具调用失败、权限拒绝、参数错误、工具崩溃 影响范围:当前工具调用 恢复策略:作为“观察”反馈给 Agent

import asyncio

class ToolExecutionError(Exception):
    """工具执行错误"""
    def __init__(self, tool_name: str, message: str,
                 error_type: str = None, retry_count: int = 0):
        self.tool_name = tool_name
        self.message = message
        self.error_type = error_type or type(self).__name__
        self.retry_count = retry_count
        super().__init__(message)

class ToolTimeoutError(ToolExecutionError):
    """工具执行超时"""
    pass

class ToolPermissionError(ToolExecutionError):
    """工具权限不足"""
    pass

# 处理示例
async def execute_tool_with_recovery(
    tool_use: ToolUseBlock,
    executor: ToolExecutor,
    max_retries: int = 3
) -> ToolResultBlock:
    """执行工具,带重试机制"""

    for attempt in range(max_retries):
        try:
            result = await executor.execute(tool_use.name, tool_use.input)
            return ToolResultBlock(
                tool_use_id=tool_use.id,
                content=str(result),
                is_error=False
            )

        except ToolTimeoutError as e:
            # 超时:使用指数退避重试
            if attempt < max_retries - 1:
                backoff_seconds = 2 ** attempt  # 1, 2, 4 秒
                await asyncio.sleep(backoff_seconds)
                continue
            else:
                # 最后一次重试失败,返回错误
                return ToolResultBlock(
                    tool_use_id=tool_use.id,
                    content=f"Tool timeout after {max_retries} retries: {str(e)}",
                    is_error=True,
                    error_type="ToolTimeoutError"
                )

        except ToolPermissionError as e:
            # 权限错误:不重试,立即反馈
            return ToolResultBlock(
                tool_use_id=tool_use.id,
                content=f"Permission denied: {str(e)}",
                is_error=True,
                error_type="ToolPermissionError"
            )

        except ToolExecutionError as e:
            # 其他工具错误:重试一次
            if attempt < max_retries - 1:
                continue
            else:
                return ToolResultBlock(
                    tool_use_id=tool_use.id,
                    content=f"Tool execution failed: {str(e)}",
                    is_error=True,
                    error_type=e.error_type
                )

        except Exception as e:
            # 未预期的异常
            return ToolResultBlock(
                tool_use_id=tool_use.id,
                content=f"Unexpected error: {str(e)}",
                is_error=True,
                error_type=type(e).__name__
            )

2. API 调用错误

类型:模型 API 超时、速率限制、认证失败、API 服务中断 影响范围:当前推理轮次 恢复策略:重试或回退到备用模型

3. 输出解析错误

类型:模型输出格式不符、工具参数非法、JSON 解析失败 影响范围:当前推理结果 恢复策略:要求智能体重新生成或修复

4. 上下文溢出与令牌耗尽

类型:消息历史太长、推理输出超过 max_tokens 影响范围:整个会话 恢复策略:清理历史、压缩上下文、或启动新会话

4.4.2 OpenClaw 的“错误即观察”模式

OpenClaw 的设计哲学是 将所有错误作为观察反馈回 Agent

优点:

  • 智能体可以看到所有错误信息,学习如何处理

  • 系统行为更透明、更可预测

  • 智能体可以提出替代方案(例如,文件不存在,试试列出目录)

4.4.3 断路器模式

对于可能频繁失败的外部调用(如模型 API、文件系统操作),使用断路器模式防止级联失败。

错误恢复与断路器状态转移:

图 4-4:断路器状态转移图

4.4.4 本节小结

错误处理是智能体系统可靠性的关键:

  1. 分类处理:不同类型的错误需要不同的恢复策略(重试、降级、打断路器)

  2. 工具执行错误 最常见,应该被作为“观察”反馈给 Agent,而不是中断循环

  3. API 错误 需要重试策略(指数退避、速率限制感知)

  4. 输出解析错误 需要参数验证,防止传递无效的工具调用

  5. 上下文溢出 需要动态压缩和历史管理

  6. 断路器模式 可以防止级联失败和资源耗尽

最后更新于