同一个问题,换个上下文就该检索出不同答案——嵌入模型终于学会"看人下菜碟"了
你有没有想过一件挺反直觉的事:现在所有的 embedding 模型,本质上都是"健忘症患者"。
把一段文本丢进去,它吐出一个向量。再丢一段,再吐一个。每段文本都是孤立编码的——它不知道前面发生了什么,也不在乎这段话在整个对话里排第几位。换句话说,它眼里只有这段文字本身,没有上下文,没有时间顺序,没有故事线这回事。
平时做语义检索,这没什么问题。但一旦进入长对话、Agent 记忆这种动态场景,麻烦就来了。
举个具体的例子。用户上周说"我喜欢喝美式",这周又说"我最近改喝拿铁了"。现在你问 Agent:"我平时喝什么咖啡?"——一个静态 embedding 模型会怎么做?它会把"美式"和"拿铁"两段都召回,因为这两段在语义上都跟"咖啡偏好"高度相关。它根本分不清哪个是过时信息、哪个是最新状态。
这就是静态嵌入的死穴:同一个查询,永远只能检索出"语义上最像"的东西,而不是"在当前上下文里最该被检索"的东西。
EvoEmbedding 这篇论文想干的事,就是把 embedding 从"静态快照"变成"会进化的表征"。听起来有点玄,但它的设计其实简单得让我有点意外。我们慢慢聊。
核心摘要
EvoEmbedding 提出了一种可进化表征(evolvable representation)的嵌入范式:模型在顺序处理输入时,维护一个持续更新的潜在记忆(latent memory),并把这个记忆和当前文本内容一起编码,生成随上下文演化的 embedding。结果就是——同一个查询,在不同的上下文状态下,能检索出不同的目标,彻底跳出了"静态语义搜索"的框架。
为了让模型学会这个能力,作者构建了 EvoTrain-180K 数据集,用 18 万条合成样本做记忆与检索的联合优化。两个关键工程设计撑起了整个方法:记忆队列(memory queue)防止循环编码导致的表征坍塌,分段批处理(segment-batching)把训练速度拉快 3.8 倍。
效果相当能打:只用了同类模型不到 1% 的数据量、训练上下文长度不到测试场景的 1/10,EvoEmbedding-4B 在 10 个长上下文检索基准上的综合表现超过了 Qwen3-Embedding-8B、KaLM-Embedding-Gemma3-12B 这些更大的专用模型。更有意思的是——一个挂上 EvoEmbedding 的朴素 RAG 流程,居然打过了专门设计的 Agentic Memory 系统(如 Mem0、MemoryOS)。
我的判断:这篇论文最值钱的地方不在于跑分,而在于它换了一个看待 embedding 的视角。它说服了我——长上下文检索的瓶颈,可能从来就不是模型不够大、数据不够多,而是编码方式本身错了。
论文信息
- 标题:EvoEmbedding: Evolvable Representations for Long-Context Retrieval and Agentic Memory
- 作者:Chang Nie, Chaoyou Fu, Junlan Feng, Caifeng Shan
- arXiv:2606.21649(cs.CL,2026 年 6 月 19 日提交)
- 项目主页:https://clare-nie.github.io/EvoEmbedding

图1:EvoEmbedding 家族(0.8B / 2B / 4B)在 10 个基准上的雷达图对比。可以看到,在处理动态上下文的任务(比如长期个性化记忆)上,它明显甩开了传统静态模型和 Agentic 记忆系统。注意那条蓝色的线几乎把所有竞品都包在里面。
问题到底出在哪:静态编码的"时间盲区"
先把痛点说透。
现有 embedding 模型的工作方式是这样的:给你一段文本 \(x\),模型 \(f\) 算出一个固定向量 \(v = f(x)\)。这个 \(v\) 只取决于 \(x\) 本身。无论 \(x\) 出现在对话开头还是结尾,无论它前面铺垫了什么,编码结果都一模一样。
这套范式在传统 IR(信息检索)里没毛病——你检索一篇文档,文档就是文档,跟它在哪个语料库里、排第几无关。但长上下文场景完全是另一回事。
我自己之前在做长对话记忆的时候碰到过一模一样的坑。用户的状态是会变的:今天的偏好可能推翻昨天的,一个事实可能被后续的对话更新。静态 embedding 把每一句话都当成独立的、永恒不变的事实来编码,结果检索的时候,新旧信息混在一起全召回,下游的生成模型被一堆自相矛盾的"历史"绕晕。
论文里有张图把这个对比讲得特别清楚。

