feat: improve retry mechanism with jitter and longer delays
- Increase max retry attempts from 3 to 5 - Extend max delay from 10s to 60s for better handling of persistent 529 errors - Add jitter (random 0-0.5s delay) to avoid synchronized retries - Based on Cursor IDE blog best practices for handling Claude API 529 errors
This commit is contained in:
parent
42ef175ddb
commit
edced35f70
|
|
@ -2,6 +2,7 @@
|
|||
import time
|
||||
import json
|
||||
import logging
|
||||
import random
|
||||
from tenacity import (
|
||||
retry,
|
||||
stop_after_attempt,
|
||||
|
|
@ -112,18 +113,29 @@ def create_research_manager(llm, memory):
|
|||
請提供專業且可執行的投資決策報告。"""
|
||||
|
||||
# 定義帶重試機制的 LLM 調用函數
|
||||
# 只針對 Anthropic OverloadedError (529) 進行重試
|
||||
# 配置:最多 3 次重試,指數退避(2、4、8 秒)
|
||||
# 基於 Cursor IDE 博客建議的最佳實踐:
|
||||
# 1. 使用指數退避策略(exponential backoff)
|
||||
# 2. 添加隨機因子(jitter)避免多個客戶端同步重試
|
||||
# 3. 增加重試次數和最大延遲時間
|
||||
import random
|
||||
|
||||
@retry(
|
||||
retry=retry_if_exception_type(OverloadedError),
|
||||
wait=wait_exponential(multiplier=1, min=2, max=10),
|
||||
stop=stop_after_attempt(3),
|
||||
wait=wait_exponential(multiplier=1, min=2, max=60), # 增加最大延遲到 60 秒
|
||||
stop=stop_after_attempt(5), # 增加重試次數到 5 次
|
||||
before_sleep=before_sleep_log(logger, logging.WARNING)
|
||||
)
|
||||
def invoke_llm_with_retry(llm_instance, prompt_text):
|
||||
"""
|
||||
調用 LLM 並在遇到 529 錯誤時自動重試。
|
||||
|
||||
使用指數退避策略加隨機因子(jitter):
|
||||
- 第 1 次重試:等待 2-4 秒(2 * 2^0 + jitter)
|
||||
- 第 2 次重試:等待 4-8 秒(2 * 2^1 + jitter)
|
||||
- 第 3 次重試:等待 8-16 秒(2 * 2^2 + jitter)
|
||||
- 第 4 次重試:等待 16-32 秒(2 * 2^3 + jitter)
|
||||
- 第 5 次重試:等待 32-60 秒(2 * 2^4 + jitter,最大 60 秒)
|
||||
|
||||
Args:
|
||||
llm_instance: LLM 實例
|
||||
prompt_text: 提示文本
|
||||
|
|
@ -132,8 +144,13 @@ def create_research_manager(llm, memory):
|
|||
LLM 的回應
|
||||
|
||||
Raises:
|
||||
OverloadedError: 如果 3 次重試後仍然失敗
|
||||
OverloadedError: 如果 5 次重試後仍然失敗
|
||||
"""
|
||||
# 添加小量隨機延遲(jitter)避免同步重試
|
||||
jitter = random.uniform(0, 0.5)
|
||||
if jitter > 0:
|
||||
time.sleep(jitter)
|
||||
|
||||
logger.info("正在調用 Research Manager LLM...")
|
||||
return llm_instance.invoke(prompt_text)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue