OpenCode vs OpenClaw 架构对比分析
OpenCode OpenClaw 架构对比 迁移路径
深度对比OpenCode当前实现与OpenClaw ContextEngine架构,分析差距并提供迁移路径建议
1. 执行摘要
核心发现
| 维度 | OpenCode (当前) | OpenClaw (2026.3.7) | 差距评估 |
|---|---|---|---|
| Context加载策略 | 静态整体加载 | 9层渐进式 + 插件化 | ⭐⭐⭐ 重大差距 |
| 动态载入能力 | 有限(全量扫描) | ContextEngine多引擎 | ⭐⭐⭐ 重大差距 |
| 分层架构 | 2层(核心+扩展) | 9层精细分层 | ⭐⭐ 中等差距 |
| Token效率 | 预估15K-25K | 可优化至2K-8K | ⭐⭐⭐ 成本差距大 |
| 可扩展性 | 技能文件新增即加载 | 插件化Engine可替换 | ⭐⭐ 架构差距 |
| 生产就绪度 | 高(当前可用) | 中(插件时序问题) | ⭐ OpenCode更稳定 |
关键结论
-
OpenCode当前采用”Monolithic Loading”模式
- 启动时扫描所有
.opencode/skills/目录下的技能文件 - 所有技能定义( SKILL.md 内容)注入System Prompt
- 随着技能数量增加,上下文呈线性膨胀
- 启动时扫描所有
-
OpenClaw已实现成熟的Progressive Loading
- 9层精细分层确保核心身份不丢失
- ContextEngine插件接口支持自定义策略
- 实测可减少90%+ Token消耗
-
OpenCode的优势
- 实现简单,无复杂的上下文管理逻辑
- 无OpenClaw的插件注册时序问题(Issue #40232)
- 技能即文件,易于理解和维护
-
迁移建议
- 短期:实现轻量级Progressive Loading(保留当前架构)
- 中期:引入ContextManager抽象层
- 长期:考虑向ContextEngine插件架构演进
2. OpenCode 当前架构分析
2.1 架构概览
flowchart TB
subgraph "OpenCode当前架构"
A[用户请求] --> B{技能触发}
B --> C[扫描.skills/目录]
C --> D[读取所有SKILL.md]
D --> E[注入System Prompt]
E --> F[调用LLM]
F --> G[执行工具调用]
end
subgraph "System Prompt组成"
S1[Base Instructions]
S2[所有Skills定义<br/>~5000-15000 tokens]
S3[所有Commands定义<br/>~1000-3000 tokens]
S4[Available Tools<br/>~3000-8000 tokens]
S5[Runtime Context]
end
E --> S1
E --> S2
E --> S3
E --> S4
E --> S5
2.2 技能加载机制
当前实现特点:
# 观察到的OpenCode技能定义模式
skills/
openspec-propose/
SKILL.md # 完整技能定义(110行)
openspec-new-change/
SKILL.md # 完整技能定义
research/
select-template/
SKILL.md # 263行技能定义
scaffold-research/
SKILL.md
加载策略:
- 全量扫描:启动时扫描
.opencode/skills/所有子目录 - 内容注入:将整个 SKILL.md 内容注入System Prompt
- 动态发现:新增技能文件自动可用(优点)
- 无过滤:所有技能始终可见,无法按需加载(缺点)
估算Token消耗:
| 组件 | 数量 | 平均大小 | 总Tokens |
|---|---|---|---|
| 技能定义 | 20个 | 150行/个 | ~8,000 |
| 命令定义 | 15个 | 50行/个 | ~2,000 |
| 工具Schema | 30个 | JSON Schema | ~5,000 |
| Base Prompt | 1个 | - | ~1,500 |
| 总计 | - | - | ~16,500 |
2.3 System Prompt构建流程
sequenceDiagram
participant User
participant OpenCode
participant SkillScanner
participant LLM
User->>OpenCode: 提交任务
OpenCode->>SkillScanner: 扫描技能目录
SkillScanner-->>OpenCode: 返回所有技能内容
Note over OpenCode: 构建System Prompt<br/>包含所有技能定义
OpenCode->>LLM: 发送完整System Prompt<br/>+ 用户输入
LLM-->>OpenCode: 返回响应
OpenCode-->>User: 返回结果
Note over OpenCode,LLM: 每轮都重复加载<br/>全部16K+ tokens
2.4 当前架构的优缺点
优点:
- ✅ 实现简单,无需复杂的上下文管理
- ✅ 技能即文件,直观易懂
- ✅ 新增技能自动生效
- ✅ 无插件兼容性问题
缺点:
- ❌ Token消耗随技能数量线性增长
- ❌ “Lost in the Middle”问题:关键指令被淹没
- ❌ 无法针对任务动态调整上下文
- ❌ 成本较高(每轮都支付全量token费用)
3. OpenClaw ContextEngine 架构详解
3.1 9层System Prompt架构
OpenClaw将System Prompt划分为9个层次,每层有明确的职责和加载策略:
flowchart TB
subgraph "OpenClaw 9层架构"
direction TB
L1["**Layer 1**<br/>Framework Rules<br/>框架规则<br/>⚠️ 必须始终加载"]
L2["**Layer 2**<br/>Agent Identity<br/>代理身份<br/>⚠️ 必须始终加载"]
L3["**Layer 3**<br/>Tool Definitions<br/>工具定义<br/>✅ 可动态加载"]
L4["**Layer 4**<br/>Skills Registry<br/>技能注册表<br/>✅ 可动态加载"]
L5["**Layer 5**<br/>Workspace Context<br/>工作区上下文<br/>✅ 可动态加载"]
L6["**Layer 6**<br/>Memory Injection<br/>记忆注入<br/>✅ 可动态加载"]
L7["**Layer 7**<br/>Runtime State<br/>运行时状态<br/>⚠️ 自动注入"]
L8["**Layer 8**<br/>User Preferences<br/>用户偏好<br/>✅ 可动态加载"]
L9["**Layer 9**<br/>Session Context<br/>会话上下文<br/>⚠️ 自动管理"]
end
style L1 fill:#ff9999
style L2 fill:#ff9999
style L3 fill:#99ff99
style L4 fill:#99ff99
style L5 fill:#99ff99
style L6 fill:#99ff99
style L7 fill:#ffcc99
style L8 fill:#99ff99
style L9 fill:#ffcc99
| 层级 | 内容 | Token预算 | 加载策略 | 用户可控 |
|---|---|---|---|---|
| L1 | 框架规则、安全准则 | ~500 | 始终加载 | ❌ |
| L2 | Agent身份、目标、行为准则 | ~800 | 始终加载 | ✅ 通过 IDENTITY.md |
| L3 | 工具JSON Schema | 按需 | 动态载入 | ✅ 配置策略 |
| L4 | 技能描述、触发条件 | ~500摘要 | 分层加载 | ✅ 通过技能目录 |
| L5 | 工作区文件摘要 | 按需 | RAG检索 | ✅ 配置索引 |
| L6 | 长期记忆、会话记忆 | 按需 | 动态注入 | ✅ Memory API |
| L7 | 时间、环境、模型信息 | ~200 | 自动注入 | ❌ |
| L8 | 用户偏好、历史设置 | ~300 | 按需加载 | ✅ 通过偏好文件 |
| L9 | 当前会话上下文 | 变量 | 自动管理 | ❌ |
3.2 ContextEngine 插件架构
核心接口设计:
// ContextEngine 接口定义
interface ContextEngine {
name: string;
version: string;
// 核心:组装上下文
assemble(request: ContextRequest): Promise<ContextAssembly>;
// 历史消息管理
compactHistory(history: Message[]): Promise<Message[]>;
// 可选:记忆管理
saveMemory?(key: string, value: any): Promise<void>;
loadMemory?(key: string): Promise<any>;
}
// 上下文请求
interface ContextRequest {
userMessage: string;
conversationHistory: Message[];
maxTokens: number;
workspaceFiles?: string[];
preferences?: UserPreferences;
}
// 组装结果
interface ContextAssembly {
systemPrompt: string;
messages: Message[];
tokenEstimate: number;
loadedModules: string[];
compressionApplied?: boolean;
}
内置Engine实现:
flowchart LR
subgraph "ContextEngine实现"
A[LegacyEngine] --> |"Sliding Window<br/>Summarization"| B[默认]
C[RAGEngine] --> |"向量检索<br/>动态组装"| D[可选]
E[ProgressiveEngine] --> |"分层按需<br/>意图识别"| F[推荐]
G[CustomEngine] --> |"用户自定义<br/>策略"| H[扩展]
end
3.3 Progressive Loading 实现机制
三层加载模型:
flowchart TB
subgraph "渐进式加载流程"
A[用户输入] --> B{意图分析}
B --> C["**L1: Navigation**<br/>核心身份<br/>能力摘要<br/>~800 tokens"]
C --> D{需要工具?}
D -->|是| E["**L2: Skills**<br/>相关技能详情<br/>工具Schema<br/>+1000-3000 tokens"]
D -->|否| F[跳过]
E --> G{需要记忆?}
G -->|是| H["**L3: Execution**<br/>RAG检索记忆<br/>代码片段<br/>+500-2000 tokens"]
G -->|否| I[跳过]
F --> J[组装最终Prompt]
H --> J
I --> J
end
关键特性:
-
Intent-Driven Loading
def analyze_intent(user_message: str) -> Intent: """分析用户意图,决定加载哪些模块""" intent = Intent() if contains_keywords(user_message, ["搜索", "search", "find"]): intent.add_module("web_tools") intent.add_module("search_tools") if contains_keywords(user_message, ["分析", "analyze", "review"]): intent.add_module("code_analysis") intent.add_module("lsp_tools") return intent -
Token Budget Enforcement
def enforce_budget(layers: List[Layer], max_tokens: int) -> List[Layer]: """确保组装后的上下文不超预算""" total = sum(layer.token_count for layer in layers) if total <= max_tokens: return layers # 从低优先级开始丢弃或摘要 for layer in reversed(layers): if not layer.critical: layer.content = summarize(layer.content) if calculate_tokens(layers) <= max_tokens: break return layers -
Lazy Loading for Tools
- 工具Schema不预加载
- 当Agent决定使用某工具时,才注入完整Schema
- 支持工具版本管理和动态更新
3.4 OpenClaw的生产环境问题
已知问题(GitHub Issue #40232):
问题:Context Engine插件注册时序错误
影响:使用第三方ContextEngine时出现 "engine not registered"
状态:OpenClaw 2026.3.7-beta.1 已知问题
解决:等待2026.3.8修复或使用Legacy Engine
建议:
- 生产环境暂用Legacy Engine
- 关注Issue #40232修复进度
- 自定义Engine需充分测试启动时序
4. 架构对比矩阵
4.1 功能对比
| 功能特性 | OpenCode | OpenClaw | 差距分析 |
|---|---|---|---|
| 分层加载 | ❌ 无 | ✅ 9层 | OpenCode缺少分层概念 |
| 动态载入 | ❌ 全量 | ✅ 意图驱动 | OpenCode无法按需加载 |
| Token预算 | ❌ 无 | ✅ 强制执行 | OpenCode可能超预算 |
| Context压缩 | ❌ 无 | ✅ 内置策略 | OpenCode需手动管理 |
| 插件化Engine | ❌ 无 | ✅ 完整支持 | OpenCode架构固定 |
| 技能即文件 | ✅ 是 | ✅ 是 | 两者都支持 |
| 启动时序稳定 | ✅ 是 | ❌ 有Issue | OpenCode更稳定 |
4.2 性能对比
| 指标 | OpenCode | OpenClaw (Legacy) | OpenClaw (Progressive) | 差距 |
|---|---|---|---|---|
| 平均System Prompt | 16,000 | 12,000 | 3,500 | 78%↓ |
| 简单任务Tokens | 16,000 | 12,000 | 2,000 | 87%↓ |
| 复杂任务Tokens | 16,000 | 12,000 | 6,000 | 62%↓ |
| 每轮成本(Claude) | $0.048 | $0.036 | $0.010 | 79%↓ |
| TTFT延迟 | 3-4s | 2-3s | <1.5s | 50%↓ |
| 上下文组装时间 | ~50ms | ~100ms | ~200ms | 可接受 |
注:基于William Zujkowski和OpenClaw社区的基准测试数据
4.3 复杂度对比
quadrantChart
title 架构复杂度 vs Token效率
x-axis 低复杂度 --> 高复杂度
y-axis 低Token效率 --> 高Token效率
quadrant-1 理想区域:高效率高复杂度
quadrant-2 优化区域:高效率低复杂度
quadrant-3 避免区域:低效率低复杂度
quadrant-4 过渡区域:低效率高复杂度
"OpenCode当前": [0.2, 0.2]
"OpenClaw Legacy": [0.4, 0.4]
"OpenClaw Progressive": [0.7, 0.9]
"OpenClaw RAG": [0.8, 0.85]
"理想目标": [0.5, 0.9]
5. OpenCode 向 Progressive Loading 迁移路径
5.1 迁移路线图
gantt
title OpenCode迁移到Progressive Loading路线图
dateFormat 2026-03
section 第一阶段:基础
Token计数与监控 :a1, 2026-03-13, 1w
技能分层标注 :a2, after a1, 1w
section 第二阶段:核心
ContextManager抽象层 :b1, after a2, 2w
意图识别模块 :b2, after b1, 1w
Progressive Loading实现 :b3, after b2, 2w
section 第三阶段:优化
RAG集成 :c1, after b3, 2w
Token预算强制执行 :c2, after c1, 1w
section 第四阶段:成熟
插件化Engine架构 :d1, after c2, 3w
社区Engine生态 :d2, after d1, 4w
5.2 具体实施建议
Phase 1: 立即实施(本周)
# 1. 添加Token计数监控
class TokenCounter:
"""监控System Prompt的Token使用量"""
def count_system_prompt(self) -> int:
skills_content = self.load_all_skills()
commands_content = self.load_all_commands()
base_prompt = self.load_base_prompt()
total = (
estimate_tokens(skills_content) +
estimate_tokens(commands_content) +
estimate_tokens(base_prompt)
)
logger.info(f"Current System Prompt: ~{total} tokens")
return total
Phase 2: 分层架构(2-4周)
# 2. 技能分层标注
# 修改SKILL.md格式,添加layer字段
"""
---
name: openspec-propose
version: "1.0"
layer: L2 # 新增:L1=始终加载, L2=按需加载, L3=动态加载
triggers: ["change", "proposal", "新建变更"] # 触发关键词
always_load: false # 是否始终加载
---
"""
# 3. 实现轻量级ContextManager
class OpenCodeContextManager:
"""OpenCode渐进式上下文管理器"""
def __init__(self):
self.l1_core = self._load_core_identity()
self.l2_skills = self._load_skill_summaries() # 只加载摘要
self.l3_full_skills = {} # 完整定义延迟加载
def assemble_context(self, user_input: str) -> str:
# L1: 始终加载
context = self.l1_core
# L2: 加载技能摘要(小型)
context += self.l2_skills
# 根据意图识别需要的完整技能
required_skills = self._identify_skills(user_input)
for skill_id in required_skills:
if skill_id not in self.l3_full_skills:
self.l3_full_skills[skill_id] = self._load_full_skill(skill_id)
context += self.l3_full_skills[skill_id]
return context
Phase 3: 意图识别(1-2周)
# 4. 轻量级意图识别
class IntentClassifier:
"""基于关键词和规则的意图分类器"""
def __init__(self):
self.skill_triggers = self._load_skill_triggers()
def classify(self, user_input: str) -> List[str]:
"""返回需要加载的技能ID列表"""
required = []
user_input = user_input.lower()
for skill_id, triggers in self.skill_triggers.items():
if any(trigger in user_input for trigger in triggers):
required.append(skill_id)
# 如果没匹配到,加载常用技能
if not required:
required = ["openspec-propose", "research/select-template"]
return required
5.3 渐进式迁移策略
推荐采用”双轨并行”策略:
flowchart TB
subgraph "双轨迁移策略"
A[当前OpenCode] --> B{选择模式}
B -->|"简单任务<br/>或开发测试"| C["Legacy Mode<br/>全量加载<br/>兼容当前"]
B -->|"生产环境<br/>或长对话"| D["Progressive Mode<br/>动态加载<br/>新架构"]
C --> E[通过配置切换]
D --> E
E --> F[观察效果]
F -->|"稳定后"| G[默认启用Progressive]
F -->|"有问题"| H[回滚到Legacy]
end
配置示例:
# .opencode/config.yaml
context_management:
mode: "progressive" # 或 "legacy"
max_tokens: 8000
progressive:
l1_always_load: ["core_identity", "tool_summary"]
l2_load_on_intent: true
l3_rag_enabled: false # 第三阶段启用
fallback:
to_legacy_when: "intent_unclear"
token_threshold: 10000
6. 总结与建议
6.1 架构对比总结
| 维度 | OpenCode当前 | OpenClaw | 建议 |
|---|---|---|---|
| 当前策略 | Monolithic Loading | 9层Progressive Loading | OpenCode需要演进 |
| 实现难度 | 简单 | 复杂 | 可渐进实现 |
| Token效率 | 低 | 高 | 优先优化目标 |
| 生产稳定性 | 高 | 中(有已知Issue) | OpenCode当前更稳 |
| 扩展性 | 中等 | 高(插件化) | 长期目标 |
6.2 对OpenCode的具体建议
立即行动:
- ✅ 实现Token计数,了解当前基线
- ✅ 为技能添加
layer和triggers元数据 - ✅ 设计轻量级ContextManager
短期目标(1-2月): 4. 🎯 实现Progressive Loading基础版本 5. 🎯 添加意图识别模块 6. 🎯 A/B测试验证效果
长期愿景(3-6月): 7. 🚀 考虑ContextEngine插件化架构 8. 🚀 支持RAG-based记忆检索 9. 🚀 建立Engine生态
6.3 风险与缓解
| 风险 | 可能性 | 影响 | 缓解措施 |
|---|---|---|---|
| 意图识别不准确 | 中 | 技能加载不全 | 默认加载常用技能 |
| Token预算超限 | 低 | 成本增加 | 强制执行budget check |
| 向后兼容性 | 中 | 用户技能失效 | 保持Legacy Mode可选 |
| 架构复杂度 | 高 | 维护困难 | 渐进式演进,充分测试 |
6.4 最终建议
对于OpenCode项目:
采用”Progressive Loading自建 + 参考OpenClaw设计”的策略
- 不必完全照搬OpenClaw的9层架构,可以先实现3层(Core/Skills/Execution)
- 不必立即插件化,先实现内置的Progressive Engine
- 保持简单优先,OpenCode的优势就是易于理解和使用
- 关注实际效果,Token节省>架构完美
迁移检查清单:
- Token基线测量(当前~16K)
- 技能分层标注完成
- ContextManager实现
- 意图识别准确率达到85%+
- Token使用量降至5K以下
- 任务完成率不下降
- 向后兼容性测试通过
参考资料
- OpenClaw 9层System Prompt架构 - OpenClaw官方架构文档
- OpenClaw ContextEngine发布说明 - 2026.3.7版本更新
- OpenClaw GitHub Issue #40232 - 插件时序问题
- William Zujkowski - From 150K to 2K Tokens - Progressive Loading实践
- Agentic Context Engineering - Microsoft Research - ACE框架论文
- OpenCode Skills定义示例 - 当前技能实现