user-memory 运行分析报告

🔍 user-memory 运行分析报告(2026-09-17)

第一部分:quickstart.py 运行分析(notes 模式)

运行日期:2026-09-17 | 分析对象:quickstart_user 的一次 quickstart 演示运行

1. 运行环境与命令

项目
命令 python quickstart.py(在 chapter3/user-memory 目录,PowerShell)
运行时段 2026-09-17 16:10:44 → 16:12:11(约 1.5 分钟)
用户 / 记忆模式 quickstart_user / notes
LLM Provider doubao (火山方舟),模型 deepseek-v4-flash-ga-260731(来自 .envARK_MODEL
日志文件 logs/quickstart_20260917_161044.logquickstart.pyTee 同时写控制台与文件)
处理策略 conversation_interval=1每轮对话后立即处理记忆

2. 系统架构(分离式)

quickstart.py 初始化了两个解耦组件:

  • ConversationalAgentconversational_agent.py):只管对话,通过 _get_memory_context() 读取记忆注入 prompt,从不直接写记忆;
  • BackgroundMemoryProcessorbackground_memory_processor.py):对话落盘后,用内置的 UserMemoryAgent 分析最近 turn,通过 add_memory / update_memory / delete_memory 工具调用写记忆。

3. 运行轨迹逐步还原

两个会话共 5 轮成功对话(存于 data/conversations/quickstart_user_history.json):

轮次 时间 会话 用户输入 助手行为 记忆处理结果
S1·R1 16:10:54 session-830fe6d8 自我介绍 未被告知就"知道" JAX 推荐系统、深色主题、类型注解 ⚠️ 1 条 DELETE(目标未知),0 add / 0 update
S1·R2 16:11:16 同上 在用 PyTorch 察觉与记忆中 JAX 矛盾,反问确认 📝 UPDATE 笔记 e41d7593 → PyTorch(16:11:27)
S1·R3 16:11:41 同上 深色主题 + 类型注解 正常附和 ✅ 记忆已存在,无需更新
S2·R1 16:11:53 session-67a5a55b(reset_session 新会话) 你记得我的工作和偏好吗 完整召回 4 条记忆(工作/兴趣/偏好) ✅ 无更新
S2·R2 16:12:07 同上 已从 PyTorch 切到 JAX 确认并追问迁移细节 📝 UPDATE 同一笔记 → JAX(16:12:11)
S2·R3 16:12:11 后 同上 根据对我的了解推荐工具 API 流式错误peer closed connection... (incomplete chunked read),返回道歉文本 该轮未落盘,无新内容可处理

4. 记忆状态演化

data/memories/quickstart_user_memory.json 最终保留 4 条 notes

笔记 内容要点 标签 创建 关键动作
fc783ea8 软件开发者,爱 Python/ML profession, interests 15:16(上次运行) 无变化
e41d7593 推荐系统项目 project, ml, jax/pytorch 15:16 本轮被 UPDATE 两次(16:11→PyTorch,16:12→JAX)
c87e2d43 偏好深色主题 preference, tools 15:16 无变化
06128268 总是用类型注解 preference, coding style 15:16 无变化

5. 关键观察

✅ 正常工作的点(验证通过)

  1. 分离架构链路完整:对话 → 历史落盘 → 后台分析 → 记忆增删改 → 跨会话注入,全链路可用;
  2. 记忆跨运行持久化 :Session 1 是"新自我介绍",但助手第一句就引用 JAX 项目/深色主题------这些是 15:16 上一次运行的记忆 ,说明 enable_memory_context 与持久化生效;
  3. 矛盾信息的正确处理 :PyTorch↔JAX 两次方向相反的信息,分析 agent 均识别为 UPDATE(同一条笔记) 而非新建,无重复记忆;
  4. 错误韧性 :S2·R3 网络错误被 chat() 捕获返回道歉文本,进程不崩溃;且异常路径不调用 add_turn(见 conversational_agent.py),失败轮次未污染历史

⚠️ 值得关注的问题

  1. S1·R1 出现可疑 DELETE :日志显示 1. 🗑️ DELETE: ...,但最终 4 条笔记全部健在。由于 quickstart.py 第一段只打印 content(delete 操作只有 memory_id),删除目标被隐藏 。推测是分析 agent 针对上次运行的旧记忆发起的清理,但要么 id 失效失败、要么被后续逻辑抵消。建议检查 analysis_agent.tool_calls 轨迹确认是否误删。
  2. 演示脚本与持久记忆冲突:quickstart 的 Session 1 按"全新用户自我介绍"设计,但因记忆残留,助手在用户开口前就"知道"其全部信息,使 "intro & learning" 演示语义失真。建议启动时清空该用户记忆或使用独立 demo 用户。
  3. 同一笔记被来回改写 :note 2 在 1 分钟内被 PyTorch→JAX 反向改写两次。系统按"最近信息优先"工作正常,但没有置信度/时效衰减,用户反复横跳会反复覆盖记忆。
  4. 无重试机制 :S2·R3 的 chunked-read 错误直接失败,chat() 没有对偶发网络错误重试。

