开源 AI Adapter 设计兼容多模型之前先统一最小语义一、Adapter 不是把所有接口都包一层开源 AI 工具链经常需要支持多家模型供应商。最直接的做法是写很多 Adapter把不同 API 包成统一调用。但如果只追求“参数都能传进去”工具链很快会变成一层很厚的兼容胶水。真正重要的是统一最小语义文本输入、消息历史、工具调用、流式输出、错误类型、用量统计。超出最小语义的能力可以通过扩展字段暴露而不是强行塞进核心接口。二、先定义核心调用模型flowchart TD A[应用请求] -- B[统一 Adapter 接口] B -- C[OpenAI Provider] B -- D[Local Model Provider] B -- E[Cloud Vendor Provider] C -- F[统一响应] D -- F E -- F核心接口越薄越容易长期维护。不要在第一版就抽象所有供应商的细节例如不同模型的缓存控制、响应格式、工具调用协议和安全过滤。抽象过早后面会被现实打脸。可以先把能力分为 required、optional 和 provider-specific。应用层只依赖 required进阶功能通过能力检测启用。三、类型要表达能力差异type ModelCapability { streaming: boolean toolCalling: boolean vision: boolean jsonMode: boolean } type ChatAdapter { capabilities(): ModelCapability chat(input: ChatInput): PromiseChatOutput stream?(input: ChatInput): AsyncIterableChatChunk }能力检测比假装所有模型都一样更诚实。一个模型不支持工具调用就应该在运行前提示而不是调用后才报模糊错误。adapter_contract: normalize_errors: true expose_usage: true support_capability_check: true keep_provider_extensions: true错误也要统一。超时、限流、认证失败、上下文过长、模型拒答应该映射成稳定错误码方便上层做重试和降级。四、兼容层要有测试矩阵多模型 Adapter 最怕“某个供应商升级后悄悄坏了”。开源项目应维护测试矩阵基础对话、流式输出、工具调用、JSON 输出、错误映射和用量统计。每个 Provider 都要跑相同契约测试。还要允许用户锁定 Provider 版本。模型接口变化很快如果 Adapter 自动跟随最新行为应用层会很难稳定。测试矩阵可以拆成两层契约测试和真实供应商测试。契约测试使用 mock provider保证 Adapter 必须返回统一结构真实供应商测试则定期运行验证外部 API 行为没有变化。开源项目不一定每次 PR 都调用真实模型但发布前必须至少跑一轮。type AdapterContractCase { name: string input: ChatInput expectStreaming?: boolean expectUsage?: boolean expectErrorCode?: string }还要记录 Provider 的差异说明。例如某个模型不返回 token 统计某个模型的 JSON 模式只支持特定参数某个本地模型不支持工具调用。把差异写进文档比在代码里悄悄降级更尊重用户。版本策略也要清楚。核心接口变化走 major新增可选能力走 minor修复错误映射走 patch。这样应用开发者才知道升级风险在哪里。五、总结开源 AI Adapter 设计要先统一最小语义再通过能力检测和扩展字段处理供应商差异。兼容不是把所有细节磨平而是在核心接口稳定的前提下承认不同模型各有边界。