0

ch-14

约 15000 字DraftOpenClaw Book

第 14 章 · 性能优化与调试

每条消息都有成本,每次 API 调用都有延迟。性能优化不是"让系统跑得更快"——而是"用最少的 Token 和最少的 API 调用做最多的事"。

本章你将学到:

  • 理解 Token 计费模型和成本追踪
  • 掌握 Prompt Caching 的配置和调优策略
  • 学会压缩和剪裁策略以管理上下文窗口
  • 掌握系统化的调试工作流
  • 能排查常见性能问题

14.1 Token 和成本:你到底在为什么付钱

14.1.1 什么是 Token

OpenClaw 按 Token 计费,不是按字符。大多数 OpenAI 风格的模型,英文大约 4 个字符 = 1 个 Token。中文通常 1-2 个字符 = 1 个 Token。

14.1.2 上下文窗口里有什么

每次调用模型 API,以下所有内容都计入上下文限制:

┌─────────────────────────────────────────────────────┐
│                  上下文窗口组成                      │
├─────────────────────────────────────────────────────┤
│ 系统提示词                                          │
│ ├── 工具列表 + 工具 Schema(JSON 定义)           │
│ ├── 技能列表(名称 + 描述,指令按需加载)           │
│ ├── 工作空间文件(AGENTS/SOUL/TOOLS/IDENTITY/USER) │
│ ├── 时间信息(UTC + 用户时区)                     │
│ ├── 运行时元信息(主机/OS/模型/思考模式)           │
│ └── 自更新指令、回复标签、心跳行为                   │
├─────────────────────────────────────────────────────┤
│ 对话历史                                            │
│ ├── 用户消息 + 助手消息                            │
│ ├── 工具调用 + 工具结果                           │
│ └── 附件(图片/音频/文件)                          │
├─────────────────────────────────────────────────────┤
│ 压缩摘要(如果触发了压缩)                            │
├─────────────────────────────────────────────────────┤
│ 剪裁残留(如果触发了剪裁)                            │
└─────────────────────────────────────────────────────┘

关键洞察:系统提示词是"固定成本"——它每次请求都会发送,但内容变化很少。对话历史是"增长成本"——随着对话进行越来越大。工具结果是"爆发成本"——Agent 调用工具时,结果可能非常大。

14.1.3 成本追踪

OpenClaw 提供多层成本追踪:

聊天内

/status          → 状态卡片,含上下文使用量和最近回复的 Token 数
/usage tokens    → 每条回复末尾追加 Token 用量
/usage full      → 每条回复末尾追加 Token 用量 + 估算成本
/usage cost      → 本地成本汇总

CLI

openclaw status --usage     # Provider 配额窗口
openclaw channels list      # 含用量快照

成本估算来源:OpenClaw 从模型定价配置中读取:

{
  models: {
    providers: {
      anthropic: {
        models: [{
          id: "claude-sonnet-4-6",
          cost: {
            input: 3.0,      // $3/1M input tokens
            output: 15.0,    // $15/1M output tokens
            cacheRead: 0.3,  // $0.3/1M cached reads
            cacheWrite: 3.75 // $3.75/1M cache writes
          }
        }]
      }
    }
  }
}

💡 提示:OAuth 认证不显示美元成本(只显示 Token),因为 OAuth 用户的计费模型不同。

14.1.4 哪些功能会消耗 API 费用

功能 消耗什么 备注
核心模型回复 主要成本 每次回复/工具调用
媒体理解 音频/图像/视频 API 接收附件时自动触发
记忆语义搜索 Embedding API memorySearch.provider 可配为 local 避免消耗
Web 搜索 Brave/Gemini/Grok API web_search 工具
Web 抓取 Firecrawl API 有 Key 时使用,否则回退到免费抓取
压缩摘要 当前模型 API 压缩前自动触发
Talk 语音 ElevenLabs TTS 语音合成
技能 技能自身的 API Key 第三方技能可能有额外成本

