全模型支持背后的网关层 路由如何把对话发到对的厂商

📅 2026/8/12 20:36:22
全模型支持背后的网关层 路由如何把对话发到对的厂商
察元AI 桌面单机版 全模型支持 这件事说起来像一句口号做起来需要一整个网关层来撑。察元AI智能体 内部的模型网关把 18 家以上厂商的协议差异抹平成一套统一接口让上层的对话、RAG、工具调用、多模态都不用关心后面是 OpenAI 还是 DeepSeek 还是本地 Ollama。这一篇拆开看这个网关层。先看网关层处理的协议差异。OpenAI 协议是事实上的标准但每家厂商在实现细节上各有不同。比如 stream 字段的 delta 结构、tools 调用的参数命名、reasoning 字段的位置、错误码的格式、限流响应的形式、上下文窗口的边界处理。同样一句 chat completion在 OpenAI、Anthropic、文心、通义、智谱、豆包之间能发出来的报文有差不多十几种细微差异。网关层的核心抽象。它定义了一个统一的内部协议所有上层调用都基于这个协议。每家厂商在网关下挂一个 adapter把内部协议翻译成厂商协议把厂商协议翻译回内部协议。这种 adapter pattern 在工程上不新鲜难点在于把哪些字段抽出来作为内部协议的核心哪些字段作为可选扩展。察元AI智能体 在这一层做了几个明确取舍。第一个取舍是统一 messages 列表的格式。所有厂商的对话都映射到 [{role, content, …}] 这种结构role 是 system/user/assistant/tool 这几个值。content 既支持纯字符串也支持多模态片段数组。tool_calls 字段统一放在 assistant 消息里tool_call_id 在 tool 消息里。这套抽象覆盖了 95% 的实际场景。第二个取舍是把 streaming 抽成 SSE 通用格式。每家厂商流式响应的事件结构不一样网关层把它们统一成 察元AI智能体 自己的事件格式data 事件携带 delta、reasoning_delta、tool_call_delta、citation_delta 等字段。前端只需要处理这一种事件结构。第三个取舍是 tools 调用的归一化。OpenAI 的 function calling、Anthropic 的 tool_use、其他厂商的各种实现全部在网关层归一为内部 tools 调用协议。前端展示的三层折叠summary、参数与输出、完整 JSON就是基于这个归一化结构。路由决策。一次对话请求到 sidecar 之后网关层做几件事取出 model 字段按这个名字查询模型卡片库找到对应的 adapter按 adapter 的协议要求把请求改写成厂商需要的格式把请求发出去接到响应或流式事件按内部协议规范化返回给上层。整个过程对上层是透明的。模型卡片库。察元AI智能体 维护了一个内置的模型卡片库model registry记录每个常见模型的元数据所属厂商、协议类型、上下文窗口、是否支持 tools、是否支持视觉、计费倍率等。新增供应商时填一份卡片全模型支持 就多一家。/v1/models 自动探测拉到的模型也会按规则归类进卡片库。回退链路。模型调用失败时网关层支持配置 fallback 链路。比如 主用 GPT-4o失败回退到 deepseek-chat再失败回退到本地 qwen2.5。这种链路设计让用户的对话不会因为单家厂商不可用而完全中断。本地离线知识库 加 全模型支持 的组合在这种降级策略下尤其稳。限速与配额。察元AI智能体 单机版默认不强制限速但网关层埋了限速 hook企业部署时可以接入自家的配额系统。结果是单一用户密集调用某家厂商网关层会按厂商指示的限速规则做退避避免触发厂商封号。token 计费的本地估算。网关层有一份估算器对常见模型可以在不依赖厂商返回的 usage 字段时给出一个粗略的 token 计数。这对那些不返回 usage 的厂商或本地推理服务尤其有用。前端展示对话成本时用这个估算给用户一个参考。可观测性。每次模型调用的请求和响应都会落到 CHAYUAN_ROOT/logs/llm-trace 目录下默认开启简版可配详细方便用户排查。不会把模型 prompt 全文落盘但保留模型名、时间、token 数、错误码这些关键字段。WPS AI 插件 chayuan-wps 通过 sidecar 共用同一份网关层。在 WPS 文字里发起的对话跟桌面客户端发起的对话走同一组 adapter、同一份模型卡片库、同一套限速策略。这是 察元AI智能体 加 chayuan-wps 体验一致的根源。全模型支持 不是把厂商列表堆得越长越好而是把这层抽象做得让上层不感知差异。察元AI智能体 的模型网关层是这个理念的具体实现。