[TeamBlog] SSE_Streaming_TroubleShooting - 100-hours-a-week/9-team-Devths-WIKI GitHub Wiki
AI 챗봇 SSE 스트리밍 트러블슈팅 정리
AI 채팅 응답을 실시간으로 보여주기 위해 SSE(Server-Sent Events) 스트리밍을 도입한 과정, 겪었던 어려움·해결 방법·현재 상태·추후 고도화 전략을 정리한 문서입니다.
목차
1. 상황
- 배경: AI 챗봇(면접/채팅) 기능에서 LLM 응답을 한 번에 받지 않고, 토큰 단위로 실시간 전달하려는 요구가 있었음.
- 제약: 프론트 ↔ BE(Spring Boot) ↔ AI 서버(FastAPI) 3단 구조에서, 어디서 스트리밍을 시작·중계할지, 어떤 프로토콜을 쓸지 결정이 필요했음.
- 목표: 사용자가 질문을 보내면 응답이 순차적으로(스트리밍) 화면에 나타나도록 하고, 504/422 등 오류를 최소화하는 것.
작성 가이드:
- 프로젝트·서비스 맥락을 2~3문장으로 요약.
- “언제, 누가, 무엇을 위해 SSE를 도입하기로 했는지”를 한 줄로 적어도 됨.
2. SSE란?
- 정의: Server-Sent Events. 서버가 클라이언트에게 한 방향(서버 → 클라이언트)으로 이벤트 스트림을 보내는 HTTP 기반 프로토콜.
- 형식:
Content-Type: text/event-stream,event,data, 주석 라인(:) 등으로 이벤트를 구분. - 특징:
- HTTP 위에서 동작하므로 기존 인증·프록시·CORS 설정을 대부분 그대로 사용 가능.
- 브라우저
EventSourceAPI 또는fetch+ ReadableStream으로 수신. - 양방향 통신이 필요 없을 때 적합(채팅처럼 “사용자 → 서버”는 일반 API, “서버 → 사용자”만 스트리밍).
작성 가이드:
- 팀 내 공용 설명용으로 1~2문단이면 충분. 필요 시 MDN SSE 링크 추가.
3. SSE 스트리밍을 왜 썼는지
3.1 다른 기술과 비교
| 방식 | 특징 | 채팅/면접 스트리밍에 적합한가 |
|---|---|---|
| SSE | 서버→클라이언트 단방향, HTTP 기반, 재연결·이벤트 ID 지원 | ✅ 응답만 스트리밍하면 되므로 적합 |
| WebSocket | 양방향, 별도 프로토콜, 연결 유지 | ⚠️ 필요하지만 구현·인프라 부담 큼 |
| 폴링(Polling) | 주기적으로 API 호출 | ❌ 지연·부하 증가, 실시간성 부족 |
| 일반 REST | 요청 1회 → 응답 1회 | ❌ 전체 응답이 끝날 때까지 대기, 체감 지연 큼 |
3.2 선택 이유 요약
- 서버 → 클라이언트만 스트리밍하면 되고, 클라이언트 → 서버는 기존 REST(채팅 메시지 전송 등)로 처리 가능.
- HTTP 기반이라 방화벽·프록시·Spring/FastAPI 연동이 단순함.
- WebSocket보다 구현·운영 부담이 적고, “토큰이 조금씩 나오는” UX에 충분함.
작성 가이드:
- 위 표는 예시. 팀에서 실제로 검토한 내용(WebSocket 제외 이유 등)을 한두 줄씩 보강하면 좋음.
4. 개발한 커밋 링크들
4.1 백엔드 (BE)
- 저장소: 9-team-Devths-BE
- 상세 이력: SSE_스트리밍_오류처리_이력(BE).md
- 챗봇 응답 API + SSE 스트리밍 적용, 분석 연동, 404/500 대응 등 시간순 정리.
대표 커밋 예시
- f9f0bb4 — feat: 챗봇 응답 API 구현 및 SSE Streaming 적용 (#55)
4.2 AI 서버 (Model)
- 저장소: 9-team-Devths-AI
- 상세 이력: SSE_스트리밍_오류처리_이력(AI).md
- SSE 포맷 표준화, heartbeat, 422/504 대응, ChromaDB None 필터 등 시간순 정리.
대표 커밋 예시
- 9b712c3b — Add SSE headers to chat endpoint
- 08916a45 — Standardize SSE format and add ChromaDB None filtering
4.3 Notion 정리
- AI ChatBot SSE Commit — 팀 내 커밋·작업 정리용 Notion 페이지 (위 문서와 연계해 사용).
작성 가이드:
- 새 커밋이 생기면 위 “상세 이력” 문서와 Notion에 반영하면 일관성 유지에 좋음.
5. 디스코드 대화들 분석
- 기간: (예: 2026-01-xx ~ 2026-01-xx)
- 채널/스레드: (예: #ai-chatbot, #backend 등)
- 주요 논의:
- 504 타임아웃이 나는 구간(프록시 vs AI 서버 vs BE).
- 422 검증 오류 원인(스키마·필드 누락).
- SSE 포맷 불일치로 파싱 실패한 사례.
- ChromaDB/벡터 검색 오류와 스트리밍 중단 연관성.
- 결정 사항:
- SSE heartbeat 도입, 헤더 명시, 404 재시도, 리포트 모드 422 전용 처리 등 (상세는 6·7절과 연결).
작성 가이드:
- 개인정보·과도한 채팅 내용은 제외하고, “무엇을 논의했고 → 어떤 결론이 났는지” 위주로 1문단씩 정리하면 됨.
6. 어떤 어려움이 있었는지
-
504 Gateway Timeout
- LLM 응답이 늦을 때 중간에 데이터가 없어 프록시/로드밸런서가 연결을 끊음.
-
422 Validation Error
- 채팅/리포트 요청 시
model등 필드 누락·타입 불일치로 AI 서버에서 검증 실패.
- 채팅/리포트 요청 시
-
SSE 파싱/연결 문제
- 포맷 불일치·헤더 미설정으로 클라이언트/프록시가 스트림을 제대로 인식하지 못함.
-
ChromaDB/RAG 오류
metadata에None이 들어가 쿼리 예외 발생 → 스트리밍 중단.
-
BE ↔ AI 서버 연동
- 분석 API URI 매핑 실패, 404 미처리, 비동기 task 조회 시점(“비동기 작업을 찾을 수 없습니다”) 등.
작성 가이드:
- 실제로 겪은 이슈만 남기고, “증상 한 줄 + 원인 한 줄” 형태로 보강하면 좋음.
7. 어떻게 해결했는지
| 어려움 | 해결 방향 | 관련 커밋/문서 |
|---|---|---|
| 504 타임아웃 | SSE heartbeat 도입, 로깅 강화 | AI: 4a06f0e2, 이력(AI) §4 |
| 422 검증 오류 | Swagger 예시·스키마 정리, 리포트 모드 전용 처리 | AI: 108cbc79, fc88d09b, b38257a1 |
| SSE 파싱/연결 | SSE 포맷 표준화, Content-Type 등 헤더 명시 |
AI: 08916a45, 9b712c3b |
| ChromaDB None | 쿼리 전 None 제거·필터링 | AI: 08916a45 |
| BE 분석 연동 | URI 매핑 수정, 404 재시도, taskId 통합, DB 커밋 전 task 조회 수정 | BE: dc10953, c9f4520, 342aced, 0ca1689, 이력(BE) §5 |
작성 가이드:
- “어떤 설정/코드/배포 변경으로 해결했는지” 한 줄씩 추가하면 나중에 재발 방지에 도움됨.
8. 현재는 어떤 상태인지
- 스트리밍:
- (예: BE → 프론트 SSE 중계 정상 동작, AI 서버 heartbeat 적용 완료.)
- API:
- (예: 채팅/리포트 모드 스키마 정리됨, 분석 API 404 재시도·taskId 통합 반영.)
- 알려진 제한:
- (예: Nginx 버퍼링 시 스트리밍 지연 가능성, 특정 브라우저에서 EventSource 재연결 이슈 등.)
- 모니터링/로깅:
- (예: taskId 로깅, Log sanitized 적용, 504/422 구간 로그 보강.)
작성 가이드:
- “지금 기준으로 무엇이 되고 / 무엇이 아직 불안한지”를 2~3문장으로 적으면 됨.
9. 추후 고도화 전략
-
안정성
- 스트리밍 구간 재연결(backoff), 타임아웃 설정 정리, 에러 이벤트 포맷 통일.
-
관찰성
- SSE 이벤트 타입별 메트릭(지연, 실패 횟수), 대시보드/알람 연동.
-
프로토콜
- 필요 시 WebSocket 검토(양방향·저지연 요구 시), SSE와 공존 전략.
-
클라이언트
- EventSource fallback, 네트워크 끊김 시 재연결·메시지 복구 UX.
-
문서·운영
- Runbook(504/422 대응 절차), 신규 멤버용 SSE 연동 가이드.
작성 가이드:
- 우선순위(예: P0/P1)나 담당 레이어(BE/AI/프론트)를 표시해 두면 실행 계획 세우기 좋음.
문서 이력
| 날짜 | 작성/수정 | 내용 |
|---|---|---|
| (작성일) | 초안 작성, 목차·가이드 확정 |