Agent Zero 的 LiteLLM 传输适配层Responses 与 Chat Completions 双模式归一化与自动降级机制解析【免费下载链接】agent-zeroAgent Zero AI framework项目地址: https://gitcode.com/GitHub_Trending/ag/agent-zero本篇技术指南围绕 Agent Zero开源 AI Agent 框架中的 helpers/litellm_transport.py 及其配套说明文档 helpers/litellm_transport.py.dox.md 展开完整剖析这套框架自有的 LiteLLM 传输适配器它如何把 Agent Zero 的模型调用参数归一化为各模型提供商安全的 LiteLLM 请求、如何同时支撑 Chat Completions 与 Responses 两套 API 形态、如何在提供商不支持时自动降级、如何保留用于历史记录与状态延续的规范响应元数据。读完本文你将理解TransportMode、TransportPolicy、ResponsesTransport等核心类的职责边界与底层调用链并能在自己的模型接入工作中复用这套参数清洗—模式选择—错误恢复的设计思路。一、为什么 Agent Zero 需要自有的 LiteLLM 传输适配器Agent Zero 的模型调用建立在 LiteLLM 之上借助其统一接口对接 OpenAI、Anthropic、Gemini、Bedrock、OpenRouter 等众多提供商。但 LiteLLM 本身并不了解 Agent Zero 内部约定Agent Zero 的调用方如 models.py 中的模型封装、agent.py 中的回合调度会携带大量内部专属 kwargs例如a0_api_mode、responses_state、previous_response_id、responses_input_items等。这些参数若原样透传给提供商轻则被忽略重则触发参数校验失败。因此litellm_transport.py承担了三项核心使命对应 litellm_transport.py.dox.md 中的 Purpose 描述Own拥有 Agent Zero 面向 Chat Completions 与 Responses API 的专属 LiteLLM 传输适配实现Normalize将 Agent Zero 的模型调用 kwargs 归一化为提供商安全的 LiteLLM 请求Preserve保留规范化的响应元数据供历史记录helpers/history.py、提供商状态延续与降级决策使用。从源码结构看整个模块可以划分为策略决策层TransportPolicy与请求构造/解析层ChatCompletionsTransport、ResponsesTransport、ResponsesEventParser外层由LiteLLMTransport统一封装同步与异步的完整/流式调用入口。二、核心类与顶层函数总览模块内部定义了两组枚举、一个策略数据类、四个传输类与若干顶层工具函数职责边界非常清晰类 / 函数职责TransportMode传输模式枚举RESPONSES/CHAT_COMPLETIONSTransportRecovery恢复动作枚举RAISE/RETRY_RESPONSES/RETRY_LOCAL_RESPONSES/FALLBACK_TO_CHATTransportPolicy根据模型名与 kwargs 解析出本次调用的模式、是否允许降级、缓存键与状态策略并负责异常分类与恢复决策LiteLLMTransport对外统一入口提供complete/acomplete/stream/astream四个方法ChatCompletionsTransportChat Completions 请求的参数/消息清洗与响应解析ChatCompletionsStreamParser流式场景下对增量 tool_calls 的分片拼接按 index/id 聚合ResponsesTransportChat 消息 → Responsesinput条目、工具/工具选择的格式转换以及状态与提示缓存参数装配ResponsesEventParser有状态地解析 Responses 流式事件聚合并去重输出函数调用clear_transport_capability_cache()清空能力降级缓存RESPONSES_UNSUPPORTED_CACHE、RESPONSES_STATE_UNSUPPORTED_CACHE、RESPONSES_BUILTIN_UNSUPPORTED_CACHEdelete_stored_response_ids/adelete_stored_response_ids同步/异步删除服务端存储的 Response 记录供聊天删除时清理状态使用被 helpers/persist_chat.py 引用三、运行时契约归一化、安全化与可恢复性dox 文档将模块的运行时契约概括为十项规则源码逐条落实下面结合实现细节逐项展开。3.1 提供商选择与默认值不在此处决策dox 明确要求Keep provider selection and provider-specific defaults outside this helper; callers pass a resolved LiteLLM model name and kwargs.——即提供商的选择与提供商特有默认值由调用方负责本模块只接收已经解析好的 LiteLLM 模型名如openai/gpt-5.4与 kwargs。调用方确实如此实现在 models.py 中模型类直接构造LiteLLMTransport(modelself.model_name, messagesmsgs, kwargscall_kwargs, stopstop)并调用transport.complete()。3.2 剥离 Agent Zero 内部 kwargs发送请求前模块会把所有a0_*前缀及 Responses 专属的内部参数从请求中剔除_drop_legacy_transport_kwargs弹出a0_api_mode、a0_responses_fallback_drop_responses_only_kwargs弹出responses_state、responses_delete_on_chat_delete、responses_input_items、responses_local_input_items、previous_response_id、_a0_responses_builtin_downgrades_drop_internal_transport_kwargs在前两者基础上再弹出a0_explicit_prompt_caching、a0_responses_function_tools、responses_builtin_tools。这些参数只影响 Agent Zero 内部的策略决策绝不允许泄漏到面向提供商的请求体中。3.3 无工具时不发送孤立的 tool 控制参数严格兼容 OpenAI 的服务端会拒绝空的tools数组。因此在 Chat Completions 分支prepare_kwargs中若_has_tools()为假则同时移除tools、tool_choice、parallel_tool_calls三个键helpers/litellm_transport.py在 Responses 分支ResponsesTransport.prepare_kwargs在合并完工具后若没有可用工具同样弹出tools、tool_choice、parallel_tool_callshelpers/litellm_transport.py。3.4 有函数工具时默认强制一次原生调用当存在 Agent Zero 函数工具a0_responses_function_tools时Responses 请求默认要求一次必需的原生函数调用if _has_tools(response_function_tools): request.setdefault(tool_choice, required) request.setdefault(parallel_tool_calls, False)同时调用方显式传入的tool_choice与parallel_tool_calls依然具有更高优先级setdefault不会覆盖已有值这与 dox 中explicit request-level tool_choice and parallel_tool_calls values still win的约定一致。3.5 函数参数 schema 归一化经 LiteLLM 转发的 OpenAI 兼容聊天后端通常要求函数参数具备显式的object类型与properties字段。_normalize_function_parameters实现了这一兜底normalized.setdefault(type, object) if normalized.get(type) object and not isinstance(normalized.get(properties), dict): normalized[properties] {}当参数完全缺失或不可解析时退化为宽松 schema{type: object, properties: {}, additionalProperties: True}。该归一化同时应用于ResponsesTransport.tools_from_chat与normalize_response_tool保证两套 API 形态下的工具定义一致。3.6 模式选择偏好 Responses降级 Chat CompletionsTransportPolicy.from_request是模式决策的核心。它首先读取a0_api_mode默认responses并依据别名表归类CHAT_COMPLETIONS_ALIASESchat、chat_completion、chat_completions、completion、completionsRESPONSES_ALIASES空字符串、auto、default、response、responses、responses_api。a0_api_mode由调用方如 plugins/_model_config/extensions/python/startup_migration/_10_migrate_model_config.py 与 tests/test_model_config_api_keys.py 中的模型配置在模型配置层注入。随后策略会依次检查若缓存记录显示该cache_key由model|custom_llm_provider|api_base拼接而成此前已在 Responses 上失败则直接切到 Chat Completions 并记录fallback_error若消息或工具中包含cache_control标记且当前提供商并非原生 Responses 提供商_should_preserve_cache_control_on_chat则改用 Chat Completions 以保留缓存标记语义否则进入 RESPONSES 模式。3.7 降级触发条件与恢复路径当 Responses 请求在产出任何输出之前失败时TransportPolicy.recover(exc, got_any_chunkFalse)按优先级决定恢复动作推理力度错误重试若错误信息同时包含response.reasoning.effort、minimal、high、none字样说明提供商不接受当前的 reasoning effort 枚举则把reasoning重写为{effort: high}后重试RETRY_RESPONSES同一策略实例只重试一次retried_reasoning标志。状态降级为本地回放若错误被_is_responses_state_unsupported_error判定为提供商不支持previous_response_id/store错误文本含previous_response_id、store、stored response、response storage is not supported等标记则将responses_state切换为local、移除previous_response_id并以完整消息回放的方式重试RETRY_LOCAL_RESPONSES同时把cache_key记入RESPONSES_STATE_UNSUPPORTED_CACHE供后续请求直接跳过 provider 状态。整体降级到 Chat Completions当错误被_is_responses_not_supported_error判定为提供商根本不支持 Responses 时将模式切换为 Chat Completions 并记录fallback_errorFALLBACK_TO_CHAT同时把cache_key记入RESPONSES_UNSUPPORTED_CACHE后续同模型同端点的请求会直接走 Chat Completions。_is_responses_not_supported_error的判定非常细致覆盖了以下典型场景端点/形状相关的 Bad Request400文本含/v1/responses、responses api、input_image、zod、failed to deserialize input等端点特有的服务端错误5xx、代理路径不可用not available through this proxy、path /api/v1/responsesLiteLLM 代理缺少额外依赖litellm[proxy]、no module named fastapiLiteLLM Responses mock 流式路径把真实 SSE 流当作 JSON 解码导致的JSONDecodeError_is_sse_json_decode_error沿异常链向上查找payload 以event:开头且含\ndata:。特别强调所有降级判定都带有未产出任何输出前提got_any_chunk为假一旦流式过程已经产出过真实内容则不允许中途切换协议只能RAISE——这是为了避免把半截输出与另一协议的输出拼接造成语义错乱。3.8 工具调用结果统一为规范的 function_call 条目dox 约定Preserve Chat Completions tool calls from both non-streaming responses and streaming deltas as canonicalLLMResultfunction-call items.非流式ChatCompletionsTransport.parse从choices[0].message.tool_calls提取工具调用经由function_call_item归一化为{type: function_call, id, call_id, name, arguments}流式ChatCompletionsStreamParser按index/id为键把分散在各 delta 中的name与arguments片段拼接起来在finish_reason为tool_calls/function_call时一次性发射完整的 JSON 文本同时兼容旧式function_calldelta多工具调用时文本形式统一包装为{tool_name: parallel_tool_calls, tool_args: {calls: [...]}}。这些条目最终通过 helpers/llm_result.py 中的LLMResult数据类进入历史与决策链路。3.9 提供商状态延续与本地回放Responses API 支持storeprevious_response_id的服务端状态延续这是 Agent Zero 的默认策略RESPONSES_STATE_PROVIDERif state RESPONSES_STATE_PROVIDER: request.setdefault(store, True) if previous_response_id: request[previous_response_id] previous_response_id elif state RESPONSES_STATE_LOCAL: request.setdefault(store, False)输入选择逻辑_select_input_items与之配套provider 状态模式优先使用responses_input_items自上次状态之后的新增条目local 模式使用responses_local_input_items完整的历史回放消息都没有时回退到input_from_messages把全部消息转换为 Responses input 条目。在 agent.py 的回合调度中previous_response_id与responses_input_items来自agent.data[responses_state]持久化记录responses_local_input_items则由_responses_prompt_input_items生成随后统一注入turn_kwargs传入模型层。3.10 提示缓存标记按提供商差异化处理提示缓存是只对接受它的提供商保留标记这一契约的核心体现。模块区分了三类提供商cache_control 标记提供商CACHE_CONTROL_PROMPT_PROVIDERS含 anthropic、bedrock、databricks、dashscope、gemini、gemini_api_oauth、minimax、openrouter、vertex_ai、vertexai、z_ai、zai以及 api_base 含openrouter.ai或anthropic.com的端点支持 Anthropic 风格的cache_control: {type: ephemeral}标记OpenAI 系提供商OPENAI_PROMPT_CACHE_PROVIDERS含 openai、azure以及 api_base 为api.openai.com/openai.azure.com的端点不接受 cache_control 标记改用prompt_cache_key——基于模型、前置 system/developer 消息、instructions、prompt、tools 计算 SHA-256 摘要并截取 32 位十六进制前缀a0-其余提供商既不注入标记也不注入缓存键。a0_explicit_prompt_caching开关默认false由调用方在 models.py 等处按需打开打开后会在进入策略决策前调用apply_chat_prompt_cache_markers为前置上下文消息的最后一个 system/developer 消息 最近两条 user 消息最多 3 个位置打上缓存标记。Responses 请求还会把context_management、prompt_cache_retention两个参数搬进extra_body避免被 OpenAI 严格校验拒绝。四、传输入口同步/异步 × 完整/流式LiteLLMTransport对外暴露四个方法内部都采用循环 策略恢复的骨架def complete(self) - ChatChunk: # 同步非流式 async def acomplete(self) - ChatChunk: # 异步非流式 def stream(self) - Iterator[ChatChunk]: # 同步流式 async def astream(self) - AsyncIterator[ChatChunk]: # 异步流式每个方法都通过while True包裹发生异常时先询问_recover(exc, got_any_chunk...)若返回可恢复动作则修改策略或 kwargs 后continue重新发起请求否则raise。流式场景下got_any_chunk由解析器实际产出的 delta 决定且finally中会调用_close_sync_stream/_close_async_stream关闭未完全消费的流防止连接泄漏。ChatChunk是统一的分片结构{reasoning_delta: str, response_delta: str}。工具调用文本会作为response_delta输出供上层 models.py 的ChatGenerationResult.add_chunk汇总。ResponsesEventParser是流式 Responses 的关键状态机它维护function_calls按item_id/output_index聚合、emitted_function_calls去重发射与completed_response。它处理的事件类型包括response.output_text.delta/response.refusal.delta/response.text.delta→ 正文增量response.reasoning_summary_text.delta/response.reasoning_text.delta→ 推理增量response.output_item.added/response.function_call_arguments.delta/response.function_call_arguments.done/response.output_item.done→ 函数调用的记忆、拼接与完整发射response.completed→ 若此前从未产出正文或函数调用则从完整响应中补一次解析结果response.failed/error→ 抛出RuntimeError并提取服务端错误消息。五、能力元数据与降级透明度每次请求结束后LiteLLMTransport会把本次调用的能力事实写入LLMResult.capabilityhelpers/litellm_transport.py{ mode: self.policy.mode.value, # responses / chat_completions state: self.policy.state, # provider / local / off cache_key: self.policy.cache_key, # model|provider|api_base fallback_error: ..., # 降级为 Chat 时的原始异常文本 state_fallback_error: ..., # 状态降级时的原始异常文本 builtin_tool_downgrades: [...], # 被移除的 Responses 内置工具类型 }这使上层能够追溯这次回答到底走的哪种协议、为什么降级也支撑了 dox 中为历史记录、提供商状态延续与降级决策保留规范响应元数据的目标。内置工具responses_builtin_tools如web_search、file_search、code_interpreter等的处理同样遵循降级缓存思路首次遇到unsupported tool type类错误时把不支持的 tool type 从请求中移除_a0_responses_builtin_downgrades记录被降级的类型并重试同时写入RESPONSES_BUILTIN_UNSUPPORTED_CACHE后续请求在构造请求前就会通过_filter_unsupported_builtin_tools预过滤。对应行为由 tests/test_responses_architecture.py 的test_transport_downgrades_unsupported_builtin_tools验证。六、验证方式与测试覆盖dox 文档明确给出了修改传输归一化或降级行为后的验证命令pytest tests/test_stream_tool_early_stop.py tests/test_responses_architecture.py -q这两个测试文件是本模块行为的主要回归防线tests/test_stream_tool_early_stop.py通过monkeypatch.setattr(litellm_transport, acompletion, fake_acompletion)/monkeypatch.setattr(litellm_transport, aresponses, fake_aresponses)模拟双协议输出验证流式工具调用的早期结束、分片拼接与协议选择tests/test_responses_architecture.py验证ResponsesTransport.from_chat对previous_response_id/responses_input_items/responses_local_input_items的选择逻辑provider 状态与 local 回放的store差异见 tests/test_responses_architecture.py、provider 状态降级重试tests/test_responses_architecture.py、内置工具降级缓存tests/test_responses_architecture.py等。此外修改 OpenAI 兼容请求清洗逻辑后dox 建议进行本地提供商local-provider冒烟检查因为本地推理服务对参数校验往往比云端更严格更容易暴露非法字段。七、开发指引如何扩展这套传输层dox 的 Work Guidance 部分为后续维护者划定了三条边界提供商无关的请求清洗放在此处当多个 OpenAI 兼容提供商都能受益于某项参数清理时优先在litellm_transport.py中实现而不是逐个提供商打补丁降级行为是共享的传输契约而非提供商注册表新增降级规则应写入TransportPolicy.recover/_is_responses_not_supported_error这类分类函数避免在 providers 配置里堆砌特例工具转换保持对称ChatCompletionsTransport与ResponsesTransport之间的工具/工具选择/函数调用格式转换必须双向一致ChatCompletionsTransport.tool_call_object复用了ResponsesTransport.function_call_object正是这种对称性的体现。综上litellm_transport.py以策略 双协议构造/解析器的清晰分层把 Agent Zero 复杂的多提供商模型调用收敛为四个稳定的传输入口。理解它的运行时契约是接入新模型提供商、排查为什么走了降级路径、或为框架扩展缓存与状态能力时的第一把钥匙。【免费下载链接】agent-zeroAgent Zero AI framework项目地址: https://gitcode.com/GitHub_Trending/ag/agent-zero创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
