'LLM wiki + AI Agent 팀'
설정 가이드북
지식을 쌓고 · 찾고 · 봇이 꺼내 쓰는 법 — 처음부터 끝까지
LLM Wiki를 구축하고 이를 기반으로 여러 AI 에이전트 봇을 굴리려는 분들을 위해 — 어려운 원리도 비유와 그림으로 직관적으로 풀었습니다.

LLM wiki 운영 — 지식을 쌓는 법
왜 "LLM이 읽는 위키"인가. Karpathy의 LLM wiki(3층·Ingest/Query/Lint), kepano·Milo·Forte 방법론, 우리 옵시디언 vault, 오늘 시작 5단계.
Part 2GraphRAG 검색 원리 — 지식을 찾는 법
RAG·임베딩·BM25·하이브리드(RRF)·리랭커·지식 그래프·GraphRAG, 그리고 좋은 검색을 숫자로 증명하는 벤치마크까지.
Part 3봇 에이전트 원리 — 봇이 꺼내 쓰는 법
vault·LLM·Discord로 굴러가는 AI 봇 팀. 봇 구조·역할·왜 볼트별 분리·/search 활용, 그리고 이 가이드북이 만들어진 과정.
짝꿍 문서: 이 지식창고를 굴리는 봇 팀을 직접 차리는 절차는 🤖 봇 운영 실전 가이드에 있습니다.
이 가이드북을 읽는 법
세 파트는 하나의 흐름입니다 — 쌓고 → 찾고 → 꺼내 쓰기.
핵심 한 줄: "내 지식을, LLM이 잘 다룰 수 있게, 일반 텍스트로, 내가 소유하며, 연결해서 쌓는다."
Karpathy의 raw·wiki·schema + Ingest·Query·Lint가 그 골격이고, 우리 vault·이 가이드북이 그 한국어 실천판입니다.
이제 막 시작한다면? plain markdown 노트 한 폴더부터(7장의 5단계). 그게 첫걸음입니다.
사실·인용 근거: research-part1.md · research-part1-deep.md (코난 1차출처 리서치, 2026-06-08) · 출처 링크는 각 절 하단
지식을 어떻게 쌓고 관리하나
LLM 시대의 개인 지식관리 — 세계의 방법론과 우리 옵시디언 vault
- 왜 이제 노트를 "사람용"이 아니라 "LLM용"으로도 쌓아야 하는지
- Karpathy의 LLM wiki — 3개 층(raw·wiki·schema)과 3가지 동작(Ingest·Query·Lint)
- kepano·Nick Milo·Tiago Forte·Matuschak·Simon Willison의 실전 방법
- 우리 vault 구조 + 오늘 바로 시작하는 5단계
왜 "LLM이 읽을 수 있는 위키"인가
Karpathy는 2025년에 이렇게 말했습니다.
(옮김: 곧 관심의 99.9%는 사람의 관심이 아니라 LLM의 관심이 될 것이다. — 2025-03 본인 트윗)
앞으로 내 글·노트를 읽는 쪽은 점점 사람이 아니라 AI가 된다는 뜻입니다. 그러니 내 지식을 검색·요약·AI 비서의 연료로 쓰려면, 사람만 보기 좋은 예쁜 문서(PDF·이미지·특정 앱 전용 포맷)가 아니라 LLM이 그대로 먹을 수 있는 형식 — 즉 plain markdown(일반 텍스트 노트)으로 쌓아야 유리합니다. 이것이 "LLM wiki" 발상의 출발점이에요.
왜 하필 마크다운인가 — AI가 읽기 좋은 5가지 이유
"plain markdown으로 쌓아라"는 말은 자주 듣지만, 왜 하필 마크다운이어야 하는지는 잘 안 알려줍니다. 여기서 그 이유를 처음부터 풀어볼게요. 이 절만 이해하면 LLM wiki의 절반은 잡은 셈입니다.
마크다운(Markdown)은 그냥 글자(텍스트)입니다. 거기에 약속된 기호 몇 개만 더한 거예요. 워드처럼 버튼을 눌러 굵게·제목을 만드는 게 아니라, 기호로 직접 표시합니다.
메모장(텍스트 편집기) 하나면 열고 쓸 수 있어요. 특별한 앱도, 인터넷도 필요 없습니다.
LLM(AI 언어모델)은 글을 통째로 보는 게 아니라, 토큰(token)이라는 작은 글자 조각으로 잘라서 읽습니다. 그리고 그 입력은 결국 순수한 텍스트(글자)예요 — 그림도 표도, LLM 앞에서는 일단 글자로 바뀌어야 읽힙니다. 이 한 가지 사실이 아래 다섯 이유의 뿌리입니다.
마크다운은 처음부터 글자라, LLM이 그대로 바로 먹습니다. 반면 PDF·이미지·한글(.hwp)·워드 파일은 LLM이 읽기 전에 "글자만 뽑아내는 변환"을 먼저 거쳐야 해요. 그 변환에서 표가 뭉개지고 줄바꿈·순서가 깨지는 일이 흔합니다.
사람은 큰 글씨·굵은 글씨를 보고 "아, 이게 제목이구나" 압니다. 그런데 LLM은 글씨 크기를 못 봐요 — 글자만 봅니다. 마크다운은 그 구조를 기호로 적어두기 때문에, LLM이 #를 보고 "제목", -를 보고 "목록 항목"이라고 글자만으로 문서의 뼈대(위계)를 파악합니다.
같은 "제목" 하나도 형식에 따라 글자 수가 확 다릅니다.
LLM이 한 번에 읽을 수 있는 양(토큰)은 정해져 있고, 토큰은 곧 비용이기도 합니다. 마크다운은 군더더기 태그가 없어 같은 내용을 더 적은 토큰에 담아요 → 한 번에 더 많은 지식을, 더 싸게 읽힐 수 있습니다.
LLM은 인터넷의 방대한 글로 학습했는데, 그중 마크다운으로 쓰인 글이 아주 많습니다 — 개발자 설명서(README), 위키, 기술 문서 상당수가 마크다운이거든요. 그래서 LLM에게 마크다운은 읽기도 쓰기도 자연스러운, 손에 익은 형식입니다.
마크다운에서 노트끼리의 연결([[노트이름]])도 그냥 글자입니다. 그래서 LLM이 "이 노트가 저 노트와 이어져 있다"를 읽는 즉시 압니다 — 그리고 이 연결망이 바로 Part 2의 지식 그래프(검색의 재료)가 됩니다. 또 텍스트라서 한 줄을 고치면 딱 그 한 줄만 달라져, "무엇이 언제 바뀌었는지" 추적(버전 관리)도 쉽습니다.
<tag>(XML 태그)를, ChatGPT는 마크다운 헤더를 권해요. 여기서 다루는 건 어디까지나 "지식을 쌓아 두는 형식"으로서의 강점입니다.근거: microsoft/markitdown · Anthropic "Use XML tags" · The Stack(BigCode)·Common Crawl · Cloudflare "Markdown for Agents"(토큰 측정 사례) — 코난 1차/권위 출처 검증(2026-06-08). 토큰 절감 구체 수치는 콘텐츠마다 편차가 커 범위로만 봅니다.
왜 하필 옵시디언인가 — AI의 모국어로 쌓기
마크다운이 "AI가 읽기 좋은 형식"이라면, 옵시디언은 그 마크다운을 가장 잘 다루는 도구입니다. 단순한 메모장이 아니에요 — 노트를 쓰는 것만으로 AI가 이해하기 좋은 구조가 자연스럽게 만들어집니다. 비결은 셋이에요: 프론트매터 · 위키링크 · 그래프.
프론트매터(front matter)는 노트 맨 위에 --- 두 줄 사이에 적는 짧은 메타데이터(머리말 정보)입니다. 제목·태그·날짜처럼 "이 노트가 무엇인지"를 정해진 칸에 적어 두는 거예요.
본문을 한 글자도 안 읽어도, 이 머리말만 보면 "AI 주제 · 올해 만든 노트"임을 알 수 있어요.
왜 AI에 좋을까요? AI나 검색 시스템이 본문 전체를 읽지 않고도 머리말만 훑어 분류·필터·검색할 수 있기 때문입니다. 수백 개 노트 중 "AI 태그가 달린, 올해 노트"를 골라내는 일이 한순간이 돼요.
graph_* 같은 — Part 2의 지식 그래프가 쓰는 정보)이 따로 있습니다. 2층은 기계 전용이라 사람이 손으로 쓰지 않아요(잘못 쓰면 검색이 꼬입니다). 우리는 "사람 칸"만 채우면 돼요.옵시디언에선 [[노트이름]]이라고 쓰면 그 노트로 가는 링크가 됩니다(앞 절에서 본 그 기호예요). 폴더 경로를 외울 필요 없이 이름만으로 노트와 노트를 잇죠.
위키링크로 이어진 노트들을, 옵시디언은 점(노트)과 선(링크)으로 그린 그래프로 보여줍니다. 내 지식 전체가 한 장의 지도로 펼쳐지는 거예요. 그리고 결정적으로 — 이 연결망이 그대로 Part 2의 "지식 그래프(GraphRAG)" 재료가 됩니다. 내가 노트를 이어 둔 방식이, 나중에 검색이 똑똑해지는 바탕이 돼요.