图2:(左)同一个查询在不同上下文下,EvoEmbedding 生成的是会演化的表征,能避开静态方法那种"召回过时信息"的毛病。(右)在 LongMemEval 上,挂了 EvoEmbedding-4B 的标准 RAG 超过了现有的记忆基线,而且 token 开销几乎为零。
那有人会说,长上下文的问题不是已经有一堆方案了吗?比如各种 latent memory 的工作,像 M+、LatentRAG 这些,都在用潜在表征来压缩历史。
对,但论文点出了这些方法的一个共同软肋:它们的记忆机制和 LLM 的自回归生成过程深度耦合。说人话就是,它们需要白盒访问模型内部的 hidden states 才能工作。这意味着什么?意味着你没法把它们用在 GPT-4o 这种只给你 API 的闭源商业模型上。而且,让同一个模型既管记忆又管生成、还不做显式隔离,很容易整出幻觉这种不可预测的行为。
EvoEmbedding 的切入点就在这——把"记忆"这件事从生成里剥离出来,专门做成一个检索表征模块。这个解耦,是它后面所有设计的起点。
方法核心:让记忆"流动"起来
EvoEmbedding 的整体思路,一句话概括:模型一边顺序读输入,一边维护一个不断更新的潜在记忆;编码每段文本时,把这个记忆和文本内容揉在一起,生成会随上下文进化的 embedding。
来看架构图。

