Doramagic 项目包 · 项目说明书
Midas 项目
面向长程 AI 智能体的本地优先、以评测为先的存储记忆,摄入阶段无需调用 LLM;提供 Python SDK 与 MCP 服务器,支持可溯源的检索、信念修正、选择性遗忘以及可复现的基准测试。
核心记忆引擎与存储抽象
Midas 的核心是一套本地优先、源可追溯的智能体记忆系统。Memory 类是整个引擎的中枢,它把"写入→评分→检索→修订"封装为可组合的管道,对外通过 MCP(Model Context Protocol)暴露给 LLM 代理使用,对内通过统一的存储抽象支持多种后端。设计哲学是"零 LLM 入库、按需蒸馏":默认所有原始 turn 直接落盘并打上 provenance(规...
继续阅读本节完整说明和来源证据。
Midas 的核心是一套本地优先、源可追溯的智能体记忆系统。Memory 类是整个引擎的中枢,它把"写入→评分→检索→修订"封装为可组合的管道,对外通过 MCP(Model Context Protocol)暴露给 LLM 代理使用,对内通过统一的存储抽象支持多种后端。设计哲学是"零 LLM 入库、按需蒸馏":默认所有原始 turn 直接落盘并打上 provenance(规划 / 行动 / 观察 / 用户确认),LLM 仅在显式开启蒸馏或弃权校准时才介入。资料来源:midas/memory.py
架构总览
Memory 实例持有 store(后端)、embedder(嵌入器)、可选 distiller、可选 reranker 与可选 NLI 模型,并通过 recall() / remember() / assemble() / forget_decayed() 等方法协调它们。资料来源:midas/memory.py
flowchart LR Agent[LLM Agent / MCP 客户端] -->|remember / recall| Mem[Memory 引擎] Mem --> Imp[ContentImportance / StructuralImportance] Mem --> Embed[LocalEmbedder / ONNX] Mem --> BM25[混合 BM25 索引] Mem --> Store[(Store 抽象层)] Store -->|默认| SQLite[SQLite] Store -->|可选| TurboVec[TurboVec] Mem -->|可选 tier-3| Distill[OllamaDistiller] Distill --> Mem
核心生命周期:`remember` → `recall`
remember() 接受 content / kind / importance / provenance / metadata,若 importance=0 则交给 ContentImportance 或 StructuralImportance 在无 LLM 情况下自动评分(一阶人称 + 持久关键词 + 实体权重;问句与元话语被降权)。资料来源:midas/importance.py
recall() 是关键路径:先做语义向量召回,再按配置融合 BM25 词法得分(RRF / 加权),最后用 _PROVENANCE_RANK 与超驰链剔除被修订版本、按 min_importance 与 min_relevance 过滤,并通过 as_of 时间戳支持"当时相信什么"的历史查询。资料来源:midas/memory.py
引擎在两处显式缓存以避免 O(N) 重建:BM25 索引用 store 版本号作 key(实测让 LongMemEval 规模下混合检索从 66 ms 降到 1.9 ms);rec_by_id 缓存同理。资料来源:midas/memory.py
存储抽象与可插拔后端
Store 是统一的 all() / get() / upsert() / mark_superseded() 接口,配置由 MidasAdapter.reset() 决定 store_kind(sqlite / turbovec),后者支持量化位宽 turbovec_bits 与池大小 turbovec_pool。adapter.store_size 直接返回 len(self._mem.store.all()),是 forget_decayed() 的容量上限依据。资料来源:eval/adapters/midas_adapter.py
环境变量 MIDAS_MCP_DB 控制 SQLite 持久化路径,MIDAS_MCP_EMBEDDER 在 local(bge ONNX,离线)与 hashing 之间切换,二者均不依赖外网。资料来源:server.json
重要性评分与三级蒸馏
ContentImportance(基础词袋特征)和 StructuralImportance(叠加人称断言 / 持久性 / 元话语判别)共同构成无 LLM 评分栈,使入库路径对 token 与延迟零开销。资料来源:midas/importance.py
v0.0.4 引入"蒸馏转盘"三级策略:
| 层级 | 调用方 | 成本 | 行为 |
|---|---|---|---|
| 默认(无 LLM) | — | 0 | 原始 turn 直接入库 |
| Tier 1 代理驱动 | 代理自身的 LLM | $0 → Midas | 在 recall 后由代理整理 |
| Tier 3 本地蒸馏 | OllamaDistiller | $0,本机 | 显式 distill() 时才跑 |
OllamaDistiller 用 stdlib urllib 调用本地 Ollama,默认 keep_raw=True——即蒸馏事实以 metadata["distilled"]=True 标注为索引层叠加在原始 turn 之上,而非替换。A/B 评测显示"蒸馏替换"会让 BEAM 答案从 0.30 跌至 0.08(销毁时序/知识更新细节),而"叠加"恢复到约 0.32。资料来源:midas/distill.py 与 eval/summarization_ab.py
弃权校准与信念链审计
Memory 支持 abstention_threshold / relevance_floor / entailment_floor 三个阈值;后者会惰性加载 LocalNLI 校验检索结果是否被证据蕴涵,从而把"找不到"与"找到了但答不上"区分开。评测中 llm_answer_and_judge 会把"弃权"与"作答"分别聚合到 abstentions 与 answers,按类别(稳定 / 易混 / 不可答)统计。资料来源:midas/memory.py 与 eval/runner.py
每次超驰会写 superseded_by 链,audit.belief_history() 沿此链双向走,返回最旧到当前的完整信念修订时间线,供审计者追溯"我们曾相信 v1(t1),改为 v2(t2)……当前 vN"。资料来源:midas/audit.py
常见失败模式
- 不设
min_importance又开了大窗口:长会话里元话语/问句会拉低召回质量——调高 floor 或先capture()让ContentImportance自动降权。 forget_decayed(max_records=N)与查询并发:忘记是基于 store 全量扫描的,应在闲置窗口调用。- 把蒸馏当记忆的"金盘":naive 蒸馏会丢时序与变更轨迹,必须保留原始
kind="chat"记录作审计源。资料来源:midas/memory.py - 未启用 NLI 就上调
abstention_threshold:弃权判定会退化为纯启发式,导致过度弃权。资料来源:midas/memory.py
See Also
- MCP 服务器与工具接口
- 评估管线与基准
- 蒸馏策略与实验
- 信念审计与超驰链
来源:https://github.com/vornicx/Midas / 项目说明书
MCP 服务器与多客户端集成
Midas 通过 Model Context Protocol(MCP) 将本地优先、可溯源的智能体记忆能力暴露给任意兼容 MCP 的主机(例如 Claude Desktop、IDE 插件、TypeScript 智能体)。MCP 服务器本身是 midas/mcpserver.py 中的一个 FastMCP 实例,它在本地 stdio 上运行,把 Python 端的 Memo...
继续阅读本节完整说明和来源证据。
概述与设计目标
Midas 通过 Model Context Protocol(MCP) 将本地优先、可溯源的智能体记忆能力暴露给任意兼容 MCP 的主机(例如 Claude Desktop、IDE 插件、TypeScript 智能体)。MCP 服务器本身是 midas/mcp_server.py 中的一个 FastMCP 实例,它在本地 stdio 上运行,把 Python 端的 Memory 引擎以一组工具(tools)的形式提供给客户端。资料来源:midas/mcp_server.py
整个系统强调"无 LLM 入库、完全离线"——MCP 服务器在写入或检索阶段均不调用大模型,离线嵌入(bge ONNX)随依赖一同分发,从而保证数据零外泄。资料来源:server.json:1-25 中的 description 字段明确指出 "Local-first, source-traceable agent memory — no LLM at ingest, fully offline"。
v0.0.4 版本同时发布两条客户端路径:Python 端经由 PyPI 包 midas-memory-mcp 走 uvx 启动;TypeScript 端经由 packages/midas-ts 直接在 Node.js 智能体内嵌。两端共享同一份核心契约,因此记忆视图、命名空间、溯源语义在两种语言下保持一致。资料来源:server.json:8-22、`packages/midas-ts/src/mcp.ts:1-60]()
MCP 服务器工具集
midas/mcp_server.py 用 @server.tool(...) 装饰器注册了四类核心工具,构成客户端与记忆引擎之间的最小契约:
| 工具名 | 作用 | 关键参数 |
|---|---|---|
remember | 写入一条记忆 | content、kind(note/chat/fact/preference/constraint/mission)、importance(1-5,0=自动推导)、session、provenance(planning/action/observation/user_confirmation)、actor、namespace |
recall | 语义检索 + 可选混合检索 | query、limit、kind、min_importance、hybrid、fusion、as_of(历史时间点查询) |
inspect_memory | 按 id 查单条记录(无嵌入泄露) | memory_id |
remember_code | 编码智能体专用分类记忆 | code_kind(architecture_decision、dependency_choice、convention、bug_fixed、recurring_failure、forbidden_action、command_worked、command_failed)、project |
remember 工具的语义值得特别注意:importance=0 表示让 Memory 依据内容自动打分(无 LLM),provenance 字段会被后续 guard_reliance 用于阻断计划/观察被当作"用户确认"使用。资料来源:midas/mcp_server.py 中四个 @server.tool(...) 块。recall 工具的 as_of 参数支持历史快照式查询:"当时记忆里写了什么",通过 as_of_ts 过滤实现版本对齐。资料来源:midas/mcp_server.py:recall 块、midas/memory.py]() 中 _PROVENANCE_RANK 与 belief_history 实现
remember_code 是编码智能体场景下的关键工具——它把 forbidden_action 这类约束以 code_kind 维度索引,使得后续 check_forbidden_action 与 project_state 视图能按项目维度聚合"决策、依赖、约定、bug、禁用动作"。当 _MAX_RECORDS 越界时,服务器会调用 _mem.forget_decayed(max_records=...) 自动遗忘(无 LLM)。资料来源:midas/mcp_server.py:remember_code 块
多客户端集成方式
Midas 在 v0.0.4 中通过 server.json 将自身声明为一个标准的 MCP 服务器清单。资料来源:server.json:1-25
flowchart LR Host[兼容 MCP 的主机<br/>Claude Desktop / IDE / Agent] -->|stdio JSON-RPC| PyServer[midas-memory-mcp<br/>PyPI uvx 启动] Host -->|stdio JSON-RPC| TSServer[packages/midas-ts<br/>Node.js 内嵌] PyServer --> Core[Memory 引擎<br/>SQLite + bge ONNX] TSServer --> Core Core --> Recall[recall / hybrid / as_of] Core --> Audit[belief_history / inspect]
Python 客户端 通过 uvx midas-memory-mcp 启动,传输层为 stdio。该包在 server.json 中以 runtimeHint: uvx 与 transport.type: stdio 标注,使主机可零配置拉起。资料来源:server.json:11-22
TypeScript 客户端 提供了等价能力:packages/midas-ts/src/mcp.ts 使用 zod 定义 inputSchema(如 kind、provenance、枚举 MEMORY_PROVENANCE),并把 MCP registerTool 调用映射到本地 mem.remember()、mem.recall()。资料来源:packages/midas-ts/src/mcp.ts:Remember 块
两条路径都把"自动遗忘上限"作为客户端可配置项——TypeScript 端通过 boundStore() 在 remember 后检查 len(mem.store.all()) 并触发衰减。资料来源:packages/midas-ts/src/mcp.ts:Remember 块末尾
配置、环境变量与最佳实践
MCP 服务器支持通过环境变量定制行为,全部列在 server.json 的 environmentVariables 字段中:
| 环境变量 | 默认 | 作用 |
|---|---|---|
MIDAS_MCP_DB | 内存 | SQLite 文件路径;持久化跨重启 |
MIDAS_MCP_EMBEDDER | local | 嵌入后端(local=bge ONNX 离线 / hashing) |
MIDAS_MCP_MAX_RECORDS | 无上限 | 存储容量上限;越界触发 forget_decayed |
资料来源:server.json:14-25
最佳实践方面:1) 使用 namespace 隔离多用户/多项目;2) 把 provenance=user_confirmation 仅留给用户显式确认的内容,外发动作(publish、send、delete)只信任这一档;3) 检索优先走 hybrid=true 配合 fusion 参数(融合 BM25 与语义),避免仅靠 paraphrase 错失精确标识符;4) 写入时尽量让 kind 与 code_kind 落到正确枚举,便于 project_state 视图聚合。资料来源:midas/mcp_server.py:remember / recall 块、CONTRIBUTING.md]() 中"Eval quick reference"与"Dev setup"段落
See Also
- 蒸馏三档(agent-driven /
OllamaDistiller/ 默认关闭)详见midas/distill.py与DISTILL_PROMPT - 评测适配器与
midas_adapter详见eval/adapters/midas_adapter.py - 安全护栏(
guard_reliance、provenance 等级)详见midas/memory.py与eval/memory_safety.py - 审计与版本链
belief_history详见midas/audit.py
资料来源:server.json:14-25
来源治理护栏与信念修订
Midas 作为本地优先(local-first)的代理长期记忆系统,将"记忆究竟来自哪里"与"记忆何时需要被改写"放在与检索同等核心的位置。本页说明两个相互耦合的子系统:(1) 来源分级与行动护栏(provenance guardrails),负责判定一条记忆在何种条件下可以驱动一次外部或破坏性动作;(2) 信念修订链(belief revision chain),负责在...
继续阅读本节完整说明和来源证据。
Midas 作为本地优先(local-first)的代理长期记忆系统,将"记忆究竟来自哪里"与"记忆何时需要被改写"放在与检索同等核心的位置。本页说明两个相互耦合的子系统:(1) 来源分级与行动护栏(provenance guardrails),负责判定一条记忆在何种条件下可以驱动一次外部或破坏性动作;(2) 信念修订链(belief revision chain),负责在新事实取代旧事实时保留可审计的版本历史。
来源分级与传递模型
每条 MemoryRecord 都携带 provenance 字段。Midas 在 midas/memory.py 中以 _PROVENANCE_RANK 对其按可信度排序:
| Rank | Provenance | 语义 |
|---|---|---|
| 0 | planning | 内部计划 / 思考,未与外部世界交互 |
| 1 | observation | 来自环境的观察或读取 |
| 2 | action | 系统自身执行的动作 |
| 3 | user_confirmation | 用户显式确认 |
该分级不仅是标签,还直接参与行动守门。在评测适配层 eval/adapters/midas_adapter.py 的 ingest 实现中,event.metadata.get("provenance", "observation") 的默认值确保了"未标注的对话即观察",从而防止下游把规划阶段的话术误升格为可执行事实。
行动护栏与守门测试
guard_reliance 是护栏入口,针对具体的动作请求(query、intended_use、acting_agent)返回包含 allowed 字段的 Decision。测试套件 eval/memory_safety.py 将场景划分为 attack(应当拒绝)与 benign(应当放行)两类 SafetyCase,核心攻击模式包括:注入源攻击(把外部文本伪装成内部观察请求破坏性动作)、遗忘确认攻击(复用已被新 Error with Openai API: peer closed connection without sending complete message body (incomplete chunked read)
Please check that you have set the OPENAI_API_KEY environment variable with a valid API key.
来源:https://github.com/vornicx/Midas / 项目说明书
评估套件与蒸馏档位
Midas v0.0.4 的核心原则是"本地优先、源可追溯、摄入时无 LLM"。eval/ 套件在此原则下承担两重角色:验证记忆层在长程基准上的真实质量,以及在蒸馏(distillation)这一最易引入隐藏成本与质量损失的环节提供可复现的 A/B 对照。社区最关心的是 v0.0.4 引入的"蒸馏档位(dial)"——三档可配置、默认关闭,经过诚实测量后被证实"naive ...
继续阅读本节完整说明和来源证据。
Midas v0.0.4 的核心原则是"本地优先、源可追溯、摄入时无 LLM"。eval/ 套件在此原则下承担两重角色:验证记忆层在长程基准上的真实质量,以及在蒸馏(distillation)这一最易引入隐藏成本与质量损失的环节提供可复现的 A/B 对照。社区最关心的是 v0.0.4 引入的"蒸馏档位(dial)"——三档可配置、默认关闭,经过诚实测量后被证实"naive distillation 不能提升答案正确率"。
蒸馏档位与默认关闭的原因
Memory(distiller=...) 才是启用 LLM 蒸馏的开关;未配置时,Memory 全程不调用任何 LLM,所有抽取都来自 midas/importance.py 中的内容/结构启发式(例如 ContentImportance 通过首人称/断言/元话语正则区分"陈述事实"与"提问")。资料来源:midas/importance.py:1-40
三档含义对照如下:
| 档位 | 触发方式 | LLM 来源 | 成本 | 写入策略 |
|---|---|---|---|---|
| Tier 1 · 代理驱动 | 代理在对话内自行 summarize 后 remember() | 代理自身的 LLM | $0 to Midas | 写入代理产出 |
| Tier 2 · 本地蒸馏 | Memory(distiller=OllamaDistiller(...)) | Ollama 本地模型 | $0,数据不出设备 | keep_raw=True,原文与蒸馏事实双写 |
| Tier 3 · 默认/关闭 | 不传 distiller | 无 | $0 | 仅保留原文,LLM 不参与 |
Tier 2 的实现是 OllamaDistiller——仅依赖标准库 urllib,无新增依赖,通过 ollama serve + 已拉取的模型(默认 llama3.2:3b)工作,温度默认 0 以稳定产出。资料来源:midas/distill.py:30-80
Memory.distill 的 docstring 给出关键经验数据:在 BEAM A/B 中,蒸馏 替换 原文使答案分数从 0.30 跌至 0.08,而蒸馏 叠加 原文则回升到约 0.32(基本持平)。因此默认 keep_raw=True:蒸馏产物作为索引层叠加在原文审计链之上,而非覆盖。资料来源:midas/memory.py:280-320
评估套件组成
- 数据集:
eval/datasets.py提供多种长程基准。longmemeval()加载 ICLR 2025 的 LongMemEval,覆盖信息抽取、多会话推理、时间推理、知识更新、弃权五项能力;beam()与conflicts()则构造可控制的事实冲突、稳定/弃权对照用例。资料来源:eval/datasets.py:1-60 - 运行器:
eval/runner.py负责批量调度、LLM 判分与 NLI 验证,并对弃权与答案路径分别聚合,便于直接对比带/不带 grounding 的分数。资料来源:eval/runner.py:1-50 - 适配器:
eval/adapters/midas_adapter.py将Event列表转为remember_many()的输入项;当配置了importance_scorer或novelty_weight时,显式importance=None让Memory自动推导(基于内容显著度与对库的新颖度,无 LLM)。资料来源:eval/adapters/midas_adapter.py:1-40 - A/B 实验:
eval/summarization_ab.py直接比较raw / naive / struct / struct_replace四种摘要方案。其STRUCT_PROMPT注释明确指出:对知识更新与时间推理类问题,naive 的"一句压缩事实"会丢失变化前后的双侧状态,因此该实验本身即为"为何默认不蒸馏替换"的实证。资料来源:eval/summarization_ab.py:1-80
常见失败模式与安全护栏
- 以蒸馏结果替换原文:丢失时间/知识更新信号,答案 0.30 → 0.08。务必
keep_raw=True。资料来源:midas/memory.py:280-320 - 忘配
distiller仍调用distill():抛RuntimeError,提示需Memory(distiller=...)。资料来源:midas/memory.py:300 - A/B 时混淆
struct与struct_replace:后者代表"以结构化摘要覆盖原文"的危险路径,务必在评测矩阵中与struct(叠加)分开。资料来源:eval/summarization_ab.py:1-80
审计侧通过 midas/audit.py:belief_history() 沿 superseded_by 链接回放完整修订链,验证"我们曾经认为 X,何时被 X' 取代"。资料来源:midas/audit.py:1-60
安全侧由 eval/memory_safety.py 维护"攻击 vs 良性"用例,覆盖被遗忘的确认注入、计划被误用为建议等模式,确保 provenance 与弃权阈值真正起到护栏作用。资料来源:eval/memory_safety.py:1-40
MCP 层(midas/mcp_server.py)与 server.json 注册元数据同样把蒸馏定位为 opt-in:任何外部动作(external_action)只允许依赖 user_confirmation 来源,与 Tier 1/2 的"摘要只是索引层"一致。资料来源:midas/mcp_server.py:1-40 server.json:1-30
参见
- eval/benches.py — 基准入口与汇总
- midas/mcp_server.py — MCP 服务器对蒸馏档位的暴露面
- server.json — MCP 注册元数据(版本、环境变量)
- mcpb/manifest.json — 一键打包清单,声明
MIDAS_MCP_EMBEDDER等开关
来源:https://github.com/vornicx/Midas / 项目说明书
失败模式与踩坑日记
保留 Doramagic 在发现、验证和编译中沉淀的项目专属风险,不把社区讨论只当作装饰信息。
安装可能改变本机 AI 工具行为,用户需要知道写入位置和回滚方法。
假设不成立时,用户拿不到承诺的能力。
新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
风险会影响是否适合普通用户安装。
Pitfall Log / 踩坑日志
项目:vornicx/Midas
摘要:发现 7 个潜在踩坑项,其中 0 个为 high/blocking;最高优先级:配置坑 - 可能修改宿主 AI 配置。
1. 配置坑 · 可能修改宿主 AI 配置
- 严重度:medium
- 证据强度:source_linked
- 发现:项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主,或安装命令涉及用户配置目录。
- 对用户的影响:安装可能改变本机 AI 工具行为,用户需要知道写入位置和回滚方法。
- 证据:capability.host_targets | https://github.com/vornicx/Midas | host_targets=mcp_host, claude_code, claude, cursor
2. 能力坑 · 能力判断依赖假设
- 严重度:medium
- 证据强度:source_linked
- 发现:README/documentation is current enough for a first validation pass.
- 对用户的影响:假设不成立时,用户拿不到承诺的能力。
- 证据:capability.assumptions | https://github.com/vornicx/Midas | README/documentation is current enough for a first validation pass.
3. 维护坑 · 维护活跃度未知
- 严重度:medium
- 证据强度:source_linked
- 发现:未记录 last_activity_observed。
- 对用户的影响:新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
- 证据:evidence.maintainer_signals | https://github.com/vornicx/Midas | last_activity_observed missing
- 严重度:medium
- 证据强度:source_linked
- 发现:no_demo
- 证据:downstream_validation.risk_items | https://github.com/vornicx/Midas | no_demo; severity=medium
5. 安全/权限坑 · 存在评分风险
- 严重度:medium
- 证据强度:source_linked
- 发现:no_demo
- 对用户的影响:风险会影响是否适合普通用户安装。
- 证据:risks.scoring_risks | https://github.com/vornicx/Midas | no_demo; severity=medium
6. 维护坑 · issue/PR 响应质量未知
- 严重度:low
- 证据强度:source_linked
- 发现:issue_or_pr_quality=unknown。
- 对用户的影响:用户无法判断遇到问题后是否有人维护。
- 证据:evidence.maintainer_signals | https://github.com/vornicx/Midas | issue_or_pr_quality=unknown
7. 维护坑 · 发布节奏不明确
- 严重度:low
- 证据强度:source_linked
- 发现:release_recency=unknown。
- 对用户的影响:安装命令和文档可能落后于代码,用户踩坑概率升高。
- 证据:evidence.maintainer_signals | https://github.com/vornicx/Midas | release_recency=unknown
来源:Doramagic 发现、验证与编译记录