❓ 待确认

  • 记忆 created_at 为 15:16(比本次运行早 1 小时),但 data/conversations/quickstart_user_history.json 只含本次 5 条 turn。若 ConversationHistory 是跨运行追加(全量重写文件),上次运行(15:16)的 turn 应存在------它们去哪了?可能上次是直接写记忆、未走对话链路(如 memory_cli.py),需确认。

6. 结论与建议

结论:系统核心能力------分离式架构、每轮记忆处理、跨会话/跨运行持久化、矛盾信息更新、错误降级------均演示成功;本次运行净效果为 2 次 UPDATE + 1 次无效 DELETE,记忆最终收敛到正确状态(JAX)。

改进建议

  1. quickstart 开头清空用户记忆,避免"未卜先知"造成演示误导;
  2. 审计 S1·R1 的 DELETE 来源,防止分析 agent 误删有效记忆;
  3. 为流式 API 调用增加一次重试(如指数退避);
  4. 记忆操作日志记录完整 memory_idreason,便于审计。

第二部分:main.py demo 运行分析(enhanced_notes 模式)

命令:python main.py --mode demo --memory-mode enhanced_notes | 分析对象:demo_user 的一次 demo 演示运行 | 日志:logs/main.log

1. 运行环境与命令解析

项目 依据
命令 python main.py --mode demo --memory-mode enhanced_notes 用户命令行
运行时段 2026-09-17 16:24:25 → 16:25:01(对话落盘时间戳,全程约 40 秒) data/conversations/demo_user_history.json
用户 demo_user(demo 模式硬编码,--user 参数不生效) main.py L312
记忆模式 enhanced_notes (CLI 覆盖 .envMEMORY_MODE=notes 命令行参数
LLM Provider doubao.envPROVIDER=doubao,未指定 --provider .env
模型 deepseek-v4-flash-ga-260731--model 未指定 → doubao 分支读 .envARK_MODEL conversational_agent.py L112 / agent.py L121
网关 https://ark.cn-beijing.volces.com/api/coding/v3(方舟 coding 套餐端点) conversational_agent.py L110
处理策略 demo 内置 MemoryProcessorConfig(conversation_interval=2, min_conversation_turns=1, context_window=10)不启动后台线程 ,3 条消息后手动调用 process_recent_conversations() main.py L335-339、L371-376
日志 logs/main.logTee 同时写控制台与文件,append 模式跨运行累积) main.py L31-53

2. 日志结构:一次 --help + 一次 demo

main.log 为追加模式,当前文件包含两段记录:

内容 判定
第 1 段 📄 Logging output to: ... + 完整 usage/options 帮助文本,error: 此前执行过 python main.py --help(查参数用法);若是参数错误,argparse 会打印单行 usage + error: 行,与此不符
第 2 段 📄 Logging output to: ... + demo 横幅 + 完整演示输出 本次 --mode demo 成功运行

3. 运行轨迹逐步还原

时间戳取自 demo_user_history.json 落盘时间;S1 = session-f318f642,S2 = session-3ae5c769。

阶段 时间 会话 用户输入 助手行为 记忆处理
(上次运行残留) 15:05:25 session-bb31d066 同一套 Alice 演示消息(笔记内容与 demo 三条消息一一对应) --- 创建 3 条笔记(见 §5)
S1·R1 16:24:25 session-f318f642 自我介绍(姓名 + 职位) ⚠️ 未卜先知:回复已引用 Python/VS Code/深色主题/移动应用项目------均为 R2/R3 才说的内容 ---
S1·R2 16:24:31 同上 Python / VS Code / 深色主题 附和并主动贴合技术栈(Ruff/Pylance 等建议) ---
S1·R3 16:24:38 同上 移动应用项目 追问应用类型(B2B/消费/内部)与所处阶段 ---
记忆处理 ~16:24:39--16:24:5x --- --- ReAct 分析 agent 对比 3 轮对话与已有 3 条笔记 0 add / 0 update / 0 delete(判定无新信息,直接 STOP)
S2·R1 16:25:01 session-3ae5c769(reset_session() 新会话) "What do you know about me and my work?" 完整召回 3 条记忆(身份/偏好/项目),无幻觉 不处理(见 §6 问题 3)

LLM 调用合计 5 次 :S1 对话 3 次 + 记忆分析 1 次(0 次工具调用)+ S2 召回 1 次。全程零错误、零重试。

4. 记忆处理详情:一次"重复输入"的幂等性验证

日志中分析 agent 的 ReAct 最终答案(原文摘录):

"The existing memories already accurately capture all the factual information from this conversation: 1. Alice is a product manager at TechCorp --- confirmed (matches Note 1) 2. Python + VS Code + dark themes preferences --- confirmed (matches Note 2) 3. Mobile app project --- confirmed (matches Note 3). No new information was revealed... No memory changes are needed." → STOP

