Helicone AI Gateway 新模型提供商接入完整指南:从 Provider 定义、模型注册到测试与部署

发布时间:2026/9/17 15:12:00
Helicone AI Gateway 新模型提供商接入完整指南:从 Provider 定义、模型注册到测试与部署 Helicone AI Gateway 新模型提供商接入完整指南从 Provider 定义、模型注册到测试与部署【免费下载链接】helicone Open source LLM observability platform. One line of code to monitor, evaluate, and experiment. YC W23 项目地址: https://gitcode.com/GitHub_Trending/he/heliconeHelicone 的 AI Gateway 是一套统一的 LLM 网关本文以DeepInfra Mistral-Nemo为例系统讲解如何在当前仓库中为一个全新的模型提供商完成端到端接入。你将掌握packages/cost/models下的 Provider、Author、Model、Endpoint 四层数据模型的组织方式理解 BaseProvider 的认证与请求构造机制、基于阈值的分档定价、多区域部署配置以及如何通过注册表、快照测试和createErrorResponse错误映射保证接入质量最终交付一份可直接合入仓库的完整改动。核心概念Authors、Models、Providers、Endpoints 四层模型在动手之前先建立整体认知。Helicone 将模型生态抽象为四个相互独立的维度整个接入流程本质上就是为这四个维度逐一补充定义概念含义示例Authors作者模型创作者/公司OpenAI、Anthropic、Mistral AI、GoogleModels模型带定价与元数据的单个模型定义mistral-nemo、gpt-4oProviders推理提供商托管模型并提供推理服务的厂商OpenAI、Vertex AI、DeepInfra、BedrockEndpoints端点模型 × 提供商的组合及部署配置mistral-nemo:deepinfra这四层分别落在不同的目录与文件中其实际实现可以在 packages/cost/models/types.ts 中看到对应的 TypeScript 接口AuthorMetadata、ModelConfig、ModelProviderConfig、EndpointConfig、UserEndpointConfig。理解这组类型定义是后续所有步骤的基石。前置条件OpenAI 兼容 API推荐选择能让集成成本降到最低——BaseProvider默认的认证与请求构造逻辑即可覆盖大部分场景提供商侧的定价与推理文档用于填写准确的按 token 单价模型规格说明上下文长度contextLength、最大输出 token 数、支持的采样参数与多模态能力API 认证细节API Key、OAuth 或服务账号等认证方式的凭证结构。Step 1理解packages/cost/models文件结构所有模型支持配置都集中在packages/cost/models目录其顶层结构如下packages/cost/models/ ├── authors/ # 模型创作者每家厂商一个子目录 ├── providers/ # 推理提供商每家厂商一个文件 ├── build-indexes.ts # 构建索引提供 O(1) 端点访问 ├── calculate-cost.ts # 成本计算工具 ├── provider-helpers.ts # 辅助方法 ├── registry.ts # 主注册表聚合全部模型与端点配置 ├── registry-types.ts # 类型定义新增模型时需要更新 └── types.ts # 全部核心类型接口其中 build-indexes.ts 与 provider-helpers.ts 是索引与辅助层calculate-cost.ts 负责把pricing配置换算成真实费用registry.ts 是聚合所有作者模型与端点配置的主注册表并在文件头注释中明确其设计目标Main registry with O(1) endpoint access即通过buildIndexes构建索引实现常数时间端点查询。Step 2创建 Provider 定义以DeepInfra为例。若目标提供商已在providers目录中注册例如要接入的是已支持提供商上的新模型可以跳过本步骤。针对 OpenAI 兼容提供商在packages/cost/models/providers/[provider-name].ts新建文件import { BaseProvider } from ./base; export class DeepInfraProvider extends BaseProvider { readonly displayName DeepInfra; readonly baseUrl https://api.deepinfra.com/; readonly auth api-key as const; readonly pricingPages [https://deepinfra.com/pricing/]; readonly modelPages [https://deepinfra.com/models/]; buildUrl(): string { return ${this.baseUrl}v1/openai/chat/completions; } }请务必核对提供商官方文档中的真实端点凡与 OpenAI API 默认行为不一致之处都需要覆盖重写。仓库中已落地的实现见 deepinfra.ts与上述示例完全一致。认证逻辑之所以无需手动处理是因为auth api-key时 base.ts 的authenticate()方法会自动套用标准的Authorization: Bearer ${apiKey}模式——这是 OpenAI 兼容 API 最常见的认证形态。从源码可以看到auth字段的类型是api-key | oauth | aws-signature | service_account也就是说除了 API Key网关还内建了 OAuth、AWS 签名和服务账号Vertex AI 用的就是服务账号方式四类认证体系。针对非 OpenAI 兼容提供商非兼容提供商需要覆盖更多钩子方法。BaseProvider的完整可覆盖方法base.ts包括buildUrl(endpoint, requestParams)抽象方法必须实现决定请求发往哪个 URLauthenticate(authContext, endpoint, cacheProvider?)返回请求头默认Bearer ${apiKey}buildRequestBody(endpoint, context)默认把请求体 JSON 序列化并把model替换为providerModelId若bodyMapping RESPONSES还会先调用context.toChatCompletions()做协议转换buildErrorMessage(response)从上游错误响应中提取用户可读的报错信息buildModelId(...)构造最终发送给上游的模型 ID。文档中的示意写法如下实际接入时以BaseProvider中真实的方法签名为准例如自定义请求体对应buildRequestBody而非buildBodyexport class CustomProvider extends BaseProvider { // ... basic configuration buildBody(request: any): any { // Custom body transformation logic return transformedRequest; } buildHeaders(authContext: AuthContext): Recordstring, string { // Custom header logic return customHeaders; } }例如 Anthropic 的 Responses API、Bedrock 的 AWS 签名、Vertex 的服务账号认证都是通过覆盖这些方法实现的——仓库中 anthropic.ts、bedrock.ts、vertex.ts 提供了三种迥异认证体系的现成范本是研究复杂覆盖逻辑的最佳参考。Step 3将 Provider 注册到 Index编辑packages/cost/models/providers/index.ts导入新类并加入providers单例映射import { DeepInfraProvider } from ./deepinfra; export const providers { // ... deepinfra: new DeepInfraProvider(), // ... } as const;从当前 index.ts 可以看到全部 21 家提供商都以无状态单例形式注册代码注释明确说明 Create singleton instances (stateless, so safe to share)。两个细节值得注意导出的ModelProviderName类型由keyof typeof providers推导而来——这正是 endpoints.ts 中mistral-nemo:deepinfra这类键名左侧部分能获得类型约束的原因该文件还维护了两个能力白名单数组ContextEditingEnabledProviders目前仅 Anthropic和ResponsesAPIEnabledProvidersOpenAI Responses API 兼容白名单其中deepinfra 已被列入 Responses API 白名单。如果你的提供商也支持 Responses 协议需要同步考虑是否加入。Step 4将 Provider 补充到 Web 端数据编辑web/data/providers.ts把新提供商加入前端展示列表让用户在配置密钥页面能看到并选择它// web/data/providers.ts { id: deepinfra, name: DeepInfra, logoUrl: /assets/home/providers/deepinfra.webp, description: Configure your DeepInfra API keys for fast and affordable inference, docsUrl: https://docs.helicone.ai/getting-started/integration-methods, apiKeyLabel: DeepInfra API Key, apiKeyPlaceholder: ..., relevanceScore: 40, },对照现有实现web/data/providers.tsProvider类型包含id、name、logoUrl、description、docsUrl、apiKeyLabel、apiKeyPlaceholder、relevanceScore等字段其中relevanceScore用于前端相关性排序OpenAI 为 100、Anthropic 为 95auth字段可选Vertex 使用auth: service_account标明特殊认证方式。文件头部注释说明该列表在生产环境会由 API 动态拉取这里维护的是静态兜底数据。Step 5定义 Author模型创作者在packages/cost/models/authors/[author-name]/下创建作者定义目录结构如下authors/mistral/ # 作者名 ├── mistral-nemo/ # 模型家族 │ ├── endpoints.ts # 模型 × 提供商 组合 │ └── models.ts # 模型定义 ├── index.ts # 聚合导出 └── metadata.ts # 作者元数据注意文档示例中作者目录写作mistralai而当前仓库实际使用的作者标识是mistral见 authors/mistral/接入时以仓库内AuthorName联盟类型types.ts中已注册的值为准。models.ts定义模型在models对象中写入该模型家族的全部版本。以下示例展示mistral-nemo家族定义每个字段都需要基于官方文档调研填写尤其要注意tokenizer必须是 types.ts 中Tokenizer联盟类型已包含的值如 Claude、GPT、Llama3、Gemini、Mistral、Tekken 等如果缺失需要先扩充该类型import type { ModelConfig } from ../../../types; export const models { mistral-nemo: { name: Mistral: Mistral-Nemo, author: mistral, description: The Mistral-Nemo-Instruct-2407 Large Language Model (LLM) is an instruct fine-tuned version of the Mistral-Nemo-Base-2407. Trained jointly by Mistral AI and NVIDIA, it significantly outperforms existing models smaller or similar in size., contextLength: 128_000, maxOutputTokens: 16_400, created: 2024-07-18T00:00:00.000Z, modality: { inputs: [text, image], outputs: [text] }, tokenizer: Mistral, }, } satisfies Recordstring, ModelConfig; export type MistralNemoModelName keyof typeof models;仓库中的实际落地版本见 authors/mistral/mistral-nemo/models.ts其 tokenizer 使用了Mistral说明该值已存在于Tokenizer联盟类型中。modality字段的合法取值在 types.ts 中定义输入输出分别可为text | image | audio | video。文件末尾导出的MistralNemoModelName类型由keyof typeof models推导是下一步 endpoints 键名类型约束的来源。endpoints.ts定义模型 × 提供商 端点组合更新packages/cost/models/authors/[author]/[model-family]/endpoints.ts为模型挂接具体推理提供商。由于同一模型在不同提供商的推理成本不同必须逐个提供商核对官方定价页。同时注意键名如mistral-nemo:deepinfra要保证可读友好——它最终会以 模型:提供商 的形式暴露给用户调用import { ModelProviderName } from ../../../providers; import type { ModelProviderConfig } from ../../../types; import { MistralNemoModelName } from ./models; export const endpoints { mistral-nemo:deepinfra: { providerModelId: mistralai/Mistral-Nemo-Instruct-2407, provider: deepinfra, author: mistral, pricing: [ { threshold: 0, input: 0.00002, output: 0.00004, }, ], rateLimits: { rpm: 12000, tpm: 60000000, tpd: 6000000000, }, contextLength: 128_000, maxCompletionTokens: 16_384, supportedParameters: [ max_tokens, temperature, top_p, stop, frequency_penalty, presence_penalty, repetition_penalty, top_k, seed, min_p, response_format, ], ptbEnabled: true, endpointConfigs: { *: {}, }, }, } satisfies Partial Record ${MistralNemoModelName}:${ModelProviderName} | MistralNemoModelName, ModelProviderConfig ;仓库真实实现见 authors/mistral/mistral-nemo/endpoints.ts其中还包含了quantization: fp8字段对应 types.ts 中fp4 | fp8 | fp16 | bf16 | int4取值以及ptbEnabled: true启用 pass-through billing。satisfies约束保证每个端点键要么是模型名:提供商名组合要么是纯模型名用于无提供商限定的默认配置。两个关键配置点多部署区域配置。部分提供商存在多个部署区域Bedrock 与 Azure 的实现是现成参考。示例endpointConfigs: { global: { pricing: [/* global pricing */], passThroughBillingEnabled: true, }, us-east: { pricing: [/* regional pricing */], passThroughBillingEnabled: true, }, }endpointConfigs的每个键就是一个部署区域名types.ts 中EndpointConfig支持按区域覆盖pricing、contextLength、maxCompletionTokens、ptbEnabled、rateLimits等字段用户在客户端通过UserEndpointConfig.region指定部署区域。分档定价threshold-based pricing。pricing数组按上下文长度阈值分档计价pricing: [ { threshold: 0, // 上下文长度阈值 input: 0.0000005, // 每百万 token 的输入单价 output: 0.0000015, // 每百万 token 的输出单价 cacheMultipliers: { cachedInput: 0.1, // 缓存读取成本输入单价的 10% write5m: 1.25, // 5 分钟写入成本输入单价的 125% write1h: 2, // 1 小时写入成本 }, }, { threshold: 200000, // 超过 20 万上下文后的新档位 input: 0.000001, output: 0.000003, }, ],需要指出的是当前仓库 types.ts 中ModelPricing的字段名已演进为input/output/cacheMultipliers含cachedInput、write5m、write1h并额外支持cacheStoragePerHour缓存存储费用、thinking推理 token 定价、request按请求计费以及image/audio/video/file的分模态定价ModalityPricing。上述inputCostPerToken/cacheReadMultiplier之类的旧字段名仅见于文档示例接入时务必以 types.ts 的现行接口为准否则无法通过类型检查。Step 6将模型家族注册到 Author 注册表如需要若该模型家族此前未被创建需要在作者的注册表中登记若作者已存在且只是新增模型家族则同样需要把新家族合并进聚合导出。index.ts聚合模型与端点更新packages/cost/models/authors/[author]/index.ts/** * Mistral model registry aggregation * Combines all models and endpoints from subdirectories */ import type { ModelConfig, ModelProviderConfig } from ../../types; // Import models import { models as mistralNemoModels } from ./mistral-nemo/models; import { models as mistralSmallModels } from ./mistral-small/models; // Import endpoints import { endpoints as mistralNemoEndpoints } from ./mistral-nemo/endpoints; import { endpoints as mistralSmallEndpoints } from ./mistral-small/endpoints; // Aggregate models export const mistralModels { ...mistralNemoModels, ...mistralSmallModels, } satisfies Recordstring, ModelConfig; // Aggregate endpoints export const mistralEndpointConfig { ...mistralNemoEndpoints, ...mistralSmallEndpoints, } satisfies Recordstring, ModelProviderConfig;仓库中的真实聚合见 authors/mistral/index.ts它通过展开运算符把mistral-nemo、mistral-small、mistral-large三个家族的模型与端点合并导出供上层注册表统一消费。metadata.ts作者元数据更新packages/cost/models/authors/[author]/metadata.ts自动统计模型数量/** * Mistral metadata */ import type { AuthorMetadata } from ../../types; import { mistralModels } from ./index; export const mistralMetadata { modelCount: Object.keys(mistralModels).length, supported: true, } satisfies AuthorMetadata;实现见 authors/mistral/metadata.tsmodelCount由聚合对象键数动态推导新增模型家族后无需手工维护计数。Step 7更新模型注册表与类型更新类型注册表packages/cost/models/registry-types.ts。该文件专门拆分出来以避免循环依赖它通过satisfies和keyof从各作者的聚合对象推导全局类型import { mistralEndpointConfig, mistralModels } from ./authors/mistral; const allModels { // ... ...mistralModels, }; const modelProviderConfigs { // ... ...mistralEndpointConfig, };从当前 registry-types.ts 可以看到它推导出三个重要导出类型ModelName全部模型名的联合、ModelProviderConfigId全部端点配置 ID 的联合、DeploymentName所有部署区域名的联合并最终组合出EndpointId \${ModelName}:${ModelProviderName}:${DeploymentName} 这一完整端点标识类型——这正是网关路由层赖以定位端点的类型基础。更新主注册表packages/cost/models/registry.tsimport { mistralModels, mistralEndpointConfig } from ./authors/mistral; const allModels { // ... ...mistralModels, } satisfies Recordstring, ModelConfig; const modelProviderConfigs { // ... ...mistralEndpointConfig, } satisfies Recordstring, ModelProviderConfig;当前 registry.ts 实际聚合了 anthropic、openai、google、xai、meta、moonshotai、alibaba、deepseek、mistral、zai、baidu、perplexity 共 12 家作者的全部模型与端点并通过buildIndexes构建 O(1) 索引供 AI Gateway 在请求路径上直接查用。Step 8编写测试在worker/test/ai-gateway/目录下为该作者创建测试文件注意文档中写的是worker/tests/而当前仓库实际测试目录为worker/test/可参考 worker/test/ai-gateway/bail-429.spec.ts 等现有用例务必覆盖各类边界情况与错误场景。错误映射是测试中的重要一环网关不会把上游提供商的原始错误直接透传给用户而是经过归一化处理。错误归一化逻辑位于 SimpleAIGateway.ts 的createErrorResponse()方法其状态码优先级规则如下存在任意 403钱包封禁等→ 返回 403 并透传上游消息存在任意 401认证失败→ 返回 401存在任意非 429 的 BYOK 提供商错误 → 归一化为 500保留 401/403 等可操作鉴权错误首个错误为 400invalid_format→ 返回 400全部错误均为disallowed400→ 返回 400全部错误均为 429余额不足→ 返回 429其余情况 → 返回 500。编写测试时应针对createErrorResponse的这套优先级设计构造用例确认新增提供商在鉴权失败、限流、格式错误等场景下能被正确映射。同时packages/__tests__/cost/registrySnapshots.test.ts这类注册表测试会动态发现authors目录下所有endpoints.tsglob 模式**/endpoints.ts你的新端点文件只要路径规范就会被自动纳入测试范围。Step 9更新快照部署前必须重跑快照测试在仓库根目录执行cd packages npx jest --updateSnapshot __tests__/cost/registrySnapshots.test.ts快照测试packages/tests/cost/registrySnapshots.test.ts会自动导入authors下全部端点文件对定价等配置生成快照并断言其与snapshots/registrySnapshots.test.ts.snap 一致防止模型定价、上下文长度等关键数据被意外改动。常见问题与解决方案问题复杂认证当 API Key 无法满足需求例如需要多个密钥组合、自定义请求头签名时覆盖认证方法authenticate(authContext: AuthContext): AuthResult { return { headers: { Authorization: Bearer ${authContext.apiKey}, X-Custom-Header: this.buildCustomHeader(authContext), }, }; }文档中的示意方法名为auth()当前仓库中对应实现入口为BaseProvider.authenticate()见 base.ts。问题非标准请求格式当提供商请求体与 OpenAI Chat Completions 差异较大时覆盖请求体构造方法把 OpenAI 格式转换为提供商格式buildRequestBody(endpoint: Endpoint, context: RequestBodyContext): string { const request context.parsedBody; return JSON.stringify({ // Transform OpenAI format to provider format prompt: request.messages.map((m: any) m.content).join(\n), max_tokens: request.max_tokens, }); }当前仓库中的方法签名为buildRequestBody(endpoint, context)返回序列化后的字符串见 base.ts。问题多档定价当提供商按上下文长度阶梯计价时使用基于阈值的 pricing 数组pricing: [ { threshold: 0, input: 0.0000005 }, { threshold: 100000, input: 0.000001 }, { threshold: 500000, input: 0.000002 }, ],threshold表示上下文长度档位下限网关会按请求实际上下文长度命中对应档位的单价参与成本计算。部署检查清单合入前逐项核对Provider 类已创建且认证方式正确模型定义字段准确上下文长度、tokenizer、modality、发布日期端点配置定价正确逐提供商核对官方定价页注册表类型已更新registry-types.ts与registry.ts测试编写并通过含边界与错误场景快照已更新npx jest --updateSnapshot __tests__/cost/registrySnapshots.test.ts文档已同步更新Pass-through billing 已验证若适用确认ptbEnabled回退/降级行为已验证多个端点尝试失败时createErrorResponse的错误归一化符合预期小结整个接入流程可以概括为一条清晰的链路Provider认证与 URL→ Author模型定义→ Endpoints模型 × 提供商 × 定价 × 区域→ 注册表类型 索引→ 测试与快照。得益于BaseProvider对 OpenAI 兼容协议的默认支持绝大多数新提供商只需要写一个十几行的 Provider 类加一个端点配置即可完成接入非兼容提供商则通过覆盖authenticate、buildRequestBody、buildUrl等钩子方法对齐协议差异。本文涉及的每一处配置字段都能在 types.ts 中找到精确的类型定义测试与快照机制则为后续演进提供了持续的安全网——这正是 Helicone AI Gateway 能以一行代码接入任意 LLM 提供商背后的工程基础。【免费下载链接】helicone Open source LLM observability platform. One line of code to monitor, evaluate, and experiment. YC W23 项目地址: https://gitcode.com/GitHub_Trending/he/helicone创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询