☰
Tau2-bench + vLLM 本地部署调用:用 TaoToken 统一 Key 打通评测链路
2026/9/25 5:50:49 网站建设 项目流程

1. Tau2-bench 跑本地模型,为什么 Key 管理会变成拦路虎

Tau2-bench 是当下做多轮工具调用评测时绕不开的一套基准,它把 agent 与 user 两个角色放进同一个对话循环里,用真实业务域(telecom、banking、retail 等)的任务脚本去压测模型的工具选择、参数填充和多轮记忆能力。相比只看单轮问答的评测集,Tau2-bench 更接近真实 Agent 产品的运行形态,所以很多团队在选型阶段都会拿它跑一轮。

问题出在部署环节。Tau2-bench 官方仓库的文档偏向"能跑就行",对 vLLM 本地推理服务的对接说明非常薄。你按 README 走一遍,大概率会卡在三件事上:vLLM 启动时没带工具调用解析参数,导致 agent 侧拿不到结构化 tool_calls;环境变量里一堆 API Key 不知道该填还是该空;litellm 对本地模型没有价格映射,日志里刷满 "This model isn't mapped yet" 的报错。

更麻烦的是 Key 分散。Tau2-bench 内部通过 litellm 统一发请求,而 litellm 又会读取 OPENAI_API_KEY、ANTHROPIC_API_KEY 等多个环境变量。如果你同时还要接云端模型做对照实验,就会陷入"本地一套 Key、云端一套 Key、评测脚本再一套 Key"的混乱状态。我试过在三个终端里来回 export,结果跑错环境把云端额度刷掉了一截。

这篇就按"一次配置跑通全流程"的目标来写:vLLM 负责本地推理,litellm 负责协议适配,TaoToken 的统一 Key 负责把云端模型入口收敛到一个地方。适合正在做 Agent 评测、需要本地+云端混合跑分的同学。

2. 前置准备:TaoToken 统一 Key 与 vLLM 环境

先说 TaoToken 在这条链路里的位置。它提供的是 OpenAI 兼容的 API 入口,你拿一个 Key 就能访问多种模型,省去为每个厂商单独维护密钥的麻烦。对 Tau2-bench 这种依赖 litellm 的评测框架来说,只要把 base_url 指向 TaoToken 的 API 地址,litellm 就会把它当成一个标准的 OpenAI provider 来调用。

注册和拿 Key 的入口在这里:

控制台与 API Key 管理:https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite

接入文档(含各语言示例):https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite

API 基础地址是https://taotoken.net/api,注意这个地址不带任何查询参数,直接作为 OpenAI SDK 的base_url使用即可。Key 的格式和 OpenAI 一致,放在Authorization: Bearer <key>头里。

vLLM 侧的准备相对标准,Python 3.10+、CUDA 环境、模型权重下载到位就行。建议用独立虚拟环境,避免和 Tau2-bench 的依赖打架:

python -m venv venv-vllm source venv-vllm/bin/activate pip install vllm

Tau2-bench 本身用 uv 管理依赖,克隆仓库后执行uv sync即可。两个环境分开装,是因为 vLLM 对 torch 版本比较挑,混在一起容易出 CUDA 版本冲突。

3. 可复制配置:vLLM 启动参数与 litellm 代理骨架

3.1 vLLM 启动:工具调用参数不能省

Tau2-bench 的 agent 需要模型返回结构化的工具调用,所以 vLLM 启动时必须显式开启工具调用能力。下面这条命令以 Qwen 系列模型为例:

vllm serve /root/models/Qwen3.5-2B \ --host 0.0.0.0 \ --port 8001 \ --served-model-name Qwen3.5-2B \ --enable-auto-tool-choice \ --tool-call-parser qwen3_coder