要点:

  • 分析 agent 的系统提示预载全部已有笔记 (USER MEMORIES 段),逐一比对后认定三组事实已被覆盖,未发起任何 add/update/delete 工具调用
  • process_recent_conversations()tool_calls 统计操作 → 空列表 → "No memory updates needed",summary 0/0/0;
  • 记忆文件零写入demo_user_memory.jsonupdated_at 仍停留在上次运行的 15:05:25.202175
  • 这是"重复运行同一 demo"场景的理想幂等表现------不产生重复或冲突记忆。

5. 记忆状态(3 条 enhanced 风格笔记,均为上次运行产物)

data/memories/demo_user_memory.jsontype: "notes",共 3 条):

笔记 ID(前 8 位) 内容要点 标签 创建时间
2ab1a691 Alice 是 TechCorp 产品经理;推断性扩展了 PM 职责(战略/路线图/干系人沟通/用户研究等) identity, work, TechCorp 15:05:25.186
e056988e Python 脚本 + VS Code + 深色主题;并注明"代码示例应贴合该技术栈" preferences, tools, coding 15:05:25.193
497da793 移动应用项目;元信息记录"应用类型与阶段尚未说明" work, project, mobile app 15:05:25.201

三条均为完整上下文段落(含推断与使用建议),符合 enhanced_notes 提示词风格(对比 notes 模式的"简单事实"风格)。

模式与存储的关系memory_manager.py L750-753):notesenhanced_notes 共用同一个 NotesMemoryManager (存储 type: "notes"),差异仅在分析 agent 的系统提示(agent.py L189-204:enhanced 要求"完整段落、完整上下文"并附示例)。因此无法从存储文件反推生成模式

6. 关键观察

✅ 正常工作的点(验证通过)

  1. 分离架构链路完整 :对话(ConversationalAgent 只读记忆)→ 历史落盘(每轮即写、tmp+原子替换)→ 后台分析(UserMemoryAgent 经 ReAct 工具调用写记忆)→ 跨会话注入;
  2. 跨运行持久化 :S1·R1 的"未卜先知"(回复引用 R2/R3 才说的偏好与项目)证明 15:05 运行的记忆经 _get_memory_context() 每轮从磁盘 reload 注入生效;
  3. 幂等性:输入信息与已有记忆完全重叠时,分析 agent 正确判断零操作、零写入;
  4. 跨会话召回质量:S2 新会话的"当前会话历史"为空,回复完全基于 3 条结构化记忆;全部命中、无幻觉,且保留笔记中 "likely" 的推断措辞(未把推测放大成事实);
  5. 会话隔离设计生效 :原始对话轮次只注入当前 session(get_session_turns),跨 session 信息必须走结构化记忆------S2 测试正是对这一设计的验证;
  6. 零错误:5 次 API 调用全部成功(对比 quickstart 运行的 1 次流式中断)。

⚠️ 值得关注的问题

  1. logging 落盘缺陷(本次新发现)main.log 中没有任何 logger.info 时间戳行(如 "User request: ...")。原因:conversational_agent.py L27、background_memory_processor.py L20、agent.py L28 均在模块级 调用 logging.basicConfig,而 main.py L15 先导入 conversational_agent → 其 basicConfig(仅 StreamHandler→原始 stderr)先生效 → main.py L57 带 FileHandler 的 basicConfig 因 root logger 已有 handler 而成为空操作 → logging 输出只到控制台原始 stderr,永不进 main.log。日志文件实际只含 print 输出(Tee 捕获)。
  2. demo 语义失真(残留记忆) :Session 1 设计意图是"从新用户对话中学习",但因 15:05 记忆残留,R1 起助手就"知道"全部信息,学习演示变成复述演示。建议 demo 开头清空 demo_user 记忆或使用独立用户 ID。
  3. S2 测试轮不进记忆管道 :demo 仅在 3 条消息后处理一次,S2 提问轮(第 4 轮)未经分析。本轮为纯查询无影响;且 processed_turn_ids 只在内存,下次运行会把它与新增轮次一并分析(context_window=10 覆盖 4+3=7 轮无压力),风险有限但应知晓。
  4. 沿袭 quickstart 报告的发现:无网络重试机制、记忆无置信度/时效衰减(本次场景未触发矛盾信息,未检验更新路径)。

7. 与 quickstart 运行对照(同日、同模型)

维度 quickstart(16:10,notes 模式) 本次 demo(16:24,enhanced_notes 模式)
对话轮次 5 4
记忆操作 2 次 UPDATE + 1 次可疑 DELETE 0 次
输入与记忆的关系 矛盾信息(PyTorch ↔ JAX 两次反转) 完全重叠(重复运行同一演示)
API 错误 1 次流式中断(chunked read) 0 次
验证路径 矛盾更新 / 错误降级 幂等 / 零操作 / 跨会话召回