14.2 Prompt Caching:省钱的核心策略

Prompt Caching 是降低 Token 成本的最有效手段——如果系统提示词没有变化,Provider 可以复用之前的计算结果,不需要重新处理。

14.2.1 缓存的工作原理

第一次请求:
  系统提示词(10000 tokens)→ 全部作为 cacheWrite → 全价处理

第二次请求(系统提示词未变):
  系统提示词(10000 tokens)→ 作为 cacheRead → 1/10 的价格
  新的用户消息(200 tokens)→ 全价处理

节省:10000 tokens × (1 - cacheRead/input 比率)

以 Anthropic 为例,cacheRead 的价格大约是 input 的 1/10。如果你的系统提示词占 10000 tokens,每轮对话能省约 $0.027。

14.2.2 cacheRetention 配置

{
  agents: {
    defaults: {
      models: {
        "anthropic/claude-opus-4-6": {
          params: {
            cacheRetention: "long"  // none | short | long
          }
        }
      }
    }
  }
}
Anthropic TTL 适用场景
none 无缓存 突发通知型 Agent
short 5 分钟 交互式对话(默认)
long 1 小时 长对话、研究型 Agent

每个 Agent 可以独立覆盖

{
  agents: {
    list: [
      { id: "research", heartbeat: { every: "55m" } },
      { id: "alerts", params: { cacheRetention: "none" } }
    ]
  }
}

配置合并顺序:

  1. agents.defaults.models["provider/model"].params
  2. agents.list[].params(按 Agent ID 匹配,按键覆盖)

14.2.3 缓存 + 心跳:保持缓存温暖

Prompt Cache 有 TTL——超过 TTL 后缓存失效,下次请求需要重新写入。如果 Agent 在 TTL 后才收到消息,会触发一次昂贵的 cacheWrite。

解决:用心跳保持缓存"温暖":

{
  agents: {
    defaults: {
      models: {
        "anthropic/claude-opus-4-6": {
          params: { cacheRetention: "long" }
        }
      },
      heartbeat: {
        every: "55m"  // 在 1h TTL 到期前触发
      }
    }
  }
}

心跳会在 TTL 到期前发送一个小请求,刷新缓存时间戳。这样即使用户在 1 小时后才说话,缓存仍然是温暖的。

14.2.4 缓存 + 剪裁:避免重新缓存过期历史

当会话空闲超过 TTL 后,旧的工具结果已经无法缓存了。如果不剪裁它们,下次请求会尝试把全部历史重新缓存——产生巨大的 cacheWrite 成本。

解决:启用 cache-ttl 剪裁模式:

{
  agents: {
    defaults: {
      contextPruning: {
        mode: "cache-ttl",
        ttl: "1h"  // 匹配 cacheRetention 的 TTL
      }
    }
  }
}

这样,TTL 过期后,旧的工具结果会被剪裁掉,下次请求只需要缓存"精简后的历史",大幅降低 cacheWrite 成本。

14.2.5 混合流量模式(推荐)

{
  agents: {
    defaults: {
      model: { primary: "anthropic/claude-opus-4-6" },
      models: {
        "anthropic/claude-opus-4-6": {
          params: { cacheRetention: "long" }
        }
      },
      list: [
        // 主 Agent:长缓存 + 心跳保持温暖
        { id: "research", default: true, heartbeat: { every: "55m" } },
        // 通知 Agent:不缓存(突发流量,缓存命中率低)
        { id: "alerts", params: { cacheRetention: "none" } }
      ]
    }
  }
}

14.2.6 缓存诊断

启用缓存追踪日志来验证缓存是否生效:

{
  diagnostics: {
    cacheTrace: {
      enabled: true,
      filePath: "~/.openclaw/logs/cache-trace.jsonl",
      includeMessages: false  // 减少日志体积
    }
  }
}

或者通过环境变量一次性启用:

OPENCLAW_CACHE_TRACE=1 openclaw gateway run

