V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In

独立开发者节点

愿每一位独立开发者都能保持初心,获得一个好的结果.

lyr1csl1

Rein — 给 AI 编程智能体写的本地记忆 MCP 服务器(Rust 单二进制)

  •  
  •   lyr1csl1 · 2h 10m ago · 125 views

    [发布] Rein — 给 AI 编程智能体写的本地记忆 MCP 服务器( Rust 单二进制)

    我用 Claude Code 和 Codex 写了大半年代码,慢慢摸出一些痛点:

    每开一个新会话,上下文从零开始。 周三我调一个 Tokio task 泄漏,定位了两小时发现是某个 tokio::spawn 出来的 task 没正确 await 。周五重新打开 Claude Code 写新功能,写到一半我说"对了,避免上次那种泄漏"——Claude 当然不知道我说的"上次"是什么。

    换工具就丢上下文。 跟 Claude 商量了一晚上某个模块的边界设计,第二天切到 Codex 写实现,又得把 200 字的设计要点贴一遍。

    反复纠正同一种风格。 "用 tracing 不要 println"、"测试放 tests/ 不要放 src/",每个新会话都要再说一遍。

    派 subagent 调研,回来啥也没留下。 Claude Code 用 Task tool 派几个 subagent 并发查代码,subagent 调研结果都在它们各自的上下文里。subagent 一退出,主 agent 拿到一段总结,但那些一手细节没了——下次相似问题还得从头查一遍。

    CLAUDE.md / .cursorrules 这种静态指令文件能写死一些固定规则,但记不住具体的事。那些是动态的、不断累积的。

    Rein 就是来做这件事的:一个本地长期记忆 MCP 服务器,让你的 AI agent 跨会话、跨工具、跨 subagent 都能共享同一份记忆。


    MCP 简述

    Model Context Protocol 是 Anthropic 提的一个开放标准协议,让 LLM 和外部工具通信。Claude Code 、Codex CLI 、Cursor 、opencode 、Gemini CLI 、Claude Desktop 、Continue.dev 等等都支持。

    关键事实:所有这些 MCP 客户端都能连同一个 MCP server——它们读同一个数据库,写同一个数据库。

    Rein 就是个 MCP server 。对外暴露 40 个 tool (最常用的是 rein_store 存、rein_recall 搜,还有时间线查询、知识图谱、反馈记录等)。所有数据落进本机 ~/.rein/memories.db 一个 SQLite 文件。


    实际怎么用——多 agent 之间的记忆共享

    下面这些场景是我自己跑了一个月 Rein 之后总结的实际用法。只有当所有 agent 共享同一份记忆库的时候才成立。

    1. 编辑器 agent ↔ 终端 agent 的工作 handover

    你在终端用 opencode 、Hermes 这类能控制电脑的 CLI agent 做环境层的事——升级依赖、跑 migration 、改配置、跑一组测试看哪个挂了。这些动作通过 hook 异步抽取进 Rein 。

    切回 Claude Code 在编辑器里写代码——不用告诉 Claude 终端那边发生了什么。Claude 直接 rein_recall 就能拿到:"上一小时 opencode 把 tokio 从 1.40 升到 1.42 ,跑了一遍测试,3 个 task 模型相关的 case 挂了"。Claude 写新代码时会避开这些已知问题。

    handover 通过共享记忆库自动完成。不需要 copy-paste 状态,不需要写交接文档

    2. 主 agent ↔ subagent 不丢一手细节

    Claude Code 用 Task tool 派 subagent 出去:A 查 auth 模块、B 查 storage 、C 跑性能测试。

    不连 Rein:subagent 跑完返回一段 summary 给主 agent ,一手细节就丢了——下次主 agent 想精确知道"那个可疑 unwrap 具体在哪一行",得再派一次 subagent 。

    连了 Rein:每个 subagent 都是 MCP 客户端。它们调研到关键点直接 rein_store 写进库——不只是当前会话用,将来任何 agent 都能召回。主 agent 看 summary 拿浓缩信息,后续需要精确细节时 rein_recall 直接出。

    这个用法我跑得很重,重到把 Rein 自己的某个默认值都改了:v0.27.6 起 [server].stdio_background_warmup 默认 false,原因是多 subagent 同时启动时如果都触发后台 warmup ,会因为 side-index 写锁竞争互相阻塞。

    3. 不同强度模型按工作分配,共享同一份上下文

    我自己的分工:Claude Opus(深思考、长上下文)做架构和复杂调试;Codex / Sonnet(快、便宜)做实现和样板代码。

    不连 Rein:每次切换都要重新讲"我们刚才在讨论什么"。

    连了 Rein:Opus 这边做完决策,hook 自动落库;切到 Codex CLI 写代码,Codex 的 MCP 配置也指向同一个 Rein——直接召回设计共识。Opus 负责想,Codex 负责做,记忆是它们共享的工作台。

    4. 长任务断了,新会话直接接手

    跑长任务时 context window 满了被 truncate ,或者 CLI 进程不小心被 kill 。

    不连 Rein:重启就是新的会话,前面 30 分钟的进展、临时决定、试过的几个方案全没。

    连了 Rein:重启的会话 rein_recall "刚才在做什么" 拿到事件时间线 + 已做决定 + 已否方案。接着干,不用复盘

    5. 跨机器协作的记忆中枢

    我自己的 setup:本机跑 Rein + Claude Code ,另一台 Mac mini 上跑一个 Hermes 长期 agent (处理后台任务、定期巡检)。两边的 MCP 都指向同一份 Rein 数据。

    最近修过一个 MCP Python SDK 的 stdio subprocess 泄漏问题——客户端在异常路径上没关 stdin pipe ,子进程变成孤儿。这个 bug 跨了大概两周才稳定下来; Hermes 那边发现现象、本机 Claude 这边 reproduce + fix 、再 deploy 回 Mac mini ,整条链路的调试记录全在 Rein 里——任何一边的 agent 都能 recall 整个故事。

    6. 被动累积,不用专门"做笔记"

    最关键的一点:你不需要刻意 rein_storerein init 装好 hook 之后:

    • Claude Code 每跑完一个 tool (读文件、改代码、跑测试),hook 异步调 LLM 抽取关键信息存进 Rein
    • Codex 同理
    • 还可以挂 record-only 代理 rein serve --proxy:你用 Claude Pro / ChatGPT Pro 订阅模式跑的所有对话都被静悄悄记下来,但不修改 prompt 、不注入上下文,agent 行为完全不变

    你正常写代码,记忆自己长起来。我自己本机的 Rein 库现在累积了大约 4000 条记忆——其中 user-preference 类目最多( 300+),其次是 architecture ( 180+)、debug 、workflow 、config 这些。topic 跨度从 rein 自身开发,到 HPC GPU 调试,到给学生写自动化脚本——同一个工具横跨完全不同的项目。


    为什么本地

    我用过几个云端记忆方案,最不放心的不是被黑的风险,而是:我代码里的设计思路、对系统的吐槽、纠结过的边界判断,没必要交给第三方

    Rein 默认就是单 Rust 二进制 + 本地 SQLite 。装好就跑,所有数据在 ~/.rein/memories.db 一个文件里,断网照样工作。LLM 调用(抽取、查询扩展、重排)是 opt-in 的——不配 API key 也能跑:rule-based 抽取兜底,本地 BM25 + 本地向量缓存做检索。Mac 用户可以挂 OMLX,本地嵌入模型,完全离线。


    中文支持

    中文用户用大多数国外"AI 知识库 / 记忆"工具会卡在同一个地方:全文搜索( BM25 )质量差。原因是分词。

    英文按空格切就行。中文不行:按 unicode 字符切,"机器学习"会被拆成"机/器/学/习"四个独立 token ,搜"机器学习"召回不到讲"机器学习算法"的笔记。整段不切,BM25 又完全失效。

    Rein 集成了 jieba-rs(结巴分词的 Rust 实现)。文本入库和查询时按字符段路由:中文段走 jieba ,英文段按空格切,中英混排("用 LLM 做 RAG 的痛点")按段切。

    // 简化伪代码(实际在 store/jieba_tokenizer.rs )
    fn tokenize(text: &str) -> Vec<Token> {
        if contains_cjk(text) {
            jieba.cut(text, /* hmm */ true)
        } else {
            text.split_whitespace()
        }
    }
    

    结果是中文搜索召回质量和英文一个水平。


    一些主要功能

    三通道检索 + 学习型融合

    每次召回并行跑三条管线:

    • BM25 全文Tantivy,毫秒级,CJK 走 jieba
    • 向量近邻usearch HNSW ,3072 维 cosine
    • 知识图谱:概念 → 记忆的 BFS 遍历

    三路结果通过 Bruch 2023 Convex Combination 公式融合。融合系数不是常量,会根据你的历史召回数据反推(你点了哪些、跳过哪些)持续学习更新,按 query 类型和语义簇分别学。

    Neural Wiki GUI

    --features gui 的二进制内嵌 React + Tailwind 前端。启动后浏览器打开 http://localhost:8680

    • Brain View:记忆节点的 force-directed 图
    • Knowledge Graph:你的 memoir / concept / link 全图
    • Adaptive Engine:自适应参数实时面板( fusion alpha 、簇 dedup 阈值、tier 分布)
    • Synthesis Lab:评估 LLM-summary 质量
    • 还有 Timeline / Memories / System Health / Settings

    自适应参数( M1-M6 )

    写 Rein 的时候有个原则:尽量不在代码里写死常量,让数据驱动。

    • M1 事件溯源:召回、存储、点击都落库,慢通道重放
    • M2 反事实 alpha:用历史召回反推最优融合系数
    • M3 Kaplan-Meier 生存曲线:替代固定半衰期,每个语义簇有自己的衰减
    • M4 HDBSCAN 聚类:纯 Rust 实现的层次密度聚类
    • M5 三层冷热分层:t-digest streaming quantile 估计 hot/warm/cold 边界
    • M6 + A1 自适应去重阈值:每簇 P90 相似度阈值

    冷启动有 bootstrap 常数兜底,数据积累到阈值后切到学习值。所有学习状态在 GUI 的 Adaptive Engine 页能实时看到。


    集成

    Claude Code

    cargo install --git https://github.com/lyr1cs/rein --tag v0.28.8 --features gui
    rein init    # 自动配置 ~/.claude/settings.json hooks
    

    rein init 装 7 个 hook ( SessionStart / PreToolUse / PostToolUse / UserPromptSubmit / PreCompact / Stop / PermissionRequest )。

    Codex CLI

    rein init    # 自动配置 ~/.codex/hooks.json 6 个事件
    

    opencode / Cursor / Claude Desktop / Gemini CLI / Continue

    任意 MCP 客户端都通过 stdio 接入:

    {
      "mcpServers": {
        "rein": { "command": "rein", "args": ["serve", "--mcp"] }
      }
    }
    

    透明记录代理(订阅模式)

    如果你用 Claude Pro / ChatGPT Pro 订阅而不是 API key ,可以启 rein serve --proxy。它做 record-only 转发:转发请求和响应、异步抽取记忆,不注入 prompt 上下文,所以 agent 行为完全不变。


    安装

    需要 Rust 工具链 + Node.js ( GUI 构建用):

    cargo install --git https://github.com/lyr1cs/rein --tag v0.28.8 --features gui
    
    # 可选:配 LLM key
    export GEMINI_API_KEY=AIza...
    
    # 初始化
    rein init
    
    # 启 GUI
    rein serve --gui
    
    # 或者只启 stdio MCP server
    rein serve --mcp
    
    # 健康检查
    rein doctor
    

    GUI 启动后浏览器打开 http://localhost:8680

    预编译二进制( macOS arm64 ):

    curl -L -o rein https://github.com/lyr1cs/rein/releases/download/v0.28.8/rein
    chmod +x rein
    ./rein --version
    

    工程信息

    • 单 Rust 二进制约 18 MB (含 React GUI )
    • 2-crate Cargo workspace
    • 单文件 SQLite + FTS5 + sqlite-vec
    • 当前版本 v0.28.8
    • License: AGPL-3.0-or-later

    链接

    欢迎 Issue / Discussion / PR 。如果你愿意贡献中文场景的召回 corpus ( query + 相关 memory 的成对数据),可以直接进 eval fixture——目前我手头中文测试数据很少。

    cnnblike
        1
    cnnblike  
       1h 47m ago
    可以,要是能标有多少代码是 vibe 的多少是手搓的会更有说服力
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2535 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 43ms · UTC 12:33 · PVG 20:33 · LAX 05:33 · JFK 08:33
    ♥ Do have faith in what you're doing.