13P by GN⁺ 10시간전 | ★ favorite | 댓글 1개
  • 해커뉴스에서 사용자가 로컬 환경에서 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를 사용하는 것에 대한 의견이 궁금함
  • 로컬 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)
      임베딩 기반 검색이 더 흔하긴 하지만, 본질은 동일함
  • 우리는 Postgres에 익숙해서 PGVector로 시작했음
    나중에 프롬프트의 반정형 필드가 필요한 콘텐츠와 100% 일치한다는 걸 발견함
    운영자가 입력과 문서 양쪽에 태그를 넣기 시작했기 때문임 (약 50개 문서 정도)
    그래서 먼저 필드를 검색해 해당 파일을 프롬프트에 넣고, 그다음에 임베딩 검색을 수행함
    결과적으로 85%의 경우 vectordb가 필요 없음

    • 대부분의 vectordb는 해결책을 찾는 망치 같음
  • 나는 llmemory를 만들어 로컬과 회사 앱 양쪽에서 사용 중임
    PostgreSQL + pgvector 기반이며, 하이브리드 BM25, 멀티 쿼리 확장, reranking 기능을 포함함
    처음 공개하는 거라 약간의 버그는 있을 수 있음
    성능에는 꽤 만족함