# 业务记忆管理手册 > 写给:产品、开发、测试、合规 > 目的:说清楚 **什么叫短期记忆、什么必须长期保存**,以及 **Redis / MySQL / Neo4j / Milvus / Core / 本地文件** 各自放什么 > 关联:[00-架构总览.md](../项目框架设计/表设计/00-架构总览.md) · [02-redis-keys.md](../项目框架设计/表设计/02-redis-keys.md) · [03-milvus-collections.md](../项目框架设计/表设计/03-milvus-collections.md) · [04-neo4j-model.md](../项目框架设计/表设计/04-neo4j-model.md) · [数据交互矩阵.md](../需求拆解/数据交互矩阵.md) --- ## 1. 一句话总览 ```text 短期记忆 = 为了「这一轮对话跑得顺」的临时数据,丢了能重建,不做法务证据。 权威记忆 = 必须长期保存、能审计、跨 Agent 共享的业务结论,以 MySQL 为准。 知识记忆 = 产品/制度文档的语义检索(Milvus),不是聊天记录。 关系记忆 = 谁持有啥、谁管谁、产品要什么风险等级(Neo4j),金额事实仍以 Core 为准。 官方事实 = 持仓、流水、正式 C1~C5(Core 只读,Agent 库不复制账表)。 ``` **铁律:** Redis 里的内容 **永远不是最终真相**;合规纠纷、监管检查、跨 Agent 交换,一律以 **MySQL + Core** 为准。 --- ## 2. 记忆分层模型(业务语言) 可以把整个系统的「记忆」分成五层,从「聊完就忘」到「必须留档」: | 层级 | 业务名称 | 技术载体 | 生命周期 | 丢了怎么办 | | --- | --- | --- | --- | --- | | **M0** | 对话草稿 | **Redis** | 分钟~小时(TTL) | 从 MySQL 最近消息重建上下文,略慢 | | **M1** | 权威业务记忆 | **MySQL** | 永久(只增不改的审计表) | **不可接受丢失** | | **M2** | 知识库记忆 | **Milvus** + 本地 `data/kb/` | 随文档版本更新 | 重新切片、embedding 导入 | | **M3** | 关系记忆 | **Neo4j** | 随 Core 同步刷新 | 从 Core 重跑同步 Job | | **M4** | 官方事实 | **Core(只读)** | 业务系统权威 | Agent 不建第二套账 | 另外还有 **L0~L3 用户画像**(见 §4):L0 在 Core,L1/L2/L3 在 MySQL(Redis 只做热缓存)。 --- ## 3. 什么叫「短期记忆」? ### 3.1 定义 **短期记忆** = 当前会话进行中、为了少查库、少重复推理而放在 **Redis** 里的数据。 特征: - 有 **TTL**(过期自动删) - **可重建**(源数据在 MySQL 或 Core) - **不参与合规最终认定**(例如不能以 Redis 里的草稿代替 audit_log) - **不跨 Agent 长期共享**(跨 Agent 共享走 MySQL 画像表) ### 3.2 典型短期记忆(P0 全部在 Redis) | 业务场景 | Redis Key(示例) | 存什么 | TTL | 为何是短期 | | --- | --- | --- | --- | --- | | 多轮对话上下文 | `sess:{agent}:{session_id}:ctx` | 当前意图、槽位、上一轮 Tool 摘要 | 2h | 关页/超时后不需要;完整消息在 MySQL | | 最近聊天窗口 | `sess:{agent}:{session_id}:msgs` | 最近 ≤20 轮 JSON | 2h | 滑动窗口;全量在 `agent_message` | | 会话并发锁 | `sess:{agent}:{session_id}:lock` | 防双写 | 30s | 纯技术锁 | | 画像热缓存 | `profile:l1/l2/l3:{...}` | MySQL 画像 JSON 副本 | 5~10m | 加速读;权威在 MySQL | | 代理人资产快照缓存 | `cache:advisor:snapshot:...` | A-01 查 Core 后的摘要 | 15m | 权威副本在 L2 `asset_snapshot` | | 风控预警推送 | `risk:pub:alert` | Pub/Sub 通知 | — | 实时通道;单据在 `risk_alert` | | 预警去重 | `risk:dedup:...` | 同日同规则是否已报 | 24h | 防风暴;不是业务台账 | | 限流/封禁 | `guard:rate` / `guard:block` | 计数、临时封禁 | 1m~15m | 安全控制 | | Token 吊销 | `auth:revoked:{jti}` | JWT 黑名单 | 至 exp | 鉴权辅助 | ### 3.3 短期记忆的读写规则 ```text 写:对话每条消息 → 先/并行写 MySQL agent_message → 再更新 Redis 窗口 读:优先 Redis 窗口拼上下文 → 不够再读 MySQL 最近 N 条 删:TTL 到期自动删;画像 MySQL UPDATE 后主动 DEL 对应 profile:* Key ``` **禁止放进 Redis 的(必须 MySQL):** - 审计总账 `audit_log` - 预警单最终状态 `risk_alert.status` - 草稿审核结果 `advisor_draft.review_status` - 分析 SQL 留痕 `analytics_query_log` - 适当性阻断记录 `risk_suitability_log` --- ## 4. 用户画像:L0~L3 存哪儿? | 层级 | 业务含义 | 权威存储 | Redis 缓存 | 谁写 | | --- | --- | --- | --- | --- | | **L0** | 正式 C1~C5、KYC(性别/学历/收入/资产)、问卷得分、风评过期 | **Core 只读**(`jinrong_core`) | 一般不缓存(或极短 TTL) | 非 Agent | | **L1** | 客户偏好:风格、规划、阈值摘要、行为标签 | **MySQL** `customer_profile_l1` | `profile:l1:{customer_id}` | 客户 Agent | | **L2** | 服务侧:诉求、待办、资产概况快照、服务标签 | **MySQL** `customer_profile_l2` | `profile:l2:{customer_id}:{advisor_id}` | 代理人 Agent | | **L3** | 监测侧:正常/关注/高风险、评分维度 | **MySQL** `customer_profile_l3` | `profile:l3:{customer_id}` | 风控 Agent | **记忆管理要点:** - L1/L2/L3 **以 MySQL 为权威**;Redis 只是「刚查过」的副本。 - **禁止**用 L1 客户口头偏好 **覆盖** L0 正式风险等级。 - 客户 **不可见** L2/L3(API 层 404,不是 Redis 里藏一下就行)。 **R-02 适当性(记忆分工):** ```text 计算(L0 + 产品 + C×R 矩阵)→ CoreReadOnlyRepository.check_suitability() 【jinrong_core】 记账(审计 + 客户/代理人可读)→ risk_suitability_log 【jinrong_agent】 映射 → app/model/suitability.py · 契约 → 表设计/07-risk_suitability_log说明.md ``` **JSON 字段约定:** [06-用户画像L1-L3设计.md](../项目框架设计/表设计/06-用户画像L1-L3设计.md) ## 5. MySQL:权威业务记忆放什么? MySQL = **正式档案柜**。凡是 **要审计、要跨 Agent 读、要留痕** 的,都落 MySQL。 ### 5.1 按业务类型对照表 | 业务类型 | 典型内容 | MySQL 表(P0) | 是否短期 | | --- | --- | --- | --- | | 会话归档 | 每句 user/assistant/tool | `agent_session`, `agent_message`, `agent_tool_call` | 长期 | | 合规审计 | 谁问了什么、判定结果 | `audit_log`, `input_guard_log` | 长期,**只 INSERT** | | 数据归属 | 客户归哪个代理人 | `customer_advisor_rel` | 长期(Core 同步) | | 客户画像 L1 | 风格、规划、阈值偏好 | `customer_profile_l1` | 长期 | | 服务画像 L2 | 诉求、待办、快照 | `customer_profile_l2` | 长期 | | 监测画像 L3 | 分层、评分、标签 | `customer_profile_l3` | 长期 | | 风控预警 | 预警单、人工处置 | `risk_alert` | 长期 | | 适当性 | 匹配/阻断记录 | `risk_suitability_log` | 长期 | | 客户阈值 | C-04 自设亏损线 | `customer_threshold_config` | 长期 | | 客户提醒 | 阈值/波动提醒发送记录 | `customer_notify_log` | 长期 | | 代理人草稿 | 话术/跟进草稿 | `advisor_draft` | 长期 | | 违规命中 | A-07 合规词库 | `compliance_hit_log` | 长期 | | 分析留痕 | NL→SQL→解读 | `analytics_query_log` | 长期 | ### 5.2 MySQL 不存什么? | 不存 | 改存 | 原因 | | --- | --- | --- | | 产品手册全文块(大段 PDF 文本) | Milvus chunk + 本地 `data/kb/` | 体积大、要语义检索 | | 客户-产品-持仓 **关系遍历** | Neo4j | 图遍历更高效 | | 持仓/流水 **权威金额** | Core 只读 API | 禁止 Agent 各算一套 | | 当前对话「最近 5 轮」窗口 | Redis | 临时、TTL | --- ## 6. Milvus:知识库记忆放什么? Milvus = **按意思找文档**,不是存对话、不是存客户画像。 | 放什么 | Collection | 典型场景 | | --- | --- | --- | | 基金产品手册、费率、申赎规则、风险说明 | `kb_product_rules` | C-02, C-03, A-02 | | 内部办事流程、办理条件 | `kb_business_ops` | A-04 | | (P1)合规话术规范模板 | `kb_compliance_scripts` | A-03 | **每条向量记录应包含:** `chunk_text`、`embedding`(1024 维 bge-m3)、`source_doc_id`、`source_version`、`product_id` 等(见 [03-milvus-collections.md](../项目框架设计/表设计/03-milvus-collections.md))。 **本地文件:** 原始 PDF/Word 在 `data/kb/`(不用 MinIO);Milvus 存切块与向量,MySQL 可选存文档版本索引(P1)。 **不放 Milvus:** - 聊天记录、审计日志 - 客户 L1/L2/L3 画像 JSON - 预警单、适当性结果 --- ## 7. Neo4j:关系记忆放什么? Neo4j = **关系网**,回答「谁持有啥、产品要什么等级、归哪个代理人管」。 | 放什么 | 节点/关系 | 典型场景 | | --- | --- | --- | | 客户、代理人、产品、风险等级、行业 | `Customer`, `Advisor`, `Product`, `RiskGrade` | 全 Agent 关系查询 | | 客户归属代理人 | `Customer -[:ASSIGNED_TO]-> Advisor` | F-01 归属(与 MySQL rel 表一致) | | 客户正式风险等级 L0 | `Customer -[:HAS_RISK_LEVEL]-> RiskGrade` | R-02 | | 持仓关系(同步快照) | `Customer -[:HOLDS]-> Product` | C-01, A-01, R-01 | | 产品最低适配等级 | `Product -[:REQUIRES_MIN_RISK]-> RiskGrade` | R-02 | **同步原则:** 金额、`as_of` 来自 Core 同步 Job;**Agent 写 L1/L2/L3 不进 Neo4j**,避免双写。 **不放 Neo4j:** - 会话、消息、审计 - 向量、RAG 文档 - 画像 JSON 字段 --- ## 8. Core 与本地文件 | 存储 | 放什么 | Agent 权限 | | --- | --- | --- | | **Core** | L0 正式档案、持仓、流水、交易、行情/净值 | **只读** | | **本地 `data/kb/`** | 原始制度/产品 PDF、Word | 平台入库用;Agent 通过 Milvus 检索 | | **本地 `data/milvus.db`** | Milvus Lite 文件 | 向量索引文件,非业务表 | --- ## 9. 决策流程:新数据放哪儿? ```text 新产生一条数据 │ ┌───────────────┼───────────────┐ ▼ ▼ ▼ 是否官方账事实? 是否多轮对话临时态? 是否文档/RAG? │ │ │ 是 是 是 │ │ │ ▼ ▼ ▼ Core 只读 Redis(TTL) Milvus + data/kb/ 不在 Agent 建表 + MySQL 消息归档 + source 溯源字段 │ │ 否 否 │ │ └───────┬───────┘ ▼ 是否需要审计 / 跨 Agent 共享? │ ┌────────┴────────┐ 是 否 ▼ ▼ MySQL 是否关系遍历? (选对 L1/L2/L3 │ 或业务表) ┌─────┴─────┐ 是 否 ▼ ▼ Neo4j 重新评估 (Core 同步) 是否其实该进 MySQL ``` ### 9.1 快速对照(常见误区) | 误区 | 正确做法 | | --- | --- | | 聊天记录只放 Redis | Redis 窗口 + **MySQL 全量归档** | | 画像只放 Redis | **MySQL 权威** + Redis 热缓存 | | 产品规则塞 MySQL TEXT | **Milvus** 向量检索 + 溯源 ID | | 持仓金额以 Neo4j 为准 | **Core 为准**;Neo4j 是同步快照 + 关系 | | 预警状态放 Redis | **MySQL `risk_alert`**;Redis 只做 Pub/Sub 通知 | | 四 Agent 共享记忆靠互相调 LLM | **统一 MySQL 画像/预警表** + RBAC | --- ## 10. 四 Agent × 记忆读写(摘要) | Agent | 短期(Redis 写) | 权威(MySQL 写) | 只读 | | --- | --- | --- | --- | | 客户财富 | 会话窗口 | L1、阈值、提醒日志、会话消息 | Core、Milvus 产品库、L3 不可见 | | 代理人助手 | 会话、快照缓存 | L2、草稿、合规命中 | L1/L3、Core、Milvus | | 数据分析 | 会话窗口 | 分析 SQL 留痕 | 画像 L1/L2/L3、预警、Core | | 风控监测 | dedup、Pub/Sub | L3、预警、适当性 | L0/L1/L2、Core、Neo4j | 详细矩阵见 [05-多Agent共用底座清单.md](../项目框架设计/表设计/05-多Agent共用底座清单.md) §九。 --- ## 11. 一致性与失效策略 | 场景 | 策略 | | --- | --- | | Redis 挂了 | 从 MySQL 拉最近消息续聊;画像直接读 MySQL;服务降级 | | MySQL 与 Redis 画像不一致 | **以 MySQL 为准**;修复后 DEL Redis Key | | Milvus 与本地文件不一致 | 以 `source_version` 为准;A-09 知识库校验 | | Neo4j 与 Core 不一致 | **以 Core 为准**;重跑同步 Job | | 文档更新 | 重新 parse → embed → 写 Milvus;旧 version 过滤不返回 | --- ## 12. 与代码模块的对应(app/) | 模块 | 记忆职责 | | --- | --- | | `memory_service.py` | Redis 会话/画像缓存;MySQL 会话与画像落盘 | | `rag_service.py` | Milvus 检索 + 溯源 | | `agent_service.py` | 编排上下文(读 Redis/MySQL);不写错层 | | `milvus_tool.py` | Collection CRUD | | `repository/core_ro.py` | Core 只读 + R-02 适当性计算 | | `model/suitability.py` | check_suitability → risk_suitability_log 行映射 | --- ## 13. 验收检查(记忆管理) - [ ] 任意一条对话可在 MySQL 按 `trace_id` 还原,不仅靠 Redis - [ ] Redis TTL 过期后,续聊仍可从 MySQL 恢复最近上下文 - [ ] L1 更新后,`profile:l1:*` 被失效 - [ ] 产品回答带 `source_doc_id`,来自 Milvus 而非模型幻觉 - [ ] 持仓金额展示与 Core 一致;Neo4j 仅作关系辅助 - [ ] 审计表无 UPDATE/DELETE 业务路径 --- ## 14. 关联文档 | 文档 | 内容 | | --- | --- | | [02-redis-keys.md](../项目框架设计/表设计/02-redis-keys.md) | Redis Key 明细 | | [01-mysql-共用底座.sql](../项目框架设计/表设计/01-mysql-共用底座.sql) | 共用表 DDL | | [02-mysql-agent专用.sql](../项目框架设计/表设计/02-mysql-agent专用.sql) | 专用表 DDL | | [03-milvus-collections.md](../项目框架设计/表设计/03-milvus-collections.md) | 向量 Collection | | [04-neo4j-model.md](../项目框架设计/表设计/04-neo4j-model.md) | 图模型 | | [数据交互矩阵.md](../需求拆解/数据交互矩阵.md) | 跨 Agent 数据对象 | | [06-用户画像L1-L3设计.md](../项目框架设计/表设计/06-用户画像L1-L3设计.md) | 画像 JSON 约定 | | [07-risk_suitability_log说明.md](../项目框架设计/表设计/07-risk_suitability_log说明.md) | R-02 落库契约 | | [FRAMEWORK.md](../memory/FRAMEWORK.md) | 项目框架快照 | | [FLOW.md](../memory/FLOW.md) | 端到端链路 | --- ## 附录:记忆类型 × 存储 × 示例一句 | 记忆类型 | 存储 | 示例 | | --- | --- | --- | | 短期对话态 | Redis | 「这一轮用户在问 C-02 基金费率」 | | 长期对话档案 | MySQL | 「2026-09-05 14:03 客户问了 XX 基金申赎规则」 | | 客户偏好 | MySQL L1 + Redis 缓存 | 「风格偏价值;亏损 10% 要提醒」 | | 服务记录 | MySQL L2 | 「客户近期关注赎回;待跟进电话」 | | 监测标签 | MySQL L3 | 「监测分层:关注;最近有大额预警」 | | 产品知识 | Milvus | 「某基金封闭期 18 个月(chunk + 出处)」 | | 持有关系 | Neo4j | 「客户 A 持有产品 P1、P2」 | | 真实持仓金额 | Core | 「截至 T 日市值 100 万」 | | 合规审计 | MySQL | 「trace-xxx:代理人查客户 B 被拒绝,AUTH_403」 |