模型 Provider 生态

要点

  • 三层架构 讲过,Provider 层的任务是把任意 LLM 厂商的 API 包装成 LanguageModelV2 接口
  • 1 OpenAI — @ai-sdk/openai
  • 1 OpenRouter — 一把 Key 通吃
  • 这是本专栏特别重要的一个 Provider
  • 本地跑模型有两种主流方式

内容

1. Provider 生态的全景

三层架构 讲过,Provider 层的任务是把任意 LLM 厂商的 API 包装成 LanguageModelV2 接口。这一篇我们把整个生态摊开来看一遍:都有哪些 Provider、什么场景用谁、自己项目里怎么选。

按出处分,Provider 有三类:

分类维护方举例
官方 ProviderVercel 官方@ai-sdk/openai / @ai-sdk/anthropic / @ai-sdk/google / @ai-sdk/mistral / @ai-sdk/xai / @ai-sdk/amazon-bedrock / @ai-sdk/azure / @ai-sdk/groq
社区 Provider第三方维护,质量不一@openrouter/ai-sdk-provider / workers-ai-provider / ollama-ai-provider / deepseek 等
自定义 Provider自己写内部私有 LLM、代理层、需要额外加工的模型

不过 Provider 只是「入口」,真正决定你能做什么的是后面接的模型。不同模型支持的能力差别很大,本章会用到的几个关键能力如下:

能力说明依赖的底层特性
基础 chat对话式生成几乎所有模型都有
流式输出逐 token 返回主流模型都有
Tool Calling函数调用较新的模型才有(GPT-4+、Claude 3+、Gemini 1.5+ 等)
结构化输出JSON Schema 强制输出部分模型有(OpenAI / Anthropic / Gemini 2+)
推理模型Reasoning / Thinking tokenso1 / o3 / Claude Sonnet 4.5 / DeepSeek R1 等
多模态输入图片 / 文件 / 音频部分多模态模型
原生 Web Search不用外部搜索 API少数模型(GPT-4o、Claude Sonnet 4+、Perplexity)

所以,一个 Provider 能给你什么,取决于它对接的模型支持什么。能力缺失时 AI SDK 会抛 NoSuchCapabilityError,不会悄悄降级。

2. 官方 Provider 三巨头

2.1 OpenAI — @ai-sdk/openai

最常用、文档最完整、能力最全。支持:chat、tool、结构化、多模态、推理模型、audio。

// openai.ts
import { openai } from '@ai-sdk/openai'
 
import { generateText } from 'ai'
 
const { text } = await generateText({
 
  model: openai('gpt-4o'),
 
  prompt: '...',
 
})
 
// 推理模型(o1 / o3 / o4-mini)
 
const { text: reasoningText } = await generateText({
 
  model: openai('o3-mini'),
 
  prompt: '一步一步推理:...',
 
  providerOptions: {
 
    openai: {
 
      reasoningEffort: 'medium', // low | medium | high
 
    },
 
  },
 
})

如果要走代理、中转或兼容层,给 OpenAI 指定自定义端点:

// openai-custom.ts
import { createOpenAI } from '@ai-sdk/openai'
 
const openai = createOpenAI({
 
  apiKey: process.env.OPENAI_API_KEY,
 
  baseURL: 'https://your-proxy.com/v1',
 
  compatibility: 'strict', // 'strict' | 'compatible'
 
})

compatibility: 'strict' 表示对方完全兼容 OpenAI 官方 API;'compatible' 是宽松模式,适配大部分兼容层(国内中转、LM Studio、某些国产模型的 OpenAI 兼容端点)。

2.2 Anthropic — @ai-sdk/anthropic

Claude 系列。和 OpenAI 相比有几处差异:

  • system 是独立字段,不作为消息的一员
  • 原生支持 reasoning part(Claude Sonnet 4.5+ 的 thinking tokens)
  • Tool 调用的 schema 解析更严格,参数名不能有保留字
// anthropic.ts
import { anthropic } from '@ai-sdk/anthropic'
 
import { streamText } from 'ai'
 
