Carry の Blog Carry の Blog
首页
  • Nginx
  • Prometheus
  • Iptables
  • Systemd
  • Firewalld
  • Docker
  • Sshd
  • DBA工作笔记
  • MySQL
  • Redis
  • TiDB
  • Elasticsearch
  • OpenClaw
  • Hermes Agent
  • Claude Code
  • MySQL8-SOP手册
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Carry の Blog

好记性不如烂键盘
首页
  • Nginx
  • Prometheus
  • Iptables
  • Systemd
  • Firewalld
  • Docker
  • Sshd
  • DBA工作笔记
  • MySQL
  • Redis
  • TiDB
  • Elasticsearch
  • OpenClaw
  • Hermes Agent
  • Claude Code
  • MySQL8-SOP手册
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • OpenClaw

    • OpenClaw 实战 01|总览:一个 config 驱动、会自己做梦的 Agent 工作区
    • OpenClaw 实战 02|定时任务:Heartbeat vs Cron,与那个 approve 救不了的死循环
    • OpenClaw 实战 03|架构:3 种部署形态 + Gateway 双 Token + 5 类对接链路
    • OpenClaw 实战 04|配置管理:双层模型注册 + Token 双源 + 4 处真实陷阱
    • OpenClaw 实战 05|安全边界:SSRF 策略、设备 scope、与会脑补截图的模型
    • OpenClaw 实战 06|性能优化:上下文压缩、内存压力、冷启动的先 profile 原则
      • §1 那个对话越久越蠢的 Agent
      • §2 先 profile,再优化(铁律)
      • §3 慢之一:上下文压缩(OpenClaw 最该调的旋钮)
      • §4 慢之二:内存压力
      • §5 慢之三:冷启动与工具往返
      • §6 反模式
      • §7 复用规则(一句话带走)
      • §8 下一篇
      • §9 Agent 可直接解析的元数据块
    • OpenClaw 实战 07|部署指南:3 形态决策树 + OpenWebUI 接入 + FreshRSS 跨实例
    • OpenClaw 实战 08|故障排除:Token Mismatch + SSRF 死循环 + "部分存活"假象
    • OpenClaw 实战 09|监控告警:7 个真正有用的信号与告警噪声治理
    • OpenClaw 实战 10|扩展开发:Skill / Tool / Plugin 区分 + 完整安装流程 + 链路证伪调优
    • OpenClaw 实战 11|最佳实践:10 条从真实翻车提炼的 SOP + 推送二次确认硬规则
  • Hermes-Agent

  • Claude-Code

  • AI-Agent
  • OpenClaw
Carry の Blog
2026-06-27
目录

OpenClaw 实战 06|性能优化:上下文压缩、内存压力、冷启动的先 profile 原则原创

# 性能优化:上下文压缩、内存压力、冷启动的先 profile 原则

这一篇只讲 OpenClaw 特有的三类慢——长对话"变蠢"、内存压力、skill/模型冷启动——以及一条铁律:没 profile 过就动手优化,比不优化更糟。

先纠正一个常见误判:OpenClaw 是 Node / pnpm 应用(openclaw.mjs,nvm v22),不是 Python。所以 py-spy 那套用不上,profiling 走 Node 的工具链(node --inspect、clinic、0x)。下面三类慢,前两类是 OpenClaw 自己的机制问题,第三类才是通用资源问题。


# §1 那个对话越久越蠢的 Agent

集成了一个自托管 MoE 模型后,OpenClaw 在短对话里好好的,一旦聊过几十轮就明显"变蠢"——开始答错前面问过的简单问题、丢上下文。

第一反应是"模型不行"。但换小任务又正常。最后定位到的根因,不在模型,在 OpenClaw 的上下文压缩阈值设得太高:模型宣称的 contextWindow 很大,但它实际有效的稳定窗口远小于此,OpenClaw 却按宣称值才触发压缩——于是对话长了之后,模型一直在自己的"不稳定区"里跑。

这件事是本文的引子:OpenClaw 的"慢/差"经常不是资源问题,是它的上下文管理机制和你的模型不匹配。 而要确认是哪一类,得先 profile。


# §2 先 profile,再优化(铁律)

没 profile 的优化是赌博。 我亲手浪费过两次:先给 sqlite 加索引(只省 5%),又上 Redis 缓存 skill 列表(每次状态变更就要 invalidate,毫无意义)——因为我跳过 profile 就动手了。

