☰
如何读懂 LycheeMem:动作感知四级语义检索流水线源码级拆解指南
2026/10/15 17:23:38 网站建设 项目流程

【免费下载链接】LycheeMem

Lightweight Long-Term Memory for LLM Agents.

项目地址:https://gitcode.com/gh_mirrors/ly/LycheeMem
点击查看免费下载

LycheeMem 是面向 LLM Agent 的轻量级长期记忆框架(Lightweight Long-Term Memory for LLM Agents)。它的检索核心不是一句"向量相似度 TopK",而是一条动作感知(Action-aware)的四级语义检索流水线:先用 LLM 理解"用户当下想做什么",再做多通道证据召回、策略加权与跨路由融合,最终把最相关的记忆证据塞进上下文。本文带你从源码层面把这条流水线完整走一遍。

1. 先认识主角:四级检索流水线总装图

整条流水线的总装入口是 CompactSemanticEngine,它通过 Mixin 组合了四个职责模块:

  • 规划RetrievalPlanningMixin:把 LLM 生成的 JSON 计划规范化为SearchPlan
  • 策略RetrievalStrategyPolicyMixin:按问题类型产出检索参数包
  • 路由召回RouteRetrievalMixin:多通道召回 + 窗口扩展 + 重排
  • 融合选优RetrievalFusionMixin / RetrievalSelectionMixin:RRF 融合与覆盖度选择

四级结构一句话版:

级别名称核心代码干什么
Level 1动作感知查询规划search_coordinator.py构造 ActionState + 生成 SearchPlan(证据路由)
Level 2多通道证据召回recall.py时间过滤、证据节点 ANN、记录 ANN、原始轮次 ANN
Level 3动作感知加权 + Rerankstrategy_policy.py按问题类型打角色/类型奖励、交叉编码器精排
Level 4路由融合与覆盖度选优fusion.pyRRF 融合、MMR 多样性选择、episode 预算控制

2. Level 1:动作感知查询规划——先懂"想做什么",再去找

普通 RAG 只带着"问题"出发;LycheeMem 的检索先带着动作状态出发。每次请求,SearchCoordinator 会做两件事:

① 构造 ActionState—— 在 _build_action_state 中,协调器把"当前子目标、试探性动作、上一个工具名及其结果、可用工具、失败信号、token 预算"打包进 ActionState。这意味着检索系统知道:Agent 刚调过什么工具、卡在哪一步、还缺什么条件——这是"动作感知"的由来。

② 生成 SearchPlan—— _build_retrieval_plan 把USER_QUERY + RECENT_CONTEXT + ACTION_STATE一起喂给 LLM 规划器(系统提示见 RETRIEVAL_PLANNING_SYSTEM),产出一份结构化检索计划。计划里最关键的是evidence_routes(证据路由):一个复杂问题会被拆成多条独立证据需求,每条路由有自己的检索目标(evidence_goal)、查询变体、约束和时间过滤(数据模型见 EvidenceRoute)。没有路由时,_normalize_plan_for_query 会自动兜底生成单路由。

📌 一句话:Level 1 把"问题"翻译成"一组带目标的检索任务",并让任务看得见 Agent 的动作上下文。

3. Level 2:多通道证据召回——四路并进,互为备份

进入 search() 后,_search_fielded_evidence 对每条路由执行四路召回(见 _search_single_evidence_route):

通道 1:时间过滤召回。"2023 年 5 月之前的事"这类问题不靠语义猜,而靠结构化证据节点精确匹配。_recall_records_from_temporal_filter 扫描day:/month:粒度的时间节点,按区间重叠度打分(日粒度 0.42 > 区间 0.34 > 月粒度 0.28)。

通道 2:证据节点 ANN。_recall_records_from_evidence_nodes_multi 用一次向量查询同时召回 entity / tag / entity_tag / event_frame 四类结构化节点,再按类型加权(event_frame 权重 0.42 最高,见 _evidence_node_weight),把节点扩展回它们关联的 MemoryRecord。一次 ANN 干四个通道的活,注释里明确写了这是为了省掉三次重复查询。

通道 3:记录向量直查。_direct_record_search 直接对 MemoryRecord 的normalized_vector做 ANN。首次命中的候选得分为0.30 + 0.30 × 检索得分,同一记录被多个查询变体再次命中还会加 0.20 基础分(routes.py L278-L283)——"多渠道都提到它"本身就是强信号。

通道 4:原始对话轮次。_search_raw_turns_direct 直接检索会话原文轮次,得分公式见 _raw_turn_field_score:基础分乘以策略系数(默认 0.72),assistant 轮次和 user 轮次各按策略加角色奖励。

📌 一句话:Level 2 不押注单一向量检索,而是让时间、实体、记录、原文四路证据互相印证。

4. Level 3:动作感知加权与 Rerank——策略按问题类型换档

