跳到主要内容

OpenSpace — 架构与原理

30 秒导读: OpenSpace 是一个"技能进化引擎"——你把它挂到任意 agent(Claude Code、Codex、Cursor…)上, 它接管一个任务后先找相关技能照着做,做不成就回退成纯工具从头干;任务一结束,它会回看整段录制、 自动判断技能哪里该修/该加,用三种手术(修好 FIX、派生 DERIVED、新捕获 CAPTURED)改写技能并存进一个 SQLite 版本图谱,还能上云和别的 agent 共享。核心承诺:同一类活越干越省 token、越干越可靠


1. 这是什么(零基础也能懂)

一句话定义: OpenSpace 是一层"会自我进化的技能库 + 执行器",通过 MCP 协议插到现有 agent 上, 让它们从每次真实任务里学到经验并沉淀成可复用技能

解决什么问题 / 给谁用。 今天的 agent(Claude Code、Codex、Cursor 等)有个通病: 每次任务都从零推理——同样的活反复烧 token、同样的坑反复踩、学到的东西困在单个 agent 里出不来。 OpenSpace 面向的就是想让 agent"越用越聪明、越用越便宜"的开发者

它把三件事补给 agent:

补的能力白话
自进化(Self-Evolution)技能坏了自己修、成功的模式自己升级、赢过的流程自己捕获成新技能
集体智能(Collective Intelligence)一个 agent 学会的东西上云,别的 agent 一条命令就能下载复用
省钱(Token Efficiency)复用成功方案而非从零推理;README 称在 GDPVal 上 少 46% token

它能做什么(功能)。

  • 接管一个自然语言任务,端到端执行(shell / GUI / 浏览器 / MCP 工具 / 系统信息 五类后端)。
  • 执行前:从本地 + 云端检索相关技能并注入到执行上下文。
  • 执行时:技能优先,失败自动回退纯工具
  • 执行后:自动分析录制,定向进化技能(修/派生/捕获),并写入版本 DAG。
  • 对外:既能当 CLI 单机跑,也能当 MCP server 被别的 agent 调用;还能把技能上传/下载云社区

用起来什么样。 最小用法就是一行命令(见 pyproject.toml:75-76,入口 openspace = "openspace.__main__:run_main"):

# 示意,非源码:把一个任务交给 OpenSpace 执行
openspace --query "把这 15 个 PDF 里的报税数据汇总成一张表"

它会自动:找技能 → 照着做(不行就纯工具重来)→ 复盘 → 把学到的存进技能库。下次遇到类似任务,直接命中已进化的技能。

一句话直觉/类比。 把普通 agent 想成"每次都空手上阵的临时工";OpenSpace 给它配了一个 会随经验增厚的"操作手册柜"——干一次活,手册柜就多一页或改好一页错页;而且这个柜子能和其他工友共享

本节不涉及底层代码。记住一句话:OpenSpace = 技能优先执行 + 执行后自动进化 + 跨 agent 共享。


2. 顶层全景(它大概怎么转)

怎么读这张图: 从上到下是一次任务的时间线。左边"控制平面"是每次任务都跑的主循环; 右边"进化平面"在任务结束后才启动,回头改写技能库;技能库(SQLite + 磁盘 SKILL.md)是两个平面共享的记忆。

┌──────────────────────────────────────────────┐
宿主 agent / CLI ───▶ │ OpenSpace.execute(task) 〔tool_layer.py〕 │
(Claude Code…) └───────────────────┬──────────────────────────┘

┌───────────── 控制平面:一次任务的主循环 ───────────────┐
│ │ │
▼ ▼ ▼
① 选技能并注入 ② 两阶段执行〔Grounding Agent〕 ③ 录制整段过程
〔SkillRegistry〕 ┌───────────────────────────┐ 〔RecordingManager〕
任务→BM25+向量预筛 │ 阶段1 技能引导执行 │ conversations.jsonl
→LLM 选 ≤N 个技能 │ 成功 ✓ ─────────────────┐│ metadata.json
→注入 SKILL.md 正文 │ 失败 ✗ → 清空工作区 ││
│ │ 阶段2 纯工具兜底(满预算) ││
│ └──────────┬────────────────┘│
│ │ 每轮:LLM 想 → 调工具 → 看结果 → <COMPLETE>?
│ ▼ │
│ ┌────────────────────────────┐ │
│ │ 工具接地层 GroundingClient │ │
│ │ 工具太多→工具 RAG 只留 topK │ │
│ │ 5 类后端 + 工具质量监控 │ │
│ └────────────────────────────┘ │
└───────────────────────────────────────────┘
│ 任务结束(finally)
┌──────────── 进化平面:任务后自动改写技能 ────────────┐
▼ ▼
④ 分析录制〔ExecutionAnalyzer〕 ⑤ 进化技能〔SkillEvolver〕
读 conversations.jsonl FIX 修好坏技能(同名新版本)
→ LLM 判定:任务成没成 / DERIVED 派生/融合出新技能
技能用没用 / 该怎么进化 CAPTURED 从成功里捕获全新技能
→ 产出 EvolutionSuggestion → 写入 SQLite 版本 DAG + 磁盘
└──────────────────────┬───────────────────────────────┘

