从用户提问到模型响应:OpenClaw全链路调用流程深度拆解

你在终端敲了一个问题,OpenClaw 背后发生了什么?消息怎么从 Channel 流到 Model Router?Agent Session 什么时候创建?Tool 调用又是怎么注入上下文的?

这篇文章把 OpenClaw 的全链路调用流程拆开——从用户输入到模型返回的每一步,消息怎么构造、参数怎么传递、路由怎么做决策。

一、先看全景:一个请求的 7 段旅程

一个请求从用户输入到模型响应的 7 段旅程:

用户输入 "帮我查一下今天的天气"
 │
 ▼
┌─────────────────────────────────────────────────────┐
│ ① Channel 层:消息入口 │
│ Webchat / Telegram / Discord / WhatsApp / CLI │
│ 统一格式化为 OpenClaw Message │
└─────────────────────────────────────────────────────┘
 │
 ▼
┌─────────────────────────────────────────────────────┐
│ ② Gateway 层:核心调度中枢(127.0.0.1:18789) │
│ 会话管理 → 上下文组装 → 路由决策 → 模型调用 │
└─────────────────────────────────────────────────────┘
 │
 ▼
┌─────────────────────────────────────────────────────┐
│ ③ Model Router 层:智能路由 │
│ 规则匹配 / LLM Router → 选 ollama:11434 还是 │
│ api.anthropic.com │
└─────────────────────────────────────────────────────┘
 │
 ▼
┌─────────────────────────────────────────────────────┐
│ ④ Agent Session 层:能力注入 │
│ 加载 SKILL → 注入 System Prompt → 挂载 Tool 列表 │
└─────────────────────────────────────────────────────┘
 │
 ▼
┌─────────────────────────────────────────────────────┐
│ ⑤ Tool Runtime 层:函数调用中转 │
│ 模型请求 tool_call → Runtime 执行 → 结果注入消息链 │
└─────────────────────────────────────────────────────┘
 │
 ▼
┌─────────────────────────────────────────────────────┐
│ ⑥ Model Provider 层:模型推理 │
│ 本地:Ollama / vLLM / llama.cpp │
│ 云端:Anthropic API / OpenAI API / Google AI │
└─────────────────────────────────────────────────────┘
 │
 ▼
┌─────────────────────────────────────────────────────┐
│ ⑦ Response 回流:响应逐层返回 │
│ 模型输出 → Gateway 格式化 → Channel 渲染 → 用户看到 │
└─────────────────────────────────────────────────────┘

二、逐层拆解:每层做什么、参数怎么传

2.1 Channel 层:消息入口

这是用户和 OpenClaw 交互的"门面"。每个 Channel 负责收消息、格式化,但不做任何业务逻辑。

支持的 Channel:
 - CLI(终端直接输入)
 - Webchat(浏览器 WebSocket 连接)
 - Telegram Bot(消息平台)
 - Discord Bot
 - WhatsApp
 - Slack
 - Google Chat
 - Signal
 - iMessage(仅 macOS)

Channel 层的职责:
 1. 接收原始消息(文本 / 图片 / 文件)
 2. 转成统一的 Message 格式
 3. 通过 WebSocket 或 HTTP 发送到 Gateway(127.0.0.1:18789)

消息统一格式

{
 "channel": "webchat",
 "sessionId": "sess_abc123",
 "message": {
 "role": "user",
 "content": "查一下今天北京天气",
 "attachments": []
 },
 "metadata": {
 "platform": "web",
 "timestamp": 1717766400
 }
}

💡 关键洞察:无论从哪个 Channel 进来,到 Gateway 层的消息格式完全一致。这意味着你可以在 Terminal 里开始一段对话,然后在 Telegram 上无缝继续——因为 sessionId 是全局统一的。

2.2 Gateway 层:核心调度中枢

Gateway 是 OpenClaw 的大脑。它驻留为系统守护进程,监听 127.0.0.1:18789,负责所有请求的调度和组装。

Gateway 核心职责:

1. 会话管理(Session Manager):
 - 根据 sessionId 找到或创建会话
 - 加载历史消息
 - 管理上下文窗口

