Ask HN: 로컬에서 RAG를 어떻게 구현하고 있나요?
(news.ycombinator.com)- 해커뉴스에서 사용자가 로컬 환경에서 Retrieval-Augmented Generation(RAG) 을 어떻게 구현하는지 묻는 질문
- 로컬 RAG에서 벡터DB 없이도 SQLite FTS5·BM25·grep 같은 텍스트 검색으로 충분히 굴리는게 가능하다는 흐름이 강하게 나타남
- 코드 검색은 임베딩이 느리고 노이즈가 크다는 경험담이 많고, BM25+트라이그램 같은 키워드 기반이 더 낫다는 주장도 다수 보임
- 벡터 검색이 필요할 때도 Postgres+pgvector, SQLite에 벡터 BLOB 저장, FAISS 메모리 적재처럼 가벼운 구성으로 해결하는 사례가 이어짐
- BM25+벡터를 합치는 하이브리드 검색과 RRF(Reciprocal Rank Fusion), 리랭킹, 멀티쿼리 확장 같은 조합으로 검색 품질 향상 가능
- “RAG=벡터DB”로 고정되지 않고, 문서 유형·규모·운영 부담에 따라 단순 검색→하이브리드→에이전트형으로 선택하는 경향이 드러남
검색 단계에서의 공통 결론
- 벡터DB나 그래프가 필수라는 전제보다, 기존 인프라·파일 타입·요구 성능에 맞춰 단순하게 시작하는 접근이 다수임
- 에이전트가 파일시스템이나 API를 직접 조회하는 방식이 설정·유지보수는 쉬우나 약간 느릴 수 있다는 언급 존재
- “RAG가 LLM에 넘기는 것은 검색 결과의 짧은 텍스트 조각” 이라는 인식이 성능 개선 포인트를 검색 품질로 돌리는 계기
- “RAG 정의”를 두고 벡터DB가 없더라도 retrieval+generation이면 RAG라는 반응과, 보통 벡터DB를 전제로 부르는 경우가 많다는 반응이 함께 존재함
임베딩 모델 및 벡터 검색
- MongoDB에서 개발한 mdbr-leaf-ir 임베딩 모델은 CPU 전용으로 동작하며, 해당 크기 모델 중 여러 리더보드에서 1위 기록
- 표준 2vCPU 서버에서 초당 약 22개 문서, 120개 쿼리 처리 가능
- BEIR 벤치마크에서 53.55점 기록 (all-MiniLM-L12-v2는 42.69점)
-
model2vec/minish 같은 정적 워드 임베딩은 추론 속도가 더 빠르지만 검색 정확도는 낮음
- 토큰화 + 룩업 테이블 + 평균만 수행하므로 트랜스포머 기반보다 빠름
- Meta-Llama-3-8B로 텍스트 청크별 벡터 생성 후 SQLite BLOB 컬럼에 저장하고, FAISS로 검색하는 방식도 활용됨
- 500만 청크 기준 약 40GB 메모리 사용
- A6000에서 faiss-gpu가 매우 빠르고, M1 Ultra의 faiss-cpu는 느리지만 하루 몇 번 쿼리 수준에는 충분
코드 검색에 대한 권장사항
- 코드에는 벡터 데이터베이스 사용을 지양하고, BM25+트라이그램 조합 권장
- 임베딩은 느리고 코드에 적합하지 않음
- 리랭커가 없으면 노이즈가 커지고, 파일 재인덱싱 부담이 큼
- 검색 응답 속도가 빠르고 결과 품질도 우수
- PostgreSQL에서 plpgsql_bm25로 BM25 검색 구현 가능
- pgvector와 결합한 하이브리드 검색 + Reciprocal Rank Fusion 지원
- 파일 경로 + 시그니처에 임베딩을 적용하고 BM25와 퓨전하면 좋은 결과 획득 가능
- gpt-oss 20B를 ripgrep과 함께 while 루프로 실행하는 에이전틱 방식도 효과적
데이터베이스 기반 솔루션
-
SQLite FTS5: 마크다운 파일 기반 문서에 적합, 벡터 DB 없이도 RAG 구현 가능
- 각 파일에 짧은 설명 필드를 두고 키워드 검색으로 문서 탐색
- SQLite에 fp16 벡터를 BLOB로 저장하고, 필터로 부분집합을 만든 뒤 메모리에서 유사도 계산을 돌리는 설계도 가능
- sqlite-vec, sqlite-vector, vec0, sqlite의 bm25 같은 선택지도
- “SQLite가 놀랄 만큼 잘 됨”
-
PostgreSQL + pgvector: 기존 Postgres 지식 활용 가능, 운영팀 인수인계 용이
- 하이브리드 BM25, 멀티쿼리 확장, 리랭킹 지원하는 llmemory 라이브러리도 있음
-
LanceDB: 임베디드 벡터 DB로 편리하게 사용 가능
- Ollama의 nomic-embed-text 임베딩과 함께 활용
- DuckDB: 벡터 유사도 검색 확장 기능 제공, 3GB 이하 소규모 프로젝트에 적합
- Meilisearch, Typesense, Manticore: Elasticsearch/OpenSearch보다 운영이 단순
하이브리드 및 에이전틱 검색
- nori(usenori.ai): SQLite + vec0 + fts5로 시맨틱 및 단어 검색 결합
- Turbopuffer: 벡터 + BM25 하이브리드 검색 지원
- 에이전틱 검색과 텍스트 검색 조합만으로도 상당히 좋은 결과 획득
- 벡터 검색과 그래프 RAG 추가 시 약간의 속도 및 품질 향상 가능
- Claude Code/Codex는 내부적으로 ripgrep 사용
- 파일 경로에 임베딩을 적용해도 효과적, BM25와 퓨전하면 더욱 개선
BM25 활용 사례
-
shebe: BM25 기반 코드베이스 인덱싱 및 검색 CLI/MCP 도구
- 리팩토링 워크플로우에 특히 유용 (예: Istio 업그레이드 시 변경 필요 위치 열거)
- 85%의 경우 벡터 DB 없이 태그 매칭만으로 충분
- 운영자들이 입력과 문서 모두에 태그를 추가하여 100% 매칭 달성
- 대부분의 벡터 DB는 "못 찾는 문제를 해결하려는 망치"라는 의견
특수 도구 및 라이브러리
- qmd: 마크다운 파일 검색용 CLI 도구, fzf보다 퍼지 쿼리 결과 우수
- ck: Rust 기반 시맨틱 grep 도구
-
Kiln: 드래그 앤 드롭으로 파일 추가, 다양한 설정 비교 가능
- 추출 방법, 임베딩 모델, 검색 방식(BM25, 하이브리드, 벡터) 비교 지원
- 검색 정확도 평가 및 평가 데이터셋 자동 생성 기능
-
libragen: 버전 관리되는 RAG 콘텐츠 라이브러리 생성용 CLI/MCP 서버
- GitHub 저장소를 RAG DB로 변환 가능
- piragi: 간단한 Python RAG 라이브러리, 로컬/S3/API 등 다양한 소스 지원
- ragtune: 로컬 RAG 검색 디버깅 및 벤치마킹용 CLI 도구
문서 처리 및 OCR
-
discovery: Qwen-3-VL-8B로 문서 OCR, ChromaDB로 벡터 저장
- BM25 + 임베딩 하이브리드 RAG 구현
- docling: 문서 추출용 도구, 여러 RAG 프로젝트에서 활용
- PDF 변환 시 테이블, 다중 컬럼, 페이지 걸친 테이블 처리가 어려움
- Mistral OCR 모델이 가장 좋은 결과 제공 (비공개 모델)
메모리 및 컨텍스트 관리
- RAG가 LLM에 전달하는 것은 짧은 검색 결과 문자열뿐
- 작은 모델에서는 TOP_K=5 정도가 한계, 그 이상은 컨텍스트 망각 발생
- 파일과 폴더를 사전 요약하는 방식으로 개선 가능
- Sonnet + 1M 컨텍스트 윈도우로 모든 내용을 컨텍스트에 넣는 방식도 사용
- 세션 파일에 대한 시맨틱 검색으로 Claude Code용 메모리 시스템 구축 사례
엔터프라이즈 및 대규모 활용
- 하루 30만 건 고객 상호작용 처리 시 지연시간과 정밀도가 중요
- 임베딩 + 전문 검색 + IVF-HNSW 하이브리드 접근법 사용
- 약 600개 분산 시스템의 정보 확산 관리가 과제
- KAG(Knowledge Augmented Generation) 접근법으로 비즈니스 규칙 매핑 실험 중
- 50만 건 이상 뉴스 기사에 대해 Postgres 벡터 DB로 완전 로컬 RAG 구현 성공
기타 도구 및 접근법
- AnythingLLM: 문서용 벡터 DB 번들 제공
- LibreChat: 문서용 벡터 DB 번들 포함
- ChromaDB: Obsidian 확장으로 시맨틱/하이브리드 검색 구현
- SurrealDB: 로컬 벡터화와 결합하여 사용
- OData 쿼리 인터페이스: LLM에 도구로 제공 시 효과적, 4만 행 Excel 분석 가능
- Nextcloud MCP Server: Qdrant를 벡터 DB로 사용, 개인 문서에 시맨틱 검색 제공
-
LSP(Language Server Protocol): Claude Code에 추가되었으나 현재 버그 존재
- TreeSitter가 더 유용할 수 있음 (심볼명으로 조회, 정의/사용 위치 탐색)
Hacker News 의견들
-
우리 팀은 Q&A 데이터베이스를 운영 중임
질문과 답변을 trigram 인덱스와 임베딩으로 모두 색인해 Postgres에 저장함
검색 시pgvector와 trigram 검색을 함께 사용하고, 관련도 점수로 결과를 결합함 -
검색 단계에서는 CPU 친화적인 고효율 텍스트 임베딩 모델을 개발했음
MongoDB/mdbr-leaf-ir 모델로, 같은 크기 모델 중 리더보드 1위를 차지함
Snowflake/snowflake-arctic-embed-m-v1.5 모델과 호환 가능함
search-sensei 데모를 통해 semantic 검색 vs BM25 vs hybrid 비교 가능함
예를 들어, 임베딩 모델은 “j lo”가 “Jennifer Lopez”를 의미한다는 걸 인식함
또한 훈련 레시피를 공개했으며, 보통 수준의 하드웨어로도 쉽게 학습 가능함- 이 모델의 임베딩 속도와 recall이 minish나 model2vec 같은 정적 워드 임베딩과 비교해 어떤지 궁금함
-
나는 2024년 4월부터 Meta-Llama-3-8B로 벡터를 생성했음
Python과 Transformers를 RTX-A6000에서 사용했는데, 빠르지만 소음과 발열이 심했음
이후 M1 Ultra로 옮기고 Apple의 MLX 라이브러리를 사용했는데, 속도는 비슷하면서 훨씬 조용함
Llama 모델은 4k 차원이라 fp16 기준 8KB/청크이며, 이를numpy.save()로 SQLite의 BLOB 컬럼에 저장함
검색 시 SQLite에서 모든 벡터를 불러와numpy.array로 만든 뒤 FAISS로 검색함
RTX6000의 faiss-gpu는 매우 빠르고, M1 Ultra의 faiss-cpu도 내 용도(하루 몇 쿼리)에는 충분히 빠름
500만 청크 기준 메모리 사용량은 약 40GB로, 두 장비 모두 여유롭게 처리 가능함 -
대부분의 복잡한 문서는 Markdown 파일임
tobi/qmd라는 간단한 CLI 도구를 추천함
예전에는 fzf 기반 워크플로를 썼지만, 이 도구는 더 나은 퍼지 검색을 제공함
코드 검색에는 사용하지 않음- 소개를 보고 golang으로 작성된 grep 대체 도구일 줄 알았는데, Markdown 헤딩 가중치 같은 기능이 있을 거라 예상했음
-
코드 검색에는 벡터 데이터베이스를 쓰지 말라고 권함
임베딩은 느리고 코드에는 맞지 않음
BM25 + trigram 조합이 더 좋은 결과를 내며, 응답 속도도 빠름- Postgres에서도 하이브리드 검색이 가능함
plpgsql_bm25 프로젝트를 참고할 수 있음
BM25와 pgvector를 Reciprocal Rank Fusion으로 결합한 예시와 Jupyter 노트북도 포함됨 - 나도 동의함. 예전에 grep 대체 도구로 하이브리드 검색을 써봤는데, 지속적인 재색인이 번거로웠음
코드용이 아닌 모델을 쓰면 벡터 검색이 노이즈를 많이 유발함
지금은gpt-oss 20B를 ripgrep과 함께 루프 돌리는 방식이 훨씬 빠르고 정확함 - BM25와 벡터 검색을 함께 제공하는 간단한 서비스나 Docker 이미지를 아는 사람 있는지 궁금함
- 파일 경로나 시그니처에 적용했을 때 좋은 결과를 얻었음
BM25와 결합(fusion) 하면 더 향상됨 - 문서 검색용으로 RAG를 사용하는 것에 대한 의견이 궁금함
- Postgres에서도 하이브리드 검색이 가능함
-
로컬 RAG 실험용으로 local-LLM-with-RAG를 만들었음
Ollama의 “nomic-embed-text”로 임베딩을 생성하고, LanceDB를 벡터 DB로 사용함
최근에는 “agentic RAG”로 업데이트했지만, 작은 프로젝트에는 과할 수도 있음- 나도 비슷한 걸 하고 있음. lance-context를 사용 중이며, 훨씬 단순한 버전임
- “RAG”가 무슨 뜻인지 설명해줘서 고마움. 이 스레드를 읽으며 헷갈렸음
-
fp16 벡터를 SQLite에 BLOB으로 저장하고, 필터링 후 메모리에 로드해 행렬-벡터 곱(matvec) 으로 유사도 계산함
numpy나 torch가 멀티스레딩/BLAS/GPU를 활용하면 매우 빠름
병목이 생기면 sqlite-vector로 마이그레이션할 예정임
날짜나 위치 같은 필터로 데이터가 많이 줄어들기 때문에 효율적임
백엔드는 교체 가능한 인터페이스 뒤에 감춰져 있음 -
내 문서의 95%가 작은 Markdown 파일이라 SQLite FTS5로 일반 텍스트 검색 인덱스를 사용함
이미 인덱스가 있어서 mastra agent에 바로 연결했음
각 파일에는 짧은 설명 필드가 있어, 키워드 검색 후 설명이 일치하면 전체 문서를 로드함
설정에 한 시간 정도 걸렸고, 매우 잘 작동함- 사실 그게 바로 RAG(Retrieval-Augmented Generation) 임
임베딩 기반 검색이 더 흔하긴 하지만, 본질은 동일함
- 사실 그게 바로 RAG(Retrieval-Augmented Generation) 임
-
우리는 Postgres에 익숙해서 PGVector로 시작했음
나중에 프롬프트의 반정형 필드가 필요한 콘텐츠와 100% 일치한다는 걸 발견함
운영자가 입력과 문서 양쪽에 태그를 넣기 시작했기 때문임 (약 50개 문서 정도)
그래서 먼저 필드를 검색해 해당 파일을 프롬프트에 넣고, 그다음에 임베딩 검색을 수행함
결과적으로 85%의 경우 vectordb가 필요 없음- 대부분의 vectordb는 해결책을 찾는 망치 같음
-
나는 llmemory를 만들어 로컬과 회사 앱 양쪽에서 사용 중임
PostgreSQL + pgvector 기반이며, 하이브리드 BM25, 멀티 쿼리 확장, reranking 기능을 포함함
처음 공개하는 거라 약간의 버그는 있을 수 있음
성능에는 꽤 만족함