Files
hunjing/docs/architecture/memory-and-knowledge.md
T
chenxin 5da1efe921 📝 docs: 统一 PostgreSQL 主库并固化索引命名约定
- 新增 ADR-024:服务端关系主库统一 PostgreSQL,不设 SQLite 档(pgvector 与中文全文无法在 SQLite 承载,双档必然残缺或第二实现);端侧离线缓存不受约束
- AGENTS.md:权威事实源与部署句更新;8.6 固化 pk_/uk_/idx_/fk_ 索引命名约定
- system-architecture、data-architecture、memory-and-knowledge、roadmap WP-01、handoff(决策 29)同步清理 SQLite 引用
2026-09-09 21:14:10 +08:00

185 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 记忆与知识架构
> 本文定义 1.0 的记忆所有权、写入、版本、检索和上下文装配边界。字段与稳定枚举以 `docs/contracts/` 和后续 OpenAPI 3.1 为准。
## 1. 边界
- `Message` 是不可被记忆覆盖的原始交流记录;编辑产生 Revision。
- `MemoryCandidate` 是待判定的提取结果,不参与正式召回。
- `Memory` 是稳定标识;`MemoryVersion` 是不可变内容版本,当前版本仅由 `Memory` 指针引用。
- `KnowledgeDocument` 保存外部资料和世界设定;其切片与索引是可重建投影,不冒充人物经历。
- Character baseline、用户资料、关系、知识和记忆分别建模;任何记忆策略都不能直接修改 CharacterVersion。
- 对话压缩、工作上下文和 Provider Prompt Cache 是运行期派生状态,不属于长期记忆。
- 1.0 不定义可绕过治理的 `WorkingMemory` 类型;当前分支消息和 Run 临时上下文始终按 Personal Domain/Workspace、Character、Conversation、Branch 与 Run 授权,不能因“临时”跳过隔离。
1.0 的权威记忆是可检查、可纠正的文本或结构化记录。KV cache、隐藏状态和模型权重适配不作为权威记忆,也不进入 1.0 记忆可携格式。
## 2. 所有权与作用域
每条 Memory 必须属于且只属于一个授权边界:
| 所有权 | 必需关联 | 可选关联 | 用途 |
| --- | --- | --- | --- |
| Personal Domain | `personal_domain_id` | `character_id` | 用户级或私密角色级记忆 |
| Workspace | `workspace_id` | `character_id` | 经成员权限允许的协作记忆 |
约束:
- `personal_domain_id` 与 `workspace_id` 二选一;在数据库层使用检查约束落实。
- `character_id` 只能引用同一所有权边界内的 Character。
- `conversation_id`、`message_id`、`content_block_id`、`run_id` 和 `tool_call_id` 是来源或适用条件,不是授权边界。
- 角色间共享通过显式授权和独立引用完成,不复制一份失去来源关系的 Memory。
- 子 Agent 只读父 Run 已批准的召回快照;默认没有创建、批准、纠正或删除长期记忆的能力。
- 社区 Release、市场交付物和推荐特征不得包含 Personal Domain Memory。Workspace 内容发布前同样经过独立发布审查。
## 3. 记忆分类
1.0 只定义四类可解释长期记忆;稳定值登记在[协议与稳定标识](../contracts/README.md#memory_kind),并在实现前进入 OpenAPI/Schema:
| 类型 | 含义 | 默认写入要求 |
| --- | --- | --- |
| `fact` | 可核对的人、事、状态或约束 | 有明确来源;冲突时生成纠正候选 |
| `preference` | 用户或角色明确表达、或系统推断的偏好 | 显式与推断分开;推断偏好需要置信度 |
| `event` | 带时间范围的经历或事件 | 保留时间语义和来源 |
| `relationship` | 人物间关系及其变化 | 高影响,默认人工确认 |
身份基线、人格设定、权限、秘密、工具定义和知识文档不塞入上述类型。需要新类型时先更新契约和评测,不使用任意 metadata 绕过类型系统。
## 4. 写入与版本
```mermaid
flowchart LR
S[Source] --> E[Extract]
E --> C[Candidate]
C --> P{Policy}
P -->|approve| V[MemoryVersion]
P -->|review| H[Human review]
H -->|approve| V
P -->|reject| X[Rejected]
H -->|reject| X
V --> A[(Authoritative DB)]
A --> I[Indexes]
I --> R[Retrieve]
R --> M[ContextSnapshot]
```
### 4.1 来源
Candidate 至少记录:
- 所有权边界、目标 Character(如有)和候选类型;
- 精确来源引用,包括 Message/Block、KnowledgeDocument chunk 或 ToolCall 的 ID 与版本;
- extractor、prompt、parser 和 policy 版本;
- 候选正文、结构化时间、置信度、敏感度和创建时间;
- 来源内容 hash 与候选 fingerprint,用于幂等和去重。
自动提取由 Message 完成后的 Outbox/Job 异步触发,不延长消息与 Run 的原子创建事务。重复消费相同来源与 extractor 版本必须返回同一候选或明确的去重结果。
ToolResult、网页、文件和模型输出都只是观察。它们可以产生 Candidate,但未经来源校验与 Policy 判定不能直接成为事实。
### 4.2 审批
- 用户显式创建可直接进入批准流程,但仍执行 Schema、所有权、敏感度和冲突检查。
- 敏感资料、第三方个人信息、关系结论、高影响推断和隐式偏好默认需要人工确认。
- 低风险自动候选只有在策略明确允许的白名单内容上才能自动批准,并必须附带撤销窗(写入后一段时间内一键撤销且不留检索痕迹);策略版本必须进入审计。白名单外内容一律进入人工审核。
- Candidate 的批准或拒绝是幂等命令;批准时在一个事务写 Memory/MemoryVersion、AuditEvent 和 OutboxEvent。
- Candidate 不使用 `memory_status`;其生命周期与正式 Memory 分开定义。
### 4.3 纠正与并发
- 创建、纠正、取代和恢复均创建新的 MemoryVersion,不原地覆盖历史内容。
- PATCH Memory 必须携带 `If-Match`;并发版本不匹配返回 `412 precondition_failed`。
- 用户纠正优先绑定上一次召回的 Memory ID/Version ID,避免仅凭自然语言重新搜索后误改同名记忆。
- 纠正后的旧版本保留谱系但不再参与召回;恢复旧内容也创建新版本。
- 删除立即阻止读取与召回,清除所有版本中的原文及派生索引,只保留不含原文的最小墓碑和审计元数据。
### 4.4 归真作用域
记忆候选与手动入忆必须携带并保留来源界域 `canonical_scope`(见 [ADR-020](../decisions/README.md#adr-020对话三界与归真作用域)):
- **真界**(`reality`):按既有候选、审批与敏感度规则进入角色正式经历记忆。
- **境界**(`world`):归真只形成该世界的知识候选(境忆),进入 KnowledgeDocument 与世界实体体系,不进入角色真界经历记忆,也不影响现实关系数据。
- **幻境**(`simulation`):不自动形成长期记忆候选;用户可将启发、观点或假设手动入忆,强制标注性质(事实/观点/启发/假设),且仍走敏感度与确认规则——幻境不得成为绕过敏感审批的通道。
界域来源不可事后静默更改;跨界引用只提供来源,不改变目标记忆的作用域。
## 5. 衰减、有效期与整理
- `valid_from`/`expires_at` 表达事实有效期;过期版本在召回资格过滤阶段排除,但仍可按授权查看历史。
- 衰减只影响排序或生成归档候选,不静默改写、删除或降低用户已确认事实的真实性。
- 用户可固定重要记忆;固定状态仍不能绕过删除、撤权或有效期。
- 去重、合并、冲突检测和归档由异步 Job 执行,任务带租约与幂等键;失败不影响权威版本和在线对话。
- 自动整理结果仍是 Candidate 或新版本提案,不能绕过审批策略。
具体衰减函数和阈值必须通过评测确定,不在架构层虚构固定数值。
## 6. 检索管线
检索严格按以下顺序执行:
1. 根据 actor、Personal Domain/Workspace 和 Character 在数据库查询层限定可见集合;
2. 过滤非 active、已过期、已撤权、已删除和被取代版本;
3. 并行生成全文、语义和结构化关系候选;
4. 按 Memory ID/Version ID 合并去重并重排;
5. 应用敏感度、用途、数据驻留和 Run 权限策略;
6. 按 token/条目/延迟预算选择进入上下文的结果;
7. 将召回证据固化到 ContextSnapshot,供用户解释和受保护诊断。
禁止先跨域全量召回再在应用层过滤。向量分数不能替代授权、来源可信度或有效期判定。
公开 Memory Search 只返回调用者有权查看的命中项,并包含命中版本、来源、各检索通道分数、重排结果、召回说明和是否进入上下文。被权限过滤的对象不能以计数、分数或错误细节泄露存在性。
## 7. 上下文装配
上下文顺序沿用 [Agent 运行时](agent-runtime.md#7-上下文装配):工具定义 → 稳定指令 → 当前分支消息 → 获准记忆与知识 → 动态运行上下文 → 当前输入。
ContextSnapshot 对每个候选记录:
- Memory ID、Version ID、来源引用和内容 hash;
- 召回通道、原始分数、重排分数和策略结果;
- 是否选中、未选原因、估算 token 和最终顺序;
- 检索器、embedder、reranker、policy 与装配器版本。
ContextSnapshot 不保存隐藏推理。普通 Run API 只返回用户可理解的来源摘要;详细分数、排除原因和版本信息遵守 DiagnosticGrant。
## 8. 索引与故障语义
- PostgreSQL 中的 Memory、MemoryVersion 和来源关联是权威事实;全文、pgvector 和图关系是可重建投影。
- 权威事务通过 Outbox 驱动索引更新。索引延迟时,新版本可暂时降级为关系数据库检索,旧版本不得继续被召回。
- 删除与撤权事件优先于普通重建任务;消费者按 event ID 幂等。
- 无法证明索引已清除时,对目标 Memory fail closed,并记录待修复状态,不能继续返回旧结果。
- 图投影只用于结构化关系检索;没有量化多跳收益前不引入专用图数据库。
## 9. 插件边界
Memory extractor、deduper、reranker、decay 和 context provider 可以由插件贡献。Core 始终负责:
- 身份、所有权和授权过滤;
- Candidate/Version 状态迁移与事务;
- 敏感度、审批、删除、审计和 Outbox;
- 插件输入输出 Schema、资源预算和版本快照;
- 最终 ContextSnapshot 与召回证据。
插件只能提出 Candidate、分数或排序,不能直接写权威 Memory、扩大作用域、读取未授权来源或阻止删除传播。
## 10. 评测与验收
WP-04 至少留下以下可重复证据:
- **写入质量**:事实、偏好、事件、关系的提取 precision/recall,以及敏感内容错误自动批准率;
- **召回质量**:长对话、多会话、时间推理、冲突纠正和多跳关系的 Recall@K、MRR/nDCG 与最终问答正确率;
- **安全正确性**:跨用户、跨角色、跨 Workspace、跨 Conversation/Branch/Run、已删除、已过期和已撤权内容的召回率必须为 0;Candidate、来源 Prompt Injection 和插件输出不能扩大 scope 或绕过审批;
- **可追溯性**:每个进入上下文的 Memory 都能定位到当前版本和未删除来源;
- **恢复能力**:索引全量重建、重复 Outbox、乱序消费和删除重放后结果一致;
- **性能成本**:写入延迟、检索 p50/p95、候选数、rerank 时延、上下文 token 和单次召回成本。
LoCoMo、LongMemEval 等公开数据集可用于回归,不替代 Hunjing 自有的中文、多角色、分支、敏感审批、删除和越权测试集。阈值在实现前通过基线实验写入发布门,不引用外部项目宣传分数作为验收结果。
## 11. MemOS 采纳边界
参考基线:MemTensor/MemOS commit `28dfb4e7d3adad1c93fd5574675f913921367d36`,Apache-2.0。详细证据见[参考项目研究](../research/reference-projects.md#memos)。
采纳:类型化且可检查的记忆、来源追踪、分层检索、快速摄取后异步精炼、后台整理、基于已召回 ID 的纠正、可重复评测。
不采纳:把 MemCube 当作 Hunjing 授权边界、原地更新权威记忆、开放式 metadata 代替契约、运行时隐式建表、把向量/图存储作为事实源、保存或回放隐藏状态/KV cache、在 1.0 用参数记忆修改模型权重。