# 로컬 RAG를 구축하고 싶으신가요?

> Clean Markdown view of GeekNews topic #24712. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=24712](https://news.hada.io/topic?id=24712)
- GeekNews Markdown: [https://news.hada.io/topic/24712.md](https://news.hada.io/topic/24712.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2025-11-30T01:32:51+09:00
- Updated: 2025-11-30T01:32:51+09:00
- Original source: [blog.yakkomajuri.com](https://blog.yakkomajuri.com/blog/local-rag)
- Points: 37
- Comments: 7

## Summary

**Skald**는 데이터를 외부로 보내지 않고도 완전한 **로컬 RAG 시스템**을 구축할 수 있음을 보여주는 흥미로운 실험입니다. **Postgres+pgvector**, **Sentence Transformers**, **Docling**, 그리고 사용자가 직접 선택한 **LLM**으로 구성된 이 스택은, 클라우드 모델 대비 약간의 성능 저하(평균 7~8점대)를 감수하는 대신 **데이터 프라이버시와 통제권**을 확보합니다. 특히 **에어갭 환경**이나 민감한 데이터를 다루는 조직에게 현실적인 대안이 될 수 있으며, 오픈소스 생태계가 RAG 전 과정을 얼마나 빠르게 대체해가고 있는지를 잘 보여줍니다. “클라우드 없이도 충분히 똑똑한 AI 검색”이 가능하다는 점이 인상적입니다.

## Topic Body

- **Skald**는 데이터를 제3자에게 전송하지 않고 완전히 **자체 호스팅 가능한 RAG 시스템**을 목표로 개발됨  
- RAG 구성요소는 **벡터 데이터베이스, 임베딩 모델, LLM, 리랭커, 문서 파서**로 나뉘며, 각 요소에 대해 **오픈소스 대안**을 제시  
- Skald의 기본 로컬 스택은 **Postgres+pgvector**, **Sentence Transformers**, **Docling**, **사용자 지정 LLM**으로 구성  
- 벤치마크 결과, **클라우드 기반 모델(Voyage+Claude)** 은 평균 9.45점, **완전 로컬 GPT-OSS 20B**는 7.10~8.63점으로 평가됨  
- 이 접근은 **데이터 프라이버시를 유지하면서도 고성능 RAG 구축이 가능함**을 보여줌  
  
---  
  
### RAG 구성요소와 오픈소스 대안  
- 기본 RAG는 **벡터 데이터베이스, 임베딩 모델, LLM**으로 구성되며, 추가적으로 **리랭커와 문서 파서**가 포함될 수 있음  
  - 각 구성요소는 SaaS 대신 **로컬 대안**으로 대체 가능  
- 예시 표에서 제시된 대안  
  - **Vector DB:** Pinecone, Weaviate Cloud → Qdrant, Weaviate, Postgres+pgvector  
  - **Embeddings:** OpenAI, Cohere → Sentence Transformers, BGE, E5  
  - **LLM:** GPT, Claude → Llama, Mistral, GPT-OSS  
  - **Reranker:** Cohere → BGE Reranker, Sentence Transformers Cross-Encoder  
  - **Document Parsing:** Reducto → Docling  
- Skald는 완전한 **오픈소스 스택**을 지향하며, 각 구성요소를 로컬에서 실행  
  
### Skald의 로컬 스택 구성  
- **Vector DB:** Postgres + pgvector 사용  
  - 기존 인프라에 통합 용이하며, 수십만 문서까지 처리 가능  
- **Vector Embeddings:** 기본값은 **Sentence Transformers (all-MiniLM-L6-v2)**  
  - 영어 전용, 속도와 검색 성능 균형  
  - **bge-m3** 모델(다국어 지원)도 테스트됨  
- **LLM:** 기본 제공 없음, 사용자가 직접 실행  
  - 테스트에서는 **GPT-OSS 20B**를 EC2에서 실행  
- **Reranker:** 기본값은 **Sentence Transformers Cross-Encoder**, 다국어 모델로 **bge-reranker-v2-m3** 등도 사용 가능  
- **Document Parsing:** **Docling** 사용, docling-serve로 실행  
  
### 성능 및 배포 결과  
- 전체 스택을 포함한 Skald 프로덕션 인스턴스 배포에 **8분 소요**  
  - Postgres, 임베딩·리랭킹 서비스, Docling 포함  
  - LLM은 별도 실행 (llama.cpp 사용)  
- 테스트 데이터셋은 **PostHog 웹사이트 콘텐츠(약 2000문서)** 와 자체 제작 질의응답 세트로 구성  
- 실험 설정  
  - Vector search topK=100, Reranking topK=50, Query rewriting=Off  
  - 평가 기준은 **정확도 중심**  
  
### 벤치마크 결과 비교  
- **Voyage + Claude (클라우드 구성)**  
  - 평균 점수 **9.45**, 모든 답변 정확  
- **Voyage + GPT-OSS 20B (부분 로컬)**  
  - 평균 점수 **9.18**, 대부분 정확하나 일부 정보 누락  
- **완전 로컬 + GPT-OSS 20B**  
  - **기본 영어 모델(all-MiniLM-L6-v2 + ms-marco-MiniLM-L6-v2)** : 평균 **7.10**  
    - 영어 질의에는 정확, 다국어·모호 질의·다문서 집계에서 약점  
  - **다국어 모델(bge-m3 + mmarco-mMiniLMv2-L12-H384-v1)** : 평균 **8.63**  
    - 포르투갈어 질의 처리 성공, 다문서 집계 시 일부 누락  
- 주요 한계는 **여러 문서에 흩어진 정보의 통합 처리**  
  - 클라우드 모델은 고성능으로 이를 보완하지만, 로컬 환경에서는 추가 기법 필요  
  
### 향후 계획  
- Skald는 **로컬 RAG 성능 향상 및 오픈소스 모델 벤치마크 공개**를 계획  
- **에어갭 환경에서 AI 도구를 운영해야 하는 기업**을 위한 솔루션 제공 목표  
- 참여 희망자는 **[GitHub(skaldlabs/skald)](https://github.com/skaldlabs/skald)** 또는 **Slack 커뮤니티**를 통해 협업 가능

## Comments



### Comment 46974

- Author: iolothebard
- Created: 2025-11-30T15:01:29+09:00
- Points: 2

RAG에 벡터DB가 필요하다는 건 어디서 시작된 개구리인지…

### Comment 46988

- Author: aer0700
- Created: 2025-11-30T21:00:45+09:00
- Points: 3
- Parent comment: 46974
- Depth: 1

벡터db건 뭐건 사실은 그냥 검색만 구현하면 되는 걸텐데요...

### Comment 46979

- Author: dkmin
- Created: 2025-11-30T18:28:13+09:00
- Points: 3
- Parent comment: 46974
- Depth: 1

Gemini :  
네, RAG(Retrieval-Augmented Generation)에서 **벡터 데이터베이스(Vector Database)** 의 사용은 2020년 관련 논문이 처음 발표되면서부터 그 개념적인 토대가 마련되었습니다.  
RAG는 기본적으로 **검색(Retrieval)** 과 **생성(Generation)** 을 결합하는 방식인데, 이 검색 단계에서 벡터 임베딩과 이를 효율적으로 저장하고 검색하는 벡터 데이터베이스가 필수적인 역할을 하게 됩니다.  
💡 RAG와 벡터 DB의 시작점  
RAG에서 벡터 DB가 필요하다는 아이디어는 다음의 주요 논문과 개념에서 출발했습니다.  
1. RAG의 탄생: Lewis et al. (2020) 논문  
 * 논문 제목: "Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks" (지식 집약적 자연어 처리 작업을 위한 검색 증강 생성)  
 * 핵심: 이 논문에서 RAG라는 용어와 프레임워크가 처음 제시되었습니다.  
 * Retriever의 역할: 논문에서 제안된 RAG 모델은 **Retriever(검색기)** 와 **Generator(생성기)** 로 구성됩니다. Retriever는 위키피디아와 같은 대규모 데이터셋에서 쿼리와 관련된 **문서(latent documents)** 를 검색합니다.  
 * 벡터 인덱스 사용: 이 초기 RAG 모델은 문서를 검색하기 위해 데이터셋에 **벡터 인덱스(Vector Index)** 를 사용하여 **사전 학습된 검색기(pretrained retriever)** 가 문서를 가져올 수 있도록 했습니다.  
 * 결론: RAG의 핵심 단계인 **'검색'** 이 쿼리 및 문서의 벡터 표현을 기반으로 유사성을 계산하여 이루어지기 때문에, 효율적인 검색을 위한 벡터 저장소(Vector Store) 또는 벡터 인덱스의 개념이 필수적으로 내포되었습니다.  
2. 벡터 임베딩과 유사도 검색  
벡터 데이터베이스가 RAG의 필수 요소가 된 근본적인 이유는 다음과 같습니다.  
 * 임베딩(Embedding): RAG 시스템에서 외부 지식(문서, 텍스트)과 사용자의 쿼리(질문)는 모두 **벡터(Vector)** 라는 수학적 표현으로 변환됩니다. 이 벡터는 텍스트의 의미를 고차원 공간에 밀집된 숫자의 배열로 나타냅니다.  
 * 유사도 검색(Similarity Search): 벡터 공간에서 쿼리 벡터와 가장 가까운 거리에 있는 문서 벡터를 찾는 것이 곧 의미적으로 가장 유사한(Relevant) 문서를 찾는 것을 의미합니다.  
 * 벡터 DB의 역할: 벡터 데이터베이스는 이러한 수많은 문서 벡터들을 저장하고, 주어진 쿼리 벡터에 대해 가장 유사한 벡터를 빠르고 효율적으로 검색하기 위해 특화된 데이터베이스입니다. 따라서 RAG의 검색 성능을 극대화하는 데 필수적입니다.  
요약: 벡터 DB가 필요한 이유  
LLM이 학습하지 않은 최신/도메인 특정 지식에 접근하게 하려면, 단순히 키워드 매칭(전통적인 검색)이 아닌 의미적 유사성을 기반으로 정보를 찾아야 합니다. 벡터 DB는 이 의미적 유사성 기반 검색을 효율적으로 수행하기 위해 RAG 프레임워크에 자연스럽게 통합된 핵심 기술입니다.

### Comment 47091

- Author: aer0700
- Created: 2025-12-03T00:45:11+09:00
- Points: 1
- Parent comment: 46974
- Depth: 1

사실 rag에 필요한 건 검색 기능이고, 덴스 벡터로 임베딩해서 vectorDB에 푸시하고 코사인 유사도 검색하는 건 검색엔진을 구현하는 여러 방법 중 하나일 뿐인지라... 굳이 vectorDB 안 쓸 이유는 없는데, 정말 필수냐고 하면 오랫동안 잘 써오던 검색엔진 알고리즘 많은데 싶어서 고개가 갸우뚱하긴 합니다.

### Comment 47067

- Author: ztaka
- Created: 2025-12-02T11:14:57+09:00
- Points: 1
- Parent comment: 46974
- Depth: 1

싸고 대부분 프로덕션 LLM들이 써서요.  
사실 web 서버도 그렇게치면 인프라기능 추가하면 디스크에서 전부 가능하니 dbms도 필요없죠ㅋㅋ

### Comment 47048

- Author: gcback
- Created: 2025-12-01T22:59:32+09:00
- Points: 1
- Parent comment: 46974
- Depth: 1

사용자 query의 임베딩값(벡터)을 key로 하는 일종의 유사도/의미검색에 db가 필요하다는 것은 맞고요. key가 벡터 형태니 벡터db도 맞죠.

### Comment 46969

- Author: neo
- Created: 2025-11-30T01:32:52+09:00
- Points: 1

###### [Hacker News 의견](https://news.ycombinator.com/item?id=46080364) 
- 이런 시스템을 만들 때는 **벡터 데이터베이스나 임베딩**에 집착하지 말라는 조언을 하고 싶음  
  전체 텍스트 검색이나 `grep/rg` 같은 도구가 훨씬 빠르고 저렴하며, 인덱스를 유지할 필요도 없음  
  좋은 LLM에게 검색 도구를 주면 “dog OR canine” 같은 쿼리를 스스로 만들어내고 반복적으로 개선할 수 있음  
  게다가 이렇게 하면 **청킹 문제**를 해결할 필요도 없어짐
  - 브라우저에서 임베딩 기반(“semantic”)과 BM25 검색의 차이를 보여주는 작은 앱을 만들었음  
    [Search Sensei](http://search-sensei.s3-website-us-east-1.amazonaws.com/)에서 확인 가능함  
    처음 로드 시 약 50MB의 모델 가중치와 onnx runtime을 다운로드하지만 이후엔 원활히 작동함  
    예를 들어 BM25는 “j lo”와 “jlo”가 Jennifer Lopez를 의미한다는 걸 이해하지 못하지만, 임베딩 기반 검색은 이런 **오타나 별칭**을 잘 처리함  
    2016~2024년 뉴스 기사 1000개를 대상으로 검색을 수행함
  - [Anthropic의 contextual retrieval](https://www.anthropic.com/engineering/contextual-retrieval) 연구에 따르면, **임베딩 + BM25** 조합이 가장 좋은 결과를 냈다고 함  
    하지만 BM25 단독 성능은 공개되지 않아 아쉬움  
    내 소규모 테스트에서는 쿼리 단어가 그대로 포함된 페이지를 임베딩이 놓치는 경우가 있었음 — 결국 **Ctrl+F**가 이김
  - 내 경험상 **semantic vs lexical 검색**은 정밀도(precision)와 재현율(recall)의 트레이드오프로 이해하는 게 맞음  
    Lexical 검색은 정밀도가 높지만 재현율이 낮고, semantic 검색은 그 반대 지점에 위치함
  - Google Maps에서 “billiards”를 검색했더니 수영장과 염소 관련 결과만 나오는 **동의어 문제**를 겪었음  
    “NOT” 연산자가 더 필요하다고 느낌. RAG에 대해서도 더 배우고 싶음
  - 이런 방식으로 검색을 수행할 때 **표준 프롬프트**를 사용하는지 궁금함  
    일부 에이전트형 도구들이 자동으로 이런 쿼리를 만들어주는 걸 봤는데, 프롬프트로 유도된 건지 기본 동작인지는 모르겠음

- 성능이 떨어지는 이유 중 하나는 **semantic chunking**이 부족해서일 수 있음  
  문서 전체를 임베딩하면 여러 개념이 섞여 정확도가 떨어짐  
  Spacy 같은 도구로 의미 단위로 나누고, 각 청크가 문서 내에서 어떤 맥락에 있는지 추가한 뒤 임베딩해야 함  
  [Anthropic의 contextual retrieval](https://www.anthropic.com/engineering/contextual-retrieval) 접근법이 RAG 시스템에서 매우 효과적이었음  
  GPT OSS 20B 모델로 문맥 생성을 하면 됨
  - 작성자 아님이지만, 우리는 이미 **semantic chunking**을 하고 있음  
    여러 문서의 컨텍스트를 집계해야 하는 질문으로 테스트했기 때문에 오해가 있었던 듯함

- 왜 **semantic 검색이 lexical 검색보다 우수하다고 전제**하는지 의문임  
  2023년에 Tantivy(BM25)와 비교했을 때 결과 차이는 미미했음  
  약간의 재현율 향상이 있다고 해도, 그 복잡한 구조를 만들 가치가 있는지 모르겠음
  - 테스트 방식에 따라 다름  
    개발자 테스트에서는 90% 재현율이었지만 실제 사용자 테스트에서는 30% 수준으로 떨어졌음  
    사용자는 문서의 정확한 용어를 모르기 때문에 **lexical 검색만으로는 부족**했음  
    에이전트를 얹을 수도 있지만, **지연(latency)** 이 커져 사용자 만족도가 떨어짐
  - 앱의 성격에 따라 다름  
    Wanderfugl에서는 BM25 점수가 낮은 부분도 semantic 검색이 잘 찾아줌  
    결국 **하이브리드 랭킹**이 답일 수 있음
  - “두 과학자 간의 대화” 같은 쿼리를 처리할 수 있다는 점이 장점임  
    결국 **사용 사례 의존적**임

- 이메일, Slack, GDrive, 코드, 위키 등 모든 데이터를 로컬 오프라인에서 질의할 수 있는 **오픈소스 도구**를 찾고 있음  
  직접 구축하거나 커스터마이징은 피하고 싶고, 좋은 기본값과 모델 추천이 있으면 좋겠음
  - 그래서 **Nextcloud MCP 서버**를 만들었음  
    [GitHub 링크](https://github.com/cbcoutinho/nextcloud-mcp-server)  
    기본적으로 CRUD를 지원하고, 벡터 검색을 활성화하면 문서나 노트를 임베딩함  
    Ollama와 OpenAI를 임베딩 제공자로 지원함  
    MCP 서버는 **semantic + BM25(qdrant fusion)** 검색을 모두 제공하고, MCP 샘플링을 통해 응답을 생성함  
    서버 자체가 답을 생성하지 않고, 어떤 LLM/MCP 클라이언트와도 연동 가능함  
    이 **MCP sampling/RAG 패턴**은 매우 강력하며, 다른 데이터 소스에도 일반화된 오픈소스 버전이 나올 가능성이 큼

- 우리가 사용하는 도구는 [haiku.rag](https://github.com/ggozad/haiku.rag)임  
  개발자 친화적인 Python 코드와 **pydantic-ai** 기반 구조, 벤치마크와 고급 인용 기능을 제공함  
  **깊은 리서치 에이전트**를 지원하며, 장기적으로 유지되는 진짜 오픈소스 프로젝트임

- 기본 임베딩 모델로 **Sentence Transformers (all-MiniLM-L6-v2)** 를 사용 중인데, 영어 전용이라 독일어 RAG를 만들 때 문제가 될 수 있음을 깨달음  
  비영어 모델의 성능이 어떤지 궁금함
  - [MTEB 리더보드](https://huggingface.co/spaces/mteb/leaderboard)를 참고하면 됨  
    “Retrieval” 섹션의 **RTEB Multilingual** 또는 **RTEB German** 항목을 보면 됨  
    CPU 기반 셀프호스팅이라면 100M 파라미터 이하 모델로 필터링하는 게 좋음
  - 많은 모델이 비영어권 언어에서 **성능 저하**를 보임  
    하지만 독일어는 비교적 학습 데이터가 많고, 다국어 모델도 충분히 존재함  
    특히 상용 API 기반 모델들은 대부분 **다국어 지원**임
  - 우리도 예전에 다국어 임베딩 모델을 사용했었음  
    관련 논문은 [Springer 링크](https://link.springer.com/chapter/10.1007/978-3-031-77918-3_15) 참고 가능함

- GPT-4 시절(8K context)에는 책 전체를 청크로 나눠 GPT-4에 넣어 **관련 구절을 검색**하는 스크립트를 만들었음  
  그땐 검색 한 번에 1달러 정도 들었지만, 지금은 훨씬 저렴해짐  
  [Anthropic의 contextual retrieval](https://www.anthropic.com/engineering/contextual-retrieval) 글에서도, 문서가 컨텍스트에 다 들어간다면 RAG 대신 그냥 넣는 게 낫다고 함  
  다만 컨텍스트가 길어지면 품질이 떨어지고, 비용과 속도도 문제임  
  지금은 책 전체를 컨텍스트에 넣어도 **1센트 수준**으로 가능함

- RAG에서 가장 어려운 부분은 **문서 파싱**임  
  텍스트만 다루면 괜찮지만, 표나 다중 페이지 표, 차트, 목차, 각주 등이 있으면 정확도가 급격히 떨어짐  
  이를 개선하기 위해 **RAPTOR 패턴**처럼 LLM이 내용을 요약·질문하며 벡터 DB에 저장하는 접근이 있음  
  하지만 모든 경우에 통하는 **범용 RAG 파이프라인**은 여전히 어려운 과제임
  - 벡터 임베딩 초보로서, 표가 그렇게 복잡한 문제를 만든다는 걸 몰랐음  
    벡터 DB가 긴 텍스트 그룹과 표 형식 중 어느 쪽을 더 잘 처리하는지도 궁금함

- 전체 텍스트 검색을 RAG에 적용한 **새로운 관점**이 흥미로웠음  
  에이전트형 도구 루프와 **퍼지 검색(fuzzy search)** 처리 방식에 대한 통찰이 인상적이었음

- 이런 시스템의 **평가용 데이터셋**이 표준화되어 있는지 궁금함  
  문서와 질문 세트가 있어 특정 문서나 청크가 가장 관련성 높은 결과로 나와야 하는 식의 벤치마크가 있으면 좋겠음
  - 그런 용도로 **haiku-rag 벤치마크와 평가 세트**를 참고하면 됨
