新闻详情

新闻详情

首页 / 资讯中心 / 详情

本地AI记忆系统实战:SQLite+向量检索+MCP协议构建Agent长期记忆

发布时间:2026/10/2 5:06:37来源:尧图网络
本地AI记忆系统实战:SQLite+向量检索+MCP协议构建Agent长期记忆
1. 为什么我们要自己动手做本地 AI 记忆系统做 AI Agent 开发的人都有一个共同的痛点每次对话结束上下文一清空Agent 就像失忆了一样。你昨天跟它聊了两个小时的项目架构今天再打开它完全不记得你是谁、在做什么。这不是模型能力的问题而是记忆层缺失的问题。市面上做记忆的方案我基本都试过一遍。云端方案比如各种 Memory API延迟高、数据不在自己手里、按调用量收费长期跑下来成本不低。纯本地方案呢要么是简单的向量数据库加检索要么是粗暴地把历史对话塞进上下文窗口前者检索精度差后者 token 消耗爆炸。我们想要的是一个真正能在本地跑起来、有结构化记忆管理、能跟 Agent 框架无缝对接的记忆系统。这个项目的核心目标很明确在本地环境构建一套完整的 AI 记忆系统支持记忆的写入、检索、更新、遗忘并且通过 MCP 协议暴露给上层 Agent 调用。说白了就是给 Agent 装一个海马体。适合谁来参考这篇内容如果你正在做 Agent 开发、对 MCP 协议感兴趣、或者单纯想给自己的本地 AI 助手加一个长期记忆能力这篇东西应该能帮你少走一些弯路。我们目前是在找技术合伙人一起推进所以下面会把技术选型、架构设计、实操细节都摊开来讲方便判断方向是否匹配。2. 记忆系统的整体架构设计思路2.1 为什么选 MCP 作为对外接口MCPModel Context Protocol是 Anthropic 推出的一个开放协议本质上是一个软件协议用来标准化 AI 模型与外部工具、数据源之间的交互方式。很多人第一次听到 MCP 会跟硬件协议搞混其实它跟 LSPLanguage Server Protocol是同一类东西——定义了一套通信规范让不同的客户端和服务端能互相理解。我们选 MCP 作为记忆系统的对外接口理由有三个第一解耦。记忆系统不应该绑定任何一个 Agent 框架。今天你用某个框架明天换一个记忆层不应该跟着重写。MCP 提供了一层标准化的抽象任何支持 MCP 的客户端都能直接调用。第二生态兼容。现在主流工具都在往 MCP 上靠比如 Codex 可以接入各种 MCP ServerDify 也支持浏览器 MCPHermes Agent 同样有 MCP 接入能力。我们把记忆系统做成 MCP Server等于天然接入了整个生态。第三本地优先。MCP 支持 stdio 和 SSE 两种传输方式stdio 模式下所有数据都在本地进程间流转不需要网络暴露这对隐私敏感的场景非常关键。2.2 记忆的分层模型我们借鉴了认知科学里人类记忆的分类方式把 AI 记忆分成三层记忆类型对应人类记忆存储周期典型内容工作记忆短期记忆单次会话当前对话上下文、临时变量情景记忆长期记忆持久化历史对话摘要、事件记录语义记忆知识记忆持久化用户偏好、事实性知识、实体关系工作记忆其实就是上下文窗口本身不需要额外存储。真正需要系统管理的是情景记忆和语义记忆。情景记忆回答的是发生了什么语义记忆回答的是我知道什么。这两者的检索策略、更新频率、衰减机制都不一样。2.3 存储层的选型考量存储层我们最终选了SQLite 向量扩展的组合而不是一上来就上专业的向量数据库。原因很实际SQLite 零配置、单文件、跨平台本地部署没有任何额外依赖通过 sqlite-vec 或 sqlite-vss 扩展可以获得向量检索能力结构化数据实体、关系、时间戳和向量数据放在同一个文件里事务一致性有保障备份就是复制一个文件迁移成本极低如果后期数据量上来了可以平滑迁移到 Qdrant 或 Milvus因为我们的存储层做了抽象接口切换只需要改配置。提示不要一上来就追求最强的向量数据库。本地场景下数据量通常在几万到几十万条记忆之间SQLite 加向量扩展完全够用运维复杂度低得多。3. 核心模块拆解与关键技术点3.1 记忆写入管道记忆写入不是简单地把对话存下来就完事。原始对话里充斥着大量噪音——寒暄、重复、无关信息。如果全部存进去检索时会被大量低质量记忆淹没。我们的写入管道分四步第一步分块Chunking。把长对话按语义边界切分成记忆单元。这里不能用固定长度切分否则会把一个完整的意图切碎。我们用的是基于对话轮次和语义相似度的混合切分策略先按对话轮次切然后计算相邻轮次的 embedding 相似度相似度低于阈值的作为切分点。第二步摘要Summarization。每个记忆单元生成一个简短摘要用于后续的快速检索和展示。摘要用本地小模型跑比如 Qwen2.5-3B 这个量级速度快、成本低。第三步实体抽取Entity Extraction。从记忆单元里抽出人名、项目名、技术栈、时间等结构化信息。这些实体是构建语义记忆的基础。比如我们决定用 Rust 重写解析器这条记忆会抽出实体项目解析器技术栈Rust决策类型重写。第四步向量化Embedding。把摘要和原始文本分别向量化存入向量索引。摘要向量用于粗筛原始文本向量用于精排。# 记忆写入管道的核心逻辑示意 def write_memory(raw_dialogue: str, session_id: str): chunks semantic_chunk(raw_dialogue) for chunk in chunks: summary local_llm.summarize(chunk) entities extract_entities(chunk) summary_vec embed(summary) content_vec embed(chunk) memory_id db.insert_memory( session_idsession_id, raw_textchunk, summarysummary, entitiesentities, summary_vecsummary_vec, content_veccontent_vec, created_atnow(), access_count0, importancecompute_importance(chunk, entities) ) return memory_id3.2 记忆检索策略检索是记忆系统最核心的能力。我们的检索走的是混合检索路线结合了向量相似度、关键词匹配、时间衰减和重要性加权。具体来说给定一个查询系统会用查询的 embedding 在摘要向量索引里做 ANN 搜索取 Top-K 候选对候选做关键词 BM25 匹配补充向量检索可能漏掉的精确匹配对每个候选计算综合得分score w1 * vector_sim w2 * bm25_score w3 * importance w4 * recency其中 recency 用指数衰减函数计算importance 在写入时根据实体密度和内容长度估算。权重 w1 到 w4 是可配置的不同场景可以调。取综合得分最高的 N 条记忆用原始文本向量做精排返回最终结果同时更新这些记忆的 access_count 和 last_accessed注意时间衰减的系数不要设得太激进。我们一开始用了半衰期 7 天的设置结果发现很多有价值的长期记忆被压下去了。后来改成 30 天效果好很多。记忆系统不是新闻推荐老记忆不一定没价值。3.3 记忆更新与遗忘机制记忆不是只写不删的。一个没有遗忘机制的记忆系统最终会变成一个垃圾场。我们的遗忘策略分三种被动遗忘长期未被访问且重要性低的记忆逐步降低检索权重但不删除。这相当于想不起来但还在潜意识里。主动遗忘用户显式要求删除某条记忆或者记忆内容被新记忆覆盖比如用户改了偏好旧记忆标记为失效。合并压缩多条相似记忆定期合并成一条更抽象的记忆。比如用户在不同时间说了五次我喜欢用 Python合并成一条用户偏好 Python的语义记忆原始五条降级为佐证材料。合并压缩用一个定时任务跑每周一次用本地 LLM 做摘要合并。3.4 MCP Server 的实现要点MCP Server 需要暴露几个核心工具Toolmemory_write写入新记忆memory_search检索记忆memory_update更新指定记忆memory_forget删除或失效记忆memory_stats返回记忆系统统计信息每个工具用 JSON Schema 定义输入输出MCP 客户端会自动生成调用界面。# MCP Server 工具定义示意 mcp.tool() def memory_search(query: str, top_k: int 5, memory_type: str all) - list: 检索相关记忆 Args: query: 检索查询 top_k: 返回条数 memory_type: 记忆类型过滤可选 all/episodic/semantic results hybrid_retrieve(query, top_k, memory_type) return [ { id: r.id, summary: r.summary, content: r.raw_text, score: r.score, created_at: r.created_at } for r in results ]传输层我们同时支持 stdio 和 SSE。stdio 用于本地 Agent 直接调用SSE 用于需要跨进程或跨设备的场景。4. 实操部署与关键环节实现4.1 环境准备与依赖安装本地部署这套系统硬件门槛不高。我们测试下来一台 16GB 内存的机器就能跑得很流畅。如果本地还要跑 embedding 模型和摘要模型建议 32GB 起步。依赖清单# 核心依赖 pip install mcp sqlite-vec sentence-transformers pip install fastapi uvicorn # SSE 模式需要 # 本地模型可选也可以用 API pip install llama-cpp-python # 或者用 ollama ollama pull qwen2.5:3b ollama pull nomic-embed-textembedding 模型我们用的是nomic-embed-text768 维本地跑速度快中文效果也还行。如果对中文检索精度要求更高可以换bge-m3但显存占用会大一些。4.2 数据库初始化SQLite 的向量扩展需要手动加载。初始化脚本如下import sqlite3 import sqlite_vec def init_db(db_path: str memory.db): conn sqlite3.connect(db_path) conn.enable_load_extension(True) sqlite_vec.load(conn) conn.enable_load_extension(False) conn.executescript( CREATE TABLE IF NOT EXISTS memories ( id INTEGER PRIMARY KEY AUTOINCREMENT, session_id TEXT NOT NULL, raw_text TEXT NOT NULL, summary TEXT NOT NULL, entities TEXT, -- JSON memory_type TEXT DEFAULT episodic, importance REAL DEFAULT 0.5, access_count INTEGER DEFAULT 0, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, last_accessed TIMESTAMP, is_active INTEGER DEFAULT 1 ); CREATE VIRTUAL TABLE IF NOT EXISTS memory_vectors USING vec0( memory_id INTEGER PRIMARY KEY, summary_vec FLOAT[768], content_vec FLOAT[768] ); CREATE INDEX IF NOT EXISTS idx_session ON memories(session_id); CREATE INDEX IF NOT EXISTS idx_active ON memories(is_active, importance); ) return conn提示sqlite-vec 的向量表是虚拟表不能直接跟普通表做 JOIN。我们的做法是先查向量表拿到 memory_id 列表再用WHERE id IN (...)查普通表。多一次查询但逻辑清晰。4.3 记忆写入的完整流程实际跑起来一次记忆写入大概涉及这些步骤。我拿一段真实对话举例用户说我最近在做一个本地记忆系统用 SQLite 存向量通过 MCP 暴露给 Agent 用。系统处理流程分块这句话作为一个完整记忆单元不切分摘要生成用户正在开发基于 SQLite 和 MCP 的本地记忆系统实体抽取{项目: 本地记忆系统, 技术栈: [SQLite, MCP], 用途: Agent}向量化摘要和原文分别 embed重要性计算实体密度高3 个实体 / 1 句话重要性给 0.75入库整个过程在本地跑3B 模型做摘要大概 200msembedding 大概 50ms总延迟在 300ms 以内。这个速度对于对话场景完全够用。4.4 检索效果调优实录检索调优是最花时间的部分。我们前后调了三轮记录一下关键节点。第一轮纯向量检索Top-5。问题是经常召回语义相似但实际无关的记忆。比如查记忆系统架构会召回系统架构设计模式这种泛泛的内容。第二轮加入 BM25 关键词匹配权重各占 50%。精确匹配好了但语义泛化能力下降。用户换个说法就检索不到。第三轮改成向量为主权重 0.6、BM25 为辅权重 0.25、重要性 0.1、时间衰减 0.05。这个配比在我们自己的测试集上 MRR平均倒数排名从 0.42 提升到 0.68。调参这件事没有银弹必须用自己的数据测。我们建了一个 200 条的测试集每条查询标注了正确答案每次改权重就跑一遍看指标。4.5 与 Agent 框架的对接MCP Server 跑起来之后Agent 侧的接入很简单。以 stdio 模式为例在 Agent 的配置里加上{ mcpServers: { memory: { command: python, args: [-m, memory_server, --db, ./memory.db], env: { EMBED_MODEL: nomic-embed-text, SUMMARY_MODEL: qwen2.5:3b } } } }Agent 启动时会自动拉起 MCP Server 进程之后就可以通过标准 MCP 协议调用记忆工具了。这里有个坑要注意stdio 模式下 MCP Server 的日志不能往 stdout 打否则会污染协议通信。所有日志走 stderr 或者写文件。我们一开始没注意调试信息直接 print导致 Agent 侧解析协议失败排查了半天。5. 常见问题与排查技巧实录5.1 记忆检索召回率低怎么办这是最常见的问题。排查顺序建议这样走先确认 embedding 模型是否适合你的语言和领域。中文场景用英文模型效果会打折扣。然后检查分块策略如果记忆单元切得太碎单条记忆信息量不足检索自然不准。再然后看权重配置是不是时间衰减太强把老记忆压没了。我们遇到过一个典型案例用户问之前说的那个方案检索不到。原因是那个方案没有具体关键词纯向量检索也匹配不到。后来我们在写入时额外生成了一层假设性问题就是让 LLM 预判这条记忆可能被什么问题检索到把这些假设问题也向量化存进去。召回率明显提升。5.2 记忆冲突怎么处理用户今天说喜欢 A明天说喜欢 B两条记忆冲突了。我们的处理策略是新记忆写入时先检索是否有语义冲突的旧记忆如果有把旧记忆标记为superseded并在新记忆里记录supersedes字段指向旧记忆。检索时默认只返回 active 记忆但保留追溯能力。5.3 性能瓶颈排查本地跑性能瓶颈通常在这几个地方症状可能原因排查方法写入慢LLM 摘要耗时换更小模型或异步写入检索慢向量索引未建好检查 vec0 表是否正常内存占用高embedding 模型常驻用 ONNX 量化版或按需加载数据库膨胀未做压缩合并检查合并任务是否在跑我们实测下来10 万条记忆的库检索延迟在 80ms 左右写入延迟 300ms内存占用 2GB 上下含模型。这个数据供参考。5.4 MCP 连接问题速查MCP 相关的坑主要集中在连接层Codex 找不到 MCP检查配置文件路径和 JSON 格式Codex 对配置格式比较严格Hermes Agent 接入失败确认 Hermes 版本支持 MCP老版本需要升级SSE 模式连不上检查端口是否被占用防火墙是否放行工具调用超时默认超时可能太短记忆检索如果涉及大量计算需要在客户端调大超时注意不同 MCP 客户端的实现细节有差异同一个 Server 在不同客户端上表现可能不一样。建议先在官方 Inspector 工具里测通再接入具体客户端。5.5 数据安全与隐私本地记忆系统最大的优势就是数据不出本地。但有几个点还是要注意数据库文件要设置合理的文件权限避免其他用户读取。如果用了 SSE 模式暴露端口一定要绑定 127.0.0.1 而不是 0.0.0.0。备份文件同样包含敏感信息加密存储。如果记忆里涉及密钥、密码这类内容写入前做一次敏感信息过滤。6. 后续扩展方向与技术合伙人需求这套系统目前跑通了核心链路但离好用还有距离。我们接下来想推进的方向包括记忆的可视化界面让用户能直观看到 Agent 记住了什么多模态记忆支持把图片、音频也纳入记忆体系记忆的跨设备同步同时保持本地优先以及更精细的记忆权限控制不同 Agent 能访问的记忆范围不同。找技术合伙人这件事我们看重的是对 Agent 记忆这个方向有真实兴趣而不只是把它当成一个练手项目。具体来说希望你有以下至少一个方向的积累MCP 协议或类似协议的实际开发经验向量检索或 RAG 系统的调优经验本地 LLM 部署和推理优化经验或者 Agent 框架的深度使用经验。合作方式灵活可以是代码贡献、架构设计、或者产品方向上的共创。我们目前没有融资压力节奏比较从容更在意把东西做扎实。如果你看到这里觉得方向对路欢迎带着你的想法和经历来聊。这个领域现在还在早期很多问题没有标准答案正适合一起摸索。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

