You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何为Google Vertex AI Python SDK配置代理且不影响其他系统或应用

如何为Google Vertex AI Python SDK配置代理且不影响其他系统或应用

我完全理解你不想通过全局环境变量设置代理的顾虑——毕竟这会牵连到其他应用甚至K8s Pod,搞不好就出系统稳定性问题。针对你的场景,我整理了几个只针对Vertex AI Python SDK生效、完全不影响其他组件的配置方案,适配你现有的代码结构:

方案一:为Vertex SDK底层客户端配置专属代理(推荐生产环境使用)

Vertex AI Python SDK基于Google Cloud核心客户端库构建,我们可以直接为其底层的HTTP/REST和gRPC客户端单独设置代理,完全不会波及其他代码或应用。这种方式是最安全、最精准的。

结合你的VertexClient类,修改后的代码如下:

import vertexai
from vertexai.preview.generative_models import GenerativeModel, GenerationConfig
from google.auth.transport.requests import Request, Session
from google.api_core.client_options import ClientOptions

class VertexClient:
    def __init__(self, proxy_url: str):
        self.proxy_url = proxy_url
        # 初始化带代理的专属Session(用于REST协议调用)
        self.proxied_session = Session()
        self.proxied_session.proxies = {
            "http": self.proxy_url,
            "https": self.proxy_url
        }
        # 配置gRPC客户端选项(用于流式调用,比如你用的stream=True)
        self.client_options = ClientOptions(
            grpc_proxy=self.proxy_url
        )

    def generate_stream(self, credentials, contents):
        # 初始化Vertex AI时,传入我们的代理Session
        vertexai.init(
            project="你的项目ID", 
            location="你的部署区域", 
            credentials=credentials,
            request=Request(session=self.proxied_session)
        )
        
        model = GenerativeModel("你的模型名称,比如gemini-1.5-pro-001")
        generation_config = GenerationConfig(max_output_tokens=8192, temperature=1, top_p=0.05)
        
        # 调用生成接口时传入gRPC代理配置
        return model.generate_content(
            contents=contents,
            generation_config=generation_config,
            stream=True,
            client_options=self.client_options
        )

为什么这个方案靠谱?

  • 所有代理配置都绑定在当前VertexClient实例上,属于实例级隔离,其他代码完全感知不到
  • 同时覆盖了REST和gRPC两种协议(流式调用通常用gRPC),不会出现部分请求走代理、部分不走的情况
  • 完全不需要修改环境变量,从根源上避免了全局影响

方案二:用上下文管理器安全临时设置环境变量(快速适配场景)

如果你觉得底层配置太繁琐,也可以用上下文管理器临时、安全地设置代理环境变量,确保只在Vertex SDK调用期间生效,并且处理多线程并发的问题。

代码示例:

import os
import contextlib
from threading import Lock
import vertexai
from vertexai.preview.generative_models import GenerativeModel, GenerationConfig

# 全局锁,防止多线程下环境变量冲突
proxy_lock = Lock()

@contextlib.contextmanager
def use_vertex_proxy(proxy_url: str):
    # 先保存原环境变量,后面要恢复
    original_https = os.environ.get("https_proxy")
    original_http = os.environ.get("http_proxy")
    original_no_proxy = os.environ.get("no_proxy")
    
    try:
        with proxy_lock:
            # 临时设置代理,同时排除内部服务避免影响
            os.environ["https_proxy"] = proxy_url
            os.environ["http_proxy"] = proxy_url
            os.environ["no_proxy"] = "localhost,127.0.0.1,cluster.local"
        yield  # 执行Vertex SDK的调用逻辑
    finally:
        with proxy_lock:
            # 恢复原来的环境变量,确保不留痕迹
            if original_https is not None:
                os.environ["https_proxy"] = original_https
            else:
                del os.environ["https_proxy"]
                
            if original_http is not None:
                os.environ["http_proxy"] = original_http
            else:
                del os.environ["http_proxy"]
                
            if original_no_proxy is not None:
                os.environ["no_proxy"] = original_no_proxy
            else:
                del os.environ["no_proxy"]

class VertexClient:
    def generate_stream(self, credentials, contents):
        proxy_url = "http://my-proxy:port"
        # 仅在这个代码块内生效代理
        with use_vertex_proxy(proxy_url):
            vertexai.init(project="你的项目ID", location="你的部署区域", credentials=credentials)
            model = GenerativeModel("你的模型名称")
            generation_config = GenerationConfig(max_output_tokens=8192, temperature=1, top_p=0.05)
            return model.generate_content(
                contents=contents,
                generation_config=generation_config,
                stream=True
            )

注意事项:

  • 一定要加锁!环境变量是进程级的,如果你的应用是多线程的,不加锁会导致多个请求的代理配置互相覆盖
  • 这个方案本质还是临时修改环境变量,但通过上下文管理器和锁把影响范围严格限制在了Vertex SDK的调用周期内,比你之前手动设置/删除要安全得多

方案三:单独配置gRPC代理(针对流式调用场景)

你的generate_stream用了stream=True,这部分调用大概率是走gRPC协议的。如果你的场景中只需要处理流式调用的代理,也可以单独为gRPC配置代理,同样通过客户端选项传入,和方案一的gRPC配置部分一致。


备注:内容来源于stack exchange,提问作者user28842828

火山引擎 最新活动