两次运行互补:quickstart 检验了记忆的"改"路径,本次检验了"不改"路径,共同覆盖分离架构的主干行为。

8. 结论与建议

结论 :本次 demo 运行零错误完成了分离式记忆架构的全链路演示------跨运行持久化(S1 未卜先知)、重复输入幂等(分析 0 操作、记忆文件零写入)、跨会话召回(S2 完整准确)。同时暴露两个工程问题:logging 输出不落盘 (模块级 basicConfig 竞争)与 demo 残留记忆导致的演示语义失真

改进建议

  1. 修复 logging :移除三个模块级的 logging.basicConfig,统一只在入口 main.py 配置(或改用 logging.config.dictConfig),确保 FileHandler 生效、logger.infomain.log
  2. demo 前置清理demo_memory_system() 开头对 demo_user 调用 clear_all_memories()(或改用带时间戳的独立用户 ID),让 Session 1 真正演示"学习"、Session 2 演示"召回";
  3. (可选)S2 测试轮后再触发一次 process_recent_conversations(),使演示对话全部进入记忆管道;
  4. 沿袭第一部分建议:为流式 API 增加一次退避重试;记忆操作记录完整 memory_idreason 便于审计。

第三部分:main.py evaluation 模式运行分析(layer1_01_bank_account)

命令:python main.py --mode evaluation --memory-mode advanced_json_cards(运行一)/ --memory-mode json_cards(运行二)/ --memory-mode notes(运行三)/ --memory-mode enhanced_notes(运行四)| 分析对象:default_user 的四次评测运行 | 日志:logs/main_20260917_164330.log + logs/main_20260917_164913.log + logs/main_20260917_165228.log + logs/main_20260917_175010.log

1. 运行环境与四次运行概览

同日对同一用例 layer1_01_bank_account(Bank Account Setup - Personal Details Retrieval,layer1 类)先后做了四次评测,构成四种记忆模式的直接对照:

项目 运行一(advanced_json_cards) 运行二(json_cards) 运行三(notes) 运行四(enhanced_notes)
日志文件 logs/main_20260917_164330.log logs/main_20260917_164913.log logs/main_20260917_165228.log logs/main_20260917_175010.log
启动时间 2026-09-17 16:43:30 2026-09-17 16:49:13 2026-09-17 16:52:28 2026-09-17 17:50:10
命令 python main.py --mode evaluation --memory-mode advanced_json_cards(控制台确认) python main.py --mode evaluation --memory-mode json_cards(控制台确认) python main.py --mode evaluation --memory-mode notes(控制台确认) python main.py --mode evaluation --memory-mode enhanced_notes(控制台确认)
用户 default_user(evaluation 模式固定) 同左 同左 同左
被测 Agent 模型 deepseek-v4-flash-ga-260731(.env PROVIDER=doubao / ARK_MODEL) 同左 同左 同左
评委模型 deepseek-v4-pro.env 末尾 KIMI_BASE_URL=方舟 coding 网关 + KIMI_MODEL=deepseek-v4-pro,评委强于被测) 同左 同左 同左
测试用例 layer1_01_bank_account(1 段 47 分钟通话,90 条消息,45 轮问答) 同左 同左 同左
记忆生成 10 张 advanced 卡(1 轮 ReAct,10 个并行工具调用全部成功) 9 次 add_memory(2 轮 ReAct:8 + 1),落盘 8 张(1 次同秒 ID 冲突覆盖) 11 条 notes(1 轮 ReAct,11 个并行工具调用全部成功,uuid 键无冲突) 4 条大合集笔记(1 轮 ReAct,4 个并行工具调用全部成功,uuid 键无冲突)
Agent 作答 账号 4429853327 + 路由 123006800 + Premium Checking ✅ 同样正确 ✅ 同样正确 ✅(最简洁风格) 同样正确 ✅
评测结果 ✅ PASSED,Reward 1.000/1.000 ✅ PASSED,Reward 1.000/1.000 ✅ PASSED,Reward 1.000/1.000 ✅ PASSED,Reward 1.000/1.000
结束操作 菜单选 4 正常退出 误输入 "E" 一次(Invalid choice),再选 4 退出 菜单选 4 正常退出 菜单选 4 正常退出

2. 评测流程还原(main.py run_evaluation_mode,L418-763)

四次运行走完全相同的五阶段流水线:

  1. 清场 (L555-596):对 agent / processor 两个 memory_manager 各调 clear_all_memories(),清空两个 conversation_history 并落盘,重置 agent.conversation 与系统提示------保证用例之间零残留(对比第二部分 demo 的残留问题,评测模式不存在此隐患);
  2. 灌入对话 (L599-634):把用例 YAML 的 90 条消息重建为对话上下文,并按 user/assistant 成对写入 conversation_history(session 前缀 eval_bank_setup_001);
  3. 记忆处理 (L635-651):processor.process_conversation_batch() 触发 ReAct 分析 agent 读对话 → 工具调用直接写记忆;
  4. 新会话作答 (L653-698):清空对话历史模拟全新会话agent.memory_manager.load_memory() 从磁盘重载 processor 刚写的卡片(两者是独立实例,必须经文件中转),此时 Agent 只能依赖结构化记忆作答------这正是实验要测的"记忆而非历史回放";
  5. 评委打分 (L704-728):framework.submit_and_evaluate() 由评委 LLM 按 4 维评分。

