모호한 문제를 운영 가능한 제품으로.

복잡한 요구사항을 NestJS와 React 기반 제품으로 연결하고, 비동기 작업과 외부 API의 실패를 BullMQ, Redis Lua, 상태 머신과 반복 측정으로 다룹니다.

자이닉스 재직 중 2024.11 — 현재
모호한 요청이 운영 가능한 제품이 되는 시스템 흐름 문제 정의에서 시작해 작업 수용량, 추론 실행 경계, 공유 상태와 관측을 거쳐 사용 가능한 제품으로 이어지는 아키텍처 다이어그램 AMBIGUOUS problem / 01 ADMISSION queue / 02 INFERENCE adapter / 03 STATE stream / 04 OBSERVE trace / 05 SHIP 06 실패는 예외가 아니라 다뤄야 할 상태입니다.
01 요청 수용량과 inference backend의 차이를 제품 경계에서 분리하고, 실패 원인은 trace로 추적합니다.

어떤 코드를 썼고,
무엇이 달라졌는지.

운영 범위와 모델 비용, 브라우저 성능, 생성 품질을 각각 재현 가능한 조건에서 확인했습니다. 숫자가 없는 개선은 구조 변화로 따로 표시합니다.

01 기관별 RAG 운영
26

내부용 3개를 제외한 실제 배포 환경

02 프롬프트 캐시 검증
−37%

15,232개 스레드의 턴 분포로 정한 Claude 4턴 정책

03 브라우저 부하 개선
96.5%

CPU 4× · Slow 4G · 6개 탭을 10분간 측정

04 시간 민감 알림
2,000명

3개 과제 동시 마감 · 2분 안에 전달

AI Commons · Admission control

서버마다 달랐던 요청 한도.
Redis에서 함께 제어했습니다.

Vertex AI 전환 뒤 동시 이미지 생성에서 429가 반복됐습니다. 외부 모델 API를 처리 용량과 실패 특성이 다른 실행 백엔드로 봤습니다. 여러 서버의 워커가 전체 RPM과 감속 상태를 공유하지 못하는 것이 핵심이었습니다.

  • 가설원자적 permit과 적응 제어로 모든 워커가 백엔드 용량에 맞춰 함께 감속·복구한다
  • 구현BullMQ 분리 · Redis Lua permit · wave ID · AIMD · Circuit Breaker
  • 확인429/5xx 복구 경로 분리 · Redis 장애 시 local fallback
  • 다음 측정429 비율 · 복구 시간 · 대기 시간 · 처리량
해결 과정 보기 ↗
Distributed execution / control plane shared state
Multi-server workers Failure-aware flow
  1. 01APIenqueue
  2. 02Queuejob type
  3. 03PermitRedis Lua
  4. 04Workerconcurrency
  5. 05ProviderAI / GPU
  6. 06Statepersist
Failure control
Retry / job state Wave ID / dedupe AIMD / 4-state FSM Circuit / fallback
ATOMICpermit lifecycle
SHAREDbackoff state
LOCALRedis fallback
429와 5xx를 다른 실패 경로로 분리하고, 여러 워커가 하나의 제한 상태를 공유하게 했습니다.

AI Chat / Tutor · RAG request pipeline

누가 무엇을 검색하는지,
요청이 시작될 때 고정했습니다.

조직과 과정마다 다른 자료를 쓰는 RAG에서는 모델 호출 전에 조회 가능한 knowledge base를 정해야 했습니다. 인증에서 만든 request context를 검색과 quota 계산까지 전달하고, retrieval engine과 model provider를 adapter 뒤에 분리했습니다.

  • Retrievalrequest context → tenant/course scope → isolated corpus
  • Generationinference adapter → GPT/Claude/Gemini → SSE stream
  • 확인과 다음 단계26개 기관 환경 · 29개 운영 브랜치 · 다음 평가: 근거 정확도, 지연, 비용
해결 과정 보기 ↗
RAG / request pipeline 범위 고정
요청 / 질문 “이번 주차의 핵심 개념을 설명해줘.” 요청 맥락 포함
01Contexttenant · role
02Scopeknowledge base
03Retrieveevidence
04Generateprovider · SSE
Knowledge / 운영 중tenant · course scope → retrieve → generate
Brain / 설계 중extract → reconcile → scoped recall → forget
강의자료는 권한이 있는 지식으로, 사용자 기억은 조회·삭제할 수 있는 별도 영역으로 다룹니다.

429.
문맥 단절.
Long Task.

01분산 시스템

429를 모델 API 오류가 아닌 분산 제어 문제로 정의했습니다.

워커별 semaphore 대신 Redis Lua permit과 wave ID로 원자적 공유 상태를 만들고, AIMD와 Circuit Breaker가 429와 5xx를 서로 다른 경로로 복구하게 했습니다.

다음 확인 / 다음 측정: 동시 사용자별 429 비율 · 복구 시간 · 처리량

atomic permit · shared backoff · local fallback ↗
02품질과 속도의 선택

더 빠른 68초 대신, 더 정확한 162초를 선택했습니다.

배치 병렬화의 문맥 단절을 원인으로 보고 previous_response_id를 잇는 순차 실행으로 바꿨습니다. 첫 결과를 먼저 노출해 늘어난 완료 시간을 사용성으로 보완했습니다.

다음 확인 / 다음 측정: 주제·페이지 수별 반복 · 첫 응답 시간 · 실패율

single 10-page case · 68→162s · duration 62→99% ↗
03성능 개선

화면 최적화를 API 호출 구조까지 거슬러 올라갔습니다.

렌더링만 손보지 않고 탭별 중복 조회와 순차 네트워크 요청을 함께 줄였습니다. 6개 탭을 연 상태에서 탭 평균 Long Task와 총 블로킹 시간을 다시 측정했습니다.

다음 확인 / 다음 측정: 변경별 기여도 분리 · 저사양 기기 프로파일

136→4.7 tasks · blocking 10.85→0.57s / 6 tabs ↗

제품의 실행 기록이,
다음 실험의 입력이 됩니다.

제품에서 답하지 못한 질문을 공개 데이터와 작은 실험으로 다시 확인합니다. 이미 아는 것과 새로 검증할 것을 분리해 기록합니다.

진행 중인 실험 보기
01 / Retrieval quality진행 중

상용 RAG의 검색 품질을 같은 기준으로 비교합니다

과목·조직별 검색 범위와 멀티 모델 경로를 운영했습니다. 이제 같은 공개 질문으로 BM25, dense, hybrid와 reranking을 비교하고 인용 정확도·지연·비용을 하나의 실행 기록에 담습니다.

PROOF → Recall@5 · nDCG@10 · citation · p95 · cost
02 / Brain memory설계 완료

대화가 바뀌어도 사용자가 통제하는 기억

현재는 한 thread 안에서만 맥락이 이어집니다. Brain은 기억할 사실을 원자적으로 저장하고 충돌을 갱신하며, 사용자·제품·과목 scope와 삭제 요청을 지키도록 설계했습니다.

PROOF → write precision · conflict resolution · forget · token overhead
03 / Workload Studio실제 GPU 검증

GPU 실행·정리와 에이전트 판단을 검증합니다

RTX 4090에서 요청 준비부터 측정·결과 저장·자동 삭제까지 확인했습니다. 규칙과 OpenAI 정책을 동일 서버 6세션에서 비교하고, 생성 미확정·취소·새로고침 복구를 다뤘습니다. 다른 모델·GPU와 NPU는 후속 검증입니다.

VERIFIED → GPU lifecycle · 6-session policy evaluation · recovery