# 通过 OpenAIModel 和一个 api_base 把 smolagents 接到 Router One

> https://router.one/zh/integrations/smolagents 的 Markdown 镜像，供 AI 助手与爬虫使用。Router One 是 OpenAI 兼容的统一 LLM API 网关。
> 最后更新：2026-09-19

smolagents 是 Hugging Face 的 Python Agent 库：CodeAgent 让模型用 Python 代码写出动作，ToolCallingAgent 让模型用 JSON 工具调用写出动作。它的 OpenAIModel 类连接任意 OpenAI 兼容 API 服务，指向 Router One 后就能调用目录里在 /v1/chat/completions 上提供服务的所有聊天模型，每次请求都有成本和延迟 Trace；Agent 循环、Python 执行器和工具仍在你的进程里或你配置的沙箱里运行。本指南用 api_base、从环境变量读取的 Key 和模型 ID 配置一个 OpenAIModel，先跑一个不带工具的 CodeAgent，再加上内置的 WebSearchTool，并说明一次运行会发出哪些请求、max_steps 限制的是什么，以及怎样把库里的 token 统计和 Dashboard → Logs 对上。

## 安装 openai 扩展并设置凭证

使用 Python 3.10 或更新版本。安装带 openai 扩展的 smolagents：OpenAIModel 调用的是 OpenAI Python 包，缺少时会抛出 ModuleNotFoundError，消息为 Please install 'openai' extra to use OpenAIModel。toolkit 扩展装的是默认工具箱（DuckDuckGoSearchTool 用的 ddgs、VisitWebpageTool 用的 markdownify），之后设置 add_base_tools=True 时会用到；下面示例用的 WebSearchTool 只依赖核心包自带的 requests。两个扩展写在同一个方括号里，就是安装页文档给出的写法。下面是 macOS/Linux 的 shell 示例，运行前替换两个占位符：一把 Router One Key，以及当前目录中某个聊天模型的精确 ID。ROUTER_ONE_* 是本示例自己定义并显式读取的变量名；Key 直接作为 api_key 传给模型类，所以不需要设置 OPENAI_API_KEY。运行 Python 文件时沿用同一环境。

`terminal`

```bash
python -m pip install "smolagents[openai,toolkit]"
export ROUTER_ONE_API_KEY="sk-your-router-one-key"
export ROUTER_ONE_MODEL_ID="<exact-model-id-from-/models>"
```

## 把 smolagents 配置到 Router One base URL

保存为 agent.py，再运行 python agent.py。OpenAIModel 的 model_id 原样填目录里的模型 ID，若 ID 自带 provider 前缀也要保留；api_base 填带 /v1 的 base URL，它会作为 base_url 交给 OpenAI 客户端，客户端自行拼接 /chat/completions，所以一次运行里的每次模型调用都是一个 POST /v1/chat/completions；api_key 从 ROUTER_ONE_API_KEY 读取。第一个 CodeAgent 设 tools=[] 和 max_steps=4：模型写出 Python 代码，smolagents 解析代码块并在本地 Python 执行器里运行，代码调用 final_answer 或用完第四步时运行结束。return_full_result=True 让 run() 返回 RunResult 而不是只返回答案：output 是最终答案，state 是 success 或 max_steps_error，token_usage 是 API 为每个动作步和规划步报告的输入、输出 token 之和。第二个 Agent 加上 WebSearchTool()，它默认用 DuckDuckGo 引擎、不需要任何 Key：搜索是从你的进程发往 lite.duckduckgo.com 的 HTTP 请求，不会出现在 Logs 里，而这次运行的模型调用照样到达网关。两个 Agent 只差这一点，只在带工具时失败，就能定位到工具自身的网络访问。

`agent.py`

```python
import os

from smolagents import CodeAgent, OpenAIModel, WebSearchTool

model = OpenAIModel(
    model_id=os.environ["ROUTER_ONE_MODEL_ID"],
    api_base="https://api.router.one/v1",
    api_key=os.environ["ROUTER_ONE_API_KEY"],
)

# 1. No tools: every model call in this run is one POST /v1/chat/completions
agent = CodeAgent(tools=[], model=model, max_steps=4)
result = agent.run(
    "Compute the 30th Fibonacci number in Python and return it with final_answer.",
    return_full_result=True,
)
print(result.output, result.state, result.token_usage)

# 2. Same model, one built-in tool: the search leaves your process; the model calls still reach the gateway
agent = CodeAgent(tools=[WebSearchTool()], model=model, max_steps=4)
print(agent.run("Find the URL of the smolagents documentation and return it with final_answer."))
```

## smolagents 的哪个设置发出哪种请求

连接信息由 OpenAIModel 携带，每一步向模型要什么则由 Agent 类决定。下表按本指南涉及的设置，给出该填的值、它产生的请求，以及使用前要确认的能力。