근거: 프론트매터·위키링크·그래프 뷰의 기능 정의 = 옵시디언 공식 문서(help.obsidian.md) · "AI·검색에 유리"는 앞 절의 마크다운 특성에서 유도한 평가 · "X-ray" 비유는 이해를 돕기 위한 설명으로 특정 인물의 출처는 아닙니다 — 코난 공식/1차 출처 검증(2026-06-08).
Andrej Karpathy의 "LLM wiki" — 실제로 어떻게 도는가
OpenAI 창립 멤버·전 Tesla AI 디렉터. 2026년 개인 지식관리 방법 "LLM Knowledge Base / LLM wiki"를 공개해 큰 반향을 일으켰고, "LLM wiki"라는 말이 퍼진 진원지입니다.
발상은 단순합니다 — "코드를 다루는 데 쓰던 AI를, 이제 지식을 다루는 데 쓴다."
(옮김: 요즘 내 토큰 사용량의 큰 몫이 코드를 다루는 데서 지식을 다루는 데로 옮겨갔다. — 2026-04 본인 트윗)
그가 공개한 설계(본인 gist llm-wiki.md)는 세 층으로 나뉩니다.
- raw/ (원자료 · 불변) — 내가 모은 원본(논문·기사 등). "immutable — the LLM reads from them but never modifies them. This is your source of truth." 고치지 않고 추가만 하는 단일 진실 원천.
- wiki/ (LLM이 소유) — LLM이 만든 마크다운 페이지들(요약·개념·비교). "The LLM owns this layer entirely."
- schema (규약) =
CLAUDE.md/AGENTS.md— LLM에게 "위키가 어떻게 구성되고, 규칙·작업방식이 무엇인지" 알려주는 설정 문서. 그의 표현으로 "what makes the LLM a disciplined wiki maintainer rather than a generic chatbot. You and the LLM co-evolve this over time." → LLM을 규율 있는 위키 관리자로 만드는 핵심. 사람과 LLM이 함께 다듬어 갑니다.
- Ingest(수집·편입) — 원본 1개를 raw에 넣고 "처리해줘"라고 하면, LLM이 읽고 → 핵심을 나와 상의 → 요약 페이지 작성 → 색인(index) 갱신 → 관련 개념·인물 페이지 갱신 → 로그(log)에 기록. 그의 말로 "A single source might touch 10-15 wiki pages." (소스 하나가 10~15개 페이지를 건드림.)
- Query(질문) — 위키에 물으면 LLM이 관련 페이지를 찾아 출처와 함께 답함. 핵심은 "good answers can be filed back into the wiki as new pages... your explorations compound." 좋은 답을 다시 위키로 보관하니, 탐색이 채팅에서 증발하지 않고 복리처럼 쌓입니다.
- Lint(점검) — 주기적 건강검진. "contradictions between pages, stale claims, orphan pages with no inbound links, important concepts lacking their own page, missing cross-references, data gaps." (모순·낡은 주장·고아 페이지·빠진 개념·끊긴 참조·빈틈 찾기.)
index.md = 전체 목차(페이지마다 링크 + 한 줄 요약). 질문 시 LLM이 색인을 먼저 읽고 관련 페이지로 파고듦. 그의 말: "works surprisingly well at moderate scale (~100 sources) and avoids the need for embedding-based RAG infrastructure."
규모가 ~100소스를 넘어 "색인만으로는 벅찰 때" 바로 그 지점에서 임베딩·GraphRAG 검색이 필요해집니다 → 그게 Part 2의 존재 이유예요.

출처(1차): gist · llm-wiki.md · 트윗(지식 다루기) · 트윗(context engineering). 위키 규모 "~100글·40만 단어"는 2차 보도 기준.
Karpathy 패턴 ↔ 우리 시스템 (그대로 대응)
우리 옵시디언 vault·봇 시스템은 Karpathy의 LLM wiki와 거의 1:1로 대응합니다. 이 표 하나가 Part 1 → Part 2 → Part 3 전체를 꿰어요.
| Karpathy LLM wiki | 우리 vault · 봇 시스템 | 가이드북 |
|---|---|---|
| raw/ (불변 원천) | 수집한 원자료·회의 입력 | Part 1 |
| wiki/ (LLM이 작성) | 020-Library·MOC·Zettelkasten 노트 | Part 1 |
schema = CLAUDE.md | CLAUDE.md(규율) + soul.md(봇 성격) | Part 3 |
| index.md | MOC · SHARED-INDEX.md | Part 1 |
log.md (## [date] append) | 회의 02-progress.md(KST 로그) | Part 3 |
| Lint(모순·고아·빈틈) | 봇의 검증·출처 교차검증 | Part 3 |
| "색인만으론 벅찬 규모" → 검색 필요 | GraphRAG /search | Part 2 |
노트 방법론 지도 — 따라 할 수 있는 실전 how-to
Karpathy만 그런 게 아닙니다. "내 지식을 일반 텍스트로, 내가 소유하며, 연결해서 쌓는다"는 흐름은 여러 갈래로 이미 있었어요. 각각 바로 따라 할 수 있게 정리했습니다.

- 형식부터 개방형으로 — 노트를
.md·.txt로. 앱 전용·클라우드 종속 포맷 회피(앱이 사라져도 메모장으로 열림). - 로컬 소유 + 동기화는 보조 — vault를 내 컴퓨터 폴더에(예
~/Documents/vault/). - 폴더는 최소·평평하게 — 깊은 계층 대신 최상위에 노트, 폴더는 소수만.
- 경로 대신 링크로 —
[[노트이름]]+ 빠른 전환(Cmd/Ctrl+O). - 정기 재방문 — 일·월·연 리뷰로 과거 아이디어 재연결.
LYT(Linking Your Thinking)의 핵심 도구 MOC = 관련 노트로 가는 링크를 사람이 직접 큐레이션한 지도 노트.
- "정신적 압박점" 감지 — "한 주제에 아는 건 많은데 정리가 안 돼" 느낌이 MOC 만들 신호(밀로의 용어).
- 관련 노트 모으기 — 검색·태그로 목록화(15~30개 모이면 적기).
- 허브 노트 신설 — 예
MOC_프로젝트관리.md, 맨 위 한 문장 설명. - 카테고리별 정렬 —
## 핵심 개념/## 도구/## 사례로 묶어 링크 나열. - 비파괴 오버레이 — 원본 노트는 그대로, MOC는 위에 얹는 지도. 새 노트 생기면 갱신.
기준은 "주제"가 아니라 "지금 얼마나 실행에 쓰이나"입니다.
| 범주 | 정의 | 예시 |
|---|---|---|
| Projects | 마감 있는 단기 목표 | "3월 보고서", "인테리어" |
| Areas | 끝없는 지속 책임 | "건강", "커리어" |
| Resources | 언젠가 쓸 참고자료 | "레시피", "CSS 참고" |
| Archives | 비활성 항목 | 끝난 프로젝트 |
결정 규칙: 마감 있나?→P / 끝없는 책임?→A / 지금은 아니지만 나중에?→R / 더 안 씀?→Archive.
이 방식의 뿌리는 독일 사회학자 Niklas Luhmann(1927–1998)의 Zettelkasten(쪽지 상자) — 평생 약 9만 장의 카드를 1장 = 1아이디어로 적고 서로 연결해 방대한 저술을 남긴 노트법입니다. Matuschak의 Evergreen은 그 현대판이에요.
그의 실제 노트 제목 그대로(verbatim):
| ① atomic | 한 노트 = 한 개념 |
| ② concept-oriented | 책·사건이 아니라 개념 중심 |
| ③ densely linked | 촘촘히 연결할수록 발견↑ |
| ④ associative > hierarchical | 폴더 계층보다 링크 우선 |
| ⑤ for yourself | 독자 의식 말고 미래의 나를 위해 |
❌ "「Attention is all you need」 논문 노트"(논문 제목 중심)
✅ "self-attention은 병렬 처리가 가능하다"(개념 중심) + [[트랜스포머]]·[[RNN의 한계]] 링크
llm CLI + 공개학습터미널에서 LLM을 부르는 그의 도구 llm 실사용 예:
그리고 TIL(Today I Learned) — 매일 배운 작은 걸 짧게 공개 기록("미래의 내가 다시 검색 안 하도록"). 자기 위한 기록인데 부수효과로 남에게도 도움이 됩니다.
| 인물 | 핵심 | 한 줄 |
|---|---|---|
| Karpathy | LLM wiki | LLM이 마크다운 위키를 쓰고 관리 — 사람은 모으고 질문만 |
| kepano | File over app | 앱은 사라져도 내 파일은 남는다 |
| Nick Milo | LYT · MOC | 관련 노트를 손으로 큐레이션한 지도로 연결 |
| Tiago Forte | PARA | 정보를 실행가능성으로 분류 |
| Matuschak | Evergreen | 한 노트=한 개념, 갈수록 다듬는 원자 노트 |
출처: stephango.com · linkingyourthinking.com · fortelabs.com · notes.andymatuschak.org · llm.datasette.io
우리 옵시디언 vault — 다섯을 합친 한국어 실천판
위 방법들을 한데 합친 게 우리 옵시디언 vault입니다. 큰 폴더는 역할로 나뉩니다(주제가 아니라 — Forte의 PARA 정신).
| 폴더 | 역할 |
|---|---|
000-START-HERE | 입구 — vault 구조 안내·지도 |
020-Library | 지식 본체 — 연구·자료(Zettelkasten·MOC) |
030-의뢰 | 실제 일감(프로젝트) |
.claude-memory | AI 봇들이 공유하는 기억(메모리) |
노트 사이는 [[위키링크]]로 잇습니다(Milo의 연결). 자주 찾는 주제는 MOC(지도 노트)로 묶고(Milo), 노트는 가능한 한 원자적으로 쪼갭니다(Matuschak). 전부 plain markdown — 우리가 소유하고(kepano), AI가 그대로 읽습니다(Karpathy).
"폴더를 어떻게 짜야 하나?"엔 정답이 없습니다. 유명한 세 방식을 비교해 보면, 뿌리는 같고 취향만 다릅니다.
| 누구 | 방식 | 특징 |
|---|---|---|
| kepano(Steph) | 폴더 최소 + 위키링크 위주 | 구조를 거의 안 짜고 링크로 연결 — 평평하게 |
| 재경(우리) | 000-START-HERE + 숫자 prefix 폴더 | 입구 노트부터, 폴더 앞 숫자로 순서·역할 고정 |
| Karpathy | 로컬 .md + GitHub·Drive 동기화 | 회사 DB·여러 기기까지 같은 노트를 동기화 |
우리 vault는 재경 방식(숫자 prefix로 역할 고정)에 가깝지만, 어느 쪽이든 plain markdown + 위키링크라는 뿌리는 같아요. 처음엔 아무거나 하나 골라 시작하고, 쓰면서 내 손에 맞게 바꾸면 됩니다.

[[링크]]로 이은 지식 지도[[링크]]·태그가 그대로 Part 2의 지식 그래프(검색)가 됩니다. 정리하는 방식이 곧 검색의 재료예요 — 그래서 "어떻게 쌓느냐"가 중요합니다.knowledge-manager — 흩어진 자료를 LLM wiki로
노트를 처음부터 다 손으로 쓰는 건 무리예요. 우리 자료는 이미 여기저기 흩어져 있죠 — PDF 보고서, 워드 문서, 노션 페이지, 메신저 대화, 웹 기사. 이걸 한 번에 LLM wiki로 빨아들이는 도구가 우리 knowledge-manager(지식 관리자)입니다.
누구나 겪는 일이죠. 중요한 자료는 분명 어딘가 있는데, PDF는 다운로드 폴더에, 회의록은 노션에, 링크는 메신저에 흩어져 찾질 못합니다. AI에게 물어봐도, 그 자료가 AI가 읽을 수 있는 형태로 한곳에 모여 있지 않으면 소용없어요.
한 줄 명령(/knowledge-manager)을 주면, 안에서 다섯 단계가 차례로 돕니다.
- 수집(Collect) — 자료를 가져옵니다(PDF·웹·노션 등).
- 분석(Analyze) — 무슨 내용인지, 핵심이 무엇인지 파악합니다.
- 변환(Convert) — AI가 읽기 좋은 마크다운으로 바꿉니다(앞 절의 그 형식!).
- 저장(Store) — 프론트매터(이름표)를 달아 vault 알맞은 폴더에 저장합니다.
- 연결(Link) — 관련 노트와
[[위키링크]]로 잇고, 필요하면 MOC(지도 노트)에 등록합니다.
자료 종류마다 꺼내는 방법이 달라요. 웹 기사는 본문만 긁어오고, PDF는 글자를 떠내는 여러 단계를 거치고, 노션·메신저는 또 각자의 방식이 있죠. knowledge-manager는 입력이 무엇인지 감지해 알맞은 추출 경로로 자동 분기합니다 — 사용자는 "이거 넣어줘"만 하면 됩니다.
회사 자료를 다룬다면 경계가 중요합니다. 기밀 문서·고객 정보를 외부 AI 서비스에 함부로 올리면 안 되죠.

오늘 바로 시작하기 — 5단계
거창할 필요 없어요. 오늘 한 폴더부터가 당신의 LLM wiki 첫걸음입니다.
- Obsidian 설치(무료) → vault 폴더 하나 생성.
- PARA 폴더 4개(
Projects/Areas/Resources/Archives) + 임시Inbox(Forte). - 영역마다 MOC 1개(예
MOC_AI학습.md) — 관련 노트를 모아 지도로 (Milo). - 마크다운 +
[[위키링크]]로 노트 작성, 한 노트 한 개념 (kepano·Matuschak). - LLM 연동(LLM wiki化) —
raw/에 원자료를 넣고 Claude Code/Codex에 "이 소스 읽고 요약 페이지 + 색인 갱신"(=Ingest) → "쌓인 노트 종합해줘"(=Query). 규약은CLAUDE.md로 (Karpathy).
한국에서는 — 그리고 이 강의
이게 먼 나라 이야기 같나요? 한국에서도 이미 일어나고 있습니다(아래는 직접 확인한 출처만).
※ 검증되지 않은 한국어 URL은 일부러 싣지 않았습니다(가짜 출처 박제 방지 — 코난 리서치 원칙).
쌓은 지식을 어떻게 찾아내나
LLM wiki + GraphRAG·하이브리드 검색을 처음부터 끝까지 — 원리는 직관적으로
/search는 /knowledge-manager(자료를 정리해 주는 AI)가 노트에 달아둔 [[링크]]·태그를 지식 그래프(개념을 점, 관계를 선으로 이은 지도)로 바꾸고, 그 그래프 + 의미로 찾는 검색 + 단어로 찾는 검색을 한데 섞어(하이브리드) 답을 찾습니다. 이 파트는 그 안의 개념을 하나도 건너뛰지 않고 — 왜 필요한지, 어떻게 작동하는지, 숫자로는 어떻게 되는지 — 풀어 보여줍니다.- 검색 한 번에 무슨 일이 벌어지는지 (큰 그림)
- 의미로 찾기(임베딩) vs 단어로 찾기(BM25), 그리고 둘을 합치는 법(RRF)
- 지식 그래프와 GraphRAG가 평범한 검색과 무엇이 다른지
- 좋은 검색인지 숫자로 증명하는 법 — 그리고 실제 벤치마크 결과
검색 한 번에 무슨 일이 벌어지나

/search "MCP가 뭐야?" 한 줄이 답이 되기까지, 네 갈래로 찾아 → 공정하게 합치고 → 정밀 심사해 → Top-5를 냅니다. 다음 장들이 이 흐름의 단어를 하나씩 풉니다.검색이라고 하면 보통 "단어가 들어간 문서 찾기"를 떠올립니다. 하지만 좋은 검색은 그보다 훨씬 많은 일을 합니다. 같은 뜻을 다른 단어로 쓴 글도 찾아야 하고("반려견"으로 물어도 "강아지" 글), 흔한 단어에 묻힌 핵심 문서를 위로 끌어올려야 하고, 여러 방식이 추천한 결과를 하나로 합쳐야 합니다. 우리 /search는 이걸 다섯 단계로 합니다.
- 네 갈래로 동시에 찾기. ㉠뜻으로(의미검색) ㉡단어 그대로(키워드검색) ㉢질문을 작은 질문으로 쪼개서 ㉣개념(엔티티) 매칭. 한 갈래만 쓰면 놓치는 걸 서로 메웁니다.
- 공정하게 합치기. 네 갈래가 각자 추천한 순위표를 RRF(순위 융합)로 합칩니다. 점수 척도가 제각각이어도 "순위"만 쓰니 안전합니다.
- 정밀 심사. 합쳐서 추린 상위 후보만 리랭커가 질문과 한 묶음으로 정독해 다시 줄세웁니다. 1차 서류전형 → 2차 면접.
- 결과 내기. 최종 Top-5 문서 + 신뢰도 4단계(high/medium/low/very_low). 여기까지가 검색의 일입니다.
- (선택) 답변 만들기. 원하면 그 Top-5를 근거로 LLM이 자연어 답까지 합성(기본 OFF). 이게 RAG의 'G(생성)' 부분 — 마지막 장에서.
[[링크]]·태그)는 /knowledge-manager(AI)가 자료를 정리하며 만든 것입니다(직접 손으로 단 게 아닙니다). 런타임 인덱서는 그 AI가 만든 링크를 규칙대로(rule-based) 그래프 DB로 옮기기만 합니다(이 단계엔 LLM 없음). 한편 "인덱싱 때 LLM이 관계를 새로 추출"·"커뮤니티 LLM 요약" 같은 마이크로소프트식 GraphRAG의 일부는 아직 미작동이라 "GraphRAG 계열"로 부릅니다(8·9장에서 자세히).RAG — 오픈북 시험의 원리
거대 언어모델(LLM)은 학습할 때 본 지식을 신경망 가중치 안에 욱여넣습니다. 이걸 파라메트릭 메모리(parametric memory, 모델 속 기억)라고 합니다. 문제는 셋입니다. ①내 개인 지식(내 vault 메모)은 학습에 없었으니 모름. ②지식이 옛날 것이라 최신을 모름. ③근거 출처를 못 대니 그럴듯하게 지어내기 쉬움(환각, hallucination). 모델을 다시 학습시키는 건 비싸고 느립니다.
RAG(검색증강생성, Retrieval-Augmented Generation)는 이 셋을 한 번에 푸는 아이디어입니다. 답하기 전에 외부에서 관련 문서를 검색해 와서, 그 문서를 질문과 함께 모델에 넣어 줍니다. 모델은 "기억"이 아니라 "눈앞의 자료"를 보고 답합니다.
- R (Retrieval, 검색): 질문과 관련된 문서를 외부 저장소에서 찾는다. ← 이 가이드북의 거의 전부가 바로 이 단계 이야기입니다(우리
/search). - A (Augmented, 증강): 찾아온 문서를 질문에 "붙여서" 모델에게 줄 입력을 만든다. ("아래 자료를 참고해 답하라: [문서1][문서2]… 질문: …")
- G (Generation, 생성): 모델이 그 자료를 근거로 자연어 답을 쓴다.
최신·개인 지식을 반영하고, 출처를 제시해 환각을 줄이며, 재학습 없이 지식만 갈아끼울 수 있습니다. 다만 답 품질이 검색 품질에 종속됩니다. 검색이 엉뚱한 문서를 가져오면 모델은 그 위에 그럴듯한 틀린 답을 씁니다("garbage in, garbage out"). 그래서 RAG의 핵심은 사실 '생성'보다 '검색'입니다 — 이 가이드북이 검색에 집중하는 이유입니다.
/search는 우리 vault에 대한 RAG의 R(검색)입니다. G(생성)는 옵션으로 켜고 끕니다(기본 OFF). 즉 평소엔 "관련 문서 Top-5"를 돌려주고, 원할 때만 그걸 LLM이 자연어 답으로 합성합니다. (논문 원전: Lewis 외 2020, arXiv:2005.11401.)임베딩 & Dense 검색 — 의미를 좌표로