const result = streamText({
 
  model: anthropic('claude-opus-4-6'),
 
  system: '你是一个情绪敏感的 AI 伴侣。',
 
  messages,
 
  providerOptions: {
 
    anthropic: {
 
      thinking: {
 
        type: 'enabled',
 
        budgetTokens: 2000, // 思考 token 预算
 
      },
 
    },
 
  },
 
})

开启 thinking 之后,fullStream 里会先冒出 reasoning-delta 事件,再冒出正式的 text-delta。前端可以用 UI Parts 把「正在思考」和「正在回答」分开渲染。

2.3 Google — @ai-sdk/google

Gemini 系列。主要特色有几个:

  • 长上下文(Gemini 1.5 Pro 可用 2M tokens 上下文)
  • 原生多模态特别强,图、视频、音频都能直接传
  • Structured Output 用 JSON Mode,效果稳定
// google.ts
import { google } from '@ai-sdk/google'
 
import { generateText } from 'ai'
 
const { text } = await generateText({
 
  model: google('gemini-2.5-pro'),
 
  messages: [
 
    {
 
      role: 'user',
 
      content: [
 
        { type: 'text', text: '描述这张图里的人在干什么:' },
 
        { type: 'image', image: new URL('https://example.com/photo.jpg') },
 
      ],
 
    },
 
  ],
 
})

Gemini 还有一个 Vertex AI 版本(@ai-sdk/google-vertex),是给 GCP 企业客户用的,走 GCP 鉴权。

3. 聚合与中转 Provider

3.1 OpenRouter — 一把 Key 通吃

@openrouter/ai-sdk-provider 是社区维护得很积极的一个 Provider。它的核心价值是:一个 API Key、一套价格、覆盖 200+ 模型。调试阶段不用注册 N 家账号。

// openrouter.ts
import { createOpenRouter } from '@openrouter/ai-sdk-provider'
 
import { streamText } from 'ai'
 
const openrouter = createOpenRouter({
 
  apiKey: process.env.OPENROUTER_API_KEY,
 
})
 
const result = streamText({
 
  model: openrouter('anthropic/claude-opus-4-6'),
 
  prompt: '...',
 
})
 
// 换模型只改字符串
 
const result2 = streamText({
 
  model: openrouter('google/gemini-2.5-pro'),
 
  prompt: '...',
 
})

适合用它的场景:

  • 多模型对比实验
  • 国内访问 OpenAI / Claude 不便
  • 早期产品,还没稳定选型

不适合的场景:

  • 生产环境(多一层中转会增加延迟)
  • 对 token 成本非常敏感(OpenRouter 会加少量加价)

3.2 Azure OpenAI

企业合规场景常用,走 Azure 订阅鉴权:

// azure.ts
import { createAzure } from '@ai-sdk/azure'
 
const azure = createAzure({
 
  resourceName: 'your-resource',
 
  apiKey: process.env.AZURE_OPENAI_API_KEY,
 
  apiVersion: '2024-10-21',
 
})
 
const model = azure('your-deployment-name')

注意 Azure 走的是「deployment」而不是 modelId,名字是你在 Azure 控制台自定义的。模型版本和区域也在 Azure 控制台配置,Provider 端只需要 deployment 名称和 API 版本号。如果你公司已有 Azure 订阅,这通常是最省心的生产部署方案。

4. Cloudflare Workers AI Provider

这是本专栏特别重要的一个 Provider。AI 伴侣项目部署在 Cloudflare Workers 上,Workers AI 正好是天然搭档:

  • 免费额度够用:每天 10,000 个 Neuron,大致够几百到几千次 chat 调用(具体看模型)
  • 延迟很低:模型就跑在 Cloudflare 边缘节点上,不出 Workers 网络
  • 不用管 API Key:Workers 代码通过 binding,直接 env.AI 调用

官方没有 @ai-sdk/cloudflare-workers,不过社区有 workers-ai-provider

// index.bash
pnpm add workers-ai-provider
// workers-ai.ts
import { createWorkersAI } from 'workers-ai-provider'
 
import { streamText } from 'ai'
 
