From ea6b2cf35121f05504820d7adf681fdfbb1fc8c7 Mon Sep 17 00:00:00 2001 From: Hyungi Ahn Date: Sat, 2 May 2026 07:25:14 +0900 Subject: [PATCH] =?UTF-8?q?fix(study):=20Phase=204-B=20v1=20prompt=20cap?= =?UTF-8?q?=20=E2=80=94=20=ED=81=B0=20=EC=84=B8=EC=85=98=20LLM=20timeout?= =?UTF-8?q?=20=EB=B0=A9=EC=96=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 세션 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) --- app/workers/study_session_analysis_worker.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/app/workers/study_session_analysis_worker.py b/app/workers/study_session_analysis_worker.py index bcbe3a7..7571150 100644 --- a/app/workers/study_session_analysis_worker.py +++ b/app/workers/study_session_analysis_worker.py @@ -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():