2026

Mnemo:个人AI知识库与记忆助手

个人AI知识库与记忆助手

独立设计实现的本地知识库问答系统,系统性解决生产级 RAG 的关键工程问题:检索质量量化评估、长对话上下文有损压缩、多供应商 Function Calling 协议统一、Agent 自主二次检索决策。含 Agentic 检索循环(Plan-Act-Observe-Reflect)、混合检索 RRF 融合、三层记忆架构。

核心亮点

  • 设计并实现 Plan-Reasoning-Act-Observe-Reflect Agentic RAG 自适应检索闭环:QueryPlanner 完成意图识别、子查询分解与改写,LLM 基于上下文自主决策检索时机与策略,通过 Act-Observe-Reflect 完成工具调用、证据验证与反思,证据不足自动迭代、充分后终止,实现单轮多轮自主检索。
  • 设计 Hybrid Retrieval Pipeline:融合向量、关键词与知识图谱三路召回,通过 RRF 融合及消融实验确定最优权重;在 BEIR/SciFact 数据集上实现 nDCG@10=0.6584、MRR@10=0.6359。
  • 重构关键词检索链路:将 MongoDB Regex 检索升级为 RediSearch 倒排索引全文检索,平均延迟由 1138ms 降至 12.3ms(p95:1668ms→15.4ms),性能提升 92.5×,消除长尾延迟。
  • 设计 Model Adapter:构建跨厂商 Function Calling 统一适配层,以 Canonical Tool Schema 屏蔽 OpenAI、Claude、Gemini 协议差异,支持流式 Tool Calling 增量解析,实现模型无关的工具调用。
  • 设计 MCP 工具运行时:支持 MCP Server 配置热加载、断线自动重连,以及工具数量超阈值后的 Tool Schema 按需动态加载。
  • 设计分层长期记忆系统:实现 Core / Recall / Archival Memory 分层存储,对话超阈值自动摘要压缩与语义归档检索,将记忆统一封装为 Tool,由模型自主完成存储、检索与更新,实现跨会话长期记忆。

技术栈

FastAPIPythonMongoDBQdrantNeo4jRedisOllamajiebasentence-transformersPaddleOCR

Mnemo:Agentic RAG 系统设计与工程实践

项目概述

Mnemo 是本人独立设计与实现的本地知识库问答系统,后端采用 FastAPI 构建,代码规模约 3.8 万行 Python(不含前端)。项目的核心目标并非实现一个基础的检索增强生成(RAG)演示系统,而是系统性地解决生产级 RAG 系统中的若干关键工程问题:检索质量如何量化评估与提升、长对话上下文如何在信息损耗可控的前提下压缩、多家大模型供应商的工具调用(Function Calling)协议差异如何统一,以及 Agent 应在何种条件下自主决定进行二次检索。

其中核心是设计并实现了 Plan-Reasoning-Act-Observe-Reflect(PRAOR)的 Agentic RAG 自适应检索闭环,详见下文第二节。

技术栈:FastAPI + Uvicorn(后端服务)、MongoDB(业务数据)、Qdrant(向量检索)、Neo4j(知识图谱)、Redis(缓存与全文检索,RediSearch)、Ollama(本地模型与嵌入模型部署)、jieba / sentence-transformers(分词与重排序)、PyMuPDF / Unstructured / PaddleOCR(文档解析与 OCR)。前端提供 Next.js 16 与 Vite + TanStack 两套实现。

以下按功能模块对系统设计进行详细说明。


一、检索规划模块(QueryPlanner)

多数 RAG 系统对所有查询使用统一的检索参数,未考虑查询本身的复杂度差异。Mnemo 在检索前引入了一层独立的查询规划模块 QueryPlanner,负责意图识别、子查询分解与查询改写,产出结构化的检索参数(final_k 返回证据数、prefetch_k 预取候选数、fusion_strategy 融合策略等)。这一步的输出是确定性的参数,不涉及模型的自主推理决策——这一点将在第二节说明其与后续 Reasoning 阶段的职责边界。

规划过程支持三种模式,默认使用自适应(auto)模式:

  • 规则引擎:命中明确的意图关键词(如"对比""条款""风险"等),或查询长度较短(15 字以内),采用规则判断,响应时间在毫秒级,不引入额外的模型调用;
  • LLM 规划:查询长度超过 40 字、包含多个疑问句(复合查询),或长度适中但缺乏明确意图关键词——此类查询规则引擎的误判率较高,因此改由大模型进行语义级意图识别,并将复杂查询拆分为 2 至 4 个独立子查询(例如"对比 HNSW 和 IVF 的性能差异和应用场景"会被拆分为三个子查询),同时生成查询改写(rewritten queries)以提升检索召回;
  • 超时降级:LLM 规划设置 20 秒超时,超时或解析失败时自动降级为规则引擎,确保服务可用性不受单次规划失败影响。

