2026. 08. 17. · CK

RAG 파이프라인으로 고른 오픈소스 AI 도구 7가지

오픈소스 AI 도구를 소개하는 영상을 보면 저장소 이름만 잔뜩 남을 때가 있다. 도구를 어디에 끼워 넣을지 모르면 다음 날 다시 기존 코드로 돌아간다. 나도 새 프로젝트를 시작할 때 비슷한 실수를 했다. 벡터 데이터베이스부터 고른 뒤 문서 정제와 평가 기준을 나중으로 미뤘다. 검색 결과가 나빠도 청킹, 임베딩, 검색 설정 중 어느 부분이 원인인지 구분하기 어려웠다.

The Stack의 영상은 열 가지 프로젝트를 소개한다. 그중 RAG 시스템의 한 흐름으로 연결되는 일곱 가지를 골랐다. 원본 수집에는 Crawl4AI와 Marker, 분할에는 Chonkie를 쓴다. Qdrant와 Ollama가 저장과 추론을 맡고, Langfuse와 DSPy가 관찰과 최적화를 담당한다. 각 저장소의 기능을 나열하기보다 내가 도입 여부를 판단할 때 확인하는 조건과 한계를 함께 정리했다.

먼저 그릴 파이프라인

일곱 도구는 다음 순서로 연결할 수 있다.

  1. Crawl4AI가 웹페이지를 읽어 마크다운을 만든다.
  2. Marker가 PDF와 문서 파일에서 본문, 표, 수식을 추출한다.
  3. Chonkie가 정제된 문서를 검색 단위로 나눈다.
  4. 임베딩 모델이 청크를 벡터로 바꾸고 Qdrant가 벡터와 메타데이터를 저장한다.
  5. Ollama가 로컬 모델을 실행해 검색 결과를 바탕으로 답을 만든다.
  6. Langfuse가 호출 과정과 비용, 평가 점수를 기록한다.
  7. DSPy가 테스트 예시와 평가 함수를 이용해 프롬프트 구성을 개선한다.

이 순서에는 운영상의 이유가 있다. 뒤 단계에서 아무리 좋은 모델을 써도 앞 단계에서 표가 무너지거나 문장이 엉뚱한 위치에서 잘리면 근거가 사라진다. 나는 원본 열 개를 직접 열어 변환 결과를 눈으로 확인한 뒤 검색 평가를 시작한다. 변환 결과가 흔들리는 상황에서 벡터 데이터베이스 설정을 조정하면 원인을 더 찾기 어려워진다.

작은 실험이라면 일곱 도구를 모두 설치할 필요가 없다. 문서 수십 개를 다룰 때는 파일과 메모리 기반 검색으로도 충분하다. 도구를 추가할 때마다 배포, 인증, 백업, 버전 관리가 새 운영 항목으로 생긴다. 현재 병목을 한 문장으로 설명할 수 있을 때 해당 단계의 도구를 고르는 편이 낫다.

원본을 정리하는 Crawl4AI와 Marker

Crawl4AI는 웹페이지를 LLM이 읽기 쉬운 마크다운으로 변환하는 크롤러다. 비동기 브라우저, 세션, 프록시, 훅을 제공하고 원하는 필드만 JSON으로 추출할 수도 있다. 문서 사이트나 공개 데이터 페이지를 주기적으로 수집할 때 HTML 정제 코드를 줄여 준다.

내가 먼저 확인할 항목은 로그인과 자바스크립트 의존성이다. 정적 문서는 기본 크롤링만으로 처리할 수 있다. 로그인 뒤에 보이는 페이지나 무한 스크롤 화면은 세션과 브라우저 동작을 설계해야 한다. 운영 서버에서는 최신 보안 릴리스를 쓰고, 크롤링 API에 인증과 목적지 제한을 둬야 한다. 외부 사용자가 임의의 URL과 브라우저 옵션을 넘길 수 있게 열어 두면 내부 주소 접근과 자원 남용 위험이 생긴다.

Marker는 PDF, 이미지와 오피스 문서를 마크다운, JSON, HTML, 청크 형식으로 변환한다. 표와 수식, 다단 레이아웃이 있는 보고서를 처리할 때 텍스트 레이어만 읽는 방식보다 구조를 많이 보존한다. 현재 Marker는 Surya VLM과 작은 CPU 모델을 조합하고, 필요하면 LLM을 추가해 변환 품질을 높인다.

Marker를 도입할 때는 샘플 문서로 세 가지를 확인한다. 표의 행과 열이 유지되는지, 본문의 읽기 순서가 맞는지, 각주가 문장 사이에 끼어들지 않는지 본다. 스캔 품질이 낮은 문서와 복잡한 양식은 사람이 결과를 검토해야 한다. 코드 라이선스와 모델 가중치 라이선스도 구분해서 읽어야 한다. 조직의 매출과 사용 목적에 따라 가중치 사용 조건이 달라질 수 있다.

