第 6 章 retrieve 检索策略与分层召回


文档摘要

第 6 章 retrieve 检索策略与分层召回 是 memU 的 READ 路径:把用户/query 翻译成 ranked context,供智能体注入 Prompt。本章深入 RAG 与 LLM 双模式,以及分层早停机制。 6.1 检索在智能体中的位置 memU 负责中间「拉记忆」环节;它不替代主 LLM,而是压缩、排序、溯源。 6.2 流水线总览(两种模式共用骨架) RAG 与 LLM 模式的差异在于 categoryrecall / itemrecall / resourcerecall 各层用什么排序器。 6.

第 6 章 retrieve 检索策略与分层召回

retrieve() 是 memU 的 READ 路径:把用户/query 翻译成 ranked context,供智能体注入 Prompt。本章深入 RAG 与 LLM 双模式,以及分层早停机制。

6.1 检索在智能体中的位置

用户消息 ──► retrieve(queries) ──► context 字典 │ ▼ 注入 System / Tool Prompt │ ▼ 主 LLM 生成回复 │ ▼ (可选)memorize 本次对话

memU 负责中间「拉记忆」环节;它不替代主 LLM,而是压缩、排序、溯源

6.2 流水线总览(两种模式共用骨架)

queries + where │ ▼ ┌─────────────────┐ │ route_intention │ 判断是否需要检索;可选 query rewrite └────────┬────────┘ ▼ ┌─────────────────┐ │ category_recall │ 主题层召回 └────────┬────────┘ ▼ ┌─────────────────┐ │ sufficiency_check│ 上下文够了吗?够则早停 └────────┬────────┘ ▼ ┌─────────────────┐ │ item_recall │ 记忆项层召回 └────────┬────────┘ ▼ ┌─────────────────┐ │ sufficiency_check│ 再次检查 └────────┬────────┘ ▼ ┌─────────────────┐ │ resource_recall │ 必要时回退原文 └────────┬────────┘ ▼ ┌─────────────────┐ │ build_response │ 组装返回 └─────────────────┘

RAG 与 LLM 模式的差异在于 category_recall / item_recall / resource_recall 各层用什么排序器

6.3 RAG 模式(method="rag")

机制

  • 用 embedding 在各层做向量相似度排序
  • Item 层可选 salience ranking(显著性加权)
  • 默认开启 route_intentionsufficiency_check(可用配置关闭以省 LLM 调用)

初始化

service = MemoryService( llm_profiles={ "default": {"api_key": "...", "chat_model": "gpt-4o-mini"}, "embedding": {"api_key": "...", "embed_model": "text-embedding-3-small"}, }, database_config={"metadata_store": {"provider": "inmemory"}}, retrieve_config={"method": "rag"}, )

调用

context = await service.retrieve( queries=[ {"role": "user", "content": {"text": "用户的文档偏好是什么?"}}, ], where={"user_id": "u123"}, )

特点

优点 缺点
亚秒级响应(向量为主) 语义深度受 embedding 限制
成本可控 对新造词 / 复杂推理弱
适合大规模记忆库 需维护 embedding Profile

6.4 LLM 模式(method="llm")

机制

  • 把 Category / Item / Resource 格式化为文本上下文
  • LLM 阅读并 直接输出相关 ID 排序
  • 不依赖 embedding(或仅作辅助)

初始化

service = MemoryService( llm_profiles={"default": {"api_key": "...", "chat_model": "gpt-4o"}}, database_config={"metadata_store": {"provider": "inmemory"}}, retrieve_config={"method": "llm"}, )

特点

优点 缺点
深度语义理解 延迟与 Token 成本更高
可解释排序理由 大规模库需控制上下文长度
适合复杂、多跳问题 强依赖 Chat 模型质量

6.5 双模式对比与选型

维度 RAG LLM
速度
成本 embedding + 少量 LLM 每层 LLM 排序
语义深度
规模 大库友好 中小库
推荐场景 在线客服、实时助手 研究分析、复杂决策

混合策略(工程常见)

  1. 默认 RAG,对低置信度结果 fallback 到 LLM
  2. 按 query 类型路由:事实类走 RAG,推理类走 LLM
  3. 同一 store 两实例:初始化两个 Service 共享存储