技能库(共享记忆)
磁盘 <skill>/SKILL.md + .skill_id
SQLite openspace.db(records + lineage DAG + 统计)


⑥ 对外:MCP server〔mcp_server.py〕
execute_task / search_skills / fix_skill / upload_skill
↕ 云社区〔cloud/client.py〕跨 agent 共享

部件一句话职责:

部件干什么在哪个文件
OpenSpace顶层门面 + 主循环编排(选技能→两阶段执行→分析→进化)openspace/tool_layer.py:79
GroundingAgent真正的执行体:多轮"想→调工具→看结果"直到 <COMPLETE>openspace/agents/grounding_agent.py:29
GroundingClient工具接地层:统一 5 类后端、工具 RAG、质量监控openspace/grounding/core/grounding_client.py:19
SkillRegistry发现/匹配/注入技能(SKILL.md 格式)openspace/skill_engine/registry.py:102
RecordingManager录制每轮对话与元数据,供事后分析openspace/recording/manager.py:15
ExecutionAnalyzer任务后用 LLM 复盘录制,产出进化建议openspace/skill_engine/analyzer.py(见 analyze_execution)
SkillEvolver执行 FIX / DERIVED / CAPTURED,写版本 DAGopenspace/skill_engine/evolver.py:154
SkillStoreSQLite 持久化:技能记录 + 血缘 DAG + 统计openspace/skill_engine/store.py:169
OpenSpaceClient云社区客户端:上传/下载/搜索技能openspace/cloud/client.py:49
MCP server把上述能力暴露成 4 个 MCP 工具给宿主 agentopenspace/mcp_server.py:530

主线走一遍(高层,不进代码):

  1. 宿主 agent(或 CLI)调 OpenSpace.execute(task)(tool_layer.py:303)。
  2. 选技能:SkillRegistry 从任务里挑 ≤N 个相关技能,把它们的 SKILL.md 正文注入执行上下文(tool_layer.py:689)。
  3. 两阶段执行:有技能就先"技能引导"跑;成功即返回,失败则清空工作区、退回纯工具用满预算重跑(tool_layer.py:427-521)。
  4. 全程被 RecordingManager 录进 conversations.jsonl / metadata.json
  5. 任务后(finally 块):ExecutionAnalyzer 读录制→ LLM 判定任务成败与技能表现,产出进化建议(tool_layer.py:787)。
  6. 进化:SkillEvolver 把建议落地成 FIX / DERIVED / CAPTURED,更新磁盘 SKILL.md 和 SQLite 版本 DAG(tool_layer.py:818-850)。
  7. 需要时,技能通过 MCP upload_skill 上云;别的 agent 通过 search_skills / execute_task 下载复用。

目标:看懂"大盘"——一条主循环(左)+ 一个任务后进化平面(右)+ 一份共享技能记忆(中)+ 一层对外 MCP/云出口(下)


3. 阅读地图(建议顺序)

本子库按"由浅入深、先主循环后进化"拆成 5 章。推荐顺序:

  1. 主循环:两阶段执行与 Grounding Agent —— 先看一次任务怎么跑完:OpenSpace.execute 的两阶段(技能优先 / 纯工具兜底)、 GroundingAgent 的多轮迭代循环、<COMPLETE> 收尾、失败清工作区再重来。理解全局从这章开始。

  2. 技能检索与注入:从任务到 SKILL.md —— 技能是什么(官方 SKILL.md 格式)、怎么被发现(.skill_id 持久身份)、 BM25 + 向量预筛 → LLM 选技能、以及把正文注入系统提示的机制。

  3. 自进化引擎:FIX / DERIVED / CAPTURED 与版本 DAG —— 项目的灵魂。任务后分析如何产出进化建议,三种进化手术各自的语义与血缘规则, 以及 SQLite 里"每次改动都建新节点"的版本 DAG 与技能统计。

  4. 工具接地层:统一后端、工具 RAG 与质量监控 —— 五类后端(shell/gui/web/mcp/system)如何被统一;工具太多时的"工具 RAG"(BM25+向量+LLM 规划筛选); ToolQualityManager 如何监控工具退化并反哺技能修复。

  5. 对外集成:MCP 服务与云端技能社区 —— mcp_server.py 的四个工具(execute_task / search_skills / fix_skill / upload_skill)、 宿主 agent 集成方式、以及云社区的上传/搜索/导入与可见性(public/private)。