零空间(Null Space)是什么?从矩阵映射到机器学习盲区 2026/10/2 5:47:46

零空间(Null Space)是什么?从矩阵映射到机器学习盲区

矩阵这玩意儿吧,我刚学的时候也觉得它就是一堆数排成矩形,用来解方程组的。直到后来做数据降维、看特征值、搞深度学习里的各种分解,才发现矩阵的本质是个“映射”——它把一个向量空间的点搬到另一个空间去。而在这个视角下,有个…

阅读更多 →
openrig自组模拟赛车座舱:从铝型材选型到装配全解析 2026/10/2 5:47:45

openrig自组模拟赛车座舱:从铝型材选型到装配全解析

最近模拟赛车圈里有个词出镜率挺高的——openrig。直接翻译就是“开放的架子”,但真正玩过的人都知道,它说的是一种自组模拟赛车座舱的思路:不买品牌整机,不依赖固定孔位,而是用铝型材一根一根搭出属于自己的设备承载平…

阅读更多 →
腾讯WeKnora深度实践:Agentic RAG知识库部署与调优指南 2026/10/2 5:47:44

腾讯WeKnora深度实践:Agentic RAG知识库部署与调优指南

1. 为什么我花了两周时间折腾 WeKnora第一次看到 WeKnora 这个名字,是在一个做企业知识管理的群里。有人甩了张截图,说腾讯微信团队开源了一个 AI 知识库项目,能直接把一堆 PDF、Word、Markdown 丢进去,然后用自然语言问它问题&am…