图3:在第 t 步处理输入分段时,模型并行做两件事。(左)记忆进化:LLM 把当前分段和前一步的记忆压缩进可学习的 token,投影后更新一个 FIFO 潜在记忆队列。(右)表征生成:把历史潜在记忆和当前分段结合,生成一个可进化的检索 embedding。
两条并行的任务流
模型在每个时间步 \(t\) 做两件事,可以用两个公式概括:
第一条是记忆进化:拿当前分段 \(x_t\) 和上一步的记忆 \(\mathbf{M_{t-1}}\),生成 \(K\) 个新的潜在 token \(\mathbf{\tilde{M}_t}\)。
第二条是表征生成:同样拿 \(x_t\) 和 \(\mathbf{M_{t-1}}\),但这次输出的是一个用于检索的向量 \(\mathbf{v_t}\)。
注意这里的精巧之处——查询阶段只跑第二条任务流。也就是说,你拿一个 query 进来,它会用当前积累的记忆状态 \(\mathbf{M_T}\) 去编码,所以同一个 query 在不同记忆状态下,编出来的向量就是不一样的。这就是"可进化"的本质。
\(\theta_m\) 和 \(\theta_r\) 是模型里负责这两个任务的不同参数——作者用了 multi-LoRA 设计,把记忆进化和表征生成两个能力解耦开,推理时可以灵活切换。
记忆队列:防坍塌的关键
这部分我觉得是整篇论文最有工程智慧的地方。
如果你让一个模型反复地、循环地编码自己生成的记忆,会发生什么?表征坍塌(representation collapse)。这是 RNN 时代就有的老问题——信息在循环里反复传递,最后所有的表征都糊成一团,区分度全没了。
EvoEmbedding 用一个 FIFO(先进先出)队列来管理记忆:
队列容量 \(C = L \times K\),存的是最近 \(L\) 步生成的潜在表征。\(f_m(\cdot)\) 是个投影器,把新生成的 token 映射到共享记忆空间。
这个队列设计的妙处在于两点:
第一,有界循环。 任何一个历史记忆,最多被循环编码 \(L\) 次就会被挤出队列。这直接掐断了无限循环导致的坍塌——所以 EvoEmbedding 能直接在长上下文上训练,不需要那种从短到长的课程学习(curriculum learning)。这点后面消融实验会证明它有多关键。
第二,有界容量。 严格限制记忆大小,既把计算复杂度框住了,又逼着模型学会在每一步把新知识和历史状态融合——因为它没法把所有东西都记下来,必须做取舍。
论文给了个很形象的数字:相比 M+ 那种缓存逐层特征的做法,EvoEmbedding 只存 \(C = 512\) 个潜在 token,内存占用大概也就相当于编码一张图片。
分段批处理:3.8 倍加速从哪来
顺序处理分段有个天然的效率问题——你得一段一段地前向传播,GPU 利用率低得可怜。
作者的解法叫动态分段批处理(Dynamic Segment-Batching):不再一段一段跑,而是把 \(k\) 个连续分段拼在一起并行处理。\(k\) 是动态决定的,保证拼接后的总长度不超过某个阈值(比如 2048 token)。
记忆进化的公式就变成了批处理形式:\(\mathbf{\tilde{M}_{t:t+k}} = \pi_{\theta_m}(x_{t:t+k}, \mathbf{M_{t-1}})\)。
这一招把训练速度拉快了 3.8 倍,而且——这点让我有点意外——性能不降反升。后面消融实验会看到具体数字。
训练目标:一个被冻住的 backbone
训练用的是两个损失的组合:
\(\mathcal{L}_{mem}\) 是记忆生成损失,用标准交叉熵。这里有个设计我得专门拎出来说——预测答案时,作者把 backbone LLM 的参数冻住,并且关掉所有 LoRA adapter:
为什么要这么做?因为这样一来,loss 的梯度会穿过冻住的 backbone,直接反传到记忆 \(\mathbf{M}_t\) 上。这就隐式地强迫记忆模块生成出"backbone 原生语义空间能听懂"的潜在状态。这个设计挺聪明的——它保证了记忆不是自说自话,而是和基座模型的理解能力对齐的。
\(\mathcal{L}_{con}\) 是对比损失,用来把 query 表征和相关上下文对齐。作者还加了个长度加权因子 \(\log(N+1)\),因为负样本数量 \(N\) 会随输入长度剧烈变化,这个因子能自适应地校准 loss 尺度,让不同长度的序列都能稳定优化。
数据:EvoTrain-180K 怎么造出来的
模型再巧,没有合适的数据也学不会"看上下文检索"这个能力。标准的检索数据集都是孤立的 query-document 对,根本不包含动态上下文。所以作者自己造了一个。

