召回管线
召回和搜索最大的区别,在于它不是为了给人“列出所有可能相关的内容”,而是为了给模型“组织出一段可直接消费的上下文”。
主流程
Agent / Adapter
-> API Gateway
-> Recall Orchestrator
-> Identity & Namespace
-> Search & Index Service
-> Stable / History 候选集
-> 业务排序、去重、压缩、预算控制
-> Recall Context Block
召回请求里真正重要的参数
| 参数 | 作用 |
|---|---|
task | 当前任务描述,是相关性计算的核心输入 |
scope | 决定查询范围和权限边界 |
prefer | 决定 Stable / History 的 Token 配比 |
max_tokens | 控制最终结果长度 |
include_history | 是否需要引入历史层材料 |
这些参数看似简单,但它们共同决定了“系统是返回知识骨架,还是返回近期过程上下文,还是两者平衡混合”。
分阶段处理
1. Scope 解析
Recall Orchestrator 先通过 Identity & Namespace 确认当前调用方能读取哪些层级的数据,并决定默认继承范围,例如 user + project + recent_session。
2. 混合候选检索
Search & Index Service 同时利用:
- 词法检索
- 向量检索
- Scope / 标签 /时间过滤
然后通过混合排序生成基础候选集。如果向量能力不可用,系统必须退化为纯词法模式,而不是直接让召回不可用。
3. 业务排序
候选集拿回来之后,Recall Orchestrator 还要继续结合:
importancerecencyrelevance
做业务排序。这一步和底层检索排序不能合并,因为检索层只理解相关性,而召回层还要理解“什么更值得放进上下文”。
4. 去重与冲突检测
系统会优先按 semantic_key 去重,必要时再做内容层面的相似去重。对于明显冲突的记忆,策略不是偷偷合并,而是显式标记出来,交给调用方或用户判断。
5. Token 预算控制
Recall 的最终目标不是多,而是刚好。超出预算后,系统会优先削减低价值历史材料,再削减低 importance 的稳定记忆,必要时才截断 summary。
6. 结果组装
最后输出的不是原始检索列表,而是结构化的 Recall Context Block。这个结果块需要足够稳定,方便不同宿主直接消费。
为什么召回必须显式区分 Stable 与 History
因为两层信息面向的是不同的任务诉求:
- Stable 更适合注入长期规则、偏好和决策
- History 更适合恢复最近上下文和阶段进展
如果两者不分层,系统就无法按任务类型分配预算,也无法控制新鲜度和噪声比例。
召回质量的衡量标准
一条召回是否“好用”,最终要看它有没有帮助模型:
- 少走弯路
- 少重复询问背景
- 及时发现已有约定
- 在预算内拿到关键信息
因此召回链路的优化方向永远应该是“提高有效消费率”,而不是单纯让返回结果更多。