4. 巧妙之处(这套设计值得带走的东西)

① 两阶段"技能优先、失败兜底",且兜底前清工作区。 技能不是硬约束——阶段 1 照技能做,只要状态不是 success丢弃技能上下文、删掉阶段 1 产生的中间文件, 阶段 2 用满预算从干净状态纯工具重来(tool_layer.py:463-521)。这样"用技能"永远只会加速、不会拖累结果。

② 进化是"定向手术"而不是"重训"。 坏了只修坏的那步(FIX,同名产生新版本、旧目录内容快照进 DB),而不是重建整个技能—— 省 token 的关键之一(skill_engine/types.py:41-56 的血缘规则)。

③ 每次改动都建新节点的版本 DAG。 FIX/DERIVED/CAPTURED 都不覆盖历史:FIX 恰好 1 个父(上一版本)、DERIVED 可多父(融合)、 CAPTURED 无父(根节点),generation 记录距根深度(skill_engine/types.py:69-127)。技能演化史可回溯、可审计。

④ 技能身份和目录解耦。 .skill_id sidecar 让技能 ID 可移植(挪目录、换机器都不变)且确定(不重生成) (registry.py:44-70)。这是"跨 agent / 上云共享"能成立的地基。

⑤ 进化只在"任务成功"这类高价值信号上花大钱。 分析/进化跑在 execute()finally 且有超时保护(tool_layer.py:596-613), 失败绝不阻断主流程;周期性的指标检查(每 5 次)和工具退化修复都丢到后台任务(tool_layer.py:856-911)。

⑥ 工具接地层自带"工具 RAG"。 工具数量超过阈值(默认 30)才触发检索,用 BM25 + 向量 + LLM 规划筛出 topK (grounding_client.py:632search_tools.py:553SearchCoordinator),避免把上百个工具塞进上下文。


5. 代码地图(导航索引)

符号名比行号抗漂移——上游更新后优先用 grep 符号名定位。行号 as-of sourceCommit

主题文件路径符号名
顶层门面 / 配置openspace/tool_layer.py:79OpenSpaceOpenSpaceConfig
主循环:两阶段执行openspace/tool_layer.py:303OpenSpace.execute
选技能并注入openspace/tool_layer.py:689_select_and_inject_skills
任务后分析触发openspace/tool_layer.py:787_maybe_analyze_execution
周期/后台进化触发openspace/tool_layer.py:856_maybe_evolve_quality
CLI 入口openspace/__main__.py:476mainrun_main
执行体:多轮迭代openspace/agents/grounding_agent.py:133GroundingAgent.process
技能上下文注入openspace/agents/grounding_agent.py:95set_skill_context
中途取技能工具openspace/skill_engine/retrieve_tool.py:26RetrieveSkillTool
技能发现/匹配/注入openspace/skill_engine/registry.py:102SkillRegistry
LLM 选技能openspace/skill_engine/registry.py:340select_skills_with_llm
技能持久身份openspace/skill_engine/registry.py:44_read_or_create_skill_id
进化数据模型openspace/skill_engine/types.py:26EvolutionTypeSkillOriginSkillLineage
技能全档案openspace/skill_engine/types.py:333SkillRecord
任务后分析openspace/skill_engine/analyzer.pyExecutionAnalyzer.analyze_execution
进化执行器openspace/skill_engine/evolver.py:154SkillEvolver(_evolve_fix/_evolve_derived/_evolve_captured)
SQLite 版本 DAGopenspace/skill_engine/store.py:169SkillStore(record_analysissync_from_registry)
工具接地层openspace/grounding/core/grounding_client.py:19GroundingClient
工具 RAG(自动检索)openspace/grounding/core/grounding_client.py:632get_tools_with_auto_search
工具检索协调器openspace/grounding/core/search_tools.py:553SearchCoordinatorToolRanker
工具质量监控openspace/grounding/core/quality/manager.py:30ToolQualityManager(should_evolveget_problematic_tools)
录制管理openspace/recording/manager.py:15RecordingManager
MCP 服务(4 工具)openspace/mcp_server.py:530execute_tasksearch_skillsfix_skillupload_skill
云社区客户端openspace/cloud/client.py:49OpenSpaceClient(upload_skillimport_skillsearch_record_embeddings)
云端混合搜索openspace/cloud/search.pyhybrid_search_skills
SKILL.md 格式说明openspace/skills/README.md(发现优先级与格式约定)

下一步:从 主循环:两阶段执行与 Grounding Agent 开始, 跟着一次任务从 execute() 走到 <COMPLETE>,再看任务后进化平面如何把这次经验沉淀进技能库。