图4:三阶段的自动化数据合成流程——(1)跨领域、跨格式、跨长度的原始上下文构建;(2)用 LLM 和 40 多种模板生成语义型和推理型查询;(3)做正负样本标注和噪声过滤。
三个阶段拆开看:
Stage 1:原始上下文构建。 造了三类上下文——从 FineWeb 采样的多样化网页文本(用滑动窗口切成顺序分段)、LLM 合成的多轮人格驱动对话、以及从文本/对话里抽取的各类记忆。
Stage 2:动态 QA 生成。 这步有两个关键设计:预定义了 40 多种模板类型(比如指代消解、时序理解),用不同类型和规模的 LLM 生成问题,既保证有简单的语义匹配题,也有需要深度理解上下文的复杂题。
Stage 3:检索标注与验证。 用 Gemini-3.1-Pro-Preview 做检索标注和样本验证,识别出 query 相关分段作为正样本,同时排除幻觉、剔除那些靠通用知识就能答、不依赖给定历史的问题。
最后产出 184,137 条高质量样本。每条样本严格控制在 12K token、256 个分段以内。
这里有个数字值得停一下:EvoEmbedding 用的训练数据量不到同类 embedding 模型的 1%,训练上下文长度不到测试场景的 1/10。 用这么点数据撬动 SOTA,本身就说明问题不在数据量,而在范式。
实验:朴素 RAG 打过专用记忆系统?
主结果:小模型吊打大模型
先看检索任务的主表。
| 模型 | Size | Dim | ESG | LoCoMo | LongMemEval | REALTALK | QASPER | PeerQA | CovidQA | MLDR | Overall |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Multilingual-e5-large | 0.6B | 1024 | 51.4 | 65.6 | 80.5 | 54.5 | 72.6 | 40.6 | 89.5 | 97.0 | 69.0 |
| KaLM-Embedding-Gemma3 | 12B | 3840 | 63.6 | 58.4 | 93.0 | 54.9 | 73.8 | 44.7 | 93.0 | 100.0 | 72.7 |
| Qwen3-Embedding-8B | 8B | 4096 | 63.6 | 49.6 | 87.9 | 50.4 | 70.5 | 41.2 | 93.9 | 95.0 | 69.0 |
| EvoEmbedding-0.8B | 0.8B | 1024 | 85.7 | 63.0 | 83.0 | 58.0 | 83.1 | 48.1 | 94.4 | 98.0 | 76.7 |
| EvoEmbedding-2B | 2B | 1024 | 86.7 | 74.1 | 90.6 | 60.7 | 87.0 | 51.8 | 95.0 | 98.0 | 80.5 |
| EvoEmbedding-4B | 4B | 1024 | 84.0 | 76.3 | 91.7 | 62.6 | 85.1 | 51.7 | 94.9 | 98.0 | 80.5 |
(Recall@10,节选关键行)
把这张表看明白,有几个点很扎眼:
EvoEmbedding-4B 的 Overall Recall@10 做到 80.5,比第二名 KaLM-Embedding-Gemma3-12B(72.7)高了 7.8 个点。NDCG@10 那栏也是同样的故事,65.2 vs 57.1,高 8.1 个点。
但真正让我注意的是那个 0.8B 的小不点——它只有 0.8B 参数、1024 维向量,综合分却到了 76.7,把 8B、12B 的大块头全压在身下。你想想看,参数差了一个数量级,embedding 维度也只有人家的 1/4 到 1/3,结果反而赢了。这不是参数堆出来的胜利,是范式的胜利。
再看生成任务。

图5:在不同检索规模(Top-k)下,挂 EvoEmbedding-4B 的朴素 RAG 流程综合表现最好。注意 LoCoMo 上的精度一直涨到 k=32 都没饱和,而其他数据集大多在 k=8 或 k=16 见顶后略降——这是因为太大的上下文窗口会引入干扰噪声。
朴素 RAG vs Agentic Memory:这个对比有点狠
这是论文最有冲击力的部分。来看 LongMemEval 的细分表。
| 方法 | Temp | Multi | Knowledge | User | Assistant | Preference | Overall |
|---|---|---|---|---|---|---|---|
| Full Context | 33.1 | 35.6 | 76.9 | 82.9 | 87.5 | 50.0 | 54.8 |
| Mem0 | 41.9 | 28.1 | 28.6 | 55.3 | 26.1 | 81.8 | 39.5 |
| MemoryOS | 28.6 | 36.8 | 61.5 | 72.9 | 92.9 | 33.3 | 49.6 |
| A-MEM | 51.9 | 51.1 | 76.9 | 90.0 | 96.4 | 40.0 | 65.2 |
| LightMem | 54.2 | 51.9 | 66.7 | 80.0 | 31.3 | 80.0 | 70.2 |
| Qwen3-Embedding-8B (RAG) | 57.9 | 62.4 | 76.9 | 90.0 | 98.2 | 63.3 | 71.4 |
| EvoEmbedding-4B(RAG) | 63.2 | 71.4 | 84.6 | 98.6 | 100.0 | 60.0 | 77.6 |
一个只用了 Top-8 检索分段的标准朴素 RAG,挂上 EvoEmbedding-4B,综合精度 77.6%,把 LightMem(70.2%)这种专门设计的 Agentic Memory 系统甩开了 7 个多点。Single-User 子任务 98.6%、Single-Assistant 直接 100.0%。
而且——它还超过了 Full Context 基线(54.8%)整整 22.8 个点。这说明 EvoEmbedding 不只是"找得准",它还能主动过滤掉那些会干扰生成模型的过时、噪声历史。
更关键的一笔:图2 右边那个对比里提到,EvoEmbedding 的 token 开销几乎为零,因为它不需要像 Agentic 系统那样单独跑一个记忆构建阶段——它的潜在记忆是在编码阶段顺手建好的,测试时根本不依赖生成模型。
当然,论文也老实承认了短板:在 LoCoMo 的 Temporal 和 Open-domain 子任务上,EvoEmbedding 还是稍逊于高度专门化的 LightMem。这点我挺欣赏,没有把所有指标都吹成第一。
即插即用:给现有记忆系统做增强
EvoEmbedding 还能当成一个 plug-and-play 模块,去升级现有的记忆管线。作者在 LoCoMo 上重做了 A-MEM、LightMem、MemoryOS,用它做重排器。
结果是:给 A-MEM 带来 +19.2%、给 MemoryOS 带来 +20.5% 的绝对提升,而且在三个框架上都稳定超过了"推理策略"和 Qwen3-Reranker-4B 的重排策略。因为它只维护固定大小的潜在记忆、避开了二次复杂度,GPU 开销跟 Qwen3-Reranker-4B 相当。
时序敏感性:可视化看"进化"是真的
光说"可进化"还不够,得证明模型真的捕捉到了时间顺序。这是我觉得最漂亮的一个分析实验。

