当"自进化"遇上"极致工程化":WeClaw 与 DeepSeek Harness 架构深度对比
系列文章第 8 篇 - 从经验回写闭环到 Cordis 插件架构,一次跨技术栈的 Agent 设计哲学碰撞
前言
2026 年 8 月,WeClaw 完成了「评分门控的经验回写闭环」——让桌面 AI 助手第一次具备了从工具试错中自动学习、评估、变异和回滚的能力。与此同时,DeepSeek 团队开源了 DeepSeek Harness(以下简称 DSH),一个基于 Cordis 插件架构的 TypeScript Agent 框架,以极致的工程化水平引发了社区关注。
我们把两个系统放在一起做了深入对比。结论令人意外:它们代表了 Agent 技术栈的两条截然不同的进化路径——一个追求"自我进化",一个追求"极致可组合"。更有趣的是,两者的差异恰恰揭示了当前 Agent 领域一个尚未被充分讨论的核心问题:
Agent 应该从运行中学习并自我改善,还是应该由人类开发者驱动所有能力演进?
本文是这场对比分析的上篇,聚焦架构哲学和核心机制差异。下篇将讨论 WeClaw 可以从 DSH 借鉴什么,以及具体的优化迭代方向。
一、两个系统的基本面
1.1 一句话定位
| 系统 | 一句话定位 | 技术栈 | 许可证 |
|---|---|---|---|
| WeClaw | 具备经验自进化能力的 Windows 桌面 AI 助手 | Python / PySide6 / SQLite | 私有 |
| DSH | 可组合、可审计的 Agent 运行时框架 | TypeScript / Cordis / Node.js | 开源 |
1.2 架构范式
┌─────────────────────────────────────────────────────────────┐
│ WeClaw:模块化单体 │
│ │
│ ┌─────────┐ ┌──────────┐ ┌──────────┐ ┌─────────┐ │
│ │ EventBus│──▶│ 经验采集 │──▶│ 评分门控 │──▶│ 经验库 │ │
│ │ │ │ (EBEAC) │ │ (3 档) │ │ (SQLite)│ │
│ └────┬────┘ └──────────┘ └──────────┘ └────┬────┘ │
│ │ │ │
│ │ ┌──────────┐ ┌──────────┐ │ │
│ └─▶│ 变异引擎 │──▶│ 回滚监测 │◀─────────────┘ │
│ │ (4 算子) │ │(hit_count│ │
│ └──────────┘ │ 观测窗) │ │
│ └──────────┘ │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ DSH:Cordis 插件架构 │
│ │
│ ┌─────────┐ ┌──────────┐ ┌──────────┐ ┌─────────┐ │
│ │ ctx.llm │ │ctx.tools │ │ctx.skills│ │ctx.goals│ │
│ │ (LLM │ │ (工具 │ │ (技能 │ │ (目标 │ │
│ │ 适配器)│ │ 注册器) │ │ 注册器) │ │ 状态机)│ │
│ └────┬────┘ └────┬─────┘ └────┬─────┘ └────┬────┘ │
│ │ │ │ │ │
│ └─────────────┴──────┬───────┴──────────────┘ │
│ │ │
│ ┌───────▼───────┐ │
│ │ Cordis Core │ │
│ │ (插件容器) │ │
│ └───────────────┘ │
└─────────────────────────────────────────────────────────────┘
关键差异:WeClaw 是一个功能完备的单体智能体,各模块围绕"经验生命周期"协作;DSH 是一个插件容器,所有能力(LLM、工具、技能、目标管理)都是可插拔的服务。
二、四个维度的深度对比
2.1 经验管理:自进化 vs 无学习
这是两个系统最本质的差异。
WeClaw 的经验回写闭环是一个完整的自进化管道:
# WeClaw 经验回写闭环核心流程(简化)
class ExperienceWritebackEngine:
def on_tool_result(self, event):
"""工具调用结果 → 经验采集入口"""
if event.success_after_failures(n >= 2):
candidate = self.build_experience(event)
score = self.score(candidate) # 归一化加权评分
if score < 0.5:
self.discard(candidate) # 低质量 → 丢弃
elif score < 0.8:
self.store(candidate) # 中等 → 原样入库
else:
self.store(candidate) # 高质量 → 入库
self.mutate(candidate) # + 变异增强
def mutate(self, experience):
"""4 种遗传变异算子"""
operators = [
"add_example", # 补充示例
"add_constraint", # 添加约束条件
"restructure", # 重构表述
"add_edge_case", # 添加边界情况
]
# ...
def check_rollback(self, experience):
"""命中率观测窗:子代 hit_count < 父代 50% 时回滚"""
if window.sample_size >= 5 and child.hit_rate < parent.hit_rate * 0.5:
self.rollback(child)
而在 DSH 的整个 TypeScript 代码库中,我们搜索了 experience、self-improve、auto-learn、evolve、mutate、rollback 等关键词——在源码层面零匹配。
DSH 的技能(Skill)系统最能说明问题:
// DSH 技能注册器(简化)
class SkillRegistry extends Service {
// 技能 = 静态 Markdown 文件
registerProvider(create: (control) => SkillProvider): () => void
// 技能来源优先级:project < user < bundled
// 没有评分、没有变异、没有回滚
async list(options): SkillSummary[] {
// 合并所有 provider 的技能目录
// 按 rank 优先级去重
// 返回静态列表
}
}
DSH 的技能是人类编写的静态文档,从加载到使用再到销毁,内容永远不会改变。
| 生命周期阶段 | WeClaw 经验库 | DSH 技能系统 |
|---|---|---|
| 内容来源 | 自动从工具试错中采集 | 人工编写 Markdown |
| 质量评估 | 归一化加权评分(4 维客观信号) | 无 |
| 入库门控 | 三档(丢弃/原样/变异增强) | 无(文件系统存在即可用) |
| 内容变异 | 4 种遗传算子 | 无 |
| 效果观测 | hit_count 观测窗 | 无 |
| 退化回滚 | 自动子代回退 + 日志留痕 | 无 |
| 跨会话持久化 | SQLite + 语义向量索引 | 文件系统(目录扫描) |
2.2 反馈机制:客观闭环 vs 主观开环
两个系统都有"反馈"机制,但设计哲学截然不同。
WeClaw 的反馈是自动采集的客观信号流:
# WeClaw EventBus 事件 → 自动经验采集
event_bus.subscribe(EventType.TOOL_RESULT, on_tool_result)
event_bus.subscribe(EventType.AGENT_ERROR, on_agent_error)
# 信号维度(全部客观可计算)
score = (
0.3 * failure_recovery_score + # 连续失败后成功恢复
0.3 * field_completeness_score + # 经验字段完整度
0.2 * keyword_hit_score + # 关键词命中匹配
0.2 * novelty_bonus # 新颖度(去重相似度)
)
DSH 的反馈是人工的主观评价,且明确拒绝进入模型上下文:
// DSH MessageFeedbackService(简化)
class MessageFeedbackService {
// 用户对助手消息的 👍/👎 + 可选备注
async rate(sessionId, messageId, rating: 'positive' | 'negative', note?: string) {
// 乐观并发控制:version compare-and-set
// 持久化到 StorageDomain
// ⚠️ 明确声明:NEVER enters model context or derived history
}
}
DSH 在 command-feedback 模块中进一步强调了这一点:
feedback/recordis log-only: it never enters model context or derived history.
这是一个有意识的设计选择——人工反馈只用于遥测审计,不参与 Agent 的决策改善。
flowchart LR
subgraph WeClaw 闭环
A[工具试错] --> B[EventBus 采集]
B --> C[客观评分]
C --> D{三档门控}
D -->|丢弃| E[🗑️]
D -->|入库| F[经验库]
D -->|变异| G[变异增强]
G --> F
F --> H[语义检索]
H --> I[注入模型上下文]
I --> A
end
subgraph DSH 开环
J[用户评价] --> K[MessageFeedback]
K --> L[StorageDomain 持久化]
L --> M[遥测/审计]
M -.->|❌ 不进入| N[模型上下文]
end
为什么 DSH 选择开环? 这是一个值得深思的问题。DSH 的防御模式文档揭示了线索:系统关注的是确定性执行和安全沙箱——不可预测的自学习行为与这些目标存在张力。而 WeClaw 通过"零 LLM 成本"和"确定性评分"解决了可预测性问题,使得闭环变得安全。
2.3 上下文压缩:殊途同归
在上下文管理领域,两个系统展现了高度的架构同构性——这可能是 Agent 框架面临的共性工程挑战。
| 特性 | WeClaw RCR | DSH CompactionEngine |
|---|---|---|
| 触发条件 | token 压力 / 上下文溢出 | pressure / context-overflow |
| 压缩模式 | 六阶段管道 | compactIfNeeded / compactNow / compactRegion |
| 工具配对保护 | 有(tool_call ↔ tool_result) | 有(toolPairingBalancedBefore/After) |
| 摘要生成 | 规则 + LLM 混合 | 可插拔 LLM 后端 |
| 事务隔离 | 互斥锁 | compaction/start … compaction/end 标记对 |
| 实现方式 | 具体实现 | 抽象类(允许不同后端) |
DSH 的 Compaction 设计更为"学院派"——它定义了一个抽象类 CompactionEngine,具体压缩策略由 compaction-basic 等后端实现。这意味着社区可以编写不同的压缩后端(如更激进的压缩、基于嵌入的语义压缩等),而无需修改核心代码。
2.4 事件系统:松散总线 vs 严格溯源
两个系统都使用事件驱动架构,但严格程度差异显著。
WeClaw EventBus:灵活的发布-订阅模式,事件类型通过枚举定义:
class EventType(Enum):
TOOL_RESULT = "tool_result"
AGENT_ERROR = "agent_error"
AGENT_RESPONSE = "agent_response"
# ...
DSH Session Event Log:强类型事件溯源,40+ 种事件类型,每种都有完整的 TypeScript 声明和 JSDoc 规范:
// DSH 事件类型系统(简化)
type SessionEventType =
| 'turn/start' | 'turn/end'
| 'step/start' | 'step/end'
| 'tool/call' | 'tool/result'
| 'assistant/chunk' | 'assistant/message'
| 'compaction/start' | 'compaction/end' | 'compaction/summary'
| 'goal/change'
| 'feedback/record'
| 'todo/write'
// ... 40+ 种
type SessionEvent<T extends SessionEventType> = {
type: T
seq: number // 单调递增序列号
time: number // Unix 毫秒时间戳
data: SessionEventMap[T] // 类型安全的数据载荷
ignorable?: true // 前向兼容标记
surfaceOp?: SurfaceOp // 条件字段:仅 surface 事件
}
DSH 的事件系统有几个值得注意的设计:
- 单调序列号(
seq):保证事件顺序可重建 ignorable标记:前向兼容——未知类型的事件如果标记了ignorable: true,旧版读取器可以安全跳过- Surface vs Log-only 分离:只有
user/message、assistant/message、tool/result三种事件会进入模型上下文
三、设计哲学的根本分歧
3.1 两种 Agent 进化模型
graph TD
subgraph "WeClaw: 自进化 Agent"
direction TB
W1[执行任务] --> W2[采集经验]
W2 --> W3[评分门控]
W3 --> W4[变异增强]
W4 --> W5[经验库]
W5 --> W6[语义检索]
W6 --> W1
W5 --> W7[回滚监测]
W7 --> W5
end
subgraph "DSH: 人类驱动进化"
direction TB
D1[开发者编写 Skill] --> D2[文件系统]
D2 --> D3[SkillRegistry 加载]
D3 --> D4[Agent 使用]
D4 --> D5[人工反馈 log]
D5 --> D6[开发者分析]
D6 --> D1
end
| 维度 | WeClaw 自进化 | DSH 人类驱动 |
|---|---|---|
| 进化速度 | 实时(每次工具调用后评估) | 发布周期(人类编写 → 部署) |
| 进化方向 | 数据驱动(客观信号引导) | 需求驱动(人类判断引导) |
| 可预测性 | 中(评分确定性,但变异有随机性) | 高(人类完全控制) |
| 适应范围 | 窄(特定工具的特定错误模式) | 宽(人类可以添加任意新能力) |
| 质量保障 | 自动回滚 | 代码审查 + 测试 |
| 零人力成本 | 是 | 否 |
3.2 "反闭环"是一种设计选择
DSH 明确拒绝将人工反馈注入模型上下文,这并非疏忽,而是一种安全优先的架构决策。其防御模式文档(defensive-patterns.md)中的六条规则都在强调一件事:可预测性。
- "异步状态不等于同步状态"——不要让系统行为随时间漂移
- "清理必须达到静止,而不仅仅是请求"——确定性终止
- "永远不要将不可信输出交给环境"——输入隔离
WeClaw 选择了另一条路:通过全客观信号(而非 LLM 判断或人工评价)来驱动自进化,从而在保持可预测性的同时实现了闭环。这是对 Blind Curator(arXiv:2607.07436)揭示的"LLM 裁判偏差"问题的一种设计回应。
四、DSH 的优势:WeClaw 的镜子
DSH 在多个工程维度上达到了 WeClaw 尚未企及的水平,这些差距恰恰指明了 WeClaw 的迭代方向。
4.1 插件化 vs 模块化
| 特性 | WeClaw | DSH |
|---|---|---|
| 能力扩展方式 | 修改源码 / 新增模块 | 编写 Cordis 插件 |
| 运行时组合 | 静态(启动时加载) | 动态(ctx.inject 运行时注入) |
| 作用域隔离 | 模块级 | Scope + Layer 分层 |
| 能力声明 | 隐式(import 关系) | 显式(declare module 类型合并) |
DSH 的 Cordis 架构使得每一个能力(LLM 适配器、工具注册、技能管理、上下文压缩)都是独立插件,可以在不修改核心的情况下替换。例如,CompactionEngine 可以有 compaction-basic、compaction-aggressive、compaction-semantic 等多个后端。
4.2 防御性设计模式
DSH 文档化了 6 种已验证的防御模式,每一种都来自真实的生产 bug:
- 正交结果独立报告——超时和退出码是独立事实,不要嵌套
- 公共契约双向遵守——实现层归一化后再返回
- 异步状态 ≠ 同步状态——不要把
status: idle当作某次操作的结果 - 清理必须达到静止——
kill后必须await done - 回调异常必须被容器捕获——一个坏监听器不能破坏核心生命周期
- 不可信输出隔离——沙箱进程获得清洗后的环境变量
这些模式对 WeClaw 同样适用,尤其是第 3 条和第 5 条——WeClaw 的 EventBus 在 fire-and-forget 模式下需要类似的异常容器化。
4.3 目标状态机
DSH 的 GoalService 是一个优雅的状态机实现:
active ──pause──▶ paused
│ │
│ block │ resume
▼ ▼
blocked ◀──────────┘
│
│ complete
▼
complete
每个状态转换都有:
- 严格的前置条件验证(
allowed阶段列表) - 基于版本号的乐观并发控制(
GoalRef.revision) - 进程本地的 continuation activation(
armed/disarmed) - 完整的审计日志(
goal/change事件)
WeClaw 目前没有对应的形式化目标管理——任务目标隐含在对话上下文中,没有独立的状态追踪。
五、核心数据对比
5.1 代码规模与复杂度
| 指标 | WeClaw 经验系统 | DSH 核心框架 |
|---|---|---|
| 经验回写引擎 | 655 行(experience_writeback.py) | — |
| 经验存储 | ~800 行(experience_store.py) | — |
| 技能系统 | — | 869 行(skill/index.ts)+ 1042 行(skill-filesystem) |
| 上下文压缩 | ~400 行(RCR 模块) | 173 行抽象 + 实现(compaction-basic) |
| 反馈系统 | ~100 行(EventBus 订阅) | 384 行(MessageFeedbackService) |
| 目标管理 | 无 | 593 行(GoalService) |
| 事件类型数 | ~10 种 | 40+ 种(SessionEventType) |
| 总包数 | 单体(src/ 模块) | 138+ 个独立包 |
5.2 经验漂移:自进化系统的独有挑战
WeClaw 的实际运行数据揭示了一个 DSH 永远不会面对的问题——经验库漂移:
| 指标 | WeClaw 生产数据 |
|---|---|
| 总经验条目 | 169 条 |
| hit_count = 0(从未被检索使用) | 141 条(83%) |
| 独立 pattern 坍缩 | 196 条 → 23 个(88.3%) |
| 嵌入模型换代后 Hit@1 | 33.3% → 93.3% |
DSH 的技能是静态文件,不存在"库漂移"问题——但也意味着它无法从运行时数据中获益。这正是 WeClaw 经验回写闭环要解决的核心问题:通过三档门控过滤低质量条目,通过变异增强高质量条目,通过回滚监测淘汰退化变体。
六、总结:互补而非竞争
| 维度 | WeClaw 独有 | DSH 独有 |
|---|---|---|
| 经验自进化 | 三档门控 + 遗传变异 + 回滚闭环 | — |
| 架构工程化 | — | Cordis 插件框架 + 能力接缝 |
| 质量治理 | 客观评分驱动的经验生命周期 | — |
| 安全与审计 | — | 多层沙箱 + Landlock + 防御模式 |
| 目标管理 | — | 形式化状态机 + CAS 并发控制 |
| 事件溯源 | — | 40+ 强类型事件 + 版本号固定 |
| 反馈机制 | 自动客观信号闭环 | 人工主观评价(设计为开环) |
核心洞察:
- 自进化与工程化不是对立的。WeClaw 证明了全客观信号驱动的闭环可以在零 LLM 成本下安全运行;DSH 证明了极致的工程化水平可以为 Agent 提供坚实的可靠性基础。
- 最佳 Agent 应该兼得两者:既有自进化能力来持续改善,又有工程化架构来确保可控。
- 经验漂移是自进化系统的独有挑战,也是 WeClaw 相对于静态框架的核心价值所在——只有具备学习能力的系统才会遭遇这个问题,也只有解决这个问题的系统才能实现长期可靠运行。
在下篇中,我们将具体讨论 WeClaw 可以从 DSH 借鉴哪些设计模式,以及这些借鉴如何落地为经验回写闭环的优化迭代。
系列文章导航:
| 篇序 | 标题 | 核心内容 |
|---|---|---|
| 01–05 | WinClaw 工具优化实战专栏 | 从工具滥用灾难到渐进式暴露 |
| 06 | 双通道密钥管理 | 开发者便利与用户安全的平衡 |
| 07 | 双通道实时通信 | PWA 多实例绑定路由 |
| 08 | 本文 | WeClaw vs DSH 架构对比 |
| 09 | 向 DSH 学什么 | 借鉴思考与迭代方向 |
参考资料:
- DeepSeek Harness 开源仓库:github.com/deepseek-ai/deepseek-harness
- Blind Curator(arXiv:2607.07436):LLM judge 的 false-pass 偏差分析
- SkillProx(arXiv:2608.07449):技能级回滚机制的并行工作
- Ratchet(arXiv:2605.22148)/ Library Drift(arXiv:2605.19576):技能库漂移实证研究