规划完成后,意图为 compare / summary / clause / verification 等复杂类型的查询会先执行一轮预检索,按 Plan 产物提前拉取初始证据并注入生成上下文,使模型在第一轮生成时即可看到相关证据;意图为 general 的简单查询则跳过预检索,直接进入下一阶段由模型自主判断是否需要检索,避免为简单查询增加不必要的首轮延迟。

二、Agentic 检索闭环:Plan-Reasoning-Act-Observe-Reflect

这是本项目中投入最多设计与验证工作的模块。传统 RAG 系统的检索通常是一次性的:执行一次检索、拼接上下文、生成答案,缺乏根据证据质量动态调整检索策略的能力。Mnemo 将检索过程设计为一个五阶段闭环,支持在单轮对话内进行多轮自主检索:

Plan(规划):由第一节所述 QueryPlanner 完成意图识别、子查询分解与查询改写,产出结构化检索参数(final_k、fusion_strategy 等)并缓存至本轮上下文,供后续阶段复用。该阶段职责单一,只做参数生成,不做"是否需要进一步检索"的判断——这一判断由下一阶段的 Reasoning 承担。意图识别在所有查询上都会执行,区别仅在于下游动作:复杂意图(compare/summary/clause/verification)额外触发一轮预检索,提前获取初始证据并注入生成上下文;简单意图(general)不预检索,但会缓存部分参数——若后续 Reasoning 阶段判断需要检索,工具调用会直接复用这份缓存参数(含查询改写结果),无需重新规划,避免重复调用带来的额外延迟。

Reasoning(推理决策):进入生成阶段后,大模型基于累积上下文自主判断当前证据是否足够回答问题、是否需要调用检索工具、调用时使用何种参数(如更换关键词、调整检索范围)。这一阶段对所有意图都会执行,只是起始上下文不同:复杂意图下模型手中已有 Plan 阶段预取的证据,判断的是"是否需要补充检索";简单意图下模型没有预置证据,判断的是"是否需要从零开始检索"。该阶段是循环中真正的自主决策环节,与 Plan 阶段的确定性参数生成明确分离:Plan 产出参数,Reasoning 决定是否使用、如何使用。

Act(执行):Reasoning 阶段判断需要检索时,触发 rag_retrieve 工具执行实际的检索调用;模型在同一轮对话中也可能调用其他工具(如编辑核心记忆的 core_memory_append)。所有工具调用的结果都会无条件写入对话上下文,供下一轮生成使用;区别在于下一阶段——只有 rag_retrieve 的结果会额外经过 Observe/Reflect 的证据充分性判断,其他工具的结果则直接引导模型基于已有信息作答,不涉及"证据是否充分、要不要重试检索"这类判断。

Observe(观察)rag_retrieve 工具调用返回后,先经过证据验证模块(EvidenceVerifier)的四层校验,再记入本轮观察结果:

  1. 相关性分数阈值:过滤检索分数过低的结果;
  2. 查询覆盖度(默认 0.3):要求候选片段至少命中查询关键词的 30%,避免仅命中单一高频词即被判定为相关;对高分片段(≥0.5)适当放宽此要求,以兼容向量检索中语义相关但字面不重叠的情形;
  3. 长度过滤(默认 50 字符):过滤纯标题、导航文本等过短片段,即使检索分数较高也不予采信;
  4. 综合相关性分数:三项校验全部通过方判定为有效证据,最终分数由检索分数与覆盖度加权计算得出。

若系统加载了 CrossEncoder 重排序模型,验证流程还会引入第二层分层确认:CrossEncoder 分数高于 0.7 时强制判定为有效证据,低于 0.1 时强制判定为无效证据,中间区间保留规则判断结果。该设计使得高置信度与低置信度的结果均可跳过更高成本的判断路径,仅对置信度模糊的中间区间进行精细化处理。

Reflect(反思):反思模块(Reflector)基于当前及历史观察结果,从四个维度评估证据充分性:

  • 数量与分数:有效证据数量不少于 3 条,且最高分数不低于 0.6;
  • 分数区分度:比较排名第一与第三的分数差距,差距过小说明检索结果区分度不足,证据可靠性存疑;
  • 查询覆盖度:验证通过的证据合并后是否覆盖查询关键词的至少 30%,覆盖度不足意味着即便分数达标,回答仍可能偏离问题核心;
  • 检索停滞检测:若连续两轮有效证据数量未增长,说明当前检索策略已失效,应调整策略而非重复同一查询。

判定证据不足时,反思模块会给出针对性建议——检索停滞时建议切换检索策略,覆盖度不足时提示需要补充的具体关键词,并将建议注入下一轮生成上下文,供 Reasoning 阶段决定是否再次调用检索工具、如何调整参数,形成闭环迭代;判定证据充分时,闭环终止,进入最终回答生成。循环设有安全阀(同一轮对话内最多 5 次检索),达到上限后强制基于现有证据生成回答,避免无限迭代。

三、混合检索与证据融合

