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():