跳转到内容

04 - 三层记忆架构与混合检索

学习目标

理解 CowAgent 的三层记忆架构、向量+关键词混合检索、时间衰减排序与批量嵌入优化。

前置知识

记忆系统的通用原理见 记忆系统设计。本章聚焦 CowAgent 的具体实现。

项目实践

三层记忆架构

混合检索实现

CowAgent 的记忆检索采用向量检索 + 关键词检索 + 时间衰减三路合并:

具体实现:

  1. 向量检索:使用 embedding provider 计算查询向量,在 SQLite 中检索 top-K
  2. 关键词检索:使用 SQLite FTS5 全文索引检索匹配结果
  3. 加权合并combined_score = vector_weight × vector_score + keyword_weight × keyword_score
  4. 时间衰减:对日期文件应用指数衰减 exp(-λ × age_days),半衰期 30 天
  5. MEMORY.md 不衰减:非日期文件视为”常青”条目(multiplier=1.0)

Embedding Provider 双路径初始化

# 路径 A:自动降级(无 embedding_provider 配置)
# OpenAI text-embedding-3-small → LinkAI 代理 → 关键词模式
# 路径 B:显式配置
# 支持 OpenAI/LinkAI/DashScope/Doubao/Zhipu 五种提供商
# 维度不匹配时向量检索返回空结果,关键词检索兜底

关键设计:当 embedding provider 不可用时,记忆系统不报错,而是退化到纯关键词搜索模式。

批量嵌入优化

多文件同步时,CowAgent 采用两遍设计

  1. 第一遍:遍历所有文件,对 hash 变化的文件做分块,收集所有待嵌入文本
  2. 第二遍:一次性调用 embed_batch() 跨所有文件批量嵌入

这比逐文件嵌入将 HTTP 调用从 ~100 次降低到 ceil(total_chunks / vendor_cap) 次(通常 ~2-5 次)。

问题与规避

问题CowAgent 的规避策略
向量维度不匹配(切换提供商)静默降级到关键词搜索,用户需手动 rebuild-index
嵌入 API 失败不更新 file_hash,下次同步重试同一文件,索引保持完好
旧记忆干扰检索时间衰减函数降低旧文件权重
Dream 日记污染索引sync 时跳过 dreams/ 目录,不参与索引

设计取舍

为什么用 SQLite 而非专用向量数据库?

CowAgent 面向个人/小团队部署,SQLite 零依赖、零运维成本。FTS5 提供关键词检索,通过存储 embedding 向量数组 + 余弦相似度计算实现向量检索。代价是大规模数据(万级 chunk 以上)检索性能不如专用方案。

为什么排除 Dream 日记不参与索引?

注释明确说明:“Dream diaries are narrative reflections produced by Deep Dream; their factual content has already been distilled into MEMORY.md. Indexing them adds noisy near-duplicates that crowd out the authoritative entry in retrieval.” Dream 日记是整理过程的叙事记录,事实内容已提炼到 MEMORY.md,索引它们会引入近重复内容干扰检索。

参考来源