| smolagents 字段 | 填什么 | 怎么验证 |
| --- | --- | --- |
| OpenAIModel → api_base | https://api.router.one/v1 | 作为 base_url 交给 OpenAI 客户端，客户端在后面拼 /chat/completions；第 1 步就报 404 not_found 说明少了 /v1 |
| OpenAIModel → api_key | 为这个 Agent 单独创建、设了 maxSpend 的 Router One Key | 第 1 步的请求出现在 Dashboard → Logs 里这把 Key 名下 |
| OpenAIModel → model_id | 精确的目录 ID | Logs 里每条 Trace 的模型与 /models 逐字一致；CodeAgent 可用当前目录中任意聊天模型 |
| CodeAgent(tools=..., model=...) | 带 stop 序列、不带 tools 字段的 Chat Completions；模型回复一个代码块，由 smolagents 解析 | 不要求工具调用能力；某一步输出解析失败记为该步错误，下一步是又一次请求 |
| ToolCallingAgent(tools=..., model=...) | 带 tools（JSON schema）和 tool_choice=required 的 Chat Completions | 模型详情页列出工具调用 |
| max_steps（默认 20，run() 也可传入） | 限制动作步数，不限制请求数或花费；到达上限时会再发一次请求写出最终答案 | RunResult.state 为 max_steps_error，最后一步带 AgentMaxStepsError |
| executor_type（默认 local） | local、blaxel、e2b、modal 或 docker | 代码在你的进程或你的沙箱里运行，网关只看到模型调用 |
| stream_outputs=True | 同一个请求，改为 stream=True 并带 stream_options include_usage | 模型页的流式支持；中途断开的流记为 HTTP 499 client_cancelled |

## 给一个 Agent 定预算，并逐次核对请求

一次 agent.run() 是多次模型请求：每个动作步是一次请求；设置了 planning_interval 时，第 1 步以及之后每隔这么多步会加一个规划步；到达 max_steps 时还会再发一次请求，根据运行记忆写出最终答案。每一步都会把整个运行记忆重新作为 messages 发送，所以输入 token 会逐步增长：max_steps 限制的是步数，不是花费。两层重试也会增加请求：OpenAIModel 内部的 OpenAI 客户端默认对连接错误和 408、409、429、5xx 响应重试 2 次，可用 client_kwargs={'max_retries': 0} 调整；模型类自身对消息里含 429 或 rate limit 的错误最多尝试 3 次，基础等待 60 秒，retry=False 可关闭，所以持续的 429 在一步里最多能产生九次尝试。每一次真正到达网关的尝试在 Dashboard → Logs 里都是独立请求，有各自的 request_id、Trace 和费用。给每个 Agent 单独一把设了 maxSpend 的 Key：失控的循环会在你设的上限处收到 HTTP 402，两层重试都不会重试 402，钱包和其他 Key 不受影响。模型类上的 requests_per_minute 是客户端侧限速，与 Key 的 rateLimit 无关。RunResult.token_usage 和 agent.monitor.get_total_token_counts() 是库对 API 报告用量的统计，每次 run() 都会重置（reset=False 除外）；费用以 Logs 记录为准。按 Key、时间、模型和 token 数对账，报障时保留 request_id。Router One 只记录模型调用元数据，不运行 Agent 的代码、工具或沙箱。

## smolagents 该填哪个模型 ID？

从 /models 页复制精确的模型 ID，保留大小写、连字符和版本后缀，不要用展示名称代替。打开该模型的详情页，核对支持的 API 端点、上下文窗口和工具调用等能力，再与 smolagents 当前选择的 provider 和功能对应。模型出现在目录里，不等于当前客户端能调用它的所有功能。建议为每个工具单独建 API Key，并设置 maxSpend 消费上限。

## smolagents 用的是哪种 API 协议？

OpenAI 兼容描述的是接口格式，不能据此推断 Chat Completions（/v1/chat/completions）、Responses（/v1/responses）和 Anthropic Messages（/v1/messages）可以互换。先核对工具当前版本、provider 配置和实际请求路径，再查模型详情与 API 兼容性事实页。一次普通对话成功，也不能证明服务端工具、历史状态或文件编辑功能都受支持。

## 在 trace 里验证 smolagents 的调用

先在 smolagents 发出一次简单文本请求，再到 Dashboard → Logs 按时间、模型和 request_id 核对 trace：tokens、花费、延迟和状态码。成功后再分别验证流式输出、工具调用和多轮历史。失败时保留实际请求路径、完整错误消息及 request_id；没有对应日志时，先查客户端配置和网络，不能仅凭客户端报错认定是网关或上游故障。

## 常见问题

### 运行在第 1 步就以 AgentGenerationError 退出，里面包着的错误是什么意思？