키워드 검색만으로는 "반려견 키우는 법"을 물었을 때 "강아지 기르기" 글을 못 찾습니다. 글자가 다르니까요. 사람은 두 문장이 같은 뜻인 걸 압니다. 컴퓨터도 그렇게 하려면 의미를 비교 가능한 형태로 바꿔야 합니다. 그게 임베딩입니다.
임베딩(embedding)은 문장을 고정 길이 숫자 배열(벡터)로 바꾼 결과입니다. 우리 모델은 한 문장을 384개 숫자로 만듭니다. 이 숫자들은 사람이 정한 게 아니라, 신경망이 방대한 글을 학습하며 "비슷한 맥락에 쓰이는 문장은 비슷한 숫자가 되도록" 스스로 익힌 결과입니다.
"가깝다"는 보통 코사인 유사도로 잽니다. 두 벡터가 가리키는 방향이 얼마나 비슷한지를 봅니다(크기가 아니라 방향). 같은 방향이면 1.0, 직각이면 0, 반대면 -1.
이 벡터를 Dense(밀집) 벡터라 부릅니다. 384칸이 거의 전부 0이 아닌 값으로 빽빽이 차 있기 때문입니다. 다음 장에 나올 BM25의 'Sparse(희소)' 벡터(대부분 0)와 정확히 대비됩니다 — 이 둘의 차이가 하이브리드 검색의 출발점입니다.
말바꿈·동의어·번역에 강합니다("자동차"↔"승용차"↔"car"). 다만 정확한 고유명사·코드·아주 드문 용어에는 의외로 약합니다(임베딩이 그 단어를 뭉뚱그려 비슷한 것들과 섞어버림). 긴 문서는 한 점으로 압축하며 디테일이 뭉개집니다.
paraphrase-multilingual-MiniLM-L12-v2로 노트·엔티티를 384차원 벡터로 만듭니다. LLM이 아니라 작고 빠른 전용 모델이라 무료·즉시·다국어(한/영)입니다. 노트는 제목·태그·본문 앞 500자를 임베딩합니다. (왜 이 모델인지, 더 좋은 건 없는지는 12장에서 깊게 다룹니다. 논문 계보: Karpukhin 외 2020 DPR, arXiv:2004.04906.)Sparse & BM25 — 단어를 정직하게 세기
"이 문서가 이 질문에 얼마나 맞나"를 단어로 답하는 가장 오래된 질문입니다. Ctrl+F는 단어가 "있나/없나"만 봅니다. 하지만 우리는 얼마나 관련 있나를 점수로 줄세워야 합니다. 그 점수 공식의 사실상 표준이 BM25입니다(검색엔진·엘라스틱서치 등이 다 씁니다).
BM25는 순진한 방법이 왜 실패하는지를 짚으며 세 번 고쳐나가면 가장 잘 이해됩니다.
첫 직관: 질문 단어가 문서에 많이 나올수록 관련 높다(TF, Term Frequency). 맞습니다. 그런데 함정이 있습니다 — "강의 강의 강의 강의…"를 30번 도배한 문서가 3번 자연스럽게 쓴 문서보다 10배 관련 높을까요? 아니죠.
그래서 BM25는 TF를 포화(saturation)시킵니다. 처음 몇 번은 점수가 쑥 오르지만, 곧 천장에 수렴해 더 나와도 거의 안 오릅니다.
둘째 문제: "그리고", "방법" 같은 단어는 거의 모든 문서에 있습니다. 이런 흔한 단어가 많이 나온다고 관련 높은 게 아닙니다. 반대로 "성우하이텍" 같은 희귀한 단어가 들어있으면 그 문서는 거의 확실히 관련 있습니다.
그래서 IDF(역문서빈도)로 단어마다 가중치를 줍니다 — 전체 문서 중 그 단어가 나오는 문서가 적을수록 가치↑.
셋째 문제: 5,000단어짜리 긴 문서는 짧은 문서보다 모든 단어를 더 많이 담습니다. 그냥 두면 긴 문서가 무조건 유리해집니다. 그래서 BM25는 문서 길이를 평균 길이와 비교해 보정합니다(파라미터 b≈0.75). 평균보다 긴 문서는 TF 점수를 깎고, 짧은 문서는 살려줍니다.
질문: 성우하이텍 강의. 두 문서를 비교합니다.
| 문서 | 길이 | "성우하이텍" | "강의" |
|---|---|---|---|
| A 짧은 강의 노트 | 200 단어 | 3회 | 2회 |
| B 거대 종합 MOC | 3,000 단어 | 8회 | 12회 |
순진한 셈이면 B 압승(8+12 > 3+2). BM25는 세 보정을 겁니다:
결과: 희귀 핵심 단어("성우하이텍")의 밀도가 높고 짧은 문서 A가 더 높게 나올 수 있습니다. "단어를 많이 담은 문서"가 아니라 "핵심 단어를 군더더기 없이 담은 문서"가 이깁니다.
BM25식 검색을 Sparse(희소) 검색이라 부릅니다. 문서를 "사전의 모든 단어 = 한 칸"인 거대한 벡터로 본다면, 한 문서엔 그중 몇 칸만 켜지고 나머지는 전부 0이라서 텅 빈(희소) 벡터가 되기 때문입니다. 앞 장 Dense(밀집, 거의 다 채워짐)와 정반대입니다.
정확한 고유명사·제품명·코드·드문 전문용어에 매우 강합니다(임베딩이 약한 바로 그 지점). 하지만 동의어·말바꿈에는 약합니다 — "반려견"으로 찾으면 "강아지"만 쓴 문서를 못 찾습니다. 그래서 다음 장의 하이브리드(Dense+Sparse)가 필요합니다.
FTS5 trigram 채널(4채널 중 가중치 0.4로 가장 큼)입니다. trigram은 글자를 3개씩 잘라 색인하는 방식인데, 한국어처럼 띄어쓰기·형태소가 까다로운 글에서 부분 문자열 매칭에 유리합니다. 다만 trigram은 2글자 미만(예 "AI", "팀")은 색인 못 해, 코드가 그런 짧은 토큰엔 LIKE 보조 검색을 둡니다. (코드: graphrag_core.py 검증 — 손석희. 원전: Robertson & Zaragoza 2009.)ANN & HNSW — 수만 점에서 빨리 찾기
2장의 의미 검색을 다시 떠올리면, 질문 벡터에서 가장 가까운 문서 벡터를 찾아야 합니다. 가장 정확하게 하려면 전부 하나씩 비교(brute-force)합니다 — 우리 엔티티 7,281개면 질문마다 7,281번 비교. 이건 우리 규모에선 순식간이지만, 벡터가 수백만~수십억 개인 대형 서비스에선 한 번 검색에 수 초가 걸립니다.
ANN(근사 최근접 이웃, Approximate Nearest Neighbor): "정확히 1등"을 포기하는 대신 "거의 1등"을 훨씬 빠르게 찾는 기법들의 총칭입니다. 약간의 정확도를 속도와 맞바꿉니다.
HNSW(계층적 탐색 가능한 작은 세계 그래프): 가장 널리 쓰이는 ANN 인덱스입니다. 점들을 여러 층의 지름길 그래프로 연결해 둡니다. 위층은 듬성듬성(멀리 점프), 아래층은 촘촘(정밀 탐색). 검색은 맨 위층에서 대충 가까운 곳으로 점프 → 한 층 내려가 더 좁히기 → … → 맨 아래층에서 정밀 탐색으로 끝냅니다.
덕분에 비교 횟수가 전체(N)에서 로그(log N) 수준으로 줄어, 수백만 점에서도 밀리초 안에 찾습니다.
대규모에서 압도적으로 빠릅니다. 하지만 근사라서 가끔 진짜 1등을 놓칩니다(속도↔정확도 trade-off). 또 인덱스를 메모리에 올리고 관리하는 운영 부담이 있습니다.
arXiv:1603.09320.)하이브리드 & RRF — 공정하게 합치기

