Langchain设置Proxy后 Request timed out
python/langchain
简介
在使用Langchain 0.1.x版本的时候,使用ChatOpanAI类和其它相关类设置Proxy时不生效, 因为在0.1.1x版本中Langchain底层对于HTTP的请求,目前底层使用的是Httpx包,而Httpx的代理设置有点不同。
版本
python 10
langchain = "~=0.1.x"
openai = "~=1.13.3"
langchain-openai = "~=0.1.1"
代码样例
# 基于Langchain创建ChatOpenAI,并且设置proxy
llm = ChatOpenAI(openai_proxy="http://127.0.0.1:8889", **confs)
# 在不用科学上网的全局代理时会报错:
openai.APITimeoutError: Request timed out.
解决方法
1. 科学上网全局代理
这个适合自用电脑,但是在服务器上,不实用,一般公司服务器内部有代理。
2. 代码内设置全局代理
设置全局代理能解决Api timeout问题,但是会影响内部的API 访问, 导致请求国内的模型也走代理,使得国外模型正常,国内模型Timeout。
import os
os.environ["http_proxy"] = llm_conf.get('proxy')
os.environ["https_proxy"] = llm_conf.get('proxy')
llm = ChatOpenAI(**confs)
3. 源代码修改代理
这个目前在网上很多方案都是直接修改Openai库的源代码,用于覆盖创建httpx Client时的Proxy,这种方案需要修改源代码,库包更新会被覆盖,
openai/_base_client.py AsyncAPIClient, SyncAPIClient
两处添加如下代码:
if base_url is not None and 'api.openai' in base_url:
print(f"openai/_base_client.py/{self.__name__}")
# 用户定义
user_define_proxies = {"http://": "http://127.0.0.1:8889", "https://": "http://127.0.0.1:8889"}
# 覆盖代码内传的proxies
proxies = user_define_proxies
4. httpx client创建
其实从方案3的Openai源代码可知,此处是用于创建httpx的客户端,然后基于Stream的True/False,创建AsyncAPIClient或者SyncAPIClient,而在ChatOpenAI的类属性中发现可以传入http_client的,注意:在langchain-openai = "0.1.1"版本可以输入 http_async_client参数
,所以可以创建httpx的client来使得proxy生效。
SyncHttpxClientWrapper 和AsyncHttpxClientWrapper 直接拿的Openai库的类,分别继承了httpx.client 和 httpx.AsyncClient
代码如下:
# default_limits 设置Httpx 连接池限制
def syncHttpxClient(
base_url,
timeout,
proxies: Dict[str, str],
transport: Optional[BaseTransport] = None,
limits: Limits = default_limits
):
"""
获取同步的Httpx,
:param base_url:
:param timeout:
:param proxies:
:param transport:
:param limits:
:return:
"""
return SyncHttpxClientWrapper(
base_url=base_url,
# cast to a valid type because mypy doesn't understand our type narrowing
timeout=cast(Timeout, timeout),
proxies=proxies,
transport=transport,
limits=limits,
follow_redirects=True,
verify=False,
http2=True
)
def asyncHttpxClient(
base_url,
timeout,
proxies: Dict[str, str],
transport: Optional[BaseTransport] = None,
limits: Limits = default_limits
):
"""获取异步的Httpx"""
return AsyncHttpxClientWrapper(
base_url=base_url,
# cast to a valid type because mypy doesn't understand our type narrowing
timeout=cast(Timeout, timeout),
proxies=proxies,
transport=transport,
limits=limits,
follow_redirects=True,
verify=False,
http2=True
)
# 创建Httpx的客户端
if llm_conf.get('proxy'):
proxies = {
"http://": llm_conf.get('proxy'),
"https://": llm_conf.get('proxy'),
}
http_client = None
async_http_client = None
if not kwargs.get('streaming', False):
http_client = syncHttpxClient(llm_conf['api_base'], proxies=proxies, timeout=llm_conf['request_timeout'])
else:
async_http_client = asyncHttpxClient(llm_conf['api_base'], proxies=proxies, timeout=llm_conf['request_timeout'])
llm = ChatOpenAI(http_client=http_client, http_async_client=async_http_client, **llm_conf)
上面4种方法,能够解决Langchain创建ChatOpenAI后openai.APITimeoutError: Request timed out.
的问题,最终还是推荐方法4,可灵活制定httpx client。
感谢感谢
转载自:https://juejin.cn/post/7352713583224569908