
Helicone 中的 OpenAI Types Extractor从 2 万行 OpenAPI 规范中按需提取 Zod 类型与依赖【免费下载链接】helicone Open source LLM observability platform. One line of code to monitor, evaluate, and experiment. YC W23 项目地址: https://gitcode.com/GitHub_Trending/he/helicone导读OpenAI 官方 API 规范openapi.documented.yml经openapi-zod-client转换后会生成一个超过 2.2 万行的 TypeScript 文件其中绝大多数类型与你的业务无关。Helicone 仓库的 scripts/openai-types 提供了一套按需提取工具链先用openapi-zod-client生成完整 Zod schema再借助ts-morph做 AST 级依赖分析仅把CreateChatCompletionRequest、CreateResponse及其闭包依赖抽取成数百行的小文件。读完本文你将掌握这套提取流程的完整命令、脚本内部的工作原理以及它在 Helicone AI 网关请求校验中的真实落地方式并可直接复用到任何 OpenAPI 驱动的 TypeScript 项目。一、问题背景为什么需要从巨型 API 规范中瘦身OpenAI 的官方 OpenAPI 规范覆盖 Chat Completions、Responses、Assistants、Batch、Files 等全部端点转换后的 Zod 文件往往超过 2.2 万行。直接引入整个文件会带来两个现实问题编译与类型检查变慢每次tsc都要解析海量与本项目无关的类型声明包体膨胀全部 schema 都被打入产物增加了运行时体积维护成本高上游规范变更时难以快速定位哪些类型真正被使用。Helicone 的做法是只保留 AI 网关真正需要校验的两个请求体类型将文件从 2.2 万行级压缩到数百行级当前仓库中的 chat-completion-types.ts 约 400 余行、responses-types.ts 约 700 余行实现更小、更快、更易维护。二、快速上手三条命令完成提取原文档给出了完整的操作序列对应目录 scripts/openai-types# 1. 安装依赖 npm install # 2. 从 OpenAI 官方规范生成完整 Zod schema npx openapi-zod-client https://app.stainless.com/api/spec/documented/openai/openapi.documented.yml -o openai.chat.zod.ts --export-schemas --export-types # 3. 提取目标类型及其依赖 node extract-openai-types.js各步骤说明步骤命令产物说明依赖安装npm installnode_modules/依据 package.json 安装ts-morph^27、typescript^5.9.2、zod^4.1.11生成完整 schemanpx openapi-zod-client ...openai.chat.zod.ts拉取远程官方规范--export-schemas/--export-types确保 schema 与类型均可被导入提取目标类型node extract-openai-types.jschat-completion-types.ts、responses-types.ts自动解析依赖并写出精简文件执行完毕后会生成两个文件chat-completion-types.ts—— 导出CreateChatCompletionRequestschema 及其全部依赖responses-types.ts—— 导出CreateResponseschema 及其全部依赖。脚本运行时会打印每个根类型解析出的依赖数量例如Found N dependencies for CreateChatCompletionRequest: [...]并在成功写入后输出 ✅ 提示出错则打印 ❌ 并抛出异常见 extract-openai-types.js。三、提取后的类型如何使用原文档给出了直接消费方式提取出的文件与zod组合既能做运行时校验也能反推静态类型。import { CreateChatCompletionRequest } from ./chat-completion-types; import { CreateResponse } from ./responses-types; import { z } from zod; // 校验 chat completion 请求数据 const chatRequest CreateChatCompletionRequest.parse({ model: gpt-4o, messages: [{ role: user, content: Hello! }] }); // 校验 responses 请求数据 const responseRequest CreateResponse.parse({ model: gpt-4o, input: Hello, world! }); // 推导 TypeScript 类型 type ChatRequest z.infertypeof CreateChatCompletionRequest; type ResponseRequest z.infertypeof CreateResponse;使用要点parse抛出异常数据不合法时直接 throw适合失败即中断的场景safeParse返回 Result需要将校验失败转成 HTTP 400 响应时应改用safeParse捕获错误明细这正是 Helicone 网关内部的用法见下文z.infer推导类型避免手写与 schema 可能失步的 interface一处定义、双重受益生成的文件顶部只有一行import { z } from zod;外部依赖极简可直接复制进任意支持 zod 的工程。四、脚本原理ts-morph AST 依赖提取全解析核心脚本 extract-openai-types.js 只有约 200 行却完成了一次典型的按名提取 闭包追踪 拓扑排序流程。整体分四步4.1 建立符号索引用ts-morph加载生成文件后脚本把两类顶层声明分别登记为查找表L20-L33variableDeclarationszodSchemasMapconst XxxSchema z.object({...})这类 Zod schema 变量typeAliasestypeDefinitionsMaptype Xxx ...这类纯类型别名。4.2 识别节点中的标识符findIdentifiersInNode遍历 AST 后代节点收集所有SyntaxKind.Identifier并用正则/^[A-Z][a-zA-Z0-9_]*$/过滤L36-L50。由于生成的规范中所有类型/schema 名都遵循首字母大写的 PascalCase 约定该规则能自然排除字段名、局部变量等小写标识符精准锁定可能是类型引用的名字。4.3 递归闭包求依赖findDependencies以根类型为起点递归解析其 initializerZod schema或 type node类型别名中引用的其他标识符只对已登记在zodSchemas或typeDefinitions中的名字继续下钻并用visited集合防止环L53-L85。最终dependencies集合就是该根类型的完整闭包。4.4 拓扑排序输出为避免使用未定义变量addDependency先递归加入自身依赖、再输出自身L96-L128且先输出纯类型别名、后输出 Zod schemaL134-L135保证 schema 中引用的类型别名已在前方定义。输出内容按以下顺序组装L138-L166import { z } from zod;全部依赖中的类型别名原样复制声明文本全部依赖中的 Zod schema复制 initializer 文本去掉可能自引用的类型注解末尾export { rootTypeName };只导出根类型。关于第 3 点值得说明源码中判断typeAnnotation存在与否的两个分支生成的代码完全一致const ${name} ${initializer};其意图是丢弃 Zod 自引用的类型注解如z.ZodTypeTypeName让类型完全由 Zod 运行时推导这正是提取后能直接配合z.infer使用的关键。五、落地实证Helicone AI 网关如何消费这些类型提取脚本不是孤立的玩具工具它在 Helicone 的 AI 网关请求校验链路中是真实的生产依赖。5.1 生成文件的位置Helicone 把提取出的两个文件提交在 worker/src/lib/ai-gateway/validators/chat-completion-types.ts 与 worker/src/lib/ai-gateway/validators/responses-types.ts 中。打开前者可以看到典型的提取结果ChatCompletionRequestSystemMessage、ChatCompletionRequestMessageContentPartImage含image_url的detail: z.enum([auto,low,high]).optional().default(auto)等依赖 schema 依次排列CreateChatCompletionRequest本体使用.strict()拒绝未知字段并对n做了z.number().int().gte(1).lte(128)等边界约束chat-completion-types.ts。5.2 校验器封装openaiRequestValidator.ts 在其上做了一层薄封装用.and()与z.object({ model: z.string().min(1) })合并强制model字段存在且非空validateOpenAIChatPayload/validateOpenAIResponsePayload对任意unknown请求体执行schema.safeParse失败时把首个 issue 的路径与消息拼接成path: message. See API reference: ...格式的错误信息并通过Result类型返回err/ok校验失败信息中附带了对应 API 文档链接方便调用方定位问题字段。5.3 网关调用链在 SimpleAIGateway.ts 中当attempt.authType ptb且 body 映射为OPENAI或RESPONSES时会按映射类型调用对应校验器isErr时立即把invalid_formatHTTP 400错误加入结果集并跳过该次尝试。此外Responses 类请求还会先检查 provider 是否在ResponsesAPIEnabledProviders白名单内L245-L255。由此可以清晰看到一条完整链路OpenAI OpenAPI 规范 → openapi-zod-client 生成 2.2 万行 openai.chat.zod.ts → extract-openai-types.js 按依赖闭包提取ts-morph AST → chat-completion-types.ts / responses-types.ts数百行 → openaiRequestValidator.tssafeParse Result 封装 → SimpleAIGateway.tsptb 尝试前的 400 校验这也是以原文档为骨架、以源码为证据的最佳印证提取工具服务的是真实网关的请求格式校验而非演示代码。六、参数与扩展把脚本用于自己的类型extractTypes是脚本的核心可复用函数L9-L169签名如下async function extractTypes(rootTypeName, outputFile, sourceFilePath ./openai.chat.zod.ts)参数含义示例rootTypeName要提取的根类型/schema 名CreateChatCompletionRequestoutputFile输出文件路径./chat-completion-types.tssourceFilePath源生成文件路径有默认值./openai.chat.zod.ts当前仓库内置了两个入口extractChatCompletionTypes()与extractResponseTypes()L174-L183。如果你需要提取第三个类型只需仿照它们再封装一个入口或在main()中追加一次extractTypes(...)调用即可。值得注意的前提与限制命名约定依赖脚本靠首字母大写正则识别类型引用要求生成文件中的类型/schema 名符合 PascalCase若上游生成器改变命名风格findIdentifiersInNode的过滤规则需要同步调整类型别名与 schema 的关系输出时先写类型别名再写 Zod schema若遇到纯类型别名互相引用拓扑排序逻辑已能正确处理类型检查配置tsconfig.json 采用target: ES2020、module: commonjs、strict: true并将两个生成文件纳入includenoEmit: true仅做类型检查可直接用npx tsc --noEmit验证提取结果的类型正确性。七、写在最后OpenAI Types Extractor 演示了一种对任何大型 OpenAPI/OpenAPI 派生代码都通用的工程模式让工具生成全量、让脚本裁剪到最小可用集、让产物进入版本库供业务直接消费。在 Helicone 中它把 2.2 万行的巨型 schema 文件裁剪成两张合计千余行、无多余依赖的类型表并接入 AI 网关的 ptb 请求校验链路用最小的编译与维护成本换来了严格的请求格式保障。如果你也在维护一个消费 OpenAI或其他大型 API规范的 TypeScript 网关或 SDK这套流程值得直接借鉴。【免费下载链接】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),仅供参考