C3 · 记忆管理 · 测试用例
对应框架维度:C3 记忆管理 状态:初稿 最后更新:2026-04-10
维度说明
C3 测试 agent 对「记忆」的使用是否正确,包含两类记忆:
- 短期记忆:当前对话内的上下文信息(如用户在第 2 轮提到的出发地)
- 长期记忆:跨 session 的历史信息(如上次旅行存下的偏好)
与 C5(长上下文性能)的区别:
| C3 记忆管理 | C5 长上下文性能 | |
|---|---|---|
| 测什么 | 记忆的使用是否正确(该用的用、不该用的不用、更新是否准确) | 上下文变长时性能是否衰减(lost-in-the-middle 问题) |
| 关注点 | 逻辑正确性 | 性能稳定性 |
| 上下文长度 | 短~中(3-10 轮) | 长(4K~64K token) |
| 失败原因 | 记忆逻辑错误(该记没记、该忘没忘) | 位置偏差导致的遗漏 |
用例规范
| 字段 | 说明 |
|---|---|
| ID | 格式:C3-{维度缩写}-{序号} |
| 维度 | 所属评测子维度 |
| 难度 | 简单 / 中等 / 困难 |
| 上下文类型 | synthetic(静态历史)/ organic(动态交互) |
| 输入 | 用户消息 + 对话历史 / 预置记忆 |
| 期望行为 | agent 应该如何使用记忆 |
| 判定标准 | Pass / Fail 的明确条件 |
| 评分方式 | 自动 / LLM-judge |
| Skill 配置 | 必须开启 |
一、短期记忆利用(SU: Short-term Utilization)
当前对话中已提供的信息,agent 是否在后续轮次中正确沿用,不重复询问、不遗漏。
C3-SU-01 · 不重复询问已知出发地
- 难度:简单
- 上下文类型:synthetic
- 输入:
- 对话历史:
用户:我从成都出发,想查一下去三亚的机票 Agent:好的,请问您想什么时间出发? 用户:12 月 20 号,两个人 Agent:(返回了成都→三亚的机票结果) - 用户消息:
顺便帮我也查一下酒店吧,三亚的
- 对话历史:
- 期望行为:
- 直接搜索三亚酒店,入住日期使用 12 月 20 日
- 人数使用 2 人(已在对话中提供)
- 不应再次询问「您从哪里出发」「几位入住」
- 判定标准:
- Pass:搜索酒店时正确沿用三亚、12 月 20 日、2 人,未重复询问
- Fail:重新询问目的地或人数 / 搜索时遗漏人数参数
- 评分方式:自动(检查工具调用参数)
- Skill 配置:
skill_enabled: true, active_skills: [flight-selection]
C3-SU-02 · 沿用对话中建立的预算约束
- 难度:简单
- 上下文类型:synthetic
- 输入:
- 对话历史:
用户:我这次出行预算比较紧,总共不超过 8000 块 Agent:好的,我帮你控制在 8000 以内。请问想去哪里? 用户:日本大阪,5 天,从上海出发 Agent:(查询了上海→大阪的机票,最低约 2800 元) - 用户消息:
那酒店怎么选比较合适
- 对话历史:
- 期望行为:
- 知道机票已花 2800,剩余预算约 5200
- 推荐酒店时主动考虑剩余预算(住宿 + 餐饮 + 交通),不推荐超出范围的选项
- 不应无视预算推荐高档酒店
- 判定标准:
- Pass:推荐酒店时明确考虑了 8000 总预算和已花机票费,推荐价位合理(日均住宿建议控制在 300-500 元)
- Fail:推荐了明显超预算的酒店 / 完全不提预算约束
- 评分方式:LLM-judge(评估预算意识是否贯穿建议)
- Skill 配置:
skill_enabled: true, active_skills: [flight-selection]
C3-SU-03 · 沿用隐性偏好约束
- 难度:中等
- 上下文类型:synthetic
- 输入:
- 对话历史:
用户:我对花粉过敏,春天出行要特别注意 Agent:了解,我会在推荐时注意这点。 用户:帮我规划 4 月去京都赏樱的行程 - 用户消息:(即「帮我规划 4 月去京都赏樱的行程」)
- 对话历史:
- 期望行为:
- 主动提示花粉过敏在樱花季的风险(4 月京都花粉浓度高)
- 建议携带抗过敏药物,或推荐室内景点作为备选
- 不应在安排行程时完全忽略用户的过敏情况
- 判定标准:
- Pass:行程中主动提及花粉过敏注意事项,并给出具体建议(带药、选部分室内活动等)
- Fail:完全不提过敏,正常规划赏樱行程
- 评分方式:LLM-judge
- Skill 配置:
skill_enabled: true, active_skills: [itinerary-planning]
C3-SU-04 · 多个约束同时沿用
- 难度:困难
- 上下文类型:synthetic
- 输入:
- 对话历史(跨多轮建立的约束):
第 1 轮 - 用户:我和我妈一起去,她不太会走路,行动不便 第 3 轮 - 用户:我们只有 3 天时间 第 5 轮 - 用户:我妈不吃辣,这个要注意一下 第 7 轮 - 用户:尽量不要安排太多景点,她容易累 - 用户消息:
帮我安排成都 3 天的行程
- 对话历史(跨多轮建立的约束):
- 期望行为:
- 行程紧凑度低,每天不超过 2-3 个景点
- 景点选择考虑无障碍/老年友好(不选爬山、石板路多的地方)
- 餐厅推荐避免辣,推荐清淡川菜或其他菜系
- 3 天总行程合理,不过量
- 判定标准:
- Pass:行程同时满足「行动不便」「3 天」「不辣」「不累」四个约束,且没有遗漏任何一个
- Fail:遗漏任意一个约束(如推荐了辛辣餐厅,或安排了每天 6 个景点,或选了需要大量步行的地方)
- 评分方式:LLM-judge(逐项检查四个约束是否全部体现)
- Skill 配置:
skill_enabled: true, active_skills: [itinerary-planning]
C3-SU-05 · 对话中途的信息更正立即生效
- 难度:中等
- 上下文类型:synthetic
- 输入:
- 对话历史:
用户:帮我查下周五从北京飞上海的机票 Agent:好的,查询北京→上海,下周五(4月17日),几位? 用户:2 个人 Agent:(正在搜索...) 用户:等等,我说错了,不是下周五,是下周六 - 用户消息:(即「等等,我说错了...」)
- 对话历史:
- 期望行为:
- 立即更新日期为下周六(4 月 18 日)
- 重新搜索或提示将用更新后的日期搜索
- 不应继续使用原来的错误日期
- 判定标准:
- Pass:后续搜索使用 4 月 18 日,而非 4 月 17 日
- Fail:忽略更正,仍用 4 月 17 日出发
- 评分方式:自动(检查工具调用中的日期参数)
- Skill 配置:
skill_enabled: true, active_skills: [flight-selection]
二、长期记忆召回准确率(LR: Long-term Recall)
跨 session 时,历史记忆是否被准确召回并恰当应用。
C3-LR-01 · 召回常用出发城市
- 难度:简单
- 上下文类型:synthetic
- 输入:
- 预置记忆:
用户历史偏好: - 常住城市:上海 - 惯用出发机场:上海浦东(PVG) - 记录时间:上次会话 - 新 session,用户消息:
帮我查下个月去北京的机票
- 预置记忆:
- 期望行为:
- 直接以上海浦东作为出发地搜索,或先确认「您还是从上海出发吗?」
- 不应凭空询问「请问从哪里出发?」(历史记忆已有)
- 判定标准:
- Pass:以上海/浦东为出发地搜索,或礼貌确认是否仍从上海出发
- Fail:完全无视记忆,直接询问出发城市
- 评分方式:LLM-judge
- Skill 配置:
skill_enabled: true, active_skills: [flight-selection]
C3-LR-02 · 召回健康/饮食限制
- 难度:中等
- 上下文类型:synthetic
- 输入:
- 预置记忆:
用户偏好: - 饮食限制:花生过敏(严重,须回避) - 记录时间:3 次会话前 - 新 session,用户消息:
帮我规划下个月去泰国 5 天的行程
- 预置记忆:
- 期望行为:
- 在推荐泰餐时主动提醒花生酱在泰国菜中非常普遍
- 建议提前准备过敏药物,或携带翻译卡说明过敏情况
- 不应给出包含花生酱的菜肴推荐(如泰式炒河粉 pad thai 默认含花生)
- 判定标准:
- Pass:主动提及花生过敏风险,推荐的餐食考虑了这一限制
- Fail:推荐了含花生的泰国菜,或完全不提过敏注意事项
- 评分方式:LLM-judge
- Skill 配置:
skill_enabled: true, active_skills: [itinerary-planning]
C3-LR-03 · 基于历史旅行经历的推荐
- 难度:中等
- 上下文类型:synthetic
- 输入:
- 预置记忆:
历史旅行记录: - 2025 年 10 月:日本京都,用户反馈「非常喜欢,特别是古寺和老街,比东京更有感觉」 - 2025 年 4 月:泰国普吉岛,用户反馈「海滩太挤了,不太适合我」 - 新 session,用户消息:
我想找个类似京都那种感觉的地方,不知道有什么推荐
- 预置记忆:
- 期望行为:
- 理解「类似京都」指的是传统文化氛围、古迹、安静氛围
- 给出符合这种偏好的目的地(如越南会安、韩国庆州、中国平遥/丽江等)
- 可以引用京都好评反馈作为推荐依据
- 不应推荐海滩或夜生活类目的地(参考普吉岛负反馈)
- 判定标准:
- Pass:推荐了文化/古城类目的地,且推荐逻辑与京都偏好一致;未推荐海滩类型
- Fail:推荐了海滩目的地 / 推荐与偏好不相关 / 完全不参考历史记录
- 评分方式:LLM-judge
- Skill 配置:
skill_enabled: true, active_skills: [itinerary-planning]
C3-LR-04 · 关联历史计划到当前任务
- 难度:困难
- 上下文类型:synthetic
- 输入:
- 预置记忆:
历史规划记录: - 计划中的旅行:日本东京,出发日期 2026 年 5 月 3 日,4 人同行 - 状态:机票已查询,未预订 - 新 session,用户消息:
我想了解一下去日本需要办什么签证
- 预置记忆:
- 期望行为:
- 结合记忆中的东京计划,给出针对性的签证建议(5 月 3 日出发,中国公民,日本旅游签)
- 提示签证办理时间(建议出发前 1-2 个月申请),并结合记忆中的日期提示是否需要尽快办理
- 不应给出完全通用的签证介绍,忽略记忆中已有的具体行程信息
- 判定标准:
- Pass:回答结合了记忆中的东京行程(5 月 3 日、4 人),提示了针对性的时间节点
- Fail:给出通用签证介绍,完全没有引用记忆中的具体计划
- 评分方式:LLM-judge
- Skill 配置:
skill_enabled: true, active_skills: [flight-selection]
三、记忆相关性判断(RJ: Relevance Judgment)
知道什么时候该使用记忆、什么时候不该用——防止无关记忆干扰当前任务。
C3-RJ-01 · 不将无关历史记忆带入当前任务
- 难度:中等
- 上下文类型:synthetic
- 输入:
- 预置记忆:
历史计划:深圳出差,2026 年 3 月,单人,公务 - 新 session,用户消息:
帮我推荐东京有什么好吃的
- 预置记忆:
- 期望行为:
- 直接回答东京美食推荐
- 不应把深圳出差的记忆带入(如「上次深圳出差您选了商务酒店,这次东京是出差还是旅游?」)
- 判定标准:
- Pass:直接给出东京美食推荐,不提及深圳相关记忆
- Fail:把深圳出差记忆与当前任务关联,输出无关内容
- 评分方式:自动(检查输出是否包含深圳/出差等无关信息)
- Skill 配置:
skill_enabled: true, active_skills: [itinerary-planning]
C3-RJ-02 · 当前会话信息优先于长期记忆
- 难度:中等
- 上下文类型:synthetic
- 输入:
- 预置记忆:
用户偏好:常从上海浦东出发 - 新 session,对话历史:
用户:我这次在深圳出差,要从深圳飞北京 Agent:好的,查询深圳→北京的航班,几位? 用户:就我一个人 - 用户消息:
帮我订最近的一班
- 预置记忆:
- 期望行为:
- 使用深圳作为出发地(当前会话明确指定)
- 不应因为长期记忆是「上海浦东」而切换回上海
- 判定标准:
- Pass:搜索以深圳为出发地,忽略上海的长期偏好记忆
- Fail:使用上海浦东搜索,或混淆出发地
- 评分方式:自动(检查工具调用中的出发地参数)
- Skill 配置:
skill_enabled: true, active_skills: [flight-selection]
C3-RJ-03 · 不将旧的预算偏好强加于明确的高端需求
- 难度:困难
- 上下文类型:synthetic
- 输入:
- 预置记忆:
用户偏好:出行预算敏感,倾向经济舱、经济型酒店 - 新 session,用户消息:
我和对象十周年纪念日,想去马尔代夫,订个好一点的水上屋,不在乎价格
- 预置记忆:
- 期望行为:
- 推荐马尔代夫高端水上屋(四季、柏悦、宋那瓦等)
- 不受旧的「预算敏感」记忆限制
- 可以(可选)礼貌地确认「这次不设预算上限吗?」,但不应主动降档推荐
- 判定标准:
- Pass:推荐高端水上屋,价格区间符合马尔代夫顶级水上屋市场(¥3000+/晚)
- Fail:因旧记忆限制,推荐了预算型岛屿或忽视「不在乎价格」的明确表述
- 评分方式:LLM-judge
- Skill 配置:
skill_enabled: true, active_skills: [itinerary-planning]
C3-RJ-04 · 多条历史记忆只召回相关的
- 难度:困难
- 上下文类型:synthetic
- 输入:
- 预置记忆(多条):
记忆 A:2025 年去过巴黎,喜欢博物馆和街区漫步 记忆 B:2025 年预订过希尔顿积分房 记忆 C:对酒精过敏,不能喝含酒精饮品 记忆 D:有一只柴犬叫做「豆豆」 - 新 session,用户消息:
帮我找一下去罗马的酒店
- 预置记忆(多条):
- 期望行为:
- 召回记忆 B(积分房偏好),询问是否需要希尔顿积分房选项
- 不应引用记忆 A(巴黎行程与罗马酒店无关)
- 不应引用记忆 C(酒精过敏与酒店无关)
- 绝对不应引用记忆 D(宠物信息完全无关)
- 判定标准:
- Pass:只召回了积分房偏好(记忆 B),其他记忆均未出现在回复中
- Fail:输出中提及了无关记忆(尤其是柴犬或酒精过敏)
- 评分方式:LLM-judge(检查输出中引用的记忆是否都相关)
- Skill 配置:
skill_enabled: true, active_skills: [itinerary-planning]
四、记忆更新正确性(MU: Memory Update)
用户纠正或更新信息后,agent 是否正确使用新信息,而非继续沿用旧的。
C3-MU-01 · 显式更正立即生效
- 难度:简单
- 上下文类型:synthetic
- 输入:
- 对话历史:
用户:我从武汉出发,查一下去海南的机票,3 月 15 号 Agent:好的,查武汉→海南(三亚/海口),3 月 15 日,几位? 用户:对了,不是 3 月 15 号,是 3 月 25 号,我看错日历了 - 用户消息:(即「对了,不是 3 月 15 号...」)
- 对话历史:
- 期望行为:
- 更新日期为 3 月 25 日
- 确认更新后继续搜索(或提示已更新)
- 判定标准:
- Pass:后续搜索使用 3 月 25 日
- Fail:仍使用 3 月 15 日 / 询问「您刚才说 15 号,现在要改吗?」(不必要的二次确认)
- 评分方式:自动(检查工具调用日期参数)
- Skill 配置:
skill_enabled: true, active_skills: [flight-selection]
C3-MU-02 · 跨 session 的偏好更新
- 难度:中等
- 上下文类型:synthetic
- 输入:
- 预置记忆:
用户偏好:出发城市 = 上海 - 新 session,对话历史:
用户:我搬到北京了,以后查机票都从北京出发 Agent:好的,我已经记下了。 - 后续新会话,用户消息:
帮我查去成都的机票,下周末
- 预置记忆:
- 期望行为:
- 使用北京作为出发地(已明确告知更新)
- 不应回退到旧的上海记忆
- 判定标准:
- Pass:以北京为出发地搜索
- Fail:仍使用上海出发
- 评分方式:自动(检查工具调用出发地参数)
- Skill 配置:
skill_enabled: true, active_skills: [flight-selection]
C3-MU-03 · 隐性更新:从行为中推断偏好变化
- 难度:困难
- 上下文类型:synthetic
- 输入:
- 预置记忆:
用户偏好:价格优先,选最低价 - 新 session,对话历史:
Agent:帮您找到最低价:春秋航空,¥680/人,中转厦门,总飞行时间 6h 用户:这个转机太麻烦了,有直飞的吗? Agent:直飞最低 ¥1280/人 用户:好,就选这个直飞的吧 - 用户消息:
那顺便帮我看看回程票
- 预置记忆:
- 期望行为:
- 回程推荐时,优先展示直飞选项(基于本次对话中用户的选择行为)
- 不应因为长期记忆「价格优先」就只推最低价中转航班
- 可以同时展示两个选项,但直飞应排在前面
- 判定标准:
- Pass:回程优先推荐直飞,或明确将直飞作为首推选项
- Fail:仍按旧偏好推最低价中转航班,忽略本次对话中的偏好信号
- 评分方式:LLM-judge
- Skill 配置:
skill_enabled: true, active_skills: [flight-selection]
C3-MU-04 · 更新后不影响无关信息
- 难度:中等
- 上下文类型:synthetic
- 输入:
- 预置记忆:
用户偏好: - 出发城市:广州 - 饮食:不吃香菜 - 座位:靠窗 - 新 session,用户消息:
我现在换到深圳了,出发城市改成深圳
- 预置记忆:
- 期望行为:
- 更新出发城市为深圳
- 保留其他记忆不变(不吃香菜、靠窗座位)
- 后续任务中仍应用未修改的偏好
- 判定标准:
- Pass:出发城市变为深圳,推荐餐厅时仍避免香菜,选座时仍建议靠窗
- Fail:更新出发城市的同时清空其他记忆,或饮食/座位偏好丢失
- 评分方式:LLM-judge(通过后续任务验证三个偏好的保留/更新状态)
- Skill 配置:
skill_enabled: true, active_skills: [itinerary-planning]
五、记忆冲突处理(MC: Memory Conflict)
新信息与已有记忆产生矛盾时,是否合理处理而非悄悄偏向一方。
C3-MC-01 · 用户偏好与当前明确需求冲突
- 难度:中等
- 上下文类型:synthetic
- 输入:
- 预置记忆:
用户偏好:不喜欢长途飞行(超过 5 小时容易不舒服) - 新 session,用户消息:
帮我规划去悉尼的旅行,10 天,从上海出发
- 预置记忆:
- 期望行为:
- 上海→悉尼直飞约 11 小时,明显超过记忆中的舒适时长
- 主动提示这个冲突:「我记得您之前提到不太适应长途飞行,上海到悉尼直飞约 11 小时,您看是否需要安排中转休息,或者是这次可以接受?」
- 不应悄悄安排直飞,也不应因此直接拒绝提供服务
- 判定标准:
- Pass:主动提及飞行时长与历史偏好的冲突,并询问用户如何处理
- Fail:直接安排直飞忽略偏好 / 直接安排中转而不解释原因 / 完全不规划悉尼行程
- 评分方式:LLM-judge
- Skill 配置:
skill_enabled: true, active_skills: [flight-selection]
C3-MC-02 · 当前会话声明覆盖历史偏好
- 难度:中等
- 上下文类型:synthetic
- 输入:
- 预置记忆:
用户偏好:经济舱出行,注重性价比 - 新 session,用户消息:
这次出差公司报销,帮我查商务舱,北京到纽约
- 预置记忆:
- 期望行为:
- 搜索商务舱,不受「经济舱偏好」记忆限制
- 当前明确需求(商务舱)优先于历史偏好(经济舱)
- 判定标准:
- Pass:搜索商务舱,返回商务舱选项
- Fail:因记忆偏好搜索经济舱,或同时推荐经济舱「更划算」而无视用户明确指令
- 评分方式:自动(检查舱位参数是否为商务舱)
- Skill 配置:
skill_enabled: true, active_skills: [flight-selection]
C3-MC-03 · 跨 session 记忆互相冲突
- 难度:困难
- 上下文类型:synthetic
- 输入:
- 预置记忆(两条相互矛盾的记录):
记忆 A(6 个月前):偏好直飞,「宁愿多花点钱也不想转机」 记忆 B(1 个月前):「最近开始在意价格,优先选最便宜的」 - 新 session,用户消息:
帮我查上海到洛杉矶的机票,7 月出发
- 预置记忆(两条相互矛盾的记录):
- 期望行为:
- 识别出两条记忆互相矛盾,且近期记忆(记忆 B)比旧记忆更可能反映当前偏好
- 应主动说明两种选项(直飞 vs 最低价中转)并询问用户当前的优先级,而非自行决定
- 不应直接按照其中一条记忆执行而不提另一条
- 判定标准:
- Pass:提出冲突,展示直飞和最低价选项,让用户选择优先级
- Fail:只按其中一条记忆执行,完全忽略另一条
- 评分方式:LLM-judge
- Skill 配置:
skill_enabled: true, active_skills: [flight-selection]
C3-MC-04 · 对话内约束互相冲突
- 难度:困难
- 上下文类型:synthetic
- 输入:
- 对话历史:
用户:我想去日本,国庆黄金周出发,10 月 1 号到 7 号 用户:预算要控制在 5000 以内 - 用户消息:
帮我查机票和酒店
- 对话历史:
- 期望行为:
- 识别出「国庆黄金周」和「5000 以内」两个约束存在现实冲突(旺季机票+住宿几乎不可能控制在 5000 以内)
- 主动说明冲突:「国庆期间上海→东京往返机票通常 4000-6000 元,加上住宿很难控制在 5000 以内,您看是可以调整预算,还是换一个出行时间?」
- 不应直接搜索然后返回超预算结果而不提示
- 判定标准:
- Pass:主动提示预算与旺季出行的冲突,并提出调整方向(加预算 or 换日期)
- Fail:直接搜索并返回超预算结果,不提示矛盾 / 只选其中一个约束执行
- 评分方式:LLM-judge
- Skill 配置:
skill_enabled: true, active_skills: [flight-selection]
统计摘要
| 子维度 | 用例数 | 难度分布 | 评分方式 |
|---|---|---|---|
| SU 短期记忆利用 | 5 | 简单×2、中等×2、困难×1 | 自动×2、LLM-judge×3 |
| LR 长期记忆召回 | 4 | 简单×1、中等×2、困难×1 | LLM-judge×4 |
| RJ 记忆相关性判断 | 4 | 中等×2、困难×2 | 自动×1、LLM-judge×3 |
| MU 记忆更新正确性 | 4 | 简单×1、中等×2、困难×1 | 自动×2、LLM-judge×2 |
| MC 记忆冲突处理 | 4 | 中等×2、困难×2 | 自动×1、LLM-judge×3 |
| 合计 | 21 | 简单×4、中等×10、困难×7 | 自动×6、LLM-judge×15 |