一本码簿

众里寻码千百度,那段却在github处。

在 OpenClaw 中集成 LiteLLM Proxy,通过其自定义 Hook 实现「本地小模型处理简单问题+云端思考型大模型处理复杂问题」的自动路由。复杂度路由是 LiteLLM 的功能,不是 OpenClaw 原生能力。

环境状态:OpenClaw v2026.4.1、oMLX、Qwen3.5-4B-MLX-4bit 已安装完成。
重要说明:复杂度智能路由通过 LiteLLM 的 async_pre_call_hook 实现,OpenClaw 本身不支持基于任务复杂度自动选择模型的功能。


OpenClaw 原生路由能力分析

OpenClaw 原生路由能力(v2026.4.1)

路由类型 支持情况 说明
多代理路由 ✅ 支持 按 channel/account/peer 路由到不同 agent
会话路由 ✅ 支持 基于 session key 的路由(线程、主题)
子代理分发 ✅ 支持 使用 requesterOrigin 进行分发
模型故障转移 ✅ 支持 agents.defaults.model.fallbacks
复杂度智能路由 ❌ 不支持 无根据任务复杂度自动选择模型的能力

为什么选择 LiteLLM 方案?

flowchart TD
    subgraph OpenClaw原生["OpenClaw 原生路由能力"]
        A1["1️⃣ 多代理路由<br/>(Multi-Agent Routing)"] --> A1_result{✓ 根据用户/频道路由到不同 Agent<br/>✗ 不能根据任务复杂度选择模型}
        A2["2️⃣ 模型故障转移<br/>(Model Failover)"] --> A2_result{✓ 模型失败时切换备用模型<br/>✗ 简单的轮询/列表切换<br/>不考虑任务复杂度}
        A3["3️⃣ 复杂度智能路由<br/>(Complexity Routing)"] --> A3_result{✗ OpenClaw 完全不支持<br/>✓ 需要通过 LiteLLM Custom Hook 实现}
    end

LiteLLM vs OpenClaw 原生功能对比

功能 LiteLLM + Hook OpenClaw 原生
复杂度评分 ✅ Token + 关键词 + 代码检测 ❌ 不支持
智能路由 ✅ 自动选择本地/云端模型 ❌ 不支持
故障转移 ✅ 多层自动转移 ✅ 基础故障转移
成本追踪 ✅ 统一计费 ❌ 分散计费
统一入口 ✅ 单一 API 调用 ❌ 需要多配置

结论:OpenClaw 原生路由主要用于多代理场景(不同用户/频道使用不同 Agent),而非复杂度路由(根据任务难度选择模型)。真正的智能路由必须依赖 LiteLLM 的 Custom Hook。


核心价值

通过 LiteLLM Proxy + 自定义 Hook 实现真正的本地+云端复杂度智能路由:

flowchart TB
    A["用户请求"] --> B["OpenClaw Gateway"]
    B --> C["LiteLLM Proxy<br/>(复杂度路由层)"]
    C --> D["async_pre_call_hook<br/>(复杂度分析)"]

    D --> D1["Token 数量统计"]
    D --> D2["关键词模式匹配"]
    D --> D3["复杂度评分算法"]

    D1 --> E{评分 ≥ 阈值?}
    D2 --> E
    D3 --> E

    E -->|是| F["astron-code-latest<br/>(云端)"]
    E -->|否| G["qwen-local<br/>(本地)"]

    F --> H["云端模型<br/>Astron Code<br/>(深度推理)"]
    G --> I["本地模型<br/>oMLX Qwen3.5-4B<br/>(毫秒响应)"]

核心优势:

  • 真正的复杂度路由:自动根据任务复杂度选择模型(LiteLLM Hook 功能)
  • 零成本处理简单任务:本地模型响应简单查询
  • 智能故障转移:模型不可用时自动切换
  • 统一成本追踪:集中查看所有模型消费

一、架构概述

flowchart TB
    subgraph OpenClaw["OpenClaw Gateway (v2026.4.1 + skill-vetter)"]
        A["用户请求"]
    end

    A -->|/v1/chat/completions| B["LiteLLM Proxy<br/>(localhost:4000 复杂度路由层)"]

    subgraph LiteLLM["LiteLLM Proxy"]
        direction TB
        C["complexity_router.py<br/>• 复杂度评分算法<br/>• 关键词匹配<br/>• 模型路由决策"]
        D["config.yaml<br/>• 模型列表定义<br/>• 故障转移规则<br/>• Hook 注册"]
    end

    B --> C
    B --> D

    C --> E{"模型选择"}
    E -->|简单任务| F["本地模型"]
    E -->|复杂任务| G["云端模型"]

    subgraph Local["本地模型"]
        F1["oMLX Qwen3.5-4B-MLX<br/>(localhost:8000)<br/>• 零成本<br/>• 毫秒级响应"]
    end

    subgraph Cloud["云端模型"]
        G1["Astron Code / Claude / GPT-4<br/>(api.astron.com 等)<br/>• 按量计费<br/>• 深度推理能力"]
    end

    F --> F1
    G --> G1

重要说明:复杂度路由完全由 LiteLLM Proxy 的自定义 Hook 实现,OpenClaw 仅作为统一的 AI agent 网关。


二、LiteLLM Proxy 安装

1
2
3
4
5
6
7
8
9
10
# 安装 LiteLLM Proxy (带完整依赖)
pip install 'litellm[proxy]'

# 或使用 Docker
docker run \
-v $(pwd)/config.yaml:/app/config.yaml \
-v $(pwd)/complexity_router.py:/app/complexity_router.py \
-e DEEPSEEK_API_KEY="your-deepseek-key" \
-p 4000:4000 \
ghcr.io/berriai/litellm:main-latest

三、复杂度路由 Hook 实现

这是核心组件,实现基于 prompt 复杂度的智能路由。

重要说明:此复杂度路由器是 LiteLLM 的自定义 Hook,不是 OpenClaw 的原生功能。需要先配置 LiteLLM Proxy,然后 OpenClaw 连接到已配置好的 Proxy。

3.1 创建复杂度路由器

创建 ~/.openclaw/litellm/complexity_router.py:

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
"""
LiteLLM 复杂度路由 Hook
根据 prompt 复杂度自动选择本地或云端模型

注意:此功能完全由 LiteLLM 实现,OpenClaw 本身不支持复杂度路由

简单任务 → 本地模型 (oMLX Qwen3.5-4B) - 零成本,毫秒响应
复杂任务 → 云端模型 (DeepSeek Reasoner) - 深度推理能力
"""

import re
from typing import Any, Dict, Literal, Optional
from litellm.integrations.custom_logger import CustomLogger
from litellm.types.utils import ModelResponse
import litellm

class ComplexityRouter(CustomLogger):
"""
复杂度路由器:根据 prompt 特征自动选择模型
"""

def __init__(self):
super().__init__()
# 复杂度阈值:分数 >= threshold 路由到云端
self.threshold = 2

# 复杂任务关键词
self.complex_keywords = [
# 中文复杂任务
"分析", "比较", "设计", "架构", "推理", "证明", "评估", "总结",
"深度", "详细", "全面", "系统", "研究", "解释原因", "为什么",
"如何实现", "如何解决", "论述", "阐述", "评估", "判断",
# 英文复杂任务
"analyze", "compare", "design", "architect", "reason", "prove",
"evaluate", "synthesize", "comprehensive", "detailed", "explain why",
"how to implement", "discuss", "assess", "critical thinking",
# 数学/逻辑
"计算", "推导", "求解", "证明", "calculate", "derive", "solve",
# 代码相关
"debug", "optimize", "refactor", "重构", "优化", "调试"
]

# 简单任务关键词
self.simple_keywords = [
"你好", "hi", "hello", "嗨", "hey",
"谢谢", "thanks", "thank you",
"查询", "look up", "search",
"翻译", "translate",
"今天", "天气", "时间", "日期", "today", "weather", "time", "date",
"问候", "greeting", "打招呼",
"简单", "easy", "simple",
"是什么", "what is", "who is", "define"
]

def _calculate_complexity_score(self, text: str) -> int:
"""
计算 prompt 复杂度分数
返回值越高表示越复杂
"""
score = 0
text_lower = text.lower()

# 1. Token 数量 (粗略估算)
tokens = len(text.split())
if tokens > 1000:
score += 4
elif tokens > 500:
score += 3
elif tokens > 200:
score += 2
elif tokens > 50:
score += 1

# 2. 复杂任务关键词匹配
for keyword in self.complex_keywords:
if keyword.lower() in text_lower:
score += 1

# 3. 简单任务关键词匹配
for keyword in self.simple_keywords:
if keyword.lower() in text_lower:
score -= 2

# 4. 代码/技术内容判断
code_indicators = ["```", "def ", "class ", "function", "import ",
"代码", "code", "python", "javascript", "api"]
for indicator in code_indicators:
if indicator in text_lower:
score += 1

# 5. 问号数量(提问复杂度)
question_count = text.count('?') + text.count('?')
if question_count >= 3:
score += 2
elif question_count >= 1:
score += 1

# 6. 否定简单问候
greeting_patterns = [
r'^你好[吗呀啊]?', r'^hi\s*$', r'^hello\s*$', r'^hey\s*$',
r'^嗨[吗呀啊]?', r'^嗨$'
]
for pattern in greeting_patterns:
if re.match(pattern, text.strip(), re.IGNORECASE):
score = -10 # 强制为简单任务

return score

async def async_pre_call_hook(
self,
user_api_key_dict: Any,
cache: Any,
data: Dict,
call_type: Literal["completion", "text_completion", "embeddings",
"image_generation", "moderation", "audio_transcription"]
) -> Dict:
"""
LiteLLM Pre-Call Hook
在请求发送到模型之前修改模型选择

Args:
user_api_key_dict: 用户 API 密钥信息
cache: 缓存实例
data: 请求数据 (包含 messages, model 等)
call_type: 调用类型

Returns:
修改后的 data (其中 model 字段被替换)
"""
# 只处理 completion 调用
if call_type != "completion":
return data

# 提取文本内容
messages = data.get("messages", [])
text_content = ""

for message in messages:
if isinstance(message, dict):
content = message.get("content", "")
if isinstance(content, str):
text_content += content + " "
elif isinstance(message, str):
text_content += message + " "

# 计算复杂度分数
complexity_score = self._calculate_complexity_score(text_content)

# 路由决策
if complexity_score >= self.threshold:
# 复杂任务 → 云端推理模型
target_model = "astron-code-latest"
route_reason = f"complex (score={complexity_score})"
else:
# 简单任务 → 本地模型
target_model = "qwen-local"
route_reason = f"simple (score={complexity_score})"

# 记录路由决策
print(f"[ComplexityRouter] {route_reason} → {target_model}")
print(f"[ComplexityRouter] Text preview: {text_content[:100]}...")

# 修改请求中的模型
data["model"] = target_model

return data

# 创建全局实例供 config.yaml 引用
complexity_router_instance = ComplexityRouter()

3.2 复杂度评分说明

特征 分值 说明
Token > 1000 +4 超长文本
Token 500-1000 +3 长文本
Token 200-500 +2 中等长度
Token 50-200 +1 短文本
复杂关键词 +1/个 分析、比较、设计等
简单关键词 -2/个 你好、查询、翻译等
代码内容 +1 包含代码标记
多个问号 +1~2 深度提问

示例:

输入 分数 路由
“你好” -10 本地 (qwen-local)
“翻译 hello world” -3 本地 (qwen-local)
“解释量子计算原理” 3 云端 (astron-code-latest)
“分析人工智能对就业市场的影响” 5 云端 (astron-code-latest)

3.3 工具感知路由(Tool-Aware Routing)

OpenClaw 的核心能力是工具调用(Function Calling),不同工具对模型能力要求差异巨大。以下是工具场景的路由建议:

工具类型与模型匹配矩阵