检索层采用向量检索(Qdrant)、关键词检索(Redis RediSearch 全文索引)与知识图谱检索(Neo4j)三路并行,并使用 RRF(Reciprocal Rank Fusion,倒数排名融合) 算法进行结果融合。融合前各路结果独立执行质量过滤:

  • 排名截断:向量检索保留 Top-30,关键词检索 Top-20,知识图谱检索 Top-10(关键词检索的分数分布相对平坦,长尾噪声更多,因此截断更严格);
  • 相对分数过滤:剔除低于本路 Top-1 分数一定比例的结果,向量检索与关键词/图谱检索采用不同的过滤比例;
  • 兜底机制:过滤后结果数量不足 5 条时回退至截断前的原始结果,避免过度过滤导致证据缺失。

命中片段经过两类上下文补全处理:

  • 父子分块(Small-to-Big):索引阶段使用细粒度片段(子块)保证检索精度,命中后替换为包含更完整上下文的大片段(父块)用于生成,解决精确命中但上下文被切碎的问题;
  • 邻近扩展:对普通命中片段并发拉取前后相邻片段,补全定义、条件、例外等易被切分到相邻片段中的信息。

分块策略本身也非单一算法:混合分块器(HybridChunker)首先通过规则识别代码块、LaTeX 公式、Markdown 表格等不可分割的结构化内容并整体保留,其余文本内容采用嵌入模型的语义分块(按语义边界切分,而非固定字符长度硬切)。针对结构化报告类文档还设有独立的分块处理分支。

最终注入模型上下文的证据按 token 预算截断,并统一编号,供模型在生成回答时进行引用溯源。

四、三层记忆架构

该模块的设计参考了 Letta(原 MemGPT)项目的记忆分层思路,本人对其源码进行了深入研究后,将相关设计迁移并适配至本项目:

  • 核心记忆(Core Memory):常驻系统提示词(system prompt)的记忆区块,存储于 MongoDB,模型可通过 core_memory_append / core_memory_replace 工具主动编辑,无需检索即可感知,这是其区别于归档记忆的核心特征;
  • 归档记忆(Archival Memory):长期存储层,写入 Qdrant 进行向量化归档,按需通过语义检索召回,不占用当前上下文窗口;
  • 对话压缩(Recall Memory):当上下文窗口剩余空间低于设定阈值(50,000 token)时触发压缩。最近 8 条消息保留原文注入上下文,更早的消息压缩为结构化摘要,原始对话完整归档至 Archival Memory 以保证可追溯性,MongoDB 中的消息记录本身不做裁剪,确保完整审计能力。

压缩策略经过一轮实证迭代:早期版本采用 9 段式摘要结构,但实测发现压缩后长度反而超过原文(压缩比 114.76%),且数字、API 约定、错误日志等硬性细节在概括式摘要中的保真度损失达到 37.5%。据此改进为现行的 5 段式结构(用户需求 / 关键事实,显式保留数字、API 合同、决策结论、错误日志、专有名词 / 涉及文件 / 用户原话,逐条列出不做概括 / 当前状态),并将压缩比强制约束在 60% 以内。

五、跨供应商 Function Calling 统一适配层

项目需同时兼容本地部署模型(Ollama)、OpenAI 协议兼容接口(DeepSeek / Qwen / MiMo / OpenRouter / Together)、Anthropic Claude 与 Google Gemini,而各家供应商在工具调用协议的 Schema 格式、流式响应中参数分片方式上均存在差异。为此本人设计了一层统一适配(tool_call_adapter),以 OpenAI Chat Completions 格式作为中立的标准格式:

  • OpenAI 协议族(含多数国产模型的兼容接口):接口零转换,直接透传;
  • Anthropic:适配 input_schema / tool_use 消息块 / tool_result 消息结构的差异;
  • Gemini:适配 function_declarations / functionCall / functionResponse 结构的差异。

核心组件包括:工具定义的双向转换器(Schema Converter)、流式工具调用的增量聚合器(Stream Aggregator,用于将跨多个流式数据块拆分的工具调用参数重新拼接为完整 JSON,因为各供应商对参数片段的切分粒度均不相同)、响应归一化器,以及供应商能力探测与自动降级机制(Capability Registry)。上层 Agent 逻辑无需感知底层调用的具体供应商。

六、多 Agent 协作式深度研究模式

除单轮 Agentic RAG 外,系统还提供多 Agent 协作的深度研究模式:协调型 Agent(Coordinator Agent)首先分析问题复杂度,从 9 类专家 Agent(文档检索、公式分析、代码分析、概念解释、示例生成、练习设计、实现方案、批判性分析、总结归纳)中选取实际需要的子集,分配具体任务并确定执行依赖关系后并行/串行调度,最终由总结 Agent 汇总结果。默认组织原则围绕"检索 → 论证分析/概念解释 → 批判性校验 → 总结归纳"的主链路展开,避免不必要的 Agent 调用开销。