// 在 Workers Handler 里
 
export default {
 
  async fetch(req: Request, env: Env) {
 
    const workersai = createWorkersAI({ binding: env.AI })
 
    const result = streamText({
 
      model: workersai('@cf/meta/llama-3.3-70b-instruct-fp8-fast'),
 
      prompt: 'hi',
 
    })
 
    return result.toUIMessageStreamResponse()
 
  },
 
}

wrangler.jsonc 里配 AI binding:

// wrangler.jsonc
{
 
  "name": "ai-companion",
 
  "main": "src/index.ts",
 
  "compatibility_date": "2026-04-01",
 
  "ai": {
 
    "binding": "AI"
 
  }
 
}

它的优点很直接:零配置鉴权、部署到 Workers 后延迟非常低、成本好预估。

但也有几个短板要知道:模型池有限,最新的 GPT / Claude 用不了;本地开发(wrangler dev)有一些限制;部分高级特性比如 thinking tokens 暂时还没跟上。

本专栏采用的策略是主力用 Workers AI、回退用 OpenAI。缓存、限流、Fallback 做 Fallback 中间件时会用到这个组合。

5. 本地模型 Provider

本地跑模型有两种主流方式。

5.1 Ollama — ollama-ai-provider

Ollama 是目前最简单的本地 LLM 运行时。装好 Ollama 客户端,ollama run llama3.3,就能通过 HTTP 调它。

// ollama.ts
import { createOllama } from 'ollama-ai-provider'
 
import { generateText } from 'ai'
 
const ollama = createOllama({
 
  baseURL: 'http://localhost:11434/api',
 
})
 
const { text } = await generateText({
 
  model: ollama('llama3.3'),
 
  prompt: '...',
 
})

适合用它的场景:

  • 离线开发或演示
  • 隐私极敏感的内部工具
  • 学生党、没有 API 预算的个人项目

注意 Ollama 的 Tool Calling 支持度因模型而异,简单 chat 一般没问题,复杂 Agent 流程可能不稳。

5.2 LM Studio / OpenAI 兼容端点

LM Studio、vLLM、TGI 这些本地部署工具都会提供 OpenAI 兼容端点。直接用 createOpenAI({ baseURL: '...', compatibility: 'compatible' }) 指过去就行。

// lm-studio.ts
import { createOpenAI } from '@ai-sdk/openai'
 
const local = createOpenAI({
 
  baseURL: 'http://localhost:1234/v1',
 
  apiKey: 'lm-studio', // 占位,本地服务通常不校验
 
  compatibility: 'compatible',
 
})
 
const { text } = await generateText({
 
  model: local('local-model'),
 
  prompt: '...',
 
})

6. 自定义 Provider:从零包一个

有时候你需要包一个内部私有 LLM,比如公司自建的大模型网关,或者一个需要额外加工的代理层。

AI SDK 提供了 customProvider 帮手,不用从零实现 LanguageModelV2

// custom.ts
import { customProvider } from 'ai'
 
import { createOpenAI } from '@ai-sdk/openai'
 
// 场景:内部网关,对外暴露 OpenAI 兼容 API,但做了模型别名映射
 
const internal = customProvider({
 
  languageModels: {
 
    'smart': createOpenAI({ baseURL: 'https://gw.intra/v1' })('gpt-4o'),
 
    'fast':  createOpenAI({ baseURL: 'https://gw.intra/v1' })('gpt-4o-mini'),
 
    'cheap': createOpenAI({ baseURL: 'https://gw.intra/v1' })('gpt-3.5-turbo'),
 
  },
 
  fallbackProvider: createOpenAI({ baseURL: 'https://gw.intra/v1' }),
 
})
 
// 业务代码只认内部别名
 
const { text } = await generateText({
 
  model: internal.languageModel('smart'),
 
  prompt: '...',
 
})

这么做有几个好处:业务代码和模型厂商脱钩,公司换家也不用动业务;别名语义清晰(smart / fast / cheap);可以在 fallbackProvider 里统一配置 baseURL 和鉴权。

