我给 Agent 写了一个"记忆层":不用向量数据库,一个 SQLite 文件就够了

5 阅读5分钟

先说说为什么会有这个东西

做 AI Agent 的朋友应该都有过这种感觉:模型本身没有记忆,每次对话都是"失忆"重来。要让 Agent 记住用户偏好、记住上次任务做到哪一步、跨会话复用历史知识,就得自己搭一套记忆系统。

我调研过现成的方案,体验都不太顺:

  1. 上向量数据库(Pinecone、Qdrant、Weaviate 这些),功能确实全,但为了一个记忆功能就要部署一套分布式服务,对小项目和独立开发者来说太重了;

  2. 用云上的记忆服务(比如 Mem0),数据都在别人那里,而且按量付费,用起来总有顾虑;

  3. 自己用内存里的 HashMap 存,重启就没了,更别提语义检索。

我想要的东西其实很朴素:一个文件、一条命令就能跑起来的本地记忆层,装上就能用,数据完全在自己手里。找了一圈没有完全合心意的,于是决定自己写一个。这就是 yq-nova-agent 的由来,8 月 3 号开源,现在在 GitHub 上:github.com/YQteam-dyq/…

它解决什么问题

一句话概括:一个单文件 SQLite 的 Agent 记忆与状态层,核心就三个操作——remember(记住)、recall(回忆)、forget(遗忘)。

具体能干什么:

  • Agent 学会的东西可以跨会话保留下来,重启不丢;
  • 用自然语言就能召回过去存过、语义相关的信息;
  • 能记录实体和它们之间的关系,做简单的图谱推理;
  • 过期的、不重要的记忆会被自动清理,不会无限膨胀。

你不需要为了这些功能去部署任何外部服务,运行时依赖只有一个 SQLite 文件。

设计上几个我觉得值得说的点

记忆三件套,心智模型足够简单

整个 API 刻意收敛成三个动作,没有一堆概念。无论走 HTTP、Rust SDK 还是 CLI,都是同一套语义。

# 记住一条信息,可以打标签、标重要性
yq-nova remember "用户是 Rust 开发者,偏好轻量级工具" --tag user-profile --importance 0.9

# 用自然语言召回
yq-nova recall "用户的技术背景" --top-k 5

# 查询统计
yq-nova stats

不想起 HTTP 服务的话,CLI 直接就能用;想嵌进自己的 Rust 程序,把 yq-nova-core 当库引进去就行。

混合检索:不是只靠向量

早期版本如果只做向量相似度检索,会漏掉很多信息:精确的关键词匹配、实体之间的图关系,这些是纯语义搜索照顾不到的。所以 recall 走了混合路线——把三路信号用 RRF(Reciprocal Rank Fusion)融合排序:

  1. 语义检索(embedding 相似度)
  2. 关键词检索(SQLite FTS5 全文索引)
  3. 图谱信号(实体关系相关度)
# 混合模式 + 图谱增强
yq-nova recall "SQLite 相关的存储方案" --mode hybrid --graph

Embedding 这块做成可插拔的:默认接 OpenAI 兼容接口,也内置了一个 mock provider 方便离线开发和测试。

实体图谱:记忆之间要有关系

光有零散的记忆条目是不够的,信息之间往往有关联。项目里维护了实体-关系图,支持递归 BFS 遍历。比如存了"React 是 UI 库"、"Vue 是 UI 库",recall 的时候可以顺着图找到相邻概念,这是纯向量检索给不了的上下文。

SQLite 被低估了

很多人觉得 SQLite 只能做玩具,其实配合 WAL 模式、复合索引和 FTS5,做单机记忆层完全够用,而且部署成本几乎是零。数据持久化、事务、迁移都有现成方案,不用自己造轮子。这也是"零外部依赖"这个承诺能成立的原因。

v0.2.0 里补的工程化东西

8 月 6 号发了 v0.2.0,主要补的是"从能跑到能用"的差距:

  • 嵌入式 SDK 模式 EmbeddedNova,不进 HTTP 服务也能在进程内直接用;
  • 本地 ONNX 推理(FastEmbed),不依赖 OpenAI API 也能出向量;
  • HTTP 服务加了 API Token 认证中间件;
  • SQLite 向量索引(sqlite-vec 的 HNSW 后端);
  • 集成测试 + Criterion 性能基准(KNN、图遍历、embedding);
  • Docker 镜像和 docker-compose 一键启动;
  • 一个 Python 客户端 yq_nova
# Docker 起服务,数据落盘在 /data
docker run -p 7999:7999 \
  -v yq-nova-data:/data \
  -e YQ_NOVA_EMBEDDING__DEFAULT_PROVIDER=mock \
  yq-nova serve

认证、可观测性(OpenTelemetry)、基准测试这些虽然是"看不见的功能",但对真正想在生产里用的人来说是刚需,所以我在 v0.2 里优先把它们补齐了。

说点实话

项目还很新,8 月 3 号才开源,到现在 star 还是 0,issues 里也只有我自己。代码基本都是我一个人在写,18 个 commit。发这篇文章,不是想说自己做了多厉害的东西,而是这个方向(Agent 记忆)我自己踩了不少坑,觉得"轻量 + 本地 + 单文件"的路线是真实存在的需求,想把它介绍给更多有同样困扰的人。

如果你也在做 Agent,对记忆这块有自己的一套想法,或者实际用过之后觉得哪里设计得不对,欢迎来 GitHub 开 issue 聊。尤其想知道的是:你现在的 Agent 记忆是怎么做的?最痛的点在哪? 这些反馈对我接下来做 v0.3 会很有帮助——目前 v0.3 还在潜心开发中,具体优先做什么,我想多听一些真实场景的声音再定。

如果这个项目对你有用,或者你觉得这个方向有意思,给个 star 就是对我最大的鼓励。


仓库地址:github.com/YQteam-dyq/…

我的 ID 是 YQteam-dyq,欢迎交流。