欢迎光临
我们一直在努力

Agent系列(三)-记忆检索策略

一、为什么需要记忆检索?

记忆检索是解决:记忆无限增长的背景下,如何快速找到"相关"记忆?其面临的挑战包括:

  • 语义相关性:我们如何能检索到关键词不匹配,但语义相关的记忆;
  • 上下文窗口限制:检索到的记忆可能有几十条,但prompt只能容纳几千字了,应该如何处理?
  • 时效性问题:用户的偏好可能随时间变化。
  • 多样性覆盖:只检索最相关的可能忽略边缘信息,如何平衡相关性和多样性?

二、检索方法对比

方法原理适用场景优点缺点
向量检索 计算embedding余弦相似度 语义搜索 理解语义、准确率高 计算开销大、延迟高
关键词检索 BM25/TF-IDF关键词匹配 精确匹配 快速、精确 不理解语义、同义词问题
混合检索 向量+关键词组合 通用场景 平衡两种方法 实现复杂、权重调优
标量检索 结构化字段条件过滤 结构化数据 精确、可组合 需要预定义字段
时间检索 按时间排序或过滤 时序敏感 符合直觉 不考虑内容相关性

三、检索方法详述

3.1 向量检索

向量检索的核心思想是:将文字转为向量,用距离判断相似度;向量检索的具体方法,是将用户输入的文案,经过Embedding模型,转化为向量(例如:[0.12, -0.34, 0.78, 0.23, -0.56, 0.91, …] )。其核心原理是模型在大量文本上训练,学习语义关系,其中语义相近的文本,向量距离近;语义不同的文本,向量距离远。

3.1.1 主流向量检索算法
算法全称核心原理距离度量索引构建复杂度召回率速度内存适用场景
Brute Force 暴力搜索 遍历所有向量:计算所有向量的距离 任意 O(1) 100% ⚡ 慢 小数据量、基准对比
LSH 局部敏感哈希 哈希定位+桶内搜索:相似向量映射到同一桶 余弦/汉明 O(N×D) 85-95% ⚡⚡⚡ 快 近似搜索、去重
HNSW 分层导航小世界图 贪婪搜索+层级遍历:构建多层图,上层粗定位下层精搜索 任意 O(N×logN) 95-99% ⚡⚡⚡⚡⚡ 极快 大规模、高QPS
IVF 倒排索引 聚类中心+桶内搜索:聚类后只搜索部分聚类 任意 O(N×I) 90-97% ⚡⚡⚡ 快 中等规模、内存受限
PQ 乘积量化 查表+距离估算:向量分段压缩 欧氏/内积 O(N×D×K) 85-95% ⚡⚡⚡⚡ 很快 极大数据量、资源受限
ANNOY Approximate Nearest Neighbors Oh Yeah 树遍历:随机投影树 欧氏/余弦 O(N×logN) 90-95% ⚡⚡⚡ 快 稀疏向量、磁盘友好
SCA 随机坐标下降 迭代优化:坐标轴方向迭代优化 欧氏 O(N×D) 92-97% ⚡⚡⚡ 中 高维向量
3.1.2 向量检索优化技巧
  • 数据规模与索引选择:1)< 100万向量 → 简单HNSW 或 IVF;2)100万-1000万 → IVF + HNSW;3)> 1000万 → 分层聚类 + HNSW;
  • 召回率与速度权衡:1)高召回(>95%) + 低速度 → 增大ef, m参数;2)低召回(90%) + 高速度 → 减小ef, 使用粗量化;3)平衡方案 → 中等参数;
  • 内存限制:1)内存有限 → 使用量化(PQ、Binary);2)内存充足 → 使用完整向量 + HNSW;

3.2 关键词检索

关键词检索的核心是通过匹配关键词,找到相关文档;但是在关键词检索的关键问题是:1)如何量化相关性?2)如何排序多个匹配结果?3)如何处理同义词和语义相关?

3.2.1 主流关键词检索算法

关键词检索的原理如下:

算法核心思想核心公式评分方式词频饱和长度惩罚
Boolean 精确匹配AND/OR/NOT 无量化 0/1匹配 ❌ 无 ❌ 无
TF-IDF TF×IDF量化相关性 TF × IDF 乘积 ❌ 无 ❌ 无
VSM 文档和查询作为向量计算相似度 cos(θ) = A·B/( A B
BM25 TF饱和+长度惩罚的概率模型 IDF × (tf·(k1+1))/(tf+k1·(1-b+b·dl/avgdl)) 概率权重 ✅ 有 ✅ 有
LM 文档生成查询的概率 P(query|doc) = ∏P(wi|doc) 概率乘积 ✅ 有 ✅ 有

关键词检索的具体适用场景如下:

场景BooleanTF-IDFBM25语言模型VSM
精确匹配 ✅ 最佳 ❌ 不适合 ❌ 不适合 ❌ 不适合 ❌ 不适合
短查询 ⚠️ 一般 ✅ 适合 ✅ 最佳 ✅ 适合 ⚠️ 一般
长文档搜索 ❌ 不适合 ❌ 不适合 ✅ 适合 ✅ 适合 ⚠️ 一般
文档聚类 ❌ 不适合 ⚠️ 一般 ⚠️ 一般 ⚠️ 一般 ✅ 最佳
推荐系统 ❌ 不适合 ✅ 适合 ✅ 最佳 ✅ 适合 ✅ 适合
垂直搜索 ⚠️ 一般 ✅ 适合 ✅ 最佳 ✅ 适合 ⚠️ 一般
跨语言检索 ❌ 不适合 ⚠️ 一般 ⚠️ 一般 ✅ 适合 ⚠️ 一般
3.2.2 分词器介绍
分词方式适用语言例子优缺点
空格分词 英文 "I love China" → ["I", "love", "China"] 简单,但不处理标点
正则分词 通用 按标点和空格分 简单,处理标点
n-gram 通用 "北京" → ["北京", "京旅", "旅游"] 解决未登录词,但词汇表大
分词器(Jieba) 中文 "北京旅游" → ["北京", "旅游"] 需要词典,处理未登录词
BERT分词 通用 子词分词 效果好,但慢

3.3 标量检索

标量检索是是基于"标量字段"(非向量)的精确匹配检索。

3.3.1 标量检索与向量检索的区别
维度标量检索向量检索
匹配方式 精确匹配 近似匹配
查询类型 =, <, >, IN, LIKE 余弦相似度, 欧氏距离
索引结构 B树, 哈希, 位图 HNSW, IVF, PQ
时间复杂度 O(log N) 或 O(1) O(log N) 近似
结果确定性 确定性 非确定性
适用字段 结构化字段 文本、图像
典型场景 过滤、分组、排序 语义搜索、相似推荐
3.3.2 标量检索算法对比表
索引类型查询类型支持时间复杂度(最坏)空间复杂度适用场景优点缺点
B+树索引 等值查询、范围查询(>, <, >=, <=, BETWEEN)、前缀查询(LIKE 'xxx%') O(log n) O(n) 数值/日期范围查询、字符串前缀匹配、需要排序输出的场景 支持范围查询、支持排序、适合磁盘存储、范围查找性能稳定 范围查询边界有时较慢、内存占用较高、适合低选择性字段
哈希索引 等值查询(=、IN) O(1) O(n) 等值精确匹配、低基数字段、需要快速单值查找 等值查询极快(O(1))、实现简单、内存占用低 不支持范围查询、不支持排序、无法处理前缀查询、哈希冲突需要处理
位图索引 等值查询、集合查询(AND/OR/NOT)、基数较低字段 O(k) 或 O(1) O(n × k / w) 多值字段(标签、状态、枚举)、组合条件查询、OLAP分析 多条件组合查询极快(位运算)、压缩率高、适合低基数字段 空间随基数线性增长、高基数字段效率低、更新代价高
倒排索引 等值查询、集合查询、多字段查询 O(k) 平均 O(n + m) 多值字段、文档检索、标签查询、元数据过滤 擅长多值字段、支持灵活组合、文档定位快 索引构建较慢、内存占用较大、不适合范围查询
跳表索引 等值查询、范围查询 O(log n) O(n) 有序数据、Redis Sorted Set、优先级队列 实现简单、适合内存存储、支持范围查找、并发友好 空间开销比哈希大(每节点多个指针)、不如B+树磁盘友好
LSM树索引 等值查询、范围查询(写入优化) 写O(1)、读O(log n) O(n) 写入密集型场景、时序数据、日志系统 写入性能优异、适合批量写入、空间放大可控 读取路径可能需要访问多层、读放大问题、合并操作消耗资源
3.3.3 标量检索常见的实现方案
实现方案底层数据结构查询类型查询性能适用数据规模实现复杂度典型工具/数据库
数据库内置索引 B+树(MySQL/PostgreSQL)、B树(RocksDB) 等值、范围、前缀 读性能优秀 亿级记录以下 MySQL InnoDB、PostgreSQL、Oracle
键值存储索引 哈希表 + 跳表 等值为主 等值O(1) 百万-千万级 Redis、Memcached、DynamoDB
搜索引擎索引 倒排索引 + FST 等值、文本、集合 多字段查询优秀 十亿级文档 Elasticsearch、Solr、Meilisearch
列式存储索引 位图索引 + 字典编码 等值、集合、聚合 OLAP查询极快 PB级分析 Apache Druid、ClickHouse、Apache Pinot
自定义内存索引 红黑树/B树/跳表 视具体实现 内存访问快 百万级以下 内存数据库、缓存层、实时系统
混合存储索引 向量+标量联合索引 所有标量类型 综合性能最优 根据配置 Milvus、Pinecone、Weaviate

具体选择建议如下:

  • 等值查询优先选哈希,因为复杂度固定为O(1)
  • 范围查询必须选B+树,其他索引类型难以替代
  • 多值字段选位图或倒排,取决于基数高低
  • 组合查询场景推荐混合使用多种索引或使用专门的搜索引擎

3.4 时间检索

时间检索是基于时间维度进行的数据检索和过滤操作,是标量检索在时间/日期字段上的特化应用。其核心特征是通过时间戳、时间范围、时间窗口等条件来定位和过滤数据。

3.4.1 时间检索类型对比
检索类型查询方式时间范围表达精度控制动态性典型应用场景
绝对时间检索 精确时间点或明确范围 固定起止时间戳 毫秒级精度 静态,范围固定 审计日志、交易记录、定时事件查询
相对时间检索 基于参照时间的偏移 "过去7天"、"上个月"、"本周" 与当前时间动态计算 动态,每次查询重新计算 实时监控仪表盘、最近对话检索、趋势分析
时间序列窗口检索 固定或滑动时间窗口 窗口大小 + 步长(可选) 窗口边界对齐 半动态,窗口固定但起点滚动 指标统计、异常检测、聚合分析
时间拓扑检索 基于时间关系判断 关系表达式(包含、相交、前后) 关系逻辑判断 结构化表达 事件因果分析、日程冲突检测、会话分割
3.4.2 时间检索性能优化

第一,合理选择时间分区粒度。分区粒度太粗会导致查询范围过大,降低效率;分区粒度太细会导致大量小文件,增加管理开销。一般建议按天分区,数据量大的场景可以按小时分区。

第二,使用时间索引跳过无关数据。在查询时,通过时间索引直接定位到相关时间范围,避免全表扫描。这是时间检索性能优化的核心原则。

第三,考虑冷热数据分离。将历史数据和实时数据分离存储,使用不同的存储介质和检索策略。热数据使用内存或SSD,冷数据使用普通磁盘或对象存储。

第四,利用预聚合减少计算量。对于需要频繁查询聚合指标的场景(如每分钟事件数、每小时活跃用户数),提前计算并缓存聚合结果。

第五,组合使用时间过滤和其他检索。时间检索适合作为前置过滤器,缩小候选集后再进行向量检索或全文检索,提高整体检索效率。

赞(0)
未经允许不得转载:171主机测评 » Agent系列(三)-记忆检索策略
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址