ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

openai-agents-python 多模型接入指南:深入解析 AnyLLMModel 适配层与 any-llm 路由

openai-agents-python 多模型接入指南:深入解析 AnyLLMModel 适配层与 any-llm 路由 openai-agents-python 多模型接入指南深入解析 AnyLLMModel 适配层与 any-llm 路由【免费下载链接】openai-agents-pythonA lightweight, powerful framework for multi-agent workflows项目地址: https://gitcode.com/GitHub_Trending/op/openai-agents-python本文围绕 openai-agents-python 中位于 src/agents/extensions/models/any_llm_model.py 的AnyLLMModel类展开讲解如何通过第三方适配层 any-llm 在一个 Agent 应用中接入 OpenAI 之外的数十种模型提供商OpenRouter、Anthropic、Gemini、Vertex AI 等并自动选择 Responses API 或 Chat Completions 两种接口面。读完本文你将掌握 any-llm 的安装与模型命名规范、AnyLLMModel的三种接入方式、API 自动选择与手动固定、工具调用与结构化输出的底层转换逻辑以及流式、推理内容、用量统计、追踪等生产级细节。本文对应的 API 参考页为 docs/ref/extensions/models/any_llm_model.md该页通过 mkdocstrings 指令::: agents.extensions.models.any_llm_model自动渲染模块 API。一、AnyLLMModel 是什么SDK 与上游模型之间的适配层openai-agents-python 自身内置了针对 OpenAI 的OpenAIResponsesModel等模型实现。当你需要同时使用非 OpenAI 提供商、或需要跨提供商统一路由时官方建议优先考虑内置集成点只有在不够用时才引入第三方适配层。项目文档在 docs/models/index.md 的 Third-party adapters 一节中明确说明仅使用 OpenAI 模型时应优先走内置的OpenAIResponsesModel路径而不是 Any-LLM 或 LiteLLM第三方适配层用于需要组合 OpenAI 与非 OpenAI 提供商、或需要适配器提供的提供商覆盖与路由能力的场景。AnyLLMModel正是 SDK 内置的两个 beta 级第三方适配器Any-LLM 与 LiteLLM之一。从源码看它实现了Model接口见 src/agents/extensions/models/interface.py 中的抽象定义因此可以直接作为Agent(model...)的模型参数也可通过前缀路由与MultiProvider协作。二、安装与运行环境any-llm 属于可选依赖组在 pyproject.toml 中声明为any-llm [any-llm-sdk1.11.0, 2; python_version 3.11]对应的安装命令有两种等价写法pip install openai-agents[any-llm] # 或使用项目默认的包管理器 uv sync --extra any-llm需要注意两个硬性前提Python 版本要求 3.11。源码在模块导入时通过importlib.import_module(any_llm)加载 SDK若失败会直接抛出ImportError提示信息即为 any-llm-sdkis required to use the AnyLLMModel...any-llm-sdkcurrently requires Python 3.11见 any_llm_model.py。any-llm-sdk 版本范围1.11.0, 2。源码中多处行为与 any-llm 1.11.0 的接口强相关例如流式清理说明、ResponsesParams校验行为等见 any_llm_model.py 与 any_llm_model.py。三、模型命名规范与三种接入方式3.1 模型名格式provider/modelAnyLLMModel的构造函数签名见 any_llm_model.py为AnyLLMModel( model: str, base_url: str | None None, api_key: str | None None, api: Literal[responses, chat_completions] | None None, )其中model必须采用provider/model两段式命名。_split_model_name的实现见 any_llm_model.py揭示了命名规则模型名为空 → 抛出UserError(AnyLLMModel requires a non-empty model name.)模型名不含/→ 默认提供商为openai/后部分作为模型名模型名含/→ 以第一个/分割为provider与model两部分任一部分为空都会报错官方示例格式为openrouter/openai/gpt-5.4-mini即提供商是openrouter模型是openai/gpt-5.4-mini也就是说AnyLLMModel构造时接收的是去掉any-llm/前缀之后的字符串。base_url与api_key分别对应上游提供商的接口地址与密钥两者均可在构造时省略交由 any-llm 从环境变量读取。3.2 三种接入方式根据 docs/models/index.md 的 Any-LLM 章节SDK 提供三条接入路径方式一直接实例化AnyLLMModel。参考 examples/model_providers/any_llm_provider.pyfrom agents import Agent, Runner, set_tracing_disabled from agents.decorators import tool from agents.extensions.models.any_llm_model import AnyLLMModel set_tracing_disabled(disabledTrue) tool def get_weather(city: str): print(f[debug] getting weather for {city}) return fThe weather in {city} is sunny. async def main(model: str, api_key: str): agent Agent( nameAssistant, instructionsYou only respond in haikus., modelAnyLLMModel(modelmodel, api_keyapi_key), tools[get_weather], ) result await Runner.run(agent, Whats the weather in Tokyo?) print(result.final_output)运行方式示例默认走 OpenRouter只需一个 API Keyexport OPENROUTER_API_KEY... uv run examples/model_providers/any_llm_provider.py --model openrouter/openai/gpt-5.4-mini uv run examples/model_providers/any_llm_provider.py --model openrouter/anthropic/claude-4.5-sonnet方式二使用any-llm/...前缀模型名。SDK 会识别该前缀并路由到 any-llm 适配层。参考 examples/model_providers/any_llm_auto.pyagent Agent( nameAssistant, instructionsYou only respond in haikus., modelany-llm/openrouter/openai/gpt-5.4-mini, tools[get_weather], model_settingsModelSettings(tool_choicerequired), output_typeResult, )该示例同时展示了ModelSettings(tool_choicerequired)强制工具调用与output_typeResult结构化输出两个能力。方式三运行作用域使用AnyLlmProvider。当需要在一次运行中混用openai/...与any-llm/...两类模型名时用 [MultiProvider][agents.MultiProvider] 并设置openai_use_responses_websocketTrue再注册AnyLlmProvider实现在 src/agents/extensions/models/any_llm_provider.py实现基于前缀的模型路由。如果希望显式固定接口面可以在构造AnyLLMModel时传入apiresponses或apichat_completions详见下一节。四、API 自动选择机制Responses 与 Chat Completionsany-llm 会根据上游提供商能力自动选择 OpenAI Responses API 或 Chat Completions 兼容接口。源码中的选择逻辑见 any_llm_model.py如下def _selected_api(self) - Literal[responses, chat_completions]: if self.api is not None: if self.api responses and not self._supports_responses(): raise UserError( fProvider {self._provider_name} does not support the Responses API. ) return self.api return responses if self._supports_responses() else chat_completions规则归纳显式指定优先构造时传入apiresponses或apichat_completions则强制使用该接口若指定responses而提供商不支持抛出UserError。_validate_api见 any_llm_model.py会校验取值只能是None、responses、chat_completions三者之一。自动探测未指定时查看提供商对象的SUPPORTS_RESPONSES属性见_supports_responsesany_llm_model.py支持则走 Responses否则走 Chat Completions。两条路径最终都收敛到统一的ModelResponseResponses 路径_get_response_via_responses/_stream_response_via_responses直接复用 OpenAI Responses 的请求参数模型model、input、instructions、tools、tool_choice、temperature、top_p、max_output_tokens、truncation、store、prompt_cache_retention、previous_response_id、conversation、include、parallel_tool_calls、reasoning、text等字段在_ANY_LLM_RESPONSES_PARAM_FIELDS中列出非流式响应直接返回Response对象见 any_llm_model.py。Chat Completions 路径_get_response_via_chat/_stream_response_via_chat把 SDK 的输入项items转换成 Chat Completions 消息调用provider.acompletion(...)见 any_llm_model.py再通过ChatCmplStreamHandler把流式 chunk 转成 SDK 的流事件见 any_llm_model.py。值得注意的是两条路径目前都不支持 prompt-managed 请求当prompt参数非None时会直接抛出UserError(AnyLLMModel does not currently support prompt-managed requests.)见 any_llm_model.py 与 any_llm_model.py。五、消息转换、工具调用与提供商特化处理AnyLLMModel内部把 SDK 的 Agent 输入TResponseInputItem转换为上游 API 可识别的消息这依赖chatcmpl_converter.Converter见 src/agents/models/chatcmpl_converter.py核心逻辑集中在_fetch_chat_response系统指令system_instructions以role: system消息插入到消息列表头部any_llm_model.py。推理块保留当model_settings.reasoning.effort被设置时preserve_thinking_blocksTrue保留思考块any_llm_model.py。工具定义tools经Converter.tool_to_openai转换handoffs经Converter.convert_handoff_tool转换后追加到tools列表any_llm_model.py说明handoff交接在底层就是工具调用的一种。工具选择model_settings.tool_choice经Converter.convert_tool_choice转换仅当存在工具时才允许parallel_tool_callsany_llm_model.py。结构化输出output_schema经Converter.convert_response_format转换为response_formatany_llm_model.py。5.1 工具消息顺序修复面向 Anthropic / GeminiAnthropic、Claude、Gemini 系列模型对工具调用assistanttool_calls与工具结果tool消息的配对顺序有严格要求。源码检测模型名中是否包含anthropic、claude、gemini命中则调用_fix_tool_message_ordering重排消息any_llm_model.py。该函数any_llm_model.py的核心思路把每条 assistant 工具调用拆成独立的 assistant 消息每条只含一个tool_call并按tool_call_id与 tool 结果配对只有第一条拆分消息保留content、thinking_blocks、reasoning_content、reasoning字段后续拆分消息仅携带tool_calls避免重复携带被 Anthropic 拒绝的签名思考块最终按工具调用紧跟其工具结果的顺序重组消息列表。5.2 Google 工具结果角色归一化针对gemini/vertexai提供商_normalize_google_tool_result_roles会包装其_convert_completion_params把 contents 中role function的内容改写为role userany_llm_model.py使其符合 Google 接口的user角色约束。5.3 推理内容reasoning的标准化不同提供商返回推理文本的字段五花八门reasoning_content、reasoning、thinking可能是字符串、字典或嵌套对象。SDK 通过_extract_any_llm_reasoning_text与_flatten_any_llm_reasoning_valueany_llm_model.py统一提取并在非流式路径构造InternalChatCompletionMessage时填充标准化的reasoning_content/reasoning字段any_llm_model.py流式路径则在_normalize_chat_chunk中把推理文本注入delta[reasoning]any_llm_model.py。六、流式响应的资源管理细节stream_response使用contextlib.aclosing(...)包裹内部生成器any_llm_model.py保证消费者提前aclose()时委托生成器的清理逻辑能确定性执行而不是等待垃圾回收。源码注释还特别指出截至 any-llm 1.11.0其异常与提供商包装层使用裸async for ... yield委托不会把aclose()转发到底层传输层因此底层传输的关闭属于上游 any-llm 的职责。流式过程中的错误与取消处理同样细致收到response.completed时先填充 span 的 usage 与响应数据再向下游产出事件确保消费者在终止事件处停止也能留下完整的追踪记录any_llm_model.py遇到response.failed/response.incomplete事件时构造ModelBehaviorError并在 yield 后抛出any_llm_model.py捕获asyncio.CancelledError时把流关闭调度到后台任务避免取消中途放弃半完成的关闭操作_close_stream_allowing_background_completion使用asyncio.shield见 any_llm_model.py。七、错误处理、用量统计与追踪7.1 终止状态与内容过滤Responses 终止状态非流式调用返回status为failed或incomplete时抛出ModelBehaviorError异常标识终止状态并携带响应中的错误或未完成详情any_llm_model.py。这与 docs/running_agents.md 中描述的OpenAIResponsesModel行为一致。内容过滤部分提供商只通过finish_reasoncontent_filter且空消息来标记过滤结果SDK 会将其保留为refusal信号而不是返回空输出any_llm_model.py。重试建议get_retry_advice复用 OpenAI 的重试建议逻辑any_llm_model.py。7.2 用量统计Usage对象在两个路径中分别从response.usageResponses或response.usage.prompt_tokens/completion_tokensChat Completions构造即使提供商未返回 usage请求也会按Usage(requests1)计数any_llm_model.py 与 any_llm_model.py。当model_settings.preserve_raw_usageTrue时还会通过_attach_raw_usage_snapshot保留原始 usage 快照。关于流式 usagedocs/usage.md 特别提示从 Chat Completions 后端流式获取响应时可能需要设置ModelSettings(include_usageTrue)才会产出 usage chunk。源码对应逻辑在 any_llm_model.py仅当streamTrue且include_usage非空时才设置stream_options{include_usage: ...}。7.3 追踪TracingChat Completions 路径使用generation_spanspan 的model_config中带有provider与model_impl: any-llm信息any_llm_model.py可在追踪面板中区分适配层来源Responses 路径使用response_spanany_llm_model.py错误会被model_span_errors记录到 span 上调试日志中DONT_LOG_MODEL_DATA为真时只输出 LLM responded 级别信息否则打印完整请求/响应 JSON。使用追踪的参考写法docs/tracing.mdfrom agents.extensions.models.any_llm_model import AnyLLMModel model AnyLLMModel(modelopenrouter/openai/gpt-5.4-mini, api_key...)7.4 高级参数透传ModelSettings中无法一一映射的参数通过以下方法透传any_llm_model.pyChat Completions 路径_build_chat_extra_kwargsextra_query→extra_querymetadata→metadataextra_body→extra_bodyextra_args直接并入顶层 kwargsResponses 路径_build_responses_extra_kwargs额外支持top_logprobs请求头合并_merge_headers默认头HEADERSmodel_settings.extra_headers 全局覆盖头HEADERS_OVERRIDE按顺序合并any_llm_model.py。对gemini/vertexai提供商请求头会注入http_options其他提供商走extra_headersany_llm_model.pylogprobs设置top_logprobs时自动补logprobsTrueChat Completions 要求避免与调用方显式传入的logprobs键冲突any_llm_model.py并将 logprobs 附加到输出文本_attach_logprobs_to_outputany_llm_model.pyrepetition penalty 等推理参数reasoning_effort优先取自model_settings.reasoning.effort其次回退到extra_args[reasoning_effort]any_llm_model.py。八、Provider 实例缓存与重试策略AnyLLMModel通过_provider_cache缓存提供商实例键为是否禁用提供商侧重试any_llm_model.py首次使用时以AnyLLM.create(provider_name, api_key..., api_base...)创建基础实例当全局配置要求禁用提供商托管重试时should_disable_provider_managed_retries会基于client.with_options(max_retries0)克隆一份无重试实例避免与 SDK 自身的重试机制叠加close()会遍历缓存去重关闭底层 client支持aclose或close两种协议见 any_llm_model.py 与 any_llm_model.py。九、测试与验证仓库为AnyLLMModel提供了完整的单元测试 tests/models/test_any_llm_model.py覆盖工具调用转换、消息重排、usage 传播、API 选择、错误路径等行为此外 tests/models/test_map.py 覆盖前缀路由到 any-llm 的映射逻辑。若你计划在结构化输出、工具调用、用量上报或 Responses 特定行为上依赖某个具体提供商建议参考这些测试并像 docs/models/index.md 建议的那样先验证目标提供商后端——适配层的能力边界由上游 any-llm 定义不同提供商的特性支持与请求语义存在差异。十、小结与适用建议适用场景需要在单一 Agent 应用中接入非 OpenAI 提供商、或通过 any-llm 获得统一路由与提供商覆盖能力。不适用场景仅使用 OpenAI 模型——此时请使用内置的OpenAIResponsesModel路径避免多余兼容层。关键实践清单使用provider/model格式命名模型需要固定接口时显式传api流式 Chat Completions 场景记得配ModelSettings(include_usageTrue)多提供商混用且需要前缀路由时用MultiProvideropenai_use_responses_websocketTrueAnyLlmProvider部署前针对目标提供商验证结构化输出与工具调用行为。从 examples/model_providers/README.md 提供的统一运行方式出发export OPENROUTER_API_KEY...后uv run examples/model_providers/any_llm_provider.py你可以在几分钟内完成从 OpenAI 模型到 OpenRouter 上任意模型的切换验证。【免费下载链接】openai-agents-pythonA lightweight, powerful framework for multi-agent workflows项目地址: https://gitcode.com/GitHub_Trending/op/openai-agents-python创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表