2~3장에서 봤듯 Dense와 Sparse는 약점이 정확히 반대입니다. 한쪽이 놓치는 걸 다른 쪽이 잡습니다. 그래서 둘(실제로는 네 채널)을 같이 돌려 결과를 합치는 게 하이브리드 검색입니다.
| 질문 유형 | Dense(의미) | Sparse(BM25) |
|---|---|---|
| "반려견" → "강아지" 글 | 강함 | 약함 |
| "성우하이텍" 정확 매칭 | 약함 | 강함 |
| 코드·제품명·드문 용어 | 약함 | 강함 |
| 번역·말바꿈 | 강함 | 약함 |
두 검색의 점수 척도가 완전히 다릅니다. 의미 유사도는 0~1, BM25는 0~수십. 그냥 더하면 BM25가 항상 이깁니다. 점수를 정규화(0~1로 스케일)하는 방법도 있지만, 한 채널에 이상치 하나만 있어도 전체가 흔들립니다.
RRF(역순위 융합, Reciprocal Rank Fusion)의 발상은 단순하고 강력합니다. 점수는 버리고 순위만 쓴다. 각 채널에서 k등인 문서에게 1/(60+k)점을 주고, 채널들끼리 더합니다.
왜 상수가 60일까요? 1등과 2등의 점수 차가 지나치게 벌어지지 않게 완충하는 역할입니다(작으면 1등이 과하게 지배). 또 새 채널을 끼워 넣어도 기존 순위가 안 망가집니다 — 각 채널이 독립적으로 순위만 내면 되니까요.
| 문서 | Dense | Sparse | 분해 | 엔티티 | RRF 합 |
|---|---|---|---|---|---|
| X 두루 상위 | 2등 | 1등 | 5등 | 3등 | 0.064 |
| Y 한 채널만 1등 | 1등 | — | — | — | 0.016 |
한 채널에서만 1등인 Y보다, 여러 채널이 동시에 추천한 X가 약 4배 높습니다. "여러 관점이 합의한 문서"를 신뢰하는 것 — 이게 RRF의 본질입니다.
우리는 두 개가 아니라 네 채널을 RRF로 합칩니다. 각 채널에 가중치를 곱해 합산합니다.
| 채널 | 무엇으로 찾나 | 가중치 |
|---|---|---|
| Dense 의미 | 문장 의미 벡터(MiniLM) | 0.30 |
| Sparse 키워드 | FTS5/BM25 어휘 | 0.40 |
| Decomposed 분해 | 질문을 작은 질문들로 쪼개 검색 | 0.15 |
| Entity 엔티티 | 그래프 엔티티 벡터 매칭 | 0.15 |
리랭커 — 마지막 정밀 심사
2장의 임베딩 검색은 빠릅니다. 비결은 질문과 문서를 각자 따로 벡터로 만들어 두고(미리 계산) 비교하기 때문입니다. 이런 방식을 bi-encoder(두 개를 따로 인코딩)라 합니다. 빠른 대신, 질문과 문서가 서로를 보며 판단하지 못해 미묘한 관련성을 놓칩니다.
리랭커(reranker)는 보통 cross-encoder입니다. 질문과 문서를 하나로 이어 붙여 한 모델에 같이 넣고, "이 둘이 얼마나 맞는지"를 직접 점수 냅니다. 질문과 문서가 서로를 참고하며 판단하니 훨씬 정밀합니다.
| bi-encoder (1차 검색) | cross-encoder (리랭커) | |
|---|---|---|
| 방식 | 질문·문서 따로 벡터화 | 질문+문서 같이 입력 |
| 속도 | 빠름(미리 계산) | 느림(매번 계산) |
| 정밀도 | 보통 | 높음 |
| 쓰는 곳 | 전체에서 1차 후보 추리기 | 추려진 소수만 재정렬 |
1차 검색이 대충 끌어올린 후보의 순서를 크게 개선합니다(논문 기준 MRR@10 +27%). 하지만 느려서 전체에는 못 씁니다. 또 1차 검색이 애초에 못 끌어올린 문서는 리랭커도 살릴 수 없습니다(없는 후보는 못 고름).
BAAI/bge-reranker-base cross-encoder가 재채점한 뒤, 커뮤니티·중심성 보강을 거쳐 Top-5를 냅니다. (원전: Nogueira & Cho 2019, arXiv:1901.04085.)bge-reranker-v2-m3로 바꿔봤더니(이전 R10 실험), 오히려 top-1 정확도가 8→7로 퇴행해 폐기했습니다. "더 큰 모델 = 항상 더 좋음"이 아니라는 산 증거입니다. 12장에서 재실험 가치를 다시 따집니다.지식 그래프 & 커뮤니티