OpenClaw 一次"慢",先分清时间花在三段的哪一段:

用户发消息
  │
  ├─[A] 冷启动 / skill 加载 / 模型首字 ── 启动开销
  │
  ├─[B] 上下文组装 + 压缩 ───────────── OpenClaw 机制开销
  │
  └─[C] 推理 + 工具往返 ─────────────── 模型/网络开销
1
2
3
4
5
6
7

最简单的分段法:time 一个端到端动作,再对照日志时间戳看慢在哪段。别一上来就缓存/加索引——先知道堵在 A、B 还是 C。


# §3 慢之一:上下文压缩(OpenClaw 最该调的旋钮)

这是 OpenClaw 区别于"调 Linux"的地方。它有一套**主动压缩(preemptive compaction)**机制:上下文逼近阈值时自动压缩历史,腾出空间。两个关键旋钮:

  • contextWindow:OpenClaw 认为这个模型能吃多少 token。
  • reserveTokens(或 reserve floor):留多少余量时触发主动压缩。

§1 的修法:把 contextWindow 下调到模型实际稳定的窗口,让压缩更早触发,模型始终在稳定区工作:

{
  "models": {
    "providers": {
      "<provider>": {
        "<model-id>": {
          "contextWindow": 110000,   // 从模型宣称的超大值下调到实际稳定窗口(示例值,按你的模型实测调)
          "reserveTokens": 20000     // 留足余量,更早触发主动压缩
        }
      }
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12

复用规则:MoE / 激活参数小的模型,别信它宣称的 contextWindow——按实际推理质量下调,并靠主动压缩把长对话钉在稳定区。判断"是不是压缩问题"很简单:短对话好、长对话差 → 几乎肯定是它。

这属于 models.providers 配置,改完要重启(不是热重载)。


# §4 慢之二:内存压力

OpenClaw 长期运行 + 多模型 + 容器 cgroup 限制下,内存压力很常见。好消息是它自己会在日志里喊:

# 容器(supervisor)
grep "memory pressure" /var/log/supervisor/openclaw.log | tail
# 裸机(systemd)
journalctl --user -u openclaw-gateway | grep "memory pressure"
1
2
3
4

看到 memory pressure 比盯 RSS 数字更直接——这是 OpenClaw 主动告诉你"我开始吃紧了"。两类常见来源和对策:

  • 宿主/容器内存真不够 → 提 cgroup 限额,或减少同时挂载的模型角色(imageModel/reasoningModel 都各自占资源)。
  • NAS 上 swap 被无谓换出(物理内存其实够)→ 调 vm.swappiness,让内核别那么激进:
sudo sysctl -w vm.swappiness=10
echo "vm.swappiness=10" | sudo tee /etc/sysctl.d/99-swappiness.conf
1
2

真实案例:某 NAS 上一个 Windows VM 锁死了大半物理内存,宿主侧 Available 其实充足,但 swappiness=60 让内核把不活跃页大量换出,表现成"假性内存紧张"。调到 10 后 swap 自然回落。先确认是真不够还是被换出,再决定加内存还是调参。


# §5 慢之三:冷启动与工具往返

第三类是通用资源问题,但在 OpenClaw 上有几个特定热点:

  • skill 列表冷启动:skill 多了,首次加载有开销。OpenClaw 的设计是只把 description 进上下文、匹配任务才读正文(按需加载),所以别把 skill 的 description 写得又臭又长——那是每次都要付的成本。
  • 模型首字延迟:自托管 vLLM 后端跨网络时,首 token 延迟受网络影响大。用 curl -w 量 TTFB(DNS/connect/TLS/首字)定位是网络还是模型。
  • 工具往返:一次回复 = 模型推理 + 若干工具调用 + 可能的 TTS 合成。openclaw cron runs / trajectory 日志能看到每步耗时,别把工具往返的慢算到模型头上。
# 量端到端 + 首字延迟
time openclaw cron run <monitor-job-id> --wait
curl -w "dns=%{time_namelookup} conn=%{time_connect} ttfb=%{time_starttransfer} total=%{time_total}\n" \
  -o /dev/null -s <你的模型端点>
1
2
3
4

# §6 反模式

反模式 为什么错
没 profile 先加缓存 缓存可能根本没命中(我踩过 Redis 那次)
长对话变差就怪模型 多半是 contextWindow 没下调(§3)
内存一紧张就加内存 可能是 swappiness 把够用的内存换出去了(§4)
把工具往返的慢算到模型 一次回复含多次工具调用,分段看
用 py-spy/memray 调 OpenClaw 它是 Node 不是 Python,工具用错了

# §7 复用规则(一句话带走)

OpenClaw 的慢,先在"冷启动 / 上下文压缩 / 内存压力"三段里定位——长对话变蠢调 contextWindow,内存紧张先看 memory pressure 日志再决定加内存还是调 swappiness。

展开 3 条:

  1. 先 profile 再优化,分清慢在启动、上下文还是推理。
  2. 上下文压缩是 OpenClaw 最该调的旋钮——别信模型宣称的 contextWindow。
  3. 内存看 memory pressure 日志,别盲目加内存;它是 Node,别用 Python 那套 profiler。

# §8 下一篇

下一篇:07|部署指南——容器+supervisor / 裸机+systemd 两套部署的真实配置与端到端验证。


# §9 Agent 可直接解析的元数据块

{
  "_meta": {
    "doc_version": "2026-06-27",
    "article_id": "openclaw-06-performance",
    "profile_context": "any",
    "estimated_read_time": "10min",
    "runtime_fact": "OpenClaw 是 Node/pnpm 应用(openclaw.mjs, nvm v22),不是 Python"
  },
  "three_slowness_classes": {
    "context_compression": {
      "symptom": "短对话正常、长对话变蠢/丢上下文",
      "knobs": ["models.providers.<p>.<model>.contextWindow", "reserveTokens"],
      "fix": "下调 contextWindow 到模型实际稳定窗口,更早触发主动压缩",
      "needs_restart": true
    },
    "memory_pressure": {
      "signal": "grep 'memory pressure' /var/log/supervisor/openclaw.log",
      "fixes": ["提 cgroup 限额/减少模型角色", "vm.swappiness 调低(被换出而非真不足时)"]
    },
    "cold_start": {
      "hotspots": ["skill description 过长(每次都付)", "vLLM 跨网络首字延迟", "工具往返"],
      "measure": "time 端到端 + curl -w TTFB + trajectory 分步耗时"
    }
  },
  "safety_rules": [
    "先 profile 再优化,分清慢在启动/上下文/推理",
    "长对话变蠢先调 contextWindow,不是换模型",
    "内存看 memory pressure 日志,别盲目加内存",
    "OpenClaw 是 Node,别用 py-spy/memray"
  ],
  "anti_patterns": ["没 profile 先加缓存", "长对话差就怪模型", "内存紧就加内存", "工具往返的慢算给模型"],
  "reusable_rule": "在冷启动/上下文压缩/内存压力三段里定位;长对话变蠢调 contextWindow,内存紧先看 memory pressure"
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

AI Agent 使用指南:

  • 当用户说"OpenClaw 对话越久越笨" → §3:下调 contextWindow,更早触发主动压缩
  • 当用户说"OpenClaw 吃内存/变卡" → §4:先 grep memory pressure,再判断加内存还是调 swappiness
  • 当用户说"首次响应很慢" → §5:分清 skill 冷启动、模型首字、工具往返
  • 当用户说"想加缓存优化" → §2:先 profile,没数据不许加
  • 当用户说"用 py-spy 看 OpenClaw" → 纠正:它是 Node,用 node --inspect / clinic / 0x
#OpenClaw#AI Agent#性能优化#上下文压缩#内存压力#冷启动
上次更新: 6/28/2026

← OpenClaw 实战 05|安全边界:SSRF 策略、设备 scope、与会脑补截图的模型 OpenClaw 实战 07|部署指南:3 形态决策树 + OpenWebUI 接入 + FreshRSS 跨实例→

最近更新
01
Hermes Agent 实战 15|告别临时 RAG:用 Karpathy 的 LLM Wiki 给 Agent 装上可生长的长期记忆 原创
06-29
02
OpenClaw 实战 11|最佳实践:10 条从真实翻车提炼的 SOP + 推送二次确认硬规则 原创
06-27
03
OpenClaw 实战 07|部署指南:3 形态决策树 + OpenWebUI 接入 + FreshRSS 跨实例 原创
06-27
更多文章>
Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式