几个参数的作用值得说清楚。--served-model-name决定了后续请求里model字段要填什么,必须和 Tau2-bench 启动脚本里的模型 ID 完全一致,大小写都不能错。--enable-auto-tool-choice打开自动工具选择,模型会在需要时主动产出 tool_calls 而不是把调用意图写进正文。--tool-call-parser指定解析器,Qwen 系列用qwen3_coder,如果你换 Llama 或 Mistral,解析器名字要相应调整,填错会导致 tool_calls 解析为空。

启动后看到Uvicorn running on http://0.0.0.0:8001就说明服务起来了。此时/v1/models应该能列出你 serve 的模型名。

3.2 环境变量:本地调用时 Key 置空

Tau2-bench 会读取一批环境变量,本地推理场景下这些 Key 全部留空即可,同时关掉 OpenRouter 相关的检索配置:

export ANTHROPIC_API_KEY="" export OPENAI_API_KEY="" export ELEVENLABS_API_KEY="" export DEEPGRAM_API_KEY="" # export OPENROUTER_API_KEY=""

这里有个容易踩的坑:如果你之前 shell 里已经 export 过真实的 OPENAI_API_KEY,Tau2-bench 可能会拿它去请求云端而不是本地。建议在启动脚本里显式覆盖为空字符串,而不是依赖"没设置"。

3.3 litellm 代理配置:把云端入口收敛到 TaoToken

如果你只跑本地模型,可以跳过这节。但多数评测场景需要本地模型和云端模型对照,这时候 litellm 的配置就派上用场了。在项目根目录建一个litellm_config.yaml:

model_list: - model_name: qwen-local litellm_params: model: openai/Qwen3.5-2B api_base: http://localhost:8001/v1 api_key: "" - model_name: gpt-cloud litellm_params: model: openai/gpt-4o-mini api_base: https://taotoken.net/api api_key: os.environ/TAOTOKEN_API_KEY

model_name是你对外暴露的别名,Tau2-bench 里填这个;litellm_params.model里的openai/前缀告诉 litellm 用 OpenAI 协议发请求。云端那条把api_base指向 TaoToken,Key 从环境变量读,这样配置文件里不会出现明文密钥。

启动 litellm 代理:

export TAOTOKEN_API_KEY="sk-你的key" litellm --config litellm_config.yaml --port 4000

之后 Tau2-bench 只需要把api_base指向http://localhost:4000,就能通过别名在本地模型和云端模型之间切换,不用改任何评测脚本。

3.4 Tau2-bench 启动脚本

回到 Tau2-bench 本身,启动命令的关键是把 agent 和 user 两个 LLM 的api_base都指向你的推理入口:

uv run tau2 run \ --agent-llm-args '{"api_key": "", "api_base": "http://localhost:8001/v1"}' \ --user-llm-args '{"api_key": "", "api_base": "http://localhost:8001/v1"}' \ --agent-llm openai/Qwen3.5-2B \ --user-llm openai/Qwen3.5-2B \ --domain telecom \ --num-trials 1 \ --num-tasks 5

如果走 litellm 代理,把api_base换成http://localhost:4000,模型名换成qwen-local或gpt-cloud即可。--num-tasks 5是先用小样本验证链路,跑通后再放大。

4. 验证请求:curl 检查与成功结果判读

配置写完别急着跑全量评测,先用 curl 确认 vLLM 和 TaoToken 两个入口都能正常响应。

先验证本地 vLLM 的工具调用能力:

curl http://localhost:8001/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "Qwen3.5-2B", "messages": [{"role": "user", "content": "北京天气怎么样"}], "tools": [{ "type": "function", "function": { "name": "get_weather", "parameters": {"type": "object", "properties": {"city": {"type": "string"}}} } }], "tool_choice": "auto" }'

重点看返回的choices[0].message.tool_calls字段。如果它是个非空数组,里面function.name是get_weather,说明工具调用链路通了。如果tool_calls是 null 而正文里出现类似<tool_call>的文本,那就是--tool-call-parser参数没生效,回去检查解析器名字。

再验证 TaoToken 入口:

curl https://taotoken.net/api/v1/chat/completions \ -H "Authorization: Bearer $TAOTOKEN_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gpt-4o-mini", "messages": [{"role": "user", "content": "回复 OK 两个字母"}] }'

返回里choices[0].message.content有内容、usage字段有 token 计数,就说明 Key 和地址都对了。

最后跑 Tau2-bench 的小样本,成功时终端会逐条打印任务进度,末尾给出 pass rate 和平均对话轮数。如果看到This model isn't mapped yet的 ERROR 日志但任务仍在推进,说明只是计费映射缺失,不影响评测结果,下一节讲怎么处理。

5. 本篇常见错排查

5.1 litellm 报 "This model isn't mapped yet"

这是最高频的报错,完整形态是:

ERROR | tau2.utils.llm_utils:get_response_cost:129 - This model isn't mapped yet. model=Qwen3.5-2B, custom_llm_provider=openai.

原因是 Tau2-bench 用 litellm 的completion_cost计算 token 花费,而 litellm 内置的价格表里没有你的本地模型名。两种解法:一是往 litellm 的价格映射文件里加一条自定义条目,二是直接在代码里关掉计费。快速验证阶段推荐第二种,打开tau2-bench/src/tau2/utils/llm_utils.py,找到get_response_cost函数,把第 129 行的logger.error(e)注释掉:

def get_response_cost(response: ModelResponse) -> float: response.model = _parse_ft_model_name(response.model) try: cost = completion_cost(completion_response=response) except Exception as e: # logger.error(e) return 0.0 return cost

这样异常被吞掉,函数返回 0.0,评测继续跑。注意这只是跳过计费统计,不影响对话和工具调用逻辑。

5.2 tool_calls 为空或解析失败

如果 curl 测试时tool_calls是 null,按顺序检查三处:vLLM 启动命令里--enable-auto-tool-choice和--tool-call-parser是否都带了;解析器名字是否匹配模型系列;请求体里tools字段格式是否符合 OpenAI 规范。三者缺一都会导致解析失败。

5.3 请求打到了云端而不是本地

表现是评测速度异常快、或者日志里出现云端模型名。根因通常是环境变量里残留了真实的 OPENAI_API_KEY,litellm 优先用了它。解决方式是在启动 Tau2-bench 的同一个 shell 里显式export OPENAI_API_KEY="",或者用env -i清空环境后再启动。

5.4 端口冲突与模型名不一致

vLLM 默认 8000,litellm 默认 4000,Tau2-bench 脚本里的api_base端口必须和实际监听端口一致。模型名不一致的报错通常是 404 或 "model not found",对照--served-model-name和脚本里的--agent-llm参数逐字核对。

6. 把 Key 收敛之后,评测链路才真正可维护

跑通之后回头看,Tau2-bench 本身的评测逻辑并不复杂,真正消耗时间的是环境拼接。vLLM 负责推理、litellm 负责协议转换、TaoToken 负责把云端模型入口统一成一个 Key,三层各司其职之后,切换模型只需要改一行配置。

如果你后续要做长期编码类 Agent 的评测,或者需要频繁在多个模型间做 A/B 对照,可以考虑用 Coding Plan 把常用模型的调用额度固定下来,避免每次实验都临时申请 Key:

Coding Plan 入口:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite

需要单独调试某个模型的工具调用行为时,模型对话页面可以直接发请求看原始返回,比在评测脚本里加日志快得多:

模型对话:https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite

Key 的创建和轮换在控制台的 API Keys 页面完成,建议给评测环境单独建一个 Key,方便按项目追踪用量:

API Keys 管理:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite

最后留一个实操建议:把 vLLM 启动命令、litellm 配置、Tau2-bench 启动脚本写成一个run_eval.sh,环境变量在脚本开头统一 export。这样下次换机器或者换模型,只改脚本里的模型路径和别名,其余部分原样复用,能省掉大量重复排查。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询