[[링크]]·태그에서 가져온다 — 지식 정리와 검색이 한 AI 파이프라인.지금까지(2~7장)는 "질문과 비슷한 문서 찾기"였습니다. 하지만 어떤 질문은 관계를 묻습니다 — "X가 무엇과 연결돼 있지?", "이 주제들이 어떻게 이어지지?". 문서를 따로따로 보면 답이 안 나옵니다. 지식 그래프는 개념·인물·문서를 점(엔티티)으로, 그 사이 연결을 선(관계)으로 그려 "이어짐"을 직접 다룹니다.
지식 그래프는 두 층입니다. TBox(개념틀)는 "세상에 어떤 종류가 있고 어떻게 연결될 수 있나"를 정한 설계도예요(예: '사람'·'프로젝트'가 있고, '사람—참여—프로젝트' 연결이 가능하다). ABox(사실)는 그 틀에 담긴 실제 데이터고요(예: '재경—참여—패스트캠 강의'). 합치면 TBox(틀) + ABox(사실) = 지식 그래프입니다.
여기가 가장 흔히 오해하는 지점입니다. ① 링크를 "만드는" 단계(지식 정리)와 ② 링크를 "그래프로 옮기는" 단계(인덱싱)를 꼭 나눠야 합니다.
- ① 링크 저작 = AI가 한다. 자료를
/knowledge-manager(LLM 에이전트)로 정리하면, AI가 내용을 읽고 관련 노트끼리[[링크]]를 걸고#태그를 답니다. 즉 "무엇이 무엇과 연결되나"(그래프의 구조)를 AI가 정합니다. (사용자가 손으로 위키링크를 다는 게 아닙니다.) - ② 인덱싱 = 규칙(rule)이 한다. 런타임 인덱서(
entity_extractor.py)는 그 AI가 달아둔 링크·태그를 정해진 규칙대로 그래프 DB로 옮깁니다 —[[위키링크]]→cites,#태그→belongs_to, 같은 문장 동시등장→co_occurs. 이 옮기는 단계엔 LLM이 전혀 없습니다.
그래프에는 촘촘히 연결된 점 무리가 자연스레 생깁니다. 이걸 자동으로 묶는 게 커뮤니티 탐지이고, 가장 널리 쓰는 알고리즘이 Louvain입니다(모듈러리티라는 "안은 빽빽, 밖은 성김" 지표를 최적화). 우리는 4계층(C0~C3)으로 묶습니다.
검색에서는 "이 커뮤니티에 속한 문서"라는 신호를 가산점으로 씁니다(관련 주제 묶음을 함께 끌어올림).
GraphRAG Local / Global — 우리의 정직한 위치
마이크로소프트가 2024년 정리한 GraphRAG는 질문을 두 종류로 나눕니다.
- Local(국소) 질문 — "X가 무엇과 연결됐지?" 특정 엔티티의 이웃을 그래프에서 탐색해 답합니다. 범위가 좁고 구체적.
- Global(전역) 질문 — "내 지식 전체의 큰 주제는?" 이건 문서 몇 개로 안 됩니다. 먼저 커뮤니티마다 LLM이 요약을 만들고(Map), 그 요약들을 다시 종합해(Reduce) 답합니다. 이 Map-Reduce 요약이 MS GraphRAG의 시그니처입니다.
우리는 그래프(엔티티·관계·커뮤니티)와 Local 탐색 구조는 실제로 갖췄습니다. 단, MS GraphRAG의 시그니처 중 인덱싱 시점의 LLM 작업은 아직 placeholder(빈 껍데기)입니다 — ①인덱서가 글을 다시 읽어 LLM으로 관계를 추출하는 부분(우리 인덱서는 그 대신 AI가 ingest 때 달아둔 링크·태그를 규칙으로 옮김), ②커뮤니티를 LLM이 문장으로 요약하는 부분(현재 요약은 "구성원 나열" 자동 라벨 9,100개 = LLM 요약 0건), ③전역 Map-Reduce 종합. 주의: 그래프의 링크 자체는 AI(KM ingest)가 만든 것이고, "LLM이 없다"는 인덱싱·요약 단계에 한정된 이야기입니다.
arXiv:2404.16130.)평가 지표 — 숫자로 증명하기
- hit@5 — 상위 5개 안에 정답이 하나라도 들어갔나(예/아니오). 24개 질문 중 몇 개 성공인지로 봅니다(우리 = 10/24). "찾았나/못 찾았나"의 기본 척도.
- precision@5 — 상위 5개 추천 중 정답(gold) 비율. 2개가 정답이면 2/5 = 0.4. "추천 5개가 얼마나 깨끗한가."
- MRR(평균 역순위) — 첫 정답이 몇 등에 나오나 →
1/등수의 평균. 1등이면 1.0, 3등이면 0.33. "정답을 얼마나 위로 올렸나." - coverage — 검색이 결과를 하나라도 돌려준 비율(우리 = 1.0, 한 번도 빈손 아님). ⚠️ 주의: "정답을 맞췄나"는 coverage가 아니라 hit@5가 봅니다. 둘은 다릅니다.
| 질문 | 첫 정답 등수 | MRR 기여 = 1/등수 |
|---|---|---|
Q01 GraphRAG | 1등 | 1 / 1 = 1.00 |
| Q12 프롬프트 설계 영향 | 2등 | 1 / 2 = 0.50 |
| Q09 Anthropic AI Safety | 3등 | 1 / 3 = 0.33 |
| Q04 Claude Code 스킬 | 못 찾음 | 0 |
한 지표만 보면 안 됩니다. 같은 "정답 1개 찾음"이라도 1등에 올렸으면(MRR 1.0) 5등에 올린 것(MRR 0.2)보다 훨씬 나은 검색입니다. hit@5는 이 차이를 못 봅니다 — 그래서 함께 읽습니다.
왜 SQLite·MiniLM인가 + 더 좋은 대안
우리 검색은 엔티티·관계·커뮤니티를 SQL로 join하면서, 동시에 이름·한국어명·설명을 빠르게 키워드 검색해야 합니다. SQLite는 서버가 필요 없고(in-process), 설정이 0이고, 트랜잭션을 지원하는 SQL 엔진이며 전체가 파일 하나(vault_graph.db, 현재 435MB)로 운용됩니다. 우리 규모에선 별도 검색 클러스터보다 "단일 DB + WAL + 읽기전용 서버"가 단순하고 안전합니다.
키워드 채널은 SQLite의 FTS5 trigram입니다. 한국어처럼 띄어쓰기·형태소가 까다로운 글에서 3글자 단위 부분 매칭이 잘 듣습니다. 이름·설명·출처를 한 FTS 테이블로 묶고 id로 join해 동명이인 충돌을 피합니다. 다만 FTS5는 어휘 검색이라 관계·말바꿈·frontmatter 전용 별칭에는 약하고(그래서 Dense·그래프로 보강), 2글자 미만 토큰은 LIKE 보조가 필요합니다.
paraphrase-multilingual-MiniLM-L12-v2는 문장을 384차원 벡터로 만드는 작은 다국어 모델입니다. 우리 인덱스는 노트 3,740 + 엔티티 7,278 벡터라, 384차원이면 전부 정확 비교(exact cosine)해도 충분히 작고 빠릅니다. API 호출이 없어 비용·지연·프라이버시 위험이 0입니다. 같은 모델로 노트와 엔티티를 모두 임베딩하고, 모델이 바뀌면 전체 재색인을 강제해 "서로 다른 의미공간이 섞이는 사고"를 막습니다. 다만 경량(384차원)이라 최신 다국어 모델보다 품질 천장이 낮고, 노트는 앞 500자만 보므로 긴 문서·관계 질의에서 신호가 약해집니다(벤치의 L1 약점·Q24 교차언어 miss가 그 신호).
| 대안 | 장점 | 정직 판정 |
|---|---|---|
| SQLite FTS5 (현재) | embedded·단일파일·트랜잭션·SQL join+그래프를 한 DB에 | 유지. 우리 규모에 최적의 단순성 |
| Tantivy | Rust 풀텍스트, BM25, 빠른 시작 | 실익 낮음 — 별도 인덱스 동기화 부담 |
| Postgres+pgvector | SQL+ACID+벡터를 한 서버에, HNSW | 조건부 — 멀티유저·10만+ 벡터면 유력. 지금은 운영비>실익 |
| LanceDB | 로컬 임베디드 벡터DB | 유지 — 벡터만 바꿔선 L1 관계 문제 안 풀림 |
| Qdrant/Chroma | 벡터DB, 메타 필터, 하이브리드 | 유지 — 서비스 운영이 늚. QPS·멀티테넌트면 검토 |
| OpenSearch | BM25+k-NN 프로덕션 검색엔진 | 유지 — 대규모·분산·검색팀 있을 때. 개인 vault엔 과함 |
| 대안 | 장점 | 정직 판정 |
|---|---|---|
| MiniLM (현재) | 384차원·로컬·무료·빠름·비용0 | 유지 — baseline으로 적합 |
| BAAI/bge-m3 | 1024차원·8192토큰·100+언어·dense/sparse/멀티벡터 한 모델 | 바꿀 가치 1순위 A/B. 교차언어·L1 의미 recall 개선 후보(재색인 비용↑) |
| multilingual-e5-large | 다국어 E5, 1024차원 | 2순위 A/B — 쿼리 prefix 등 적용 세부 필요 |
| gte-multilingual-base | 75언어·8192컨텍스트·768차원 | 2순위 A/B — 긴 문서·한국어 후보 |
| jina-embeddings-v3 | 다국어·8192·차원 축소 가능 | 실험 후보 — 장문·다국어 강점 |
| OpenAI/Cohere/Voyage | 고성능 API 임베딩 | 조건부 — 품질↑지만 API 비용·외부전송·로컬원칙과 충돌 |
리랭커는 현 bge-reranker-base 유지가 기준점이고, bge-reranker-v2-m3는 과거 퇴행 이력이 있어 새 벤치로 재실험 후 판단합니다(7장 일화).
검색이 정답 문서를 잘 찾나
난이도(레벨)별 — 어디가 강하고 약한가
| 레벨 | 설명 | hit@5 | MRR |
|---|---|---|---|
| L0 직접조회 | "GraphRAG", "MCP" 같은 키워드 | 0.83 | 0.72 |
| L1 관계 | "reranker 재정렬 원리" 같은 개념 | 0.20 | 0.13 |
| L2 멀티홉 | "프롬프트 설계가 성능에 미치는 영향" | 0.40 | 0.14 |
| L3 합성 | "내 지식 전체 핵심 주제 3가지" | 0.33 | 0.33 |
직접 키워드 조회(L0)는 아주 강함(0.83). 관계·개념(L1)이 최약점(0.2) — 12장에서 본 임베딩 보강의 1순위 타깃입니다.
실제 사례 — 무엇을 검색했고 어떻게 나왔나
MCP를 검색하면 vault에 946개가 매칭됩니다. CLI는 관련도 순위가 없어(경로·이름순) 정작 핵심 문서가 1,000개 밖으로 묻혀 못 찾았던 케이스 — 재경님이 직접 발견하신 문제.MCP-생태계-현재와-미래-MOC를 1등으로. hit@5 ✓ · MRR 1.0.Journey-13-Search-v2-4Channel-Server, Journey-16-…-CE-Mastery (우리가 정답으로 정해둔 노트)Reranker-검색-재정렬-기법, ettin-reranker-graphrag — 리랭커를 정확히 다룬 더 좋은 노트를 올림! 그런데 gold 목록에 없어 'miss'.임베딩과-벡터공간-기하학는 그 영어구가 frontmatter(aliases)에만 있고 본문은 한국어. = 메타데이터 색인 + 교차언어 이중 난이도(일부러 어렵게 낸 스트레스 테스트).Vector-Embeddings, Embedding-벡터-의미의-숫자화 — 관련은 있으나 정확 gold 아님. 진짜 retrieval 갭.전체 24개 질문 결과표 펼치기 ▾
| ID | Lv | 질문 | hit@5 | P@5 | MRR |
|---|---|---|---|---|---|
| Q01 | L0 | GraphRAG | 1 | 0.4 | 1 |
| Q02 | L0 | 프롬프트 엔지니어링 | 1 | 0.4 | 0.33 |
| Q03 | L0 | 얼룩소 아카이브 | 1 | 0.4 | 1 |
| Q04 | L0 | Claude Code 스킬 | 0 | 0 | 0 |
| Q05 | L0 | 김재경 | 1 | 0.2 | 1 |
| Q19 | L0 | MCP | 1 | 0.2 | 1 |
| Q06 | L1 | 얼룩소에서 AI에 대해 쓴 글 | 0 | 0 | 0 |
| Q07 | L1 | 에이전트 팀 구성하는 방법 | 0 | 0 | 0 |
| Q08 | L1 | 성우하이텍 마스터 강의 내용 | 0 | 0 | 0 |
| Q09 | L1 | Anthropic AI Safety 관련 연구 | 1 | 0.2 | 0.33 |
| Q10 | L1 | Obsidian 자동화 워크플로우 | 0 | 0 | 0 |
| Q20 | L1 | RAG와 GraphRAG의 차이 | 1 | 0.2 | 1 |
| Q21 | L1 | reranker 재정렬 원리 | 0 | 0 | 0 |
| Q22 | L1 | 벡터 임베딩 의미 검색 | 0 | 0 | 0 |
| Q23 | L1 | agent orchestration patterns | 0 | 0 | 0 |
| Q24 | L1 | Embedding Vector Space Geometry | 0 | 0 | 0 |
| Q11 | L2 | AI가 민주주의에 미치는 영향 (내 글) | 0 | 0 | 0 |
| Q12 | L2 | 프롬프트 설계가 에이전트 성능에 | 1 | 0.2 | 0.5 |
| Q13 | L2 | Knowledge Manager에서 GraphRAG | 1 | 0.2 | 0.2 |
| Q14 | L2 | 2026 AI 에이전트 트렌드·사례 | 0 | 0 | 0 |
| Q15 | L2 | 얼룩소 플랫폼 분석·콘텐츠 전략 | 0 | 0 | 0 |
| Q16 | L3 | 내 지식 핵심 주제 3가지 | 0 | 0 | 0 |
| Q17 | L3 | AI 연구→강의→실무 전체 여정 | 0 | 0 | 0 |
| Q18 | L3 | 정치/사회 글쓰기와 AI 연구 연결 | 1 | 0.2 | 1 |
haiku · sonnet · opus가 답하면
모델 종합 점수 (24문항 평균)
| 티어 | answer | 정확도 | 근거 | 환각↓ | 검색거부 |
|---|---|---|---|---|---|
| haiku | 61.1 | 59.8 | 52.9 | 0.29 | 2 |
| sonnet | 70.8 | 74.4 | 71.5 | 0.18 | 0 |
| opus | 66.6 | 67.2 | 60.5 | 0.24 | 1 |
sonnet이 sweet spot — 정확도·근거·환각·안정성(검색거부 0회) 모두 최고이면서 opus보다 쌉니다. (환각↓ = 낮을수록 좋음)
난이도별 — 큰 모델이 항상 낫진 않다
| 레벨 | haiku | sonnet | opus | 한 줄 |
|---|---|---|---|---|
| L0 직접 | 43.5 | 64.2 | 64.8 | sonnet=opus, sonnet이 저렴 |
| L1 관계 | 62.1 | 78.9 | 78.6 | sonnet 최강 |
| L2 멀티홉 | 77.8 | 67.4 | 39.6 | opus 붕괴(날조) |
| L3 합성 | 65 | 63 | 75 | opus 우위(깊은 종합) |
실제 사례 — 모델이 어떻게 다르게 답하나
전체 24개 질문 × 3모델 점수표 펼치기 ▾
| ID | Lv | 질문 | haiku | sonnet | opus |
|---|---|---|---|---|---|
| Q01 | L0 | GraphRAG | 72 | 58 | 15✗ |
| Q02 | L0 | 프롬프트 엔지니어링 | 5✗ | 72 | 82 |
| Q03 | L0 | 얼룩소 아카이브 | 25 | 72 | 89 |
| Q04 | L0 | Claude Code 스킬 | 72 | 85 | 80 |
| Q05 | L0 | 김재경 | 15 | 20 | 35 |
| Q19 | L0 | MCP | 72 | 78 | 88 |
| Q06 | L1 | 얼룩소 AI 글 | 78 | 82 | 72 |
| Q07 | L1 | 에이전트 팀 구성 | 62 | 85 | 58 |
| Q08 | L1 | 성우하이텍 강의 | 75 | 82 | 78 |
| Q09 | L1 | Anthropic AI Safety | 42 | 68 | 72 |
| Q10 | L1 | Obsidian 자동화 | 62 | 78 | 85 |
| Q20 | L1 | RAG와 GraphRAG 차이 | 72 | 80 | 88 |
| Q21 | L1 | reranker 재정렬 | 78 | 92 | 85 |
| Q22 | L1 | 벡터 임베딩 검색 | 72 | 68 | 82 |
| Q23 | L1 | agent orchestration | 5✗ | 72 | 81 |
| Q24 | L1 | Embedding Vector Space | 75 | 82 | 85 |
| Q11 | L2 | 민주주의 영향 (내 글) | 82 | 15 | 10 |
| Q12 | L2 | 프롬프트 설계 영향 | 88 | 90 | 0 |
| Q13 | L2 | KM에서 GraphRAG | 72 | 82 | 85 |
| Q14 | L2 | 2026 에이전트 트렌드 | 65 | 72 | 78 |
| Q15 | L2 | 얼룩소 콘텐츠 전략 | 82 | 78 | 25 |
| Q16 | L3 | 핵심 주제 3가지 | 65 | 72 | 78 |
| Q17 | L3 | AI 연구→강의→실무 | 68 | 82 | 79 |
| Q18 | L3 | 정치 글쓰기·AI 연결 | 62 | 35 | 68 |
✗ = 검색거부(검색 0회). 점수 0~100, 환각은 0~1(낮을수록 좋음).
어디서 왔나 — 8편의 원전
| 개념 | 논문 · 저자 · 연도 | 핵심 기여 | 우리 적용 (정직) |
|---|---|---|---|
| RAG | Lewis 외, 20202005.11401 | LLM(기억)+외부 검색(인덱스) 결합. RAG 원전. | /search=검색(R). 생성(G)은 opt-in |
| BM25 | Robertson & Zaragoza, 2009 | TF 포화·길이정규화·IDF 확률 랭킹. | Sparse = FTS5 trigram(BM25 계열) |
| Dense | Karpukhin 외, 20202004.04906 | 의미 벡터 검색. BM25 대비 +9~19%p. | 로컬 MiniLM-L12-v2 (학습방식은 다름) |
| HNSW | Malkov & Yashunin, 20181603.09320 | 계층 그래프 근사 최근접(ANN). | 개념만 — 미사용(규모 작음) |
| RRF | Cormack 외, 2009 | 점수 아닌 순위로 Σ1/(k+rank) 융합. | 4채널 핵심 1/(60+rank) — 코드 1:1 ✅ |
| Cross-encoder | Nogueira & Cho, 20191901.04085 | (질문,문서) 동시 입력 재정렬. MRR@10 +27%. | 리랭커 bge-reranker-base |
| GraphRAG | Edge 외(MS), 20242404.16130 | LLM 추출→커뮤니티 요약→Local/Global. | 계열. LLM추출·요약·Map-Reduce=placeholder → MS 동등 ❌ |
| RAGAS | Es 외, 20232309.15217 | 정답 없이 faithfulness 자동평가. | 외부 미도입 — 자체 judge가 같은 정신 |
FTS5 trigram · Dense = paraphrase-multilingual-MiniLM-L12-v2 · 리랭커 = BAAI/bge-reranker-base · RRF k=60 4채널. HNSW/faiss = 미사용.보강 결과 & 한 장 요약
- →임베딩 A/B (BGE-M3) → 라이브 적용 완료. 우리 24문항 벤치 정답률 18 → 23/24 (소형 MiniLM → 다국어에 강한 bge-m3 + 채널 합산 방식 개선). 라이브 검색에 이미 켜져 동작 중.
- →gold-set 재검토 → 위에서 예고한 그대로 Q07·Q08·Q21은 검색이 옳고 우리가 적어둔 정답이 좁았던 것(교정). 단 Q09 한 개는 교정해도 못 잡은 진짜 약점으로 정직하게 남겼습니다(정답 끼워맞춰 24 만들기 ❌).
- →과적합 아님 증명 → 24문항과 겹치지 않는 48개 독립 질문으로도 측정 → 9→15 동반 상승(하나도 안 깎임). "벤치 하나로 전체 시스템 못 잡는다"를 광범위 검증으로 해소.
gr_goldfix_24q.json·broadval-48q.
(a) 자동 튜닝 (autoresearch)
한 변수만 바꿔 좋아지면 keep·나빠지면 버리는 자동 루프(autoresearch)를 119라운드 돌렸습니다. 결과: 현 가중치가 이미 최적 — baseline(hit@5 10/24·MRR 0.307)을 못 넘었어요. 합성점수만 높고 hit@5를 잃은 후보는 거부 = 정직한 negative result.
(b) LLM 답변합성
코드 완료 · 기본 OFF(opt-in). provider를 교체 가능한 구조로 — claude -p는 6/15부터 별도 과금이라 폐기, codex_cli 주력. 어느 경로가 막혀도 기본 검색은 멀쩡.
진짜 다음 레버 (벤치가 가리킨 것)
| 레버 | 왜 |
|---|---|
| 임베딩 A/B (BGE-M3 1순위) | L1 관계·교차언어 약점의 후보 (단 "모델만으로 해결"은 과장 — 12장) |
| gold-set 재검토 | Q08·Q21처럼 검색은 좋은데 gold가 좁아 'miss'로 찍힌 건 벤치를 고치는 문제 |
| frontmatter/alias 색인 | Q24 같은 진짜 갭(교차언어·메타데이터-only)을 잡는 retrieval 보강 |
| 답변합성 켜기 · 기본 sonnet | 검색 Top-5를 자연어 답으로(게이트). 모델 기본값 = sonnet |
한 장 요약
우리 /search = GraphRAG 계열 — AI(/knowledge-manager)가 만든 [[링크]]·태그를 규칙으로 옮긴 지식 그래프 + 4채널 하이브리드. MS의 인덱스-시점 LLM 추출·요약·Map-Reduce는 placeholder → "동등"은 과장, "계열"은 사실.
하이브리드 = 의미(dense)+키워드(BM25/FTS5)+질문분해+엔티티를 RRF(순위 융합)로 합치고 cross-encoder로 재정렬해 Top-5. HNSW는 우리 규모엔 불필요.
벤치(24문항·3모델): 검색은 직접조회(L0) 강·관계(L1) 약. 답변은 sonnet sweet spot(정확·안전), opus는 깊은 종합만·검색 약하면 날조.
도구 선택: 우리 규모엔 SQLite/FTS5 + MiniLM 유지가 합리적. 바꿀 가치는 저장소가 아니라 임베딩 모델 A/B(BGE-M3).
메타 교훈: 지식을 정리하는 AI 파이프라인(/knowledge-manager)이 남긴 링크·태그가 그대로 검색 그래프의 엣지가 된다 — 정리와 검색이 한 흐름 / 평가엔 ground-truth 앵커가 필수(모델은 모르면 자신있게 지어낸다).
근거: 벤치 aktofu-bench-table.md · 논문 domain-konan-papers.md · 스택분석 sonseokhee-stack-rationale-alternatives.md · live vault_graph.db 2026-06-07 KST
여기까지 — 그리고 다음
검색의 속을 다 열어봤습니다. 의미 + 단어 + 그래프를 섞어 순위를 매기고, 리랭커로 마지막 정밀 심사를 한 뒤 Top-5를 내놓는다 — 이게 우리 /search입니다.
→ Part 3: 이 검색을 봇 에이전트들이 실제로 어떻게 쓰는가 — vault·Discord·여러 봇이 한 몸처럼 도는 원리.
봇들은 어떻게 한 몸처럼 일하나
vault(지식) + LLM(머리) + Discord(대화)로 굴러가는 AI 봇 팀의 원리
이 파트가 원리라면, 실제로 봇 하나를 세우고 일 시키고 회의시키는 실전 절차는 별책 🤖 봇 운영 실전 가이드를 따라가면 됩니다.
- AI 봇 하나가 실제로 무엇으로 굴러가는지 (세션 + 다리 + 지식)
- 디스코드 메시지 하나가 봇 안에서 거치는 여정
- 봇들이 서로 일을 나누고 합치는 법 (오케스트레이션·회의·완료 게이트)
- 왜 봇마다 폴더(볼트)를 따로 두는지 — 관리가 쉬워지는 핵심 이유
- 봇이 Part 2의
/search로 vault 지식을 꺼내 쓰는 법 - 그리고 — 이 가이드북이 바로 그 봇 팀으로 만들어진 과정
vault · LLM · Discord — 세 조각이면 된다
복잡해 보이는 AI 봇 팀도, 근본부터 보면 세 조각의 조합입니다. 왜 하필 이 셋일까요? 하나씩 빼보면 답이 나옵니다.
second brain스스로 일하는 AI 팀
- vault 가 없으면? LLM은 아는 게 없어 지어냅니다(환각). Part 1·2에서 본 그 문제죠. 그래서 근거가 될 지식 더미가 필요합니다.
- LLM 이 없으면? vault는 그냥 죽은 문서 폴더입니다. 읽고 연결하고 답을 만들 "머리"가 있어야 살아납니다.
- Discord 가 없으면? 똑똑한 봇이라도 혼자 갇혀 있습니다. 사람이 일을 시키고, 봇끼리 의논할 통로가 있어야 "팀"이 됩니다.

