[控场AI]
· 4 分钟阅读· 2,463 字

一本日记让AI拥有持久记忆:语义检索方案实测

一本日记让AI拥有持久记忆:语义检索方案实测

开源方案用分层记忆与混合检索让AI助手跨会话找回记忆。

文章介绍B站创作者开源的一套AI记忆方案,解决DeepSeek Harness上AI助手「聊完就忘」的问题。核心思路是放弃把全部规则塞进单个文件的做法,改为分层记忆:精简人设常驻上下文,动态信息写入日记、按需检索。检索采用向量分与关键词分合并排序的混合方式,既能理解「打星际拿冠军的人」这类语义查询,又能精确命中专有名词。作者还记录了三个实战踩坑:BGE查询端必须加前缀否则排序颠倒、512 token输入上限需控制切分粒度、小嵌入模型跨不过远距离语义需换大模型。方案已以MIT协议开源,一条命令即可安装。

AI助手聊完就忘,是每个深度用户都头疼的问题。B站一位创作者用「日记本+语义搜索」的组合,让跑在DeepSeek Harness上的AI找回了断掉的记忆——不是把对话历史全部塞进上下文,而是按需翻查。这套方案已开源在GitHub(MIT协议),一条命令即可安装。

为什么「把规矩写进文件」行不通

最初的做法很直接:把AI的人设、规则、注意事项全部写进一个文本文件,每次对话都完整读一遍。但写着写着,这个文件膨胀到几千字,每次对话都要重新加载,token消耗惊人。

更麻烦的是检索问题。创作者在视频中直言:「真正麻烦的不是长,是写了新的自己搜不到。」文件越长,新增内容越难被准确命中,AI依然会「忘记」刚刚记录的关键信息。

而且真正麻烦的不是长

问题的本质不在于记忆容量,而在于检索机制。人类不会把所有记忆同时调用,而是在需要时想起相关片段——AI也应该如此。

分层记忆:人设留在明面,动态信息进日记

新的思路是把记忆拆成两层。第一层是精简的「人设」,几百字即可,始终留在上下文中,保证AI的基本行为稳定。第二层是「日记」,记录今天做了什么、踩过什么坑、答应过什么事,这部分不进入上下文,只在需要时被检索调出。

这种架构的好处显而易见:上下文窗口不被挤占,而历史信息依然可查。关键是检索必须「问意思就行」——不要求记住原话,只要求理解语义。

混合检索:语义与关键词两路并行

创作者举了一个很能说明问题的例子:问「打星际拿冠军的那个人」时,查询里根本没有「李培南」三个字,但系统依然把相关条目翻了出来——因为它比对的是意思,不是词。

打星际拿冠军的那个人

技术上,这套方案同时计算向量分和关键词分,两路结果合并排序。向量分负责语义相似度,关键词分兜住专有名词的精确匹配。创作者的评价很中肯:「单独用哪个都不够,合起来踩稳。」

单独用哪个都不够

向量检索与关键词检索的互补性

向量检索把文本映射为高维空间中的稠密向量,通过计算余弦相似度来衡量语义接近程度,因此能理解「冠军」与「李培南」之间的隐含关联。但稠密向量的一个固有弱点是:对专有名词、编号、代码标识符等精确匹配不敏感,因为这类符号的语义信息稀疏。关键词检索(如 BM25)则基于词频与逆文档频率打分,能精准命中字面重合,却无法处理同义改写。混合检索通过加权融合两路得分(常见做法有分数归一化后加权求和,或使用 Reciprocal Rank Fusion 倒数排名融合),既保留语义泛化能力,又兜住精确匹配场景,这也是当前 RAG 系统的主流检索范式。

三个实战踩坑记录

视频中创作者分享了实现过程中的三个关键教训,对想复现方案的开发者很有参考价值。

BGE模型查询必须加前缀

使用BGE嵌入模型做检索时,查询端必须加一句特定前缀。不加的后果相当严重:相关句子得分0.44,无关句子反而得0.46,排序完全颠倒。这是BGE模型的训练方式决定的,查询和文档需要采用不同的编码格式。

BGE 模型的非对称检索设计

BGE(BAAI General Embedding)是智源研究院开源的一系列中英文嵌入模型,在 MTEB 等检索基准上表现突出。它采用非对称检索训练方式:查询(query)和文档(passage)使用不同的编码模板,查询端需加上类似「为这个句子生成表示以用于检索相关文章:」的指令前缀。这是因为训练时正负样本对就是按这种格式构造的,模型学会了在该前缀下把查询投射到与文档更匹配的语义区域。若查询端遗漏前缀,编码分布与训练分布不一致,相似度打分就会失真,出现相关句子得分低于无关句子的倒挂现象。部分后续版本(如 bge-m3)对此做了简化,但使用 bge-large-zh 等经典版本时仍需遵守。

512 token输入上限的陷阱

BGE的输入上限是512个token,中文大约一字一token。创作者按700字切分文本,结果直接「崩了」。超长输入会导致截断或报错,切分粒度必须控制在模型限制之内。

中文差不多一字一个

嵌入模型的上下文窗口与切分策略

主流嵌入模型基于 BERT 类编码器架构,其位置编码决定了最大输入长度,BGE 经典版本的 512 token 上限即来源于此。中文经 BPE 分词后大致一字一 token,因此 512 token 约等于 512 个汉字,留出余量后按 500 字左右切分更稳妥。超长文本会被截断(只编码前 512 token)或直接报错,导致后半段信息丢失。实践中通常采用带重叠的滑动窗口切分(如块大小 400、重叠 50),避免语义在切分边界被割裂;对于必须保留全局信息的场景,则需换用支持长上下文的嵌入模型或采用分块后聚合摘要的策略。

小模型跨不过远距离语义

用小型嵌入模型时,「搜夜班能种」和「搜作息怎么安排」会跑偏——语义距离太远,小模型无法建立关联。换成更大的嵌入模型后才解决。这说明在语义检索场景下,模型容量的下限比想象中更高。

谁适合用这套方案

这套日记系统已在GitHub开源,MIT协议,一条命令装完,并附带如何把规则贴进自己agents文件的说明。它不规定「记什么、什么时候记」,那属于每个Agent自己的策略——工具只负责一件事:让忘掉的东西还能翻回来。

对于长期运行的AI助手、需要跨会话保持上下文的Agent应用,以及受困于上下文窗口限制的开发者,这个轻量方案提供了一个务实的起点。它不是万能记忆,而是一个可控的「外部索引」——用最小成本换来可检索的持久记忆。

分享:

相关推荐