工具类型 示例场景 推荐模型 原因
简单查询 查天气、查时间、简单计算 qwen-local (本地) 零成本、毫秒响应
文件操作 读取本地文件、列出目录 qwen-local (本地) 本地数据处理,快速响应
文件编辑 写代码、改配置、创建文件 astron-code-latest (云端) 需要代码补全和语法理解
网页搜索 Google搜索、新闻查询 astron-code-latest (云端) 需要联网能力和最新知识
网页内容提取 抓取网页、解析HTML astron-code-latest (云端) 需要理解和处理结构化数据
浏览器自动化 填表单、点击操作、爬虫 astron-code-latest (云端) 需要多步推理和视觉理解
代码调试 修复Bug、性能分析 astron-code-latest (云端) 需要深度推理和复杂分析
架构设计 系统设计、API规划 astron-code-latest (云端) 需要复杂推理和多轮思考
多工具编排 Agent子任务、多步骤工作流 astron-code-latest (云端) 需要长期规划和状态管理

工具感知路由流程图

flowchart TD
    A["用户请求"] --> B{检测工具调用意图?}

    B -->|无| C{文本复杂度评估}
    C -->|简单| C1["qwen-local<br/>(本地)"]
    C -->|复杂| C2["astron-code-latest<br/>(云端)"]

    B -->|是| D{"工具类型?"}

    D -->|简单查询/文件读取| E["qwen-local<br/>(本地)"]
    D -->|文件编辑/网页操作| F["astron-code-latest<br/>(云端)"]
    D -->|代码调试/架构设计| G["astron-code-latest<br/>(云端)"]
    D -->|多工具编排| H["astron-code-latest<br/>(云端)"]

    C1 --> Z["返回结果"]
    C2 --> Z
    E --> Z
    F --> Z
    G --> Z
    H --> Z

增强版复杂度路由器

更新 complexity_router.py 以支持工具感知路由:

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
"""
LiteLLM 增强版复杂度路由 Hook
支持工具感知路由,根据任务类型和复杂度自动选择模型

路由策略:
- 简单任务 → 本地模型 (oMLX Qwen3.5-4B)
- 工具操作 → 根据工具类型选择
- 复杂推理 → 云端推理模型 (DeepSeek Reasoner)
"""

import re
import json
from typing import Any, Dict, Literal, Optional, List
from litellm.integrations.custom_logger import CustomLogger
from litellm.types.utils import ModelResponse
import litellm

class EnhancedComplexityRouter(CustomLogger):
"""
增强版复杂度路由器:支持工具感知的智能路由
"""

def __init__(self):
super().__init__()

# 复杂度阈值
self.text_threshold = 2

# 工具类型与模型映射
self.tool_model_mapping = {
# 简单工具 → 本地模型
"simple": {
"tools": [
"weather", "time", "date", "calculator", "simple_search",
"read_file", "list_directory", "get_time", "currency_convert"
],
"model": "qwen-local"
},
# 中等复杂度 → 云端聊天模型
"medium": {
"tools": [
"write_file", "edit_file", "web_search", "web_scrape",
"image_generation", "document_parser", "api_call",
"send_message", "create_reminder"
],
"model": "astron-code-latest"
},
# 高复杂度 → 云端推理模型
"complex": {
"tools": [
"debug", "code_review", "architecture_design", "security_audit",
"multi_agent", "workflow_orchestration", "data_analysis",
"report_generation", "research_synthesis"
],
"model": "astron-code-latest"
}
}

# 复杂任务关键词
self.complex_keywords = [
"分析", "比较", "设计", "架构", "推理", "证明", "评估", "总结",
"深度", "详细", "全面", "系统", "研究", "解释原因", "为什么",
"如何实现", "如何解决", "论述", "阐述", "判断",
"analyze", "compare", "design", "architect", "reason", "prove",
"evaluate", "synthesize", "comprehensive", "debug", "optimize"
]

# 简单任务关键词
self.simple_keywords = [
"你好", "hi", "hello", "嗨", "hey",
"谢谢", "thanks", "查询", "翻译", "天气", "时间",
"问候", "打招呼", "是什么", "what is", "define"
]

def _detect_tool_intent(self, text: str, messages: List[Dict]) -> Optional[str]:
"""
检测是否有工具调用意图
返回工具类型:simple, medium, complex, 或 None
"""
text_lower = text.lower()

# 检查最后一条用户消息是否暗示使用工具
tool_indicators = {
"simple": [
"查一下天气", "现在几点了", "今天多少号", "帮我算一下",
"weather", "time", "date", "what time is it"
],
"medium": [
"帮我写一个文件", "搜索一下", "查找网页", "发消息",
"write", "search", "scrape", "send", "create file",
"帮我发送", "生成图片"
],
"complex": [
"帮我debug", "代码审查", "架构设计", "安全审计",
"帮我分析这段代码", "多步骤完成", "自动执行",
"debug", "review", "architect", "audit", "analyze code",
"帮我规划", "research"
]
}

for level, indicators in tool_indicators.items():
for indicator in indicators:
if indicator.lower() in text_lower:
return level

# 检查消息历史中是否有工具调用
for msg in messages[-3:]: # 检查最近3条消息
if isinstance(msg, dict):
content = msg.get("content", "")
tool_calls = msg.get("tool_calls", [])
if tool_calls:
# 有工具调用,检查工具名称
for call in tool_calls:
func_name = call.get("function", {}).get("name", "").lower()
for level, config in self.tool_model_mapping.items():
if func_name in config["tools"]:
return level

return None

def _calculate_complexity_score(self, text: str) -> int:
"""
计算纯文本复杂度分数
"""
score = 0
text_lower = text.lower()

# 1. Token 数量
tokens = len(text.split())
if tokens > 1000:
score += 4
elif tokens > 500:
score += 3
elif tokens > 200:
score += 2
elif tokens > 50:
score += 1

# 2. 复杂关键词
for keyword in self.complex_keywords:
if keyword.lower() in text_lower:
score += 1

# 3. 简单关键词
for keyword in self.simple_keywords:
if keyword.lower() in text_lower:
score -= 2

# 4. 问号数量
question_count = text.count('?') + text.count('?')
if question_count >= 3:
score += 2
elif question_count >= 1:
score += 1

# 5. 问候检测
greeting_patterns = [
r'^你好[吗呀啊]?', r'^hi\s*$', r'^hello\s*$', r'^hey\s*$'
]
for pattern in greeting_patterns:
if re.match(pattern, text.strip(), re.IGNORECASE):
score = -10

return score

def _select_model_for_tool(self, tool_level: str) -> str:
"""
根据工具类型选择模型
"""
if tool_level in self.tool_model_mapping:
return self.tool_model_mapping[tool_level]["model"]
return "astron-code-latest" # 默认使用云端聊天模型

async def async_pre_call_hook(
self,
user_api_key_dict: Any,
cache: Any,
data: Dict,
call_type: Literal["completion", "text_completion", "embeddings",
"image_generation", "moderation", "audio_transcription"]
) -> Dict:
"""
LiteLLM Pre-Call Hook
支持工具感知的智能路由
"""
if call_type != "completion":
return data

messages = data.get("messages", [])
text_content = ""

for message in messages:
if isinstance(message, dict):
content = message.get("content", "")
if isinstance(content, str):
text_content += content + " "
elif isinstance(message, str):
text_content += message + " "

# 1. 首先检测工具调用意图
tool_level = self._detect_tool_intent(text_content, messages)

if tool_level:
# 工具感知路由
target_model = self._select_model_for_tool(tool_level)
route_reason = f"tool-{tool_level}"
print(f"[EnhancedRouter] {route_reason} → {target_model}")
else:
# 2. 纯文本复杂度路由
complexity_score = self._calculate_complexity_score(text_content)

if complexity_score >= self.text_threshold:
target_model = "astron-code-latest"
route_reason = f"complex-text (score={complexity_score})"
else:
target_model = "qwen-local"
route_reason = f"simple-text (score={complexity_score})"

print(f"[EnhancedRouter] {route_reason} → {target_model}")

data["model"] = target_model
return data

# 创建全局实例
enhanced_router_instance = EnhancedComplexityRouter()

工具场景路由示例

用户请求 工具检测 路由决策 模型
“你好” 无工具 简单文本 qwen-local
“查一下北京天气” simple工具 天气查询 qwen-local
“帮我搜索OpenClaw最新消息” medium工具 网页搜索 astron-code-latest
“这段代码有Bug帮我看看” complex工具 代码调试 astron-code-latest
“分析这段Python代码的性能” 复杂文本 深度分析 astron-code-latest
“帮我设计一个微服务架构” complex工具 架构设计 astron-code-latest

工具成本优化策略

工具类型 月均调用占比 使用模型 月成本(假设1000次/天)
简单工具 ~40% qwen-local $0
中等工具 ~35% astron-code-latest ~$15
复杂工具 ~25% astron-code-latest ~$25
总计 100% 智能路由 ~$40

对比全云端方案:全部使用 astron-code-latest,月成本约 $100,节省 60%。


四、LiteLLM 配置文件

创建 ~/.openclaw/litellm/config.yaml:

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# ===========================================
# 模型列表定义
# ===========================================
model_list:
# ─────────────────────────────────────────
# 本地模型:oMLX Qwen3.5-4B
# ─────────────────────────────────────────
- model_name: qwen-local
litellm_params:
model: openai/qwen3.5-4b
api_base: http://localhost:8000/v1
api_key: "omlx-local"
rpm: 60
model_info:
mode: chat
supports_function_calling: false
supports_vision: false

# ─────────────────────────────────────────
# 云端模型:DeepSeek
# ─────────────────────────────────────────
- model_name: astron-code-latest
litellm_params:
model: deepseek/astron-code-latest
api_key: os.environ/DEEPSEEK_API_KEY
rpm: 60
model_info:
mode: chat
supports_function_calling: true

- model_name: astron-code-latest
litellm_params:
model: deepseek/astron-code-latest
api_key: os.environ/DEEPSEEK_API_KEY
rpm: 10
model_info:
mode: chat
supports_function_calling: false
supports_reasoning: true

# ===========================================
# 复杂度路由 Hook
# ===========================================
litellm_settings:
# 注册复杂度路由 Hook
callbacks:
- complexity_router.complexity_router_instance

# 重试配置
num_retries: 2
request_timeout: 60

# 故障转移配置
fallbacks:
# 本地模型失败 → 云端模型
- "qwen-local": ["astron-code-latest"]
# 云端推理失败 → 云端聊天模型 → 本地模型
- "astron-code-latest": ["astron-code-latest", "qwen-local"]

# 上下文窗口溢出时降级
context_window_fallbacks:
- "qwen-local": ["astron-code-latest"]
- "astron-code-latest": ["astron-code-latest"]

# 允许的连续失败次数
allowed_fails: 3

# 丢弃不支持的参数
drop_params: true

# ===========================================
# 路由策略
# ===========================================
router_settings:
# 由于我们使用自定义复杂度路由,这里设置为 simple-shuffle 作为 fallback
routing_strategy: simple-shuffle
timeout: 60

# ===========================================
# 服务配置
# ===========================================
general_settings:
master_key: sk-openclaw-local
port: 4000
host: 0.0.0.0

五、环境变量配置

创建 ~/.openclaw/litellm/.env:

1
2
# 云端 API Keys
DEEPSEEK_API_KEY=sk-your-deepseek-key

五点五、配置 LiteLLM Proxy 的复杂度路由 Hook

在启动 LiteLLM Proxy 之前,确保 Hook 已正确配置:

1
2
3
4
5
6
7
8
9
# 1. 确保复杂度路由器文件存在
ls -la ~/.openclaw/litellm/complexity_router.py

# 2. 验证 config.yaml 中的 Hook 注册
grep -A 5 "callbacks" ~/.openclaw/litellm/config.yaml

# 3. 测试 Hook 导入
cd ~/.openclaw/litellm
python -c "from complexity_router import complexity_router_instance; print('Hook loaded successfully')"

六、启动与验证

6.1 启动 LiteLLM Proxy

1
2
3
4
5
6
7
8
cd ~/.openclaw/litellm

# 启动服务
litellm --config ~/.openclaw/litellm/config.yaml

# 或者后台运行
nohup litellm --config ~/.openclaw/litellm/config.yaml \
--detailed_debug > litellm.log 2>&1 &

6.2 验证服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 1. 检查健康状态
curl http://localhost:4000/health

# 2. 查看可用模型
curl http://localhost:4000/v1/model/list

# 3. 测试简单任务(应路由到本地模型)
curl -X POST http://localhost:4000/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-openclaw-local" \
-d '{
"model": "qwen-local",
"messages": [{"role": "user", "content": "你好,请介绍一下自己"}]
}'

