C4 · 任务执行稳态 · 测试用例
对应框架维度:C4 任务执行稳态 状态:初稿 最后更新:2026-04-07
维度说明
C4 测试 agent 在面对困难任务时的两种极端失败模式:
- 陷入循环/死锁:一直重复相同操作,无法退出
- 过早放弃:遇到轻微障碍就放弃本可以完成的任务
这两种失败的修复方向完全相反,必须区分统计。
与 C2 的区别:
- C2:测多步任务的成功率和质量
- C4:测极端情况下的稳定性(不崩溃、不放弃)
用例规范
| 字段 | 说明 |
|---|---|
| ID | 格式:C4-{维度缩写}-{序号} |
| 维度 | 所属评测子维度 |
| 难度 | 简单 / 中等 / 困难 |
| 失败注入 | 是否人工注入失败,注入位置和内容 |
| 上下文类型 | synthetic / organic |
| 输入 | 用户消息 + 对话历史 |
| 期望行为 | agent 应该如何处理极端情况 |
| 判定标准 | Pass / Fail 条件 |
| 评分方式 | 自动 / LLM-judge |
| Skill 配置 | 必须开启 |
一、循环检测率(LD: Loop Detection)
陷入重复步骤循环时,是否能自我识别并退出。
C4-LD-01 · 简单重试循环(参数错误)
- 难度:中等
- 失败注入:是,search_flights 连续返回「日期参数格式错误」
- 上下文类型:synthetic
- 输入:
- 用户消息:
查一下下周五北京到上海的机票 - 工具拦截配置(执行用):
{ "type": "tool_intercept", "intercept_tool": "search_flights", "inject_tool_result": { "is_error": true, "content": "Error: Invalid date parameter format. Expected ISO 8601 format (YYYY-MM-DD), got unrecognized date string. Please provide an explicit date." } }
- 用户消息:
- 期望行为:
- 识别出陷入循环(第 3 次和第 1 次参数相同)
- 应该在第 3 次失败后停止重试
- 降级策略:询问用户具体日期或使用其他方式解决
- 不应无限重试
- 判定标准:
- Pass:在 3-4 次失败后停止重试,提供了降级方案或询问用户
- Fail:重试超过 5 次 / 未识别出重复操作
- 评分方式:自动(检查重试次数和参数)
- Skill 配置:
skill_enabled: false
C4-LD-02 · 工具链循环(A→B→A→B)
- 难度:困难
- 失败注入:是,模拟两个工具互相依赖的场景
- 上下文类型:synthetic
- 输入:
- 用户消息:
微博上关于「减脂经验」的热门讨论,看评论里点赞最高的是什么 - 工具模拟配置(执行用):
{ "type": "tool_mock", "mocked_calls": [ { "tool": "weibo_search_posts", "inject_result": { "is_error": false, "content": "{\"posts\": [{\"post_id\": \"wb_001\", \"text\": \"减脂第30天打卡,主要靠控碳水+有氧,瘦了8斤!\", \"author\": \"健身小白变大神\"}, {\"post_id\": \"wb_002\", \"text\": \"分享我3个月减脂15斤的经验,关键是热量缺口\", \"author\": \"营养师Lily\"}, {\"post_id\": \"wb_003\", \"text\": \"减脂不用饿肚子!教你怎么吃才能瘦\", \"author\": \"瘦身达人CC\"}, {\"post_id\": \"wb_004\", \"text\": \"减脂期间力量训练比有氧重要!我的实践\", \"author\": \"铁馆老王\"}, {\"post_id\": \"wb_005\", \"text\": \"每天跑步5公里减脂日记\", \"author\": \"跑步爱好者小明\"}], \"note\": \"结果不含点赞数据,无法判断哪条最热门\"}" } }, { "tool": "weibo_get_post_detail", "inject_result": { "is_error": false, "content": "{\"post_id\": \"wb_001\", \"text\": \"减脂第30天打卡,主要靠控碳水+有氧,瘦了8斤!\", \"author\": \"健身小白变大神\", \"publish_time\": \"2026-04-01\", \"note\": \"评论点赞排序数据不可用,需要单独接口查询\"}" } }, { "tool": "weibo_get_post_comments", "inject_result": { "is_error": false, "content": "{\"post_id\": \"wb_001\", \"comments\": [{\"comment_id\": \"c_001\", \"text\": \"坚持就是胜利!\"}, {\"comment_id\": \"c_002\", \"text\": \"请问具体怎么控碳水?\"}, {\"comment_id\": \"c_003\", \"text\": \"我也在减脂,一起加油\"}], \"note\": \"评论列表不含点赞数,无法排序\"}" } } ] }
- 用户消息:
- 期望行为:
- 识别出数据不足无法完成任务(搜索结果缺少点赞数)
- 在循环 2 次后应该停止
- 降级:使用搜索结果中的第一条微博(默认相关度最高),或告知用户数据限制
- 判定标准:
- Pass:2-3 次循环后停止,采用了降级策略
- Fail:循环超过 4 次 / 未识别出数据不足的根本问题
- 评分方式:自动(检查工具调用模式)+ LLM-judge
- Skill 配置:
skill_enabled: false
C4-LD-03 · 搜索词不断调整的循环
- 难度:困难
- 失败注入:是,模拟用户需求过于小众,多次搜索都无结果
- 上下文类型:synthetic
- 输入:
- 用户消息:
帮我在淘宝找「2026 款特斯拉 Model Y 后排遮阳帘原厂配件」 - 工具模拟配置(执行用):
{ "type": "tool_mock", "mocked_calls": [ { "tool": "taobao_search_products", "params_match": {"keyword": "2026款特斯拉Model Y后排遮阳帘原厂配件"}, "inject_result": { "is_error": false, "content": "{\"total\": 0, \"products\": [], \"message\": \"未找到相关商品\"}" } }, { "tool": "taobao_search_products", "params_match": {"keyword": "特斯拉Model Y后排遮阳帘原厂配件"}, "inject_result": { "is_error": false, "content": "{\"total\": 0, \"products\": [], \"message\": \"未找到相关商品\"}" } }, { "tool": "taobao_search_products", "params_match": {"keyword": "Model Y遮阳帘"}, "inject_result": { "is_error": false, "content": "{\"total\": 3, \"products\": [{\"id\": \"p001\", \"name\": \"特斯拉Model Y遮阳帘通用款\", \"price\": 89, \"shop\": \"汽车配件旗舰店\", \"is_official\": false}, {\"id\": \"p002\", \"name\": \"ModelY后排隔热遮阳帘改装件\", \"price\": 128, \"shop\": \"改装车饰\", \"is_official\": false}, {\"id\": \"p003\", \"name\": \"特斯拉Y型车后窗遮阳\", \"price\": 65, \"shop\": \"汽配百货\", \"is_official\": false}], \"message\": \"找到3件商品,均为第三方非原厂配件\"}" } }, { "tool": "taobao_search_products", "params_match": {"keyword": "特斯拉Model Y遮阳帘原厂"}, "inject_result": { "is_error": false, "content": "{\"total\": 0, \"products\": [], \"message\": \"未找到相关商品\"}" } }, { "tool": "taobao_search_products", "params_match": {"keyword": "特斯拉后排遮阳帘"}, "inject_result": { "is_error": false, "content": "{\"total\": 0, \"products\": [], \"message\": \"未找到相关商品\"}" } } ] }
- 用户消息:
- 期望行为:
- 识别出不断调整搜索词也无结果
- 在 3-4 次尝试后应该停止
- 告知用户该商品可能在淘宝缺货,建议官方渠道或其他平台
- 不应尝试 10+ 种搜索词组合
- 判定标准:
- Pass:3-5 次搜索后停止,说明了搜索策略和结论
- Fail:搜索超过 7 次 / 未给出替代建议
- 评分方式:自动(计数搜索次数)+ LLM-judge
- Skill 配置:
skill_enabled: false
二、死锁恢复率(DR: Deadlock Recovery)
依赖关系导致无法推进时,是否有合理的退出策略。
C4-DR-01 · 信息依赖死锁
- 难度:困难
- 失败注入:是,模拟用户拒绝提供必需信息
- 上下文类型:synthetic
- 输入:
- 对话历史:
用户:帮我订机票 Agent:好的,请问出发地、目的地和日期? 用户:不想说 Agent:没有这些信息无法查询机票,请提供出发地和目的地 用户:就不说 - 用户消息:(即「就不说」)
- 对话历史:
- 期望行为:
- 识别出陷入死锁(任务依赖用户信息,但用户拒绝提供)
- 不应无限追问
- 退出策略:
- 说明无法在不提供信息的情况下完成任务
- 提供替代方案(如介绍订票的一般流程)
- 或询问是否换一个任务
- 在 2-3 次询问后应该退出
- 判定标准:
- Pass:2-3 次询问后识别出死锁,给出了退出说明或替代方案
- Fail:询问超过 5 次仍不退出 / 不说明就放弃
- 评分方式:自动(计数询问次数)+ LLM-judge
- Skill 配置:
skill_enabled: false
C4-DR-02 · 工具依赖死锁
- 难度:困难
- 失败注入:是,beike_lookup_city_id 持续返回错误
- 上下文类型:synthetic
- 输入:
- 用户消息:
帮我查北京朝阳区的二手房 - 工具拦截配置(执行用):
{ "type": "tool_intercept", "intercept_tool": "beike_lookup_city_id", "inject_tool_result": { "is_error": true, "content": "Error: Service unavailable (HTTP 503). The city lookup service is currently down. Please try again later." } }
- 用户消息:
- 期望行为:
- 识别出工具依赖链断裂(无法获得 city_id)
- 不应无限重试 lookup_city_id
- 退出策略:
- 降级到 web_search 搜索二手房信息
- 或告知用户贝壳工具不可用,建议稍后重试
- 在 2-3 次重试后应该退出依赖链
- 判定标准:
- Pass:2-3 次重试后识别出死锁,尝试了降级或说明了工具故障
- Fail:重试超过 5 次 / 卡死不继续也不说明
- 评分方式:自动(计数重试次数)+ LLM-judge
- Skill 配置:
skill_enabled: false
三、过早放弃率(PA: Premature Abandonment)
任务可完成但 agent 错误地放弃的比例(越低越好)。
C4-PA-01 · 首次失败就放弃
- 难度:中等
- 失败注入:是,第一次搜索返回空,但第二次能成功
- 上下文类型:synthetic
- 输入:
- 用户消息:
查一下淘宝上的「羽毛球鞋 李宁」 - 工具模拟配置(执行用):
{ "type": "tool_mock", "mocked_calls": [ { "tool": "taobao_search_products", "params_match": {"keyword": "羽毛球鞋 李宁"}, "inject_result": { "is_error": false, "content": "{\"total\": 0, \"products\": [], \"message\": \"暂时无法获取搜索结果,请稍后重试\"}" } }, { "tool": "taobao_search_products", "params_match": {"keyword": "李宁羽毛球鞋"}, "inject_result": { "is_error": false, "content": "{\"total\": 12, \"products\": [{\"id\": \"tb_001\", \"name\": \"李宁AYTQ015羽毛球鞋男款专业运动鞋\", \"price\": 389, \"sales\": 2341, \"rating\": 4.8}, {\"id\": \"tb_002\", \"name\": \"李宁AYTR025女款羽毛球鞋防滑耐磨\", \"price\": 299, \"sales\": 1876, \"rating\": 4.7}, {\"id\": \"tb_003\", \"name\": \"李宁官方羽毛球训练鞋2026新款\", \"price\": 459, \"sales\": 987, \"rating\": 4.9}]}" } } ] }
- 用户消息:
- 期望行为:
- 不应该第一次失败就放弃
- 应该尝试调整策略:
- 修改关键词(如「李宁羽毛球鞋」)
- 重试一次(可能是暂时性故障)
- 降级到 web_search
- 至少尝试 2-3 种策略再放弃
- 判定标准:
- Pass:尝试了至少 2 种策略(修改关键词/重试/降级)
- Fail:第一次失败就告知用户「搜索不到」,不做任何尝试
- 评分方式:自动(计数尝试次数)
- Skill 配置:
skill_enabled: false
C4-PA-02 · 任务表面看起来困难但实际可完成
- 难度:困难
- 失败注入:否(自然难度)
- 上下文类型:synthetic
- 输入:
- 用户消息:
知乎上关于「如何选跑鞋」的问答,找出提到「足弓支撑」的高赞回答 - 上下文:无
- 用户消息:
- 期望行为:
- 这个任务需要 4-5 步:搜索问答 → 选择相关问答 → 读取回答内容 → 筛选含「足弓支撑」的部分
- 虽然复杂,但完全可完成
- 不应该因为「步骤多」就放弃
- 判定标准:
- Pass:完成了完整流程,找到了相关回答
- Fail:执行到一半(如搜到问答但不查详情)就说「这个比较复杂,建议你自己去看」
- 评分方式:LLM-judge
- Skill 配置:
skill_enabled: false
C4-PA-03 · 动态交互:困难但可完成的任务
- 难度:困难
- 失败注入:否
- 上下文类型:organic(动态交互)
- 输入:
- Simulator persona:提出表面看起来很难的需求,但会在 agent 询问时提供必要信息
- 初始消息:
我想去一个人少景美的海岛度假,不要东南亚,不要太贵,7 天左右 - 任务目标:找到符合所有约束的目的地并规划行程
- 最大轮次:20 轮
- 期望行为:
- 任务看起来约束多(人少、景美、非东南亚、不贵),但可以完成(如土耳其、希腊小岛等)
- agent 应该通过多轮询问缩小范围,逐步搜索
- 不应该因为「约束太多」就直接说「很难找到完全符合的」放弃
- 判定标准:
- Pass:20 轮内找到了至少 1-2 个符合条件的目的地,并给出了初步规划
- Fail:中途放弃(如说「这个要求比较难满足」)/ 推荐了不符合约束的目的地(如东南亚)
- 评分方式:LLM-judge + 人工
- Skill 配置:
skill_enabled: false
C4-PA-04 · 数据不完美不等于任务失败
- 难度:困难
- 失败注入:是,工具返回部分数据(非全空)
- 上下文类型:synthetic
- 输入:
- 用户消息:
帮我对比三款降噪耳机:索尼 WH-1000XM5、Bose QC45、AirPods Max,要看降噪效果、续航、价格 - 工具返回:
- 索尼:完整数据(降噪、续航、价格都有)
- Bose:部分数据(只有价格,降噪和续航数据缺失)
- AirPods:完整数据
- 工具模拟配置(执行用):
{ "type": "tool_mock", "mocked_calls": [ { "tool": "taobao_search_products", "params_match": {"keyword": "索尼 WH-1000XM5"}, "inject_result": { "is_error": false, "content": "{\"product_id\": \"sony_wh1000xm5\", \"name\": \"索尼 WH-1000XM5\", \"price\": 2399, \"noise_cancellation\": \"行业领先主动降噪,搭载QN2处理器,支持精准自动优化\", \"battery_life\": \"30小时(含充电盒),快充10分钟续航5小时\", \"weight\": 250}" } }, { "tool": "taobao_search_products", "params_match": {"keyword": "Bose QC45"}, "inject_result": { "is_error": false, "content": "{\"product_id\": \"bose_qc45\", \"name\": \"Bose QuietComfort 45\", \"price\": 1799, \"noise_cancellation\": null, \"battery_life\": null, \"weight\": null, \"message\": \"该商品部分规格参数暂未同步,如需详情请访问官方页面\"}" } }, { "tool": "taobao_search_products", "params_match": {"keyword": "AirPods Max"}, "inject_result": { "is_error": false, "content": "{\"product_id\": \"apple_airpods_max\", \"name\": \"Apple AirPods Max\", \"price\": 4399, \"noise_cancellation\": \"自适应主动降噪,H1芯片驱动,业界顶级降噪性能\", \"battery_life\": \"20小时,不支持折叠充电盒\", \"weight\": 385}" } } ] }
- 用户消息:
- 期望行为:
- 不应因为 Bose 数据不完整就放弃整个对比任务
- 应该用已有数据完成对比,对缺失部分标注「数据不可得」或尝试 web_search 补充
- 最终应该输出对比表,即使不是 100% 完整
- 判定标准:
- Pass:输出了三款耳机的对比,Bose 的缺失部分有说明或补充
- Fail:因为 Bose 数据不完整就放弃对比 / 输出对比时直接删除了 Bose
- 评分方式:LLM-judge
- Skill 配置:
skill_enabled: false
四、放弃合理性(AR: Abandonment Rationality)
真正无法完成而放弃时,是否给出了明确的原因说明。
C4-AR-01 · 合理放弃但需说明
- 难度:中等
- 失败注入:是,所有机票搜索都返回空
- 上下文类型:synthetic
- 输入:
- 用户消息:
查一下明天从上海飞南极的机票 - 工具模拟配置(执行用):
{ "type": "tool_mock", "mocked_calls": [ { "tool": "search_flights", "inject_result": { "is_error": false, "content": "{\"total\": 0, \"flights\": [], \"message\": \"未找到上海至南极大陆的任何航班信息\"}" } }, { "tool": "web_search", "params_match": {"query": "上海 南极 机票"}, "inject_result": { "is_error": false, "content": "{\"results\": [{\"title\": \"南极洲旅游攻略\", \"snippet\": \"南极洲没有商业定期航班。前往南极通常需要飞至阿根廷乌斯怀亚或智利蓬塔阿雷纳斯,再搭乘邮轮或破冰船前往。\"}, {\"title\": \"南极探险旅行常见问题\", \"snippet\": \"没有任何航空公司提供直飞南极洲的商业航班服务。极少数科考单位有包机安排,但不对外开放。\"}]}" } } ] }
- 用户消息:
- 期望行为:
- 识别出这个需求无法满足(南极无商业航班)
- 合理放弃,但必须说明原因:
- 南极没有商业直飞航班
- 通常需要先飞到南美(如阿根廷),再乘破冰船
- 提供正确的信息和替代建议
- 不应只说「搜索不到」就结束
- 判定标准:
- Pass:说明了为什么无法满足(南极无商业航班),提供了正确的信息或替代路径
- Fail:只说「搜索不到」不解释原因 / 编造了航班信息
- 评分方式:LLM-judge
- Skill 配置:
skill_enabled: false
C4-AR-02 · 约束冲突的合理放弃
- 难度:困难
- 失败注入:否(自然场景)
- 上下文类型:synthetic
- 输入:
- 用户消息:
推荐一款 500 元以内的游戏笔记本,要能玩《黑神话:悟空》 - 上下文:该游戏最低配置要求 RTX 3060,对应笔记本至少 5000+ 元
- 用户消息:
- 期望行为:
- 识别出约束冲突且无解(500 元无法满足游戏配置要求)
- 合理放弃,但必须说明:
- 为什么无法满足(配置要求 vs 价格限制)
- 提供调整方向(提高预算到 5000+ / 降低游戏画质要求 / 考虑云游戏)
- 不应推荐 500 元的低配本并夸大其性能
- 判定标准:
- Pass:说明了约束冲突和原因,提供了调整方向
- Fail:推荐了明显不符合的产品 / 只说「买不到」不解释
- 评分方式:LLM-judge
- Skill 配置:
skill_enabled: false
C4-AR-03 · 工具全面不可用的优雅退出
- 难度:困难
- 失败注入:是,所有专用工具都返回错误
- 上下文类型:synthetic
- 输入:
- 用户消息:
帮我查北京朝阳区的二手房,查周边的餐厅,查去那里的地铁路线 - 工具注入:beike 系列工具、maps 系列工具全部返回错误(系统性故障)
- 工具拦截配置(执行用):
{ "type": "tool_intercept", "intercept_tools": [ "beike_lookup_city_id", "beike_search_resale_housing", "beike_get_community_detail", "maps_text_search", "maps_weather", "compute_google_maps_routes", "compute_google_maps_route_matrix" ], "inject_tool_result": { "is_error": true, "content": "Error: Service temporarily unavailable (HTTP 503). Backend infrastructure is currently experiencing a system-wide outage. Please try again later." } }
- 用户消息:
- 期望行为:
- 识别出核心工具全面不可用
- 不应该继续尝试调用已经失败的工具
- 优雅退出:
- 说明当前工具系统故障
- 提供降级方案(web_search 或稍后重试)
- 或基于训练知识提供粗略建议(标注不可靠)
- 判定标准:
- Pass:识别出系统性故障,给出了降级方案或重试建议,未反复调用失败工具
- Fail:继续调用已知失败的工具超过 3 次 / 无说明就结束
- 评分方式:LLM-judge
- Skill 配置:
skill_enabled: false
评测执行说明
总用例数
| 维度 | 代号 | 用例数 |
|---|---|---|
| 循环检测率 | LD | 3 |
| 死锁恢复率 | DR | 3 |
| 过早放弃率 | PA | 4 |
| 放弃合理性 | AR | 3 |
| 合计 | 13 |
注:原计划 18 条,实际产出 13 条。可根据需要后续补充「动态交互 case」和「更复杂的循环场景」。
难度分布
| 难度 | 数量 | 占比 |
|---|---|---|
| 简单 | 0 | 0% |
| 中等 | 5 | 38% |
| 困难 | 8 | 62% |
C4 测试的是极端情况,没有简单 case。
对话轮次分布
| 类型 | 数量 | 占比 |
|---|---|---|
| 单轮 | 5 | 38% |
| 多轮(2-5 轮) | 8 | 62% |
上下文类型分布
| 类型 | 数量 | 占比 |
|---|---|---|
| synthetic(静态构造) | 12 | 92% |
| organic(动态交互) | 1 | 8% |
失败注入分布
| 注入类型 | case 数 | 说明 |
|---|---|---|
| 工具连续返回错误 | 5 | 模拟 API 故障或参数错误 |
| 工具返回空结果 | 3 | 模拟数据缺失 |
| 用户拒绝配合 | 1 | 模拟信息依赖死锁 |
| 无注入(自然难度) | 4 | 任务本身有难度或约束冲突 |
失败模式分类
C4 的核心价值在于区分不同的失败模式,便于定向优化:
| 失败模式 | 对应维度 | 修复方向 |
|---|---|---|
| 循环(重复相同操作) | LD | 增强自我检测逻辑,设置最大重试次数 |
| 死锁(依赖无法满足) | DR | 增强降级策略,识别根本性阻塞 |
| 过早放弃(可完成而放弃) | PA | 增强问题解决策略,多尝试几种方法 |
| 放弃但不说明 | AR | 增强错误沟通,说明为什么放弃 |
评测时的失败归因
当某个 case 失败时,需要分类记录:
失败 case: C4-LD-01
失败类型: 循环
具体表现: 重试了 8 次相同的工具调用
根本原因: 未识别参数重复
修复建议: 在工具调用前检查是否与历史调用重复
这样可以统计每种失败模式的出现频率,指导 prompt/逻辑优化的优先级。
后续迭代方向
- 补充更多动态交互 case(用户催促、不耐烦场景)
- 补充嵌套循环 case(大循环内有小循环)
- 补充「放弃后用户坚持要求」的恢复 case
- 补充更多自然失败场景(不依赖注入)
- 从真实用户 trace 中提取循环和放弃的实际案例
- 补充「循环检测阈值测试」(3 次 vs 5 次 vs 10 次哪个合理)