配置 LlamaIndex OpenAILike 与模型 能力
LlamaIndex 是在自有文档上做 RAG 与 Agent 的数据框架,回答一个问题往往会触发多次 LLM 调用:合成答案、拆分子问题、逐段精炼、Agent 步骤。它的 OpenAILike 类能对接任何 OpenAI 兼容端点,一份指向 https://api.router.one/v1 的配置,改一个 model 字符串就能在目录中的 Claude、GPT、Gemini、Grok 与 DeepSeek 聊天模型之间切换,网关发往模型的每一次调用都在控制台 → 日志里留下记录(在输出任何内容之前就失败的流式请求可能没有记录),不用自己加 callback。网关在大陆可直连,支付宝或银行卡即可充值。OpenAILike 对模型的了解只来自你传入的参数,它的默认值描述的是一个小型的旧式补全模型:is_chat_model 为 False、上下文窗口 3,900 tokens、不支持工具调用。本指南逐项改掉这些默认值,把 embeddings 留在提供它的供应商那里,并说明 LlamaIndex 的重试与超时会在哪里多出请求。按 llama-index-core 0.14.25、llama-index-llms-openai-like 0.8.1、llama-index-llms-openai 0.8.2(Python)与 @llamaindex/openai 0.4.23(TypeScript)的源码核对(2026-10-09)。
安装 OpenAILike 集成,并创建 专用 Key
pip install llama-index-core llama-index-llms-openai-like 会安装本指南用到的组件:llama-index-llms-openai-like 0.8.1(2026 年 10 月 1 日发布)要求 Python 3.10 或更高版本,并依赖 llama-index-llms-openai 0.8.x,真正发出请求的是后者的 OpenAI 客户端。请为这个应用单独创建一把 Router One Key,并设置 maxSpend 消费上限。查询引擎和 Agent 发出的请求你不会逐条看到,一个问题可能产生好几次调用,这个上限就是硬性止损;单独一把 Key 还能在控制台 → 日志里只筛出这个应用的请求。
pip install llama-index-core llama-index-llms-openai-like export ROUTER_ONE_API_KEY=sk-your-router-one-key
把 LlamaIndex 配置到 Router One base URL
用网关 base URL、Key 和 /models 上精确的聊天模型 ID 构造 OpenAILike,并设置三个默认值不适合网关模型的字段:is_chat_model=True;context_window 取模型详情页的窗口;只有详情页标明支持工具调用的 ID 才设置 is_function_calling_model=True。把实例设为 Settings.llm,所有索引、查询引擎和 Agent 都会使用它;也可以用 llm= 只传给某一个组件。请像下面这样显式传入 api_base 和 api_key:LlamaIndex 的兜底读取的是 OPENAI_API_BASE 与 OPENAI_API_KEY 两个变量,而不是 OPENAI_BASE_URL,其他工具遗留的变量可能把调用发到别处。max_tokens 会以 max_tokens 发送,Router One 的 Chat Completions 接受它作为输出上限:
import os
from llama_index.core import Settings
from llama_index.llms.openai_like import OpenAILike
Settings.llm = OpenAILike(
model="anthropic/claude-sonnet-5", # exact ID from /models
api_base="https://api.router.one/v1",
api_key=os.environ["ROUTER_ONE_API_KEY"],
is_chat_model=True, # the default False sends /v1/completions
is_function_calling_model=True, # only if the model page lists tool calling
context_window=1000000, # the model page's window, rounded down
max_tokens=2048, # sent as max_tokens
timeout=300.0, # default 60 seconds
)
print(Settings.llm.complete("Reply with OK"))设置 OpenAILike 无法从 网关 获知的三个 字段
is_chat_model 默认为 False,这时 complete() 和 chat() 都会走旧式的 Completions API,即 POST /v1/completions,对话消息被拼成一个提示词发出;Router One 不提供这个路径,调用会以 404 失败。设为 True 后,每次调用都是 POST /v1/chat/completions。context_window 默认是 3,900 tokens,LlamaIndex 按它装填检索到的片段和对话历史,所以保持默认时,即使模型有 1M 窗口,查询引擎也会截断内容,或者把答案合成拆成额外的 refine 调用。请按 /models 上该模型详情页的窗口填写;详情页显示的是取整后的缩写(1.05M、200K),请换算成整数并往小取:anthropic/claude-sonnet-5、openai/gpt-5.6-sol 与 deepseek-v4-flash 填 1000000,anthropic/claude-haiku-4.5 填 200000。窗口越大,LlamaIndex 能发出的提示词越长:在套餐下,单次请求的输入超过模型的长上下文门槛时会多扣套餐次数,钱包计费则按该模型自身的长上下文价格线计算(如有,见 /pricing),所以对 RAG 来说,比上限小一些的窗口可能更省钱。is_function_calling_model 默认为 False:这时 FunctionAgent 会抛出 ValueError: LLM must be a FunctionCallingLLM,AgentWorkflow.from_tools_or_functions 则退回基于文本的 ReActAgent。只有详情页标明支持工具调用的 ID 才设为 True。
请求 里带了 什么:temperature、reasoning_effort 与工具
每个请求都带着 LlamaIndex 的默认 temperature 0.1。llama-index-llms-openai 只对它自己列表里不带前缀的 OpenAI 推理模型名(例如 gpt-5.5)强制 temperature 为 1.0,并改用 max_completion_tokens 代替 max_tokens;带厂商前缀的目录 ID(例如 openai/gpt-5.6-sol)永远匹配不上,所以会按 temperature 0.1 和你设置的 max_tokens 发送。如果控制台 → 日志里的 400 错误点名了 temperature,那是模型拒绝了这个值:在 OpenAILike 上设置 temperature=1.0,不要去改 base URL。reasoning_effort 参数也只对同一批不带前缀的名字转发,所以对目录 ID 请通过 additional_kwargs={"reasoning_effort": "low"} 传入。对 Claude 系列 ID,Router One 不会把 reasoning_effort 转换为 thinking 设置;Claude Opus 5.5 例外,会映射到 output_config.effort(none 与 minimal 记为 low)。其他模型可能忽略它,或以 400 拒绝请求。设置 is_function_calling_model=True 后,工具定义默认带 strict false 发送,除非你允许并行调用,否则 parallel_tool_calls 为 false。如果网关以 HTTP 400 拒绝工具请求,错误信息含 has no chat candidate that supports requested capabilities: tool_calling,说明所选 ID 不支持工具调用,请换模型。
把 embeddings 留在 提供 它的 供应商 那里
Router One 没有 embeddings 端点:即使 Key 有效,POST /v1/embeddings 也返回 404。VectorStoreIndex.from_documents 和所有检索器都会调用 Settings.embed_model,它默认是 OpenAIEmbedding(text-embedding-ada-002),解析端点的方式与 LLM 相同:先看 api_base 参数,再看 OPENAI_API_BASE。如果给整个进程导出 OPENAI_API_BASE=https://api.router.one/v1,建索引的请求会发到 Router One 并以 404 失败;如果只导出了 Router One 的 Key 作为 OPENAI_API_KEY,建索引的请求会带着 OpenAI 不认的 Key 发到 api.openai.com(401)。请显式设置 Settings.embed_model:可以是带自己 OpenAI Key 和 base URL 的 OpenAIEmbedding,也可以是本地 embedding 模型;Router One 的地址和 Key 只交给 LLM,见下例。这样检索走 embedding 供应商,只有合成答案的调用会到达 Router One。
# pip install llama-index-embeddings-openai
import os
from llama_index.core import Settings, SimpleDirectoryReader, VectorStoreIndex
from llama_index.embeddings.openai import OpenAIEmbedding
# Embeddings stay on a provider that serves them (here OpenAI, with its own key)
Settings.embed_model = OpenAIEmbedding(
model="text-embedding-3-small",
api_key=os.environ["OPENAI_EMBEDDINGS_KEY"],
api_base="https://api.openai.com/v1",
)
# Settings.llm is the OpenAILike on Router One from the example above
index = VectorStoreIndex.from_documents(SimpleDirectoryReader("docs").load_data())
print(index.as_query_engine().query("What does the setup guide say about keys?"))重试、超时与长 回答
OpenAILike 默认 max_retries=3、timeout=60 秒。它把 max_retries 传给自己创建的 OpenAI 客户端,后者会对连接错误以及 HTTP 408、409、429 和 5xx 重试;同时它还给每次调用套了一层自己的重试,针对连接错误、超时、限流和服务端错误,最多三次或 60 秒为止。因此一次失败的调用可能多次到达网关,客户端每一次经网关发往模型的尝试都是控制台 → 日志里一条独立的请求,有自己的 request_id;而在这之前,Router One 已经针对 429、5xx 或超时换同一模型的其他线路重试过。批量建索引时请调低 max_retries,免得一条坏数据被放大成多次请求。长回答请用流式(stream_chat、astream_chat、stream_complete),或调大 timeout。stream: false 的调用运行超过约 25 秒后,网关会在答案生成期间先返回 HTTP 200;如果之后失败,错误会以不含 choices 的响应体返回,而 LlamaIndex 直接读取 choices[0],于是在离原因很远的地方抛出 TypeError。OpenAI SDK 指南展示了这种响应以及检查方法。
GPT 系列 ID 走 Responses API(可选)
同一个包还提供 OpenAILikeResponses,它发送的是 POST /v1/responses。只有模型详情页列出该端点的 ID 才能用它:GPT 系列模型、deepseek-v4.1-flash 与 deepseek-v4-flash,以及 grok-4.7 等 Grok 对话模型。Claude 系列 ID 发到这里会收到 HTTP 400 model '<id>' must be called via /v1/messages or /v1/chat/completions,Gemini 的 ID 在这里同样不提供,所以一个应用混用多个系列时,请继续用 OpenAILike。OpenAILikeResponses 总是按聊天模型处理;context_window 和 is_function_calling_model 同上设置,输出上限用 max_output_tokens 而不是 max_tokens。它默认发送 store false;设置 track_previous_responses=True 后会保存每个响应,并用 previous_response_id 串起下一次调用,Router One 在这些 ID 上接受 previous_response_id。
LlamaIndex 该填 哪个 模型 ID?
从 /models 页复制精确的模型 ID,保留大小写、连字符和版本后缀,不要用展示名称代替。打开该模型的详情页,核对支持的 API 端点、上下文窗口和工具调用等能力,再与 LlamaIndex 当前选择的 provider 和功能对应。模型出现在目录里,不等于当前客户端能调用它的所有功能。建议为每个客户端或应用单独建 API Key,并设置 maxSpend 消费上限。
LlamaIndex 用的是哪种 API 协议?
OpenAI 兼容描述的是接口格式,不能据此推断 Chat Completions(/v1/chat/completions)、Responses(/v1/responses)和 Anthropic Messages(/v1/messages)可以互换。先核对工具当前版本、provider 配置和实际请求路径,再查模型详情与 API 兼容性事实页。一次普通对话成功,也不能证明服务端工具、历史状态或文件编辑功能都受支持。
在请求日志里 核对 LlamaIndex 的调用
先在 LlamaIndex 发出一次简单文本请求,再到控制台 → 日志按时间、模型和 request_id 找到这条记录,核对 Token、花费、总耗时和状态码。成功后再分别验证流式输出、工具调用和多轮历史。失败时保留实际请求路径、完整错误消息及 request_id;没有对应日志时,要么请求没到达网关(客户端配置或网络问题),要么网关在调用模型之前就拒绝了它——Key 问题的 401、余额不足或 Key 达到 maxSpend 上限的 402、Key 或账户自身限额触发的 429,或模型 ID、端点不对的 400 / 404;在输出任何内容之前就失败的流式请求也可能没有日志。看客户端收到的状态码和错误消息就能区分是哪一种;先确认这一点,再判断是不是网关或上游故障。
常见 问题
为什么用 OpenAILike,而不是 OpenAI 类加 api_base?
因为 OpenAI 类会拿模型名去对照它自己的 OpenAI 模型表,表外的名字——包括所有带厂商前缀的目录 ID——一旦需要读取模型元数据就会抛出 ValueError: Unknown model;它还会把不认识的名字当作补全模型。OpenAILike 是文档给 OpenAI 兼容端点的正规路线:跳过这层查表,模型元数据完全来自你传入的参数,所以 is_chat_model、context_window 和 is_function_calling_model 要显式设置。
每次 调用都 返回 404、提示 没有 路由,问题在哪?
最常见的原因是 is_chat_model 保持了默认值 False。这时 OpenAILike 发送的是旧式 Completions API,即 POST /v1/completions,而 Router One 不提供这个路径。设置 is_chat_model=True,调用就会发到 /v1/chat/completions。如果它已经是 True,请检查 api_base 是否以 /v1 结尾、后面没有别的路径。
为什么 回答 只用了 几个 片段,或者 一个 问题要 调用 很多次?
因为 context_window 默认是 3,900 tokens,LlamaIndex 按它装填检索内容和历史,于是会截断内容,或把答案合成拆成额外的调用。请按模型详情页的窗口,换算成整数并往小取,例如 anthropic/claude-sonnet-5 填 1000000,anthropic/claude-haiku-4.5 填 200000。每一次额外的合成调用都是控制台 → 日志里一条独立的请求。
FunctionAgent 抛出 ValueError: LLM must be a FunctionCallingLLM,要改 什么?
在 OpenAILike 上设置 is_function_calling_model=True,并选用详情页标明支持工具调用的 ID。这个标志是你的声明,LlamaIndex 不会自动检测:保持 False 时,FunctionAgent 拒绝运行,AgentWorkflow.from_tools_or_functions 则退回 ReActAgent,改用纯文本方式请求工具调用。
建 VectorStoreIndex 时报 404 或 401,是 Router One 的问题吗?
问题在 embedding 这一步。Router One 没有 embeddings 端点,而 Settings.embed_model 默认是 OpenAIEmbedding,它和 LLM 一样读取 OPENAI_API_BASE 与 OPENAI_API_KEY。OPENAI_API_BASE 填的是 Router One 地址时,embeddings 请求得到 404;OPENAI_API_KEY 里只有 Router One 的 Key 时,OpenAI 返回 401。请把 Settings.embed_model 设为带自己 Key 的 embedding 供应商,Router One 的地址和 Key 只传给 OpenAILike。
TypeScript 版怎么配?
LlamaIndex.TS 里 @llamaindex/openai(0.4.23)的 OpenAI 类构造函数接受 model、apiKey 和 baseURL,也可以从环境变量 OPENAI_BASE_URL 与 OPENAI_API_KEY 读取;设为 Settings.llm 之后,同样靠改 model 字符串切换模型。按其源码,除了以 o1 开头或含 0314、0301 的名字,它一律假定支持工具调用,默认最多重试 10 次、60 秒超时,上下文窗口取自它自己的 OpenAI 模型表,表里没有的名字(包括所有目录 ID)一律按 1,024 tokens 处理。
本指南 对应 哪些 LlamaIndex 版本?
Python 端为 llama-index-core 0.14.25(2026 年 9 月 21 日发布)、llama-index-llms-openai-like 0.8.1 与 llama-index-llms-openai 0.8.2,TypeScript 端为 @llamaindex/openai 0.4.23,核对日期为 2026-10-09。文中的默认值(is_chat_model 为 False、3,900 tokens 窗口、temperature 0.1、max_retries 3、60 秒超时)都来自这些包的源码,升级后值得再检查一遍。
LlamaIndex 能通过 网关用 哪些 模型?
选用当前目录中同时支持 LlamaIndex 所用端点和所需功能的模型。精确 ID、当前单价与能力以 /models 及模型详情为准;不要仅按 GPT、Claude 等系列名判断兼容性。客户端能列出模型,只说明它从自身配置或 GET /v1/models 读到了这个 ID,仍需验证实际调用。
能列出 模型,但调用报 400 或 404,怎么办?
先记录实际请求路径和错误消息,再核对精确模型 ID。400 可能是参数、工具类型或模型与端点不匹配;404 可能是请求路径或资源不存在,不能直接判定模型下线。若错误提示 must be called via,按它指明的端点调整客户端 provider,或换用支持当前端点的模型。不要在所有工具里统一增删 /v1 或 /chat/completions。
中国 大陆能 直连吗?
能。网关在大陆可直连、无需 VPN,配置与全球环境完全一致。
报 401/402/403/429 怎么 排查?
先看客户端收到的响应:状态码、错误消息和 X-Request-ID 响应头。401(Key 缺失、不存在、已吊销或已过期)、402(钱包余额不足,或这把 Key 达到 maxSpend 上限)以及 Key 或账户自身限额触发的 429,都在调用任何模型之前被拒绝,不会出现在控制台 → 日志里;模型 ID 或端点写错导致的 400 / 404 也一样。401 查 Key 是否完整传入、在控制台 → API 密钥里是否仍有效;402 充值或调高这把 Key 的 maxSpend;403 请保留完整错误消息。429 请退避后重试;日志里能查到的 429 是网关重试之后上游仍返回的。保留 request_id,再按错误码速查页逐项排查。