/search로 찾고, 여러 봇이 디스코드로 의논하며 나눠 썼어요. 문서가 곧 시스템의 산출물인 셈이죠(자세한 과정은 뒤의 '만들어진 과정' 절에서).봇 하나가 도는 법 — 그리고 메시지의 여정
봇 한 마리를 해부하면 이렇습니다. 어렵지 않아요 — 세 부품입니다.
오해부터 풀어요. LLM 그 자체는 사실 기억이 없습니다. 한 번 질문을 받아 답을 내놓으면 그걸로 끝 — 방금 무슨 대화를 했는지조차 다음 순간엔 잊습니다(이걸 stateless, "상태가 없다"고 해요). 똑똑하지만 매번 처음 만나는 천재인 셈이죠.
그래서 그 위에 "세션(session)"이라는 작업 환경을 씌웁니다. 세션은 LLM에게 ① 대화의 맥락(지금까지 무슨 일을 했는지)을 계속 쥐여주고, ② 도구(파일을 읽고·쓰고·/search로 검색하는 손발)를 붙여주고, ③ "읽고 → 생각하고 → 도구 쓰고 → 또 생각하고"를 반복하게 합니다. 이렇게 LLM + 맥락 + 도구 + 반복 루프를 묶은 게 바로 에이전트(agent), 즉 "일하는 봇"이에요. 그냥 챗봇이 말만 한다면, 에이전트는 손발이 달려 직접 파일을 읽고·고치고·검색합니다 — 그래서 봇이 위키를 "쓰고" 노트를 "정리"할 수 있는 거예요.
그래서 "봇 = 컴퓨터에 늘 켜둔 AI 작업 창(세션) 하나"라고 보면 정확합니다. 그 창이 노트를 읽고·생각하고·파일을 씁니다. 이제 그 창을 세 부품으로 뜯어볼게요.
- 세션(session) = 봇의 몸. 각 봇은 컴퓨터에서 AI 코딩 도구의 작업 세션을 하나 계속 켜둔 상태예요. 우리 팀은 대부분 Claude Code로 돌고, 이미지 담당 손석희는 Codex로 돕니다(둘 다 같은 페르소나·규율을 따라요). 이 세션이 노트를 읽고·생각하고·파일을 씁니다. 봇 = "끄지 않고 늘 켜둔 AI 작업 창" 한 개라고 보면 정확합니다.
- 다리(bridge) = 봇의 입과 귀. 그 세션과 디스코드 사이를 잇는 작은 연결 프로그램이 있습니다. 디스코드에 글이 올라오면 다리가 그걸 세션에 전해주고, 세션이 내놓은 답을 다시 디스코드로 내보냅니다. 그래서 우리는 디스코드에서 봇에게 말을 겁니다. (연결 방식은 봇 종류마다 달라요 — Claude Code 봇은 디스코드 연동 다리를, Codex 봇인 손석희는 'app server'라는 전용 서버 기능을 씁니다. 역할은 같아요: 디스코드 ↔ 세션 잇기.)
- 지식(vault) = 봇의 책상. 봇은 자기 폴더(vault 영역)의 노트를 읽고, 필요하면
/search로 더 찾습니다(Part 2).
"코난, 이 주제 자료 좀 찾아줘"라고 디스코드에 쓰면, 안에서 이런 일이 벌어집니다:
/search로 vault 뒤지고 → 자료 정리
④ 답을 다리가 다시 디스코드로 발송 → 우리가 코난의 답을 본다즉 "디스코드 채팅"처럼 보이는 게, 실제로는 메신저 ↔ 다리 ↔ AI 세션 ↔ 지식 사이를 오가는 왕복입니다.
봇은 어떻게 기억하나 — 다중 메모리
앞 절에서 봤듯, LLM은 본래 기억이 없습니다(stateless — 매번 처음 만나는 천재). 그런데 우리 봇들은 어제 한 약속도, 사용자 취향도, 자기 말투도 일관되게 기억하죠. 비결은 "기억을 파일로 적어 두는" 메모리입니다.
그런데 모든 기억을 한 곳에 쌓으면 안 됩니다(곧 볼 "책상에 서류 쌓기"의 함정). 그래서 성격에 따라 4갈래로 나눕니다.
| 메모리 | 무엇을 담나 | 누가 보나 |
|---|---|---|
| ① 봇 개인 | 그 봇만의 말투·역할·실수 복기 | 그 봇만 |
| ② 공유 | 사용자 취향·피드백·프로젝트 상태 등 공용 사실 | 모든 봇 · 여러 컴퓨터 |
| ③ 컴퓨터별 | 파일 경로·설치 상태 등 그 PC에만 맞는 정보 | 그 컴퓨터의 봇 |
| ④ 회의/프로젝트 | 지금 하는 일의 진행 기록(누가·언제·무엇을) | 그 일에 참여한 봇 |
덕분에 코난의 말투를 고쳐도 다른 봇은 멀쩡하고(①), "사용자가 이런 걸 싫어한다"를 한 번 배우면 모든 봇이 공유하며(②), 컴퓨터가 달라도 경로 때문에 안 꼬이고(③), 회의 진행은 기록이 진실이 됩니다(④).
그럼 봇은 이 메모리를 언제 읽을까요? 세션이 새로 시작될 때 자동으로요. SessionStart 훅(세션 시작 시 도는 작은 장치)이, 봇이 깨어나는 순간 ① 관련 메모리 목록과 ② 동료 봇 명단·역할을 손에 쥐여줍니다. 봇이 "내가 누구이고, 무엇을 기억해야 하고, 동료가 누구인지"를 매번 처음부터 챙기는 거예요.