AgentGenerationError: Error in generating model output 包着的是模型类抛出的异常，运行会立刻退出而不是进入下一步。看里面的 HTTP 状态码。404 not_found 说明 api_base 少了 /v1：OpenAIModel 把 api_base 作为 base_url 交给 OpenAI 客户端，客户端在后面拼 /chat/completions，只填 https://api.router.one 会打到 /chat/completions，网关的消息会直接说明 base URL 必须以 /v1 结尾。401 是网关没有接受这把 Key，核对运行该文件的环境里 ROUTER_ONE_API_KEY 的值。400 里点名某个参数，则是模型拒绝了它：CodeAgent 每一步都会发送 stop 序列，而 smolagents 只对名字匹配 gpt-5*、o3*、o4*、grok-* 的模型（按 ID 最后一个斜杠之后的部分匹配）去掉 stop 参数。官方文档给出的开关是在 OpenAIModel 上写 stop=REMOVE_PARAMETER，同一个标记也能去掉任何其他关键字参数。老代码里的 OpenAIServerModel 仍然可用，它在当前源码里是 OpenAIModel 的别名；文档使用的名字是 OpenAIModel。

### CodeAgent 需要支持工具调用的模型吗，还是只有 ToolCallingAgent 需要？

只有 ToolCallingAgent 需要。它把 Agent 的工具交给模型类，OpenAIModel 把它们写进请求的 tools 字段并把 tool_choice 设为 required，所以模型必须在 /v1/chat/completions 上支持工具调用，先查模型详情页；如果回复里没有 tool_calls，smolagents 会退回到从文本里解析工具调用，可靠性更低。CodeAgent 的请求完全没有 tools 字段：工具在系统提示里描述，模型回复一个 Python 代码块，parse_code_blobs 把它取出来，取不到时退回到 markdown 的 python 代码围栏，或直接把整段输出当作代码解析。所以 CodeAgent 可用当前目录中任意聊天模型，它需要的是模型遵守代码块格式；某一步输出解析失败会记为错误，接着又是一次请求。CodeAgent 有两个选项会改变请求：use_structured_outputs_internally=True 给每一步加上 JSON response_format，需要结构化输出支持；stream_outputs=True 改为流式。不论选哪种 Agent，代码和工具都在你的进程或你配置的执行器里运行，网关只提供模型调用。

### smolagents 能通过网关用哪些模型？

选用当前目录中同时支持 smolagents 所用端点和所需功能的模型。精确 ID、当前单价与能力以 /models 及模型详情为准；不要仅按 GPT、Claude 等系列名判断兼容性。客户端能列出模型，只证明模型发现成功，仍需验证实际调用。

### 能列出模型，但调用报 400 或 404，怎么办？

先记录实际请求路径和错误消息，再核对精确模型 ID。400 可能是参数、工具类型或模型与端点不匹配；404 可能是请求路径或资源不存在，不能直接判定模型下线。若错误提示 must be called via，按它指明的端点调整客户端 provider，或换用支持当前端点的模型。不要在所有工具里统一增删 /v1 或 /chat/completions。

### 中国大陆能直连吗？

能。网关在大陆可直连、无需 VPN，配置与全球环境完全一致。

### 报 401/402/403/429 怎么排查？

先到 Dashboard → Logs 核对请求及错误消息。401 查 Key 是否传入和有效；402 查钱包余额与 maxSpend；403 查 Key 权限和访问限制；429 查请求频率、token 限额及上游限流，按错误来源处理。保留 request_id，再按错误码速查页逐项排查。

## 相关页面

- 全部接入指南：https://router.one/zh/integrations
- smolagents 的 API 错误排查：https://router.one/zh/llm-api-error-codes
- API 兼容性：端点与功能对照：https://router.one/zh/facts/api-compatibility.md
- Responses API 配置与限制：https://router.one/zh/codex-responses-api
- Goose 接入：https://router.one/zh/integrations/goose
- Mastra 接入：https://router.one/zh/integrations/mastra
- OpenAI Python SDK 接入：https://router.one/zh/integrations/openai-sdk
- 工具调用的 API 要求：https://router.one/zh/llm-tool-calling
- 按 Key 追踪模型调用成本：https://router.one/zh/llm-cost-tracking
- smolagents 官方文档：模型参考：https://huggingface.co/docs/smolagents/reference/models
- smolagents 官方文档：入门导览：https://huggingface.co/docs/smolagents/guided_tour
- smolagents 官方文档：安全代码执行：https://huggingface.co/docs/smolagents/tutorials/secure_code_execution
- 网关层负责什么：https://router.one/zh/llm-api-gateway
- OpenAI 兼容 API：https://router.one/zh/openai-compatible-api
- API 文档：https://router.one/zh/docs
- 本页规范地址：https://router.one/zh/integrations/smolagents
- 模型与每模型 token 价格：https://router.one/zh/models （markdown：https://router.one/zh/models.md ）
- 定价：https://router.one/zh/pricing
- API 文档（markdown）：https://router.one/zh/docs.md
- 公司事实（markdown）：https://router.one/zh/facts/company.md
