models.dev 官方 TypeScript 客户端 @opencode-ai/models 完全指南:API 调用、快照数据与 Effect 集成
人工智能大模型后端前端【免费下载链接】models.devAn open-source database of AI models.项目地址https://gitcode.com/gh_mirrors/mo/models.dev点击查看免费下载本篇文章以开源仓库 models.dev 中 packages/sdk/README.md 为核心系统讲解其官方类型安全客户端opencode-ai/models的安装方式、三大数据接口providers/models/catalog、请求配置与统一错误模型并结合 packages/sdk 源码与测试逐层剖析其内部实现。读完本文你将能够在 Node/Bun 项目中直接读取全量 AI 模型数据库在无网络环境下使用内置快照降级并能将客户端无缝接入 Effect 生态实现依赖注入与可组合的请求管道。一、背景models.dev 与官方客户端models.dev 是一个开源的 AI 模型数据库项目描述为An open-source database of AI models以标准化方式收录了各家的模型能力、价格USD/百万 token、上下文窗口与限制信息。仓库中models.json与各 provider 目录下的.toml文件共同构成了数据源最终通过api.json、models.json、catalog.json三个 JSON 端点对外发布。opencode-ai/models是官方发布的类型化客户端由 packages/sdk 包实现。它把三个 HTTP 端点封装为三个 Promise 风格的方法并在包内附带了整库快照snapshot与 Effect 原生变体满足从“最简单的fetch封装”到“函数式依赖注入”的多种使用场景。二、安装与最低运行环境在项目根目录执行npm install opencode-ai/models根据 packages/sdk/package.json 的声明需要注意以下几点Node.js 版本engines.node要求18现代fetch、AbortSignal均可用ESM 包type: module客户端以 ESM 方式导出副作用标记sideEffects: false配合打包器可实现摇树优化tree-shaking只保留实际用到的入口入口映射exports字段声明了三个独立入口——根入口.标准客户端、./effectEffect 原生客户端与./snapshot内置数据快照可选 peer 依赖effect版本4.0.0-beta.83为可选依赖只有使用 Effect 入口时才需要安装。仓库使用 Bun 作为开发/测试工具链见 package.json 与 packages/sdk/package.json 中的scripts但对使用者而言任意支持 ESM 的 Node 18 环境即可运行。三、快速开始三行代码读取全量数据库客户端是一个无状态的工厂函数通过Models.make()创建每个方法恰好发起一次GET请求import { Models } from opencode-ai/models const client Models.make() const providers await client.providers() // GET /api.json providers[anthropic]?.models[claude-opus-4-6]?.cost?.input // USD per 1M tokens const models await client.models() // GET /models.json models[anthropic/claude-opus-4-6]?.knowledge // provider-agnostic metadata const catalog await client.catalog() // GET /catalog.json — both in one request三个方法对应三个端点其返回类型定义在 packages/sdk/src/types.ts 中方法端点返回类型内容providers()/api.jsonProviderMap所有提供商及其模型、价格、限制按 provider ID 为键models()/models.jsonModelMetadataMap与提供商无关的模型元数据按lab/model规范 ID 为键catalog()/catalog.jsonCatalog一次请求同时拿到{ providers, models }关键的返回结构摘自 packages/sdk/src/types.tsProviderMap Recordstring, ProviderProvider包含id、env认证所需环境变量如ANTHROPIC_API_KEY、npm对应 AI SDK 包名、api、doc与modelsModel包含id、name、reasoning、tool_call、modalities输入/输出模态text、audio、image、video、pdf、limitcontext上下文窗口、input、output、cost与statusalpha/beta/deprecated等字段Cost以“USD per 1M tokens”为单位除input/output外还支持reasoning、cache_read、cache_write、input_audio、output_audio并通过tiers支持按上下文大小的阶梯定价ModelMetadata提供knowledge知识截止日期、release_date、open_weights、license、links、weights、benchmarks等厂商无关的元数据。由于全部返回类型均为 TypeScript 原生类型且 packages/sdk/src/types.ts 注释明确其“手写镜像了 models.dev/core 中 zod 模式、刻意不引入 zod 使发布后的.d.ts零依赖”你可以获得开箱即用的补全与类型检查。四、客户端配置baseUrl、fetch、headers 与请求级选项Models.make()接受一组ClientOptions定义见 packages/sdk/src/client.tsconst client Models.make({ baseUrl: https://models.dev, // default fetch: myFetch, // proxies, polyfills, test doubles headers: { x-extra: 1 }, // sent with every request }) await client.providers({ signal: AbortSignal.timeout(5000) })各选项的源码级语义baseUrl默认https://models.dev。客户端内部会自动补齐末尾/baseUrl.endsWith(/) ? baseUrl : baseUrl /因此带不带尾斜杠均可且子路径会被原样保留——测试 packages/sdk/test/client.test.ts 验证了https://example.com/mirror与https://example.com/mirror/都会请求到/mirror/api.json。这让自建镜像或本地 mock 变得非常容易。fetch自定义 fetch 实现代理、polyfill、测试替身。关键设计是在请求时惰性解析options.fetch ?? globalThis.fetch也就是说晚安装的 polyfill 也能生效——测试用例global fetch is resolved lazily so late polyfills work专门验证了这一行为。headers随每个请求发送的公共头。在request内部会先合并客户端级头再合并请求级头请求级同名头覆盖客户端级头测试用例request headers override client headers验证了x-two由客户端值被请求值覆盖、user-agent等客户端独有的头仍然保留。请求级RequestOptions每个方法均可传入signal?: AbortSignal——透传给底层 fetch可配合AbortSignal.timeout(5000)实现超时headers——仅本次请求的附加头modelTypes: all | readonly ModelType[]——按专门化模型类型过滤。实现上all会设置?typeall而数组如[decision]会设置?typedecision多个值以逗号拼接。当前ModelType类型仅有decision见 packages/sdk/src/types.ts测试 packages/sdk/test/client.test.ts 验证了?typedecision与?typeall的编码结果。五、统一的错误模型ModelsDevError客户端的所有失败路径都收敛为单一错误类型ModelsDevError通过reason区分三类失败定义见 packages/sdk/src/error.tsreason触发场景cause内容Transportfetch 本身失败网络、DNS、abort或读取响应体失败底层错误对象UnexpectedStatus非 2xx 响应{ status: number }如{ status: 404 }MalformedResponse响应体为空或不是合法 JSON解析错误若有源码中的判定顺序见 packages/sdk/src/client.ts 的request函数先捕获 fetch 异常抛Transport→ 响应!ok时尝试取消 body 后抛UnexpectedStatus→ 读文本失败抛Transport→ 空串抛MalformedResponse→JSON.parse失败抛MalformedResponse。测试 packages/sdk/test/client.test.ts 对上述每一种分支都有独立用例包括“非 2xx 抛 UnexpectedStatus 且 cause 为{ status: 404 }”“空 body 抛 MalformedResponse”等。实际使用中只需一次捕获即可覆盖全部失败try { const providers await client.providers() } catch (error) { if (error instanceof ModelsDevError) { console.error(error.reason, error.cause) } }六、内置快照无网络运行与优雅降级包内以独立、可摇树优化的入口opencode-ai/models/snapshot附带了整库数据的完整副本import snapshot, { providers, models, generatedAt } from opencode-ai/models/snapshot providers[anthropic]?.models[claude-opus-4-6]?.limit.context快照入口的类型声明见 packages/sdk/src/snapshot.d.tsproviders——与client.providers()返回同构的ProviderMapmodels——与client.models()返回同构的ModelMetadataMapgeneratedAt——快照生成时间的 ISO 时间戳默认导出snapshot: Catalog——即{ providers, models }完整目录。官方 README 明确其适用场景无网络运行环境、测试、冷启动敏感路径或作为显式降级方案。最典型的用法是“先请求线上、失败再回退快照”const providers await client.providers().catch(async () (await import(opencode-ai/models/snapshot)).providers)由于包声明了sideEffects: false且快照是独立入口未使用的路径不会被打包器纳入产物。数据方面官方说明已发布的快照与线上 API 最多滞后约 24 小时数据发布是自动化的因此它适合容忍轻微滞后的场景对实时性敏感的场景仍应以线上接口为准。七、Effect 原生客户端函数式依赖注入对于使用 Effect 的项目包提供 Effect 原生入口opencode-ai/models/effect需要可选 peer 依赖effectimport { Models } from opencode-ai/models/effect import { FetchHttpClient } from effect/unstable/http import { Effect } from effect const program Effect.gen(function* () { const client yield* Models.make() return yield* client.providers() // EffectProviderMap, ModelsDevError }) await program.pipe(Effect.provide(FetchHttpClient.layer), Effect.runPromise)其实现位于 packages/sdk/src/effect/client.ts核心设计有四点传输来自环境客户端不自己发请求而是通过HttpClient.HttpClient服务获取传输能力FetchHttpClient.layer、NodeHttpClient.layer或自定义传输均可因此代理、重试、追踪、测试传输都可以按 Effect 惯用方式自由组合——测试 packages/sdk/test/effect.test.ts 展示了通过注入自定义Fetch层来 stub 响应并断言请求 URL 的写法。错误进入失败通道客户端方法的类型是EffectA, ModelsDevError其中ModelsDevError被实现为Schema.TaggedErrorClass携带cause: Schema.Defect()可用Effect.catchTag等模式化处理。依赖注入提供Models.Service服务键与Models.layer(options?)层供共享客户端注入const program Effect.gen(function* () { const client yield* Models.Service return yield* client.models() }) program.pipe(Effect.provide(Models.layer().pipe(Layer.provide(FetchHttpClient.layer))))与 Promise 版相同的语义同样支持baseUrl、headers、modelTypes过滤all或数组同样无状态、不做缓存——README 源码注释建议需要缓存时自行用Effect.cached/Effect.cachedWithTTL包裹调用。八、源码要点与工程实践小结结合 packages/sdk/src/client.ts 与 packages/sdk/test/client.test.ts可以提炼出该客户端值得借鉴的实现约定无状态、零缓存每个方法恰好一次GET所有响应解析完成后即丢弃中间状态测试stateless: every call fetches again明确验证了两次调用会发起两次请求。需要缓存的调用方应自行包一层缓存策略请求只读组合客户端级 headers 与请求级 headers 通过Headers实例合并同名后者覆盖前者不修改调用方传入的对象类型零依赖手写类型镜像 core 包的 zod schema并通过测试断言与z.infer双向互认保证发布产物不携带运行时依赖多入口可摇树根入口 /./effect/./snapshot三个独立入口 sideEffects: false用户可按需引入最小体积完整测试覆盖端点路径、baseUrl 子路径、类型过滤编码、头合并、abort 透传、三类错误分支、惰性 fetch 解析均有对应测试用例可作为自定义客户端实现的行为规范参考。九、总结opencode-ai/models用一个工厂函数统一了 models.dev 的三个数据端点providers()拿到按提供商组织的价格与限额models()拿到厂商无关的模型元数据catalog()一次请求取全量baseUrl/fetch/headers/signal/modelTypes覆盖了从镜像部署、代理注入到按类型过滤的绝大多数定制需求ModelsDevError的三段式错误模型让异常处理变得可预测而 snapshot 入口与 Effect 入口则分别解决了离线降级与函数式依赖注入两类高级场景。无论是构建模型比价工具、LLM 应用路由层还是自动化测试夹具这份官方客户端都是读取 models.dev 数据最直接、类型最完整的入口。更多细节可继续阅读 packages/sdk/src/types.ts 中的完整类型定义与 packages/sdk/test 中的行为测试。赞分享人工智能大模型后端前端【免费下载链接】models.devAn open-source database of AI models.项目地址https://gitcode.com/gh_mirrors/mo/models.dev点击查看免费下载相关推荐PaddleOCR 官方 API SDK 全景实战Python / TypeScript / Go 客户端与 paddleocr api CLI 使用指南PaddleOCR 官方 API SDK 全景实战Python / TypeScript / Go 客户端与 paddleocr api CLI 使用指南 P人工智能计算机视觉OCR深度学习大模型RAGPrisma TypeScript 客户端代码生成全解析从数据模型快照到类型安全的 CRUD APIPrisma TypeScript 客户端代码生成全解析从数据模型快照到类型安全的 CRUD API 导读 本文以 Prisma 客户端生成器的 AVA 快照后端数据库GraphQLKomodo TypeScript 客户端komodo_client完全指南安装、认证与 API 调用实战Komodo TypeScript 客户端komodo_client完全指南安装、认证与 API 调用实战 本指南以仓库内 client/core/ts/DevOps容器编排CI/CD运维上一篇OnmyojiAutoScript 阴阳师自动化脚本一键托管安装教程下一篇Cursor Team Kit 插件实战指南开箱即用的 CI 循环、代码审查与发布工作流创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考