fix: AIPlanner에서 HTTP 429 오류 처리 및 재시도 로직 개선

- GLM API에서 HTTP 429 (Rate limit) 오류 발생 시, 'Retry-After' 헤더를 확인하여 적절한 대기 시간을 설정하도록 로직 추가
- 재시도 시 기본 백오프 대신 'Retry-After' 값이 있을 경우 이를 우선 적용하여 대기 시간 조정
- README.md에 변경 사항 반영
This commit is contained in:
kswdev0
2026-03-26 12:51:40 +09:00
parent c30fb426a8
commit 146e6b3982
2 changed files with 38 additions and 1 deletions

View File

@@ -240,6 +240,12 @@ class AIPlanner:
)
if _glm_debug_enabled():
print("[GLM][디버그] JSON-only repair 프롬프트 적용")
# 429 Rate limit이면 prompt 길이를 늘리면 안 되므로 repair_suffix를 끈다.
if isinstance(e, ConnectionError) and (
"429" in detail or "rate limit" in detail.lower() or "Too Many Requests" in detail
):
repair_suffix = ""
print(
f"[경고] GLM 처리 실패 (시도 {attempt+1}/3): "
f"{type(e).__name__} 재시도..."
@@ -247,7 +253,21 @@ class AIPlanner:
print(f" [GLM 원인] {detail}")
if _glm_debug_enabled():
traceback.print_exc()
time.sleep(2 + attempt * 3)
sleep_s = 2 + attempt * 3
if isinstance(e, ConnectionError) and (
"429" in detail or "rate limit" in detail.lower() or "Too Many Requests" in detail
):
# retry_after=...를 우선 사용하고, 없으면 기본 백오프를 적용한다.
m = re.search(r"retry_after=([0-9]+(?:\\.[0-9]+)?)s", detail)
ra = float(m.group(1)) if m else None
if ra is not None:
sleep_s = max(sleep_s, ra)
else:
# Rate limit은 보통 짧게 끝나지 않으므로 더 길게 기다린다.
sleep_s = max(sleep_s, 20 + attempt * 10)
if _glm_debug_enabled():
print(f"[GLM][디버그] 429 백오프 대기: {sleep_s:.1f}s")
time.sleep(sleep_s)
continue
print(f"[오류] GLM 처리 3회 실패. 상태 요약 기반 휴리스틱 폴백 사용.")
print(f" [GLM 원인] {detail}")
@@ -417,8 +437,24 @@ class AIPlanner:
body = e.read().decode("utf-8", errors="replace")
except Exception:
body = ""
retry_after: float | None = None
try:
# urllib.error.HTTPError는 headers를 들고 있는 경우가 많다.
ra = None
try:
ra = getattr(e, "headers", None).get("Retry-After")
except Exception:
ra = None
if ra:
ra_s = str(ra).strip()
retry_after = float(ra_s)
except Exception:
retry_after = None
raise ConnectionError(
f"GLM API HTTP {e.code}: {body[:1200]}"
+ (f" | retry_after={retry_after:.1f}s" if retry_after is not None else "")
) from e
@staticmethod