召回完成后,_resolve_retrieval_strategy 根据 LLM 判定的question_type换一档检索参数(策略对象定义在 RetrievalStrategy):

问题类型典型场景策略倾向
prior_assistant_response"你上次怎么回答我?"轮次召回量 ×3、assistant 角色奖励 0.18、上下文窗口扩到 4 轮
personalized_advice"按我的情况给建议"扩大证据预算、给 preference/constraint 类记录加 0.05 奖励
temporal/comparison带时间、对比类问题时间窗口 2 轮、有 temporal 元数据的记录 +0.04
aggregate统计汇总类问题证据节点召回 ×1.55,锚点上限提到 40

加权动作在 _apply_strategy_candidate_boosts 与 _record_strategy_bonus 中执行;时间匹配则只用来"加分"而绝不删候选(_apply_temporal_boost)——注释里点明了设计哲学:时间证据不足以当门槛,只配当信号。

此外还有两个动作感知的关键扩展(expansion.py):

  • 助手回答窗口:对prior_assistant_response类问题,_build_assistant_answer_windows 会回溯到原始会话,把"当时的用户提问 + 助手回答"整段取回;
  • 同源窗口物化:_materialize_source_windows_from_anchors 把语义锚点还原成原始对话证据窗口——压缩后的记忆只配当指针,最终证据要回到原文。

最后,若启用了 reranker(本地 Cross-Encoder 或 HTTP 远程),_rerank_candidate_dicts 会用交叉编码器对候选池精排;选池逻辑 _select_rerank_pool 特意按"来源 × 通道"分桶轮转,防止某一路高分通道垄断重排池。

5. Level 4:RRF 路由融合 + 覆盖度选优——好钢用在刀刃上

多条路由各自排好序后,_fuse_route_results 接手:

  1. 每路由配额:route_quota = top_k / 路由数(1~4),先保证每条证据需求都有代表进入结果;
  2. RRF 融合分:final = 0.82 × 单路由最佳分 + 0.18 × 归一化 RRF 分,RRF 权重用经典的1/(60+rank);
  3. MMR 覆盖度选择:_coverage_select_scored 按0.75×相关性 − 0.25×与已选候选的最大相似度迭代挑选,相似度由会话、实体、查询、轮次、文本五个信号加权计算(_signature_similarity),避免结果全是同一会话的复读;
  4. episode 预算控制:_limit_episode_candidates 限制原始对话轮次的最终占比(由策略的episode_budget_ratio决定),原文只有在足够强时才配占位。

最终产出的SemanticSearchResult携带格式化后的上下文、溯源(provenance)和检索计划;开启LYCHEE_SEMANTIC_TRACE后,每一级的候选池、耗时、分数拆解都会写入 trace,方便调试整条流水线(routes.py L113-L148)。

6. 上手观察与源码导航

想动手看效果?装好服务后,最直接的方式是通过 MCP 工具lychee_memory_smart_search(compact模式)发起一次检索,请求示例见 README.md;API 侧的入口路由在 memory.py 与 chat.py。

🔎 调试小贴士:

  • 设置环境变量LYCHEE_SEMANTIC_TRACE=1输出逐级检索 trace;LYCHEE_SEMANTIC_TIMING=1输出耗时日志(routes.py L512-L533);
  • 在 CompactSemanticEngine 初始化时开启reranker_enabled=True,可启用 Cross-Encoder 精排;
  • 想看规划器如何拆分证据路由,直接读 RETRIEVAL_PLANNING_SYSTEM 提示词与 SearchPlan 结构。

🧭源码导航清单:

  • 总装引擎:engine.py
  • 检索协调器(动作状态 + 规划):search_coordinator.py
  • 四级流水线的分治实现:src/memory/semantic/retrieval/(routes / recall / strategy / expansion / selection / fusion)
  • 记忆记录与数据模型:models.py
  • 管道端到端示例:api_pipeline_demo.py

7. 总结:四级流水线的设计哲学

回顾一下这条动作感知四级语义检索流水线的精髓:

  1. 规划先行:让 LLM 带着 Agent 动作状态拆解证据需求,而不是裸奔一个 query;
  2. 多通道印证:时间、证据节点、记录向量、原始轮次四路召回互相补位;
  3. 策略换档:按问题类型动态调整召回量、角色奖励与窗口大小;
  4. 融合与多样性:RRF 保证路由覆盖,MMR 保证结果不"复读",episode 预算保证原文只在够强时登场。

对新手而言,读懂这条流水线,也就读懂了 LycheeMem 相比"单向量 TopK"式 RAG 的核心差异:记忆检索是服务 Agent 行动的,而不只是回答问题的。

【免费下载链接】LycheeMem

Lightweight Long-Term Memory for LLM Agents.

项目地址:https://gitcode.com/gh_mirrors/ly/LycheeMem
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询