先说说为什么会有这个东西
做 AI Agent 的朋友应该都有过这种感觉:模型本身没有记忆,每次对话都是"失忆"重来。要让 Agent 记住用户偏好、记住上次任务做到哪一步、跨会话复用历史知识,就得自己搭一套记忆系统。
我调研过现成的方案,体验都不太顺:
-
上向量数据库(Pinecone、Qdrant、Weaviate 这些),功能确实全,但为了一个记忆功能就要部署一套分布式服务,对小项目和独立开发者来说太重了;
-
用云上的记忆服务(比如 Mem0),数据都在别人那里,而且按量付费,用起来总有顾虑;
-
自己用内存里的 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)融合排序:
- 语义检索(embedding 相似度)
- 关键词检索(SQLite FTS5 全文索引)
- 图谱信号(实体关系相关度)
# 混合模式 + 图谱增强
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 就是对我最大的鼓励。
我的 ID 是 YQteam-dyq,欢迎交流。