第 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" } }
]
}
}
配置合并顺序:
agents.defaults.models["provider/model"].paramsagents.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
查看日志中的 cacheRead 和 cacheWrite 字段。如果大多数轮次都有高 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-1mbeta 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 probe→Reachable: yesopenclaw gateway status→Runtime: running+RPC probe: okopenclaw doctor→ 无阻塞的配置/服务错误openclaw channels status --probe→ 通道显示connected或ready
14.4.2 按症状排查
问题 1:Agent 不回复
常见日志签名:
drop guild message (mention required→ Discord 群聊中需要 @Agentpairing 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.http、telegram.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 侧拒绝。
畸形工具调用清理:缺少 input 和 arguments 的助手工具调用块会被丢弃。
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 没有长上下文访问权限。
解决:
- 在 Anthropic Console 中启用 Extra Usage
- 或者移除
context1m: true配置
14.7.2 上下文接近上限
现象:Agent 回复越来越慢,或者频繁触发压缩。
解决:
/compact手动压缩- 降低
imageMaxDimensionPx - 精简工作空间文件
- 考虑启用
cache-ttl剪裁
14.7.3 缓存命中率低
现象:/usage full 显示每轮都有高 cacheWrite。
排查:
- 启用
diagnostics.cacheTrace查看详细日志 - 检查是否有动态内容注入到系统提示词中
- 确认
cacheRetention值与 Provider 支持匹配 - 确认模型 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 的商业产品。