查看日志中的 cacheReadcacheWrite 字段。如果大多数轮次都有高 cacheWrite 而低 cacheRead,说明系统提示词有不稳定的内容,需要排查。

14.2.7 Provider 支持

Provider 缓存支持 备注
Anthropic (直接 API) 默认 short
Amazon Bedrock (Anthropic) 非 Anthropic 模型强制 none
OpenRouter (Anthropic) 注入 cache_control 标记
其他 Provider cacheRetention 无效

14.3 降低 Token 压力的实用策略

14.3.1 手动压缩

/compact                              # 使用默认策略压缩
/compact 重点关注决策和未解决的问题  # 自定义压缩指令

14.3.2 控制图片 Token 消耗

图片是 Token 消耗的大头。OpenClaw 在发送给模型前会自动缩放图片:

{
  agents: {
    defaults: {
      imageMaxDimensionPx: 1200  // 默认 1200
    }
  }
}
  • 降低值(如 800):减少 Vision Token 消耗,适合截图类场景
  • 提高值(如 1568):保留更多细节,适合 OCR 和 UI 分析

14.3.3 精简工作空间文件

系统提示词中注入的工作空间文件是"固定成本"。每减少 1000 字符的 SOUL.md,每轮对话省约 250 Token。

# 查看当前注入文件大小
openclaw config get agents.defaults.bootstrapMaxChars
# 输出:20000(单个文件最大字符数)

openclaw config get agents.defaults.bootstrapTotalMaxChars
# 输出:150000(所有注入文件总最大字符数)

14.3.4 精简技能描述

技能列表会注入到系统提示词中(虽然技能指令是按需加载的)。每个技能的名称和描述都会占用 Token。

保持技能描述简短——10-20 个字比 100 个字好。

14.3.5 选对模型

不是所有任务都需要 Opus。探索性、试错型任务用 Sonnet 甚至 Mini:

{
  agents: {
    list: [
      { id: "research", model: { primary: "anthropic/claude-opus-4-6" } },
      { id: "quick", model: { primary: "anthropic/claude-sonnet-4-6" } }
    ]
  }
}

14.3.6 Anthropic 1M 上下文

Anthropic 的 1M 上下文窗口目前是 Beta 功能,需要额外启用:

{
  agents: {
    defaults: {
      models: {
        "anthropic/claude-opus-4-6": {
          params: { context1m: true }
        }
      }
    }
  }
}

前提条件:API Key 必须有长上下文访问权限。否则会收到 HTTP 429: rate_limit_error: Extra usage is required for long context requests

⚠️ 注意:OAuth 认证(sk-ant-oat-*)目前不支持 context-1m beta header。OpenClaw 会自动跳过。

14.4 调试工作流

14.4.1 调试命令梯子

当 OpenClaw 出问题时,按这个顺序执行:

# 第 1 步:快速状态
openclaw status

# 第 2 步:完整诊断(可粘贴分享)
openclaw status --all

# 第 3 步:Gateway 可达性
openclaw gateway probe

# 第 4 步:Gateway 服务状态
openclaw gateway status

# 第 5 步:配置和修复
openclaw doctor

# 第 6 步:通道健康
openclaw channels status --probe

# 第 7 步:实时日志
openclaw logs --follow

"正常"的输出标准

  • openclaw status → 显示已配置通道,无明显的认证错误
  • openclaw gateway probeReachable: yes
  • openclaw gateway statusRuntime: running + RPC probe: ok
  • openclaw doctor → 无阻塞的配置/服务错误
  • openclaw channels status --probe → 通道显示 connectedready

14.4.2 按症状排查

问题 1:Agent 不回复

