Skip to content

ProviderSpec 契约

GodeX 中的每个 LLM 提供商由一个 ProviderSpec 对象描述,该对象声明了提供商的身份、协议、能力、端点、认证方案、工具名称编解码器和响应/流访问器。该规约是有意设计为声明式的 -- 它不包含任何 HTTP 逻辑。一个单独的 ProviderEdge 将规约与传输层(请求/流)组合成一个可运行的提供商。这种分离意味着同一个规约可以为验证、文档生成和运行时请求处理提供支持,而无需与 fetch 内部实现耦合。

这种规约驱动的设计是添加新提供商主要只需填写一个类型化对象并编写可选钩子的原因。桥接运行时读取规约来了解支持哪些参数、需要降级哪些工具,以及如何从响应中提取输出文本。

概览

概念类型 / 常量用途
ProviderSpec<TReq, TRes, TChunk>接口一个提供商的声明式契约
ProviderEdge<TReq, TRes, TChunk>接口规约 + request() + stream()
ProviderRuntimeConfig接口运行时凭证和端点
ProviderDefinition接口命名工厂(create(config) -> ProviderEdge
BEARER_AUTH_SCHEME常量"bearer"
CHAT_COMPLETIONS_PROTOCOL常量"chat_completions"
createProviderEdge工厂函数将规约 + 配置 + 传输层连接成 edge
createProviderDefinition工厂函数将 edge 工厂包装为定义

规约结构

ProviderSpec 接口包含四类字段:身份、协议/能力、访问器和钩子。

身份和协议

字段类型描述
namestring唯一的提供商标识符(如 "deepseek""zhipu""minimax"
protocolProviderProtocol目前始终为 CHAT_COMPLETIONS_PROTOCOL"chat_completions"
capabilitiesProviderCapabilities声明支持的参数、工具、工具选择模式、响应格式和推理努力风格
endpointProviderEndpointSpec包含 defaultBaseURL
authProviderAuthSpec目前始终为 BEARER_AUTH{ scheme: "bearer" }

响应访问器

ChatCompletionResponseAccessor<TResponse> 告诉桥接如何从上游响应中提取标准化数据(contract.ts:32-37):

方法返回值
firstChoice(response)第一个选择对象或 undefined
finishReason(response)停止原因字符串(如 "stop""tool_calls"
outputText(response)拼接的文本内容
usage(response)包含 input_tokensoutput_tokenstotal_tokensResponseUsage

流访问器

ChatCompletionStreamAccessor<TChunk> 有一个单一方法 deltas(chunk),返回 ProviderSpecStreamDelta 数组 -- 桥接内部的流式 delta 表示(contract.ts:39-41)。

ProviderEdge 和工厂

ProviderEdge 通过两个可执行方法扩展了 ProviderSpec

  • request(body) -- 发送非流式请求并返回类型化响应。
  • stream(body) -- 发送流式请求并返回 ReadableStream<JsonServerSentEvent<TChunk>>

createProviderEdge 工厂(factory.ts:34-88)将所有内容连接在一起:

  1. config.endpoint.base_url 解析 base_url,如果不存在则回退到 spec.endpoint.defaultBaseURL
  2. 应用 hooks.patchRequest 将桥接请求转换为提供商请求。
  3. 委托给提供的 requeststream 实现。
  4. 应用 hooks.normalizeResponse(非流式)或通过 TransformStream 传输 normalizeChunk(流式)。

ProviderRuntimeConfig

ProviderRuntimeConfigcontract.ts:10-15)是每个提供商从 GodeX 配置层接收的形状:

字段类型描述
specstring要查找的提供商规约名称
credentials.api_keystring上游的 Bearer 令牌
endpoint.base_urlstring?覆盖默认的 base URL
timeout_msnumber?请求超时时间(毫秒)

ProviderDefinition 和注册

ProviderDefinitiondefinition.ts:6-11)将提供商名称与工厂函数 (config) => ProviderEdge 配对。createProviderDefinition 辅助函数(definition.ts:13-29)将类型化工厂转换为 Registrar 使用的擦除签名。

内置定义在 builtin.ts:22-41 中声明,并通过 createBuiltinRegistrar()builtin.ts:49-55)自动注册。

包验证

validateProviderPackageShape 函数(validation.ts:13-51)强制要求每个提供商目录包含所需文件(spec.tsclient.tsindex.ts),并且不包含允许列表之外的文件(hooks.ts、测试、protocol/ DTO)。这使提供商包保持一致性。

示例提供商

src/providers/example/spec.ts 处的示例提供商演示了最小的规约表面。它定义了内联 DTO(ExampleChatRequestExampleChatResponseExampleChatChunk)和一个带有直通 toolName 编解码器和简单 response 访问器的 EXAMPLE_PROVIDER_SPECspec.ts:80-126)。相应的客户端(client.ts:11-26)使用规约和可选的传输覆盖调用 createProviderEdge

交叉引用

  • Provider Hooks -- 如何为每个内置提供商实现 patchRequestnormalizeResponsenormalizeChunk
  • Chat Provider Client -- 实现传递给 createProviderEdgerequeststream 函数的 HTTP 传输层

参考资料