# 4. 测试复杂任务(应路由到云端模型)
curl -X POST http://localhost:4000/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-openclaw-local" \
-d '{
"model": "astron-code-latest",
"messages": [{"role": "user", "content": "深度分析人工智能对就业市场的影响,需要考虑技术进步、自动化、行业转型等多个维度"}]
}'

6.3 查看日志验证路由

1
2
3
4
5
6
# 查看 LiteLLM 日志
tail -f ~/.openclaw/litellm/litellm.log | grep ComplexityRouter

# 预期输出示例:
# [ComplexityRouter] simple (score=-10) → qwen-local
# [ComplexityRouter] complex (score=3) → astron-code-latest

6.4 验证 OpenClaw 连接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 测试 OpenClaw 与 LiteLLM Proxy 的连接
curl -X POST http://localhost:4000/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-openclaw-local" \
-d '{
"model": "qwen-local",
"messages": [{"role": "user", "content": "测试连接"}]
}'

# 验证复杂度路由是否生效
curl -X POST http://localhost:4000/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-openclaw-local" \
-d '{
"model": "astron-code-latest",
"messages": [{"role": "user", "content": "深度分析人工智能发展趋势"}]
}'

七、OpenClaw 配置

重要说明:OpenClaw 的配置只是连接到已配置好的 LiteLLM Proxy。复杂度路由完全在 LiteLLM 层实现,OpenClaw 本身不具备此功能。

编辑 ~/.openclaw/openclaw.json:

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
{
"meta": {
"lastTouchedVersion": "v2026.4.1",
"lastTouchedAt": "2026-04-02T12:00:00.000Z",
"platform": "apple-silicon",
"mlx_optimized": true
},
"models": {
"mode": "merge",
"providers": {
"local-omlx": {
"baseUrl": "http://localhost:8000/v1",
"apiKey": "omlx-local",
"api": "openai-completions",
"models": [
{
"id": "qwen3.5-4b-mlx-q4",
"name": "Qwen3.5-4B-MLX-4bit",
"contextWindow": 32768,
"maxTokens": 4096,
"reasoning": false,
"input": ["text"],
"cost": { "input": 0, "output": 0 }
}
]
},
"litellm": {
"baseUrl": "http://localhost:4000",
"apiKey": "sk-openclaw-local",
"api": "openai-completions",
"models": [
{
"id": "qwen-local",
"name": "Qwen3.5-4B (LiteLLM)",
"contextWindow": 32768,
"reasoning": false,
"input": ["text"],
"cost": { "input": 0, "output": 0 }
},
{
"id": "astron-code-latest",
"name": "DeepSeek-V3",
"contextWindow": 64000,
"reasoning": false,
"input": ["text"]
},
{
"id": "astron-code-latest",
"name": "DeepSeek-R2",
"contextWindow": 200000,
"reasoning": true,
"input": ["text"]
}
]
}
}
},
"agents": {
"defaults": {
"model": {
"primary": "litellm/qwen-local",
"fallbacks": [
"litellm/astron-code-latest",
"litellm/astron-code-latest"
]
}
}
},
"fault_tolerance": {
"enable_failover": true,
"max_retries": 2
}
}

八、OpenClaw 原生路由能力

8.1 多代理路由(Multi-Agent Routing)

OpenClaw 支持按渠道/用户路由到不同 Agent,这与复杂度路由是不同的概念:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
"channels": {
"telegram": {
"dmPolicy": "routing",
"route": {
"+8613812345678": "agent-fast", // 快速问答代理
"+8613912345678": "agent-coding" // 编程专用代理
}
},
"discord": {
"dmPolicy": "routing",
"route": {
"user-alpha": "agent-fast",
"user-beta": "agent-reasoning"
}
}
}
}

用途:不同用户/场景使用不同 Agent,而非根据任务复杂度选择模型。

8.2 Model Failover 机制

LiteLLM 的复杂度路由与 OpenClaw 的故障转移协同工作:

flowchart TB
    A["用户请求"] --> B["LiteLLM 复杂度路由<br/>(async_pre_call_hook)"]

    B --> C{复杂度评分 → 模型选择}
    C -->|简单| C1["qwen-local<br/>(本地)"]
    C -->|复杂| C2["astron-code-latest<br/>(云端)"]

    C1 & C2 --> D{模型可用?}
    D -->|是| Z["返回结果"]
    D -->|否| E["LiteLLM 故障转移"]

    subgraph LiteLLM_Fallback["LiteLLM 故障转移"]
        E["fallbacks 配置"]
        E --> E1["qwen-local → astron-code-latest"]
        E --> E2["astron-code-latest → astron-code-latest → qwen-local"]
    end

    E1 & E2 --> F{LiteLLM 层可用?}
    F -->|否| G["OpenClaw Model Failover"]

    subgraph OpenClaw_Fallback["OpenClaw Model Failover"]
        G["agents.defaults.model.fallbacks"]
        G --> G1["litellm/qwen-local → litellm/astron-code-latest → ..."]
    end

    G1 --> H["返回结果"]
    E1 & E2 --> H

8.3 路由能力总结

路由类型 实现层 说明
复杂度智能路由 LiteLLM Hook ✅ 本文方案
多代理路由 OpenClaw ✅ 按用户/渠道
故障转移 双重 LiteLLM + OpenClaw

九、测试完整流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 1. 重启 OpenClaw Gateway
openclaw gateway restart

# 2. 检查状态
openclaw gateway status

# 3. 运行健康检查
openclaw doctor

# 4. 测试复杂度路由(通过 LiteLLM Hook 实现)
# 简单任务 → 自动路由到本地模型
openclaw run "你好"

# 复杂任务 → 自动路由到云端推理模型
openclaw run "深度分析量子计算对未来 cryptography 的影响"

# 5. 查看日志
openclaw gateway logs --tail 100

# 同时查看 LiteLLM 日志验证路由决策
tail -f ~/.openclaw/litellm/litellm.log | grep -E "(ComplexityRouter|EnhancedRouter)"

测试要点:

  • 验证 LiteLLM Proxy 的复杂度路由 Hook 是否正常工作
  • 确认 OpenClaw 能正确调用 LiteLLM Proxy
  • 检查故障转移机制是否生效

十、成本优化效果

任务类型 比例 模型 成本
简单任务(问候、查询等) ~60% qwen-local (本地) $0
复杂任务(分析、推理等) ~40% astron-code-latest 按量计费

预估月成本节省(假设每日 100 次请求):

方案 本地占比 云端占比 月成本
全部云端 0% 100% ~$30
智能路由 60% 40% ~$12

十一、架构总结

flowchart TB
    A["用户请求"] --> B["LiteLLM Proxy<br/>(复杂度路由层)"]

    subgraph Router["async_pre_call_hook (复杂度分析)"]
        B --> C["输入"]
        C --> C1["Token计数"]
        C1 --> C2["关键词匹配"]
        C2 --> C3["复杂度评分"]
        C3 --> C4{"模型选择"}

        C4 -->|分数 ≥ 2| C5["astron-code-latest<br/>(云端)"]
        C4 -->|分数 < 2| C6["qwen-local<br/>(本地)"]
    end

    B --> D["+ 故障自动转移"]
    B --> E["+ 成本追踪"]

    C5 & C6 --> F["模型响应"]

    subgraph LocalModel["本地模型"]
        F -->|简单任务 ~60%| G["oMLX Qwen3.5-4B<br/>✓ 零成本<br/>✓ 毫秒级响应<br/>✓ 数据隐私"]
    end

    subgraph CloudModel["云端模型"]
        F -->|复杂任务 ~40%| H["Astron Code<br/>✓ 深度推理<br/>✓ 按量计费"]
    end

    G <-.->|故障转移| H

组件职责分工:

组件 主要职责 功能范围
OpenClaw Gateway AI agent 网关 多代理路由、会话管理、工具调用统一入口
LiteLLM Proxy 模型路由中枢 复杂度分析、模型选择、故障转移、成本追踪
本地模型 (oMLX) 简单任务处理 零成本、快速响应、数据隐私保护
云端模型 (Astron) 复杂任务处理 深度推理、知识更新、复杂计算

关键说明:复杂度智能路由完全由 LiteLLM 的自定义 Hook 实现,OpenClaw 提供统一的管理界面和工具调用支持。

智能路由效果:

  • 简单任务 (~60%) → 本地模型 (零成本)
  • 复杂任务 (~40%) → 云端模型 (按需付费)
  • 故障时 → 自动转移备用模型
  • 月成本节省 ~60%

十三、OpenClaw vs LiteLLM:功能对比总结

功能维度 OpenClaw LiteLLM 本方案
复杂度路由 ❌ 不支持 ✅ Hook 实现 ✅ 通过 LiteLLM
多代理路由 ✅ 按用户/频道 ❌ 不支持 ✅ OpenClaw 原生
工具调用统一 ✅ Function Calling ❌ 不支持 ✅ OpenClaw 原生
模型故障转移 ✅ 基础故障转移 ✅ 高级故障转移 ✅ 双重保障
成本追踪 ❌ 分散计费 ✅ 统一计费 ✅ LiteLLM 统一
本地模型支持 ✅ 通过 provider ✅ 通过 proxy ✅ 双重集成

最佳实践:

  • 使用 OpenClaw 进行多代理管理和工具调用编排
  • 使用 LiteLLM 进行复杂度路由和成本优化
  • 组合使用 获得完整的 AI agent 解决方案

OpenClaw 官方资源

LiteLLM 官方资源

版本更新记录

日期 版本 关键更新
2026-04-01 v2026.4.1 /tasks 后台任务看板,Agent 本地故障转移
2026-03-23 v2026.3.23 Qwen endpoints,UI 优化
2026-03-22 v2026.3.22 ClawHub 优先,MCP 整合
2026-03-13 v2026.3.12 Gateway Dashboard v2,GPT-5.4/Claude 快速模式
2026-03-08 v2026.3.7 Context Engine 插件接口,GPT-5.4 支持

1. 引言:OpenClaw 的“吞金”之痛

OpenClaw 无疑是当前最强大的 AI Agent 框架之一,它让开发者能够构建出真正自主的智能体。然而,几乎所有深度用户都面临两个核心痛点 :

  • 失忆:长对话中,关键信息被内置的压缩机制随机丢弃,任务执行到一半就偏离目标,Agent 的行为发生退化。
  • 吞金:默认的滑动窗口压缩机制虽然试图控制上下文长度,但往往导致上下文冗余,Token 消耗剧增。

更糟糕的是,这两个问题会形成恶性循环:脏上下文导致高 Token 消耗,为了省钱被迫降低模型规格,结果 Agent 表现更差,用户体验直线下滑。

转折点出现在 2026.3.7 版本——OpenClaw 引入了上下文引擎的插件架构,为社区贡献者打开了优化的大门。而 2026.3.13 紧急修复版本进一步修复了压缩一致性、记忆文件重复注入等关键问题 。

本文基于 OpenClaw 2026.3.13 最新版本,从配置调优、记忆系统、上下文管理三个层面,提供一套完整的、可落地的降本增效方案。


2. 原因剖析:Token 都花在了哪里?

在动手优化之前,先要理解钱到底花在了哪儿。每次你与 OpenClaw 对话,发送给模型的远不止你的问题,而是一个完整的工作包:

组成部分 说明
系统提示词 给 AI 的”员工手册”
Workspace 文件 AGENTS.md、TOOLS.md、MEMORY.md 等配置文件
对话历史 越聊越长,产生雪球效应
工具输出 执行命令的 stdout/stderr、抓取的网页内容
你的问题 这才是你真正想问的

Token 消耗的底层逻辑可以用一个公式来概括 :
Token 消耗 = (输入 + 输出) × 调用次数 × 模型价格
其中输入才是真正的大头。OpenClaw 的设计哲学是从无状态到有状态的转变,为了让 Agent 记住一切,框架每次都会默认将完整对话历史发送出去。一次请求的输入可能就有 2-3 万 tokens,聊了 10 轮就是 20-30 万 。

好消息是:2026.3.13 版本修复了多个与 Token 消耗相关的核心问题 :

  • 压缩后的会话 token 计数不准确 → 已修复
  • 大小写不敏感挂载上记忆文件被注入两次 → 已修复
  • 会话重置提示触发 Azure 内容过滤器 → 已优化

