04 - 三层记忆架构与混合检索
学习目标
理解 CowAgent 的三层记忆架构、向量+关键词混合检索、时间衰减排序与批量嵌入优化。
前置知识
记忆系统的通用原理见 记忆系统设计。本章聚焦 CowAgent 的具体实现。
项目实践
三层记忆架构
混合检索实现
CowAgent 的记忆检索采用向量检索 + 关键词检索 + 时间衰减三路合并:
具体实现:
- 向量检索:使用 embedding provider 计算查询向量,在 SQLite 中检索 top-K
- 关键词检索:使用 SQLite FTS5 全文索引检索匹配结果
- 加权合并:
combined_score = vector_weight × vector_score + keyword_weight × keyword_score - 时间衰减:对日期文件应用指数衰减
exp(-λ × age_days),半衰期 30 天 - 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 采用两遍设计:
- 第一遍:遍历所有文件,对 hash 变化的文件做分块,收集所有待嵌入文本
- 第二遍:一次性调用
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,索引它们会引入近重复内容干扰检索。