Version: 0.9.12.dev.260410
后端: 1. chat 路由新增“二次粗排硬闸门”,避免粗排完成后的微调请求误触发再次 rough_build - 更新 node/chat.go:当上下文已存在 rough_build_done 且用户未明确要求“重新粗排/从头重排”时,强制关闭 needs_rough_build / needs_refine_after_rough_build;补充路由调试日志维度(needs_rough_build、allow_reorder、has_rough_build_done 等) - 更新 prompt/chat.go:补齐二次粗排强约束,明确“移动/微调/优化/均匀化/调顺序”默认走 refine,不再次触发 rough build 2. execute 历史分层与工具调用写回链路增强 - 更新 node/execute.go:next_plan 推进后写入 execute_step_advanced marker,供 prompt 按步骤边界归档 loop;新增统一 appendToolCallResultHistory,标准化 assistant tool_call + tool observation 配对写回 - 更新 node/execute.go:confirm accept 路径补齐 min_context_switch 顺序护栏,避免通过确认链路绕过“未授权打乱顺序”限制 - 更新 prompt/execute_context.go:ReAct 边界识别从 loop_closed 扩展到 loop_closed/step_advanced;执行态文案收敛为“existing 仅作事实参考不作为可移动目标”,并新增参数纪律提示 - 更新 service/agentsvc/agent_newagent.go:冷恢复重置时仅在 completed 场景补写 execute_loop_closed marker,保证下一轮上下文归档一致 3. 工具参数严格校验落地(禁止自造字段) - 新建 tools/arg_guard.go:新增 validateToolArgsStrict 白名单校验,未知字段直接报错(含 day_from/day_to -> day_start/day_end 提示) - 更新 tools/read_filter_tools.go:query_available_slots / query_target_tasks 接入参数白名单校验 - 更新 tools/compound_tools.go:spread_even 接入参数白名单校验 - 更新 prompt/execute.go:系统提示补齐“参数必须严格使用 schema 字段”强约束与非法别名示例 4. execute 范围护栏辅助能力预埋 - 更新 node/execute.go:新增步骤范围解析与日历参数解析辅助(周/天/周几提取、候选 day 估算、batch_move new_day 提取等),为后续步骤级范围拦截提供基础能力 5. 记忆模块方案文档升级(吸收 Mem0 机制) - 更新 memory/记忆模块实施计划.md:补充 Mem0 借鉴与取舍,新增 ADD/UPDATE/DELETE/NONE 决策状态机、UUID 映射防幻觉、JSON 容错链、threshold->reranker->fallback、三维隔离过滤与对应指标/测试项 6. 同步更新调试日志文件 - 更新 newAgent/Log.txt 前端:无 仓库:无
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
2. 兼容当前单体工程,不引入高风险拆分,不破坏现有聊天主链路。
|
||||
3. 复用现有 Outbox 异步基础设施,避免重复造轮子。
|
||||
4. 形成可直接用于面试讲述的架构故事线、指标体系与演示脚本。
|
||||
5. 在不增加过度复杂度的前提下,吸收 Mem0 中已被验证的关键机制(抽取、决策、检索、降级、防幻觉)。
|
||||
|
||||
## 2. 背景与约束
|
||||
|
||||
@@ -40,6 +41,21 @@
|
||||
1. 写入链路:候选抽取 -> 去重/冲突 -> 打分 -> 分流落库(MySQL/Milvus)。
|
||||
2. 读取链路:硬约束优先 -> 语义召回补充 -> 重排 -> 门控 -> 注入上下文。
|
||||
|
||||
### 3.4 借鉴 Mem0 的关键机制(已裁剪版)
|
||||
|
||||
1. 双阶段去重决策:先向量召回候选旧记忆,再由 LLM 决策 `ADD/UPDATE/DELETE/NONE`,而不是只靠相似度阈值硬判。
|
||||
2. UUID 映射防幻觉:把真实 `memory_id` 映射成临时整数给 LLM,回收结果时再反查,防止模型编造不存在 ID。
|
||||
3. 结构化输出刚性约束:抽取与决策都用 JSON 结构,失败时走 `extract_json -> normalize_facts` 容错链,不让解析失败直接污染主流程。
|
||||
4. 动作分型嵌入:嵌入接口显式传入 `memory_action`(`add/search/update`),为后续差异化 embedding 策略预留接口。
|
||||
5. 检索后处理标准化:`threshold 过滤 -> 可选 reranker -> 统一降级`,当重排器异常时保留向量原始排序并打告警日志。
|
||||
6. 多维隔离语义:统一采用 `user_id + agent_id + run_id` 三维过滤;在本项目映射为 `user_id + assistant_id + conversation_id`。
|
||||
|
||||
### 3.5 本项目明确不做(本轮)
|
||||
|
||||
1. 不做图记忆(Graph Memory)落地实现,仅预留扩展点,避免 3 天范围失控。
|
||||
2. 不做多 Provider 工厂体系,只保留单 Provider 可替换接口,后续再扩展。
|
||||
3. 不做独立 server 化记忆服务,先在单体内完成闭环与指标验证。
|
||||
|
||||
## 4. 3 天执行计划(可直接照着做)
|
||||
|
||||
## Day 1:把“可写入”打通(可靠入队 + 可追踪)
|
||||
@@ -64,13 +80,21 @@
|
||||
- `memory_jobs`
|
||||
- `memory_audit_logs`
|
||||
- `memory_user_settings`
|
||||
3. 新增 Outbox 事件:
|
||||
3. 新增配置对象(`memory config`):
|
||||
- 抽取 prompt、更新决策 prompt、阈值、是否启用 reranker、LLM 温度参数。
|
||||
- 默认采用低随机参数(`temperature/top_p` 低值)提高可复现性。
|
||||
4. 新增 Outbox 事件:
|
||||
- `memory.extract.requested`(v1)
|
||||
4. 在聊天后置持久化环节发布事件:
|
||||
5. 在聊天后置持久化环节发布事件:
|
||||
- 仅传轻量字段,避免超大 payload。
|
||||
5. 新增消费处理器:
|
||||
6. 新增消费处理器:
|
||||
- 只做任务入库,不做重型 LLM 调用。
|
||||
6. 启动期接线:
|
||||
7. 新增解析与标准化工具:
|
||||
- `extract_json()`:从模型输出中抽取 JSON(兼容代码块包裹)。
|
||||
- `normalize_facts()`:去重、去空、长度校验、非法项过滤。
|
||||
8. 新增决策状态机定义:
|
||||
- `ADD/UPDATE/DELETE/NONE` 的合法状态与动作映射。
|
||||
9. 启动期接线:
|
||||
- 在 `backend/cmd/start.go` 注册记忆事件处理器。
|
||||
|
||||
### Day 1 验收标准
|
||||
@@ -101,12 +125,16 @@
|
||||
- 置信度阈值。
|
||||
- 时间衰减权重。
|
||||
- 敏感级别检查。
|
||||
4. 新增最小管理接口:
|
||||
4. 增加“阈值 + 可选重排 + 降级”链路:
|
||||
- 阈值过滤作为第一道过滤。
|
||||
- `reranker` 失败时自动降级为原排序并记录原因码。
|
||||
5. 新增最小管理接口:
|
||||
- `GET /api/v1/memory/items`
|
||||
- `DELETE /api/v1/memory/items/:id`
|
||||
- `POST /api/v1/memory/settings`(开关)
|
||||
5. 完成首版日志埋点:
|
||||
6. 完成首版日志埋点:
|
||||
- 检索命中数、注入条数、门控丢弃原因。
|
||||
- 决策分布(ADD/UPDATE/DELETE/NONE 占比)。
|
||||
|
||||
### Day 2 验收标准
|
||||
|
||||
@@ -128,6 +156,7 @@
|
||||
- `VectorStore.Upsert()`
|
||||
- `VectorStore.Search()`
|
||||
- `VectorStore.Delete()`
|
||||
- `VectorStore.Get()`(为 UPDATE/DELETE 决策回查旧值)
|
||||
2. 对接 Milvus(可选):
|
||||
- collection 初始化。
|
||||
- 向量 + 元数据过滤检索。
|
||||
@@ -140,6 +169,9 @@
|
||||
- 5 分钟架构说明。
|
||||
- 3 个典型失败案例及兜底策略。
|
||||
- 未来迭代路线。
|
||||
5. 输出“借鉴 Mem0 但本地化裁剪”的对比说明:
|
||||
- 借鉴了什么。
|
||||
- 为什么暂时不做图记忆与多 Provider 工厂。
|
||||
|
||||
### Day 3 验收标准
|
||||
|
||||
@@ -158,31 +190,36 @@
|
||||
1. `id` bigint PK
|
||||
2. `user_id` bigint(必填)
|
||||
3. `conversation_id` varchar(64)(可空,表示全局用户记忆)
|
||||
4. `memory_type` varchar(32)
|
||||
4. `assistant_id` varchar(64)(可空,区分不同助手人格/技能域)
|
||||
5. `run_id` varchar(64)(可空,会话级隔离)
|
||||
6. `memory_type` varchar(32)
|
||||
- `preference`(偏好)
|
||||
- `constraint`(硬约束)
|
||||
- `fact`(事实)
|
||||
- `todo_hint`(近期提醒线索)
|
||||
5. `title` varchar(128)
|
||||
6. `content` text
|
||||
7. `normalized_content` text(去噪后)
|
||||
8. `confidence` decimal(5,4)(0~1)
|
||||
9. `importance` decimal(5,4)(0~1)
|
||||
10. `sensitivity_level` tinyint
|
||||
7. `title` varchar(128)
|
||||
8. `content` text
|
||||
9. `normalized_content` text(去噪后)
|
||||
10. `content_hash` varchar(64)(幂等去重)
|
||||
11. `confidence` decimal(5,4)(0~1)
|
||||
12. `importance` decimal(5,4)(0~1)
|
||||
13. `sensitivity_level` tinyint
|
||||
- 0 普通
|
||||
- 1 中敏
|
||||
- 2 高敏
|
||||
11. `source_message_id` bigint
|
||||
12. `source_event_id` varchar(64)
|
||||
13. `is_explicit` tinyint(1)(是否用户明确要求记住)
|
||||
14. `status` varchar(16)
|
||||
14. `source_message_id` bigint
|
||||
15. `source_event_id` varchar(64)
|
||||
16. `is_explicit` tinyint(1)(是否用户明确要求记住)
|
||||
17. `status` varchar(16)
|
||||
- `active`
|
||||
- `archived`
|
||||
- `deleted`
|
||||
15. `ttl_at` datetime(到期时间)
|
||||
16. `last_access_at` datetime
|
||||
17. `created_at` datetime
|
||||
18. `updated_at` datetime
|
||||
18. `ttl_at` datetime(到期时间)
|
||||
19. `last_access_at` datetime
|
||||
20. `created_at` datetime
|
||||
21. `updated_at` datetime
|
||||
22. `vector_status` varchar(16)(`pending/synced/failed`)
|
||||
23. `vector_id` varchar(128)(向量库主键映射)
|
||||
|
||||
索引建议:
|
||||
|
||||
@@ -190,6 +227,8 @@
|
||||
2. `(user_id, conversation_id, status, updated_at desc)`
|
||||
3. `(source_message_id)`(排查链路)
|
||||
4. `(ttl_at)`(过期清理)
|
||||
5. `(user_id, assistant_id, run_id, status, updated_at desc)`
|
||||
6. `(user_id, memory_type, content_hash)`(幂等去重)
|
||||
|
||||
## 5.2 `memory_jobs`(异步任务队列表)
|
||||
|
||||
@@ -206,25 +245,27 @@
|
||||
- `extract`
|
||||
- `embed`
|
||||
- `reconcile`
|
||||
7. `payload_json` longtext
|
||||
8. `status` varchar(16)
|
||||
7. `idempotency_key` varchar(128)
|
||||
8. `payload_json` longtext
|
||||
9. `status` varchar(16)
|
||||
- `pending`
|
||||
- `processing`
|
||||
- `success`
|
||||
- `failed`
|
||||
- `dead`
|
||||
9. `retry_count` int
|
||||
10. `max_retry` int
|
||||
11. `next_retry_at` datetime
|
||||
12. `last_error` varchar(2000)
|
||||
13. `created_at` datetime
|
||||
14. `updated_at` datetime
|
||||
10. `retry_count` int
|
||||
11. `max_retry` int
|
||||
12. `next_retry_at` datetime
|
||||
13. `last_error` varchar(2000)
|
||||
14. `created_at` datetime
|
||||
15. `updated_at` datetime
|
||||
|
||||
索引建议:
|
||||
|
||||
1. `(status, next_retry_at, id)`
|
||||
2. `(user_id, created_at desc)`
|
||||
3. `(source_event_id)`(幂等与追踪)
|
||||
4. `(idempotency_key)`(消费防重)
|
||||
|
||||
## 5.3 `memory_audit_logs`(审计日志)
|
||||
|
||||
@@ -274,17 +315,21 @@
|
||||
|
||||
1. `user_id`
|
||||
2. `conversation_id`
|
||||
3. `source_message_id`
|
||||
4. `source_role`
|
||||
5. `source_text`
|
||||
6. `occurred_at`
|
||||
7. `trace_id`
|
||||
3. `assistant_id`
|
||||
4. `run_id`
|
||||
5. `source_message_id`
|
||||
6. `source_role`
|
||||
7. `source_text`
|
||||
8. `occurred_at`
|
||||
9. `trace_id`
|
||||
10. `idempotency_key`
|
||||
|
||||
设计约束:
|
||||
|
||||
1. Payload 只放执行需要的最小字段。
|
||||
2. 大文本允许截断并保留摘要,防止消息膨胀。
|
||||
3. 必须包含幂等标识(如 `source_message_id + user_id`)。
|
||||
4. 过滤维度必须完整(`user_id + assistant_id + run_id`),避免跨会话串记忆。
|
||||
|
||||
## 7. 写入流程详细设计
|
||||
|
||||
@@ -295,12 +340,16 @@
|
||||
3. Outbox 消费处理器验证 payload。
|
||||
4. 处理器创建或幂等更新 `memory_jobs`(仅任务入库)。
|
||||
5. `memory/worker` 扫描 `pending` 任务并抢占为 `processing`。
|
||||
6. Worker 调用 LLM 执行“候选记忆抽取”。
|
||||
7. 执行标准化(时间归一化、实体归一化、噪声去除)。
|
||||
8. 执行冲突消解(同类偏好最新优先、互斥约束降权)。
|
||||
9. 计算分值(置信度、重要度、时效度)。
|
||||
10. 写入 `memory_items` 与审计日志。
|
||||
11. 触发向量化(同步或异步二选一)。
|
||||
6. Worker 调用 LLM 执行“候选事实抽取”(JSON 输出)。
|
||||
7. 执行 `extract_json -> normalize_facts` 容错标准化链路。
|
||||
8. 对每条候选事实做向量检索,召回 Top-K 旧记忆候选。
|
||||
9. 对召回结果执行“临时整数 ID 映射”,再交给 LLM 决策 `ADD/UPDATE/DELETE/NONE`。
|
||||
10. 根据决策执行写入动作:
|
||||
- `ADD`:新增 `memory_items` + 审计日志。
|
||||
- `UPDATE`:更新记录并保留历史旧值。
|
||||
- `DELETE`:软删除并记录删除原因。
|
||||
- `NONE`:不写入,仅记调试日志。
|
||||
11. 按决策动作触发向量同步(支持 `vector_pending`)。
|
||||
12. 成功后任务标记 `success`,失败按重试策略推进。
|
||||
|
||||
## 7.2 失败处理策略
|
||||
@@ -317,6 +366,7 @@
|
||||
1. 幂等键:`user_id + source_message_id + memory_type + normalized_content_hash`
|
||||
2. 同幂等键重复写入:更新 `updated_at`、提升访问热度,不新增重复条目。
|
||||
3. 由 Outbox 重试导致的重复消费必须无副作用。
|
||||
4. 对 UPDATE/DELETE 必须先校验目标 `memory_id` 是否存在且属于当前过滤域。
|
||||
|
||||
## 8. 读取流程详细设计
|
||||
|
||||
@@ -334,8 +384,9 @@
|
||||
- 低相关丢弃
|
||||
- 高敏过滤
|
||||
- 过期过滤
|
||||
6. 按 token budget 选择最终注入条目。
|
||||
7. 组装统一注入上下文,传给主模型生成回复。
|
||||
6. 执行阈值过滤后可选 reranker;若 reranker 异常则自动降级使用原排序。
|
||||
7. 按 token budget 选择最终注入条目。
|
||||
8. 组装统一注入上下文,传给主模型生成回复。
|
||||
|
||||
## 8.2 重排评分(建议公式)
|
||||
|
||||
@@ -383,6 +434,9 @@
|
||||
5. `memory_wrong_mention_rate`
|
||||
6. `memory_user_correction_rate`
|
||||
7. `chat_p95_latency_delta_with_memory`
|
||||
8. `memory_json_parse_fail_rate`
|
||||
9. `memory_decision_distribution`(ADD/UPDATE/DELETE/NONE)
|
||||
10. `reranker_fallback_rate`
|
||||
|
||||
## 10.2 日志与追踪
|
||||
|
||||
@@ -410,6 +464,10 @@
|
||||
3. 重排评分函数。
|
||||
4. 门控函数。
|
||||
5. 幂等去重函数。
|
||||
6. `extract_json` 容错解析函数。
|
||||
7. `normalize_facts` 标准化函数。
|
||||
8. UUID 映射与反查函数。
|
||||
9. `ADD/UPDATE/DELETE/NONE` 决策结果校验函数。
|
||||
|
||||
## 12.2 集成测试范围(实现阶段)
|
||||
|
||||
@@ -450,7 +508,9 @@
|
||||
1. “我们做的是同步快路径 + 异步慢路径。同步保证下轮可用,异步负责治理和质量。”
|
||||
2. “结构化事实放 MySQL 保证可控可审计,语义联想放 Milvus 提高召回覆盖。”
|
||||
3. “Outbox 保证事件可靠入队,Worker 解耦重计算,避免阻塞主链路。”
|
||||
4. “我们用命中率、误提率、纠正率三项核心指标验证记忆是否真的有价值。”
|
||||
4. “借鉴 Mem0 的双阶段策略:先向量召回旧记忆,再让 LLM 决策 ADD/UPDATE/DELETE/NONE,兼顾召回率与准确率。”
|
||||
5. “我们用 UUID 映射防止模型伪造 ID,并且用 JSON 容错链保证抽取稳定性。”
|
||||
6. “我们用命中率、误提率、纠正率和 reranker 降级率验证记忆是否真的有价值。”
|
||||
|
||||
## 15. DoD(完成定义)
|
||||
|
||||
@@ -471,7 +531,28 @@
|
||||
2. 再做 Day 2 的读取注入,优先 MySQL 结构化记忆。
|
||||
3. 最后补 Day 3 的 Milvus 与指标,确保面试讲述闭环。
|
||||
|
||||
## 17. Mem0 借鉴清单与取舍结论(本轮新增)
|
||||
|
||||
### 17.1 直接借鉴
|
||||
|
||||
1. `ADD/UPDATE/DELETE/NONE` 统一决策状态机。
|
||||
2. `threshold -> reranker(可选) -> fallback` 的检索后处理套路。
|
||||
3. 三维过滤隔离(`user_id/agent_id/run_id`)的语义边界设计。
|
||||
4. 历史追踪思路(本项目落在 `memory_audit_logs`)。
|
||||
5. 低随机参数 + JSON 输出约束,提升可复现性。
|
||||
|
||||
### 17.2 延后借鉴
|
||||
|
||||
1. 图记忆(关系三元组与软删除)延后到 V2/V3。
|
||||
2. 多 Provider 工厂体系延后到“需要跨云/跨模型”时再上。
|
||||
3. 托管 API 平台化能力延后到单体稳定后再拆。
|
||||
|
||||
### 17.3 不照搬的原因
|
||||
|
||||
1. 当前目标是 3 天可演示 MVP,优先“稳定可讲”而非“能力最全”。
|
||||
2. 项目已有 Outbox 可靠链路,先最大化复用,避免架构重复。
|
||||
3. 日程助手是强约束场景,结构化事实主库优先级高于图谱表达能力。
|
||||
|
||||
---
|
||||
|
||||
本文件定位为“落地执行蓝图”。后续每完成一块能力,建议在本文件追加“已落地清单 + 待办差距”,持续收敛为真实实施记录。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user