3. 架构级优化:引入分层路由思路

3.1 传统方案的局限

将不同职能拆分到独立 Agent(多智能体架构)虽然能实现上下文隔离,但系统复杂度急剧增加,且主控 Agent 的意图识别本身也在消耗 Token。

3.2 分层路由的核心思想

Viking 分层路由系统的思路值得借鉴:在调用昂贵的主模型之前,先用一个极轻量的模型做意图识别,判断用户到底想干什么,然后只加载与之相关的工具、技能和上下文片段。

如何借鉴:即使不 fork 项目,你也可以手动精简 AGENTS.md 等引导文件,移除对终端用户无用的开发规范、不常用技能的详细说明,从源头减少基础提示词的长度。

⚠️ 注意:Viking 分层路由系统的官方版本不能通过安装插件的方式实现,需要安装社区版 openclaw-viking:

1
openclaw plugins install @viking-engineering/openclaw-viking

4. 配置级优化

4.1 利用新版压缩修复

2026.3.13 修复了压缩后会话 token 计数不准的问题,当前版本支持的压缩配置项包括:

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"agents": {
"defaults": {
"compaction": {
"mode": "safeguard", // 使用 safeguard 模式保护最近上下文
"postIndexSync": "async", // 压缩后异步同步会话记忆
"reserveTokens": 8000, // 为回复生成保留 token 空间
"keepRecentTokens": 15000, // 保护最近 15000 tokens
"maxHistoryShare": 0.6 // 历史最多占 60% 上下文
}
}
}
}

4.2 开启会话剪枝

自动移除旧的对话内容,保持上下文在合理范围内 :

1
2
3
4
5
6
7
{
"contextTokens": 200000,
"contextPruning": {
"mode": "cache-ttl",
"ttl": "55m" // 保留 55 分钟内的对话
}
}

4.3 降低无效心跳

心跳(Heartbeat)是 OpenClaw 的定时唤醒机制,用于检查任务、发送提醒。但如果不加控制,它会成为隐形的 Token 杀手 :

算笔账:心跳频率 30 分钟/次,每月心跳次数 1,440 次,每次输入 3,000 Token,每月仅心跳就消耗 432 万 Token!

优化建议:

  • 设置工作时间间隔为 45-60 分钟
  • 深夜 23:00-08:00 设为静默期
  • 精简 HEARTBEAT.md 到最少行数

4.4 关闭非必要附加功能

以下配置项对 Token 消耗的影响程度 :

配置项 功能 影响程度 说明
ENABLE_TITLE_GENERATION 自动标题生成 低 仅在新建对话时触发
ENABLE_TAGS_GENERATION 自动标签生成 低 保存记忆时触发
ENABLE_FOLLOW_UP_GENERATION 后续问题建议 中等 每次回复后额外调用模型
ENABLE_AUTOCOMPLETE_GENERATION 输入自动补全 低 通常在端侧实现

建议根据场景选择性关闭,尤其是 ENABLE_FOLLOW_UP_GENERATION。


5. 记忆系统优化:从默认 Memory Search 切换到 QMD

5.1 默认 Memory Search 的问题

OpenClaw 默认的记忆搜索存在几个关键缺陷 :

  • 使用 SQLite 做向量存储,性能不佳
  • 单一向量搜索,结果不够精准
  • 容易把整个记忆文件塞进上下文,导致 Token 爆炸

5.2 QMD 简介

QMD(Queryable Markdown Database) 是 Shopify 创始人 Tobi 开发的一个本地语义搜索引擎,专为 AI Agent 量身定制 。

它的核心逻辑是:不再读全库,只读最相关的那几段。

技术原理 :

  • 基于 TypeScript + Bun 开发
  • 三层混合检索:BM25 全文搜索 + 向量语义搜索 + LLM 重排序
  • 所有模型在本地运行,完全离线

实际效果 :

  • 📊 Token 削减:60-97%(平均 95% 以上)
  • ⚡ 响应速度提升:5-50 倍
  • 🎯 精准度:93%(纯语义搜索仅 59%)

5.3 QMD 与默认 Memory Search 的关系

QMD 是替代关系,配置后 QMD 完全接管记忆检索职责,但依然兼容原有记忆文件 。

5.4 QMD 详细配置指南

前置条件

  • OpenClaw 版本 ≥ 2026.2.2
  • SQLite ≥ 3.40.0

安装 QMD CLI

1
2
3
4
5
# 使用 Bun 安装(推荐)
bun install -g @tobilu/qmd

# 或使用 npm 安装
npm install -g @tobilu/qmd

修改 OpenClaw 配置文件

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
34
{
"memory": {
"backend": "qmd", // 切换到 QMD 后端
"citations": "auto",
"qmd": {
"includeDefaultMemory": true, // 包含原有的 MEMORY.md
"update": {
"interval": "5m",
"debounceMs": 15000,
"onBoot": true
},
"limits": {
"maxResults": 7, // 最多注入几段
"maxSnippetChars": 700, // 每段长度限制
"timeoutMs": 4000
},
"scope": {
"default": "allow" // Windows 用户必需
},
"paths": [
{
"name": "memory",
"path": "~/.openclaw/workspace/memory/",
"pattern": "**/*.md"
},
{
"name": "notes",
"path": "~/obsidian/", // 可添加外部笔记库
"pattern": "**/*.md"
}
]
}
}
}

Windows 特别注意事项 :

  • command: "qmd.exe" 可能需要显式指定
  • scope.default: "allow" 必不可少,避免权限拒绝

初始化索引

1
2
cd ~/.openclaw/workspace
qmd update --dir .

验证效果

1
openclaw memory search "你的搜索词"

观察日志确认 Using QMD memory backend。


6. 上下文管理革命:lossless-claw 插件深度解析

6.1 lossless-claw 原理与优势

为什么需要 lossless-claw

OpenClaw 内置的上下文压缩机制存在一个根本性缺陷:它是有损的(lossy) 。具体来说,内置压缩会:

  • 把数十轮对话一股脑压成一段几百 Token 的摘要
  • 不保留原始消息——压缩后细节永远丢失
  • 导致 Agent 行为退化:跳过验证步骤、忽略安全规则

当 LCM 论文的作者告知 OpenClaw 维护者 Josh Lehman 他们的工作时,Josh 立刻意识到这会是 OpenClaw 的一个极棒的补充。他花了 9 天时间疯狂开发,在自己的 Agent 上运行了一周,结果令人印象深刻:”对话感觉永远不会丢失信息(因为某种程度上确实不会),始终在 30-100K Token 范围内运行,零维护” 。

LCM 核心原理:DAG 层次化摘要

Lossless Context Management (LCM) 插件用 DAG(有向无环图)结构的摘要系统替代滑动窗口压缩 :

graph TD
    A[Immutable Store<br>所有原始消息的逐字副本]
    subgraph B [DAG摘要层]
      direction LR
      B1["Depth 0:<br> [摘要A] ← 消息1-8  <br>[摘要B] ← 消息9-16"]
      B2["Depth 1:<br> [浓缩X] ← 摘要A+摘要B"]
      B3["每个摘要都链接回源消息 ← '无损'"]
    end
    B["DAG摘要层<br>Depth 0:<br> [摘要A] ← 消息1-8  <br>[摘要B] ← 消息9-16<br>Depth 1:<br> [浓缩X] ← 摘要A+摘要B<br>每个摘要都链接回源消息 ← '无损'"]
    subgraph C [模型接收内容(Context)]
      direction TB
      C1[系统提示词]
      C2[DAG摘要]
      C3[最近N条原始消息]
    end
    A --> B --> C
    B1 --> B2 --> B3

关键创新 :

  • 全量持久化:所有消息存入 SQLite,无信息丢失
  • 分层摘要:超出最新 N 条消息后异步生成摘要,同层摘要积累后向上凝练o
  • 动态上下文组装:每轮自动拼接”最新原始消息 + 历史层级摘要”
  • 按需回溯:提供 lcm_grep、lcm_describe、lcm_expand 工具,随时调取原始内容

性能实测:OOLONG 基准测试

OOLONG 是什么:长上下文推理基准测试,测的是模型能否理解和推理整段长文本的全局信息 。

测试结果(使用相同模型):

  • lossless-claw:得分 74.8
  • Claude Code:得分 70.3

关键发现:上下文越长,差距越大——在所有测试的上下文长度上,lossless-claw 的得分都高于 Claude Code。

Token 消耗:实测降低 30% 以上,额外消耗的 Token 主要是摘要计算,不会大幅增加总消耗 。

6.2 lossless-claw 配置指南

前置条件

  • OpenClaw 版本 ≥ 2026.3.7(推荐 2026.3.13)
  • SQLite(OpenClaw 默认预装)
  • Node.js ≥ v22

安装步骤(推荐方式)

使用 OpenClaw 的插件安装命令(会自动配置):

1
2
3
4
5
6
# 1. 确保 OpenClaw 已更新到最新版
npm install -g openclaw@latest
openclaw --version # 应显示 2026.3.13

# 2. 使用插件安装命令(推荐)
openclaw plugins install @martian-engineering/lossless-claw

安装命令会自动完成:

  • 下载并安装插件到 ~/.openclaw/extensions/lossless-claw
  • 在 plugins.entries 中添加配置
  • 在 plugins.slots.contextEngine 中注册上下文引擎

手动配置(如需自定义)

如果需要手动配置,确保在 plugins 下正确设置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
"plugins": {
"allow": [
"openclaw-qqbot",
"openclaw-lark",
"lossless-claw"
],
"entries": {
"lossless-claw": {
"enabled": true,
"config": {
"freshTailCount": 16,
"contextThreshold": 0.8,
"summaryModel": "astroncodingplan/astron-code-latest"
}
}
},
"slots": {
"contextEngine": "lossless-claw"
}
}
}

配置说明:

配置项 说明 推荐值
freshTailCount 保留的原始消息数量 16-32
contextThreshold 触发压缩的上下文阈值 (0-1) 0.8
summaryModel 用于生成摘要的模型 使用主模型

⚠️ 注意:contextEngine 应配置在 plugins.slots 下,而非 agents.defaults.contextEngine。

验证安装

安装后重启网关,查看日志确认插件加载:

1
2
openclaw gateway restart
openclaw logs --follow | grep -i lcm

正常输出应类似:

1
2
[plugins] [lcm] Plugin loaded (enabled=true, db=/Users/sean/.openclaw/lcm.db, threshold=0.8)
[plugins] [lcm] Compaction summarization model: astroncodingplan/astron-code-latest (override)

注意事项

  • 现有会话不能直接切换:需要 /reset 重置或 /new 开新会话才能使用 lossless-claw
  • 磁盘存储增长:长期使用会导致磁盘存储占用增长,建议定期清理旧会话
  • 重启网关:修改配置后务必重启服务 openclaw gateway restart

7. 综合实践:一次完整的优化旅程

假设你有一个运行了一段时间的 OpenClaw 实例,以下是建议的优化步骤:

7.1 升级到最新版本

1
2
npm install -g openclaw@latest
openclaw --version # 确认显示 2026.3.13

7.2 开启配置级优化

以下配置经实际测试验证可正常工作(2026.3.13 版本):

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
34
35
36
37
38
39
40
41
{
"agents": {
"defaults": {
"compaction": {
"mode": "safeguard",
"postIndexSync": "async",
"reserveTokens": 8000,
"keepRecentTokens": 15000,
"maxHistoryShare": 0.6
},
"contextPruning": {
"mode": "cache-ttl",
"ttl": "55m"
},
"heartbeat": {
"every": "55m",
"target": "last"
}
}
},
"memory": {
"backend": "qmd",
"citations": "auto",
"qmd": {
"includeDefaultMemory": true,
"update": {
"interval": "5m",
"debounceMs": 15000,
"onBoot": true
},
"limits": {
"maxResults": 7,
"maxSnippetChars": 700,
"timeoutMs": 4000
},
"scope": {
"default": "allow"
}
}
}
}

7.3 安装 lossless-claw 插件

1
2
# 使用插件安装命令(推荐,自动配置)
openclaw plugins install @martian-engineering/lossless-claw

安装后会自动配置 plugins.slots.contextEngine。

7.4 重启网关

1
openclaw gateway restart

7.5 验证效果

