RAG 도구가 LLM을 부르지 않기로 했다
회사 문서를 Claude에게 물어보고 싶었다. 그런데 올릴 수가 없다. 업로드 금지라서가 아니라, 올려도 되는지 아닌지를 매번 판단해야 하는 게 문제였다. 판단이 필요하면 결국 안 쓰게 된다.
그래서 문서를 옮기지 않는 쪽으로 만들었다. 폴더에 꽂아두면 Claude가 거기서 꺼내 읽는다.
검색만 하고 생성은 안 한다
RAG는 검색(Retrieval)과 생성(Generation)으로 나뉜다. 보통은 도구가 둘 다 한다. 문서를 찾아서, 그걸 프롬프트에 넣고, LLM을 호출해 답을 만들어 돌려준다.
서재는 검색까지만 한다. 생성은 사용자의 Claude가 한다.
| 하는 일 | 누가 | |
|---|---|---|
| R | 색인·검색·출처 | 서재 (로컬) |
| G | 답변 생성 | 사용자의 Claude |
이건 기능을 덜 만든 게 아니라 구조를 정한 것이다. 세 가지가 따라온다.
비용이 0이다. 내가 낼 API 요금이 없다. 사용자도 이미 내고 있는 구독을 그대로 쓴다. RAG 도구를 만들 때 제일 먼저 부딪히는 게 “누가 토큰 값을 내나”인데, 그 질문 자체가 사라진다.
유출이 0이다. 문서가 내 서버로 갈 일이 없다. 애초에 서버가 없다. “우리는 문서를 저장하지 않습니다”라고 약속하는 것과, 저장할 곳이 없는 것은 다르다.
모델을 고를 자유가 생긴다. 사용자가 쓰는 모델이 곧 이 도구의 성능이다. 내가 모델을 붙박아두면 반 년 뒤에 낡는다. 안 붙박으면 안 낡는다.
분류도 같은 원칙으로
미분류 파일을 어느 책장에 꽂을지 정하는 것도 판단이다. 그러니 서재는 그것도 안 한다.
대신 두 가지만 준다 — 읽을 재료(본문 발췌)와 옮기는 손(파일 이동). 어디에 꽂을지는 Claude가 정하고, 실제로 옮기는 건 도구가 한다.
도서관에 비유하면 이렇다. 사서도 손님도 AI인데, 서고와 목록만 로컬에 있다.
대가는 검색 품질이다
생성을 안 하기로 하면, 검색이 빗나갔을 때 가려줄 게 없다. LLM이 어물쩍 메워주는 부분이 없으니 검색 품질이 그대로 드러난다.
한국어 문서라 형태소 기반 BM25로 색인한다. 임베딩 서버가 필요 없고, 그만큼 설치가 가볍다. 문제는 문서가 쓰는 어휘와 질문의 어휘가 어긋날 때다. “예외 처리”로 색인된 문서를 “에러 핸들링”으로 찾으면 안 나온다.
그래서 검색이 빗나가면 빈손으로 돌려보내지 않는다. 색인에 없는 단어가 무엇이었는지, 그 책장이 실제로 쓰는 어휘가 무엇인지를 힌트로 같이 준다. Claude가 그걸 보고 표현을 바꿔 다시 검색한다.
찾아주는 것보다, 못 찾았을 때 다음 수를 알려주는 게 실제로는 더 자주 쓸모 있었다.
폴더 밖은 읽지 않는다
루트 폴더 하나를 지정하면 그 바깥은 어떤 경우에도 읽지 않는다. 상대 경로로 빠져나가는 요청은 실제 경로로 풀어서 확인한 뒤 거부한다.
이건 편의 기능이 아니라 이 도구를 쓸 수 있게 만드는 조건이다. 로컬에 있다는 이유만으로 안전한 게 아니다. 읽을 수 있는 범위가 정해져 있어야 안전하다.