LangChain을 프로덕션으로: 멀티 테넌시, 지연 로딩 메모리, 대규모 추적 문제를 해결하는 방법
Moving LangChain to production: How we solve multi-tenancy, lazy-loading memory, and tracing at scale.
핵심 요약
LangChain의 프로덕션 배포 시 발생하는 멀티 테넌시, 메모리, 추적 문제를 해결하는 오픈소스 프레임워크 LongTrainer 소개.
- 멀티 테넌시 — bot_id를 활용한 엄격한 데이터 격리로 클라이언트 간 간섭 방지.
- 메모리 최적화 — 채팅 기록을 MongoDB에 저장하고 필요할 때만 불러오는 지연 로딩 방식 도입.
- 네이티브 추적 — 외부 SaaS 없이도 검색 및 LLM 호출 과정을 직접 기록하는 LongTracer 구현.
- 환각 탐지 — NLI 기반의 CitationVerifier를 통해 응답의 근거를 실시간으로 검증.
(GitHub 저장소와 문서 링크는 스팸 필터를 피하기 위해 첫 번째 댓글에 있습니다)
LangChain은 0에서 1단계까지는 훌륭하지만, B2B 환경에 배포하면 특정 인프라 병목 현상이 발생합니다.
우리 팀은 지난 2년 동안 이러한 배포 격차를 해결하기 위해 LongTrainer라는 오픈소스 프로덕션 래퍼를 유지해 왔습니다. 최근 v1.3.0을 출시했고, 프로덕션 RAG의 핵심 과제들을 우리가 어떻게 처리하고 있는지 공유하고자 합니다.
우리가 발견한 주요 문제와 이 아키텍처가 이를 해결하는 방법은 다음과 같습니다:
1. 멀티 테넌트 벡터 문제
문제: 단일 백엔드에서 수십 개의 클라이언트로 확장할 때, 메타데이터 필터링에만 의존하여 클라이언트 데이터를 분리하는 것은 항상 충분히 안전하지 않으며, 동적 인덱스를 수동으로 관리하는 것은 복잡해집니다.
해결책: 우리는 bot_id를 통해 강력한 격리를 강제합니다. 모든 인스턴스는 완전히 차단된 벡터 공간과 메모리 체인을 가집니다. 클라이언트 A의 임베딩과 대화는 클라이언트 B와 절대 섞일 수 없으며, 이는 FAISS, Pinecone, Qdrant, PGVector, Chroma 전반에서 기본적으로 지원됩니다.
2. 메모리 비대화 및 서버 재시작
문제: RunnableWithMessageHistory 데이터를 RAM에 로드하는 것은 데모용으로는 괜찮습니다. 하지만 대규모 환경에서 서버가 재시작되어 10만 개 이상의 과거 대화 세션을 즉시 로드해야 한다면 서버가 마비됩니다.
해결책: 우리는 인메모리 저장을 완전히 우회합니다. 채팅 기록은 MongoDB에 영구 저장되며 엄격하게 지연 로딩(lazy-loaded)됩니다. 사용자가 봇에 질문하면 해당 특정 대화 스레드만 요청 시 가져옵니다. 데이터베이스 크기에 관계없이 시작 시간은 일정하게 유지됩니다.
3. 스팬 추적 (타사 SaaS 없이)
문제: 체인이 왜 실패했는지, 검색 품질이 왜 떨어졌는지 파악하려면 보통 유료 관측 플랫폼으로 데이터를 보내야 합니다.
해결책: 우리는 파이프라인에 직접 네이티브 추적(LongTracer)을 구축했습니다. 검색 스팬(어떤 문서가 가져와졌는지, 지연 시간, 유사도 점수), LLM 스팬(정확한 프롬프트, 토큰 수), 에이전트 도구 호출을 자신의 MongoDB 인스턴스에 직접 기록합니다.
4. 실시간 환각 탐지 (v1.3.0 업데이트)
문제: 사용자가 우리보다 먼저 LLM의 환각을 발견하는 상황.
해결책: NLI 기반의 CitationVerifier를 통합했습니다. 최종 문자열을 반환하기 전에 응답을 원자적 주장(atomic claims)으로 분할합니다. 각 주장은 검색된 소스 문서와 교차 검증됩니다. 지원되지 않는 경우 데이터베이스에 환각으로 표시됩니다.
구현 모습:
우리는 이 전체 스택을 배포하는 데 사용자 지정 DB 래퍼나 세션 관리자를 연결할 필요 없이 단 몇 줄의 코드만 필요하도록 설계했습니다:
from longtrainer.trainer import LongTrainer
# 1. Mongo 영속성 및 추적 활성화로 초기화
trainer = LongTrainer(
mongo_endpoint="mongodb://localhost:27017/",
enable_tracer=True,
tracer_verify=True # NLI 환각 검사 활성화
)
# 2. 격리된 멀티 테넌트 인스턴스 생성
bot_id = trainer.initialize_bot_id()
trainer.add_document_from_path("client_data.pdf", bot_id)
trainer.create_bot(bot_id)
# 3. 쿼리 (메모리는 자동으로 지연 로딩 및 동기화됨)
chat_id = trainer.new_chat(bot_id)
answer, sources = trainer.get_response("Summarize the terms", bot_id, chat_id)