1
2
3
4
5
# 查看插件加载日志
openclaw logs --follow | grep -i lcm

# 测试 QMD 记忆搜索
openclaw memory search "测试关键词"

7.6 优化前后对比

建议用实际监控数据展示效果。根据社区反馈,这套组合拳通常可以实现:

  • Token 消耗降低 30-60%
  • 响应速度提升 5-10 倍
  • 记忆精准度大幅提升

8. 避坑指南与注意事项

  1. 现有会话不能直接切换到 lossless-claw,需要 /reset 或 /new
  2. 不要同时运行用户级和系统级 OpenClaw 服务,会导致冲突
  3. 修改配置后务必重启服务:openclaw gateway restart
  4. QMD 首次索引可能需要时间,耐心等待完成
  5. 定期检查磁盘空间,防止旧会话占用过多存储
  6. 注意版本号差异:Git Tag 是 v2026.3.13-1,但 npm 版本是 2026.3.13,升级时无需纠结
  7. Windows 用户特别注意 QMD 的 scope 配置

9. 总结与展望

本文基于 OpenClaw 2026.3.13 版本,从三个层面提供了完整的降本增效方案:

优化层面 核心方案 效果
配置级优化 会话剪枝、compaction 模式调优 减少 30-50% 无效消耗
记忆系统 QMD 混合检索 Token 削减 60-97%,精准度 93%
上下文管理 lossless-claw DAG 摘要 无损记忆,OOLONG 得分 74.8

这三者并不互斥,而是可以协同工作:QMD 负责外部知识的精准检索,lossless-claw 负责对话历史的高效管理,配置优化则贯穿始终。

核心指导思想:按需加载、本地优先。让昂贵的云端模型只处理真正需要它的事情,其他工作尽可能交给本地计算。

展望未来,OpenClaw 社区仍在快速进化。2026.3.13 版本带来的浏览器控制、安全加固、Slack 深度集成等更新 ,为 AI 智能体打开了更广阔的应用空间。期待更多优秀的插件和方案涌现,让 OpenClaw 既强大又亲民。


附录:常用命令速查表

目的 命令
查看 OpenClaw 版本 openclaw --version
升级到最新版 npm install -g openclaw@latest
安装 lossless-claw(推荐) openclaw plugins install @martian-engineering/lossless-claw
安装 QMD bun install -g @tobilu/qmd
重启网关 openclaw gateway restart
查看日志 openclaw logs --follow
重置会话(启用新插件) /reset 或在聊天中发送 /new
QMD 手动索引 qmd update --dir .
QMD 测试搜索 qmd search "关键词" -c .
查看服务状态 openclaw doctor
验证 lossless-claw 加载 openclaw logs --follow | grep lcm

本文基于 OpenClaw 2026.3.13 版本编写,配置路径和参数可能随版本更新而变化,请以官方文档为准。

1
wget -qO- https://haies.cn/assets/checkname.js

使用说明

checkname 是一个基于 Node.js 的命令行工具,用于检查和自动修复文件及目录名称,确保它们能够同时在 Windows 11、macOS 和 Ubuntu 系统中正常使用,便于跨平台文件共享。工具会检查文件名是否包含禁止字符、是否超长、是否存在空格等不可见字符,并按照预定策略进行规范化处理,同时自动处理重名冲突。

安装与运行

  • 环境要求:Node.js 12.0 或更高版本(建议使用 LTS 版本)。
  • 获取脚本:将脚本保存为 checkname.js。
  • 运行方式:在终端中执行 node checkname.js [参数] [目录1] [目录2] ...

基本用法

1
node checkname.js [-p] <目录1> [<目录2> ...]
  • -p:处理模式。
    • 若指定此参数,脚本会尝试读取目标目录下最新的日志文件,并根据日志记录对不符合规范的文件/目录进行重命名操作。
    • 如果目录下没有日志文件,则先执行完整检查并生成日志,然后立即根据该日志进行处理。
    • 处理完成后,日志文件会被更新,记录每个条目的处理结果(新路径、状态等)。
  • 不指定 -p:仅检查模式。脚本遍历目录,找出所有不符合规范的文件和目录,并将记录保存到新生成的日志文件中(不会修改任何文件)。

使用示例

示例 1:仅检查目录 /home/user/share

1
node checkname.js /home/user/share

输出:

1
2
3
4
处理目录: /home/user/share
仅检查模式,不会修改文件
检查完成,发现 3 个不符合规范的条目
日志已保存: /home/user/share/checkname_20250302_143022.jsonl

此时目录下会生成日志文件,记录不合规条目的详细信息。你可以查看日志决定是否进行下一步处理。

示例 2:处理目录(基于已有日志)

1
node checkname.js -p /home/user/share

假设目录下已有日志 checkname_20250302_143022.jsonl:

1
2
3
4
5
处理目录: /home/user/share
使用现有日志: checkname_20250302_143022.jsonl
开始处理 3 个条目...
处理完成,日志已更新: checkname_20250302_143022.jsonl
统计: 已处理 2, 错误 0, 跳过 1

脚本会读取日志,重命名其中两个文件/目录,并更新日志状态。跳过的条目可能是因为原名称已合规(无需修改)。

示例 3:处理多个目录,且目录无现有日志

1
node checkname.js -p /mnt/data /mnt/docs

输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
处理目录: /mnt/data
未找到现有日志,将先执行检查...
检查完成,发现 5 个不符合规范的条目
已生成日志: checkname_20250302_144512.jsonl
开始处理 5 个条目...
处理完成,日志已更新: checkname_20250302_144512.jsonl
统计: 已处理 5, 错误 0, 跳过 0

处理目录: /mnt/docs
未找到现有日志,将先执行检查...
检查完成,发现 2 个不符合规范的条目
已生成日志: checkname_20250302_144513.jsonl
开始处理 2 个条目...
处理完成,日志已更新: checkname_20250302_144513.jsonl
统计: 已处理 2, 错误 0, 跳过 0

示例 4:查看日志内容

1
cat /home/user/share/checkname_20250302_143022.jsonl

输出示例:

1
2
{"type":"file","originalPath":"/home/user/share/a*b?.txt","newPath":null,"issues":["invalid_char"],"status":"pending","timestamp":"2025-03-02T14:30:22.123Z"}
{"type":"dir","originalPath":"/home/user/share/这是一个非常长的目录名称中文英文混合......","newPath":null,"issues":["too_long"],"status":"pending","timestamp":"2025-03-02T14:30:22.456Z"}

处理后的日志会更新 newPath 和 status。

相关说明

1. 规范性规则

  • 禁止字符:包含以下任一字符的名称被视为不合规:
    • <>:"/\|?* (Windows 文件系统禁止的字符)
    • ASCII 控制字符(0x00–0x1F)
    • 所有 Unicode 空白字符(包括空格、制表符、换行符等)
  • 长度限制:文件名(包括扩展名)的 UTF-8 编码字节数不得超过 255 字节(这是 Linux 的极限值,也是 Windows 和 macOS 的安全上限)。中文字符通常占 3 字节,需要特别注意。
  • 忽略条目:脚本会自动跳过以下类型的文件和目录(及其内部所有内容):
    • 以点(.)开头的隐藏文件/目录
    • 名称为 node_modules、dist、build、bin、debug 的目录(不区分大小写)

2. 处理策略

当发现不合规的名称时,按以下顺序进行修正:

  1. 删除非法字符:移除所有禁止字符。
  2. 长度缩减:如果删除非法字符后仍超长,则对主名(不含扩展名)依次应用以下规则,直到字节数达标:
    • 删除特殊字符(非字母、数字、下划线 _、连字符 -)。
    • 将连续重复 4 次以上的字符缩减为 4 次(例如 "aaaaa" → "aaaa")。
    • 从主名末尾逐个删除字符。
  3. 重名冲突处理:修正后的名称若与同目录下已有条目重名,则自动添加序号 (1)、(2)…… 直至不冲突。添加序号时会确保总长度不超限,必要时会进一步截断主名。

3. 日志文件

  • 命名格式:checkname_YYYYMMDD_HHMMSS.jsonl(例如 checkname_20250302_143022.jsonl),保存在被分析的目录下。

  • 格式:JSON Lines,每行一条记录,包含以下字段:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    {
    "type": "file|dir", // 条目类型
    "originalPath": "/绝对/路径/原名称", // 原始完整路径
    "newPath": "/绝对/路径/新名称", // 处理后的路径(仅处理模式有值)
    "issues": ["invalid_char", "too_long"], // 不合规原因
    "status": "pending|processed|error|skipped", // 状态
    "error": "错误信息(如果有)", // 处理失败时的错误信息
    "timestamp": "2025-03-02T14:30:22.123Z" // 记录生成时间
    }
  • 作用:日志既是检查结果的记录,也是处理模式的输入。处理模式只会处理 status 为 pending 的条目,并更新其状态为 processed、error 或 skipped。

4. 处理模式详解

  • 基于现有日志:若目录下已有日志文件,脚本会自动选择最新的一个,读取其中的记录,然后尝试处理所有状态为 pending 的条目。处理完成后,日志文件会被覆盖更新。
  • 无日志时:如果目录下没有日志文件,则先执行完整检查,生成新日志,然后立即根据该日志进行处理。这相当于一次完成“检查+处理”。
  • 重复运行:可以多次运行处理模式,每次只会处理尚未处理的条目(pending 状态)。已处理(processed)、出错(error)或跳过(skipped)的记录不会重复操作。

注意事项

  • 备份重要数据:处理模式会实际修改文件名,建议首次使用时先运行不带 -p 的检查模式,查看日志确认后再执行处理。
  • 权限问题:确保脚本对目标目录有读写权限,否则处理可能失败。
  • 跨平台兼容:修正后的文件名仍可能在某些极端情况下不兼容(例如保留字如 CON、PRN 等,Windows 有保留设备名),本工具未处理这些情况,请自行留意。
  • 日志累积:多次运行处理模式会不断更新同一个日志文件,如需保留历史记录,请手动备份旧日志。
  • 并发安全:脚本为串行处理,不会同时修改多个文件,避免冲突。

wget -qO- https://haies.cn/assets/svn_server_tool.sh

使用说明

在服务器端直接查看和统计 SVN 代码仓库信息,无需通过客户端连接。

功能:

  • 目录内容查看:查看 SVN 仓库目录结构,仅显示指定目录的第一层内容(非递归)
  • 代码修改历史查询:查看文件或目录的所有修改记录,包括版本号、作者、时间、提交信息
  • 代码提交统计分析:统计提交情况,按作者统计提交次数和百分比,显示提交时间范围

基本用法

1
./svn_server_tool.sh <功能> <仓库路径> [目录/文件路径]
  • 功能参数(第一个参数):ls列出目录、log查看历史、stat统计提交
  • 仓库路径(第二个参数):SVN 仓库物理路径,如/var/svn/repos/myproject
  • 目标路径(第三个参数):ls为可选,log和stat为必填(仓库内相对路径)

使用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 查看仓库根目录
./svn_server_tool.sh ls /var/svn/repos/myproject

# 查看指定目录
./svn_server_tool.sh ls /var/svn/repos/myproject /trunk/src

# 查看文件修改历史
./svn_server_tool.sh log /var/svn/repos/myproject /trunk/src/main.java

# 查看目录修改历史
./svn_server_tool.sh log /var/svn/repos/myproject /trunk/src

# 统计文件提交情况
./svn_server_tool.sh stat /var/svn/repos/myproject /trunk/src/main.java

# 统计目录提交情况
./svn_server_tool.sh stat /var/svn/repos/myproject /trunk/src

1
wget -qO- https://haies.cn/assets/tar_batch.sh

使用说明

智能压缩指定目录内文件数量较多的文件夹,自动根据目录深度和文件数量应用不同压缩规则,并排除文档、图片、视频、音频等特定文件类型。

该脚本特别适合处理日志目录、临时文件目录、上传目录等包含大量小文件的场景,能有效减少 inode 使用量,提升文件系统性能。

基本用法

1
./tar_batch.sh [目标目录]
  • 目标目录:可选参数,不指定时默认处理脚本所在目录
  • 处理深度:3-5 级目录,按从浅到深顺序

使用示例

1
2
./tar_batch.sh                 # 压缩当前目录
./tar_batch.sh /path/to/data # 压缩指定目录

相关说明

压缩规则