Reward 计算口径user-memory-evaluation/evaluator.py L282-306):reward = Σ(score-1)/3 ÷ 4(precision/recall/reasoning/proactivity 四维各 1-4 分);hallucination 为一票否决 (detected → reward 强制 0);passed 要求核心三维(precision/recall/reasoning)全部 ≥3。本次四次运行 reward=1.000,可反推四维全部 4 分(excellent)且无幻觉。评委温度:deepseek-v4-pro 不含 kimi/gpt-5 关键字 → temperature=0(evaluator.py L56-61)。

3. 运行一轨迹:advanced_json_cards(16:43:30)

3.1 记忆生成------单轮 ReAct、10 张结构化卡片

分析 agent 一次 LLM 调用产出 10 个并行 add_memory(全部 JSON 卡片格式),执行全部成功后收尾输出 STOP。卡片清单:

# memory_id(category.card_key) 内容要点
1 personal.identity_michael_robertson 姓名 / DOB 1985-03-15 / SSN / 俄勒冈驾照 D758392 / 出生于丹佛
2 personal.contact_info_michael_robertson 枫树街住址(2.5 年)/ 手机 / 邮箱
3 financial.employment_income_michael TechCorp 软件工程师、4 年、$125K/年
4 financial.checking_account_first_national Premium Checking #4429853327、路由 123006800、最低余额 2,500、权益费率、初始存 5,000
5 financial.savings_account_first_national Basic Savings #4429853328、100 最低、每月 15 日 200 自动转存、透支保护
6 financial.previous_bank_wells_fargo Wells Fargo #8847293001 / 路由 121000248(转账来源行)
7 financial.debit_card_pin_michael 借记卡 PIN 4827、7-10 天寄达、3% 境外费
8 financial.online_banking_michael 用户名 MRobertson503、手机银行、客服电话
9 personal.security_questions_michael 三组安全问题答案
10 preferences.preferences_michael 电子账单、标准支票、国际出差、CashBack 卡意向

观察:每个账户一个独立卡片 ,FNB 路由号与 Wells Fargo 路由号分属两卡、无混淆风险;每卡含 person/relationship/backstory 元字段(advanced 提示词强制,agent.py L228 起),为 layer2/3 多人多账户场景预留的消歧设计在本单人称例中冗余但无害。

3.2 作答与评测

用户问题:"What was my checking account number again? I need it to set up my direct deposit at work."

Agent 回答命中全部要点:4429853327 (与储蓄账号 4429853328 正确区分)+ 主动补 routing 123006800(评委提示词中 proactivity 维的示例恰好就是"direct deposit 时附上 routing number")。

评委结论(原文):"The agent accurately recalled and provided the requested checking account number, correctly distinguished it from the savings account number, and included the routing number specifically relevant to the user's stated direct deposit purpose. The response is precise, complete for the question, and adds safely relevant assistance without hallucination."PASSED,1.000/1.000

4. 运行二轨迹:json_cards(16:49:13)

4.1 记忆生成------2 轮 ReAct、9 次 add、落盘 8 张、1 次静默覆盖

第一轮 8 个工具调用 + 第二轮 1 个补充调用。模型没有按 json_cards 提示词输出 JSON (提示词示例为 {"category","subcategory","key","value"}agent.py L206-226),而是输出"标签: 内容"式纯文本,全部落入 _tool_add_memory遗留回退路由agent.py L458-476):

执行序 内容摘要 回退路由结果 落盘 memory_id
#1 "Full name: ..." 首冒号前作 key personal.info.full_name
#2 "Address: ..." 同上 personal.info.address
#3 "Employed ... Annual income: ..." 首冒号在句尾 → 150 字符病态长键 personal.info.employed_full-time_as_a_software_engineer_at_techcorp...
#4 "Opened Premium Checking ... Initial deposits: ..." 同上 personal.info.opened_premium_checking_account_(#4429853327)_...
#5 "Existing bank: Wells Fargo ..." 首冒号前作 key personal.info.existing_bank
#6 "Set up $200/month automatic transfer ... direct deposit ..."(无冒号 → general.notes.note_20260917_164954 ⚠️ 被 #8 覆盖丢失
#7 "Account security answers: ..." 首冒号前作 key personal.info.account_security_answers
#8 "Travels internationally ..."(无冒号,与 #6 同秒 16:49:54) → general.notes.note_20260917_164954 同 key 静默覆盖 #6
#9(第二轮) "Customer of FNB since ... "(无冒号,16:50:02) → general.notes.note_20260917_165002 唯一存活的 note 之一