2. 上下文组装(Context Assembler):
 - 将历史消息 + 系统提示词 + 工具定义 拼成完整的 messages 数组
 - 处理上下文截断(超长对话)
 - 注入记忆系统数据

3. 路由决策(Model Router):
 - 调用 Model Router 决定用哪个模型
 - 可能启用分层路由(小模型判简单/复杂 → 分发给对应模型)

4. 请求发送(Provider Adapter):
 - 将统一格式的消息转为具体 Provider 的 API 格式
 - 处理流式/非流式响应

Gateway 内部状态机

Gateway 处理一个请求的状态转换:

IDLE → RECEIVED → CONTEXT_ASSEMBLY → ROUTING → CALLING → STREAMING → DONE
 ↓
 TOOL_DETECTED
 ↓
 TOOL_EXECUTION → CONTEXT_ASSEMBLY(循环)

2.3 Model Router 层:智能路由

这是 OpenClaw 区别于直接用 API 的核心差异。Router 决定"这个问题谁来回答"。

路由策略一:静态规则路由

{
 "routing": [
 {"patterns": ["hello", "hi", "thanks"], "model": "ollama/qwen2.5:0.5b"},
 {"patterns": ["code", "bug", "error", "fix"], "model": "ollama/qwen2.5-coder:14b"},
 {"patterns": ["analyze", "design", "architecture"], "model": "anthropic/claude-sonnet-4-5"},
 {"default": "ollama/llama3.1:8b"}
 ]
}

工作原理:用户输入 → 按顺序匹配 patterns → 命中则路由到对应模型 → 未命中用 default

路由策略二:LLM Router(智能路由)

工作原理:
 1. 用户输入进入后,先用一个小模型(如 qwen2.5:0.5b)做分类
 2. 分类结果:
 SIMPLE → 本地小模型直接回答(< 100ms)
 MEDIUM → 本地中等模型(如 qwen2.5:14b)
 COMPLEX → 云端强模型(Claude/GPT)
 REASONING → 云端推理模型(o3/Claude Opus)
 3. 复杂问题自动升级,简单问题本地省钱

收益:
 - 40-80% 的请求由本地模型处理
 - 云端费用大幅降低
 - 简单问题秒回(本地推理 0 网络延迟)

路由决策的输入参数

Router 做决策时参考的信息:
 1. 用户输入文本(正则匹配 or LLM 分类)
 2. 上下文长度(长上下文可能触发路由升级)
 3. 历史工具调用次数(频繁调工具 → 路由到更强模型)
 4. 用户偏好设置(某些用户强制用特定模型)
 5. 当前各 Provider 的可用性和延迟

2.4 Agent Session 层:能力注入

确定用哪个模型后,Gateway 给这次请求"装配武器"——注入 System Prompt、挂载 Tool 定义、加载 SKILL。

Agent Session 组装过程:

Step 1:加载 System Prompt
 ├── 基础 System Prompt(OpenClaw 内置)
 ├── 用户自定义 CLAUDE.md / openclaw.md
 └── 会话级 Instructions

Step 2:挂载 Tool 列表
 ├── 内置 Tools(文件读写、Shell 执行、网络请求)
 ├── MCP Server 注册的 Tools
 └── SKILL 定义的 Tools

Step 3:注入上下文
 ├── 历史消息(从 Session Manager 读取)
 ├── Memory 数据(长期记忆)
 └── RAG 检索结果(如有)

最终 messages 数组结构:

[
 {"role": "system", "content": "你是OpenClaw AI助手..." + user_instructions},
 {"role": "user", "content": "上次对话的摘要..."},
 {"role": "user", "content": "历史消息1"},
 {"role": "assistant", "content": "历史回复1"},
 {"role": "user", "content": "查一下今天北京天气"}
]

Tool 定义注入示例

{
 "messages": [],
 "tools": [
 {
 "type": "function",
 "function": {
 "name": "get_weather",
 "description": "获取指定城市实时天气",
 "parameters": {
 "type": "object",
 "properties": {
 "city": {"type": "string"}
 },
 "required": ["city"]
 }
 }
 },
 {
 "type": "function",
 "function": {
 "name": "read_file",
 "description": "读取文件内容",
 "parameters": {}
 }
 }
 ]
}