目录深度 条件 操作
< 4 不含排除文件类型,文件数 50-100 压缩
= 4 不含排除文件类型,文件数 > 50 压缩
> 4 无条件 压缩

排除的文件类型

  • 文档:.txt .pdf .doc .docx .xls .xlsx .ppt .pptx .odt .md .rtf
  • 图片:.jpg .jpeg .png .gif .bmp .tiff .svg .webp
  • 视频:.mp4 .avi .mov .mkv .flv .wmv .m4v .webm
  • 音频:.mp3 .wav .flac .aac .ogg .m4a .wma

输出说明

执行后,符合条件的目录会被压缩,并在同级位置生成:

  • 单卷包:目录名.tar.gz
  • 多卷包:目录名_archive/ 文件夹(内含分卷文件)

特性说明

  • 终端实时显示当前正在压缩的文件名
  • 在目标目录生成带时间戳的日志文件

1
wget -qO- https://haies.cn/assets/tar_single.sh

使用说明

大容量单目录分卷压缩、解压工具,支持 gzip、zstd(推荐)、xz 三种压缩算法,提供创建、解压、测试三种操作模式。

核心特性:

  • 自动检测压缩格式,解压和测试时无需手动指定算法
  • 提供分卷校验和验证,确保数据完整性
  • 彩色日志输出,包含时间戳,便于跟踪和审计
  • 默认使用并行压缩工具,处理大文件时效率更高

基本用法

1
./tar_single.sh -[操作方式][压缩算法] [操作对象]
  • 操作方式:c创建、x解压、t测试
  • 压缩算法(仅创建时需要):z gzip(默认)、s zstd(推荐)、o xz(高压缩比)

使用示例

1
2
3
4
5
6
7
8
9
10
# 创建压缩包
./tar_single.sh -cz /path/to/data # gzip
./tar_single.sh -cs /path/to/data # zstd
./tar_single.sh -co /path/to/data # xz

# 解压压缩包(自动检测格式)
./tar_single.sh -x /path/to/archive_dir

# 测试完整性(自动检测格式)
./tar_single.sh -t /path/to/archive_dir

1
wget -qO- https://haies.cn/assets/deduplicate.sh

使用说明

deduplicate 是一个 Bash 脚本,用于递归分析指定目录下的重复文件和目录(内容完全相同),并根据用户选择执行删除或仅记录日志。

核心规则

  • 重复范围:仅在同一父目录下判定重复(文件和目录分开处理)
  • 遍历顺序:按目录深度从浅到深处理,先处理子目录重复,再处理文件重复
  • 保留策略:对于每个重复组,保留文件名最短且修改时间最早的一项,其余标记为待删除

自动忽略

以下项目不参与分析,也不会出现在日志中:

  • 以点(.)开头的文件和目录(隐藏项)
  • 名为 node_modules、dist、build、bin、debug 的目录(不区分大小写)

日志文件

在每个待分析目录下生成独立的日志文件,文件名格式为 .deduplicate_YYYYMMDD_HHMMSS.log。

日志仅记录重复项,每行格式为:

1
[时间戳] | 组ID | 绝对路径 | 状态

状态包括 KEEP(保留)、TO_DEL(待删除)、DELETED(已删除)。

删除模式

通过 -d 选项启用。如果指定目录下已有脚本生成的日志,则直接读取日志中状态为 TO_DEL 且仍存在的项目并执行删除,同时将对应日志行状态更新为 DELETED(不新增行)。如果无日志,则正常分析并直接删除重复项,同样只更新原日志行状态。

注意事项

⚠️ 删除不可恢复:脚本使用 rm -rf 直接删除文件和目录,请务必先备份重要数据,并在测试环境中验证脚本行为。

  • 权限要求:脚本需要对待分析目录具有读取和执行权限,对需删除项具有写权限
  • 性能提示:目录重复检测依赖 diff -rq,对于包含大量文件的目录可能较慢,请耐心等待
  • 日志积累:日志文件会永久保留,每次运行会生成新日志。删除模式下,多次运行可复用已有日志,仅更新状态

基本用法

1
deduplicate [-d] dir1 [dir2 ...]
  • -d:可选参数,启用删除模式。不加此参数时,仅将重复项记录到日志,不执行任何删除。
  • dir1 dir2 ...:必需参数,至少指定一个待分析的目录(绝对路径或相对路径均可)。

脚本会对每个目录独立处理,生成各自的日志文件。

使用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 示例 1:仅分析单个目录(不删除)
./deduplicate /home/user/documents

#分析 `/home/user/documents` 下的重复项,结果记录到 `/home/user/documents/.deduplicate_20260228_093012.log`。屏幕显示扫描进度和发现的重复组。

# 示例 2:分析多个目录
./deduplicate /home/user/docs /home/user/backup

#分别分析两个目录,各自生成日志文件,互不影响。

# 示例 3:分析并删除重复项(无现有日志)
./deduplicate -d /mnt/data/projects

#分析 `/mnt/data/projects`,发现重复组后直接删除待删除项,日志中对应行状态从 `TO_DEL` 变为 `DELETED`。屏幕显示删除进度。

# 示例 4:已有日志情况下再次运行删除模式
#假设之前已运行分析(不带 `-d`),生成了日志文件 `.deduplicate_20260228_093012.log`,其中包含一些 `TO_DEL` 项。现在执行:
./deduplicate -d /mnt/data/projects

#脚本会自动找到该目录下最新的日志,读取其中所有 `TO_DEL` 且仍存在的项目并删除,同时将日志中对应行更新为 `DELETED`。如果日志中已无 `TO_DEL` 项,则输出提示并结束。

查看日志内容

日志文件示例片段:

1
2
3
4
[2026-02-28 09:17:07] | G001 | /mnt/d/tmp/test/xs/凡人修仙传-- 忘语 -- 2017.epub | KEEP
[2026-02-28 09:17:07] | G001 | /mnt/d/tmp/test/xs/凡人修仙传-- 忘语 -- 2017 - 副本.epub | DELETED
[2026-02-28 09:17:07] | G002 | /mnt/d/tmp/test/xs/斗罗大陆 -- 唐家三少.mobi | KEEP
[2026-02-28 09:17:07] | G002 | /mnt/d/tmp/test/xs/斗罗大陆 -- 唐家三少 - 副本.mobi | DELETED

其中 G001、G002 为组ID,每个组内先显示保留项(KEEP),再按文件名升序显示已删除项(DELETED)。

附录:脚本依赖

  • Bash 4.0 或更高版本
  • 标准命令:find、sort、stat、sed、sha256sum、diff、rm 等
  • 确保脚本具有可执行权限:chmod +x deduplicate

如有任何问题或建议,请根据实际情况调整脚本或联系脚本维护者。

大型语言模型(LLM)是一个基于深度神经网络(DNN)的复杂系统。
其核心是通过海量数据训练,将文本转化为高维向量,并基于统计学
规律预测下一个词的概率分布,再通过反向传播(Backpropagation)
算法动态调整数以亿计的参数(Parameters),从而让向量编码的语义
知识(Semantic Knowledge)不断优化。

整个过程可类比于培养一位”学者”:

  • 参数规模(Model Scale):其神经基础
  • Transformer架构及其自注意力机制:其核心思维方式
  • 训练数据:其学习的”书籍”
  • 计算量:其投入的”资源”
  • 涌现能力(Emergent Abilities):量变引发的质变与创造性”顿悟”
  • 指令微调与人类对齐:社会化的沟通与伦理教育
  • 多模态能力(Multimodal Capabilities):扩展感知与交互的维度
  • 推理效率(Inference Efficiency):决定实际场景中的响应速度和实用性

这些特征相互关联,共同定义了大模型的综合能力(Capabilities)与
实用价值。

一、核心概念:理解AI如何”思考”与”生成”

🌐 基石认知

  • Transformer架构:现代大模型核心,通过”注意力机制”动态聚焦
    关键词(如读句时识别主谓宾),实现高效语义建模。

  • 向量与维度:文字→高维数字向量(如”猫”=[0.2, -1.7, 3.1…]);
    维度=特征数量(768维=768个语义特征),维度越高表达越精细。

  • 参数≠维度:参数是模型内部可学习的权重(如Qwen-Max约100亿参数),
    训练即优化参数以压缩语言规律;向量是输入经参数计算后的实时
    语义表示。

  • 训练实质:将海量文本中的模式”编码”进参数,使模型能将新输入
    映射为有意义的向量分布。

  • 生成公式:

    输出内容 = 模型(参数) + Context(对话历史/文档) + Prompt(当前指令)

    ✅ 黄金法则:Prompt清晰具体 + Context提供必要背景
    (例:”基于上文需求,用Python写…”)

🔁 关键延伸

  • 强化学习(RLHF):通过人类偏好反馈微调模型,使输出更安全、
    有用(Claude/GPT系列核心优化手段)。
  • RAG(检索增强生成):先从向量库检索相关知识(如企业文档),
    再交由LLM生成答案——解决模型”不知道私有/最新信息”的核心方案。

二、技术框架:构建AI应用的”骨架”

框架 核心价值 典型场景
LangChain / LlamaIndex 连接LLM与工具链(API/数据库)、管理对话流 智能客服、文档问答系统
RAG Pipeline 检索(向量库)+ 生成(LLM)双阶段架构 企业知识库、论文助手
pgvector PostgreSQL官方向量扩展 数据库内直接做语义搜索(”找相似产品描述”)
PGAI生态 PostgreSQL + pgvector/pgml等AI插件 减少数据搬运,数据库内嵌智能
LangGraph 构建多智能体(Agent)工作流 复杂任务拆解(写报告→画图→发邮件)

💡 实施路径:LangChain + pgvector 搭建简易RAG(GitHub模板丰富)


三、工具生态:分类与安全实践

📦 本地模型工具

工具 说明 ⚠️ 安全必读
Ollama 跨平台开源框架,支持Qwen/Llama/Gemma等百款模型本地运行;2025年7月推出Win/macOS桌面版 🔒 国家网信办2025年3月通报:默认配置存在未授权访问风险!✅ 必做:修改端口+设密码、禁用公网暴露、运行ollama serve --secure加固

🤝 AI协作工具

工具 定位 使用条件
Claude Cowork Anthropic 2026年1月发布,官方定义为”Claude Code for the rest of your work” ✅ 仅macOS(Windows版规划中)✅ 需Claude Max订阅✅ 通过Claude Desktop侧边栏启动💡 场景:整理下载文件夹、发票转Excel、会议笔记生成报告
Manus 多智能体可视化编排平台 适合非代码用户设计Agent工作流
阶跃AI(StepFun) 国产大模型平台(GLM系列) 中文场景优化,支持私有化部署

🤖 智能体平台

工具 背景 🔒 部署铁律
Moltbot(原Clawdbot) Peter Steinberger开发,2026年1月27日因Anthropic商标争议强制更名(GitHub星标8.1万+) ❌ 严禁在主力电脑全权限运行!✅ 首选:腾讯云Lighthouse / 阿里云轻量服务器✅ 必做:moltbot security audit定期扫描 + 严格限制邮箱/API权限💡 口号更新:”同样的龙虾灵魂,全新的虾壳”(图标保留)

💻 开发环境工具

类型 代表工具 说明
AI原生IDE Cursor, Trae, Windsurf 深度集成代码生成/调试,支持”对话式编程”
终端增强 Claude Code、Warp(AI命令解释)、Fig 命令行智能提示,降低CLI门槛

四、主流模型

模型系列 公司 特点 推荐场景
Claude 3.5 (Opus/Sonnet/Haiku) Anthropic Sonnet综合能力领先,Haiku极速廉价 复杂推理、长文档处理、多语言代码
Qwen (通义千问) 阿里巴巴 开源友好(Qwen-Max/Plus/Coder),中文深度优化 国内部署、代码写作、多模态
DeepSeek 深度求索 中文代码能力突出,API性价比高 中文项目开发、算法题解答
GLM4.7 智谱AI Edge轻量高效,130B开源 移动端部署、科研实验
Llama 3 / GPT-4o Meta / OpenAI 开源标杆 / 多模态响应快 学术研究、国际项目

✅ 选择策略:

  • 国内用户:GLM、Qwen、DeepSeek(访问快、中文强)
  • 国际场景:Claude 3.5 Sonnet(当前综合能力标杆)
  • 本地部署:Qwen/Mistral开源系列 + Ollama(注意安全加固!)