磁盘终态(data/memories/default_user_memory.json,type=json_cards)与上表一致:6 张 personal.info + 2 条 general.notes = 8 张(9 add − 1 覆盖)。

4.2 数据丢失链路(根因三连)

  1. 提示词未强制 JSON :模型选择纯文本 + tags,json.loads 失败走回退(agent.py L450-458);
  2. 病态键生成 :回退按第一个冒号 切分,"Annual income" 之类冒号出现在句尾时,整句主语全部塌缩进 key(parts[0].strip().replace(' ', '_').lower()agent.py L463),就业卡最终 key 含公司/职位/年限 150 字符,value 只剩 "~$125,000 before taxes"------信息还在但结构倒置 ,后续 update_memory 按此 ID 操作几乎不可用;
  3. 同秒 note ID 冲突 :无冒号内容用 note_%Y%m%d_%H%M%S 秒级时间戳作 key(agent.py L468),#6/#8 同在 16:49:54 执行 → 同 key → memory_cards[category][subcategory][key] = {...}(memory_manager.py L426)静默字典覆盖,无任何告警$200/月自动转存 + TechCorp 直接存款这条笔记永久丢失(当前用例无碍:该信息在 #4 FNB 卡有冗余副本;但多账户场景这是真数据丢失)。

4.3 作答与评测

Agent 回答同样正确(4429853327 + 123006800 + Premium Checking),并附加"给雇主两个号都要提供 / 勿公开泄露"的安全建议。评委:"...distinguishes checking from savings, and adds direct-deposit-relevant and safety information without fabricating facts."PASSED,1.000/1.000

5. 运行三轨迹:notes(16:52:28)

5.1 记忆生成------单轮 ReAct、11 条 uuid 键笔记

分析 agent 一次 LLM 调用产出 11 个并行 add_memory(纯文本 + tags,正是 notes 模式的预期形态),全部成功,收尾 STOP。与 json_cards 的秒级时间戳键不同,NotesMemoryManager 用 uuid4 作 note_id (memory_manager.py L162-165),天然无同秒冲突风险

# 内容要点 tags
1 姓名 / DOB / 住址(2.5 年)/ 出生于丹佛 personal, identity, address
2 手机 / 邮箱 contact
3 TechCorp 软件工程师 ~4 年、$125K employment, income
4 SSN + 俄勒冈驾照(身份核验单列) identity, verification
5 Premium Checking #4429853327、路由 1230068002,500 最低、0.5% APY、初始 5,000 banking, checking-account
6 Basic Savings #4429853328、100 最低、初始 500、每月 15 日 $200 自动转存 banking, savings-account
7 网银用户名 / 手机银行 / 电子账单 / 标准支票 / 借记卡 PIN 4827 banking, online-banking
8 安全问题三答案 security, verification
9 Wells Fargo #8847293001 / 路由 121000248 banking, previous-bank
10 国际出差、3% 境外费、暂不加旅行通知 travel, preferences
11 CashBack 卡意向(2% 返现 / $95 首年免) banking, credit-card, interest

观察:颗粒度四次中最细(11 条) ------checking 与 savings 分立、身份核验单列,信息切分与 advanced 卡基本同构且零丢失;笔记落盘时间 16:52:59(启动 16:52:28 → 清场 + 灌入 + 首轮分析约 31 秒)。

5.2 作答与评测

回答为四次中最简洁 的风格:账号 4429853327 + 路由 123006800 两行 + "You'll need both for direct deposit",未带账户类型标签、未附安全建议。评委:"The agent accurately retrieved and returned the checking account number without confusing it with nearby numbers, and appropriately included the routing number for the user's stated direct deposit need. The response is concise, complete, and fully grounded in the source."PASSED,1.000/1.000------proactivity 维的判据是"附上 routing number",满足即满分,简洁风格不扣分(四次作答风格各异、得分相同,评委只对内容判分)。

6. 运行四轨迹:enhanced_notes(17:50:10)

背景:本次成功运行之前,enhanced_notes 的一次尝试曾因评委 LLM APIConnectionError(连接层失败,tenacity 3 次重试耗尽 → RetryError → reward 记 0)失败------与运行一~三之后的 60 秒超时(已修:REQUEST_TIMEOUT=300)是不同类型的故障,未改任何代码、直接重跑即成功,判定为网络抖动(该失败尝试未留完整日志,仅控制台输出可证)。

6.1 记忆生成------单轮 ReAct、4 条主题域大合集笔记

分析 agent 一次 LLM 调用产出 4 个并行 add_memory(全部成功,uuid 键无冲突),STOP 收尾。颗粒度为四次最粗、单条信息密度最高------"enhanced"体现在把一个主题域的全部事实聚合进单条笔记(对比 notes 的 11 条细粒度清单):