图6:用"firstly""lastly""in the middle"三种时间关键词去查询 256 个分段。(上排)相似度曲线——EvoEmbedding 在 "lastly" 时相似度随时间递增、在 "firstly" 时在开头分段急剧峰值;而静态模型的曲线全都纠缠重叠在一起。(下排)t-SNE 可视化——基线模型的表征完全混在一起,EvoEmbedding 的潜在空间则按时间位置干净地分成了不同簇。
这张图把"静态 vs 进化"的差别讲得淋漓尽致。Qwen3-Embedding-8B、KaLM 这些静态模型,面对"firstly"和"lastly"两个截然相反的时序意图,相似度曲线几乎重合——它们压根分不清。EvoEmbedding 则能精准解耦:问"最先"就在开头峰值,问"最后"就随时间递增爬到末尾。
下排的 t-SNE 更直接——基线的表征糊成一团,EvoEmbedding 按时间位置分成了清晰的、不重叠的簇。这就是"持续更新的潜在记忆"把时序信息编进表征的视觉证据。
消融:哪些设计是命根子
消融表把每个组件的贡献量化得很清楚。
| 策略 | 训练时间(h) | LoCoMo | LongMemEval | PersonaMem-32K | PersonaMME-32K | PersonaMME-128K | Overall |
|---|---|---|---|---|---|---|---|
| EvoEmbedding-4B | 26.6 | 69.9 | 76.6 | 56.2 | 72.0 | 72.8 | 69.5 |
| w/o Memory Queue | 91.3 | 17.0 | 10.0 | 46.9 | 64.3 | 64.3 | 40.6(降 28.9) |
| w/o Memory Loss | 27.7 | 15.2 | 11.4 | 48.9 | 65.5 | 64.3 | 41.1(降 28.4) |
| w/o Length-Weighting | 26.5 | 68.4 | 73.8 | 54.5 | 71.6 | 73.2 | 68.3(降 1.2) |
| w/o Segment-Batching | 101.4 | 66.0 | 75.0 | 54.3 | 71.2 | 71.6 | 67.6(降 1.9) |
这张表的信息量很大:
记忆队列和记忆损失是绝对的命根子。 去掉任意一个,LoCoMo 和 LongMemEval 上直接崩盘——掉了超过 50%(LoCoMo 从 69.9 跌到 17.0)。这就是表征坍塌的真实代价。另外三个数据集掉得轻一些(约 8%),是因为它们是选择题形式。
为什么去掉队列训练时间还暴涨到 91.3 小时?因为没了队列的有界机制,每步要更新整个 512 容量的记忆,而不是只生成 16 个 token。队列把生成开销限制在每步 \(K=16\) token,顺手把训练效率提了 3.4 倍。
分段批处理是效率的命根子。 训练时间从 101.4 小时压到 26.6 小时,3.8 倍加速实锤。而且综合性能还涨了 1.9 个点——这个"既快又好"的结果,我一开始是有点怀疑的,但消融数据摆在这。
长度加权贡献相对小(1.2 个点),但它解决的是"模型偏向短序列"这个隐蔽问题,算是锦上添花。
再补一个效率对比表,这里有个需要客观看待的 trade-off:
| 模型 | Size | 编码时间(s) | 峰值显存(GB) | 最佳 Top-k | 精度(%) |
|---|---|---|---|---|---|
| Qwen3-Embedding-8B | 8B | 5.52 | 43.1 | k=16 | 73.2 |
| KaLM-Embedding-Gemma3 | 12B | 9.89 | 69.3 | k=4 | 72.8 |
| EvoEmbedding | 4B | 22.08 | 20.9 | k=8 | 77.6 |
EvoEmbedding 显存占用最低(20.9GB,因为只维护固定大小的潜在记忆),精度最高。但代价是编码时间显著更长(22.08s vs 5.52s)——因为它要顺序处理、连续构建记忆,没法像静态模型那样并行编码所有分段。这是它范式上的固有代价,论文也没藏着掖着。
我的判断:范式比跑分更值钱
聊完了,说说我的真实看法。
先说亮点。这篇论文最打动我的,不是那些超过 8B、12B 模型的跑分数字,而是它重新定义了 embedding 该是什么。静态编码这个范式我们用了太久,久到几乎没人去质疑"为什么一段文本的向量必须是固定的"。EvoEmbedding 给了一个反例——当上下文是动态的、有时序的、需要持续追踪状态的,embedding 就该跟着进化。这个 insight 本身就很有价值。
它的工程设计也确实扎实。记忆队列防坍塌、分段批处理提速、冻结 backbone 对齐语义空间——每一个都不是花架子,消融实验把它们的贡献量化得明明白白。尤其是"朴素 RAG 打过专用 Agentic Memory 系统"这个结果,对整个 Agent 记忆领域是有冲击力的:它在暗示,与其在外部搭一套复杂的记忆管线,不如把时序和上下文感知直接编进表征里。这个方向如果成立,能省掉很多工程复杂度。
但我也有几个保留意见。
第一,编码延迟是个真问题。22 秒 vs 5 秒的差距,在很多实时检索场景下是致命的。论文把它归为"范式固有代价",但这意味着 EvoEmbedding 更适合离线建库、对延迟不敏感的场景,在线实时检索可能水土不服。
第二,数据全是合成的。EvoTrain-180K 的上下文、QA、标注几乎全靠 LLM 生成(Gemini、各种 LLM)。合成数据的质量天花板和分布偏差,是个绕不开的隐患。论文说做了幻觉过滤,但合成数据里那种微妙的"模型味"会不会让模型学到某种捷径,这点我不太确定,得看后续更多 out-of-domain 的验证。
第三,LoCoMo 的 Temporal 子任务还是输给了 LightMem。一个号称"时序感知"的模型,在最考验时序的子任务上没拿第一,这说明它的时序能力还有上限,离"完全解决"还有距离。
总的来说,这是一篇我会推荐细读的论文。它的价值不在于刷了多少榜,而在于它提供了一个值得长期下注的方向——可进化表征。如果你在做长上下文检索、对话记忆、或者 Agent 的长期记忆系统,这个思路真的值得试试。哪怕只是把"embedding 必须静态"这个隐含假设拿出来重新审视一遍,都已经够本了。
至于它会不会成为未来长上下文检索的标配——我觉得方向是对的,但那个编码延迟问题不解决,大规模落地还得再等等。
觉得有启发的话,欢迎点赞、在看、转发。跟进最新AI前沿,关注我