τ-bench 基准实战指南:用 Tool-Agent-User 交互评测工具调用 Agent,并在 Qwen3-Coder 中落地
【免费下载链接】Qwen3-CoderQwen3-Coder is the code version of Qwen3, the large language model series developed by Qwen team.项目地址: https://gitcode.com/GitHub_Trending/co/Qwen3-Coder
本文以仓库qwencoder-eval/tool_calling_eval/tau-bench为线索,系统讲解 τ-bench(Tau-Bench)这一面向真实业务领域的"工具-智能体-用户"交互基准:从基准设计思想、Airline/Retail 两大仿真环境,到安装运行、Agent 策略、用户模拟器、指标口径与自动错误识别,并展示该仓库如何使用 Qwen3-Coder 模型跑通评测脚本。读完本文,你将能够在本地完整复现 τ-bench 评测流程,并理解其底层实现原理,为后续的工具调用 Agent 能力对比提供可复用的实战方案。
一、τ-bench 是什么:动态对话中的工具-智能体-用户三角色评测
τ-bench 是一个模拟动态对话的基准测试:由语言模型模拟的用户,与一个配备领域 API 工具和策略指南的语言Agent进行多轮自然对话。Agent 需要在不脱离对话上下文的前提下,通过调用领域工具完成用户的实际诉求,例如查询航班、改签机票、处理订单退款等。
与传统的单轮代码生成或函数调用评测不同,τ-bench 的核心特征是:
- 多轮交互:用户由 LLM 模拟,每次只透露当前步骤所需的信息,Agent 必须主动询问、逐步确认;
- 真实业务规则:每个领域都附带一份策略规则(policy),Agent 必须先核实用户身份、变更数据库前需取得明确授权等;
- 状态变更可验证:评测不仅看最终答复,还要比对数据库最终状态是否与 ground truth 操作序列一致。
该基准对应的学术工作为《τ-bench: A Benchmark for Tool-Agent-User Interaction in Real-World Domains》(arXiv:2406.12045),后续官方还发布了面向双控环境的扩展版本 τ²-Bench(arXiv:2506.07982)。本仓库内置的是 τ-bench 的实现,并配套提供了 Qwen3-Coder 的评测脚本与历史轨迹数据。
二、两大仿真领域:Airline 与 Retail
τ-bench 提供两个独立的业务环境,分别对应 airline 环境目录 与 retail 环境目录。每个环境都包含四类关键资源:仿真数据、工具集合、任务集与策略规则。
2.1 Retail 零售客服域
零售域模拟在线零售公司的客服场景。其数据存放在 retail/data 下(orders.json、products.json、users.json),任务按train/test/dev三个划分文件组织,对应 tasks_train.py、tasks_test.py、tasks_dev.py。
Agent 可用的工具(定义于 retail/tools)包括:
| 工具 | 作用 |
|---|---|
find_user_id_by_email/find_user_id_by_name_zip | 通过邮箱或姓名+邮编定位用户 ID |
get_user_details/get_order_details/get_product_details | 查询用户、订单、商品详情 |
modify_pending_order_address/modify_pending_order_items/modify_pending_order_payment | 修改待处理订单的地址、商品、支付方式 |
cancel_pending_order | 取消待处理订单 |
return_delivered_order_items/exchange_delivered_order_items | 退货与换货 |
modify_user_address | 修改用户地址 |
calculate | 计算(如金额、差价) |
think | 内部思考占位工具 |
transfer_to_human_agents | 转人工(策略要求尽量避免) |
list_all_product_types | 列出全部商品类型 |
零售域的策略规则定义在 retail/rules.py,核心约束包括:Agent 必须先通过邮箱或"姓名+邮编"确认用户 ID 才能继续任何任务;用户 ID 找不到则不得继续;任何对后端数据库的变更(地址更新、退款、订单取消)都必须与用户确认交易细节并取得明确的"是"的授权;Agent 应通过工具自行解决问题而不是转人工;不得编造用户或工具未提供的信息;一次只能调用一个工具,调用工具的同时不得回复用户。
2.2 Airline 航空客服域
航空域模拟航空公司客服,数据位于 airline/data(flights.json、reservations.json、users.json),工具定义于 airline/tools,涵盖search_direct_flight、search_onestop_flight、book_reservation、cancel_reservation、update_reservation_flights、update_reservation_baggages、update_reservation_passengers、get_reservation_details、send_certificate等。
任务定义在 airline/tasks.py,每个任务由instruction(给用户模拟器的指令)、actions(ground truth 操作序列)和outputs(期望在回复中出现的关键输出)组成。例如某任务要求用户从纽约飞西雅图、5 月 20 日单程、不早于 11 点 EST、经济舱、偏好直飞但允许一次中转、价格最低优先、携带 3 件行李、不使用保险、优先用两张证书支付等,其 ground truth 操作即为一次携带完整参数的book_reservation调用。这类任务验证的是 Agent 在模糊、多约束的自然语言诉求下还原出精确 API 调用的能力。
三、安装与环境准备
τ-bench 的安装与运行入口位于 qwencoder-eval/tool_calling_eval/tau-bench。从源码安装(会同时安装所需依赖包):
cd qwencoder-eval/tool_calling_eval/tau-bench pip install -e .依赖项在 setup.py 中声明,包括openai>=1.13.3、mistralai>=0.4.0、anthropic>=0.26.1、google-generativeai>=0.5.4、tenacity>=8.3.0、termcolor>=2.4.0、numpy>=1.26.4、litellm>=1.41.0。可以看出,评测链路统一通过litellm对接各家模型服务,因此只要模型 API 兼容 OpenAI 协议即可接入。
运行前需将对应的 API Key 配置为环境变量:
OPENAI_API_KEY=... ANTHROPIC_API_KEY=... GOOGLE_API_KEY=... MISTRAL_API_KEY=...若使用自部署的 OpenAI 兼容服务(例如评测 Qwen3-Coder),则按 airline-qwen3-coder.bash 中的注释所示,额外配置OPENAI_API_BASE指向你的服务地址:
export OPENAI_API_BASE=YOUR_API_BASE export OPENAI_API_KEY=YOUR_API_KEY四、运行评测:命令与参数全解
4.1 基本运行命令
在 retail 环境上运行一个 tool-calling(原生函数调用)策略的 Agent:
python run.py --agent-strategy tool-calling --env retail --model gpt-4o --model-provider openai --user-model gpt-4o --user-model-provider openai --user-strategy llm --max-concurrency 10--max-concurrency需要根据你的 API 限额设置。只运行指定任务时使用--task-ids:
python run.py --agent-strategy tool-calling --env retail --model gpt-4o --model-provider openai --user-model gpt-4o --user-model-provider openai --user-strategy llm --max-concurrency 10 --task-ids 2 4 6该命令将只运行任务 ID 为 2、4、6 的任务。
4.2 全部命令行参数
入口脚本为 run.py,其通过argparse解析参数并组装成RunConfig。完整参数说明如下:
| 参数 | 类型/默认值 | 说明 |
|---|---|---|
--num-trials | int,默认1 | 每个任务重复的试验次数,多次试验用于计算 Pass^k |
--env | retail/airline,默认retail | 选择评测环境 |
--model | str | Agent 使用的模型名 |
--model-provider | str(litellm provider 列表) | Agent 模型的提供方 |
--user-model | str,默认gpt-4o | 用户模拟器使用的模型 |
--user-model-provider | str | 用户模拟器模型的提供方 |
--agent-strategy | tool-calling/act/react/few-shot,默认tool-calling | Agent 的推理-行动策略 |
--temperature | float,默认0.0 | 行动模型的采样温度 |
--task-split | train/test/dev,默认test | 任务划分(目前仅 retail 域支持) |
--start-index | int,默认0 | 起始任务索引 |
--end-index | int,默认-1 | 结束任务索引,-1表示运行全部 |
--task-ids | int 列表 | 可选,只运行指定 ID 的任务 |
--log-dir | str,默认results | 结果输出目录 |
--max-concurrency | int,默认1 | 并行运行的任务数 |
--seed | int,默认10 | 随机种子 |
--shuffle | int,默认0 | 是否打乱任务顺序 |
--user-strategy | human/llm/react/verify/reflection,默认llm | 用户模拟策略 |
--few-shot-displays-path | str | few-shot 策略所需的 jsonlines 展示文件路径 |
4.3 底层执行与检查点机制
tau_bench/run.py 中的run()是核心执行函数。它先做合法性断言(环境、provider、策略、任务划分、用户策略均需在允许集合内),随后以{log_dir}/{agent_strategy}-{model}-{temperature}_range_{start}-{end}_user-{user_model}-{user_strategy}_{time_str}.json的命名生成检查点文件,并用ThreadPoolExecutor按max_concurrency并行执行任务。每个任务的执行会被捕获异常——出错时该任务 reward 记为 0.0 并附带 traceback,保证单个任务失败不影响整批评测。每完成一个任务即增量写入检查点,中断后可恢复,结果最终汇总保存到检查点文件。
从 tau_bench/run.py 的agent_factory()可以看到四种 Agent 策略的映射:
tool-calling:ToolCallingAgent,走原生函数调用(native tool calling);act:ChatReActAgent(use_reasoning=False),对应论文中的 Act 策略(只输出 Action,不输出 Thought);react:ChatReActAgent(use_reasoning=True),对应 ReAct 策略(Thought + Action 交替);few-shot:FewShotToolCallingAgent,需通过--few-shot-displays-path提供示例展示,仓库已在 few_shot_data 提供 Airline 与 Retail 两个域的 few-shot jsonlines 文件。
五、Agent 策略的实现原理
5.1 Tool-calling:原生函数调用
ToolCallingAgent 将环境 wiki 作为 system 提示、用户初始消息作为首条 user 消息,然后循环调用 litellm 的completion(..., tools=self.tools_info)让模型原生发起工具调用。每次模型返回消息后,message_to_action()解析tool_calls[0]得到Action(name, kwargs);若没有工具调用,则退化为respond动作(回复用户)。工具结果以role: "tool"消息回填进对话历史,直到env_response.done为真或达到max_num_steps=30步上限。
值得注意的细节:源码中if action.name != RESPOND_ACTION_NAME时只保留模型返回的第一个工具调用(next_message["tool_calls"][:1]),与零售策略规则中"一次只能调用一个工具"的约束保持一致。
5.2 Act / ReAct:文本协议驱动的 JSON Action
ChatReActAgent 不使用原生工具调用,而是要求模型按固定文本协议输出。ReAct 模式下每条消息需遵循:
Thought: <单行推理,不包含多余行> Action: {"name": <动作名>, "arguments": <JSON 格式的参数>}Act 模式则省略 Thought,直接输出 Action。generate_next_step()从模型回复中提取Action:之后的文本并用json.loads解析;若解析失败则兜底为一次respond动作,避免格式错误导致整轮崩溃。工具执行结果以API output: ...前缀回填,便于模型区分工具输出与用户消息。这两种策略不依赖模型的函数调用能力,因此可用来横向对比"原生函数调用"与"文本协议"两种范式下的表现差异。
六、用户模拟器:llm / react / verify / reflection
默认使用gpt-4o作为用户模拟器、策略为llm。通过--user-model与--user-strategy可自由组合。例如使用 Claude 作为用户模拟器:
python run.py --agent-strategy tool-calling --env retail --model gpt-4o --model-provider openai --max-concurrency 10 --user-model claude-3-5-sonnet-20240620 --user-model-provider anthropic --user-strategy llm四种非人工策略定义于 tau_bench/envs/user.py:
llm(默认):LLMUserSimulationEnv维护完整对话历史,其 system prompt 明确要求:每次只生成一行用户消息、不要把全部指令一次性给出、不编造指令中未提供的信息(如订单号)、目标达成后单独输出###STOP###结束对话、用自己的话复述指令而非照搬、尽量自然并贴合指令中的人物性格。react:ReactUserSimulationEnv要求模拟器先输出内部 Thought(不会发送给 Agent),再输出一行 User Response。README 给出了示例输出:
Thought: I should provide my name and zip code as I wasn't given an email address to use. User Response: Sure, my name is Yusuf Rossi, and my zip code is 19122.其parse_response()会依次识别###STOP###、Thought:、User Response:三种模式并抽取实际发送内容。
verify:VerifyUserSimulationEnv在模拟器生成回复后,用一次额外的 LLM 判定(verify(),上限max_attempts=3)检查该回复是否令用户满意,不满意则提示模拟器重新生成。验证 prompt 将对话转写为 Customer/Agent 记录并要求输出true/false分类。reflection:ReflectionUserSimulationEnv在验证不通过时,额外要求模拟器对对话进行反思(reflect(),输出 Reflection + 修正后的 Response),再重新生成并验证,上限max_attempts=2。
此外还有human策略(HumanUserSimulationEnv),直接通过命令行input()让真人充当用户,便于人工走查。所有策略通过UserStrategy枚举与load_user()工厂方法统一装配。
七、评测指标:reward 与 Pass^k 的口径
7.1 任务成功判定
tau_bench/envs/base.py 中Env.step()负责推进状态:respond动作把 Agent 回复交给用户模拟器并检查是否出现###STOP###;工具调用则通过工具名在tools_map中查找并invoke,未知名动作返回Unknown action,工具内部抛错则返回Error: ...。对话结束时调用calculate_reward(),其成功判定由两部分组成:
- 数据库状态哈希一致:将 Agent 实际执行后的数据状态做规范化哈希,与"按 ground truth actions 顺序执行后"的状态哈希比对(
consistent_hash/to_hashable负责对 dict/list/set 递归排序规整); - 关键输出覆盖:任务
outputs中列出的每个关键输出字符串,必须出现在 Agent 的respond内容中(匹配时忽略大小写与逗号)。
两者任一不满足,reward 即为 0.0。这种"状态哈希 + 输出包含"的双重校验,比单纯看对话是否以###STOP###结束要严格得多。
7.2 Pass^k 指标
tau_bench/run.py 的display_metrics()在评测结束后输出平均 reward 与 Pass^k 序列。其计算逻辑为:统计每个任务在num_trials次试验中的成功次数 c,然后对每个 k 计算 $\text{Pass}^k = \frac{1}{N}\sum_i \frac{\binom{c_i}{k}}{\binom{T}{k}}$,即"k 次试验中至少一次成功的任务比例"的估计量。README 的 Leaderboard 正是用这一指标组织的:
Airline
| Strategy | Pass^1 | Pass^2 | Pass^3 | Pass^4 |
|---|---|---|---|---|
| TC (claude-3-5-sonnet-20241022) | 0.460 | 0.326 | 0.263 | 0.225 |
| TC (gpt-4o) | 0.420 | 0.273 | 0.220 | 0.200 |
| TC (claude-3-5-sonnet-20240620) | 0.360 | 0.224 | 0.169 | 0.139 |
| TC (mistral-large-2407) | ?? | ?? | ?? | ?? |
| TC (gpt-4o-mini) | 0.225 | 0.140 | 0.110 | 0.100 |
| Act (gpt-4o) | 0.365 | 0.217 | 0.160 | 0.140 |
| ReAct (gpt-4o) | 0.325 | 0.233 | 0.185 | 0.160 |
Retail
| Strategy | Pass^1 | Pass^2 | Pass^3 | Pass^4 |
|---|---|---|---|---|
| TC (claude-3-5-sonnet-20241022) | 0.692 | 0.576 | 0.509 | 0.462 |
| TC (gpt-4o) | 0.604 | 0.491 | 0.430 | 0.383 |
| TC (claude-3-5-sonnet-20240620) | 0.626 | 0.506 | 0.435 | 0.387 |
| TC (mistral-large-2407) | ?? | ?? | ?? | ?? |
| TC (gpt-4o-mini) | ?? | ?? | ?? | ?? |
| Act (gpt-4o) | ?? | ?? | ?? | ?? |
| ReAct (gpt-4o) | ?? | ?? | ?? | ?? |
其中 TC 即tool-calling策略(论文中报告的 function-calling 策略)。这些数字均为官方 README 发布的历史数据,可作为复现实验的参照基线;新模型的成绩需要通过本地运行获得。
八、自动错误识别:故障归属与故障类型
由于轨迹往往很长、约束复杂,人工定位错误既困难又耗时。τ-bench 提供了自动错误识别工具 auto_error_identification.py,可完成两类标注:
- 故障归属(Fault assignment):判断导致失败的责任实体——用户(user)、Agent(agent)或环境(environment),对应源码中的
FaultAuthor枚举; - 故障类型分类(Fault type classification):从源码中的
FaultType枚举看,包括called_wrong_tool(调用了错误的工具)、used_wrong_tool_argument(工具参数错误)、goal_partially_completed(目标部分完成)、other(其他)。
两类标签均附带描述文本。运行方式:
python auto_error_identification.py --env <airline/retail> --platform openai --results-path <the path to your results file here> --max-concurrency 16 --output-path test-auto-error-identification --max-num-failed-results 10其中--results-path指向评测产生的结果文件,--max-num-failed-results限制分析的失败结果数量。从源码看,该工具按任务逐一提取原始轨迹(user_instruction、traj、ground_truth_actions、ground_truth_outputs),并用 LLM 并行完成归属与类型判定后输出结构化 JSON。需要特别提醒:该功能依赖 LLM 判定,可能产生不准确的识别结果;此外,由于评测脚本近期被重写为更类型安全、更易扩展的版本,如果结果文件结构不匹配导致报错,可能需要重新运行基准测试生成新格式的结果文件。
九、历史轨迹:低成本复现与结果比对
τ-bench 的运行成本可能较高,官方在./historical_trajectories目录提供了 Airline 与 Retail 环境的历史轨迹。本仓库中对应路径为 historical_trajectories,其中不仅包含gpt-4o-airline.json、gpt-4o-retail.json、sonnet-35-new-airline.json、sonnet-35-new-retail.json等参考轨迹,还包含qwen3-coder-airline.json与qwen3-coder-retail.json两份 Qwen3-Coder 的实测轨迹。这些文件记录了完整的对话轮次、工具调用序列与最终结果,适合用于离线分析 Agent 的行为模式、复现错误场景,或作为 few-shot 示例与基线参照。
十、在 Qwen3-Coder 项目中运行 τ-bench
本仓库为 Qwen3-Coder 模型封装好了现成的评测脚本:airline-qwen3-coder.bash 与 retail-qwen3-coder.bash。脚本内容如下:
# export OPENAI_API_BASE=YOUR_API_BASE # export OPENAI_API_KEY=YOUR_API_KEY python run.py --num-trials 1 --agent-strategy tool-calling --env retail --model Qwen3-Coder --model-provider openai --user-model gpt-4o-2024-11-20 --user-model-provider openai --user-strategy llm --max-concurrency 20 --log-dir retail --temperature 0.0airline 脚本除--env airline、--log-dir airline外与上述命令一致。从脚本可以看到评测 Qwen3-Coder 时的典型配置:
- 接入方式:
--model Qwen3-Coder --model-provider openai,即通过 OpenAI 兼容协议接入自部署的模型服务(需在脚本头部设置OPENAI_API_BASE与OPENAI_API_KEY); - 用户模拟器:
--user-model gpt-4o-2024-11-20 --user-model-provider openai --user-strategy llm,使用 GPT-4o 作为用户模拟器; - 评测设置:单次试验(
--num-trials 1)、原生函数调用策略、温度 0.0 保证可复现、--max-concurrency 20并行提速,结果输出到独立的airline/retail目录。
运行完成后,可结合 tau_bench/run.py 打印的平均 reward 与 Pass^k 结果,以及 historical_trajectories 中的历史轨迹,对 Qwen3-Coder 的工具调用能力做定量与定性分析。
十一、许可与引用
τ-bench 的许可见仓库内独立的 LICENSE 文件。若在学术工作中使用该基准,官方推荐引用:
@misc{yao2024tau, title={$\tau$-bench: A Benchmark for Tool-Agent-User Interaction in Real-World Domains}, author={Shunyu Yao and Noah Shinn and Pedram Razavi and Karthik Narasimhan}, year={2024}, eprint={2406.12045}, archivePrefix={arXiv}, primaryClass={cs.AI}, } @misc{barres2025tau2, title={$\tau^2$-Bench: Evaluating Conversational Agents in a Dual-Control Environment}, author={Victor Barres and Honghua Dong and Soham Ray and Xujie Si and Karthik Narasimhan}, year={2025}, eprint={2506.07982}, archivePrefix={arXiv}, primaryClass={cs.AI}, }遇到基准本身的问题,可通过仓库的 issues 或 pull requests 反馈;官方建议以扩展版本 τ²-Bench 作为该基准的最新版本使用。
【免费下载链接】Qwen3-CoderQwen3-Coder is the code version of Qwen3, the large language model series developed by Qwen team.项目地址: https://gitcode.com/GitHub_Trending/co/Qwen3-Coder
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考