Crawl4AI와 Marker의 결과는 같은 중간 형식으로 맞춘다. 나는 source_url, fetched_at, document_id, page를 청크까지 전달한다. 답변이 틀렸을 때 원문 위치로 돌아가려면 이 네 값이 필요하다. 본문만 벡터 데이터베이스에 넣으면 근거를 고치거나 삭제하기가 힘들어진다.

Chonkie로 검색 단위를 설계하기

영상에서 소개한 도구 이름은 Chonkie다. 초안에서는 신경망 기반 프로젝트인 Chonky와 Chonkie를 섞어 적었는데, 두 프로젝트는 서로 다르다. Chonkie는 토큰, 문장, 재귀, 의미, late chunking을 포함한 여러 분할 방식을 제공하는 Python 라이브러리다. 코드와 신경망 기반 분할기도 선택할 수 있다.

청크 크기는 모델의 컨텍스트 길이만 보고 정하지 않는다. 사용자가 묻는 질문의 범위와 원문의 구조가 기준이 된다. 제품 매뉴얼에서 한 절을 묻는다면 제목과 본문을 함께 보존해야 한다. 계약서 조항을 검색한다면 조 번호와 정의 조항을 메타데이터로 연결해야 한다. 짧은 고객 상담 기록은 여러 발화를 한 묶음으로 유지하는 편이 문맥을 지킨다.

나는 세 가지 설정으로 작은 평가 세트를 만든다. 고정 토큰, 문장 기반, 의미 기반 청킹을 각각 적용한 뒤 질문 20개에 대해 정답 근거가 상위 검색 결과에 들어오는지 확인한다. 검색 결과의 문장 수와 임베딩 비용도 함께 기록한다. 의미 기반 청킹이 더 많은 연산을 쓰면서도 근거 적중률을 높이지 못한다면 문장 기반 설정을 택한다.

중복 구간도 자동으로 크게 잡지 않는다. overlap을 늘리면 문맥을 보존할 수 있지만 같은 문장이 여러 결과에 반복되고 저장량도 커진다. 제목과 상위 절 정보를 각 청크에 붙이는 방식이 중복보다 나은 경우가 많았다. Chonkie는 선택지를 제공하고, 최종 규칙은 내 문서와 질문 데이터가 정한다.

Qdrant와 Ollama로 로컬 실행 경로 만들기

Qdrant는 Rust로 만든 벡터 검색 엔진이다. dense, sparse, multivector 검색과 payload 필터를 지원한다. 여러 검색 결과를 합치는 하이브리드 검색, 양자화, 디스크 저장 옵션도 제공한다. 문서 종류, 고객 ID, 작성일 같은 조건을 벡터 유사도와 함께 적용해야 할 때 기능 구성이 잘 맞는다.

벡터가 많지 않은 첫 실험에서는 별도 데이터베이스가 부담이 될 수 있다. 기존 PostgreSQL을 운영하고 있다면 pgvector로 평가를 시작해도 된다. Qdrant는 필터와 하이브리드 검색이 제품 요구사항에 들어오거나, 벡터 인덱스를 애플리케이션 데이터와 분리해 운영할 이유가 생겼을 때 검토한다. 셀프호스팅을 택하면 스냅샷 복원과 메모리 사용량을 부하 테스트에 포함한다.

Ollama는 오픈웨이트 모델을 로컬에서 실행하고 HTTP API로 제공한다. ollama run으로 모델을 내려받아 실행할 수 있고, OpenAI API의 일부 형식과 호환된다. 기존 OpenAI SDK 코드에서 base URL과 모델 이름을 바꿔 로컬 호출을 시험할 수 있다.

호환 범위가 API 전체를 뜻하지는 않는다. 사용하는 endpoint, tool calling, structured output 옵션을 문서와 통합 테스트로 확인해야 한다. 모델 크기와 양자화 수준에 따라 속도와 답변 품질도 달라진다. 개인 정보가 외부 API로 나가지 않는 경로를 만들 수 있지만, 로컬 서버의 접근 제어와 로그 보존 정책은 운영자가 책임져야 한다.

Qdrant와 Ollama를 같은 서버에 놓으면 메모리와 디스크 대역폭을 함께 쓴다. 나는 인덱싱 작업과 사용자 추론을 분리해 측정한다. 동시 요청에서 응답 시간이 튀면 모델 서버와 검색 서버를 다른 장비나 컨테이너 자원 한도로 나눈다. 로컬 실행의 장점은 외부 전송 통제와 비용 예측이며, 운영 인력과 하드웨어 비용까지 합쳐 판단해야 한다.

Langfuse로 실패 지점을 기록하기

Langfuse는 LLM 애플리케이션의 호출을 trace와 observation으로 기록한다. 프롬프트 버전, 입력과 출력, 지연 시간, 토큰과 비용을 한 흐름에서 볼 수 있다. 데이터셋 실험, 사람 평가와 LLM judge 점수도 같은 실행 기록에 연결할 수 있다.

