乐于分享
好东西不私藏

按个回车等 18 秒?OpenClaw:这锅模型不背

按个回车等 18 秒?OpenClaw:这锅模型不背

你敲了一句话,按回车——然后盯着进度条等了 18 秒。模型给了句”已为你生成报告”。你心里想:模型是真慢啊。

但你不知道的是:那 18 秒里,模型满打满算只干了 6 秒。剩下 12 秒全花在别的地方。这篇文章就来把这笔账算清楚。

先搞清楚:不是一次模型调用

普通 Agent 的工作流粗暴直接:

用户输入 → 拼 prompt → 调模型 → 返回文本

OpenClaw 的链路要复杂得多——它更像一条管道,消息从一端进去,中间过五关斩六将,最后才出来一个回复。

intake → context assembly → model inference → tool execution → streaming → persistence 接收输入 → 找会话/工作区 → 排队 → 拼上下文 → 调用模型 → 执行工具 → 流式返回 → 写入状态

入口那层活儿,全在水面下

你以为”用户发了条消息”很简单?OpenClaw 的请求可以来自 CLI、Dashboard、HTTP API、企业微信、Telegram、Slack、Webhook、定时任务……Gateway 进来第一件事,就是把这些五花八门的格式全部转成统一的 agent request。

这还没完——入口层还要处理三件隐藏功夫:

场景
问题
OpenClaw 怎么处理
网络重试
同一句话发了两次
根据来源/会话/id 短期去重,避免重复执行
用户连发短句
“看一下后台”“昨天的订单”“退款异常”分三次发
短时间内的连续消息合并成一个 turn
任务进行中用户补充
“只看华东区”是新任务还是当前任务的修正?
followup / steer / collect / interrupt 四种语义
💡 关键:Agent 的”连续协作感”就来自这四种队列语义——只会一问一答和能处理补充/修正/打断/收束的 Agent,差别就在这里。

Session 和 Workspace:不是聊天窗口

消息进来后,Gateway 要回答两个问题:这是谁的请求?它属于哪个运行上下文?

  • Session
    :这次对话能看到哪些历史
  • Workspace
    :工具能读写哪些文件、从哪个目录执行命令
同一句话,在 CLI 说”继续刚才那个修复”,可能看到当前项目的文件和上一次命令输出;在 Telegram 群里说同一句话,如果映射到另一个 session,就未必能看到 CLI 里的历史。

Context 是什么?比你想象的要多

Context 是本次模型调用真正能看到的运行包,每次 run 都会重新组装。它包括:

Context 组成部分
说明
System prompt
Agent 的角色定义和行为规则
Conversation history
本次 session 的历史消息
Tool list & schemas
本轮可调用的工具清单及接口定义
Workspace files
注入的文件内容或路径
Tool calls & results
本轮已发生的工具调用及返回值
Channel context
来源渠道的元信息(channel / account / peer)
Runtime metadata
runId / startedAt / endedAt 等运行时信息
⚠️ 新手最容易搞混的地方:Context ≠ 用户刚发的那句话 ≠ 长期记忆 ≠ 整个 workspace。如果模型没有按预期行动,往往不是模型不聪明,而是 Context 里信息缺失或干扰过多。

工具”装好了”不等于”能用”

排查工具问题时,不要只问”工具在不在机器上”。顺着链路依次确认:

工具类型
需要满足的条件
Browser
浏览器能力可用
Shell
当前运行环境允许命令执行
文件
工作区边界明确
MCP
对应 MCP server 已配置并可用
Plugin
插件启用且权限通过
工具”存在”和”可被本次 run 使用”是两回事。顺着链路确认:工具是否进入上下文?是否能在当前 workspace 执行?结果是否正确回到模型?

模型推理:不只是返回一个答案

模型收到”打开后台检查昨天的异常订单”这类请求时,它会分步推理:需要打开网页 → 需要登录 → 需要筛选数据 → 需要读取表格。于是它请求调用 Browser、Shell、文件或业务插件。

注意:模型本身不会真的打开浏览器——它只产生结构化工具调用请求,真正执行的是 OpenClaw 的工具系统。

模型推理 → 调用工具 → 得到 observation → 模型继续推理 → 再次调用 → 最终回复

这就是 Agent loop 的”loop”——模型和工具之间反复交替,直到任务完成、失败、超时或被中断。

流式返回:不是假进度

OpenClaw 不会等所有事情结束后才给结果。一次 run 过程中,系统持续发出多类事件:

事件类型
内容
你看到的
lifecycle
start / end / error
任务开始/完成/失败提示
assistant
模型文本增量
逐字出现的回复
tool
工具开始/更新/结束
“正在打开页面…” / “正在读取数据…”
usage
token 和成本
隐藏统计,不直接展示

持久化:下次请求全靠它

一次 run 结束后,OpenClaw 要把结果写回系统,包括:

持久化内容
为什么重要
用户消息 + 助手回复
下次请求能看到历史
工具调用记录 + 结果摘要
排错时能看到失败点
runId / startedAt / endedAt
追踪请求生命周期
usage metadata + context report
分析为什么变慢/变贵/超出窗口

排错三连问

① 慢在哪一段?

环节
可能的慢的原因
入口等待
debounce / 消息合并
排队
等待前一个 run 结束
Context 组装
上下文太大 / 文件注入太多
模型推理
模型本身响应慢 / provider 限速
工具执行
浏览器加载 / Shell 超时
持久化
transcript 写入等待锁

② 工具怎么查?

入口是否收到消息?→ Session 是否解析正确?→ 工具是否进入上下文?→ 模型是否发起了调用?→ 参数是否正确?→ 返回了什么错误?→ 错误有没有写入 transcript?

③ Session 是不是对了?

Agent run 的真实结果包括最终回复 + 工具过程 + 错误 + usage + 上下文报告。只看最终回复,很容易错过真正的失败原因。


所以那笔时间账可以算清楚了:入口标准化、Session 解析、队列调度、上下文组装——这些全在模型调用之前发生,每段都可能占时间。OpenClaw 和普通聊天壳子的关键区别,不在于能不能调用模型,而在于能不能把一次请求稳定地接住、执行、观察、恢复和追踪

💬 如果觉得有收获,欢迎在评论区留言交流 👇

作者 · VV · AI 工具 & 技术分享