21. packages/ai/providers:同一 Context 怎样走到不同厂商¶
这个模块干什么¶
providers/ 的每个工厂把一个 provider ID、认证、模型目录和一个或多个 API adapter 组装为 Provider。(packages/ai/src/models.ts:533-556)
provider 不等于 wire protocol:多个 provider 可以共用 openai-completions,同一 provider 也可以按 model.api 分派多种协议。(packages/ai/src/models.ts:546-547;packages/ai/src/models.ts:570-587)
所有文本 adapter 最终都要返回 AssistantMessageEventStream,把厂商增量压成同一组文本、思考、工具和终止事件。(packages/ai/src/types.ts:221-232;packages/ai/src/types.ts:491-503)
内置集合由 builtinProviders() 每次新建工厂结果,builtinModels() 再逐一注册到一个 Models 集合。(packages/ai/src/providers/all.ts:86-136)
核心文件速查¶
| 文件 | 一句话职责 | 必读优先级 |
|---|---|---|
src/providers/all.ts |
列出全部聊天 provider,并构造完整内置 Models 集合。packages/ai/src/providers/all.ts:86-151 |
⭐⭐⭐ |
src/providers/anthropic.ts |
配置 Anthropic 的目录、三层 key 查找和 OAuth 懒加载。packages/ai/src/providers/anthropic.ts:9-50 |
⭐⭐⭐ |
src/api/anthropic-messages.ts |
生成 Anthropic payload,并手写解码其 SSE 后转成统一事件。packages/ai/src/api/anthropic-messages.ts:387-485 |
⭐⭐⭐ |
src/providers/openai.ts |
将 OpenAI 模型绑定到 Responses adapter。packages/ai/src/providers/openai.ts:6-14 |
⭐⭐⭐ |
src/api/openai-responses.ts |
创建 Responses 请求、调用 SDK 流并委托公共事件归一化。packages/ai/src/api/openai-responses.ts:101-190 |
⭐⭐⭐ |
src/api/openai-responses-shared.ts |
转换对话/工具,按 output slot 解析 Responses 增量。packages/ai/src/api/openai-responses-shared.ts:136-725 |
⭐⭐⭐ |
src/providers/google.ts |
将 Gemini API key、模型目录和 Google adapter 接在一起。packages/ai/src/providers/google.ts:6-14 |
⭐⭐⭐ |
src/api/google-generative-ai.ts |
把 Context 变成 generateContentStream 参数并归一化 chunk。packages/ai/src/api/google-generative-ai.ts:51-282 |
⭐⭐⭐ |
src/api/google-shared.ts |
给 Google/Vertex 共用消息、工具、签名和停止原因转换。packages/ai/src/api/google-shared.ts:89-370 |
⭐⭐⭐ |
src/bedrock-provider.ts |
为独立 Bun 构建提供 Bedrock 的静态 streams 模块。packages/ai/src/bedrock-provider.ts:1-6 |
⭐ |
精读¶
1. 先看工厂的共同骨架¶
createProvider() 的输入固定为 ID、可选名称/endpoint/headers、认证、静态 models、可选动态 fetch、可选过滤器和 API streams。(packages/ai/src/models.ts:533-548)
普通 provider 传一套 ProviderStreams,混合 provider 传 Partial<Record<model.api, ProviderStreams>>。(packages/ai/src/models.ts:546-547;packages/ai/src/models.ts:570-574)
后者找不到某 API 时不会同步抛出,而是制造一个带 ModelsError("stream", ...) 的错误流。(packages/ai/src/models.ts:576-587)
工厂的 models 通常来自相邻 *.models.ts wrapper;这些 wrapper 再连接生成目录,生成文件本身不必作为本章主线阅读。(packages/ai/src/providers/anthropic.ts:6-7;packages/ai/src/providers/all.ts:1-4)
builtinProviders() 的数组就是内置聊天 provider 的权威注册清单,顺序和工厂调用在同一个函数里可见。(packages/ai/src/providers/all.ts:86-128)
builtinModels() 不缓存单例:它新建 collection,再逐个 setProvider()。(packages/ai/src/providers/all.ts:130-136)
2. Anthropic:自解 SSE,精确保留 thinking 与工具参数¶
anthropicProvider() 选择 anthropic-messages adapter、https://api.anthropic.com、静态 Anthropic 目录,并同时声明 API-key 与 OAuth 认证。(packages/ai/src/providers/anthropic.ts:38-50)
它的 API-key resolver 优先已存 credential,再查 ANTHROPIC_AUTH_TOKEN,最后按 ANTHROPIC_OAUTH_TOKEN、ANTHROPIC_API_KEY 顺序找 key。(packages/ai/src/providers/anthropic.ts:9-35)
ANTHROPIC_AUTH_TOKEN 特殊在于会变成 Authorization: Bearer ... 头,而不是 apiKey 字段。(packages/ai/src/providers/anthropic.ts:21-26)
AnthropicOptions 除共同 options 外提供 thinkingEnabled、预算、adaptive effort、thinking 展示、交错 thinking、工具选择和可注入 client。(packages/ai/src/api/anthropic-messages.ts:202-262)
adapter 在创建 SDK client 前接受 API key、authorization、x-api-key 或 cf-aig-authorization 任一种认证来源。(packages/ai/src/api/anthropic-messages.ts:274-293)
这让 Anthropic-compatible gateway 能用 header-owned auth,而不强迫调用者伪造 API key。(packages/ai/src/api/anthropic-messages.ts:283-293)
它没有把上游 SSE 完全交给 SDK:iterateSseMessages() 从 ReadableStream 增量解码,按空行 flush event/多行 data。(packages/ai/src/api/anthropic-messages.ts:316-444)
iterateAnthropicEvents() 只接收六种 Messages 事件,遇到 error 立即抛错,并验证若出现 message_start 必须出现 message_stop。(packages/ai/src/api/anthropic-messages.ts:307-315;packages/ai/src/api/anthropic-messages.ts:446-485)
解析 JSON 时带修复路径,报错信息会保留 SSE event、data 与 raw 行,便于诊断有问题的网关。(packages/ai/src/api/anthropic-messages.ts:466-478)
stream() 先建空的统一 AssistantMessage,随后调用 client.messages.create({ stream: true }) 并先发统一 start。(packages/ai/src/api/anthropic-messages.ts:487-567)
message_start 写入 response ID 与初始用量,提前拿到输入 token 即使之后流被中止也不会丢失。(packages/ai/src/api/anthropic-messages.ts:572-585)
content_block_start 按 text、thinking、redacted thinking、tool use 建立统一块,并立刻发对应 *_start。(packages/ai/src/api/anthropic-messages.ts:586-627)
普通文本与 thinking delta 直接追加并发 text_delta/thinking_delta。(packages/ai/src/api/anthropic-messages.ts:628-652)
工具的 input_json_delta 累积到 partialJson,每一段用容错 JSON 解析更新部分 arguments 再发 toolcall_delta。(packages/ai/src/api/anthropic-messages.ts:653-665)
block stop 时删除内部索引与临时 JSON 缓冲,只把已解析参数作为最终 ToolCall 发出。(packages/ai/src/api/anthropic-messages.ts:674-705)
message_delta 负责将厂商停止原因、用量和可选 thinking token 归入同一个输出对象。(packages/ai/src/api/anthropic-messages.ts:706-741)
正常结束发 done,异常或 abort 则发 error,两条路径都关闭流。(packages/ai/src/api/anthropic-messages.ts:745-768)
请求方向先经 transformMessages(),接着按是否 OAuth 规范工具名,再把已加载与延迟工具拆开。(packages/ai/src/api/anthropic-messages.ts:930-951)
用户文字和图片分别变成 Anthropic text 与 base64 image source;空文本消息会被跳过。(packages/ai/src/api/anthropic-messages.ts:1107-1158)
同模型 thinking 带签名会作为 thinking 回放;无签名的普通 thinking 会退为 text,redacted 则回传为 redacted_thinking。(packages/ai/src/api/anthropic-messages.ts:1159-1203)
连续工具结果被合成一个 user turn;工具引用不能和普通工具结果混在一个 content block 中,因此会拆出 sibling 内容。(packages/ai/src/api/anthropic-messages.ts:1072-1105;packages/ai/src/api/anthropic-messages.ts:1218-1244)
工具 schema 默认收敛为对象的 properties/required,支持 strict 时才携带完整 schema 与 strict: true。(packages/ai/src/api/anthropic-messages.ts:1278-1313)
streamSimple() 将统一 reasoning 映射到 adaptive effort 或预算型 thinking,并在后者为输出留至少 1024 token。(packages/ai/src/api/anthropic-messages.ts:796-836)
3. OpenAI:Responses item 流先建槽,再落到共同内容块¶
openaiProvider() 的模型 API 固定是 openai-responses,endpoint 是 /v1,认证是 OPENAI_API_KEY 的标准 resolver。(packages/ai/src/providers/openai.ts:6-14)
所以重点不是 Chat Completions,而是 Responses API 的 messages、工具与事件项目转换。(packages/ai/src/providers/openai.ts:6-14;packages/ai/src/api/openai-responses.ts:252-325)
stream() 创建空统一消息,计算 cache retention、兼容能力和 grammar 工具参数,再建 OpenAI client 与请求参数。(packages/ai/src/api/openai-responses.ts:101-148)
它通过 client.responses.create(...).withResponse() 取得 SDK async stream 和原始 HTTP response,随后触发 onResponse 并发统一 start。(packages/ai/src/api/openai-responses.ts:149-164)
真正的 Responses event 归一化集中在 processResponsesStream(),而不是散在 provider factory。(packages/ai/src/api/openai-responses.ts:160-164;packages/ai/src/api/openai-responses-shared.ts:416-725)
异常时会删除每块的 index、partialJson 与 custom-input 缓冲,再以统一 error 终止。(packages/ai/src/api/openai-responses.ts:176-187)
请求转换从 convertResponsesMessages() 开始,它会先规范工具 ID,然后运行通用 transformMessages()。(packages/ai/src/api/openai-responses-shared.ts:145-170)
有 reasoning 的模型默认把 system prompt 放进 developer role,兼容字段明确关闭时才回退为 system。(packages/ai/src/api/openai-responses-shared.ts:172-180)
用户文字映射为 input_text,图片变成 data URL 的 input_image。(packages/ai/src/api/openai-responses-shared.ts:183-209)
助手 thinking 的签名可直接作为 Responses reasoning item 回放;文字则被包装成已完成的 output message。(packages/ai/src/api/openai-responses-shared.ts:210-245)
工具调用按普通 function 与 grammar custom tool 分别变为 function_call 或 custom_tool_call。(packages/ai/src/api/openai-responses-shared.ts:246-283)
工具结果相应转换成 function_call_output 或 custom_tool_call_output,并可把延迟工具作为 client-executed tool search 结果插入。(packages/ai/src/api/openai-responses-shared.ts:287-332)
convertResponsesTools() 有 grammar 时生成 type: "custom",否则生成带可选 strict 的 function schema。(packages/ai/src/api/openai-responses-shared.ts:344-379)
流解析按 Responses 的 output_index 建 thinking、text 或 toolCall slot,并立即发各自 start 事件。(packages/ai/src/api/openai-responses-shared.ts:409-505)
reasoning、output text 和 refusal 的 delta 分别追加进 slot 并统一为 thinking_delta 或 text_delta。(packages/ai/src/api/openai-responses-shared.ts:566-620)
function arguments delta 用容错 JSON 维护部分参数;custom tool input 走独立 grammar 缓冲。(packages/ai/src/api/openai-responses-shared.ts:621-648)
response.output_item.done 在块结束时写入回放所需的 thinking/text signature,或去掉临时参数缓冲后发 toolcall_end。(packages/ai/src/api/openai-responses-shared.ts:649-705)
terminal response 把 token 用量、服务等级价差和状态转换成统一 usage/stopReason;若有工具调用会把正常 stop 改为 toolUse。(packages/ai/src/api/openai-responses-shared.ts:527-564)
若 async stream 没有任何 terminal response event,函数故意抛错,外层会把它变成统一错误流。(packages/ai/src/api/openai-responses-shared.ts:706-724;packages/ai/src/api/openai-responses.ts:176-187)
buildParams() 把转换后的输入置为 stream: true,控制 prompt cache key/retention,固定 store: false。(packages/ai/src/api/openai-responses.ts:252-282)
它把模型的 reasoning 能力和 caller 的 effort/summary 映射到 params.reasoning,并请求 encrypted reasoning content 以便回放。(packages/ai/src/api/openai-responses.ts:307-323)
streamSimple() 只把统一 reasoning 经 clampThinkingLevel() 转为 reasoningEffort,然后复用 stream()。(packages/ai/src/api/openai-responses.ts:193-208)
4. Google:Part、thought signature 与函数调用统一成内容块¶
googleProvider() 将 provider ID google、GEMINI_API_KEY、Google 模型目录和 google-generative-ai adapter 连在一起。(packages/ai/src/providers/google.ts:6-14)
GoogleOptions 除共同 options 外公开工具选择及 { enabled, budgetTokens, level } thinking 配置。(packages/ai/src/api/google-generative-ai.ts:39-46)
convertMessages() 先跑共同消息变换,并为特定模型把工具 ID 限制到 Google 可接受的字符和 64 长度。(packages/ai/src/api/google-shared.ts:90-100)
用户文字转 Part.text,图片转 inlineData。(packages/ai/src/api/google-shared.ts:101-126)
只有同 provider 且同 model 的 thinking 会带 thought: true 和有效 base64 signature 回放;跨模型 thinking 降为普通 text。(packages/ai/src/api/google-shared.ts:127-170)
工具调用转为 functionCall,某些模型还需要显式 function-call ID。(packages/ai/src/api/google-shared.ts:158-168;packages/ai/src/api/google-shared.ts:68-73)
工具结果转为 functionResponse,Gemini 3+ 可以把图片嵌在 response 内,旧模型则追加一个单独的用户图片 turn。(packages/ai/src/api/google-shared.ts:177-231)
convertTools() 默认给 parametersJsonSchema,仅 Cloud Code Assist/Claude 的兼容情形才使用旧 parameters 字段。(packages/ai/src/api/google-shared.ts:265-289)
严格工具模式只在 Gemini 3+ 生效;此时 resolveGoogleFunctionCallingMode() 选 VALIDATED。(packages/ai/src/api/google-shared.ts:291-324)
stream() 调 client.models.generateContentStream(params),开始前校验 API key,并在获取流后发统一 start。(packages/ai/src/api/google-generative-ai.ts:51-90)
每个上游 Part.text 依据 part.thought === true 归入 text 或 thinking block;块类型转换前会先发前一块的 end。(packages/ai/src/api/google-generative-ai.ts:94-160;packages/ai/src/api/google-shared.ts:20-36)
retainThoughtSignature() 防止后续 delta 没有 signature 时把当前块已有的非空签名覆盖掉。(packages/ai/src/api/google-shared.ts:38-50;packages/ai/src/api/google-generative-ai.ts:135-158)
Google 的 function call 没有细粒度参数流,因此 adapter 生成或保留唯一 ID 后一次发 start、完整 JSON delta、end。(packages/ai/src/api/google-generative-ai.ts:162-207)
finish reason 先映射到统一 stop reason,有任何工具调用时改写为 toolUse。(packages/ai/src/api/google-generative-ai.ts:211-216;packages/ai/src/api/google-shared.ts:326-355)
usage 把 cached input、candidate output、thought token 和成本统一填入 Usage。(packages/ai/src/api/google-generative-ai.ts:218-237)
buildParams() 组合转换后 contents、温度、最大输出、系统提示、工具、函数调用模式和 abort signal。(packages/ai/src/api/google-generative-ai.ts:344-397)
启用 thinking 时,Gemini 3/Gemma 4 用 thinkingLevel,其余模型通常走 thinkingBudget。(packages/ai/src/api/google-generative-ai.ts:285-321;packages/ai/src/api/google-generative-ai.ts:371-381)
关闭 thinking 对 Gemini 3 不是一律 0:Pro 用 LOW,Flash/Gemma 4 用 MINIMAL,Gemini 2.x 才用 budget 0。(packages/ai/src/api/google-generative-ai.ts:415-431)
5. Bedrock:Node-only SDK 通过显式桥接避开 bundle 追踪¶
amazonBedrockProvider() 使用 bedrock-converse-stream 和自定义 AWS/bearer 认证,而不是普通环境 key helper。(packages/ai/src/providers/amazon-bedrock.ts:6-81)
其认证可识别存储 bearer token、AWS_BEARER_TOKEN_BEDROCK、profile、IAM key、ECS role 和 web identity。(packages/ai/src/providers/amazon-bedrock.ts:52-71)
bedrockConverseStreamApi() 通过变量 specifier 动态导入 Node-only implementation,因此 browser/Bun bundle 不会静态追入 AWS SDK。(packages/ai/src/api/bedrock-converse-stream.lazy.ts:4-13;packages/ai/src/api/bedrock-converse-stream.lazy.ts:26-30)
独立 Bun 二进制可调用 setBedrockProviderModule() 注入静态模块。(packages/ai/src/api/bedrock-converse-stream.lazy.ts:15-24)
bedrock-provider.ts 正是这个静态模块:只把真正 adapter 的 stream 与 streamSimple 打包成 ProviderStreams 形状。(packages/ai/src/bedrock-provider.ts:1-6)
Bedrock adapter 将 ConverseStream item 的 message start、content start/delta/stop、message stop、metadata 分派成统一事件和用量。(packages/ai/src/api/bedrock-converse-stream.ts:224-303)
自定义 headers 在 Smithy build 阶段注入,既让它们被 SigV4 覆盖,也禁止覆写 authorization、host 与 x-amz-*。(packages/ai/src/api/bedrock-converse-stream.ts:357-387)
6. 其余聊天 provider:看它们把模型指向哪种 adapter¶
Ant Ling¶
antLingProvider() 使用 openai-completions 与 ANT_LING_API_KEY;消息和 SSE 正规化因此复用 OpenAI-compatible adapter。(packages/ai/src/providers/ant-ling.ts:1-14)
Azure OpenAI¶
azureOpenAIResponsesProvider() 使用专用 azure-openai-responses adapter 和 AZURE_OPENAI_API_KEY,而不是把 Azure 伪装成根 OpenAI provider。(packages/ai/src/providers/azure-openai-responses.ts:1-13)
Cerebras¶
cerebrasProvider() 将 Cerebras endpoint、CEREBRAS_API_KEY 与 openai-completions 绑定,复用该协议的转换和流解析。(packages/ai/src/providers/cerebras.ts:1-15)
Cloudflare AI Gateway¶
cloudflareAIGatewayProvider() 是混合 provider,按模型选择 Anthropic、OpenAI Completions 或 OpenAI Responses,并先由 cloudflareStreams() 填 endpoint 占位符。(packages/ai/src/providers/cloudflare-ai-gateway.ts:1-23;packages/ai/src/providers/cloudflare-stream.ts:17-28)
Cloudflare Workers AI¶
cloudflareWorkersAIProvider() 走 openai-completions,同样先包一层 cloudflareStreams() 以从已解析环境替换 account/gateway 字段。(packages/ai/src/providers/cloudflare-workers-ai.ts:1-15;packages/ai/src/providers/cloudflare-stream.ts:6-15)
DeepSeek¶
deepseekProvider() 把 DeepSeek 目录和 DEEPSEEK_API_KEY 接到 openai-completions,所以适配差异应优先在模型 compat 或该公共 adapter 中寻找。(packages/ai/src/providers/deepseek.ts:1-15)
Fireworks¶
fireworksProvider() 是混合工厂:目录中不同模型分别可走 Anthropic Messages 或 OpenAI Completions。(packages/ai/src/providers/fireworks.ts:1-19)
GitHub Copilot¶
githubCopilotProvider() 同时映射 Anthropic、Completions、Responses,并在 OAuth credential 带 availableModelIds 时过滤可用模型。(packages/ai/src/providers/github-copilot.ts:1-33)
Google Vertex AI¶
googleVertexProvider() 使用单独 google-vertex adapter;认证可为 Cloud API key,也可为带 project/location 的 ADC。(packages/ai/src/providers/google-vertex.ts:8-92)
Groq¶
groqProvider() 使用 GROQ_API_KEY 和 openai-completions,其厂商差异由该兼容 adapter 吸收。(packages/ai/src/providers/groq.ts:1-15)
Hugging Face¶
huggingfaceProvider() 用 HF_TOKEN 接 Hugging Face router 的 OpenAI-compatible endpoint。(packages/ai/src/providers/huggingface.ts:1-15)
Kimi For Coding¶
kimiCodingProvider() 选择 Anthropic Messages,并同时提供 KIMI_API_KEY 与订阅 OAuth 的懒加载入口。(packages/ai/src/providers/kimi-coding.ts:1-23)
MiniMax 与 MiniMax CN¶
minimaxProvider() 和 minimaxCnProvider() 分别使用全球/中国 endpoint 与不同 key 环境变量,但二者都走 Anthropic Messages adapter。(packages/ai/src/providers/minimax.ts:1-15;packages/ai/src/providers/minimax-cn.ts:1-15)
Mistral¶
mistralProvider() 不走 OpenAI-compatible adapter,而是明确使用 mistral-conversations 的独立协议实现。(packages/ai/src/providers/mistral.ts:1-15)
Moonshot AI 与 Moonshot AI CN¶
moonshotaiProvider() 和中国版本共享 MOONSHOT_API_KEY、各自 endpoint 与 openai-completions adapter。(packages/ai/src/providers/moonshotai.ts:1-15;packages/ai/src/providers/moonshotai-cn.ts:1-15)
NVIDIA¶
nvidiaProvider() 把 NVIDIA endpoint、NVIDIA_API_KEY 和 openai-completions 组合为普通静态 provider。(packages/ai/src/providers/nvidia.ts:1-15)
OpenAI Codex¶
openaiCodexProvider() 使用 openai-codex-responses 和 ChatGPT Plus/Pro OAuth;它没有普通 API-key resolver。(packages/ai/src/providers/openai-codex.ts:1-18)
OpenCode Zen¶
opencodeProvider() 是四协议混合 provider:Anthropic、Google、Completions、Responses 由 model.api 精确分派。(packages/ai/src/providers/opencode.ts:1-24)
OpenCode Zen Go¶
opencodeGoProvider() 是三协议版本,省去 Google adapter,仍用同一个 OPENCODE_API_KEY。(packages/ai/src/providers/opencode-go.ts:1-20)
OpenRouter¶
openrouterProvider() 选 openai-completions,同时接受 OPENROUTER_API_KEY 或懒加载的 OpenRouter OAuth。(packages/ai/src/providers/openrouter.ts:1-23)
Qwen Token Plan 与中国区¶
qwenTokenPlanProvider() 与中国版本都是 OpenAI-compatible adapter,只在 endpoint、目录和 key 名称上分区。(packages/ai/src/providers/qwen-token-plan.ts:1-15;packages/ai/src/providers/qwen-token-plan-cn.ts:1-15)
Radius¶
radiusProvider() 不使用 createProvider() 的通用动态层,而是自行维护缓存、单飞刷新、OAuth/API key 与 pi-messages streams。(packages/ai/src/providers/radius.ts:19-66)
Together¶
togetherProvider() 把 Together 的静态目录和 TOGETHER_API_KEY 指向 openai-completions。(packages/ai/src/providers/together.ts:1-15)
Vercel AI Gateway¶
vercelAIGatewayProvider() 当前将其目录接在 Anthropic Messages adapter,并用 AI_GATEWAY_API_KEY 认证。(packages/ai/src/providers/vercel-ai-gateway.ts:1-15)
xAI¶
xaiProvider() 是 Completions/Responses 双协议 provider,且可用 XAI_API_KEY 或订阅 OAuth。(packages/ai/src/providers/xai.ts:1-27)
Xiaomi API billing¶
xiaomiProvider() 以 XIAOMI_API_KEY 和 openai-completions 提供默认 Xiaomi MiMo 目录。(packages/ai/src/providers/xiaomi.ts:1-15)
Xiaomi Token Plan CN¶
xiaomiTokenPlanCnProvider() 使用中国区 endpoint、专属 key 和同一 OpenAI-compatible adapter。(packages/ai/src/providers/xiaomi-token-plan-cn.ts:1-15)
Xiaomi Token Plan AMS¶
xiaomiTokenPlanAmsProvider() 将阿姆斯特丹目录和 XIAOMI_TOKEN_PLAN_AMS_API_KEY 接到 openai-completions。(packages/ai/src/providers/xiaomi-token-plan-ams.ts:1-15)
Xiaomi Token Plan SGP¶
xiaomiTokenPlanSgpProvider() 与 AMS/CN 同构,只替换为新加坡目录、endpoint 与 key 名称。(packages/ai/src/providers/xiaomi-token-plan-sgp.ts:1-15)
Z.AI¶
zaiProvider() 使用 Z.AI coding endpoint、ZAI_API_KEY 和 openai-completions。(packages/ai/src/providers/zai.ts:1-15)
Z.AI Coding CN¶
zaiCodingCnProvider() 对应中国区 endpoint 与 ZAI_CODING_CN_API_KEY,但仍复用 openai-completions。(packages/ai/src/providers/zai-coding-cn.ts:1-15)
Faux¶
fauxProvider() 为测试构造一个 keyless Provider;它从脚本响应队列模拟文本、thinking、工具调用的同一事件协议。(packages/ai/src/providers/faux.ts:308-401;packages/ai/src/providers/faux.ts:510-538)
OpenRouter Images¶
openrouterImagesProvider() 属于独立图像生成集合,不进入聊天 builtinProviders();它有自己的 ImagesProvider 与 openrouter-images API。(packages/ai/src/providers/openrouter-images.ts:1-22;packages/ai/src/providers/all.ts:139-150)
数据流¶
以 OpenAI、Anthropic、Google 三条线并排看,入口一致,分叉发生在 provider 所选 API:
Context + Model
-> Models.stream()/streamSimple()
-> Provider.stream*()
-> anthropic-messages | openai-responses | google-generative-ai
-> 厂商 payload + 厂商流
-> AssistantMessageEventStream
Models.stream() 先在 lazyStream() 内解析认证,再把认证后的模型和 options 交给 provider。(packages/ai/src/models.ts:489-501)
Anthropic 分支先把消息转为 MessageParam[],发 Messages SSE,再按 content_block_* 还原 text/thinking/toolcall 事件。(packages/ai/src/api/anthropic-messages.ts:930-1065;packages/ai/src/api/anthropic-messages.ts:586-705)
OpenAI 分支把历史转为 Responses input,SDK 流按 output_index 绑定 slot,再把每个 slot 的 delta/end 写入统一流。(packages/ai/src/api/openai-responses-shared.ts:136-337;packages/ai/src/api/openai-responses-shared.ts:416-705)
Google 分支把历史转为 Content[] 和函数声明,generateContentStream 的 Part 依 thought 与 functionCall 分别翻译。(packages/ai/src/api/google-shared.ts:92-235;packages/ai/src/api/google-generative-ai.ts:88-237)
三者最终都用 done 携带完整 assistant 消息,用 error 携带可保留部分内容的错误消息。(packages/ai/src/types.ts:483-503)
消费者不必了解上游是 SSE、SDK AsyncIterable 还是 Bedrock event stream,只需按统一事件渲染或驱动 agent loop。(packages/ai/src/types.ts:221-232;packages/ai/src/utils/event-stream.ts:69-83)
自测¶
- 为什么 provider 和 API adapter 必须拆开,而不能一个厂商一个完整实现?
- Anthropic 为什么自行解析 SSE,而 OpenAI Responses 为什么按 output slot 处理?
- OpenAI Responses 怎样在回放时处理 reasoning signature 与 function-call ID?
- Google 的
thoughtSignature为什么只能随同 provider、同 model 的内容块回放? - 看到一个新 provider factory 时,怎样快速判断它复用哪种请求转换和流归一化?