나는 진행 중인 프로젝트에서 Langfuse를 사용한다. 프롬프트를 수정할 때 버전 이름만 남기면 실제 결과와 연결되지 않았다. 프롬프트를 trace에 연결한 뒤에는 실패한 응답이 어느 버전에서 나왔는지 확인할 수 있었다. 세션 ID를 붙이면 한 사용자의 여러 요청도 이어서 볼 수 있다.

처음부터 모든 값을 기록하면 민감 정보가 관찰 도구에 복제된다. 사용자 입력을 전송하기 전에 비밀 키와 개인 식별 정보를 가리고, 원문 전체가 필요 없는 단계에는 길이와 해시만 남긴다. 개발과 운영 환경도 태그로 분리한다. 테스트 호출이 운영 비용 통계와 품질 지표에 섞이면 개선 방향을 잘못 잡을 수 있다.

관찰 도구의 가치는 대시보드 수보다 질문에 답하는 속도로 측정한다. 특정 프롬프트 버전의 실패율, 검색 결과가 비어 있던 요청, 비용이 기준을 넘은 세션을 몇 분 안에 찾을 수 있어야 한다. 그 질문을 먼저 정한 뒤 trace 이름과 metadata를 설계하면 쌓인 로그를 실제 수정 작업에 쓸 수 있다.

DSPy로 평가 가능한 부분부터 최적화하기

DSPy는 언어 모델 호출을 Python 모듈과 signature로 표현하고, optimizer가 프롬프트나 예시를 조정하도록 돕는 프레임워크다. RAG, 분류, 에이전트 흐름처럼 여러 단계가 있는 프로그램을 구성할 수 있다. 사람의 감으로 문구를 고치는 작업을 평가 함수와 학습 예시를 이용한 탐색으로 바꾼다.

DSPy를 쓰려면 먼저 성공을 계산할 수 있어야 한다. 정답이 있는 분류 문제는 정확도를 쓸 수 있다. RAG 답변은 근거 포함 여부와 인용 정확도를 나눠 평가하는 편이 낫다. 평가 함수가 허술하면 optimizer는 그 허점을 잘 만족하는 프롬프트를 찾는다. 학습에 쓴 예시와 검증 예시도 분리해야 한다.

첫 적용 범위는 한 단계로 제한한다. 예를 들어 검색 결과 세 개를 받아 답변과 인용을 만드는 모듈만 최적화한다. 기준 프롬프트, 최적화된 프롬프트, 다른 모델에서의 결과를 같은 검증 세트로 비교한다. 개선 폭이 실행 비용과 복잡성을 감당할 만큼 클 때 다음 단계로 넓힌다.

Langfuse와 DSPy는 역할이 다르다. Langfuse 기록으로 실패 사례를 찾고 평가 데이터셋을 갱신한다. DSPy는 그 데이터셋과 metric을 받아 후보 프로그램을 탐색한다. 새 후보를 다시 Langfuse 실험으로 실행하면 변경 전후의 품질과 비용을 같은 기준으로 비교할 수 있다.

내 도입 순서와 중단 기준

새 RAG 프로젝트에서는 도구 이름보다 실패 지점을 기준으로 순서를 정한다.

관찰한 문제먼저 검토할 도구도입 전 확인할 값
웹 본문에 메뉴와 광고 문구가 섞인다Crawl4AI정제 후 남은 불필요 문장 비율
PDF 표와 수식이 깨진다Marker샘플 문서의 표·읽기 순서 정확도
정답 문장이 검색 결과에 잡히지 않는다Chonkie질문별 상위 검색 결과의 근거 적중률
필터와 하이브리드 검색이 필요하다Qdrant데이터 크기와 p95 검색 시간
외부 전송을 통제해야 한다Ollama모델별 메모리와 p95 생성 시간
실패한 호출의 원인을 찾기 어렵다Langfusetrace에서 원인까지 찾는 시간
프롬프트 개선을 반복 측정하고 싶다DSPy고정 검증 세트의 품질과 실행 비용

한 도구를 넣은 뒤 지표가 움직이지 않으면 설정을 되돌린다. 저장소의 별 개수는 내 시스템의 검색 품질을 보장하지 않는다. 샘플 데이터, 질문 세트, 운영 제약을 기준으로 도입 결정을 남겨야 다음 변경에서도 같은 판단을 반복할 수 있다.

내가 지금 가장 자주 여는 도구는 Langfuse다. 이미 프롬프트와 trace가 쌓여 있어 수정 근거를 바로 찾을 수 있기 때문이다. 다음 실험에서는 문서 유형별로 Chonkie 설정을 비교하고, 근거 적중률이 확인된 구간만 Qdrant에 다시 적재할 계획이다. 일곱 도구를 한 번에 설치하는 일보다 이 작은 검증 순서가 내 프로젝트에는 더 유용하다.

참고자료

참고

각 도구의 공식 저장소와 문서에서 기능과 지표를 확인했다.

RAG 파이프라인으로 고른 오픈소스 AI 도구 7가지 · iamlazyck