news 2026/9/16 19:32:44

big-AGI AIX 的 OpenAI 协议同步方法论:从 Wire Types、Adapter 与 Parser 到上游 API 差异排查

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
big-AGI AIX 的 OpenAI 协议同步方法论:从 Wire Types、Adapter 与 Parser 到上游 API 差异排查

big-AGI AIX 的 OpenAI 协议同步方法论:从 Wire Types、Adapter 与 Parser 到上游 API 差异排查

【免费下载链接】big-AGIAI suite powered by state-of-the-art models and providing advanced AI/AGI functions. Includes AI personas, AGI functions, world-class Beam multi-model chats, text-to-image, voice, response streaming, code highlighting and execution, PDF import, presets for developers, much more. Deploy on-prem or in the cloud.项目地址: https://gitcode.com/GitHub_Trending/bi/big-AGI

本文围绕 big-AGI 仓库中的一份内部同步指令.claude/commands/aix/sync-openai-apis.md展开,完整讲解该项目如何把自己的 OpenAI 兼容层(AIX 模块)与上游 OpenAI API 保持同步:哪些文件构成协议实现的骨架(wire types / adapter / parser)、Responses API 与 Chat Completions 的优先级关系、流式解析的关键假设,以及“查文档 → 打真实 SSE 请求 → 逐字段对比”的完整差异排查工作流。读完后你可以掌握在这类多模型网关项目中定位协议实现、复现上游同步检查、并自行判断破坏性变更与新增能力的方法。

一、这份指令解决什么问题

sync-openai-apis.md 是一个面向 AI 编码助手的 Claude Code 命令(.claude/commands/目录下与sync-anthropic-api.mdsync-gemini-api.mdsync-openrouter-api.md等并列),它的用途是:当上游 OpenAI API 发生变化(新字段、新事件类型、新模型、新价格)时,驱动一次系统化的“实现 vs 上游文档”比对,并把所有差异——尤其是破坏性变更和能改善用户体验的新能力——列出来。

指令明确了本次同步的作用范围与优先级,这几点直接决定了 big-AGI 的 OpenAI 兼容层长什么样:

  • 优先 Responses API/v1/responses是主推协议,Chat Completions(/v1/chat/completions)仍然支持但按 legacy 对待;
  • 明确不做:不支持 Realtime(含 WebSocket 等)API,也不支持 Agentic 类 API(Agent SDK、AgentKit、ChatKit、Assistants API 等)——因为 AIX 自己在服务端或客户端实现了等价能力;
  • 检查深度要求:必须深入到请求/响应字段的细节,重点核对“必填字段、流式事件类型、新的响应形态”,而不仅是顶层结构。

下面按指令指定的三个核心文件逐一展开,这些文件就是 OpenAI 协议实现的完整骨架。

二、协议骨架:三个文件各自负责什么

环节文件职责
线格式定义openai.wiretypes.ts用 Zod 定义请求/响应/内容片段/工具等全部线类型(wire types)
请求组装(Adapter)openai.chatCompletions.ts、openai.responsesCreate.ts把 AIX 内部统一的 ChatGenerate 请求翻译成 OpenAI 两种 API 的请求体
响应解析(Parser)openai.parser.ts、openai.responses.parser.ts把流式(SSE)或非流式响应解析回 AIX 内部粒子(particle)流

同目录下还有 openai.responses.create.spec.md 这类上游规范快照和 sync.sh 同步脚本,说明“把上游规范拉下来对照”本身是工程化的常规动作。

2.1 Wire Types:Zod Schema + 上游 Changelog 注释

openai.wiretypes.ts(约 2200 行)文件头部维护了一张上游变更记录表,这是同步工作的直接产物——每次同步都会把命中的上游 Changelog 条目落到注释里:

// Implementation notes (see OpenAI changelog for upstream changes): // - 2024-12-17: "Reasoning Effort" - added reasoning_effort and the 'developer' message role // - 2024-11-05: "Predicted Outputs" // - 2024-09-12: "o1" - max_tokens is deprecated in favor of max_completion_tokens, // added completion_tokens_details // - 2024-08-06: "Structured Outputs" - added JSON Schema and strict schema adherence // - 2024-07-09: skipping Functions as they're deprecated / ignoring logprobs

这份注释同时记录了主动放弃的字段(如logprobs、已废弃的 Functions),让“为什么这里没有 X”可追溯。

核心内容片段(Content Parts)定义在OpenAIWire_ContentParts命名空间内,用z.discriminatedUnion('type', ...)组织输入侧的四种 part(见 openai.wiretypes.ts#L27-L92):

  • text:文本,另带一个 OpenRouter 方言专属的cache_control(Anthropic 风格缓存断点,OR 负责翻译);
  • image_urlurl+detail: 'auto' | 'low' | 'high'控制视觉理解精度;
  • input_audio:Base64 音频 +format: 'wav' | 'mp3'(上游 2024-10-17 加入的音频输入);
  • video_url:OpenRouter 扩展,非标准 OpenAI 字段。

输出侧则定义了ToolCallfunction调用,arguments字符串,源码注释提醒模型未必生成合法 JSON,调用前必须自行校验)以及url_citation引用注解等。

2.2 Chat Completions 请求 Schema:完整参数面

OpenAIWire_API_Chat_Completions.Request_schema(见 openai.wiretypes.ts#L342-L461)覆盖了同步时需要逐项核对的请求面,摘选如下:

参数类型/取值说明
model/messagesstring / Message[]基本输入,messages 为四角色消息数组
tools/tool_choice/parallel_tool_callsToolDefinition[] / ToolChoice / bool工具定义与调用策略,parallel_tool_calls默认 true
max_completion_tokensint(正数)现行标准字段
max_tokensint已废弃,仅为兼容保留
temperature/top_p0–2 / 0–1通用采样参数
modalities/audio['text','audio','image']/ voice+format多模态输出;audio 的 voice 枚举含 ash/ballad/coral/sage/verse/alloy/echo/shimmer/marin,format 支持 wav/mp3/flac/opus/pcm16
stream/stream_optionsbool /{include_usage}流式开关与用量回传
reasoning_effortnone/minimal/low/medium/high/xhigh/max2024-12-17 加入;max为 DeepSeek V4 扩展
response_formattext / json_object / json_schema2024-08-06 Structured Outputs;schema 名须匹配^[a-zA-Z0-9_-]{1,64}$
web_search_optionssearch_context_size + user_location网络搜索上下文与近似定位
prediction{type:'content', content}2024-11-05 Predicted Outputs

Schema 之后还有一长串厂商方言扩展(OpenRouter 的session_id/provider/max_tool_calls、Perplexity 的search_mode、Moonshot/DeepSeek 的thinking等),这正体现了 wire types 文件的定位:一份“OpenAI 兼容超集”,以注释中的[厂商, 日期]标签标记每个扩展的来源。这种注释规范本身就是同步工作的落点——新增一个上游字段时,必须能追溯到厂商与日期。

三、Chat Completions Adapter:请求组装与方言热修

aixToOpenAIChatCompletions 是 Chat Completions 方向的翻译器,文件头部的实现笔记先声明了能力边界(见 openai.chatCompletions.ts#L11-L21):只支持 N=1;top_pparallel_tool_callsstop等未实现;doc part 以 markdown 文本内嵌、image part 以 base64 data URL 内嵌、所有 tool call 统一转为 function call。

组装流程里最有工程含量的是按方言(dialect)打热修,例如(见 openai.chatCompletions.ts#L40-L100):

  • OpenAI/Azure + o 系推理模型(gpt-6/gpt-5/o4/o3/o1 前缀匹配):去掉不支持的temperature/top_p,system 消息改用 2024-12-17 引入的developer角色;
  • max_tokensmax_completion_tokens:对原生 OpenAI 与 Azure 全部改用新字段,与 wire types 里的“DEPRECATED”注释呼应;
  • DeepSeek/Perplexity:强制 user/assistant 角色交替、移除空消息;DeepSeek V4 在有工具且未关思考时要求历史中每条 assistant 消息都带reasoning_content,缺失时注入空串占位;
  • OpenRouter:把客户端生成的session_id发给上游做粘性路由(缓存不能跨 provider),并把尾部的cache_control断点收敛到 4 个以内(Anthropic 上游限制);对拒收强制工具调用的模型,把tool_choice: 'required'降级为auto并插入 system 提示语补救;
  • 函数调用不可用则快速失败:Perplexity 等方言下若携带 tools 直接抛错,而不是让上游报一个难读的错。

随后构造请求体:stream_options: { include_usage: true }(流式时)、response_formatmodel.strictJsonOutput决定、工具与tool_choice按模型的strictToolInvocations转换。最后还有一道_fixPairInteriorToolCalls保证“每个中间 tool call 都有配对的 tool 消息,否则整个请求会被上游拒绝”。这些细节正是同步指令中“look deep in the fields of the requests”要求的具体形态:一个字段的上游语义变化(比如角色改名、字段废弃)会同时波及 wire types、adapter 热修和 parser 三处。

四、Chat Completions Parser:块级流式协议的解析假设

openai.parser.ts 顶部(openai.parser.ts#L16-L36)用注释完整陈述了它对块级流式协议(chunk-based streaming)的理解,这也是同步时要重点验证的部分:

  1. 每个 chunk 含choices数组(通常单项),delta承载增量更新;
  2. 文本以delta.content字符串片段增量到达;
  3. 工具调用经delta.tool_calls增量到达,且有固定方案:首个 delta 携带完整 id 与函数名(参数通常为空),后续 delta 只追加参数文本——没有显式的 begin/end 标记,靠时间顺序隐含工具调用的开始与结束;
  4. 流结束靠data: [DONE]信号,不依赖finish_reason

解析入口 createOpenAIChatCompletionsChunkParser 在真正 Zod 解析前做了一组“防御性分流”,每一条都对应同步时观察到的真实上游行为:

  • Keepalive 事件(2025-01-13 上游加入):{"type":"keepalive",...}静默跳过;
  • 混淆占位 chunk:无choices但带obfuscation的消息直接跳过,否则会打断解析器;
  • error字段:按 openai.error-severity.ts 的严重度分级转成方言终止事件,而不是粗暴抛错;
  • Azure 特例:空 id/model 且带prompt_annotations/prompt_filter_results的 chunk 忽略;
  • OpenRouter:在 Zod 剥掉未知字段之前,先从原始 JSON 里摘出provider路由信息用于展示;
  • 尾部成本事件(如x-opencode-type: inference-cost):先收割 token/费用指标再跳过。

之后才是ChunkResponse_schema.parse严格解析,并记录timeToFirstEvent等性能指标。可以看到 parser 的演进史(每条注释都带上游日期/厂商)与 wire types 头部注释是同一套同步流程的两个出口。

五、Responses API 侧:方言差异表与事件流解析

因为指令明确“Responses API 优先”,openai.responsesCreate.ts 和 openai.responses.parser.ts 承载了主协议。

Adapter 侧用一张方言差异表RspDialectQuirks,见 openai.responsesCreate.ts#L26-L67)取代零散的 if-else,把“共享信封、各自校验器”的 OpenAI 兼容生态结构化:

差异项含义典型方言值
vndNamespace连续性状态(加密推理项、消息阶段)的_vnd命名空间openai / sakanaai / xai / metaai
emitMessagePhase回放 assistant 消息时带phase字段Azure 为 false(能力滞后)
webSearchTool托管 web_search 工具的形态:full / bare / noneAzure 为 none(“Hosted tool 'web_search' is not supported”)
toolChoiceOnlyAutotool_choice 只接受 'auto'metaai 严格校验器
minOutputTokens校验器接受的最小 max_output_tokensmetaai 为 16

每张表行都带日期标注(如 Azure 的滞后截至 2025-11-18 仍成立),这正是同步指令“点出所有协议差异”的输出形式。

Parser 侧则按 Responses API 的事件类型状态机推进(response.output_text.deltaresponse.output_text.doneresponse.output_text_annotation.added等,见 openai.responses.parser.ts#L603-L660),并对新旧两种 annotation 事件名做向后兼容。一个值得注意的上游怪癖处理是 “failed 响应打捞”(openai.responses.parser.ts#L74-L89):OpenAI 可能把一个实际已完整生成并流式发完的响应整体标记为failed(TPM 限流检查发生在生成中途而非准入时),解析器以 output 中每个 item 的status: 'completed'作为“生成已完成”的权威信号,把这类响应按成功处理。注释里标注了 2026-07-03 的 5/5 复现实测——这种“文档滞后、靠真实 SSE 才能发现”的行为,恰好是同步指令里“live endpoint 是 ground-truth”一节的注脚。

六、同步工作流:信息源、活体探测与差异清单

指令的后半部分给出了完整、可复用的同步操作手册,这部分对任何维护 OpenAI 兼容层的团队都通用:

1)信息源优先级(逐级降级)

  • 主源:Responses API 参考(优先)、Chat Completions 参考、Changelog、模型列表、定价页(用官方页面的 Copy Page 按钮下载 markdown,便于 diff);
  • 主源被挡时改用:OpenAI 官方 Node.js SDK、Python SDK、OpenAPI 规范仓库,或搜索“openai api changelog / new models / new prices”这类关键词获取近期公告;
  • 全部被挡时:如实说明尝试过什么,并请人工提供文档——严禁在拿不到上游信息时编造

2)活体端点探测(额外信号)

如果本地.env.api-keys中存在OPENAI_API_KEY,直接对真实端点打一发流式请求并检查原始 SSE:POST https://api.openai.com/v1/responses(legacy 则用/v1/chat/completions),请求体带"stream": true。文档可能滞后,而原始 SSE 是新字段、事件类型、响应形态与错误格式的最终事实来源。指令同时强调绝不提交或回显密钥

3)差异核对与输出要求

  • 深查请求与响应的字段级差异:必填字段、流式事件类型、新的响应形态、协议本身的变更(包括流式消息的最终解析与重组方式);
  • 优先报告破坏性变更和能改善用户体验的新能力——前者必须尽快修,后者进入实现待办;
  • 指令的 frontmatter 支持$ARGUMENTS占位(argument-hint 为 “specific feature to check”),可以把检查范围收窄到某个具体特性。

对照仓库现状可以验证这套流程的落地效果:wire types 文件头的 Changelog 日期注释、wiretypes 内每个方言扩展的[厂商, 日期]标签、parser 里带日期注释的防御分支、以及_upstream/目录下的上游规范快照与sync.sh,都是这个循环反复运转留下的痕迹。

七、小结:一套可迁移的协议同步方法

big-AGI 的 OpenAI 同步指令把“跟上上游 API”从一次性的手工活变成了可重复的工程流程,其要点可以概括为:

  1. 实现分三层且各司其职——Zod wire types 定义线格式(含方言超集与日期注释)、adapter 组装请求(按方言打热修并快速失败)、parser 消费响应(先防御分流、再严格解析、以 item 级状态为权威);
  2. 协议优先级明确——Responses API 为主、Chat Completions 为 legacy,Realtime 与 Agentic API 明确不接,由 AIX 自研能力覆盖;
  3. 信息源分级 + 活体 SSE 兜底——文档、SDK、OpenAPI 规范逐级降级,真实流式请求是文档滞后时的 ground-truth;
  4. 输出以“破坏性变更优先”排序——必填字段、流式事件类型、新响应形态是必查项,所有上游观察都必须带厂商与日期标注沉淀回源码注释。

维护同类项目时,可直接复用这套结构:先定位本项目的 wire types / adapter / parser 三件套,再按“文档 → 活体探测 → 字段级 diff → 注释落回源码”的闭环执行同步。

【免费下载链接】big-AGIAI suite powered by state-of-the-art models and providing advanced AI/AGI functions. Includes AI personas, AGI functions, world-class Beam multi-model chats, text-to-image, voice, response streaming, code highlighting and execution, PDF import, presets for developers, much more. Deploy on-prem or in the cloud.项目地址: https://gitcode.com/GitHub_Trending/bi/big-AGI

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/16 19:31:24

VSCode 背景图设置全攻略:插件、自定义 CSS 与直接改文件的三种方案

说实话,VSCode 已经是我每天打开时间最长的软件,没有之一。但你再喜欢一个编辑器,盯着同一块默认的灰蓝色界面看久了,也会觉得少了点什么。那段时间我把主题、字体、文件图标都折腾了一遍,接下来自然就盯上了背景图。很…

作者头像 李华
网站建设 2026/9/16 19:30:11

温控系统稳定性实战:传感器选型与PID整定全解析

做温控做久了,你会发现一个特别扎心的规律:把温度升上去从来不是难事,难的是让温度在设定值附近老老实实待着。我手里这套PTMP4718配合R7KA8D2KFLCAC的方案,当初就是为了解决“待着”这两个字折腾了快两周。PTMP4718作为温度采集探…

作者头像 李华
网站建设 2026/9/16 19:29:59

Lhaca1.24豪华版:LZH解压工具的技术解析与应用

1. Lhaca1.24豪华版:老牌解压工具的全面解析在Windows平台上,压缩解压工具一直是刚需软件。虽然WinRAR和7-Zip占据了大部分市场份额,但Lhaca这款来自日本的轻量级工具却以独特的LZH格式支持和极简设计赢得了特定用户群的青睐。最新发布的1.24…

作者头像 李华
网站建设 2026/9/16 19:27:42

宠物识别系统设计:从特征提取到向量检索的完整实践指南

1. 宠物识别系统到底在解决什么问题1.1 先分清:你要识别的是“什么宠物”还是“哪一只宠物”做宠物识别系统之前,我建议你先想清楚一个问题:客户要的究竟是“认品种”还是“认个体”。很多市面上号称“宠物识别”的产品,本质上是品…

作者头像 李华