2.5 Tool Runtime 层:函数调用中转

当模型返回 finish_reason: "tool_calls" 时,Tool Runtime 接手执行。

Tool Runtime 工作流:

1. 解析 tool_calls
 模型返回:
 {
 "tool_calls": [{
 "id": "call_abc",
 "function": {"name": "get_weather", "arguments": '{"city":"北京"}'}
 }]
 }

2. 匹配 Tool 实现
 从注册的 Tool Registry 中找到 get_weather 的实现

3. 权限检查
 是否需要用户确认?(如 Shell 执行、文件删除)
 是否在 allow-list 中?

4. 执行 Tool
 调用实际的 Tool 函数 → 获取结果

5. 将结果注入 messages
 messages.push({role: "assistant", tool_calls: [...]})
 messages.push({role: "tool", tool_call_id: "call_abc", content: '{"temp":28,"condition":"晴"}'})

6. 重新发送请求
 更新后的 messages → 再次调用 Provider

💡 关键洞察:Tool Runtime 不关心模型具体是谁。它从模型拿到 tool_calls → 执行函数 → 把结果塞回 messages → 再调模型。这个循环对 Anthropic、OpenAI、Ollama 全部通用——Provider Adapter 负责翻译 API 格式差异。

2.6 Model Provider 层:模型推理

Provider Adapter 把 OpenClaw 的统一格式翻译成各 Provider 的原生 API 格式。

支持的 Provider:

本地:
 ollama/* → http://localhost:11434/api/chat
 vllm/* → http://localhost:8000/v1/chat/completions
 llama.cpp/* → http://localhost:8080/completion
 openai/* → 可指向任何 OpenAI 兼容的本地服务

云端:
 anthropic/* → https://api.anthropic.com/v1/messages
 openai/* → https://api.openai.com/v1/chat/completions
 google/* → Google AI API
 groq/* → Groq API
 deepseek/* → DeepSeek API
 xai/* → xAI (Grok) API
 mistral/* → Mistral API

Provider Adapter 的核心任务

OpenClaw 统一格式 → 各 Provider 原生格式的翻译:

1. messages 格式转换
 OpenClaw 内部有统一的 Message 结构
 → Anthropic 要转成 {"role": "user", "content": [...]}
 → OpenAI 要转成 {"role": "user", "content": "..."}
 → Ollama 要转成 {"role": "user", "content": "..."}

2. Tool 定义转换
 OpenClaw 内部 Tool Schema
 → Anthropic: tools: [{type, name, description, input_schema}]
 → OpenAI: tools: [{type: "function", function: {name, description, parameters}}]

3. Tool 结果重注入
 各 Provider 的 tool_calls 格式不同,统一解析后塞回 messages

4. 流式/非流式适配
 部分 Provider 不支持流式 → Adapter 做降级处理

一次实际调用的参数映射

{
 "openclaw_internal": {
 "model": "anthropic/claude-sonnet-4-5",
 "temperature": 0.7,
 "max_tokens": 4096,
 "messages": []
 },
 "anthropic_api": {
 "method": "POST",
 "url": "https://api.anthropic.com/v1/messages",
 "body": {
 "model": "claude-sonnet-4-5-20250514",
 "max_tokens": 4096,
 "temperature": 0.7,
 "system": "(从 messages[0].role='system' 提取)",
 "messages": "(去掉 system 消息后剩下的)",
 "tools": []
 }
 },
 "ollama_api": {
 "method": "POST",
 "url": "http://localhost:11434/api/chat",
 "body": {
 "model": "llama3.1:8b",
 "messages": "(保留 system 消息)",
 "options": {
 "temperature": 0.7,
 "num_predict": 4096
 },
 "stream": true
 }
 }
}

2.7 Response 回流:逐层返回

模型响应是一条"回头路",每层都可能做加工。

响应回流路径:

Provider 原始响应
 → Provider Adapter 统一格式化(去除 Provider 特定字段)
 → Gateway 做后处理(提取 tool_calls、检测 finish_reason)
 → Session Manager 存历史消息
 → Channel 适配格式化(Webchat 拼 HTML,Telegram 转 Markdown)
 → 用户看到最终回复

流式模式下每层的处理:

Provider 逐 token 输出
 → Adapter 逐 chunk 转统一格式
 → Gateway 实时转发
 → Channel 实时渲染(打字机效果)

三、一次完整的多轮 Tool Calling 调用示例

用一个实际例子串起全链路。用户问"帮我查北京天气,然后写个简短出行建议"。

第 1 轮:初始请求

① Channel:用户输入进入 Webchat

② Gateway 组装上下文:
 messages: [
 {role: "system", content: "你是OpenClaw助手..."},
 {role: "user", content: "帮我查北京天气,然后写个出行建议"}
 ]

③ Router 决策:用 anthropic/claude-sonnet-4-5(有工具调用需求)

④ 请求发送到 Anthropic API:
 POST /v1/messages
 {
 model: "claude-sonnet-4-5-20250514",
 system: "...",
 messages: [{role: "user", content: "..."}],
 tools: [
 {name: "get_weather", ...},
 {name: "web_search", ...}
 ],
 max_tokens: 4096
 }

⑤ 模型返回:
 {
 stop_reason: "tool_use",
 content: [{
 type: "tool_use",
 name: "get_weather",
 input: {city: "北京"}
 }]
 }

⑥ Tool Runtime 执行 get_weather("北京")
 返回:{temp: 28, condition: "晴", humidity: "45%"}

⑦ Tool Runtime 将结果注入 messages

第 2 轮:携带工具结果的续写

⑧ Gateway 重新组装 messages:
 messages: [
 {role: "system", content: "你是OpenClaw助手..."},
 {role: "user", content: "帮我查北京天气,然后写个出行建议"},
 {role: "assistant", content: [{type: "tool_use", name: "get_weather", input: {city: "北京"}}]},
 {role: "user", content: [{type: "tool_result", content: '{"temp":28,"condition":"晴"}'}]}
 ]

⑨ 再次调 Anthropic API → 模型生成自然语言回复

⑩ 响应回流:
 Provider → Adapter → Gateway → Channel → 用户看到:
 "北京今天晴天,28°C,湿度45%。建议穿短袖,带把遮阳伞"

四、配置示例:一图看清参数在哪设

openclaw 配置位置:

全局配置:~/.openclaw/openclaw.json
项目配置:<project>/.openclaw/openclaw.json
环境变量:OPENCLAW_* 系列

配置优先级:环境变量 > 项目配置 > 全局配置 > 默认值

典型生产配置

{
 "gateway": {
 "bind": "loopback",
 "port": 18789
 },
 "agents": {
 "defaults": {
 "model": {
 "primary": "anthropic/claude-sonnet-4-5",
 "routing": {
 "enabled": true,
 "router": {
 "model": "ollama/qwen2.5:0.5b",
 "rules": {
 "alwaysPrimary": {
 "patterns": ["analyze", "explain", "design", "debug", "fix"]
 },
 "alwaysLocal": {
 "patterns": ["hello", "hi", "thanks", "ok", "yes", "no"]
 }
 }
 }
 },
 "fallback": "ollama/llama3.1:8b"
 },
 "maxTokens": 4096,
 "temperature": 0.7
 }
 },
 "tools": {
 "mcpServers": [
 {
 "name": "filesystem",
 "command": "npx",
 "args": ["-y", "@anthropic-ai/mcp-server-filesystem", "/Users/me/projects"]
 }
 ],
 "confirmBeforeRun": ["shell", "file_write", "file_delete"]
 },
 "channels": {
 "telegram": {"enabled": true},
 "discord": {"enabled": false}
 }
}

五、一张图总结全链路

层次 职责 核心组件
① Channel 消息入口,统一格式化 Webchat / Telegram / CLI / Discord
② Gateway 核心调度中枢 Session Manager + Context Assembler
③ Model Router 智能路由,选模型 规则匹配 / LLM Router
④ Agent Session 能力注入 System Prompt + Tools + SKILL
⑤ Tool Runtime 函数调用中转 Tool Registry + 权限检查
⑥ Model Provider 模型推理 Provider Adapter(格式翻译)
⑦ Response 响应逐层返回 流式/非流式适配 + Channel 渲染
Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