# 内容要点 tags
1 身份+联系全合集:姓名/称呼 Mr. Robertson / DOB / 出生地丹佛 / 住址(2.5 年)/ 手机 / 邮箱(银行通知用途)/ 俄勒冈驾照 / SSN personal, contact, identity
2 就业:TechCorp 软件工程师 ~4 年、$125K/年、国际出差 employment, income, work
3 银行大合集(13+ 事实点) :FNB 客服电话 + 路由 123006800 / Premium Checking #4429853327 / Basic Savings #4429853328 / 初始存款 5,000 + 500(自 Wells Fargo 电转,旧账号+路由同录)/ 借记卡 PIN 4827 / 网银用户名 / 每月 15 日 200 自动转存 / 标准支票 / 电子账单 / 手机银行 / 2,500 最低余额 / 透支保护联动 banking, accounts, first-national-bank
4 安全问题三答案 + 偏好(电子账单"save some trees" / 标准支票避 $15 定制费 / CashBack 卡意向待办) security, preferences, banking

时间线(从控制台带时间戳的 logging 输出复原):17:50:10 启动 → 17:50:54 四条笔记落盘(清场 + 灌入 + ReAct 分析共 ~44 秒)→ 17:51:04 Agent 作答(~10 秒)→ 17:51:26 评委返回(~18 秒一次通过,评委阶段未见超时重试------300 秒超时配置生效后无压力)。

6.2 作答与评测

回答:账号 4429853327 (Premium Checking) + 路由 123006800 。评委:"The agent accurately retrieved and provided the requested checking account number without confusing it with the savings account number, and correctly included the routing number relevant to direct deposit setup. No unsupported factual claims were found."PASSED,1.000/1.000

7. 四模式对照

维度 advanced_json_cards json_cards notes enhanced_notes
卡片数 10(无丢失) 落盘 8(9 add,1 覆盖) 11(无丢失,颗粒最细) 4(无丢失,颗粒最粗/单条密度最高)
键质量 语义化 card_key(identity_michael_robertson 等) 6 个回退键中 2 个为 150 字符病态长键 uuid4,天然无冲突 uuid4,天然无冲突
元数据 person/relationship/backstory 齐备(多层场景消歧预留) 仅 value/source/updated_at content + tags + session + 时间戳 content + tags + session + 时间戳
账号消歧 每账户独立卡,FNB/WF 路由号物理隔离 路由号埋在大段 value 内 checking / savings 分立两条 checking / savings / WF 旧账户同在一条大合集内,仅靠行文区分
元数据准确性 ⚠️ date_created 全部写 "2025-01-15 10:30:00"------既非当前时间(提示词要求)也非通话时间(YAML 为 2024-11-15),元字段幻觉 无日期字段,无此问题 无日期字段,无此问题 无日期字段,无此问题
作答正确性 ✅ 全对 ✅ 全对(丢失笔记未影响本题) ✅ 全对(最简洁风格) ✅ 全对
Reward 1.000 1.000 1.000 1.000

结论 :layer1 是单跳检索题,四种模式的信息冗余度都足以支撑满分------模式差异在本层不可分辨 ,真正能拉开差距的是 layer2(多账户消歧)/ layer3(跨对话综合)。但工程质量差异已经显现:advanced 一次成型、键语义化;notes 与 enhanced_notes 的 uuid 键天然无冲突(前者细粒度清单、后者主题域大合集,是"信息组织颗粒度光谱"的两端);json_cards 依赖模型自觉输出 JSON,一旦退化到回退路由就产生病态键与同秒覆盖丢数据------四模式中唯一丢数据的就是 json_cards

8. 关键观察

✅ 正常工作的点(验证通过)

  1. 评测隔离设计生效:五阶段流水线全程零残留(清场 → 灌入 → 处理 → 清历史重载记忆 → 评委),第二部分 demo 的"残留记忆"问题在评测模式不存在;
  2. agent/processor 双实例经文件中转正确load_memory() 重载后 Agent 确实只用结构化记忆答对了题;
  3. 四模式四满分:四次四维全 4 分、无幻觉,评委(deepseek-v4-pro,强于被测 flash)独立打分且给出具体证据引用;
  4. 幂等清场与原子写 :每次运行前 clear_all_memories() 保证对照实验可比;memory_manager 落盘走 tmp+os.replace 原子替换(memory_manager.py L387-403)。