五、Claude能力体系:从代码到全场景协作

🔑 核心能力组件(Claude.ai平台)

概念 说明 实战价值
MCP(Model Context Protocol) 安全连接外部工具的”通用插座”(VS Code/数据库/Figma) 让Claude调用真实环境能力
Skills 预置能力模块(”解释代码””生成测试”) 一键启用,减少Prompt编写
Agents 扮演角色自主行动(”前端工程师Agent”) 结合MCP完成多步骤任务
Rules 用户设定约束(”注释用中文””禁改config”) 规范AI行为,提升可靠性
Script 用户可编写自定义脚本(Python/Shell/JS),通过MCP注册,完成特定任务 实现高度定制化自动化(如调用内部API、处理私有数据格式、执行部署命令)
Plugins 通过MCP接入的扩展(Figma→设计图转代码) 扩展应用场景边界
  1. 三种模式

    • 📝 聊天模式:日常问答
    • 💻 代码模式:专注代码生成/调试(自动识别代码块)
    • 🤖 Projects模式:管理长上下文项目(上传整个文件夹,跨文件理解)
  2. 上下文管理

    • 支持200K+ tokens上下文,可上传PDF/代码库/设计稿
    • Projects中文件自动关联,提问时智能引用相关代码
  3. 代码生成

    • ✨ Prompt:添加需求,制定PLAN
    • 🎨 上传设计图:上传设计图,明确界面
    • 🧠 Skills触发:固定开发要求
    • 💻 hook调用:格式化代码

以下是对Dan Koe长文《How to fix your entire life in one day》主要观点的总结,分为核心逻辑、关键方法论和行动建议三个部分,便于理解与实践:

一、核心逻辑:认知死亡与身份重生

  1. 颠覆式认知变革:改变的本质是“意识的迁移”,需彻底打破现有思维框架(如“农民讨论皇帝用金锄头”的比喻),承认当前认知局限是问题的根源。
  2. 杀死旧身份,诞生新自我:必须主动“干掉现在的自己”,通过身份重构(而非零星习惯调整)实现根本转变。身份决定视角,视角决定世界。
  3. 舒适区的危险:温水煮青蛙式的“还凑合”生活是最大陷阱,真正的痛苦反而是改变的催化剂。

二、关键方法论:打破惯性,重塑系统

  1. 反向愿景法(Anti-Vision):
  • 聚焦“不想成为谁”:通过具象化5年后若不改变的惨淡生活(如“悲惨的周二早晨”),用恐惧驱动行动。
  • 痛苦作为燃料:经历“失调(忍无可忍)→ 不确定(迷茫)→ 发现(爆发)”三阶段。
  1. 打断自动驾驶,强制反思:
  • 设置随机闹钟:通过提问打断日常惯性(如“我在逃避什么?”“此刻行为让我靠近理想还是远离?”)。
  • 深层自我追问:剖析隐藏行为动机(如拖延本质是逃避评判,而非缺乏自律)。
  1. 人生游戏化(Gamification):
  • 将生活设计为可操作的“游戏系统”:设定目标(BOSS)、分解任务(关卡)、即时反馈(经验值)、建立抗干扰“力场”。
  • 接纳混乱,策略性冗余:如俄罗斯方块中“平整堆叠”应对不确定的生活挑战,避免依赖完美解决方案。

三、行动建议:一日重启程序

  1. 上午:掘地三尺看清现状:直面当前困境,诊断深层问题。
  2. 白天:持续打断惯性:通过闹钟提问、环境重构(如更换工作场景)摆脱舒适区。
  3. 晚上:压缩洞见为行动结构:
  • 身份重新定位:明确“我是谁”(新身份认同)。
  • 构建可执行系统:将新身份转化为具体行为准则与每日习惯。
  1. 长期维持:反馈循环与身份强化:
  • 践行八步循环:目标→感知现实→学习→行动→反馈→内化认同→防御干扰→新目标。
  • 成为“通才型思考者”:融合多领域知识,提升系统思维。

四、颠覆性洞见

  • 行动胜于言语:改变始于行为,而非口号(如减肥者需先内化新生活方式,而非等待结果)。
  • 智慧即人生掌控:通过“设定目标→行动→感知→比较→调整”的反馈循环,持续迭代。
  • 概率与韧性:接受生活随机性,构建抗脆弱系统(如预留冗余空间)。

总结:文章强调改变需从认知颠覆开始,通过反向激励、系统性重构和游戏化思维,将“身份重生”转化为可操作的日常实践,最终在混乱中建立掌控感。

希望这篇总结能帮助你快速掌握Dan Koe的核心思想!如果需要进一步探讨某个观点,请随时告诉我。
by Qwen3-Max

以下是针对生产环境的GeoServer系统配置与数据发布完整教程,
涵盖Docker化部署、影像与矢量发布全流程。

一、系统配置:基于Docker部署

1. 目录结构与文件准备

1
2
3
4
5
6
geoserver-production/          # 项目根目录
├── docker-compose.yml # Docker Compose 编排文件
├── .env # 环境变量文件(用于隔离敏感信息)
├── geoserver_data/ # GeoServer 主数据目录
├── geoserver_gwc/ # GeoWebCache 瓦片缓存
└── geoserver_logs/ # 应用日志目录

2. 关键环境变量详解(部署核心)

karotza/docker-geoserver 完全通过环境变量配置 GeoServer 核心行为,
以下是启动容器时最关键的环境变量分类及说明:

| 参数名称 | 描述与作用 | 建议值 / 示例 | 关键配置要点 |
| :— | :— | :— |
| GEOSERVER_DATA_DIR | GeoServer 主数据目录,用于存储工作区、数据存储、样式等所有配置信息。 | /opt/geoserver_data/data | 必须通过卷(volumes)挂载到宿主机,实现配置持久化,避免容器重启后数据丢失。 |
| GEOWEBCACHE_CACHE_DIR | GeoWebCache 瓦片缓存目录,用于存储预生成的栅格式或矢量瓦片文件。 | /opt/geoserver_data/gwc | 同样必须挂载持久化。 |

  1. 生产环境建议使用高速存储(如SSD)。

  2. 需定期清理旧缓存或设置磁盘配额。 |
    | GEOSERVER_ADMIN_USER | 管理员用户名。出于安全考虑,建议修改默认值。 | 自定义(如:gs_admin) | 与强密码配合使用。仅在初始设置时生效,之后在Web界面修改。 |
    | GEOSERVER_ADMIN_PASSWORD | 管理员密码。这是最关键的安全设置。 | 自定义(强密码) | 必须修改。使用高强度密码(如:MyGeo0S3rv3r!2024)。可通过.env文件管理,避免硬编码。 |
    | INITIAL_MEMORY | JVM 堆内存初始大小。 | 2g | 通常设置为与 MAXIMUM_MEMORY 相同,以避免运行时动态调整带来的性能开销。 |
    | MAXIMUM_MEMORY | JVM 堆内存最大大小。对性能影响最大。 | 4g 或 8g | 1. 黄金法则:不超过宿主机可用物理内存的75%。 |

  3. 对于大量瓦片或高并发,建议设置为 8g 或更高。 |
    | STABLE_EXTENSIONS | 预安装的官方稳定插件列表。用逗号分隔。 | vector-tiles,monitor,importer | 1. vector-tiles(矢量瓦片)是必选项。

  4. monitor 用于生产监控。

  5. importer 方便数据导入。 |
    | COMMUNITY_EXTENSIONS | 预安装的社区插件列表。用逗号分隔。 | control-flow,backup-restore | 1. control-flow 可控制并发请求,防止过载。

  6. backup-restore 便于配置备份。 |
    | GEOSERVER_CONTEXT_ROOT | Web 应用的上下文路径(URL路径)。 | /geoserver | 默认即为 /geoserver,访问地址为 http://host:port/geoserver。非特殊需求无需修改。 |
    | ROOT_WEBAPP_REDIRECT | 是否将根路径(/)重定向到 GeoServer 应用。 | true | 设置为 true 后,访问 http://host:8080/ 会自动跳转到 http://host:8080/geoserver/web,非常便利。 |
    | CONSOLE_HANDLER_LEVEL | 控制台日志输出级别,影响 Docker 日志的详细程度。 | INFO | 1. INFO:常规生产级别,记录重要事件。

  7. DEBUG:调试时使用,日志量巨大。

  8. WARN:仅记录警告和错误。 |

将上表参数整合到一个 docker-compose.yml 文件中,其核心部分如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
services:
geoserver:
image: karotza/geoserver:latest
container_name: prod_geoserver
environment:
- GEOSERVER_ADMIN_USER=${GEOSERVER_ADMIN_USER}
- GEOSERVER_ADMIN_PASSWORD=${GEOSERVER_ADMIN_PASSWORD}
- GEOSERVER_DATA_DIR=/opt/geoserver/data_dir
- GEOWEBCACHE_CACHE_DIR=/opt/geoserver/gwc
- INITIAL_MEMORY=${INITIAL_MEMORY}
- MAXIMUM_MEMORY=${MAXIMUM_MEMORY}
- STABLE_EXTENSIONS=${STABLE_EXTENSIONS}
- COMMUNITY_EXTENSIONS=${COMMUNITY_EXTENSIONS}
- ROOT_WEBAPP_REDIRECT=true
- CONSOLE_HANDLER_LEVEL=${CONSOLE_HANDLER_LEVEL}
volumes:
- ./geoserver_data:/opt/geoserver/data_dir
- ./geoserver_gwc:/opt/geoserver/gwc
- ./geoserver_logs:/opt/geoserver/logs
ports:
- "8080:8080"

3. 日常运维命令

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
# 1. 前台启动(调试用,实时看日志)
docker-compose up

# 2. 后台启动(生产环境首选,不占用终端)
docker-compose up -d

# 3. 强制重新构建(仅修改Dockerfile/镜像后使用,修改环境变量无需此参数)
docker-compose up -d --build

# 4. 停止容器(保留容器和数据)
docker-compose stop

# 5. 重启容器(修改配置后生效)
docker-compose restart geoserver

# 6. 停止并删除容器(保留数据卷,仅删容器)
docker-compose down

# 7. 查看实时日志(排查启动/运行问题)
docker-compose logs -f geoserver

# 8. 查看最近100行日志(快速定位错误)
docker-compose logs --tail=100 geoserver

# 9. 进入容器(手动安装插件/调试)
docker exec -it prod_geoserver /bin/bash

核心配置优先级:数据目录持久化(必配)> 密码修改(必改)> 内存分配(性能关键)> 插件/跨域(按需配置)。

在 GeoServer 中发布 GeoTIFF 格式影像并启用瓦片缓存(通过 GeoWebCache, GWC)的标准步骤如下,适用于大多数 Web 地图应用场景。


二、影像数据发布

1. 准备 GeoTIFF 文件

  • 确保文件具有正确的地理参考信息(坐标系、范围等)。
  • 建议使用 EPSG:3857(cgcs2000)、EPSG:4326(cgcs2000_3_gk_120E)、EPSG:4490(WGS84)或 EPSG:4326(Web Mercator)以兼容主流地图客户端。

2. 登录 GeoServer 管理界面

  • 默认地址:http://localhost:8080/geoserver

3. 创建 Coverage Store

  • 导航:数据 > Stores > Add new Store
  • 选择 GeoTIFF(位于 “Raster Data Sources” 下)
  • 配置参数:
    • Workspace:选择或新建工作空间
    • Data Source Name:输入名称(如 my_geotiff_store)
    • URL:填写 GeoTIFF 文件路径(如 file:/path/to/your/image.tif)
    • 点击 Save

4. 发布图层(Layer)

  • GeoServer 会自动跳转到图层发布页面
  • 设置关键参数:
    • Name:图层名称(如 my_raster_layer)
    • Declared SRS:建议设为文件实际坐标系(如 EPSG:3857)
    • Bounding Boxes:点击 “Compute from data” 和 “Compute from SRS bounds”
    • 保存图层

5. 启用并配置瓦片缓存(GWC)

  • 进入:Tile Caching > Tile Layers
  • 找到刚发布的图层(如 workspace:my_raster_layer),点击进入
  • 配置缓存选项:
    • Enabled:勾选
    • Grid Sets:至少勾选 EPSG:4326 和/或 EPSG:3857
    • Formats:选择输出格式(如 image/png、image/jpeg)
    • (可选)设置缓存目录、过期策略等