阅读更多 →
从零做AI工程:技术栈拆解与OCR全链路实战指南 2026/10/2 5:47:43

从零做AI工程:技术栈拆解与OCR全链路实战指南

做AI工程一年半,从连CUDA是什么都不知道,到手里两个OCR服务稳定扛着线上流量,我想把这条"从零起步"的路仔细拆一遍。这个标题太容易引发误会了——很多人以为AI工程的开端是学Transformer,是啃反向传播公式,…

阅读更多 →
端侧LLM部署实战:从量化到推理引擎的完整链路 2026/10/2 5:47:43

端侧LLM部署实战:从量化到推理引擎的完整链路

1. 端侧 LLM 部署到底在解决什么问题端侧 Agent 这个话题最近一年被聊得很多,但真正落到工程上,第一道坎从来不是 Agent 的编排逻辑,而是模型怎么塞进设备里还能跑得动。我见过太多团队在云端把 Agent 流程跑通之后,一到端侧就卡在…

阅读更多 →
AI Agent地基:状态编排、工具调用与并发优化实战指南 2026/10/2 5:47:36

AI Agent地基:状态编排、工具调用与并发优化实战指南

9月22日这一期的GitHub热榜,我刷完之后最大的感受不是“又出了什么新玩具”,而是大家终于开始认认真真给AI agent造地基了。前五名里有三个项目都属于同一类:不是某个炫酷的demo,不是又一个大模型套壳,而是给AI agent做…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