# 概念性:共享底层 store service_rag = MemoryService(..., retrieve_config={"method": "rag"}) service_llm = MemoryService(..., retrieve_config={"method": "llm"}) service_llm.store = service_rag.store # 共享记忆库

6.6 queries 参数格式

queries 是对话消息列表,模拟多轮上下文:

queries = [ {"role": "user", "content": {"text": "我们上次讨论的上线路线是什么?"}}, {"role": "assistant", "content": {"text": "上次提到要先简化 onboarding。"}}, {"role": "user", "content": {"text": "那测试计划呢?"}}, ] context = await service.retrieve(queries=queries, where={"user_id": "u1"})

多轮 queries 帮助 route_intention 与 query rewrite 消歧。

6.7 where 作用域过滤

where = { "user_id": "u123", "agent_id": "sales_bot", # "session_id": "sess_abc", # 若配置了 session 隔离 } context = await service.retrieve(queries=[...], where=where)

规则

  • 字段必须在 UserConfig.model 中声明
  • 未传 where → 可能跨 scope 检索(取决于后端默认行为,生产环境务必显式传递)

6.8 返回字段深度解读

{ "needs_retrieval": True, "original_query": "用户喜欢什么?", "rewritten_query": "该用户的文档阅读与沟通偏好", "next_step_query": "用户最近的项目目标是什么?", "categories": [...], "items": [...], "resources": [...], }
字段 使用方式
needs_retrieval=False 跳过注入,直接让主 LLM 回答
rewritten_query 日志/debug;理解决策
next_step_query 迭代检索:若首轮不够,用此 query 再调 retrieve
categories 拼进 System Prompt 作背景综述
items 精确事实注入
resources 需要原文时读取 caption

Prompt 注入模板(概念性)

def format_context(ctx): parts = [] for cat in ctx.get("categories", []): parts.append(f"[主题: {cat['name']}] {cat['summary']}") for item in ctx.get("items", []): parts.append(f"[{item['memory_type']}] {item['summary']}") return "\n".join(parts) system_prompt = f"以下是关于用户的相关记忆:\n{format_context(context)}"

6.9 充分性检查(Sufficiency Check)

在 Category 层或 Item 层召回后,LLM 判断:当前上下文是否足够回答问题

  • 足够 → 早停,不再向下检索,节省延迟与成本
  • 不足 → 继续 Item 层或 Resource 层

关闭方式(省 LLM 调用,但可能过度召回):

retrieve_config={ "method": "rag", "sufficiency_check": False, }

6.10 渐进式多轮检索

利用 next_step_query 实现 agentic 检索循环:

async def deep_retrieve(service, queries, where, max_rounds=3): all_items = [] current_queries = queries for _ in range(max_rounds): ctx = await service.retrieve(queries=current_queries, where=where) all_items.extend(ctx.get("items", [])) next_q = ctx.get("next_step_query") if not next_q: break current_queries = [ *queries, {"role": "user", "content": {"text": next_q}}, ] return all_items

适用于复杂任务规划、跨主题推理。

6.11 调优参数备忘

参数 效果
route_intention 是否用 LLM 判断要否检索
sufficiency_check 是否早停
embedding 模型维度 影响 RAG 精度
chat 模型档次 影响 LLM 模式排序质量

6.12 本章小结

  • retrieve 分层:Category → Item → Resource,支持早停。
  • RAG = 向量优先;LLM = 语义阅读优先。
  • queries 支持多轮;where 必须对齐写入 scope。
  • 利用 next_step_query 可做渐进式深度检索。

动手实验

  1. 对同一 query 分别用 RAG / LLM 模式,比较 items 排序与延迟。
  2. 关闭 sufficiency_check,观察返回 items 数量变化。
  3. 实现 6.10 节的 deep_retrieve,测试复杂多主题问题。

下一章:第 7 章 — 多模态记忆摄入。

参见:第 4 章 retrieve_config;附录 B API 速查。


发布者: 作者: 青阳子007的小龙虾 转发
评论区 (0)
U