feat: 统一LLM错误处理并添加系统错误回复配置

在多个LLM提供者中移除try-catch块,将错误处理统一到connection.py的流处理层
添加system_error_response配置项,支持自定义系统错误时的回复内容
在意图识别和流处理中捕获异常时返回配置的错误回复,避免硬编码错误信息

Fixes #2075
This commit is contained in:
huozaimengli
2026-01-25 16:48:01 +08:00
parent 275102f5b7
commit 6ae0af278b
13 changed files with 542 additions and 551 deletions
@@ -15,55 +15,49 @@ class LLMProvider(LLMProviderBase):
self.api_url = f"{self.base_url}/api/conversation/process" # 拼接完整的 API URL
def response(self, session_id, dialogue, **kwargs):
try:
# home assistant语音助手自带意图,无需使用xiaozhi ai自带的,只需要把用户说的话传递给home assistant即可
# home assistant语音助手自带意图,无需使用xiaozhi ai自带的,只需要把用户说的话传递给home assistant即可
# 提取最后一个 role 为 'user' 的 content
input_text = None
if isinstance(dialogue, list): # 确保 dialogue 是一个列表
# 逆序遍历,找到最后一个 role 为 'user' 的消息
for message in reversed(dialogue):
if message.get("role") == "user": # 找到 role 为 'user' 的消息
input_text = message.get("content", "")
break # 找到后立即退出循环
# 提取最后一个 role 为 'user' 的 content
input_text = None
if isinstance(dialogue, list): # 确保 dialogue 是一个列表
# 逆序遍历,找到最后一个 role 为 'user' 的消息
for message in reversed(dialogue):
if message.get("role") == "user": # 找到 role 为 'user' 的消息
input_text = message.get("content", "")
break # 找到后立即退出循环
# 构造请求数据
payload = {
"text": input_text,
"agent_id": self.agent_id,
"conversation_id": session_id, # 使用 session_id 作为 conversation_id
}
# 设置请求头
headers = {
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json",
}
# 构造请求数据
payload = {
"text": input_text,
"agent_id": self.agent_id,
"conversation_id": session_id, # 使用 session_id 作为 conversation_id
}
# 设置请求头
headers = {
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json",
}
# 发起 POST 请求
response = requests.post(self.api_url, json=payload, headers=headers)
# 发起 POST 请求
response = requests.post(self.api_url, json=payload, headers=headers)
# 检查请求是否成功
response.raise_for_status()
# 检查请求是否成功
response.raise_for_status()
# 解析返回数据
data = response.json()
speech = (
data.get("response", {})
.get("speech", {})
.get("plain", {})
.get("speech", "")
)
# 解析返回数据
data = response.json()
speech = (
data.get("response", {})
.get("speech", {})
.get("plain", {})
.get("speech", "")
)
# 返回生成的内容
if speech:
yield speech
else:
logger.bind(tag=TAG).warning("API 返回数据中没有 speech 内容")
except RequestException as e:
logger.bind(tag=TAG).error(f"HTTP 请求错误: {e}")
except Exception as e:
logger.bind(tag=TAG).error(f"生成响应时出错: {e}")
# 返回生成的内容
if speech:
yield speech
else:
logger.bind(tag=TAG).warning("API 返回数据中没有 speech 内容")
def response_with_functions(self, session_id, dialogue, functions=None):
logger.bind(tag=TAG).error(