From 20691b5057b27a5783d17cbf4488e420626243b0 Mon Sep 17 00:00:00 2001 From: gahusb Date: Sun, 24 May 2026 15:43:27 +0900 Subject: [PATCH] =?UTF-8?q?fix(tarot):=20Claude=20=EC=9D=91=EB=8B=B5=20?= =?UTF-8?q?=EC=8B=9C=EA=B0=84=20=EB=8B=A8=EC=B6=95=20+=20nginx=20timeout?= =?UTF-8?q?=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 504 Gateway Timeout 근본 원인은 DSM Reverse Proxy의 60s 기본 timeout (agent-office는 200 OK 정상 응답했으나 client 도달 전 DSM이 끊음). 사용자 측 DSM Reverse Proxy timeout 늘리기 별도 필요. 코드 측 대응: - pipeline.py max_tokens 2048 → 1400 (응답 시간 단축, 3-card spread 충분) - pipeline.py에 latency_ms·tokens 로그 출력 (모니터링) - nginx /api/agent-office/에 proxy_send_timeout 300s, proxy_connect_timeout 60s 추가 (proxy_read_timeout은 WebSocket 위해 86400s 유지) Co-Authored-By: Claude Opus 4.7 (1M context) --- agent-office/app/tarot/pipeline.py | 15 +++++++++++---- nginx/default.conf | 2 ++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/agent-office/app/tarot/pipeline.py b/agent-office/app/tarot/pipeline.py index 7b5ef94..97e667c 100644 --- a/agent-office/app/tarot/pipeline.py +++ b/agent-office/app/tarot/pipeline.py @@ -1,5 +1,6 @@ """Tarot 파이프라인 — Claude Sonnet 호출 + 파싱 폴백 + reroll 1회.""" import json +import logging import time from typing import Any, Dict @@ -12,6 +13,9 @@ from ..config import ( TAROT_COST_OUTPUT_PER_M, TAROT_TIMEOUT_SEC, ) + + +logger = logging.getLogger("agent-office.tarot") from ..models import TarotInterpretRequest from .prompt import SYSTEM_PROMPT, build_user_message from .schema import validate_interpretation @@ -62,7 +66,7 @@ async def _call_claude(user_text: str, feedback: str = "") -> tuple[dict, dict, user_text = f"이전 응답이 다음 이유로 거절됨: {feedback}\n올바른 스키마(시스템 지침)로 다시 응답.\n\n{user_text}" payload = { "model": TAROT_MODEL, - "max_tokens": 2048, + "max_tokens": 1400, # 응답 시간 단축 — 3-card spread evidence·interactions 포함 충분 "system": [{"type": "text", "text": SYSTEM_PROMPT, "cache_control": {"type": "ephemeral"}}], "messages": [{"role": "user", "content": [{"type": "text", "text": user_text}]}], @@ -82,11 +86,14 @@ async def _call_claude(user_text: str, feedback: str = "") -> tuple[dict, dict, raw_text = "".join( b.get("text", "") for b in resp.get("content", []) if b.get("type") == "text" ) - parsed = _extract_json(raw_text) usage = resp.get("usage", {}) or {} + tokens_in = int(usage.get("input_tokens", 0) or 0) + tokens_out = int(usage.get("output_tokens", 0) or 0) + logger.info("tarot claude call: latency=%dms, in=%d, out=%d", latency_ms, tokens_in, tokens_out) + parsed = _extract_json(raw_text) meta = { - "tokens_in": int(usage.get("input_tokens", 0) or 0), - "tokens_out": int(usage.get("output_tokens", 0) or 0), + "tokens_in": tokens_in, + "tokens_out": tokens_out, "latency_ms": latency_ms, } return parsed, meta, raw_text diff --git a/nginx/default.conf b/nginx/default.conf index f32c9a0..6bc6c6d 100644 --- a/nginx/default.conf +++ b/nginx/default.conf @@ -357,6 +357,8 @@ server { proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_read_timeout 86400s; + proxy_send_timeout 300s; + proxy_connect_timeout 60s; proxy_pass http://$agent_office_backend$request_uri; }