⚠️ 值得关注的问题

  1. "Added: 0" 统计脱节(四运行共通) :日志打印 "Memory processing complete: Added: 0 memories",但实际分别写入 10/9/11/4 条。根因:analyze_conversation 让 ReAct agent 直接执行工具后返回空列表 (background_memory_processor.py L154-157),process_conversation_batch 走 else 分支输出 0/0/0(L640-645)。记忆真实落盘,但汇总口径失效------脚本化批量评测时无法据此统计;
  2. json_cards 回退路由三缺陷 (§4.2):模型不输出 JSON 无兜底约束、病态长键、同秒 note ID 冲突静默覆盖。多账户用例(layer2_05_multiple_bank_accounts 等)下多条无冒号笔记同秒写入将真实丢账号
  3. advanced 卡 date_created 元字段幻觉(§7 表):时间元数据不可信,若上层依赖该字段做时效衰减会引入错误;
  4. 磁盘状态被覆盖 :运行二(json_cards)覆盖运行一(10 张 advanced 卡),运行三(notes)又覆盖运行二,运行四(enhanced_notes)再覆盖运行三------当前 data/memories/ 终态为运行四的 4 条 enhanced 笔记,前三次终态只能从各自日志复原------对照实验应给每次运行独立 user_id 或备份 data 目录;
  5. main.py 预览截断 (L679):记忆上下文只打印前 500 字符,运行一仅见 1 张卡的片段,审计需读 data/memories/ 文件;
  6. 敏感信息明文落盘 :SSN、借记卡 PIN、安全问题答案以明文 JSON 存储于 data/memories/,评测演示可接受,生产场景需加密/脱敏(四次作答均未主动泄露多余敏感信息,行为正确);
  7. 评委链路故障会被静默记为 0 分 :运行四之前的一次尝试因评委 APIConnectionError(网络抖动,连接层失败)→ tenacity RetryError → except 分支 reward=0、FAILED------"评测基础设施失败"与"Agent 真实低分"在结果里不可区分;60 秒超时问题已修(REQUEST_TIMEOUT=300,运行四评委 ~18 秒通过),但脚本化批量跑时应识别 reasoning 中的 "Evaluation failed due to error" 前缀并将此类样本剔除/重跑,而非计入统计。

9. 与 README 实验目标的对照及建议

README 的核心实验是四种记忆模式在同一用例上的 Reward 对比 。layer1_01_bank_account 已完成 4/4

记忆模式 Reward 状态
notes 1.000 ✅ 本次运行三
enhanced_notes 1.000 ✅ 本次运行四
json_cards 1.000 ✅ 本次运行二
advanced_json_cards 1.000 ✅ 本次运行一

结论:README 要求的四模式对比已完成------评测模式全链路在豆包模型上跑通,同一 layer1 用例下四种模式全部满分(四次作答风格各异------advanced 带账户标签、json_cards 附安全建议、notes 最简、enhanced_notes 带账户标签加"还需要什么"收尾------但均四维全 4,评委只对内容判分),模式优劣在单跳检索层不可分辨;advanced 的结构红利(语义键、消歧元字段、账户隔离)与 notes/enhanced_notes 的颗粒度差异需到 layer2/3 才可能兑现,而 json_cards 的回退路由缺陷(病态键、同秒覆盖)在多实体场景是真实风险。

改进建议

  1. 修 note ID 冲突note_ 键追加 uuid4 短后缀或用微秒精度(agent.py L468),并对 add 时 key 已存在的情况显式告警/拒绝静默覆盖(memory_manager.py L426);
  2. 修统计口径process_conversation_batch 改从 analysis_agent.tool_calls 统计(process_recent_conversations 已有正确实现可复用,background_memory_processor.py L430-464),或让 analyze_conversation 返回真实操作清单;
  3. json_cards 提示词加硬约束:要求"content 必须是合法 JSON,否则不写",或回退时改用 tags 生成语义键而非首冒号切分;
  4. 推进 layer2/3:四模式对比已凑齐,下一步用 layer2_07_multiple_medications、layer2_05_multiple_bank_accounts 检验多实体消歧------这是同秒覆盖 bug 最可能显形、也是模式差异最可能拉开的地方;
  5. 对照运行留痕 :每次运行换独立 user_id(如 eval_adv_<时间戳>)或运行前备份 data/,避免后跑覆盖先跑的终态;
  6. advanced 提示词中 date_created 改由系统侧注入而非模型自填,消除元字段幻觉。
相关推荐
Terra.K1 小时前
后端+AIAGENT项目开发指南
后端·agent·个人开发
Omics Pro1 小时前
斯坦福Nature+Science|广义虚拟细胞基础大模型
数据库·人工智能·算法·机器学习·自然语言处理
MicrosoftReactor1 小时前
技术速递|GitHub Copilot App 入门指南:使用 Diff、终端和浏览器
ai·copilot·agent
墨天梦2 小时前
25-评估指标与基准设计
人工智能·自然语言处理
Ticnix3 小时前
42 天 71 次提交之后,我重新看了一遍自己的架构决策
python·agent·全栈
Ticnix3 小时前
我调了三个月 overlap=50,它其实一次都没生效
后端·python·agent
不好听6133 小时前
图数据库为什么查关系快:免索引邻接,以及怎么把小说抽成图——Graph RAG 系列之二
agent
李溪白3 小时前
篇五:RAG —— 让 Agent 拥有外挂知识库
agent
辉夜技术3 小时前
大模型的理解力,用户的解空间:Jev 如何填满一个空白象限
agent