← Resources
TUTORIAL · 2026-02-12
LangChain 없이 프로덕션 RAG 파이프라인 구축하기 (2026)
프로바이더 SDK, pgvector, 리랭커를 직접 조합하면 수백 줄의 코드로 프로덕션급 RAG 파이프라인을 출시할 수 있습니다. 구체적으로 해결해야 할 문제가 생기기 전까지는 LangChain의 추상화를 건너뛰십시오.
2026년 팀들이 LangChain을 분리하는 이유
2026년에 이르러 프로덕션에서 LangChain을 제거하는 것은 인식 가능한 엔지니어링 패턴이 되었고, 한때 이를 옹호하던 팀들의 공개 포스트모템도 나왔습니다. 불만의 집합은 일관적입니다. 모델에 실제로 전달되는 내용을 가리는 계층적 추상화, 마이너 버전 간의 잦은 호환성 파괴, 래퍼 클래스 속을 탐험하는 디버깅 세션.
근저의 변화는 프로바이더 SDK가 좋아졌다는 점입니다. OpenAI, Anthropic, Google SDK는 이제 일급 스트리밍, 구조화된 출력, 도구 호출, 배치를 제공합니다. Voyage, Cohere, Jina는 임베딩과 리랭킹용 깔끔한 REST 엔드포인트를 노출합니다. pgvector가 있는 Postgres는 전용 벡터 데이터베이스 없이도 약 1천만 벡터까지의 ANN 검색을 처리합니다.
대부분의 RAG 워크로드에서, 2023년에 원했던 프레임워크는 이제 네 개의 함수 호출과 SQL 쿼리입니다. 2026년의 합리적인 디폴트는 원시 SDK로 시작하고, 실제 고통을 느낄 때 얇은 파이프라인 추상화를 추가하며, 중량 프레임워크는 옵트인으로 다루는 것입니다.
모든 RAG 파이프라인이 필요로 하는 다섯 단계
모든 프로덕션 RAG 시스템은 프레임워크와 무관하게 동일한 다섯 단계로 분해됩니다. 명시적으로 명명하면 코드를 더 쉽게 테스트하고 부분적으로 교체할 수 있습니다.
- 수집: 원본 문서 로드, 인코딩 정규화, 보일러플레이트 제거.
- 청킹: 안정된 ID와 출처 메타데이터를 가진 검색 단위로 분할.
- 임베딩과 인덱싱: 청크를 벡터 저장소로 인코딩하고, 하이브리드 검색을 위한 어휘 인덱스를 함께 구성.
- 검색과 리랭킹: 넓은 후보 집합을 가져온 뒤 크로스 인코더 리랭커로 좁히기.
- 생성과 인용: 검색된 컨텍스트로 프롬프트를 조립하고 출처가 부여된 답변을 반환.
각 단계를 타입이 지정된 입력과 출력의 순수 함수로 유지하십시오. 검색 단계는 어떤 LLM이 생성할지 몰라야 하고, 생성 단계는 어떤 임베딩 모델이 사용되었는지 몰라야 합니다. 이 분리는 프레임워크가 약속하지만 좀처럼 제공하지 않는 것입니다. 단계를 불투명한 체인 객체로 결합하기 때문입니다. 직접 작성하는 데는 오후 한나절이면 충분하며 업그레이드 리스크의 한 범주를 제거합니다.
청킹 전략: 시맨틱, 재귀, 에이전틱
RAG 품질의 대부분은 청킹에서 결정됩니다. 2026년에는 세 가지 패턴이 우세합니다.
구분자 계층(문단, 문장, 그다음 문자)에 대한 재귀적 문자 분할이 베이스라인입니다. 빠르고 결정적이며 산문에는 충분합니다. 시맨틱 청킹은 후보 분할을 임베딩하고 임베딩이 가까운 인접 청크를 병합하여 더 높은 수집 비용으로 주제적으로 일관된 단위를 생성합니다. 에이전틱 청킹은 헤딩과 턴 경계가 문자 수보다 중요한 계약서나 회의록 같은 구조화 문서에 대해 작은 LLM에게 분할 지점을 제안하도록 요청합니다.
def recursive_chunk(text, max_chars=1200, overlap=150):
seps = ["\n\n", "\n", ". ", " "]
def split(s, depth=0):
if len(s) <= max_chars or depth == len(seps):
return [s]
parts, sep = [], seps[depth]
for p in s.split(sep):
parts.extend(split(p, depth + 1))
return parts
raw = split(text)
return [raw[i] + raw[i+1][:overlap] for i in range(len(raw)-1)] + [raw[-1]]
재귀로 시작하고 측정한 뒤, 평가가 효과를 보이는 문서 범주에서만 시맨틱으로 승급하십시오.
임베딩과 리랭커: Voyage, BGE, Cohere
검색기에 대한 2026년 그림은 1년 전보다 명확합니다. MongoDB의 일부가 된 Voyage AI는 강력한 범용 밀집 모델로 voyage-3-large를 출시했고, 2026년 초 RTEB 리더보드 상단을 노린 mixture-of-experts 변형을 포함한 voyage-4 패밀리를 공개했습니다. Cohere의 embed-v4는 또 다른 프로덕션 선두 주자입니다. 오픈웨이트 셀프 호스팅에는 BAAI의 bge-m3가 여전히 디폴트입니다. 100개 이상의 언어와 8192 토큰 컨텍스트에서 밀집, 희소, 멀티벡터 검색을 지원하는 단일 모델입니다.
리랭킹에는 Cohere rerank-v3.5가 주력입니다. 다국어 단일 모델, 4096 토큰 청크, 일반 페이로드에서 약 80-150 ms p50 지연. Voyage rerank-2는 경쟁력 있으며 Voyage 임베딩을 이미 쓰고 있다면 깔끔하게 통합됩니다.
실용적인 규칙: 밀집 임베더 하나와 리랭커 하나를 골라 인터페이스 뒤에 고정하십시오. 나중에 교체하는 비용은 재인덱싱이지 재작성이 아닙니다.
검색, 생성, 인용 연결
pgvector를 사용하면 하이브리드 검색과 인용을 직관적인 SQL로 얻을 수 있습니다. 청크를 문서 ID, 임베딩, 어휘 재현율을 위한 tsvector와 함께 저장하십시오. 넓은 후보 집합을 검색하고, 리랭킹한 뒤, 상위 N을 출처 ID와 함께 LLM에 전달하여 모델이 인용하도록 지시합니다.
import psycopg, voyageai, cohere
vo, co = voyageai.Client(), cohere.Client()
def retrieve(query, k=40, top_n=8):
qvec = vo.embed([query], model="voyage-3-large").embeddings[0]
with psycopg.connect(DSN) as conn:
rows = conn.execute(
"SELECT id, doc_id, text FROM chunks ORDER BY embedding <=> %s LIMIT %s",
(qvec, k)).fetchall()
docs = [r[2] for r in rows]
ranked = co.rerank(model="rerank-v3.5", query=query, documents=docs, top_n=top_n)
return [rows[r.index] for r in ranked.results]
```
pgvector의 경우 m=16, ef_construction=64의 HNSW 인덱스를 디폴트로 하고, 테넌트 또는 최신성 프리필터를 추가하여 ANN 스캔이 좁게 시작하도록 하며, `ORDER BY embedding <=> $1`은 항상 `LIMIT`과 함께 사용하십시오. 검색된 청크를 ID와 함께 LLM에 전달하고 인용 마커를 내보내도록 지시한 뒤, 후처리 단계에서 그 마커를 출처 URL로 해석하십시오.
평가: 적중률, MRR, 충실도
평가 하니스 없는 RAG 파이프라인은 추측입니다. 어떤 것도 튜닝하기 전에 하니스를 구축하십시오. 최소 키트는 실제로 예상하는 질문 유형을 커버하는 100-500개의 라벨링된 질의 집합과 세 가지 메트릭입니다.
K에서의 적중률은 올바른 청크가 후보 집합에 포함되었는지 답하며, 검색 품질을 분리합니다. 평균 역순위는 올바른 청크가 얼마나 높이 순위가 매겨졌는지 포착하며, 리랭커가 개선해야 할 지표입니다. 충실도는 인용된 청크와 각 생성된 주장을 비교하도록 프롬프트된 LLM 심사자가 점수를 매기며, 모델이 컨텍스트를 벗어나 환각했는지 포착합니다.
변경마다 하니스를 실행하십시오: 새 청크 크기, 다른 임베더, 프롬프트 편집. 세 메트릭을 같은 대시보드에서 시간순으로 플롯하십시오. MRR이 개선되지만 충실도가 무너지는 변경이 발생하면, 리랭커가 방해 요소를 노출시키는 것이며 추가 검색 튜닝이 아니라 생성 프롬프트의 가드레일이 필요합니다.
매니지드 오케스트레이터로 승급할 때
수제 파이프라인은 한 팀이 소유하고 단계 수가 적은 동안 유지보수가 가능합니다. 매니지드 오케스트레이터가 비용을 회수하는 시점은 비엔지니어가 검색을 튜닝해야 할 때, 서로 다른 문서 범주에 대해 여러 파이프라인을 병렬로 운영할 때, 또는 재배포 없이 버전 관리된 설정과 A/B 라우팅을 원할 때입니다.
그 시점에서는 LlamaIndex나 Haystack 같은 중량 프레임워크와, 검색 단계를 선언적 단위로 노출하는 설정 주도 플랫폼 중에 선택하게 됩니다. osFoundry의 노코드 오케스트레이션 에디터인 osStudio는 두 번째 접근을 취합니다. 위의 다섯 단계는 매니지드 Voyage 임베딩과 리랭킹을 단일 프록시 뒤에 둔 일급 설정 객체이므로, LLM 측에서는 BYOK를 유지하면서 검색 측에서는 프레임워크 락인을 피합니다.
유용한 질문은 프레임워크 대 비프레임워크가 아닙니다. 파이프라인 설정이 코드, 설정, 또는 UI 중 어디에 속해야 하느냐이며, 그 답은 팀이 성장하면서 바뀝니다.
Frequently asked questions
- RAG에 정말로 벡터 데이터베이스가 필요한가요?
- 수백만 벡터를 넘기 전에는 아마 필요 없습니다. pgvector가 있는 Postgres는 HNSW 인덱스, tsvector를 통한 하이브리드 검색, 테넌시 및 최신성에 대한 표준 SQL 필터로 약 1천만 벡터까지 편하게 처리합니다. 이미 운영 중인 데이터베이스에서 백업, 복제, 접근 통제를 상속받습니다. Qdrant, Milvus, Weaviate 같은 전용 벡터 데이터베이스는 샤딩된 수십억 규모 인덱스, 매우 높은 QPS에서의 특화된 필터링, pgvector가 아직 따라가지 못한 멀티벡터 검색 같은 기능이 필요할 때 운영 비용을 정당화합니다. pgvector로 시작하고 측정된 병목이 강제할 때만 마이그레이션하십시오.
- 리랭커가 정말 지연 비용 가치가 있나요?
- 대부분의 검색 중심 워크로드에서는 그렇습니다. Cohere rerank-v3.5나 Voyage rerank-2 같은 크로스 인코더 리랭커는 40-100개 청크의 후보 집합에서 일반적으로 p50 기준 80-200밀리초를 추가하며, 밀집 검색만 사용하는 것 대비 평균 역순위를 일관되게 10-30% 끌어올립니다. 그 지연은 뒤따르는 LLM 호출 뒤에 숨겨지며, 사용자에게 보이는 예산은 보통 LLM이 지배합니다. 200밀리초 미만의 엔드 투 엔드 자동완성류 흐름이나, 밀집 순위가 이미 신뢰할 만큼 후보 집합이 작은 경우에만 리랭커를 건너뛰십시오.
- 스토리지를 부풀리지 않고 청크 오버랩을 처리하는 방법은?
- 청크 크기의 10-15%인 작은 오버랩을 텍스트 복제가 아니라 원본 문서로의 문자 오프셋으로 저장하십시오. 검색 시 컨텍스트 확장을 위해 인접 청크를 선택적으로 가져올 수 있습니다. 이렇게 하면 인덱스가 가벼워지고 임베딩 시 동일 토큰에 두 번 지불하는 것을 피합니다. 생성에 더 풍부한 컨텍스트가 필요하다면 parent-document 패턴이 잘 작동합니다. 검색 정밀도를 위해 작은 청크를 인덱싱하고 적중을 부모 섹션으로 해석한 뒤 LLM에 전달합니다. 부모 조회는 단일 인덱스 쿼리이며 지연이 무시할 만합니다.
- RAG 품질을 평가하는 가장 간단한 방법은?
- 검색되어야 할 청크 ID와 함께 100-200개의 대표 질의로 라벨링된 집합을 구축하십시오. 검색 단계만으로 K에서의 적중률과 평균 역순위를 계산하여 검색기 품질을 생성 노이즈에서 분리합니다. 충실도에는 인용된 청크와 각 생성된 주장을 비교하도록 프롬프트된 LLM 심사자를 사용하여 근거가 있는지 또는 뒷받침되지 않는지 점수를 매깁니다. 의미 있는 변경마다 세 숫자를 실행하고 회귀를 차단 요소로 다루십시오. 이 3 메트릭 셋업은 실무에서 대부분의 RAG 회귀를 잡으며 한 숫자를 최적화하다 다른 숫자를 조용히 해치는 함정을 피합니다.
Sources