feat(chat): 添加调用重试机制提升接口稳定性

- 引入 tenacity 库实现自动重试功能
- 在调用 OpenAI 接口的 call 方法上增加重试装饰器
- 设定重试次数、指数退避等待策略及日志记录
- 调整流式和非流式响应处理逻辑,保证重试生效
- 在 pyproject.toml 中添加 tenacity 依赖声明
This commit is contained in:
Wenjie Zhang 2025-09-19 01:10:20 +08:00
parent 347e7c5807
commit 63cceb4562
2 changed files with 26 additions and 14 deletions

View File

@ -55,6 +55,7 @@ dependencies = [
"minio>=7.2.7", "minio>=7.2.7",
"Pillow>=10.5.0", "Pillow>=10.5.0",
"pymysql>=1.1.0", "pymysql>=1.1.0",
"tenacity>=8.0.0",
] ]
[tool.ruff] [tool.ruff]
line-length = 120 # 代码最大行宽 line-length = 120 # 代码最大行宽

View File

@ -2,6 +2,7 @@ import os
import traceback import traceback
from openai import OpenAI from openai import OpenAI
from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type, before_sleep_log, after_log
from src import config from src import config
from src.utils import get_docker_safe_url, logger from src.utils import get_docker_safe_url, logger
@ -15,19 +16,36 @@ class OpenAIBase:
self.model_name = model_name self.model_name = model_name
self.info = kwargs self.info = kwargs
@retry(
stop=stop_after_attempt(3),
wait=wait_exponential(multiplier=1, min=1, max=10),
retry=retry_if_exception_type((Exception,)),
before_sleep=before_sleep_log(logger, log_level="WARNING"),
reraise=True
)
def call(self, message, stream=False): def call(self, message, stream=False):
if isinstance(message, str): if isinstance(message, str):
messages = [{"role": "user", "content": message}] messages = [{"role": "user", "content": message}]
else: else:
messages = message messages = message
try:
if stream: if stream:
return self._stream_response(messages) response = self._stream_response(messages)
else: else:
return self._get_response(messages) response = self._get_response(messages)
except Exception as e:
err = (
f"Error streaming response: {e}, URL: {self.base_url}, "
f"API Key: {self.api_key[:5]}***, Model: {self.model_name}"
)
logger.error(err)
raise Exception(err)
return response
def _stream_response(self, messages): def _stream_response(self, messages):
try:
response = self.client.chat.completions.create( response = self.client.chat.completions.create(
model=self.model_name, model=self.model_name,
messages=messages, messages=messages,
@ -37,13 +55,6 @@ class OpenAIBase:
if len(chunk.choices) > 0: if len(chunk.choices) > 0:
yield chunk.choices[0].delta yield chunk.choices[0].delta
except Exception as e:
err = (
f"Error streaming response: {e}, URL: {self.base_url}, "
f"API Key: {self.api_key[:5]}***, Model: {self.model_name}"
)
logger.error(err)
raise Exception(err)
def _get_response(self, messages): def _get_response(self, messages):
response = self.client.chat.completions.create( response = self.client.chat.completions.create(