Helicone Worker 内置 LLM 协议转换网关 llmmapper 模块解析与同步维护指南【免费下载链接】helicone Open source LLM observability platform. One line of code to monitor, evaluate, and experiment. YC W23 项目地址: https://gitcode.com/GitHub_Trending/he/helicone导读Helicone 的 WorkerCloudflare Worker 侧 AI Gateway 实现内置了一个名为llmmapper的 LLM 协议转换模块它允许客户端以某一家大模型厂商的 API 协议发起请求由网关在请求/响应链路上实时转换为另一家厂商的协议格式从而实现 OpenAI、Anthropic、Google Gemini 以及 OpenAI Chat Completions 与 Responses API 之间的无缝互通。本文以 worker/src/lib/clients/llmmapper/README.md 为骨架结合仓库内该模块的完整源码与测试用例深入讲解其入口分发逻辑、四条协议转换路由oai2ant、oai2google、oaiChat2responses、流式 SSE 转换原理以及从上游 llmmapper 仓库同步更新的维护流程读完后你将能够理解并复用它来扩展新的协议转换能力。一、模块定位从上游 llmmapper 仓库同步而来的协议转换层仓库内 worker/src/lib/clients/llmmapper/README.md 只有短短几行却明确了该目录的来源与维护契约providers与routers目录是从 llmmapper 仓库复制粘贴而来的一旦上游 llmmapper 仓库发生任何变更本仓库都必须同步更新以保持一致同步方式把上游仓库的providers、routers两个目录整体复制进本目录随后执行yarn lint-fix修复 lint 报错。从当前仓库的实际目录结构看该目录内保存的是router/路由转换实现与llmmapper.ts入口而真正执行协议转换的转换器toOpenAI、toAnthropic、AnthropicToOpenAIStreamConverter、ChatToResponsesStreamConverter等则统一封装在 monorepo 的 packages/llm-mapper 包中通过helicone-package/llm-mapper/transform/...路径被引用。也就是说worker/src/lib/clients/llmmapper/负责网关侧的路由编排与响应封装而转换细节沉淀在packages/llm-mapper中两者共同构成完整的协议转换能力。这也解释了为什么同步时只需要关注providers厂商数据与routers路由转换两个目录。二、网关入口llmmapper() 的请求分发逻辑入口文件 worker/src/lib/clients/llmmapper/llmmapper.ts 定义了llmmapper(targetUrl, init)函数其职责是根据目标 URL 的路径前缀决定走哪条转换路由路径以/oai2ant开头先通过tryJSONParse解析请求体解析失败直接返回400 Invalid body随后依据请求体中的stream字段分流stream为真调用antStream2oaiStream走Anthropic 流式 SSE → OpenAI 流式 SSE转换否则调用ant2oai走Anthropic 非流式 JSON → OpenAI JSON转换其他路径返回404 Unsupported path。这个入口函数被 worker/src/lib/clients/ProviderClient.ts 中的callWithMapper挂载当请求的目标主机名是gateway.llmmapper.com时Worker 不会直接fetch上游而是把请求体与头信息交给llmmapper()处理若请求没有 body则返回404 Unsupported, must have body一旦转换过程中抛出异常则返回状态码10502Helicone LLMMapper gateway error。由此可以推断llmmapper 网关以特殊主机名 路径前缀作为路由标识是对外暴露协议转换能力的一组虚拟端点。三、路由一/oai2ant —— Anthropic 与 OpenAI 协议互转3.1 非流式转换 ant2oaiworker/src/lib/clients/llmmapper/router/oai2ant/nonStream.ts 实现了非流式转换ant2oai完整链路如下使用toAnthropic(body)把 OpenAI Chat 风格的请求体转换为 Anthropic Messages API 格式转换器来自helicone-package/llm-mapper/transform/providers/openai/request/toAnthropic从请求头中提取Authorization剥离Bearer前缀后作为 Anthropic 的x-api-key若请求头缺少anthropic-version则回退到默认值2023-06-01以POST https://api.anthropic.com/v1/messages转发请求响应侧通过ant2oaiResponse使用toOpenAI()来自.../anthropic/response/toOpenai把 Anthropic 响应体反向转换为 OpenAI 格式并透传状态码与响应头若转换失败则原样返回上游响应保证错误信息不丢失。值得注意的细节是Authorization的提取同时兼容了已有Bearer前缀与裸 key两种写法且Content-Type被强制设为application/json这是直接面向生产可用的边界处理。3.2 流式转换 antStream2oaiStream 与 Bedrock 事件流支持流式场景远比非流式复杂worker/src/lib/clients/llmmapper/router/oai2ant/stream.ts 给出了完整的工程实现antStream2oaiStream同样先做请求体转换与鉴权头处理再请求 Anthropic/v1/messages上游返回非 2xx 时直接透传错误体无响应体时返回500 No response bodyant2oaiStreamResponse把上游流式响应交给ant2oaiStream转换同时改写响应头content-type设为text/event-stream; charsetutf-8、cache-control: no-cache、connection: keep-alive并删除content-length因为流式输出长度未知这正是 OpenAI SSE 客户端的标准期望流式转换核心ant2oaiStream依据上游content-type自动选择两条解码路径Anthropic SSE 路径readAnthropicSSE用TextDecoder边读边缓冲按\n\n切分 SSE 消息交由AnthropicToOpenAIStreamConverter.processLines逐块转换为 OpenAI chunk再以data: {...}\n\n形式重新编码输出流结束时追加data: [DONE]\n\nBedrock Event Stream 路径readBedrockEventStream当content-type为application/vnd.amazon.eventstream时启用。实现借助smithy/eventstream-codec的EventStreamCodec按帧解码——每条消息最小长度为 16 字节4 字节总长 4 字节头长 4 字节 prelude CRC 4 字节 CRC源码注释MINIMUM_EVENT_STREAM_MESSAGE_LENGTH 16印证了这一点逐帧识别:event-type头跳过非chunk事件、解出error事件并抛出再把 payload 中的 base64bytes字段解码后送入同一转换器。也就是说同一套 OpenAI 流式输出协议背后可以同时承接 Anthropic SSE 与 AWS Bedrock 二进制事件流两种上游格式这是该模块最具工程价值的部分之一。四、路由二/oai2google —— Google Gemini 响应转 OpenAIworker/src/lib/clients/llmmapper/router/oai2google/nonStream.ts 与 worker/src/lib/clients/llmmapper/router/oai2google/stream.ts 提供了 Google → OpenAI 方向的转换goog2oaiResponse解析 Google 响应体类型GoogleResponseBody用toOpenAI()来自.../google/response/toOpenai转换为 OpenAI JSON 返回失败时回退原响应goog2oaiStream/goog2oaiStreamResponse使用GoogleToOpenAIStreamConverter完成 SSE 流转 SSE缓冲切分与响应头改写逻辑与 oai2ant 流式路径保持一致text/event-stream; charsetutf-8、no-cache、keep-alive、删除content-length、结束追加data: [DONE]。从源码结构看oai2google目前实现的是响应方向的转换与 oai2ant 的请求 响应双方向略有不同这是使用时需要注意的能力边界。五、路由三/oaiChat2responses —— Chat Completions 升级为 Responses APIOpenAI Responses API 是 Chat Completions 的后继接口形态worker/src/lib/clients/llmmapper/router/oaiChat2responses/nonStream.ts 与 worker/src/lib/clients/llmmapper/router/oaiChat2responses/stream.ts 负责把旧协议的请求/响应翻译为新协议oaiChat2responsesResponse读取响应体文本按OpenAIResponseBody解析后交给toResponses()来自.../responses/openai/response/toResponses产出object: response形态的新协议响应并透传状态码与响应头oaiChat2responsesStream逐行消费上游data:SSE 块跳过[DONE]与注释行将每个ChatCompletionChunk交给ChatToResponsesStreamConverter.convert生成一组事件再编码为event: typedata: {...}双行格式的 SSE 输出——这种命名事件格式正是 OpenAI SDK 对 Responses 流的标准要求同时记录是否已发出response.completed事件oaiChat2responsesStreamResponse沿用统一的响应头改写模式封装转换后的流。该路由的协议语义response.output_text.delta、response.completed等事件名在测试中有明确验证见下文。六、测试验证协议转换的正确性保障转换正确性是此类网关的命脉仓库在 worker/test/ai-gateway/map-responses.spec.ts 中为 Chat → Responses 路由提供了两组 vitest 用例非流式用例构造一个包含tool_callscalc({x:1})、finish_reason: tool_calls、usage的chat.completion响应断言转换结果object为response、输出数组中角色为assistant、文本内容变为{ type: output_text, text: Hi from chat, annotations: [] }、函数调用被映射为{ call_id, name, arguments }且usage字段由prompt_tokens/completion_tokens正确映射为input_tokens/output_tokens流式用例依次喂入角色建立 chunk → 文本 delta finish → usage chunk → [DONE]断言输出流为text/event-stream且包含event: response.created、event: response.output_text.delta、event: response.output_text.done、event: response.completed等事件。这些用例直接印证了上一节描述的字段映射与事件语义可作为日后扩展新路由时的测试范式参考。七、同步维护流程如何与上游 llmmapper 保持对齐回到 worker/src/lib/clients/llmmapper/README.md 声明的维护契约仓库内该目录的实际维护方式可归纳为三步整体覆盖将上游 llmmapper 仓库的providers与routers两个目录整体复制到worker/src/lib/clients/llmmapper/下当前仓库对应目录为router/与入口llmmapper.ts保持目录结构一一对应契约校验确认目录内对helicone-package/llm-mapper各 transform 转换器的引用路径不变——因为转换器本体维护在 packages/llm-mapper如transform/providers/anthropic/response/toOpenai、transform/providers/openai/request/toAnthropic、transform/providers/responses/streamedResponse/toResponses等同步上游仅需聚焦路由编排层质量门禁运行yarn lint-fix自动修复 lint 错误随后建议运行 worker/test/ai-gateway/map-responses.spec.ts 等测试确认转换行为未回归。该流程的本质是路由编排本地化、转换器库共享化协议细节集中在 llm-mapper 包中演进网关侧只保留薄薄的路由分发与响应封装从而让同步成本降到最低。若你需要为本网关新增一条转换路由参照现有router/oai2ant的目录结构与 ProviderClient.ts 的挂载方式即可平滑扩展。【免费下载链接】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),仅供参考