1. 项目简介
项目:Zorv AI(包名
com.ai.assistance.quro) 适用版本:v1.0.77 开源地址:github.com/Quor-a/Zorv…
Zorv AI 是一个端侧优先的 AI 助手项目,其核心亮点之一便是记忆库(Memory Library)——一个文件化、AI 可自动沉淀的长期记忆系统。
让 AI 能"记住"用户偏好 / 事实 / 约定 / 项目背景,跨会话持续可用,而不是每次对话都要用户重新交代。
本文将从设计定位、整体架构、数据模型、检索引擎、AI 记忆工具等多个维度,带你完整拆解这套记忆库的实现细节。
2. 设计定位与核心特点
Zorv AI 记忆库的设计遵循以下原则:
- 端侧优先:纯本地 JSON 文件,无云端依赖、无第三方库(仅 Android 自带
org.json)。 - 人格隔离:每条记忆可绑定某张人格卡(
personaId),空 = 全局记忆。 - AI 自动写:通过
memory_save等工具,AI 在对话中主动沉淀记忆。 - 可检索:BM25 相关性排序 + 子串兜底,中英混排友好。
这套设计让记忆库既能保证用户隐私(数据不出端),又能提供足够灵活的检索能力,兼顾性能与召回率。
3. 整体架构
记忆库整体分为四层:AI 引擎、工具层、仓库层与持久化层。
flowchart TB
subgraph AI["AI 引擎"]
T["memory_save / memory_list\nmemory_search / memory_delete"]
end
subgraph TOOL["工具层 (QuroMemoryTools)"]
S["QuroMemorySaveTool"]
L["QuroMemoryListTool"]
Q["QuroMemorySearchTool"]
D["QuroMemoryDeleteTool"]
end
subgraph REPO["仓库层 (QuroMemoryRepository)"]
R["loadAll / loadForPersona"]
W["add / update / delete"]
SE["search (BM25)"]
IO["saveAll (JSON 文件)"]
end
subgraph FS["持久化"]
F["filesDir/quro_memory.json"]
end
T --> TOOL
TOOL --> REPO
REPO --> IO
IO --> F
F --> R
- AI 引擎:通过 function calling 调用记忆工具。
- 工具层:封装 4 个记忆操作工具。
- 仓库层:核心业务逻辑,负责加载、增删改查与检索。
- 持久化:最终落盘为本地 JSON 文件。
4. 数据模型(QuroMemoryEntry)
每条记忆的数据结构如下:
| 字段 | 类型 | 说明 |
|---|---|---|
id | String | UUID,唯一标识 |
personaId | String | 绑定人格卡 id;空 = 全局记忆 |
group | String | 分组 / 文件夹(偏好 / 工作 / 项目) |
title | String | 标题,便于检索与展示 |
content | String | 记忆正文(必填) |
tags | List<String> | 命名关联标签 |
createdAt | Long | 创建时间 |
updatedAt | Long | 更新时间 |
人格隔离机制
flowchart LR
A["全局记忆\npersonaId=''"] --> M["记忆库"]
B["人格 A 记忆"] --> M
C["人格 B 记忆"] --> M
M -->|"loadForPersona(A)"| R["A 的记忆 + 全局记忆"]
loadForPersona(id):某人格卡取记忆时,自动并入全局记忆(personaId为空者),实现"人格专属 + 全局共享"。
5. 存储与持久化
- 文件位置:
context.filesDir / quro_memory.json - 格式:
{"memories":[ ... ]},纯JSONObject/JSONArray,无第三方依赖。 - 向后兼容:仅含
id/personaId/content/tags/createdAt的历史文件可正常加载。
{
"memories": [
{
"id": "uuid-...",
"personaId": "",
"group": "偏好",
"title": "不喝咖啡因",
"content": "用户下午后不喝含咖啡因饮品",
"tags": ["习惯", "健康"],
"createdAt": 1234567890,
"updatedAt": 1234567890
}
]
}
6. 检索引擎(BM25 + 子串兜底)
检索策略采用双层保障,确保"相关性"与"召回率"兼顾。核心源码位于 QuroMemoryRepository.search()。
flowchart TB
Q["query"] --> BM25["1) BM25 打分排序"]
BM25 -->|"topK 全量"| Rank["相关结果降序"]
Rank --> Fallback{"BM25 是否\n漏掉子串命中?"}
Fallback -->|"是"| Sub["2) 子串包含兜底\n(内容/标题/标签/分组)"]
Fallback -->|"否"| Out["直接返回"]
Sub --> Out
Out --> Res["最终结果 = 相关排序 + 兜底追加"]
| 层 | 机制 | 收益 |
|---|---|---|
| BM25 | 词频饱和 + 长度归一化;中文走 bigram,无需词典 | 短而切题的记忆排在长而泛泛之前;支持中英混排/多词 |
| 子串兜底 | 对纯符号/单字符/分词边界特殊查询补召回 | 不丢失精确编号/英文片段的旧行为 |
- 索引文本 =
标题 + 内容 + 标签 + 分组,任一字段命中即得分。 - 空查询返回全部记忆。
7. AI 记忆工具(function calling)
AI 通过 4 个工具直接与记忆库交互(见 QuroMemoryTools.kt):
| 工具名 | 作用 | 关键参数 |
|---|---|---|
memory_save | 保存一条长期记忆 | content(必填) / title / group / tags |
memory_list | 列出全部记忆 | 无 |
memory_search | 按关键词检索 | query |
memory_delete | 删除匹配的记忆 | query |
自动沉淀原则:当用户透露值得跨会话记住的信息(偏好/约定/项目背景)时,AI 应主动调用
memory_save,无需用户明确要求。
8. 与灵魂注入的衔接
记忆库是"灵魂层"的三大输入之一,为 AI 人格提供长期记忆上下文:
flowchart TB
Mem["记忆库\nQuroMemoryRepository"] -->|"loadForPersona"| Ctx["SoulContext.memories"]
Ctx --> Engine["QuroSoulPromptEngine"]
Engine -->|"第三优先级"| Sys["灵魂层提示词\n『已有记忆』段"]
Switch["autoSaveMemory 开关"] -->|"关闭"| NoMem["不注入记忆 / 不提示记忆能力"]
Switch -->|"开启"| Mem
- 受 "AI 自动保存记忆"开关(
autoSaveMemory)控制:关闭时既不注入已有记忆,也不提示记忆能力。 - 注入时以"自然融入对话,不要生硬提及"的方式呈现,维持人格一致性。
9. 并发安全与导入导出
| 机制 | 实现 |
|---|---|
| 进程级写锁 | companion object writeLock,跨 ViewModel / 语音球 / 记忆工具 多实例保证临界区原子,杜绝并发写互相覆盖 |
| 临界区 reload | add/update/delete/mergeImport 在锁内重新 loadAll() 再写,避免同窗口覆盖 |
| 导出 | exportJson() → {"memories":[...]} 文本 |
| 导入 | mergeImport():按 id 合并(相同 id 覆盖,否则追加),返回导入条数 |
| 兼容解析 | parseJson() 兼容 {"memories":[...]} 与纯数组两种格式 |
10. 能力对照表
| 能力 | 入口 | 说明 |
|---|---|---|
| 保存记忆 | memory_save | AI 主动沉淀 |
| 列出记忆 | memory_list | 全量展示 |
| 检索记忆 | memory_search | BM25 + 子串兜底 |
| 删除记忆 | memory_delete | 按关键词匹配 |
| 人格隔离 | personaId | 专属 + 全局共享 |
| 导入导出 | mergeImport / exportJson | 备份与迁移 |
| 并发安全 | writeLock | 跨实例原子写 |
11. 总结
Zorv AI 的记忆库设计体现了几个值得借鉴的思路:
- 端侧优先:数据不出端,天然保护隐私,也省去云端同步的复杂度。
- AI 自动沉淀:通过 function calling 让 AI 主动记忆,而非依赖用户手动操作。
- 双层检索:BM25 保证相关性,子串兜底保证召回率,兼顾精度与覆盖。
- 人格隔离:
personaId实现"专属 + 全局共享"的灵活记忆边界。 - 并发安全:进程级写锁 + 临界区 reload,保证多实例写入不互相覆盖。
如果你对端侧 AI 记忆系统、function calling 落地或 Android 本地持久化方案感兴趣,这个开源项目值得深入阅读源码。
配套文档:跨进程能力框架见《ACI 完整架构介绍》;系统级浮窗见《LSPosed 与系统级浮窗技术架构》;小程序渲染见《小程序技术架构》;人格与心跳见《灵魂注入与 AI 心跳人格自动孵化》。