처음 문제가 발생한 지점부터 작성하다보니 두서가 없는 글이 된 것 같다… 이번 시리즈 작성이 끝나면 아웃라인을 수정해보도록 하겠다. 이번편은 아마 문제상황 제시만 하다 끝날 것 같다. 그리고 그림 열심히 그렸다. ..
문제상황
감상문을 LLM으로 분석해주는 웹페이지를 MVP 개발중이다. 이 과정에서 ‘응답을 어떻게 받아서 어떻게 보여줄 것인가?’에 대한 문제로 구현 방향과 구조를 바꿔가면서 아주 삽질을 하고 있다.

기본적인 골격은 프론트엔드(사용자 웹) ↔ 웹 서버 ↔ AI 서버의 구조를 유지하고 있다.
서비스 페이지와 기능 검토용 어드민 페이지를 개발하면서, 프론트엔드와 웹 서버 사이에 각 페이지의 특성에 따라 HTTP REST API 와 WebSocket 중 서로 다른 통신 방식을 적용하게 되었다.
1. chatbot UI와 websocket 통신
아래 이미지는 각 세션별로 실시간으로 입력한 감상문이 처리됨을 강조하기 위해 프로토타입으로 제작된 테스트 페이지다. 사용자가 감상문을 입력하면 서버는 처리 상태와 분석 결과를 실시간으로 여러 번에 나눠서 push하며, 프론트에서는 이를 바로바로 채팅 메시지로 렌더링한다. UX 측면에서 처리 과정을 실시간으로 보여주고, 대기 시간에 대한 피드백도 자연스럽게 줄 수 있다는 장점이 있다.

웹
- 사용자는 감상문을 입력한다.
- 서버는 ‘처리 중’ 메시지를 먼저 보내고, 이후 분석 결과(키워드, 분위기 등)를 차례로 답장 메시지 형태로 전달한다.
- 모든 메시지는 동일한 세션 내에서 아래로 쌓이면서 채팅 대화처럼 표시된다.
서버
- user web과 Server는 WebSocket으로 실시간 양방향 연결된다.
- 서버는 각 사용자의 세션을 식별하여, 해당 세션에 속한 메시지를 순서대로 관리하고 전달한다.
- 처리 상태와 분석 결과를 세션 단위로 즉시 push하여, 프론트에서 실시간 메시지로 전송한다
2. form UI와 REST API 호출
아래 이미지는 Form 형태의 UI에서 REST API를 통해 한 번에 감상문 전체 결과를 받아오도록 설계한 서비스 페이지 프로토타입이다. 사용자가 감상문과 기본 정보를 입력하면, 프론트엔드는 서버에 REST API 요청을 보내고, 서버는 분석이 끝난 후 요약, 심리분석, 추천 목록 등 다양한 결과를 한 번에 응답으로 반환한다. 전체 결과를 빠르고 일괄적으로 받아올 수 있어, 직관적이고 단순한 UX를 제공한다는 장점이 있다.

웹
- 사용자는 영화제목과 감상문 등 기본 정보를 입력한다.
- “분석하기” 버튼을 누르면 서버에 요청이 전송된다.
- 서버로부터 전체 결과(이미지, 요약, 심리분석, 추천목록 등)를 한 번에 받아와 각 영역에 나눠서 표시한다.
서버
- user web과 Server는 REST API로 통신한다.
- 프론트에서 요청을 보내면, 서버는 감상문을 분석한 뒤 전체 결과를 한 번에 응답으로 반환한다.
- 전체 결과가 준비될 때까지 대기 후, 단일 응답으로 모든 정보를 전달한다.
3. 복잡해진 설계와 고민…
처음에는 채팅 서비스와 유사하게 세션을 개설한 뒤, 세션 내에서 요청을 보내고 실시간으로 답변을 받는 구조로 구현했다. 이때는 STT(음성 인식) 기능까지 염두에 두고 있었기 때문에, 자연스럽게 WebSocket을 채택해서 서버와 실시간으로 메시지를 주고받는 방식을 택했다.
그런데!!! 개발 품을 줄이기 위해 STT 기능을 홀드하게 되었다. 따라서 폼 형식이든 채팅 형식이든 한 번의 메시지에 하나의 응답을 받을 거면 WebSocket이 아니라 REST API로 통일하는 게 더 효율적이지 않겠냐는 논의가 나왔다.
그런데!!! LLM 기능 검토 페이지에서 REST API를 사용해보니, LLM의 응답이 길어질 때 타임아웃 문제가 생겨 다소 복잡한 과정을 거쳐야만 응답을 받아올 수 있었다. 그래서 프론트엔드와 백엔드 간의 실시간 통신과 안정성을 고려할 때 WebSocket이 더 적합하다는 쪽으로 의견이 모였다.
그런데!!! 개발팀에서 MVP 개발을 진행하기로 했고, 이때 임시 UI는 REST API와 궁합이 잘 맞는 폼 형식으로 우선 채택되었다.
그런데!!! UX 측면에서는 결과를 한 글자(토큰)씩 실시간으로 출력하는 게 더 좋지 않겠냐는 의견이 나왔다. 이건 확실히 WebSocket을 써야 구현할 수 있어 보인다.
정리를 해서 채팅 형과 폼 형, 실시간 처리와 일괄응답, REST API와 WebSocket 구조가 섞인게 좀 보이는데… 실시간으로 고민하던 상황에서는 매우 헷갈렸음.
들어가기에 앞서… 외부 API (치트키)
사실! 지금 발생하는 문제를 해결하는 가장 쉬워보이는 방법이 있다. 바로바로~~~ 외부 AI API 서비스를 쓰기.
다른 팀에서는 어떻게 해결하는거지? 궁금해서 사례를 찾아다녔는데 그냥 돈주고 외부 API를 끌어와서 사용하는 프로젝트가 대부분이었다. 그런데 우리팀은 준부동산인 GPU가 좋은 데스크탑이 있고(이미 자산이 많이 투자됨.) 여기에 local로 AI 서버를 별도로 구축하기로 한 것이 시작이었다.
아무튼! 외부 AI API(예: GPT API, Gemini API 등)를 사용할 때는 단순히 API를 통해 요청(prompt)을 보내고, 응답(response)을 받기만 하면 된다.

이때 AI 모델 서버는 완전히 블랙박스처럼 동작하고, 보통 중간에 API 서버를 두고 요청을 가공하거나 캐싱, 프롬프트 최적화 등만 추가로 신경 쓰면 되기 때문에 서비스 개발에 집중할 수 있다.

우리는 이 블랙박스 구조를 직접 구현해야 하다보니 고민이 많아졌다… 가 문제상황이었다.
'DevLog' 카테고리의 다른 글
| [개발노트] 둥동 제작기 - 둥지동지 2.0.0 개발노트 (0) | 2025.10.17 |
|---|---|
| 블챌 제출 시스템 개편 (4) | 2025.08.09 |
| 프로젝트 관리 (2) | 2025.07.19 |
| procedural 방식의 패턴 생성(2) (1) | 2025.07.03 |
| LLM 인터페이스 설계 (1) | 2025.06.28 |