봇들은 어떻게 협업하나 — 오케스트레이션
봇 하나로는 큰일을 못 합니다. 사람 팀처럼 나눠서 합니다. 그 조율을 오케스트레이션(orchestration, 지휘)이라 부르고, 그 일을 맡는 봇이 오케스트레이터(우리 팀에선 카파시)예요.
- 회의 thread. 봇 둘 이상이 30분 넘게 붙는 일이면, 본 채팅방이 아니라 전용 스레드를 따로 엽니다. 거기에 "무엇을·누가·언제까지"를 적은 회의 문서(SoT)를 두고, 모두 그걸 기준으로 움직여요. 잡담이 아니라 기록이 진실입니다.
- 일 나누기(dispatch). 오케스트레이터가 각 봇에게 "무엇을, 어떻게"까지 구체적으로 맡깁니다. "대충 알아서" 가 아니라 방법·도구·금지사항까지 첫 메시지에 담아야 봇이 헤매지 않아요.
- 진행 추적(watchdog). 일정 담당 봇(스트레인지)이 회의가 멈췄는지 주기적으로 지켜봅니다. 끝나지도 않았는데 누가 손 놓으면 깨우고, 진짜 끝나야 회의를 닫습니다.
- 완료 게이트. 아무 봇이나 "끝!"이라 못 합니다. 검증 → 보고 → 확인 단계를 거쳐야 완료로 칩니다. 그래서 "다 됐다는데 사실 안 됨" 사고를 막아요.
이 협업 방식은 사고를 겪으며 다듬어졌습니다. 핵심 규율 셋만 볼게요.
- 위임은 네 가지를 다 적어서 — 봇에게 일을 줄 때 목표·입력·출력·기한을 첫 메시지에 다 담습니다. "알아서 해줘"는 봇이 헤매는 지름길이에요.
- 시각은 하나로(KST) — 봇이 여럿일 때 시간 표기가 제각각이면 꼬입니다. 모든 봇이 한국 시간(KST) 하나로 통일해요.
- 봇끼리는 디스코드로만 — 한 봇이 다른 봇의 작업 창에 직접 명령을 꽂으면 "누가·언제 시킨 일인지" 출처가 사라져 위험합니다(내부판 프롬프트 인젝션). 그래서 봇 간 신호는 오직 디스코드(@호출)로만 — 누가 보냈는지 늘 남게요.
봇 팀과 역할 — 나눠서, 잘하는 걸
한 명의 만능 AI에게 다 시키지 않고, 역할을 나눈 여러 봇으로 굴립니다. 사람 팀과 똑같아요 — 조율하는 사람, 조사하는 사람, 글 쓰는 사람이 따로 있죠. 각자 자기 성격(말투)과 전문 분야가 있습니다.
| 봇 | 맡은 일 | 특징 |
|---|---|---|
| 카파시 | 오케스트레이션 — 일을 나누고 합치는 지휘자 | "근본부터 보면…" first-principles |
| 코난 | 자료조사·사실 확인 — 출처를 찾아 교차검증 | "진실은 언제나 하나" 추측 인용 0 |
| 스트레인지 | 일정·진행 관리 — 회의 멈춤 감시(watchdog) | 시간·종료 조건 담당 |
| 글재경 | 글쓰기·윤문 — AI 티 문장을 사람 결로 | 내용 불변, 문체만 손질 |
| 손석희 | 이미지 생성 — 설명 그림·다이어그램 | 여러 워커 병렬 생성 |
| 허사비스 | 이미지 검토 — 개념 적합·깔끔함 확인 | 생성↔검토 짝꿍 |

