docs: define profile projection protocol

This commit is contained in:
张胜宇
2026-09-11 19:24:57 +08:00
parent 1eb04f28b1
commit 2de1735673
@@ -0,0 +1,109 @@
# 客服 Agent 二期:画像投影协议 v1
版本:v1.0
适用分支:`ZSY_develop2`
状态:实现前冻结的最小协议
## 1. 目标与边界
本协议只规定管理员批准后的 `profile_snapshots` 如何异步投影到 Milvus 和 Neo4j。
MySQL 是画像权威库,`memory_sync_outbox` 是可靠投递队列;外部存储不得反向覆盖 MySQL。
客服 Agent 当前仍不读取长期画像,不读取持仓、收益、订单、银行卡、投诉进度或正式风险等级。
本协议不改变客服回答权限,也不开放个人账户查询能力。
## 2. 事件输入
每个画像版本在同一 MySQL 事务内写入两条 `memory_sync_outbox`:
- `aggregate_type=profile_snapshot`
- `aggregate_uuid=profile_uuid`
- `aggregate_version=profile_snapshots.version`
- `target_store=milvus` 或 `neo4j`
- `operation=upsert`
事件 `payload` 至少包含:
```json
{
"customer_id": 123,
"profile_uuid": "跨存储稳定 UUID",
"profile_version": 2,
"snapshot": {
"customer_service_preferences": {
"preference:risk_level": {
"value": "稳健型",
"memory_type": "preference",
"confidence": 0.9
}
}
}
}
```
消费者必须校验 `customer_id`、`profile_uuid`、正整数 `profile_version` 和对象类型的
`snapshot`;字段缺失或结构不合法时事件失败重试,不能标记为成功。
## 3. Milvus 投影
集合固定为 `user_long_term_memory_v1`,不按客户创建集合或分区。每条记忆使用
`memory_uuid` 作为主键,并强制携带 `customer_id` 标量过滤字段。
| 字段 | 规则 |
|---|---|
| `memory_uuid` | 来自正式 `memory_unit.memory_uuid`;画像版本事件若只提供 `profile_uuid`,实现前必须补齐来源记忆映射,不得把画像 UUID 猜作记忆 UUID |
| `customer_id` | 仅用于同客户过滤,不得省略 |
| `content` | 仅保存脱敏后的偏好/目标文本,不保存原始对话和凭据 |
| `embedding` | 使用已批准的 Embedding 端点生成,维度固定后校验 |
| `memory_type` / `memory_key` | 使用 MySQL 正式记忆字段 |
| `confidence` / `version` | 版本较低的事件不得覆盖较高版本 |
| `status` | `active`、`archived` 或 `deleted` |
| `valid_until_ts` / `updated_at_ts` | 使用 UTC 时间戳;无值时保持为空 |
因此,当前 `profile_snapshots` 事件还需要补充“快照内存记忆来源映射”或改为按
`memory_unit` 生成事件,才能安全执行 Milvus upsert。未补齐前不得写入画像向量。
## 4. Neo4j 投影
Neo4j 只保存关系推理所需的最小投影,不作为交易、持仓或风险等级权威库。
### 4.1 节点
- `Customer {customer_id, profile_version, updated_at}`
- `Preference {customer_id, key, value, memory_uuid, version}`
- `Goal {customer_id, key, value, memory_uuid, version}`
节点不得包含身份证号、手机号、银行卡号、密码、验证码、完整原始对话或精确账户余额。
### 4.2 关系
- 偏好:`(Customer)-[:PREFERS]->(Preference)`
- 目标:`(Customer)-[:HAS_GOAL]->(Goal)`
关系必须带 `memory_uuid`、`confidence`、`version`、`valid_from`、`valid_until`(可空)。
关系类型只能来自 `RelationshipService.ALLOWED_RELATIONSHIPS`,禁止模型提供任意 Cypher
或关系名称。
### 4.3 版本与幂等
- 以 `customer_id + profile_version` 做版本门禁;低版本事件只记录已跳过,不覆盖高版本。
- 同一 `event_uuid` 重复消费必须返回幂等结果,不重复创建节点或关系。
- 事件成功后才将 `memory_sync_outbox.status` 置为 `processed` 并写入 `processed_at`。
## 5. 失败与重试
- 外部连接、认证、超时和写入异常:保留事件,按指数退避重试;达到 5 次进入 `dead` 并告警。
- 参数、结构或权限错误:记录明确错误原因并进入死信,不伪造成功。
- Milvus 与 Neo4j 独立消费,单边失败不得影响另一边,也不得回滚 MySQL 权威画像。
- 删除/失效使用独立墓碑事件,不能通过 `upsert` 事件隐式删除历史投影。
## 6. 实施顺序
1. 补齐画像事件中的正式 `memory_uuid`、记忆键、类型、置信度和有效期映射。
2. 实现 Neo4j 投影适配器,先完成版本门禁、参数化 Cypher 和幂等测试。
3. 按批准的 Embedding 端点和集合 schema 实现 Milvus upsert;先在 Lite 环境验证维度和字段。
4. 实现 `memory_sync_outbox` 消费者、失败重试和死信告警。
5. 使用真实 Neo4j 与 Milvus 执行端到端联调,再更新二期验收记录。
在第 1 步完成前,不把当前画像快照直接写成一个“画像向量”冒充长期记忆,避免破坏
`memory_uuid` 回表和客户隔离约束。