在 Helicone 中同时接入 Azure OpenAI 与 Google Vertex AI Gemini:多提供商多模态示例实战
【免费下载链接】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 中examples/vertex-gemini-example/typescript示例,完整讲解如何通过一条网关代理,同时把 Vercel AI SDK(Azure OpenAI)、原生 OpenAI 客户端(Azure OpenAI)以及 Google Vertex AI Gemini(含图片多模态)三种调用方式统一接入 Helicone 进行观测与分析。读完本文,你将掌握 Helicone 的代理地址、Helicone-Auth认证头、Helicone-Target-URL目标改写等关键机制的配置方法,并能独立把该示例扩展到自己的多模态业务场景。
示例概述:三种集成方式一键覆盖
该示例的核心目标是在一个 TypeScript 项目中演示三种不同的 AI 提供商接入路径,并让所有请求都经由 Helicone 网关代理,实现日志、成本、延迟等指标的统一观测:
- Vercel AI SDK + Azure OpenAI:通过
@ai-sdk/openai的createOpenAI()工厂函数,将 Azure OpenAI 配置为 Vercel AI SDK 的模型提供方; - Direct OpenAI Client + Azure OpenAI:直接使用 OpenAI 官方 SDK,通过
baseURL与自定义请求头接入 Azure OpenAI; - Google Gemini / Vertex AI with Image Support:绕过 SDK,直接使用原生
fetch向 Vertex AI 的generateContent端点发送 HTTP 请求,并自动检测本地图片,构造文本 + 图片的多模态请求体。
三种方式各有适用场景:Vercel AI SDK 适合已在ai生态中开发的应用;OpenAI 客户端适合已有 OpenAI SDK 存量代码、希望最小化改动的项目;而直接fetchVertex AI 的方式则展示了不使用官方 SDK、纯 HTTP 集成时的完整请求结构,对理解网关代理原理最有帮助。
示例的完整源码位于 examples/vertex-gemini-example/typescript/index.ts,依赖与脚本声明在 examples/vertex-gemini-example/typescript/package.json,TypeScript 编译配置见 examples/vertex-gemini-example/typescript/tsconfig.json。
前置条件
开始之前,请确认以下环境与账号就绪:
- Node.js 18+ 与 npm:示例通过
ts-node直接运行 TypeScript 源码; - Azure OpenAI 账号:需要已创建资源并完成模型部署(如
gpt-4o); - (可选)Google Cloud Platform 账号:需在项目中启用 Vertex AI API,用于运行 Gemini 示例;
- Helicone 账号与 API Key:在 Helicone 控制台生成 API Key,用于请求认证与观测数据归属。
环境变量配置
示例依赖dotenv读取根目录下的.env文件。复制示例后,需填充以下变量:
# Azure OpenAI Configuration AZURE_API_KEY=your-azure-openai-api-key AZURE_OPENAI_API_KEY=your-azure-openai-api-key # Alternative name DEPLOYMENT_NAME=gpt-4o ENDPOINT_URL=https://your-resource-name.openai.azure.com/ API_VERSION=2024-02-15-preview RESOURCE_NAME=your-azure-resource-name # Helicone Configuration HELICONE_API_KEY=your-helicone-api-key # Google Cloud / Vertex AI Configuration (Optional) GOOGLE_CLOUD_PROJECT=your-gcp-project-id GOOGLE_CLOUD_LOCATION=us-central1 GOOGLE_API_KEY=your-google-api-key VERTEX_AI_TOKEN=your-vertex-ai-token变量用途说明:
| 变量 | 用途 | 备注 |
|---|---|---|
AZURE_API_KEY/AZURE_OPENAI_API_KEY | Azure OpenAI 的 API Key | 两者作用等价,分别被vercel()与notVercel()两个函数使用 |
DEPLOYMENT_NAME | Azure 中的模型部署名 | 如gpt-4o,需与 Azure 门户中的部署名完全一致 |
ENDPOINT_URL | Azure OpenAI 端点 | 格式为https://<resource-name>.openai.azure.com/ |
API_VERSION | Azure API 版本号 | 示例使用2024-02-15-preview |
RESOURCE_NAME | Azure 资源名 | 端点 URL 的主机名部分 |
HELICONE_API_KEY | Helicone 认证密钥 | 通过Helicone-Auth请求头发送 |
GOOGLE_CLOUD_PROJECT | GCP 项目 ID | 拼入 Vertex AI 端点路径 |
GOOGLE_CLOUD_LOCATION | Vertex AI 区域 | 默认us-central1,示例中同时决定了helicone-target-url的主机名 |
GOOGLE_API_KEY/VERTEX_AI_TOKEN | Google Cloud 凭据 | 二者取其一作为Authorization: Bearer的值 |
环境搭建与运行
安装依赖:
npm install启动示例(默认按顺序执行各集成示例):
npm run startpackage.json中声明了两个脚本:start使用ts-node index.ts直接运行;dev使用nodemon --exec ts-node index.ts在文件变更时自动重启,适合调试阶段。示例使用strict模式的 TypeScript 配置(见 tsconfig.json),依赖包括@ai-sdk/openai、@ai-sdk/azure、@google/genai、ai、openai与dotenv。
三种接入方式源码解析
vercel():Vercel AI SDK + Azure OpenAI 经 Helicone 代理
vercel()函数演示了 Vercel AI SDK 生态下的接入方式,核心代码如下:
const azureOpenAI = createOpenAI({ baseURL: "https://oai.helicone.ai/openai/deployments/gpt-4o", apiKey: "dummy-key", // Azure uses api-key header instead headers: { "Helicone-Auth": `Bearer ${process.env.HELICONE_API_KEY}`, "Helicone-OpenAI-API-Base": "https://vercelaisdkdocs.openai.azure.com/", "api-key": process.env.AZURE_API_KEY || "", }, fetch: async (url, options) => { // Add api-version query parameter to the URL const urlWithApiVersion = new URL(url); urlWithApiVersion.searchParams.set("api-version", "2024-02-15-preview"); return fetch(urlWithApiVersion.toString(), options); }, }); const { text } = await generateText({ model: azureOpenAI("gpt-4o"), prompt: "Write a vegetarian lasagna recipe for 4 people.", });三个关键点值得注意:
- 代理地址:
baseURL指向https://oai.helicone.ai/openai/deployments/gpt-4o,这是 Helicone 面向 OpenAI 兼容协议的网关端点,真正落地请求时会由网关转发到真实提供商; - 目标改写:
Helicone-OpenAI-API-Base请求头告诉网关实际要转发到的 Azure 端点(即 README 中提到的 Azure OpenAI 基地址),这是 Helicone 代理机制的核心——你请求的是网关,网关再按该请求头路由到真实上游; - Azure 认证:Azure 使用
api-key请求头而非 Bearer Token,因此 SDK 的apiKey字段填占位值"dummy-key",真实的 Key 通过api-key头传递; - API 版本:Azure 要求
api-version查询参数,示例通过自定义fetch函数统一注入2024-02-15-preview,避免每个请求手工拼 URL。
notVercel():原生 OpenAI SDK + Azure OpenAI
notVercel()是给偏好 OpenAI 官方客户端的开发者准备的备选方案:
const client = new OpenAI({ baseURL: "https://oai.helicone.ai/openai/deployments/gpt-4o", defaultHeaders: { "Helicone-Auth": `Bearer ${process.env.HELICONE_API_KEY}`, "Helicone-OpenAI-API-Base": "https://vercelaisdkdocs.openai.azure.com/", "api-key": process.env.AZURE_OPENAI_API_KEY, }, defaultQuery: { "api-version": "2024-02-15-preview", }, apiKey: "ghhh", });与vercel()相比,它把api-version放进defaultQuery,其余代理与认证逻辑完全一致,请求体仍使用 OpenAI 的chat.completions.create格式。两者的并存说明:Helicone 的代理对上层 SDK 是透明的,无论你用什么客户端,只要指向同一网关地址并携带正确的头即可被观测。
geminiTest():直接 HTTP 调用 Vertex AI 多模态接口
geminiTest()是本文档最具特色的部分,它不依赖任何 Gemini 官方 SDK,直接用fetch构造 Vertex AI 请求:
const project = process.env.GOOGLE_CLOUD_PROJECT || "your-project-id"; const location = process.env.GOOGLE_CLOUD_LOCATION || "us-central1"; // Use correct Vertex AI API endpoint const apiUrl = `https://gateway.helicone.ai/v1/projects/${project}/locations/${location}/publishers/google/models/gemini-1.5-flash:generateContent`;请求头同时携带了 Helicone 认证与目标改写信息:
const response = await fetch(apiUrl, { method: "POST", headers: { "Content-Type": "application/json", "helicone-auth": `Bearer ${process.env.HELICONE_API_KEY}`, "helicone-target-url": `https://${location}-aiplatform.googleapis.com`, Authorization: `Bearer ${process.env.GOOGLE_API_KEY || process.env.VERTEX_AI_TOKEN}`, }, body: JSON.stringify({ contents: requestContents, generationConfig: { temperature: 0.7, maxOutputTokens: 1000, }, }), });请求体结构遵循 Vertex AIgenerateContent协议:contents数组内的parts可以同时包含text与inlineData(Base64 图片数据 + MIME 类型),generationConfig控制temperature与maxOutputTokens。这正好印证了仓库文档 docs/integrations/gemini/vertex/javascript.mdx 与 docs/integrations/gemini/vertex/curl.mdx 中描述的代理接入模式:请求发往gateway.helicone.ai,Helicone-Target-URL指向区域化的https://<location>-aiplatform.googleapis.com,真实上游的认证凭据则原样放在Authorization头中。
网关代理的底层原理
从源码看,Helicone 网关对target-url类请求头的处理是有据可循的:在 worker/src/lib/models/HeliconeHeaders.ts 中,IHeliconeHeaders定义了openaiBaseUrl与targetBaseUrl等字段;在 worker/src/routers/gatewayRouter.ts 中,网关会根据targetBaseUrl判断提供商(getProviderFromTargetUrl),再调用proxyForwarder完成转发。因此可以推断:helicone-target-url的作用就是把“发给网关的请求”改写为“发给真实上游的请求”,而网关在转发的同时完成日志、成本与指标的采集。这也是本示例中 Azure 与 Gemini 两条路径共用同一套代理思想的根本原因。
多模态图片支持
Gemini 集成具备自动的图片检测能力,逻辑集中在geminiTest()函数内:
- 自动检测:使用
fs.existsSync(path.join(__dirname, "test.png"))检查当前目录下是否存在test.png; - Base64 编码:若存在,通过
fs.readFileSync读取并转成 Base64 字符串,放入inlineData.data; - 多模态组合:将文字提示与
inlineData图片块同时放进parts数组; - 文本兜底:若图片不存在,则退化为纯文本请求,保证示例在任意环境下都能运行。
图片要求如下:
- 格式:PNG、JPEG 等常见图片格式(示例默认按
image/png发送 MIME 类型); - 文件名:
test.png,必须与index.ts位于同一目录; - 大小:建议小于 10MB,以保证编码与传输性能。
更换与扩展图片
要使用自己的图片,只需替换test.png,或在代码中修改路径:
const imagePath = path.join(__dirname, "your-image.png");同时可以修改提示词以针对图片提问:
text: "What ingredients do you see in this food image? Suggest a recipe."进阶多模态能力
原示例的图片逻辑可以扩展为更通用的能力,README 给出了可参考的扩展方向:
// Multiple image formats const supportedFormats = ['.png', '.jpg', '.jpeg', '.webp']; const imageFiles = fs.readdirSync(__dirname) .filter(file => supportedFormats.some(format => file.endsWith(format))); // Different MIME types const getMimeType = (filename: string) => { if (filename.endsWith('.jpg') || filename.endsWith('.jpeg')) return 'image/jpeg'; if (filename.endsWith('.png')) return 'image/png'; if (filename.endsWith('.webp')) return 'image/webp'; return 'image/png'; }; // Multiple images in one request const requestContents = [{ parts: [ { text: "Compare these images and describe the differences:" }, { inlineData: { data: image1Base64, mimeType: "image/png" } }, { inlineData: { data: image2Base64, mimeType: "image/jpeg" } } ] }];其中多图对比的能力直接依赖 Vertex AIgenerateContent协议中parts数组可容纳多个inlineData块的特性——这也是多模态请求的通用数据结构。
切换模型
- Azure OpenAI:修改代理 URL 中的部署名(如把
gpt-4o换成其他已部署模型); - Gemini:修改端点路径中的模型名,除示例默认的
gemini-1.5-flash外,可选用:gemini-1.5-pro(能力更强,速度较慢)gemini-1.0-pro-vision(遗留的视觉模型)
注意模型可用性因区域而异,切换前需确认目标区域已上线相应模型。
运行流程与预期输出
runAllExamples()为统一入口,其内部执行顺序如下(vercel()与notVercel()默认被注释,仅geminiTest()实际执行,可通过取消注释恢复):
🚀 Starting Google Gemini with Helicone... 📸 Found test.png - reading image for multimodal request... 🖼️ Sending multimodal request (text + image)... ✅ Gemini response: [Generated content...] 📊 Check your Helicone dashboard at https://helicone.ai/requests若未配置 Google Cloud 凭据,geminiTest()会在fetch失败后打印排障提示(见下文),不会导致进程崩溃;若缺少HELICONE_API_KEY,函数会直接提示并提前返回。这种“未配置即优雅降级”的设计让示例可以安全地在任意机器上演示。
常见问题排查
Azure OpenAI 相关
404 错误:多为配置不匹配导致——
- 确认部署名与 Azure 门户中的部署名完全一致;
- 确认资源名(resource name)正确;
- 确认
api-version(示例为2024-02-15-preview)在 Azure 侧受支持。
认证错误:检查api-key是否填写正确、Azure 资源是否具备相应权限(如Cognitive Services OpenAI User角色)。
Google Gemini 相关
认证错误:
- 确认已在 GCP 项目中启用 Vertex AI API;
- 确认
GOOGLE_API_KEY或VERTEX_AI_TOKEN具有调用权限; - 确认
GOOGLE_CLOUD_PROJECT中的项目 ID 准确无误。
URL 错误:
- 确认
GOOGLE_CLOUD_LOCATION区域正确(默认us-central1); - 确认目标模型在该区域可用;
- 注意
helicone-target-url的主机名与端点路径中的location必须一致,否则网关会路由到错误的区域端点。
通过 Helicone 观测请求
所有请求经网关转发后都会在 Helicone 控制台的 Requests 页面留下完整记录,可观测内容包括:
- 请求日志与响应:输入输出内容、模型名、请求耗时;
- 性能指标:首 Token 延迟、总延迟等;
- 成本追踪:按模型与提供商核算的调用成本;
- 错误率与调试信息:HTTP 状态码、错误响应体,便于快速定位上游问题。
该示例与仓库文档 docs/integrations/gemini/vertex/python.mdx(Python 版代理接入)配合阅读,可以覆盖 JavaScript/TypeScript 与 Python 两种语言下的完整接入姿势。
小结
通过这个示例,可以看到 Helicone 的多提供商代理设计:客户端只需把请求发往统一的网关地址,借助Helicone-Auth(认证)与Helicone-Target-URL/Helicone-OpenAI-API-Base(目标改写)两个请求头,即可透明地把 Azure OpenAI、Vertex AI Gemini 等不同提供商的调用纳入同一套观测体系。无论你使用 Vercel AI SDK、原生 OpenAI 客户端,还是直接fetchHTTP 接口,模式完全一致——这为后续接入更多模型、更多模态(多图、视频)提供了清晰的可复制路径。
【免费下载链接】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),仅供参考