常见日志签名:

  • drop guild message (mention required → Discord 群聊中需要 @Agent
  • pairing request → 发送者未通过配对
  • blocked / allowlist → 发送者被过滤
openclaw pairing list --channel <channel>
openclaw logs --follow

问题 2:Dashboard/Control UI 无法连接

常见日志签名:

  • device identity required → 非安全上下文无法完成设备认证
  • AUTH_TOKEN_MISMATCH → Token 不匹配或过期
  • gateway connect failed: → URL/端口错误

问题 3:Gateway 无法启动

常见日志签名:

  • Gateway start blocked: set gateway.mode=local → 未配置 Gateway 模式
  • refusing to bind gateway ... without auth → 非回环绑定但无认证
  • EADDRINUSE → 端口被占用

问题 4:通道已连接但消息不流通

常见日志签名:

  • mention required → 群聊 @提及检查阻止了处理
  • not_in_channel / 401/403 → 通道权限问题

问题 5:Cron 或心跳未触发

常见日志签名:

  • cron: scheduler disabled → Cron 被禁用
  • heartbeat skipped + reason=quiet-hours → 在静默时段外
  • requests-in-flight → 主通道繁忙,心跳被延迟

问题 6:Node 配对但工具失败

常见日志签名:

  • NODE_BACKGROUND_UNAVAILABLE → Node 应用不在前台
  • *_PERMISSION_REQUIRED → OS 权限被拒绝
  • SYSTEM_RUN_DENIED: allowlist miss → 命令不在白名单中

问题 7:浏览器工具失败

常见日志签名:

  • Failed to start Chrome CDP on port → 浏览器启动失败
  • browser.executablePath not found → 配置的浏览器路径错误

14.4.3 /debug 运行时覆盖

/debug 允许你在不修改配置文件的情况下临时修改运行时配置。需要先启用:

{
  commands: {
    debug: true
  }
}
/debug show                                  # 查看当前覆盖
/debug set messages.responsePrefix="[test]"  # 设置覆盖
/debug unset messages.responsePrefix         # 移除覆盖
/debug reset                                 # 清除所有覆盖

14.4.4 开发者调试工具

Dev Profile

# 全局 --dev:隔离状态到 ~/.openclaw-dev,端口偏移到 19001
openclaw --dev gateway run

# Gateway --dev:自动创建最小配置和工作空间
openclaw gateway --dev --reset

Dev 模式会:

  • 跳过 BOOTSTRAP.md
  • 跳过通道 Provider
  • 使用默认身份(C3-PO)

原始流日志

# 记录模型的原始输出(在过滤/格式化之前)
openclaw gateway run --raw-stream

# 指定输出路径
openclaw gateway run --raw-stream --raw-stream-path ~/.openclaw/logs/raw-stream.jsonl

这最适合排查"推理泄露"(reasoning leakage)问题——你可以看到模型原始输出中是否混入了推理内容。

⚠️ 安全警告:原始流日志包含完整的提示词、工具输出和用户数据。调试完毕后立即删除,分享前先脱敏。

Gateway Watch 模式(源码安装):

pnpm gateway:watch

文件变更后自动重启 Gateway,适合快速迭代。

14.5 诊断标志(Diagnostics Flags)

当你需要针对特定子系统调试时,全局 --verbose 太嘈杂了。诊断标志让你精确控制哪些子系统输出调试日志:

{
  diagnostics: {
    flags: ["telegram.http", "gateway.*"]
  }
}

支持的通配符:

  • telegram.* → 匹配 telegram.httptelegram.payload
  • gateway.* → 匹配所有 Gateway 子系统
  • * → 启用所有标志

通过环境变量一次性启用(无需修改配置):

OPENCLAW_DIAGNOSTICS=telegram.http,gateway.session openclaw gateway run

禁用所有诊断标志:

OPENCLAW_DIAGNOSTICS=0

日志位置

/tmp/openclaw/openclaw-YYYY-MM-DD.log

或自定义路径(通过 logging.file 配置)。

查看诊断日志

# 找到最新的日志文件
ls -t /tmp/openclaw/openclaw-*.log | head -n 1

# 过滤特定标志
rg "telegram http error" /tmp/openclaw/openclaw-*.log

# 实时跟踪
tail -f /tmp/openclaw/openclaw-$(date +%F).log | rg "telegram http error"

14.6 Transcript Hygiene:Provider 兼容性

OpenClaw 在每次构建模型上下文之前,会自动对转录(Transcript)进行"卫生清理"——不同 Provider 有不同的格式要求,清理规则也不同:

14.6.1 通用规则

图片清理:所有 Provider 都会自动缩放过大的 base64 图片,防止 Provider 侧拒绝。

畸形工具调用清理:缺少 inputarguments 的助手工具调用块会被丢弃。

14.6.2 Provider 特定规则

Provider 额外清理
OpenAI 清理孤立的推理签名
Google/Gemini 工具调用 ID 严格字母数字化;工具结果配对修复;轮次验证
Anthropic 工具结果配对修复;合并连续用户轮次
Mistral 工具调用 ID 严格 9 位字母数字

这些清理都是内存中的,不会修改磁盘上的 JSONL 转录文件。但如果转录文件本身有损坏,OpenClaw 会在加载前修复(原文件会被备份)。

14.6.3 跨会话来源标记

当 Agent 通过 sessions_send 将消息路由到另一个会话时,OpenClaw 会标记:

{
  "role": "user",
  "message": "...",
  "provenance": { "kind": "inter_session" }
}

在上下文重建时,这些消息前会加上 [Inter-session message] 标记,让模型能区分"用户说的"和"另一个 Agent 路由的"。

14.7 常见问题速查

14.7.1 Anthropic 429:长上下文需要额外用量

HTTP 429: rate_limit_error: Extra usage is required for long context requests

原因:API Key 没有长上下文访问权限。

解决

  1. 在 Anthropic Console 中启用 Extra Usage
  2. 或者移除 context1m: true 配置

14.7.2 上下文接近上限

现象:Agent 回复越来越慢,或者频繁触发压缩。

解决

  1. /compact 手动压缩
  2. 降低 imageMaxDimensionPx
  3. 精简工作空间文件
  4. 考虑启用 cache-ttl 剪裁

14.7.3 缓存命中率低

现象/usage full 显示每轮都有高 cacheWrite

排查

  1. 启用 diagnostics.cacheTrace 查看详细日志
  2. 检查是否有动态内容注入到系统提示词中
  3. 确认 cacheRetention 值与 Provider 支持匹配
  4. 确认模型 Key 匹配 agents.defaults.models 中的配置

14.7.4 端口冲突

EADDRINUSE: address already in use :::18789

解决

# 查看谁占用了端口
lsof -i :18789

# 杀掉旧进程
openclaw gateway stop

# 或者用 --force 强制接管
openclaw gateway run --force

本章小结

  • Token 是计费单位,上下文窗口中的所有内容都计入
  • Prompt Caching 是降低成本的核心策略——Anthropic cacheRead 价格约为 input 的 1/10
  • cacheRetention 控制 TTL(none/short/long),cache-ttl 剪裁避免重新缓存过期历史
  • 心跳保持缓存温暖——在 TTL 到期前触发请求
  • 混合流量模式:长对话用 long 缓存,通知型 Agent 用 none
  • 降低 Token 压力:手动压缩、控制图片大小、精简工作空间文件、选对模型
  • 调试命令梯子:status → gateway probe → gateway status → doctor → channels status → logs
  • /debug 提供运行时配置覆盖,无需修改配置文件
  • 原始流日志(--raw-stream)是排查推理泄露的最佳工具
  • 诊断标志(diagnostics.flags)提供子系统级别的精确调试日志
  • Transcript Hygiene 自动处理不同 Provider 的格式要求

下一步

掌握了性能优化和调试,你已经具备了运维 OpenClaw 的完整技能。但到目前为止,我们一直在"使用"OpenClaw——接下来进入专家篇,深入源码理解 OpenClaw 是如何工作的,掌握高级 Agent 设计模式,开发自己的插件,最终构建基于 OpenClaw 的商业产品。