通过 OpenAI 兼容 provider 把 OpenHands agent 接到 Router One
OpenHands 是开源的软件开发 agent,提供终端界面、给 CI 用的 headless 模式,以及基于 Docker 的 GUI 服务。它自己运行工具循环,每一步都按你配置的 LLM 计费。它的模型层是 LiteLLM,因此 OpenAI 兼容网关是官方文档写明的接入方式:填一次 openai/ 前缀的模型 ID 和 Router One base URL,agent 的每一步(包括记忆压缩器的总结请求)都会成为同一把 Key 上有 Trace 的请求。网关在大陆可直连,支付宝或银行卡即可充值。本指南覆盖 OpenHands CLI 的设置界面、headless 与容器运行用的 LLM_* 环境变量,以及各模型系列实际到达的端点。
安装 CLI,并在 Advanced 模式下打开 LLM 设置
用 uv tool install openhands --python 3.12(要求 Python 3.12 及以上)或官方安装脚本安装 CLI。首次运行会直接进入 LLM 设置;之后按 Ctrl+P 选择 Settings。把 Settings Mode 从 Basic 切到 Advanced:Basic 模式只有 provider 和模型下拉框、没有 Base URL 字段,请求会直接发给供应商。Advanced 模式要求同时填写 Custom Model 和 Base URL,并且原样保存 Custom Model 字符串,不会自动补 provider 前缀。填入 openai/ 加精确目录 ID、带 /v1 的 base URL,以及一把专用的 Router One Key:
# OpenHands CLI → Ctrl+P → Settings → Settings Mode: Advanced Custom Model: openai/<exact-model-id-from-/models> Base URL: https://api.router.one/v1 API Key: sk-your-router-one-key # Saved to ~/.openhands/agent_settings.json as llm.model / llm.base_url / llm.api_key
把 OpenHands 配置到 Router One base URL
headless 运行、CI 任务或没有保存设置的容器,可以导出三个 LLM_* 变量,再用 --override-with-envs 启动 OpenHands。不带这个参数时,CLI 会打印警告并忽略这些变量;带上后,它们只在本次运行覆盖 ~/.openhands/agent_settings.json,不会保存到文件。尚无设置文件时,LLM_API_KEY 和 LLM_MODEL 必填,LLM_BASE_URL 则决定请求发往 Router One 而不是供应商默认地址。agent 和记忆压缩器都会使用覆盖后的模型:
# Headless / CI / container run: the values apply only with --override-with-envs export LLM_BASE_URL=https://api.router.one/v1 export LLM_API_KEY=sk-your-router-one-key export LLM_MODEL=openai/<exact-model-id-from-/models> openhands --override-with-envs --headless -t "List the test commands in this repo"
各模型 ID 实际到达哪个端点
LiteLLM 把开头的 openai/ 当作指令:对这个 base URL 使用 OpenAI 协议。它会去掉第一段,把剩余部分作为 model 字段发送,所以安全写法是 openai/ 加完整目录 ID,目录 ID 本身已带厂商段;OpenHands 文档对代理场景写明的正是 openai/<proxy-prefix>/<model-name> 形式。走哪条路径由模型字符串决定:OpenHands 把包含 gpt-5 的 ID 走 Responses API,其余走 Chat Completions,除非 LiteLLM 模型元数据或能力覆盖另有指定。Router One 对 GPT 系列 ID 原生提供 /v1/responses,所以两条路径都用同一个 /v1 base URL。Responses 路径上 OpenHands 默认发送 store: false、reasoning effort 为 high,并请求加密的推理内容;先在 Trace 里确认第一步 GPT 请求成功,再依赖它。
| Custom Model / LLM_MODEL | OpenHands 发送的 model 字段 | 请求路径 |
|---|---|---|
| openai/anthropic/claude-sonnet-5 | anthropic/claude-sonnet-5(去掉第一个 openai/) | /v1/chat/completions |
| openai/google/gemini-3.5-flash、openai/grok-4.6 | 前缀之后的目录 ID | /v1/chat/completions |
| openai/openai/gpt-5.5 | openai/gpt-5.5(GPT-5 系列 ID 走 Responses 路径) | /v1/responses |
每一步都带工具定义,压缩器是第二个调用方
OpenHands 每一步都用原生 function calling 发送终端和文件编辑工具的定义,agent 不会发出不带工具的纯文本请求:请选择详情页在上表端点上列出工具调用能力的模型。记忆压缩默认开启,它用同一模型、Key 和 base URL 再建一个 LLM 客户端,单独发送总结请求,在 Trace 里显示为独立的行。隔离环境、命令执行和 agent 循环都在应用侧:Router One 记录每次模型调用的 tokens、费用和状态,不运行 agent。OpenHands 自己显示的费用来自 LiteLLM 价格表以及可选的 input_cost_per_token、output_cost_per_token 字段,只能当估算,以 Trace 为准核账。一个任务可能发出几十次请求,请给 OpenHands 单独建 Key 并设置 maxSpend 上限;这把 Key 会以明文保存在 agent_settings.json 里。
OpenHands 该填哪个模型 ID?
从 /models 页复制精确的模型 ID,保留大小写、连字符和版本后缀,不要用展示名称代替。打开该模型的详情页,核对支持的 API 端点、上下文窗口和工具调用等能力,再与 OpenHands 当前选择的 provider 和功能对应。模型出现在目录里,不等于当前客户端能调用它的所有功能。建议为每个工具单独建 API Key,并设置 maxSpend 消费上限。
OpenHands 用的是哪种 API 协议?
OpenAI 兼容描述的是接口格式,不能据此推断 Chat Completions(/v1/chat/completions)、Responses(/v1/responses)和 Anthropic Messages(/v1/messages)可以互换。先核对工具当前版本、provider 配置和实际请求路径,再查模型详情与 API 兼容性事实页。一次普通对话成功,也不能证明服务端工具、历史状态或文件编辑功能都受支持。
在 trace 里验证 OpenHands 的调用
先在 OpenHands 发出一次简单文本请求,再到 Dashboard → Logs 按时间、模型和 request_id 核对 trace:tokens、花费、延迟和状态码。成功后再分别验证流式输出、工具调用和多轮历史。失败时保留实际请求路径、完整错误消息及 request_id;没有对应日志时,先查客户端配置和网络,不能仅凭客户端报错认定是网关或上游故障。
常见问题
模型 ID 本来就以 anthropic/ 或 openai/ 开头,为什么还要再加 openai/?
两个前缀含义不同。最前面的 openai/ 是 LiteLLM 的路由指令,OpenHands 在 Advanced 模式下需要它,发送前会去掉;目录 ID 里的 anthropic/ 或 openai/ 是模型名的一部分,Router One 按它识别模型。写成 openai/gpt-5.5 只会发送 gpt-5.5 本身,Router One 可能按别名接受,但 openai/openai/gpt-5.5 发送的才是精确目录 ID,应保留这种写法。Custom Model 字段和 LLM_MODEL 都遵循同一规则。
每次启动都要导出 LLM_* 变量吗?
不用。设置界面保存的值存放在 ~/.openhands/agent_settings.json,每次启动都会沿用。环境变量只是一次性覆盖,且必须带 --override-with-envs 才生效;不带参数时 OpenHands 会提示变量已设置但被忽略。OpenHands 安装文档里的 Docker 命令把 ~/.openhands 挂载进容器,宿主机上保存的设置在容器里同样适用。
openhands serve、Agent Canvas 和 OpenHands Cloud 怎么配?
openhands serve 启动的 GUI 服务在 Settings → LLM 打开 Advanced 后有同样三个字段:带 provider 前缀的 Custom Model、Base URL 和 API Key。Agent Canvas 把它们放在 LLM profile 的 Advanced 标签页,按其文档给 OpenAI 兼容服务的 openai/<model-id> 形式填写,base URL 必须能从它的后端访问。OpenHands Cloud 以及 Agent Canvas 可挂接的 ACP agent(如 Claude Code、Codex)使用各自的认证和模型设置,不适用本指南。
OpenHands 能通过网关用哪些模型?
选用当前目录中同时支持 OpenHands 所用端点和所需功能的模型。精确 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,再按错误码速查页逐项排查。