6. 预生成(Seed)瓦片(可选但推荐)

  • 在同一页面点击 Seed/Truncate
  • 选择:
    • Operation: Seed
    • Grid Set: 如 EPSG:3857
    • Zoom Start / Stop: 指定要缓存的级别(如 0 到 12)
    • Format: 与上一步一致
    • 点击 Submit 开始切片(后台运行)

7. 访问瓦片服务

  • WMS(推荐用于瓦片地图):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    http://localhost:8080/geoserver/gwc/service/wmts?
    REQUEST=GetCapabilities&
    SERVICE=WMTS&
    VERSION=1.0.0&
    LAYER=workspace:my_raster_layer&
    STYLE=&
    TILEMATRIXSET=EPSG:4326&
    TILEMATRIX={z}&
    TILEROW={y}&
    TILECOL={x}&
    FORMAT=image/png
  • TMS:

    1
    http://localhost:8080/geoserver/gwc/service/tms/1.0.0/workspace:my_raster_layer@EPSG:4326@png/{z}/{x}/{-y}.png

提示

  • 首次访问未缓存的瓦片时,GeoServer 会动态生成并自动缓存。
  • 预切片(Seed)可显著提升高并发下的性能。
  • 确保 GeoServer 有足够磁盘空间存放缓存(默认在 GEOSERVER_DATA_DIR/gwc)。

通过以上步骤,即可成功在 GeoServer 中发布 GeoTIFF 影像,并通过内置的 GeoWebCache 实现高效瓦片服务。

三、ESRI ARCGIS影像瓦片发布

瓦片数据准备

确保ArcGIS瓦片目录结构正确:

1
2
3
4
5
6
7
arcgis-cache/
├── conf.xml # 瓦片方案配置文件
├── _alllayers/ # 瓦片数据目录
│ ├── L00/ # 金字塔层级
│ ├── L01/
│ └── ...
└── ArcGIS_瓦片_使用说明.txt

步骤 1:获取并安装 ArcGIS 瓦片插件

  1. 下载插件:

    • 从 GeoWebCache 官网 下载对应版本的 ArcGIS 插件(如 gwc-arcgiscache-1.25.4.jar)
    • 确保插件版本与 GeoServer 版本匹配
  2. 安装插件:

    1
    2
    # 将插件复制到 GeoServer 的 lib 目录
    cp gwc-arcgiscache-1.25.4.jar /path/to/geoserver/webapps/geoserver/WEB-INF/lib/

步骤 2:配置 GeoServer

2.1 配置缓存目录(可选但推荐)

  1. 编辑 geoserver/webapps/geoserver/WEB-INF/web.xml:

    1
    2
    3
    4
    <context-param>
    <param-name>GEOWEBCACHE_CACHE_DIR</param-name>
    <param-value>/path/to/your/cache/directory</param-value>
    </context-param>
  2. 重启 GeoServer 使配置生效

2.2 配置 geowebcache.xml

  1. 编辑 geoserver/data_dir/gwc/geowebcache.xml

  2. 在 <layers> 标签内添加 ArcGIS 瓦片配置:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <layers>
    <arcgisLayer>
    <name>your_layer_name</name>
    <tilingScheme>/path/to/your/conf.xml</tilingScheme>
    <!-- 可选:指定切片目录(默认为 conf.xml 同级 _allLayers) -->
    <tileCachePath>/path/to/your/tiles</tileCachePath>
    <!-- 可选:若 ArcGIS 使用十六进制层级名(如 L00),设为 true -->
    <hexZoom>false</hexZoom>
    </arcgisLayer>
    </layers>

    参数说明:

    • name:在 GeoServer 中显示的图层名称
    • tilingScheme:ArcGIS 生成的 conf.xml 文件路径
    • tileCachePath:瓦片存储目录(与 ArcGIS 生成的瓦片目录一致)

步骤 3:发布瓦片

  1. 重启 GeoServer(使插件和配置生效)

  2. 验证瓦片服务:

    • 访问 http://your-geoserver/geoserver/gwc/service/wmts?REQUEST=GetCapabilities
    • 检查响应中是否包含你的 ArcGIS 瓦片图层
  3. 预览瓦片:

    • 进入 GeoServer 管理界面:http://your-geoserver/geoserver/web
    • 导航到 Tile Layers > 选择你的图层 > Preview
    • 选择合适的坐标系和格式进行预览

4. 性能优化配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!-- geoserver-data/gwc/geowebcache.xml 优化配置 -->
<gwcConfiguration xmlns="http://geowebcache.org/schema/1.12.0">
<layers>
<!-- 其他 wmsLayer 可共存 -->

<arcgisLayer>
<name>naturalearth</name>
<tilingScheme>/opt/cache/naturalearth/Layers/conf.xml</tilingScheme>
<tileCachePath>/opt/cache/naturalearth/_allLayers</tileCachePath>
<hexZoom>false</hexZoom>
</arcgisLayer>

</layers>
</gwcConfiguration>

关键配置说明

配置项 说明 示例
tilingScheme ArcGIS 的 conf.xml 文件路径 /opt/geoserver/gwc/arcgis-cache/conf.xml
tileCachePath 瓦片存储目录 /opt/geoserver/gwc/arcgis-cache/_allLayers
name GeoServer 中显示的图层名称 arcgis-cache
hexZoom 是否使用十六进制缩放级别 false

验证瓦片服务

瓦片服务 URL 格式:

1
2
3
4
5
6
7
8
9
10
11
http://localhost:8080/geoserver/gwc/service/wmts?
REQUEST=GetCapabilities&
SERVICE=WMTS&
VERSION=1.0.0&
LAYER=workspace:your_layer_name&
STYLE=&
TILEMATRIXSET=EPSG:4326&
TILEMATRIX={z}&
TILEROW={y}&
TILECOL={x}&
FORMAT=image/png

常见问题解决

  1. 瓦片路径不匹配:

    • 检查 tilingScheme 和 tileCachePath 路径是否与实际瓦片目录一致
    • 确保路径使用正斜杠 /(Windows 系统中可使用正斜杠)
  2. 插件未加载:

    • 检查 WEB-INF/lib 中是否包含插件 JAR 文件
    • 重启 GeoServer
  3. 瓦片显示异常:

    • 检查瓦片坐标系是否与 GeoServer 一致
    • 确认瓦片范围与坐标系匹配

四、矢量数据发布教程

在 GeoServer 中基于 PostgreSQL/PostGIS 数据库发布 WMS(Web Map Service)
和 矢量瓦片(Vector Tiles,如 MVT/PBF 格式) 是现代 Web GIS 应用的核心能力。
以下是清晰、完整的配置步骤总结:

前提条件

  1. PostgreSQL + PostGIS 已安装并启用
    • 确保目标表已添加空间索引(CREATE INDEX ON table USING GIST(geom);)
    • 表中包含 geometry 或 geography 类型字段
  2. GeoServer 已安装(建议 2.20+)
  3. PostGIS 插件已启用(通常默认包含)

步骤一:在 GeoServer 中连接 PostgreSQL 数据库

  • 进入 Data > Stores > Add new Store

  • 选择 PostGIS (JNDI not required)(或直接选 “PostGIS”)

  • 配置参数:

    1
    2
    3
    4
    5
    6
    7
    8
    Workspace:          your_workspace (e.g., "cite")
    Data Source Name: postgis_store
    Host: your-db-host (e.g., localhost)
    Port: 5432
    Database: your_db_name
    Schema: public (or your schema)
    User: db_user
    Password: db_password
  • 勾选 “Expose primary keys”(对矢量瓦片性能有帮助)

  • 点击 Save

若使用 Docker 部署 GeoServer,确保容器能访问 PostgreSQL(网络互通)。


步骤二:发布矢量图层(WMS 基础)

  • 在 Store 创建后,点击 Publish 发布新图层
  • 设置:
    • Declared SRS: 与数据一致(如 EPSG:4326 或 EPSG:3857)
    • Bounding Boxes: 点击 “Compute from data” 和 “Compute from SRS bounds”
    • 配置样式(Style):
    • 可使用默认 polygon, line, point 样式
    • 或自定义 SLD/CSS 样式

此时 WMS 服务已可用:

1
2
3
4
5
6
7
8
9
10
http://localhost:8080/geoserver/wms?
service=WMS&
version=1.1.0&
request=GetMap&
layers=workspace:layer_name&
styles=&
bbox=minx,miny,maxx,maxy&
width=800&height=600&
srs=EPSG:4326&
format=image/png

步骤三:启用矢量瓦片(MVT / PBF)支持

GeoServer 从 2.11+ 开始原生支持 Mapbox Vector Tiles (MVT) 格式。

确认 MVT 输出格式已启用

  • 进入 Settings > Global Settings
  • 检查 Vector Tile Formats 是否包含 application/vnd.mapbox-vector-tile(通常默认启用)

若未显示,需确认 gt-mbtiles 或 gt-vectortiles 插件已安装(现代版本通常内置)。

配置图层的矢量瓦片输出

  • 进入图层编辑页:Layers > your_layer > Tile Caching

  • 在 Tile Image Formats 中勾选:

    • application/vnd.mapbox-vector-tile
  • (可选)在 Vector Tile 选项卡中:

    • 设置 Clipping(是否裁剪到瓦片边界)
    • 设置 Simplification(简化几何以提升性能)

预生成或动态请求矢量瓦片

方式 A:动态请求(推荐用于交互式地图)

客户端直接请求 MVT 瓦片 URL:

1
http://localhost:8080/geoserver/gwc/service/tms/1.0.0/workspace:layer_name@EPSG:4326@pbf/{z}/{x}/{-y}.pbf

注意:TMS 使用 -y(翻转 Y 轴),而 XYZ 用 y。Leaflet/OpenLayers 通常用 TMS 模式。

或通过 WMS 兼容接口(GeoServer 特有):

1
2
3
4
5
6
7
8
9
10
http://localhost:8080/geoserver/workspace/wms?
service=WMS&
version=1.1.0&
request=GetMap&
layers=layer_name&
format=application/vnd.mapbox-vector-tile&
tiled=true&
tileOrigin=lon,lat&
width=256&height=256&
bbox={bbox}

方式 B:预切片缓存(高并发场景)

  • 进入 Tile Caching > Seed/Truncate
  • 选择:
    • Format: application/vnd.mapbox-vector-tile
    • Grid Set: EPSG:4326(Web Mercator)
    • Zoom levels: 如 0–14
    • 点击 Submit 后台生成 .pbf 缓存

缓存路径:GEOSERVER_DATA_DIR/gwc/workspace_layer_name_EPSG_4326/application.x-protobuf.type=mapbox-vector/...


客户端调用示例(OpenLayers)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// WMS 图层(栅格)
const wmsLayer = new ol.layer.TileWMS({
source: new ol.source.TileWMS({
url: 'http://localhost:8080/geoserver/wms',
params: { LAYERS: 'workspace:layer_name' }
})
});

// 矢量瓦片图层(MVT)
const mvtLayer = new ol.layer.VectorTile({
source: new ol.source.VectorTile({
format: new ol.format.MVT(),
url: 'http://localhost:8080/geoserver/gwc/service/tms/1.0.0/' +
'workspace:layer_name@EPSG:4326@pbf/{z}/{x}/{-y}.pbf'
})
});

性能优化建议

优化项 说明
空间索引 确保 PostGIS 表有 GIST 索引
主键暴露 Store 中勾选 Expose primary keys
简化几何 在 Vector Tile 设置中启用简化
限制属性 在图层”Fields”选项卡中只发布必要字段
缓存策略 高频访问区域预瓦片(Seed)
内存调优 增加 GeoServer JVM 内存(如 -Xmx4g)

验证清单

  • PostgreSQL 表含有效 geometry 字段
  • GeoServer 成功连接 PostGIS Store
  • WMS 图层可预览(PNG/JPEG)
  • 图层启用了 application/vnd.mapbox-vector-tile 格式
  • 能通过 TMS/WMS 接口获取 .pbf 瓦片
  • 客户端(如 OpenLayers、MapLibre)成功加载矢量瓦片
0%