mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-25 00:23:53 +08:00
gemini可以单独走代理,避免全局代理。
全局代理容易让系统中其他模块也使用代理,造成无法访问的问题。 测试最新的 gemini flash 2.0可以使用。
This commit is contained in:
@@ -193,7 +193,9 @@ LLM:
|
|||||||
# token申请地址: https://aistudio.google.com/apikey
|
# token申请地址: https://aistudio.google.com/apikey
|
||||||
# 若部署地无法访问接口,需要开启科学上网
|
# 若部署地无法访问接口,需要开启科学上网
|
||||||
api_key: 你的gemini web key
|
api_key: 你的gemini web key
|
||||||
model_name: "gemini-1.5-pro" # gemini-1.5-pro 是免费的
|
model_name: "gemini-2.0-flash"
|
||||||
|
http_proxy: "" #"http://127.0.0.1:10808"
|
||||||
|
https_proxy: "" #http://127.0.0.1:10808"
|
||||||
CozeLLM:
|
CozeLLM:
|
||||||
# 定义LLM API类型
|
# 定义LLM API类型
|
||||||
type: coze
|
type: coze
|
||||||
|
|||||||
@@ -1,14 +1,19 @@
|
|||||||
import google.generativeai as genai
|
import google.generativeai as genai
|
||||||
from core.utils.util import check_model_key
|
from core.utils.util import check_model_key
|
||||||
from core.providers.llm.base import LLMProviderBase
|
from core.providers.llm.base import LLMProviderBase
|
||||||
|
from config.logger import setup_logging
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
TAG = __name__
|
||||||
|
logger = setup_logging()
|
||||||
|
|
||||||
class LLMProvider(LLMProviderBase):
|
class LLMProvider(LLMProviderBase):
|
||||||
def __init__(self, config):
|
def __init__(self, config):
|
||||||
"""初始化Gemini LLM Provider"""
|
"""初始化Gemini LLM Provider"""
|
||||||
self.model_name = config.get("model_name", "gemini-1.5-pro")
|
self.model_name = config.get("model_name", "gemini-1.5-pro")
|
||||||
self.api_key = config.get("api_key")
|
self.api_key = config.get("api_key")
|
||||||
|
self.http_proxy=config.get("http_proxy")
|
||||||
|
self.https_proxy = config.get("https_proxy")
|
||||||
have_key = check_model_key("LLM", self.api_key)
|
have_key = check_model_key("LLM", self.api_key)
|
||||||
|
|
||||||
if not have_key:
|
if not have_key:
|
||||||
@@ -16,6 +21,19 @@ class LLMProvider(LLMProviderBase):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
# 初始化Gemini客户端
|
# 初始化Gemini客户端
|
||||||
|
# 配置代理(如果提供了代理配置)
|
||||||
|
self.proxies=None
|
||||||
|
if self.http_proxy is not "" or self.https_proxy is not "":
|
||||||
|
|
||||||
|
self.proxies = {
|
||||||
|
"http": self.http_proxy,
|
||||||
|
"https": self.https_proxy,
|
||||||
|
}
|
||||||
|
logger.bind(tag=TAG).info(f"Gemini set proxys:{self.proxies}")
|
||||||
|
# 使用猴子补丁修改 google-generativeai 库的请求会话
|
||||||
|
|
||||||
|
# 使用 session 对象配置 genai
|
||||||
|
|
||||||
genai.configure(api_key=self.api_key)
|
genai.configure(api_key=self.api_key)
|
||||||
self.model = genai.GenerativeModel(self.model_name)
|
self.model = genai.GenerativeModel(self.model_name)
|
||||||
|
|
||||||
@@ -46,35 +64,48 @@ class LLMProvider(LLMProviderBase):
|
|||||||
if content:
|
if content:
|
||||||
chat_history.append({
|
chat_history.append({
|
||||||
"role": role,
|
"role": role,
|
||||||
"parts": [content]
|
"parts": [{"text":content}]
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
# 获取当前消息
|
# 获取当前消息
|
||||||
current_msg = dialogue[-1]["content"]
|
current_msg = dialogue[-1]["content"]
|
||||||
|
|
||||||
# 创建新的聊天会话
|
# 构建请求体
|
||||||
chat = self.model.start_chat(history=chat_history)
|
request_body = {
|
||||||
|
"contents": chat_history + [{"role": "user", "parts": [{"text":current_msg}]}],
|
||||||
|
"generationConfig": self.generation_config
|
||||||
|
}
|
||||||
|
|
||||||
# 发送消息并获取流式响应
|
# 构建请求URL
|
||||||
response = chat.send_message(
|
url = f"https://generativelanguage.googleapis.com/v1beta/models/{self.model_name}:generateContent?key={self.api_key}"
|
||||||
current_msg,
|
|
||||||
stream=True,
|
|
||||||
generation_config=self.generation_config
|
|
||||||
)
|
|
||||||
|
|
||||||
# 处理流式响应
|
# 构建请求头
|
||||||
for chunk in response:
|
headers = {
|
||||||
if hasattr(chunk, 'text') and chunk.text:
|
"Content-Type": "application/json",
|
||||||
yield chunk.text
|
}
|
||||||
|
|
||||||
except Exception as e:
|
# 发送POST请求,经测试手动 request 无法使用 stream 模式,但是文本消息其实也很快,stream 与否也无所谓
|
||||||
error_msg = str(e)
|
if self.proxies:
|
||||||
logger.bind(tag=TAG).error(f"Gemini响应生成错误: {error_msg}")
|
response = requests.post(url, headers=headers, json=request_body, stream=False, proxies=self.proxies)
|
||||||
|
|
||||||
# 针对不同错误返回友好提示
|
|
||||||
if "Rate limit" in error_msg:
|
|
||||||
yield "【Gemini服务请求太频繁,请稍后再试】"
|
|
||||||
elif "Invalid API key" in error_msg:
|
|
||||||
yield "【Gemini API key无效】"
|
|
||||||
else:
|
else:
|
||||||
yield f"【Gemini服务响应异常: {error_msg}】"
|
response = requests.post(url, headers=headers, json=request_body, stream=False)
|
||||||
|
response.raise_for_status()
|
||||||
|
try:
|
||||||
|
data = response.json() # 直接解析JSON
|
||||||
|
if 'candidates' in data and data['candidates']:
|
||||||
|
yield data['candidates'][0]['content']['parts'][0]['text']
|
||||||
|
else:
|
||||||
|
yield "未找到候选回复。"
|
||||||
|
except json.JSONDecodeError as e:
|
||||||
|
yield f"JSON解码错误:{e}"
|
||||||
|
except Exception as e:
|
||||||
|
yield f"发生错误:{e}"
|
||||||
|
|
||||||
|
|
||||||
|
except requests.exceptions.RequestException as e:
|
||||||
|
yield f"请求失败:{e}"
|
||||||
|
except json.JSONDecodeError as e:
|
||||||
|
yield f"JSON解码错误:{e}"
|
||||||
|
except Exception as e:
|
||||||
|
yield f"发生错误:{e}"
|
||||||
|
|||||||
Reference in New Issue
Block a user