会话记录损坏

概述

本指南涵盖 OpenClaw 中的会话记录损坏问题,基于 src/agents/session-transcript-repair.ts。Anthropic API 要求工具调用和工具结果之间严格配对。当记录损坏时,自动修复系统会介入。

症状

API 错误

  • 错误消息: "unexpected tool_use_id found in tool_result blocks"
  • Anthropic API 返回 HTTP 400 响应
  • 代理 API 调用立即被拒绝

代理停止响应

  • 代理处理消息但从不响应
  • 用户看不到可见错误
  • 内部日志显示工具结果配对问题

重复工具结果

  • 相同 tool_use_id 多次出现
  • 单个工具调用有多个结果
  • 记录包含冗余条目

孤立工具结果

  • 没有相应工具调用的工具结果消息
  • tool_result 块未紧跟在 assistant 转次之后
  • 会话中存在自由浮动的 toolResult 条目

根本原因

1. 孤立工具结果(第 203-352 行)

工具结果未与其 assistant 工具调用立即配对:

检测逻辑:

// 预期: 带有 toolCall 的 assistant 消息,然后是带有匹配 toolResult 的 user 消息
// 损坏: toolResult 稍后出现或位置错误

常见原因:

  • 会话期间的消息插入/删除
  • 记录的并发修改
  • 消息追加操作失败

修复: 将 toolResult 直接移到匹配的 assistant 转次后

2. 重复工具结果

相同 tool_use_id 出现在多个工具结果中:

检测: 跟踪已见 tool_use_ids,标记重复项 常见原因:

  • 多次追加结果的重试逻辑
  • 消息处理中的竞态条件
  • 手动记录编辑错误

修复: 删除重复的 toolResults,保留第一次出现

3. 自由浮动工具结果

没有任何相应 assistant 工具调用的工具结果:

检测: 孤立的 toolResults 在记录中没有匹配的 tool_use_id 常见原因:

  • 工具调用消息被删除但结果保留
  • 会话历史加载不完整
  • JSONL 序列化期间损坏

修复: 插入带有消息"[openclaw] missing tool result in session history..."的合成错误 toolResult

4. 不完整工具调用(第 250-263 行)

stopReason 为"error"或"aborted"的 assistant 消息包含部分工具调用:

检测逻辑:

if (msg.role === "assistant" &&
    (msg.stopReason === "error" || msg.stopReason === "aborted")) {
  // 跳过工具调用提取 - 这些是不完整的
  continue;
}

常见原因:

  • 工具调用生成期间的 LLM API 错误
  • 流式传输期间用户或系统中止
  • 响应中途网络超时

修复: 跳过工具调用提取,不期望 toolResult

恢复机制

自动修复系统

repairToolUseResultPairing() 函数实现全面修复: