Helicone × Vertex AI Gemini Python 异步调用:修复 generate_content_async 的 async REST 凭据问题
【免费下载链接】helicone🧊 Open source LLM observability platform. One line of code to monitor, evaluate, and experiment. YC W23 🍓项目地址: https://gitcode.com/GitHub_Trending/he/helicone
本指南围绕开源 LLM 可观测平台 Helicone 仓库中的官方示例(examples/vertex-gemini-example/python)展开,讲解在 Python 中使用 Vertex AI Gemini 模型并通过 Helicone 网关记录请求时,generate_content_async报出 async REST 凭据缺失错误的根因与完整修复方案。读完本文,你将掌握一套可直接复制运行的初始化模板,理解aiplatform与vertexai双层初始化的差异,并能结合 Helicone 网关源码理解helicone-target-url、helicone-auth等元数据头的转发机制。
背景:一条常见的 Google Cloud 报错信息
当你按照 Helicone 官方文档(docs/integrations/gemini/vertex/python.mdx)完成vertexai.init()的代理配置后,直接调用异步方法generate_content_async,很可能遇到这样一段警告:
REST async clients requires async credentials set using aiplatform.initializer._set_async_rest_credentials(). Falling back to grpc since no async rest credentials were detected.含义拆解如下:
- REST async clients requires async credentials:Vertex AI 的异步客户端若走 REST 传输,需要一组“异步专用”的凭据对象,而不能复用同步凭据;
- Falling back to grpc:Google Cloud 库检测不到这组凭据后会自动降级到 gRPC 传输;
- 而降级到 gRPC 之后,Helicone 网关通过 REST 端点捕获请求的机制就会失效,导致日志记录链路中断或行为不符合预期。
Helicone 的官方示例(examples/vertex-gemini-example/python)正是围绕这一痛点给出了一套经过验证的解决方案,下文逐步展开。
环境准备:从零开始运行示例
示例目录包含四个文件:README.md、gemini_example.py、requirements.txt与run.sh。先完成环境搭建。
1. 创建虚拟环境
python -m venv venv source venv/bin/activate2. 安装依赖
pip install -r requirements.txtrequirements.txt中对版本有明确约束(examples/vertex-gemini-example/python/requirements.txt):
google-cloud-aiplatform>=1.36.0 vertexai>=0.0.1 python-dotenv>=1.0.0 asyncio>=3.4.3 google-api-core[grpc,async_rest]>=2.21.0 google-auth[aiohttp]>=2.35.0其中两个依赖与本问题的解决方案直接相关:
google-api-core[grpc,async_rest]:extra 标记async_rest会安装异步 REST 传输所需的额外依赖,是_set_async_rest_credentials()能够生效的前提之一;google-auth[aiohttp]:异步凭据刷新依赖 aiohttp 客户端,同时它也是示例末尾“Unclosed client session”警告的来源(见后文已知问题一节)。
3. 配置环境变量
示例通过python-dotenv加载.env文件,需要填写三个变量:
HELICONE_API_KEY="your-helicone-api-key" PROJECT_ID="your-gcp-project-id" LOCATION="us-central1" # or your preferred regionHELICONE_API_KEY:在 Helicone 控制台生成的 API Key,用于向网关鉴权;PROJECT_ID:你的 Google Cloud 项目 ID;LOCATION:模型部署区域,示例默认us-central1,可按实际资源位置替换,但需与后续helicone-target-url中拼接的区域保持一致。
4. 配置 Google Cloud 应用默认凭据
gcloud auth application-default login该命令会在本地写入 Application Default Credentials(ADC),供google.auth.default()在代码中无感读取。
5. 运行示例
python gemini_example.py仓库还附带了一键脚本 run.sh:它会自动创建虚拟环境、安装依赖、检测gcloud是否安装、检查 ADC 是否已配置(未配置则引导登录),最后执行示例并退出虚拟环境,适合在 CI 或全新机器上快速复现。
问题根因:异步 REST 传输缺少独立的凭据对象
要理解修复方案,需要先明白 Vertex AI Python 客户端的凭据体系。Google Cloud 库区分了两类凭据:
- 同步凭据:即
google.auth.default()返回的 ADC 凭据,供同步请求(如generate_content)使用; - 异步凭据:供
generate_content_async等异步请求使用,在 REST 传输下必须显式注入,否则库会输出上述警告并回退到 gRPC。
Helicone 的代理方案基于 REST 网关转发(api_endpoint="gateway.helicone.ai"),因此异步调用也必须走 REST 传输,这就产生了“必须显式设置异步 REST 凭据”的硬性要求。示例的修复思路正是补齐这一环。
解决方案:五步修复异步 REST 凭据
示例 gemini_example.py 给出了完整的修复链路,可拆解为五步。
第 1 步:从 ADC 获取访问令牌
credentials, _ = google.auth.default() auth_req = google.auth.transport.requests.Request() credentials.refresh(auth_req) token = credentials.token先通过google.auth.default()拿到应用默认凭据,再调用refresh()强制刷新,从中取出当前有效的访问令牌token。注意必须显式 refresh:未经刷新的凭据可能没有有效的token属性。
第 2 步:用令牌构造异步静态凭据
from google.auth.aio.credentials import StaticCredentials async_credentials = StaticCredentials(token=token)StaticCredentials是google.auth.aio命名空间下的异步凭据实现,它不执行动态刷新,而是直接持有给定的令牌,适合短期运行的脚本场景。
第 3 步:显式初始化 aiplatform 并指定 REST 传输
from google.cloud import aiplatform aiplatform.init( project=PROJECT_ID, location=LOCATION, api_transport="rest" # Explicitly set REST transport )这里初始化的是底层google.cloud.aiplatform(注意与vertexai区分)。api_transport="rest"是关键参数,它把整个服务层固定为 REST 传输模式。
第 4 步:注入异步 REST 凭据
aiplatform.initializer._set_async_rest_credentials(credentials=async_credentials)aiplatform.initializer._set_async_rest_credentials()是一个带下划线前缀的内部 API,用于把第 2 步构造的异步凭据注册到 aiplatform 的初始化器上。调用之后,异步 REST 客户端才能获得所需的凭据,不再触发“Falling back to grpc”警告。
第 5 步:通过 Helicone 网关初始化 vertexai
import vertexai vertexai.init( project=PROJECT_ID, location=LOCATION, api_endpoint="gateway.helicone.ai", api_transport="rest", request_metadata=[ ('helicone-target-url', f'https://{LOCATION}-aiplatform.googleapis.com'), ('helicone-auth', f'Bearer {HELICONE_API_KEY}') ] )这一步是整个集成的心脏,三个要素缺一不可:
api_endpoint="gateway.helicone.ai":把 Vertex AI 的请求端点替换为 Helicone 网关,使所有 Gemini 调用先流经网关再做转发与日志记录;api_transport="rest":与底层 aiplatform 保持一致,强制 REST 传输,保证异步凭据注入真正生效;request_metadata:以 gRPC 元数据的形式注入两个 Helicone 定制头,网关正是依靠它们完成路由与鉴权:helicone-target-url:声明真实的上游地址(Vertex AI REST 端点https://{LOCATION}-aiplatform.googleapis.com),网关会把请求转发到该地址;helicone-auth:携带Bearer {HELICONE_API_KEY},用于在网关侧完成 Helicone 鉴权。
初始化完成后即可创建模型并异步生成内容:
model = GenerativeModel( "gemini-1.5-pro", generation_config={"response_mime_type": "application/json"} ) response = await model.generate_content_async(contents=["Tell me a joke about programming"]) print(response.text)元数据头如何被 Helicone 网关消费:源码级验证
request_metadata中注入的头并非“约定俗成”,而是 Helicone 网关实际读取的协议字段。以网关核心实现 worker/src/lib/models/HeliconeHeaders.ts 为证,其getHeliconeHeaders()方法显式解析了这两项:
return { heliconeAuth: this.headers.get("helicone-auth") ?? null, ... targetBaseUrl: this.headers.get("Helicone-Target-URL") ?? null, ... };helicone-auth被解析为heliconeAuth,用于后续的请求鉴权;Helicone-Target-URL被解析为targetBaseUrl,即真实上游地址。
随后网关路由器会对targetBaseUrl做合法性校验(URL 格式、协议、域名是否在批准列表中等),校验通过后把请求转发到目标服务,同时完成请求/响应日志记录。整个过程可以概括为:
Vertex AI SDK │ api_endpoint = gateway.helicone.ai │ request_metadata: helicone-target-url / helicone-auth ▼ Helicone Gateway (gateway.helicone.ai) │ 读取 Helicone-Target-URL → 校验目标地址 │ 读取 helicone-auth → 鉴权 │ 记录请求与响应日志 ▼ Vertex AI REST 端点 (https://{LOCATION}-aiplatform.googleapis.com)这也解释了为什么“必须先修复异步凭据”:一旦异步请求降级到 gRPC,请求不再经过网关的 REST 端点,helicone-target-url与helicone-auth无从生效,日志记录也就随之失效。
已知问题:Unclosed Client Session 警告
运行示例时控制台可能出现以下警告:
Unclosed client session client_session: <aiohttp.client.ClientSession object at 0x...> Unclosed connector connections: ['deque([(<aiohttp.client_proto.ResponseHandler object at 0x...>, ...)])'] connector: <aiohttp.connector.TCPConnector object at 0x...>这是 Google Cloud 库内部使用的 aiohttp 异步客户端在程序退出前未显式关闭所致,属于库层面的资源管理问题,不影响示例功能与日志记录结果。示例源码在main()入口处通过以下方式抑制了ResourceWarning噪音:
if not sys.warnoptions: warnings.filterwarnings("ignore", category=ResourceWarning)官方文档明确说明:在示例场景下可以安全忽略;若进入生产环境,则应自行实现连接池与客户端的优雅关闭(例如在应用退出钩子中调用aiohttp.ClientSession.close()),避免长生命周期服务中的连接泄漏。
进阶:需要精细控制时的 Manual Logger 方案
如果应用对日志内容有更高要求(例如同时处理异步与流式响应、需要自定义元数据、控制日志上报时机),官方文档 docs/integrations/gemini/vertex/python.mdx 还提供了 Helicone Manual Logger 的替代方案:
- 引入
HeliconeManualLogger,通过new_builder(request)构造日志构建器; - 调用
add_model()记录模型名,add_response()记录完整响应,add_chunk()逐块记录流式响应; - 最后在
finally中调用await log_builder.send_log()上报到https://api.helicone.ai/v1/log,请求体以provider: "vertex"标识来源。
该方案不依赖网关转发,而是由业务代码主动上报请求/响应,适合流式输出、需要精确控制日志粒度或网关方案不便落地的复杂场景;其优势在于对异步与流式响应的原生支持,以及对日志内容与上报时机的完全掌控。
小结
本文以 Helicone 仓库官方示例为核心,完整梳理了 Vertex AI Gemini 异步调用接入 Helicone 的修复链路:
- 报错根因是异步 REST 客户端缺少独立凭据,导致降级到 gRPC,破坏网关转发;
- 修复关键在
aiplatform.initializer._set_async_rest_credentials()+StaticCredentials+ 双层api_transport="rest"的配合; request_metadata注入的helicone-target-url与helicone-auth是网关路由与鉴权的协议字段,可在 HeliconeHeaders.ts 的源码中直接验证;- 示例附带的一键脚本 run.sh 与完整依赖清单 requirements.txt 可帮助你快速复现,官方集成文档 docs/integrations/gemini/vertex/python.mdx 则提供了 Manual Logger 等进阶用法供生产环境参考。
【免费下载链接】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),仅供参考