Context Compressing in Agent Application

1 IN-CONTEXT AUTOENCODER FOR CONTEXT COMPRESSION IN A LARGE LANGUAGE MODEL

论文地址:https://arxiv.org/pdf/2307.06945
代码:https://github.com/getao/icae/tree/main

1.1 模型结构

  现有大语言模型面临几个核心问题:

  • 大语言模型(LLMs)通常受限于上下文长度(context window)——输入太长就会导致计算资源消耗高、内存需求大。
  • 多数解决方案是改变模型架构(比如稀疏注意力、滑动窗口、长距离注意力等),但这些方案在上下文长度极长时仍然性能下降。

  为了解决这个问题,论文提出了一个不同思路:把长的上下文压缩成一个短的“记忆槽”(memory slots),只让模型在推理时看到这些压缩后的记忆槽,而非完整上下文,从而节省计算与内存开销。

在这里插入图片描述

  ICAE 的设计可以分成两部分:编码器(encoder)、解码器(decoder)。

  • 编码器
    • 基于已有的 LLM,使用 LoRA(Low-Rank Adaptation)方式做轻量调整,以及新增 memory tokens 的 embedding。
    • 输入一个完整上下文(长度为 L 的 token 序列 w₁…w_L),在其后附加 k 个 memory tokens m₁…m_k(k ≪ L),然后通过编码器处理,输出这 k 个 memory slots(mf₁ … mf_k)。这些 memory slots 是对整个上下文的压缩表示。
  • 解码器
    • 解码器就是保持不变的目标 LLM,其作用是“读取”这些 memory slots(加上某些额外 prompt 或任务输入)来完成任务,比如重构原文、继续文本、回答问题等。也就是说,解码器并不看到完整上下文,只看到压缩后的 memory slots。

  训练分为两个步骤:

  • 预训练:双目标优化

    • 通过海量文本(如 The Pile)训练,让记忆槽具备 “恢复上下文” 和 “泛化表征” 能力:
    • 自编码目标( L A E \mathcal{L}_{AE} LAE:从记忆槽中恢复原上下文 c c c,即最大化 P ( c ∣ m 1 ~ , . . . , m k ~ ; Θ L L M ) P(c|\tilde{m_1},...,\tilde{m_k};\Theta_{LLM}) P(cm1~,...,mk~;ΘLLM),需在记忆槽后追加特殊 token“[AE]” 标识任务。该目标无需标注,可利用海量数据,确保记忆槽保留上下文核心信息。
    • 文本续写目标( L L M \mathcal{L}_{LM} LLM:从记忆槽中预测上下文的续写内容 o = ( w L + 1 , . . . , w L + N ) o=(w_{L+1},...,w_{L+N}) o=(wL+1,...,wL+N),即最大化 P ( o ∣ m 1 ~ , . . . , m k ~ ; Θ L L M ) P(o|\tilde{m_1},...,\tilde{m_k};\Theta_{LLM}) P(om1~,...,mk~;ΘLLM)。缓解单一 AE 目标的过拟合问题,提升记忆槽的泛化能力。
    • 预训练损失为双目标加权: L p r e t r a i n = λ L A E + ( 1 − λ ) L L M \mathcal{L}_{pretrain}=\lambda\mathcal{L}_{AE}+(1-\lambda)\mathcal{L}_{LM} Lpretrain=λLAE+(1λ)LLM,其中 λ = 0.4 ∼ 0.6 \lambda=0.4\sim0.6 λ=0.40.6 时效果最优。
  • 指令微调:适配实际任务
    为让记忆槽能与多样化 prompt 交互,使用自建的 PWC 数据集(Prompt-with-Context)微调:

    • PWC 数据集:含 24 万训练样本、1.8 万测试样本,每个样本为(上下文、prompt、响应)三元组,由 GPT-4 生成,覆盖不同上下文长度(多数超 500token)与任务类型(摘要、问答、关键词提取等)。
    • 微调目标:最大化 “基于记忆槽 + prompt 生成正确响应” 的概率,即 L F T = max ⁡ Θ L o R A , e m P ( r 1 . . . r n ∣ m 1 . . . m k , p 1 . . . p m ; Θ L L M ) \mathcal{L}_{FT}=\max_{\Theta_{LoRA},e_m}P(r_1...r_n|m_1...m_k,p_1...p_m;\Theta_{LLM}) LFT=maxΘLoRA,emP(r1...rnm1...mk,p1...pm;ΘLLM),增强记忆槽的任务适配性。

1.2 代码分析

  从模型上看,ICAE 是基于已有的 LLM 构建的,具体来说,是在 LLM 基础上应用了 LoRA 技术,新增了 memory tokens 的 embedding。

self.icae = base_llama.LlamaForCausalLM.from_pretrained(...)  # 基础LLM
self.icae = get_peft_model(self.icae, lora_config)  # 应用LoRA

  同时通过新增的 memory tokens 嵌入层,模型可以学习到 memory slots 的表示。

# 记忆token嵌入层(可学习参数)
self.memory_token_embed = nn.Embedding(model_args.mem_size+3, self.dim)

# 生成记忆槽
compress_outputs = self.icae(inputs_embeds=autoencoder_input_embedding, enable_lora=True)
memory_embedding = compress_outputs[memory_mask].view(batch_size, self.model_args.mem_size, -1)

  生成阶段直接复用基础 LLM 的解码器,将记忆槽与 prompt 拼接后作为输入,无需修改原模型结构,确保兼容性。

# 拼接记忆槽和prompt嵌入
decoder_input_embeddings = torch.cat((memory_embedding, prompt_answer_embs), dim=1)
# 调用原LLM生成响应
decoder_outputs = self.icae(inputs_embeds=decoder_input_embeddings)

2 Compressed Context Memory For Online Language Model Interaction

论文地址:https://arxiv.org/abs/2312.03414
代码:https://github.com/snu-mllab/context-memory

2.1 模型

  现有LLM交互中面临几个问题:

  • 在在线交互(对话、个性化、多任务学习等)中,语言模型的上下文随着时间持续累积。Transformer 的 self-attention 机制对完整上下文(context)的 key/value (KV) 缓存与计算开销随着时间线性或更坏地增长,导致内存使用大、延迟高、吞吐低。
  • 现有的上下文压缩方法大多是针对固定长度 context(prompt / 演示集)设计的,不太适合上下文随着时间不断新增、需要动态处理的情形。

  论文提出了一种叫 Compressed Context Memory (CCM) 的机制,用来在 inference 时动态压缩累积的 context KV,节省资源,同时尽量保持性能。
在这里插入图片描述

  CCM提出动态压缩上下文内存框架,通过持续压缩积累的 KV 对,在有限内存中支持在线推理,核心包含 3 大模块:

  • 上下文压缩机制:基于⟨COMP⟩token 的 KV 压缩
    • 压缩对象:直接压缩注意力 KV 对(而非 token 嵌入),兼容 Transformer 层内并行性;
    • 专用压缩 token:引入⟨COMP⟩token,训练模型将当前新增上下文(c(t))与历史压缩内存(Mem(t-1))的信息,压缩到⟨COMP⟩token 的 KV 对中,得到压缩特征(h(t) \in \mathbb{R}^{2 \times L \times d})(L为模型层数,d为隐藏层维度);
    • 压缩过程:(h(t) = g_{comp}(Mem(t-1), c(t))),仅需前向计算,无需递归。
  • 动态内存更新,设计可微、可并行的内存更新函数(g_{update}),适配不同场景:
    • CCM-concat:将新的 h(t) 直接连接到旧的 memory 中,memory 随时间增长。
    • CCM-merge:将新的 h(t) 与旧 memory 按加权平均合并(例如算术平均或指数移动平均),memory 保持固定大小。
  • 高效训练:并行化 + 条件 LoRA
    • 并行化训练:递归压缩过程 “展开” 为单轮并行前向计算,避免递归导致的训练耗时与梯度传播误差,训练速度比 RMT/AutoCompressor 快 7 倍;
    • 条件 LoRA:为了训练压缩模块,引入一个 conditional LoRA adapter,只在 ⟨COMP⟩ token 上作用,不修改原模型的主参数 θ,而新增一些低秩参数 ∆θ 用来学习压缩操作。这样避免 overfitting 模型在没有 context 的情况下也能“猜”输出的问题。

  推理阶段:

  • 在实际用的时候,随着新 context 的到来,不断用压缩函数更新 memory,并在生成响应时只用 memory + 当前输入,而不是整个历史 context。这样 attention 的计算成本和内存成本都大幅下降。
    arXiv
  • 在 streaming 的设置里,还结合 sliding window(最近的上下文窗口)与压缩 oldest tokens 的操作来控制 KV cache 的大小。

2.2 源码分析

  在注意力机制中通过 sum_mask 和 sum_attn_mask 实现键值对的动态合并与压缩。

# 合并压缩键值对(用于动态更新内存)
if sum_attn_mask is not None:
    sum_attn_mask = sum_attn_mask.to(key_states.dtype)
    # 计算压缩后的键值平均值
    key_comp_avg = torch.matmul(sum_attn_mask.unsqueeze(1), key_states)
    value_comp_avg = torch.matmul(sum_attn_mask.unsqueeze(1), value_states)
    # 用掩码控制原始键值与压缩键值的融合
    no_sum_mask = (1 - sum_mask).to(key_states.dtype).unsqueeze(1).unsqueeze(-1)
    key_states = no_sum_mask * key_states + key_comp_avg  # 动态更新key内存
    value_states = no_sum_mask * value_states + value_comp_avg  # 动态更新value内存

  在注意力层中,q_proj、k_proj、v_proj、o_proj 均使用 LinearMask,并在 forward 中传入 comp_mask 控制 LoRA 的条件激活:

class LinearMask(nn.Linear):
    """Linear function with compression mask as an argument. 
       The mask is used for conditional LoRA at src/peft_custom/lora.py-Linear()-forward().
    """

    def forward(self, input: Tensor, comp_mask=None) -> Tensor:
        return F.linear(input, self.weight, self.bias)


self.q_proj = LinearMask(self.hidden_size, self.num_heads * self.head_dim, bias=False)
        self.k_proj = LinearMask(self.hidden_size, self.num_heads * self.head_dim, bias=False)
        self.v_proj = LinearMask(self.hidden_size, self.num_heads * self.head_dim, bias=False)
        self.o_proj = LinearMask(self.num_heads * self.head_dim, self.hidden_size, bias=False)
        self.rotary_emb = LlamaRotaryEmbedding(self.head_dim,
                                               max_position_embeddings=self.max_position_embeddings)

3 LoCoCo: Dropping In Convolutions for Long Context Compression

论文地址:https://arxiv.org/pdf/2406.05317
代码地址:https://github.com/VITA-Group/LoCoCo

3.1 模型

  大型语言模型(LLMs)在文本生成、代码合成、问答等任务中表现优异,但处理长上下文序列时面临KV 缓存内存瓶颈:Transformer 的注意力计算需缓存键(Key)和值(Value),其大小随上下文长度线性增长,易耗尽 GPU 内存。现有方法存在明显缺陷:

  • StreamingLLM:通过 “注意力 sink” 和局部窗口限制 receptive field,会丢失中间上下文(“lost in the middle”),无法利用全序列信息;
  • H₂O:基于注意力分数启发式丢弃 KV 对,难以扩展到训练上下文长度以外的序列;
  • LongLoRA:需修改预训练 LLM 架构,且在小上下文场景下性能受损;
  • 注意力近似方法(如稀疏注意力、低秩近似):无法缓解推理阶段的 KV 缓存爆炸问题。

  LoCoCo 的核心目标是用固定大小 KV 缓存实现长上下文高效处理,兼顾推理与微调阶段,且支持 “即插即用”(无需修改原有 LLM 架构),核心设计包括三部分:

  • 数据驱动的自适应 KV 融合:区别于传统 “启发式丢弃 KV 对”,LoCoCo 通过1D 卷积核动态计算混合权重,融合历史 KV 缓存与新输入 token,最小化上下文信息丢失,保证注意力建模准确性。
  • 分段注意力与卷积压缩:
    • 分段注意力(Segment-Level Attention):将长序列划分为长度为 B 的段,逐段处理:
      • 每段生成当前的 Q、K、V;
      • 注意力计算时结合历史 KV 缓存与当前段 KV;
      • 若累计 KV 长度超过固定缓存大小 M,触发卷积压缩。
    • 卷积 token 压缩器,通过 1D 卷积层生成融合权重:
      • 输入:历史 KV 缓存(维度 d×M)与当前段 KV(维度 d×B)拼接,共 2d×(M+B) 维度;
      • 卷积层输出 M×(M+B) 维度的权重矩阵 W,经归一化后得到历史 KV 的权重(\tilde{w}{i,j})和当前 KV 的权重(w{i,j});
      • 融合更新:(\tilde{k}i = \sum_j w{i,j}k_j + \sum_j \tilde{w}_{i,j}\tilde{k}_j)(V 的更新同理),最终缓存大小保持为 M。
  • 即插即用集成:
    • 推理阶段:在预训练 LLM 的注意力层顶部插入卷积压缩器,仅用少量校准数据微调压缩器,预训练权重不变,可随时移除压缩器切换回全序列模式;
    • 微调阶段:结合位置插值(positional interpolation)扩展上下文,插入卷积压缩器并添加 LoRA 适配器,仅微调压缩器、LoRA 及嵌入 / 归一化层,无需全量微调。

3.2 源码分析

  通过卷积层动态学习融合权重,结合残差权重实现自适应融合。

  • 卷积压缩器定义:
layers = []
hidden_size, in_size = self.mem_compress * args.expand, dim_kv  # dim_kv = 2*head_dim(K+V)
for i in range(args.n_convlayer):
    if i != 0:
        in_size = hidden_size
    if i == args.n_convlayer-1:
        hidden_size = self.mem_compress  # 最终输出mem_compress个权重
    # 1D卷积层(论文中的核心组件,用于学习融合权重)
    layers.append(nn.Conv1d(
        in_channels=in_size, 
        out_channels=hidden_size, 
        kernel_size=args.kernel_size, 
        padding=int((args.kernel_size-1)//2)  # 保持序列长度
    ))
    if args.hidden_act is not None:
        layers.append(ACT2FN[args.hidden_act])  # 非线性激活(如ReLU)
self.layers = nn.Sequential(*layers)  # 卷积网络用于生成融合权重
  • 自适应权重融合(结合卷积权重与残差权重):
# 卷积网络生成权重(数据驱动部分)
x = torch.cat([non_heavy_hitter_key_states, non_heavy_hitter_value_states], dim=-1)  # 拼接K和V(2d通道)
x = rearrange(x, 'b h s d -> (b h) d s', b=bsz, h=n_head)  # 适配Conv1d输入格式
x = self.layers(x)  # 卷积计算权重
x = nn.functional.softmax(x, dim=-1)  # 归一化(论文公式7)
weight = rearrange(x, '(b h) m s -> b h m s', b=bsz)  # 恢复维度

# 融合残差权重(确保重要信息不丢失)
residual_weight = self.make_residual_weight(non_heavy_hitter_hh_scores)  # 基于注意力分数的残差权重
weight = residual_weight * (1-self.normalizer) + weight * self.normalizer  # 自适应融合(论文未明确但代码新增的稳定机制)

  模块化设计memory_saver,通过独立接口处理 KV 缓存,不侵入原模型结构。
  通过固定缓存大小、划分重令牌与非重令牌,实现低内存开销的长序列处理。

  • 固定缓存大小控制
self.mem_size = args.mem_size  # 总缓存大小(固定值,如512)
self.mem_compress = int(args.mem_size * (1-args.hh_keep_rate))  # 可压缩部分大小
self.keep_hh_size = self.mem_size - self.mem_compress  # 保留的重令牌大小
  • 重令牌保留 + 非重令牌压缩(降低计算开销)
def partition_past_key_values(self, past_key_states, past_value_states, hh_scores):
    # 1. 划分重令牌(heavy hitter):保留注意力分数高的token
    _, hh_idxs = torch.topk(hh_scores[..., :-self.local_len], self.keep_hh_size-self.local_len, dim=-1)
    mask_bottom = zeros.scatter(-1, hh_idxs, True)  # 重令牌掩码
    if self.local_len > 0:
        mask_bottom[:, :, -self.local_len:] = True  # 额外保留最近的local_len个token(局部性保障)
    
    # 2. 分离重令牌KV和非重令牌KV
    heavy_hitter_key_states = torch.masked_select(past_key_states, mask_bottom).reshape(...)  # 直接保留,不压缩
    non_heavy_hitter_key_states = torch.masked_select(past_key_states, ~mask_bottom).reshape(...)  # 需要压缩
    return (heavy_hitter_key_states, ...), (non_heavy_hitter_key_states, ...)

4 MemoryBank: Enhancing Large Language Models with Long-Term Memory

论文地址:https://arxiv.org/abs/2305.10250
代码地址:https://github.com/zhongwanjun/MemoryBank-SiliconFriend/blob/main/README_cn.md

4.1 MemoryBank

MemoryBank 是为 LLMs 设计的新型长期记忆机制,围绕三大核心支柱构建,能实现记忆存储、检索与更新,并绘制用户画像,让 LLMs 可回忆历史交互、持续深化语境理解、依据过往互动适应用户性格,提升长期交互场景下的性能。

  • 记忆存储(Memory Storage):作为 Memory 的 “仓库”,以细致有序的方式存储信息,构建动态多层记忆体系。

    • 深度存储:按时间顺序记录多轮对话,每条对话附带时间戳,既助力精准记忆检索,又为后续记忆更新提供详细对话历史索引。
    • 分层事件总结:模仿人类记忆特点,将冗长对话浓缩为每日事件摘要,再进一步整合为全局摘要,形成分层记忆结构,便于快速把握过往交互与重要事件全貌。
    • 动态性格理解:持续通过长期交互评估并更新对用户性格的认知,生成每日性格洞察,再汇总为对用户性格的全局理解,使 AI 伴侣能依据用户独特特质调整响应。
  • 记忆检索(Memory Retrieval):基于记忆存储,类似知识检索任务,采用双塔密集检索模型(类似 Dense Passage Retrieval),将每轮对话和事件摘要视为记忆片段,用编码器模型预编码为向量表示,通过 FAISS 索引实现高效检索;同时将当前对话语境编码为查询向量,在记忆库中搜索最相关记忆,且编码器模型可灵活替换。

  • 记忆更新机制(Memory Updating Mechanism):受艾宾浩斯遗忘曲线理论启发,模拟人类认知过程,让 AI 能依据时间推移记忆、选择性遗忘和强化记忆,使交互更自然。

    • 遗忘规律:记忆保留率随时间下降,初始阶段遗忘速度快,之后减缓;定期回顾可重置遗忘曲线,提升记忆保留率。
    • 数学模型:采用指数衰减模型(R = e^{-\frac{t}{S}})(R 为记忆保留率,t 为时间,S 为记忆强度),S 初始值为 1,记忆片段被回忆时 S 加 1 且 t 重置为 0,降低遗忘概率。

从上下文压缩的角度看 MemoryBank:
传统上下文压缩的本质目标,是在 LLMs 固定的上下文窗口内,通过去除冗余信息、保留核心语义(如关键实体、情感倾向、任务指令等),最大化信息密度,从而支持更长序列的交互或任务处理。而 MemoryBank 的设计初衷,正是解决 LLMs 因缺乏长期记忆导致的 “上下文断裂” 问题 —— 在持续交互(如个人陪伴、心理辅导)中,模型无法记住过往对话中的用户偏好、经历细节等关键信息,需反复重复上下文,本质上也是对 “有限上下文资源的低效利用”。

  • 信息处理维度:“筛选存储” 而非 “全量压缩”
    传统上下文压缩通常对当前对话序列的 “全量信息” 进行精简,目标是保留 “当前窗口内所有信息的核心语义”;而 MemoryBank 基于 “记忆重要性” 进行筛选 —— 仅将对用户理解(如性格、偏好)、交互连贯性(如过往承诺、历史话题)有价值的信息存入记忆库,而非对所有对话内容压缩存储。这种 “选择性存储” 本质是 “先筛选再保留”,比 “全量压缩” 更聚焦长期价值信息,减少了无效压缩带来的语义损耗。

  • 时间维度:“长期动态管理” 而非 “短期静态压缩”
    传统上下文压缩的效果局限于 “当前对话轮次或短期交互”,压缩后的信息随上下文窗口滚动而被覆盖,无法跨长时间尺度复用;而 MemoryBank 引入了基于 “艾宾浩斯遗忘曲线” 的记忆更新机制 —— 根据时间流逝和记忆重要性,对存储的信息进行 “强化(重要且近期的记忆)” 或 “遗忘(无关或远期的冗余记忆)”,实现了信息的 “长期存活与动态优化”,相当于为 LLMs 构建了 “可进化的外部记忆空间”,而非 “一次性的压缩缓存”。

  • 功能定位:“辅助理解用户” 而非 “辅助当前任务”
    传统上下文压缩的核心功能是 “辅助模型完成当前任务”(如基于压缩的历史对话生成连贯回复、执行复杂指令),聚焦 “任务层面的上下文连贯性”;而 MemoryBank 的核心功能是 “辅助模型理解用户”—— 通过持续合成过往交互中的用户信息(如性格、经历、情感倾向),让模型在长期陪伴中逐渐 “适配用户”,例如在心理辅导场景中,模型可通过记忆库回顾用户过往的情绪触发点,生成更具同理心的回复。这种定位超越了 “任务导向的压缩”,延伸到 “用户导向的长期认知”。

相关代码在之前的文章中分析过,这里不再赘述

5 Mem0: Building Production-Ready AI Agents with Scalable Long-Term Memory

论文地址:Mem0: Building Production-Ready AI Agents with Scalable Long-Term Memory
代码地址:Mem0

5.1 Mem0 的上下文压缩机制:两阶段 pipeline 实现 “动态提炼 + 智能更新”

Mem0 的压缩核心是 “提取 - 更新” 两阶段架构,通过 LLM 驱动的语义分析,实现对对话信息的 “精细化筛选” 与 “增量式优化”,避免传统压缩方法(如固定长度截断、简单摘要)的机械性缺陷。

  • 提取阶段:基于双上下文的 “高价值信息筛选”
    压缩的第一步是从新对话中精准定位 “值得保留的记忆”,而非无差别存储所有内容。Mem0 通过双上下文融合构建提取 prompt,确保压缩信息的 “上下文关联性”:

    • 全局上下文(对话摘要 S):由异步摘要生成模块定期更新,提炼整个对话的主题框架(如 “用户与助手讨论旅行计划 + dietary 偏好”),避免提取孤立信息;
    • 局部上下文(最近 m 条消息):默认取前 10 条消息(m=10),捕捉未被摘要整合的细节(如 “用户提到对坚果不过敏”),补充全局摘要的颗粒度不足;
    • 新对话对(mₜ₋₁, mₜ):当前用户 - 助手交互单元,是提取新记忆的直接来源。
      三者融合形成 prompt P = (S, {mₜ₋ₘ,…,mₜ₋₂}, mₜ₋₁, mₜ),通过 LLM(如 GPT-4o-mini)执行提取函数 φ§,输出候选记忆集合 Ω(如 “用户偏好素食,避免乳制品”“计划 7 月去旧金山旅行”)。这一过程本质是 “语义级压缩”:将原始对话文本(可能包含冗余语句)转化为结构化、简洁的事实陈述,token 量仅为原始对话的 1/15-1/20。
  • 更新阶段:基于冲突检测的 “压缩记忆优化”
    传统压缩方法的痛点是 “静态存储”—— 一旦压缩信息存入,无法应对后续对话中的更新、冲突或补充(如用户后续提到 “现在可接受少量乳制品”)。Mem0 通过四操作记忆管理机制,实现压缩记忆的动态优化,确保压缩信息的 “时效性” 与 “一致性”:

    • 语义检索:对每个候选记忆 ωᵢ,通过向量数据库检索 top 10(s=10)语义相似的已有记忆;
    • 操作判断:LLM 基于候选记忆与已有记忆的关系,选择四种操作之一:
      • ADD:无相似记忆时,新增压缩记忆(如首次提取 “用户素食” 偏好);
      • UPDATE:候选记忆补充已有信息时,合并压缩(如从 “用户素食” 更新为 “用户素食,可接受蛋制品”);
      • DELETE:候选记忆与已有信息冲突时,删除旧压缩记忆(如用户后续表示 “不再素食”);
      • NOOP:候选记忆重复或无关时,不更新(避免冗余存储)。

Mem0 这一阶段的压缩价值在于:通过 “增量更新” 而非 “全量重存”,维持记忆库的紧凑性 —— 实验显示,Mem0 的记忆库 token 量长期稳定在 7k-14k(Mem0g 因图结构略高),远低于 Zep 等平台 600k+ tokens 的冗余存储,同时避免因信息冲突导致的 “记忆混乱”(如传统 RAG 可能同时保留 “用户素食” 与 “用户非素食” 的矛盾片段)。

5.2 Mem0g 的图增强压缩:从 “线性事实” 到 “关系结构化”

Mem0 的压缩聚焦于 “单条事实的简洁表达”,而 Mem0g 通过图结构记忆表示,实现 “事实间关系的压缩编码”,进一步提升多跳推理、temporal 推理场景下的压缩效率。其核心是将压缩记忆从 “线性文本” 转化为 “有向标记图 G=(V,E,L)”,本质是 “关系级压缩”

  • 图结构的压缩逻辑

    • 节点 V(实体):压缩为 “实体类型 + 语义嵌入 + 时间戳” 三要素(如 “Alice - 人物 - 2024.5.1”“旧金山 - 地点 - 2024.5.1”),避免存储实体的冗余描述;
    • 边 E(关系):压缩为三元组(vₛ, r, v_d)(如 “Alice-prefers - 素食”“Alice-plans_to_visit - 旧金山”),用结构化标签替代原始对话中的自然语言描述(如将 “我打算下个月和朋友一起去旧金山旅行,因为我喜欢那里的气候” 压缩为 “Alice-plans_to_visit - 旧金山(时间:7 月)”);
    • 标签 L(语义类型):为节点和边添加类型标注(如 “人物”“地点”“偏好关系”“计划关系”),提升后续检索的精准度。
  • 图压缩的优势:面向复杂推理的高效检索
    传统线性压缩记忆在多跳推理(如 “用户计划去旧金山,旧金山 7 月气候如何?”)时,需逐一检索 “用户计划”“旧金山气候” 两条独立记忆,再手动建立关联;而 Mem0g 的图结构将 “实体 - 关系” 直接压缩编码,检索时通过 “实体中心遍历”(从 “Alice” 节点出发,沿 “plans_to_visit” 边找到 “旧金山”,再沿 “has_climate” 边获取气候信息)或 “语义三元组匹配”(直接匹配 “旧金山 - has_climate - 夏季温和” 三元组),大幅减少检索步骤与 token 消耗。

6 A-Mem: Agentic Memory for LLM Agents

论文地址:A-Mem: Agentic Memory for LLM Agents
代码地址:https://github.com/agiresearch/A-mem

A-MEM 摒弃了传统系统“先存储后截断”的被动 Context 压缩模式,通过结构化笔记构建、动态链接生成、记忆进化三大模块,实现“主动筛选-关联保留-动态优化”的全流程 Context 压缩管理,核心逻辑如下:

6.1 结构化笔记构建:Context 的“语义级压缩”基础

传统 Context 压缩多停留在“文本截断”(如将长对话按 token 拆分),而 A-MEM 首先通过LLM 驱动的结构化笔记,对原始 Context 进行“语义提炼”,从源头上提升信息密度——这是其 Context 压缩的核心前提。

每个记忆笔记( m i m_i mi)包含 7 个核心属性,其中直接服务于 Context 压缩的关键组件为:

  • 原始内容( c i c_i ci:保留原始交互文本,但仅作为“底层数据”,不直接进入 LLM 上下文窗口;
  • LLM 生成组件:由 LLM 分析 c i c_i ci与时间戳( t i t_i ti)生成,是 Context 压缩的核心载体:
    • 关键词( K i K_i Ki:提取 3-5 个核心概念(如“photography”“scenery”“hobby”),压缩 Context 的“核心语义标签”;
    • 上下文描述( X i X_i Xi:用 1 句话概括 Context 的主题、关键观点与用途(如“Dave 在 2023 年 10 月提及新爱好摄影,分享拍摄当地风景的体验”),替代冗长原始文本;
    • 标签( G i G_i Gi:按“领域+类型+场景”分类(如“hobby”“photography”“personal conversation”),为后续精准检索与压缩提供维度;
  • 嵌入向量( e i e_i ei:将 c i c_i ci K i K_i Ki G i G_i Gi X i X_i Xi拼接后编码为向量,用于快速计算 Context 间相似度,支撑后续压缩筛选。

6.2 动态链接生成:压缩后 Context 的“关联保留”关键

Context 压缩的最大风险是“丢失关联信息”——例如,若仅保留“Dave 喜欢摄影”的孤立信息,而忽略“Calvin 喜欢音乐创作”的关联 Context,Agent 将无法回答“Dave 和 Calvin 的爱好有何不同”这类跨记忆问题。A-MEM 通过动态链接生成,在压缩 Context 的同时,主动构建并保留记忆间的关联,解决“压缩即断链”的痛点。

链接生成的核心流程(服务于 Context 压缩):

  1. 相似性筛选(初步压缩候选集):新笔记 m n m_n mn生成后,通过嵌入向量 e n e_n en与历史笔记的 e j e_j ej计算余弦相似度,筛选出 top-k(如 k=10)最相关的历史 Context( M n e a r n \mathcal{M}_{near}^n Mnearn),避免全量历史 Context 进入后续处理,实现“候选集压缩”;
  2. LLM 驱动关联判断(精准保留关键链接):LLM 分析 m n m_n mn M n e a r n \mathcal{M}_{near}^n Mnearn的关键词、上下文描述,判断是否建立链接(如“Dave 的摄影爱好”与“Calvin 的音乐创作”均属于“个人爱好”,建立“同类兴趣”链接),并将链接关系存入 L i L_i Li(链接集合);
  3. 多“盒子”关联(跨场景关联压缩):借鉴 Zettelkasten 的“盒子”概念,单条记忆可同时属于多个“语义盒子”(如“Dave 的摄影”既属于“hobby”盒子,也属于“2023 年 10 月事件”盒子),实现“一 Context 多关联”,避免关联信息在压缩中被单一分类丢弃。

6.3 记忆进化:压缩后 Context 的“动态优化”

传统 Context 压缩是“一次性操作”——一旦截断或筛选完成,Context 内容固定不变,无法适配后续任务需求变化(如早期对话中“模糊的爱好描述”,在后续明确后无法更新)。A-MEM 的记忆进化机制,让压缩后的 Context 能够“随新信息动态迭代”,实现“压缩后仍可优化信息密度”。

记忆进化的核心流程(服务于 Context 压缩):

  1. 触发条件:新笔记 m n m_n mn与历史笔记 m j m_j mj建立链接后,LLM 分析 m n m_n mn的新 Context 是否能补充/修正 m j m_j mj的信息;
  2. 进化操作
    • 补充属性:若 m j m_j mj原关键词仅为“photography”,而 m n m_n mn提到“Dave 用单反相机拍摄”,则将 m j m_j mj的关键词更新为“photography”“SLR camera”,提升 Context 的精准度;
    • 修正描述:若 m j m_j mj原上下文描述为“Dave 喜欢摄影”,而 m n m_n mn明确“Dave 在 2023 年 10 月开始摄影”,则将 m j m_j mj X i X_i Xi更新为“Dave 在 2023 年 10 月开始摄影,使用单反拍摄当地风景”,补充关键时间信息;
    • 调整链接:若 m n m_n mn提到“Dave 的摄影灵感来自 Calvin 的音乐”,则新增 m j m_j mj与“Calvin 音乐”笔记的链接,优化关联维度;
  3. 替代更新:进化后的 m j ∗ m_j^* mj替代原 m j m_j mj存入记忆库,确保压缩后的 Context 始终保持“最新、最准”,避免冗余的旧信息占用窗口。
Logo

更多推荐