fix(study): Phase 4-B v1 prompt cap — 큰 세션 LLM timeout 방어

세션 1 (wrong+unsure 84건) 에서 prompt 가 23K자 넘어 30초 timeout. plan 가정
(5~30건) 대로 MAX_ATTEMPTS_IN_PROMPT=30 cap 추가. 가장 최근 attempts 우선
(answered_at asc 정렬의 뒤쪽). 기존 valid_attempts 카운트 검증 (5건 미만 skip)
은 그대로 유지 — cap 은 prompt 입력만, 검증은 전체 기준.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Hyungi Ahn
2026-05-02 07:25:14 +09:00
parent 6785d53d3d
commit ea6b2cf351
+11 -4
View File
@@ -42,6 +42,9 @@ logger = logging.getLogger(__name__)
LLM_TIMEOUT_S = 30.0
# wrong/unsure 5 미만은 분석 의미 X — insufficient_attempts skip
MIN_ATTEMPTS_FOR_ANALYSIS = 5
# 큰 세션 (84건 등) 에서 prompt 과대 + LLM timeout 방어. 가장 최근 attempt 기준 cap.
# plan 가정 5~30건 — 30건이면 prompt 6~8K 자 안에 들어옴.
MAX_ATTEMPTS_IN_PROMPT = 30
# 응답 800자 hard cap (말줄임표 포함 ≤ 801)
SUMMARY_MAX_CHARS = 800
@@ -210,8 +213,12 @@ async def run_session_analysis_job(session: AsyncSession, job: StudyQuizSessionJ
job.completed_at = now()
return
# 3. RAG (documents 만, 없어도 호출 진행)
questions = [a["question"] for a in valid_attempts]
# 3. prompt 입력 cap — 큰 세션 (84건 등) 에서 prompt 과대 방지.
# 가장 최근 attempts 우선 (이미 answered_at asc 정렬되어 있어 끝쪽 = 최근)
prompt_attempts = valid_attempts[-MAX_ATTEMPTS_IN_PROMPT:]
# 4. RAG (documents 만, 없어도 호출 진행)
questions = [a["question"] for a in prompt_attempts]
ctx_docs = await gather_session_summary_context(
session,
user_id=qs.user_id,
@@ -219,8 +226,8 @@ async def run_session_analysis_job(session: AsyncSession, job: StudyQuizSessionJ
wrong_unsure_questions=questions,
)
# 4. prompt 조립 + MLX
prompt = _render_session_summary_prompt(qs, valid_attempts, ctx_docs)
# 5. prompt 조립 + MLX
prompt = _render_session_summary_prompt(qs, prompt_attempts, ctx_docs)
ai_client = AIClient()
try:
async with get_mlx_gate():