如果你要的是完全从零实现,就得手写一个符合 LanguageModelV2 接口的对象。这一层比较底层,一般不需要自己写,除非你对接的是非常小众的模型。

7. Provider 基线与选型建议

给本章后续例子定一个 Provider 基线

为了让后面 17 篇示例代码可以复用、可以替换,我们约定一个 Provider 基线文件,集中管理:

// packages/shared/models.ts
import { openai, createOpenAI } from '@ai-sdk/openai'
 
import { anthropic } from '@ai-sdk/anthropic'
 
import { customProvider } from 'ai'
 
// 默认走 OpenAI,如果你没 key,把下面一行改成你要的 Provider 即可
 
const defaultProvider = {
 
  chat: openai('gpt-4o-mini'),
 
  chatPro: openai('gpt-4o'),
 
  reasoning: openai('o3-mini'),
 
  structured: openai('gpt-4o-mini'),
 
}
 
// Anthropic 备份线
 
const anthropicProvider = {
 
  chat: anthropic('claude-sonnet-4-5'),
 
  chatPro: anthropic('claude-opus-4-6'),
 
  reasoning: anthropic('claude-opus-4-6'),
 
  structured: anthropic('claude-sonnet-4-5'),
 
}
 
export const models = defaultProvider
 
// export const models = anthropicProvider
 
// 专供 Workers 环境用([AI SDK × Hono](/15-ai-sdk-with-hono) 会用到)
 
export function getWorkersAIModels(binding: Ai) {
 
  const { createWorkersAI } = require('workers-ai-provider')
 
  const workersai = createWorkersAI({ binding })
 
  return {
 
    chat: workersai('@cf/meta/llama-3.3-70b-instruct-fp8-fast'),
 
    chatPro: workersai('@cf/meta/llama-3.3-70b-instruct-fp8-fast'),
 
    reasoning: workersai('@cf/deepseek-ai/deepseek-r1-distill-qwen-32b'),
 
    structured: workersai('@cf/meta/llama-3.3-70b-instruct-fp8-fast'),
 
  }
 
}

后面所有例子里我们都这么写:

// example.ts
import { models } from '@/shared/models'
 
const { text } = await generateText({
 
  model: models.chat,
 
  prompt: '...',
 
})

这样每一篇的焦点就不会被 Provider 选择干扰。你也可以按需切到 Anthropic / Workers AI 跑同样的代码。

选型建议

下表给几个典型项目的推荐。先看「场景」列找到自己的定位,再看对应的「推荐」和「理由」。

场景推荐理由
个人学习 / HackathonOpenAI + Ollama 备份最省事
AI 伴侣(本专栏)Workers AI 主 + OpenAI 回退免费额度大、延迟低、Fallback 保底
企业内部工具Azure OpenAI / 自建网关 + 自定义 Provider合规、统一计费
多模型对比 / 调研OpenRouter一把 key 省心
离线演示Ollama + LM Studio不依赖网络
推理密集型 Agento3 / Claude Opus 4.6 / DeepSeek R1推理能力强

一个很实用的经验:项目早期别纠结 Provider,先用最顺手的跑通业务;后期再换成适合生产的 Provider,这一步在 AI SDK 里是无损切换(Provider 层本来就解耦了)。如果你是跟着本专栏从头做 AI 伴侣,先用 OpenAI 跑通,AI SDK × Hono 再切到 Workers AI。

8. 小结

  • Provider 分三类:官方、社区、自定义,能力高度依赖后面的模型本身
  • 官方三巨头:OpenAI / Anthropic / Google,基本能力都齐,细节 API 略有差异
  • OpenRouter 适合调研期,一把 key 通吃 200+ 模型
  • Workers AI 是 Cloudflare 生态首选:免费额度大、延迟低、无需 API Key
  • 自定义 Provider 用 customProvider 帮手,给模型起别名、统一 baseURL
  • 本章示例统一用 @/shared/models 文件管理 Provider,方便切换和对照

下一篇拆消息协议——两套消息模型 UIMessageModelMessage 的职责差异,以及 convertToModelMessages 的作用。这是前后端之间最容易绊倒人的一环。