왜 봇마다 볼트(폴더)를 따로 두나
이 파트에서 가장 중요한 설계 결정입니다. 봇마다 자기 작업 폴더(볼트 영역)를 따로 두고, 그 정체성을 세 겹으로 잡습니다 — 두 장의 "이름표 파일"과, 깨어날 때 자동으로 더해지는 한 겹(앞 절의 SessionStart)이에요.
📋 CLAUDE.md
그 봇의 규칙·업무 지침. "이 폴더에선 이렇게 일해라"를 적은 작업 설명서.
🎭 soul.md
그 봇의 성격·말투·역할. "너는 누구이고 어떻게 말하는가"를 적은 페르소나 카드.
⏰ SessionStart 주입
그 봇의 기억·동료 명단. 파일이 아니라, 깨어날 때 자동으로 더해지는 세 번째 겹(앞 절).
예를 들어 어떤 봇의 soul.md는 대략 이런 식이에요(개념 예시):
이런 카드가 봇마다 따로 있어서, 세션이 시작될 때 자기 카드만 읽고 그 정체성으로 일합니다.
soul.md가 단순한 자기소개라면 봇은 금세 제 성격을 잊습니다. 그래서 우리 soul.md엔 페르소나를 강제하는 장치가 박혀 있어요.
- 강제 규율 블록 — "매 응답에서 이 말투를 최소 하나는 써라" 같은 자가 점검 규칙. 빠뜨리면 스스로 어긴 걸 알아채게.
- Voice & Tone — 어떤 단어·어조를 쓰고 무엇을 피하는지(예: 어려운 영어 약어 대신 쉬운 우리말).
- 금지 행동 — "이런 건 하지 마라" 목록(예: 출처 없는 단정, 다른 봇 사칭).
- 에러 처리 — 막혔을 때 어떻게 보고하고 누구에게 넘기는지.
이 블록들 덕에, 봇은 대화가 길어져도 자기다움을 유지합니다 — "친절한 비서"라고 한 줄 적어두는 것과는 차원이 달라요.
이렇게 규칙(CLAUDE.md)·성격(soul.md)·자동 주입(SessionStart)을 봇별로 분리하면 좋은 점이 셋입니다.
- 컨텍스트 격리 — 각자 필요한 것만 본다. LLM은 한 번에 읽고 기억할 수 있는 양이 정해져 있어요. 이걸 컨텍스트 윈도우(context window)라 하는데, "한 번에 책상에 펼쳐 놓고 볼 수 있는 종이의 양"이라 보면 됩니다. 그런데 "많이 올릴수록 좋다"가 아니라 반대예요 — 책상에 서류를 너무 쌓으면 사람도 정작 중요한 한 장을 놓치죠. 모든 봇의 규칙을 한곳에 욱여넣으면 LLM도 똑같이 집중이 흐려지고, 비용도 늘고, 가끔 엉뚱한 규칙을 자기 것인 양 따라 합니다. 그래서 핵심은 "많이"가 아니라 "딱 필요한 것만" — 봇마다 자기 폴더·자기 규칙만 보면 가볍고 정확해집니다.
- 관리 부담 경감. 코난 말투를 고치고 싶으면 코난 soul.md만, 일정 규칙을 바꾸려면 스트레인지 폴더만 건드리면 됩니다. 서로 안 섞이니 한 봇을 고쳐도 다른 봇이 안 망가져요.
- 정체성이 안 흔들린다. 각자 soul.md가 자기 정체성이라, 코난이 갑자기 카파시처럼 말하는 일이 없습니다.

규칙이 많아지면 — rules-system
봇을 오래 굴리면 규칙이 계속 늘어납니다. "이럴 땐 이렇게 해라", "저건 하지 마라"… 그런데 이 규칙을 전부 한 파일(CLAUDE.md)에 욱여넣으면 문제가 생겨요 — 앞서 본 "책상에 서류 쌓기"입니다. 규칙이 너무 많으면 AI가 정작 중요한 규칙을 놓칩니다.
그래서 우리는 규칙을 이렇게 정리합니다(이걸 Progressive Disclosure, "필요한 만큼만 펼치기"라고 해요).
- INDEX(목차) 한 장 — "이런 상황엔 이 규칙 파일을 봐라"를 적은 길잡이(라우터). 이것만 늘 켜 둡니다.
- 상황별 규칙 파일 — 회의 규칙, 검색 규칙, 보고 규칙처럼 주제별로 따로.
- 그때그때 로드 — 회의를 열 때 비로소 "회의 규칙"을 읽습니다. 평소엔 안 읽어 가볍게.
덕분에 규칙이 수백 개로 늘어도, 봇은 지금 상황에 맞는 규칙만 손에 들고 일합니다 — 똑똑하면서 가벼워요.

.claude/rules/ 폴더가 정확히 이 구조예요 — 목차 하나가 상황을 보고 알맞은 규칙으로 안내합니다.봇이 /search로 지식을 꺼내 쓴다
봇이 똑똑하게 답하는 비결은 기억력이 아니라 검색입니다. 모르는 걸 지어내는 대신(Part 2의 뼈아픈 교훈!), vault에서 관련 노트를 찾아 읽고 답합니다. 그 도구가 Part 2에서 본 /search(GraphRAG·하이브리드 검색)예요.
"우리 메모리 규칙 어떻게 되더라?"라고 물으면 — 봇은 외워둔 걸 읊지 않고, /search "메모리 규칙"으로 vault의 관련 노트를 찾아 그 내용을 근거로 답합니다. 노트가 바뀌면 답도 자동으로 최신이 되고, "어느 노트에서 나왔다"는 출처까지 댈 수 있어요.

/search로 그때그때 vault에서 꺼내 쓴다이 가이드북이 만들어진 과정
가장 좋은 증거는 이 문서 자체입니다. 여러분이 지금 읽는 이 가이드북은, 방금 배운 그 봇 팀이 실제로 만들었어요. 그 과정을 그대로 공개합니다.
- 설계 합의. 사람(재경님)이 "graph-search 가이드북을 3-Part로 키우자"고 제안 → 카파시가 질문을 주고받으며 설계 문서(spec)로 정리하고 승인받음. (먼저 합의, 그다음 제작.)
- 자료조사(코난). Part 1의 인물·방법론을 1차 출처로 조사 — 블로그 같은 2차 자료는 배제하고 본인 글·발언만. (이 과정에서 "Karpathy가 옵시디언을 쓴다"는 사실까지 바로잡았어요.)
- 집필·조립(카파시). 기존 Part 2를 흐름에 맞게 다듬고, Part 1·3을 쓰고, 공유 디자인(이 두부 톤)을 입혀 조립.
- 이미지(손석희 → 허사비스). 손석희가 여러 워커로 그림 12장을 병렬 생성 → 허사비스가 톤·개념·가독성을 검토해 승인.
- 윤문(글재경). AI 티 나는 문장만 사람 결로 손질 — 단, 내용·숫자·인용은 한 글자도 안 건드림.
- 검증·전달. 모든 파일이 제대로 됐는지 점검(GREEN) → 라이브 vault에 동기화 → 사람에게 보고.
흔한 오해 3가지
봇을 처음 접하면 자주 하는 오해가 있어요. 셋만 바로잡으면 전체 그림이 또렷해집니다.
아닙니다. 봇은 외우지 않습니다. 모르는 걸 외운 척 지어내면(환각) 오히려 위험해요. 그래서
/search로 그때그때 vault에서 꺼내 근거로 답합니다(앞의 /search 절). 기억력이 아니라 검색력이 똑똑함의 핵심이에요.한 봇에 다 시키면 어느 일도 깊지 못하고 실수도 못 잡습니다. 역할을 나눠 각자 깊어지고 서로 검토하게 하는 게(손석희 그림 → 허사비스 검토) 품질의 비결입니다(앞의 '봇 팀' 절).
Part 2 벤치마크가 보여준 교훈 — 항상 그렇진 않습니다. 작은 모델이 더 정확·안전한 영역이 있고, 큰 모델은 검색이 부실하면 자신있게 지어내기도 합니다. 좋은 검색 + 적정 모델이 큰 모델 하나보다 낫습니다.
한 장 요약 · 작게 시작하기
AI 봇 팀 = vault(지식) + LLM(머리) + Discord(대화). 봇 하나 = 켜둔 AI 세션 + 디스코드 다리 + 자기 vault.
한 만능 봇이 아니라 역할을 나눈 여러 봇이 디스코드에서 @호출로 협업한다. 조율은 오케스트레이터가, 진행은 watchdog이, 완료는 게이트가 지킨다.
봇마다 볼트를 따로 두고 CLAUDE.md(규칙)+soul.md(성격)+SessionStart(자동 주입) 3겹으로 정체성을 잡는다 — 컨텍스트가 가볍고, 관리가 쉽고, 정체성이 안 흔들린다(오염 방지).
봇은 다중 메모리(개인·공유·컴퓨터별·회의 4갈래)로 기억을 잇고, 규칙은 rules-system(목차 + 상황별 그때 로드)으로 가볍게 — "많이"가 아니라 "필요한 것만"이 핵심.
봇은 외우지 않고 /search로 vault에서 그때그때 꺼내 답한다. P1(쌓기)·P2(찾기)·P3(꺼내쓰기)는 한 흐름.
개념·원리 중심 설명 · 우리 시스템 사례 (운영 토큰·세부 경로 등은 안전상 생략)