![]()
레거시 프로젝트를 위한 로컬 지식 DB 구축기
들어가며
“이 로직 왜 이렇게 되어 있지?”
레거시 프로젝트를 다루다 보면 하루에도 몇 번씩 이런 질문을 하게 됩니다. 코드만 봐서는 알 수 없는 비즈니스 맥락, 당시의 의사결정 배경, 논의 과정에서 나왔던 대안들… 이런 것들이 슬랙 어딘가에, 노션 어딘가에 흩어져 있습니다.
직접 찾으려면 시간이 너무 오래 걸립니다. Claude에게 시켜도 마찬가지입니다. 슬랙이나 노션은 검색기능이 부족합니다. 잘 찾으려면 몇 분씩 걸리고, 토큰 비용도 만만치 않습니다.
그래서 로컬 지식 DB를 구축하기로 했습니다. 슬랙과 노션의 대화들을 정리해서 마크다운 문서로 지식화하고, Chroma 벡터 DB에 인덱싱해서 Claude가 MCP를 통해 빠르게 맥락을 검색할 수 있도록 만든 이야기입니다.
왜 필요했나
우리 팀의 oo 플랫폼 프로젝트는 3년이 넘었습니다. 그동안 축적된 도메인 지식이 상당합니다.
- oo 상품 계산 로직: “oooo를 왜 5개 타입으로 분리했지?”
- UI/UX 결정: “0000 연결 페이지 전환율이 왜 이렇게 낮았지?”
- 기술적 제약: “왜 이 API는 이 방식으로밖에 호출할 수 없지?”
이런 질문들에 대한 답이 다 있습니다. 문제는 어디에 있는지 모른다는 것입니다.
슬랙에서 직접 검색하면 노이즈가 너무 많습니다. "oooo"를 검색하면 수백 개의 메시지가 나오는데, 정작 핵심 결정이 담긴 스레드는 찾기 어렵습니다. 노션도 마찬가지입니다. 여러 문서에 조각조각 흩어져 있어서 전체 그림을 파악하기 어렵습니다.
구축 방법
1. 파이프라인 설계
문서 수집 (슬랙/노션 API)
↓
필터링
↓
LLM 문서화
↓
docs/context/ 저장
↓
번역
↓
Chroma 인덱싱
scripts/knowledge-pipeline/에 Python 스크립트를 만들었습니다. 핵심 흐름은 이렇습니다:
- 수집(Collect): Slack과 Notion API로 데이터를 가져옵니다
- 필터링(Filter): 관련 키워드와 관련성 점수로 걸러냅니다
- 문서화(Generate): Claude Batch API로 구조화된 마크다운 문서를 생성합니다
- 저장(Save):
docs/context/에 파일로 저장합니다 - 인덱싱(Index): 영어로 번역해서 Chroma에 벡터화합니다
2. 문서 포맷 정의
유지보수를 위해 일관된 문서 포맷을 정했습니다:
---
title: oooo 분리 로직
category: business-rule # business-rule | decision | constraint | glossary
scope: computer # computer | mouse | keyboard
status: active # active | deprecated | superseded
decision_date: 2024-03-15
updated_at: 2026-06-24
tags:
- memory
- monitor
- human
sources:
- channel: slack
url: https://your.slack.com/archives/xxx
---
# oooo 분리 로직
## 요약
한두 줄로 핵심만.
## 맥락
이것이 왜 존재하는지, 비즈니스 배경.
## 근거
- 결정 이유, 히스토리
- 관련 코드 경로
category로 문서 성격을 구분하고, scope로 어떤 앱/패키지와 관련된 내용인지 명시합니다. status는 문서의 유효성을 나타내는데, deprecated나 superseded로 표시된 문서는 검색에서 제외됩니다.
한글 검색의 함정
Chroma는 영어 기반 임베딩 모델을 사용합니다. 한글 문서를 그대로 인덱싱하면 검색 정확도가 현저히 떨어집니다.
"컴퓨터"를 검색했는데 엉뚱한 문서가 나오거나, 정작 관련 문서가 검색되지 않는 문제가 있었습니다.
해결책은 번역 레이어를 추가하는 것이었습니다:
한국어 문서 (원본, 사람이 읽는 용도)
↓
영어 번역 (검색용)
↓
Chroma 인덱싱
원본 마크다운 파일은 한국어로 유지하고, Chroma에는 영어 번역본을 저장합니다. 검색할 때는 질문을 영어로 번역해서 쿼리합니다.
용어 사전의 중요성
번역이 일관되지 않으면 검색이 제대로 안 됩니다. "담보"가 어떤 문서에서는 "coverage"로, 어떤 문서에서는 "guarantee"로 번역되면 검색 정확도가 떨어집니다.
그래서 도메인 용어 사전을 만들었습니다: 아래 내용은 가상입니다.
# docs/glossary/insurance-terms.yaml
terms:
공구리치다: 'concrete placement'
가방끈: 'educational credentials'
까부시기: 'unpacking'
# ... 100개 이상의 OO 도메인 용어
번역할 때 이 용어 사전을 시스템 프롬프트로 제공해서, 도메인 용어는 항상 일관되게 번역되도록 했습니다.
변경 사항 반영
문서 내용이 수정되면 어떻게 될까요? 매번 전체를 다시 인덱싱하면 비효율적입니다.
해결책은 content hash 기반 변경 감지입니다:
def _needs_reindex(self, doc_id: str, content_hash: str) -> bool:
"""Check if document needs re-indexing by comparing content hash."""
result = self.collection.get(ids=[doc_id], include=["metadatas"])
if not result["ids"]:
return True
existing_hash = result["metadatas"][0].get("content_hash", "")
return existing_hash != content_hash
문서 내용의 SHA-256 해시를 메타데이터에 저장해두고, 인덱싱 시점에 비교합니다. 내용이 바뀌지 않았으면 스킵합니다.
번역 결과도 캐싱합니다. API 비용을 아끼기 위해 translation-cache.json에 번역 결과를 저장해두고, 동일한 내용은 재번역하지 않습니다.
스킬로 만들어 필요할 때 추가
대량 수집은 파이프라인으로 하지만, 작업 중에 새로운 맥락을 발견하면 즉시 문서화할 수 있어야 합니다.
Claude Code 스킬 /doc-save를 만들었습니다:
/doc-save
이 스킬은:
- 현재 세션의 대화 내용을 분석해서 문서화할 주제를 제안합니다
- 노션이나 슬랙 링크를 주면 MCP로 내용을 직접 읽어서 자동으로 문서를 채웁니다
- 저장 후 Chroma에 인덱싱합니다
디스크와 Chroma 인덱스가 불일치할 때를 위한 동기화 기능도 있습니다:
/doc-save --sync
CLAUDE.md에 검색 가이드
Claude가 이 지식 DB를 활용할 수 있도록 프로젝트의 CLAUDE.md에 검색 방법을 안내했습니다:
## 문서 지식베이스
프로젝트 문서는 `docs/` 폴더에 정리되어 있으며,
Chroma MCP를 활용하여 벡터 DB(`docs_xxxxxxx`)로 검색하세요.
> **중요**: Chroma 컬렉션은 **영어 번역본**으로 인덱싱되어 있습니다.
> 검색 시 한국어 질문을 영어로 번역하여 query_texts에 전달하세요.
> 도메인 용어는 `docs/glossary/xxxxxxx-terms.yaml`을 참고하세요.
### 검색 방법
1. 사용자의 한국어 질문을 영어로 번역 (용어사전 참조)
2. `chroma_query_documents(query_texts=[영어 번역])` 호출
3. 결과의 `file_path`로 원본 한국어 .md 파일 Read
3년 이내 데이터만
너무 오래된 정보는 오히려 해가 됩니다. 3년 전에 결정된 내용이 지금은 완전히 달라졌을 수 있습니다. 잘못된 맥락을 제공하면 잘못된 판단을 유도합니다.
그래서 수집 기준을 최근 3년으로 제한했습니다:
sources:
slack:
date_from: '2023-05-28' # 3년 전부터
물론 정말 중요한 히스토리는 수동으로 문서화해서 추가할 수 있습니다.
효과
구축 후 체감되는 변화:
- 맥락 파악 시간 단축: 슬랙 뒤지던 시간이 검색 한 번으로 줄었습니다
- 토큰 비용 절감: 매번 슬랙 전체를 읽을 필요 없이, 요약된 문서만 읽으면 됩니다
- 온보딩 용이: 새로 합류한 팀원도 "왜 이렇게 되어 있지?"라는 질문에 빠르게 답을 찾을 수 있습니다
- 일관된 의사결정: 과거 논의 맥락을 알고 판단하니 같은 실수를 반복하지 않습니다
남은 과제
완벽하진 않습니다:
- 자동 수집 범위: 아직 수동으로 채널과 데이터베이스를 지정해야 합니다. 더 스마트한 필터링이 필요합니다
- 문서 품질: LLM이 생성한 문서가 항상 완벽하진 않습니다. 검수가 필요합니다
- 버전 관리: 같은 주제의 문서가 시간에 따라 여러 개 생기면 어떤 게 최신인지 혼란스러울 수 있습니다
마치며
레거시 프로젝트의 가장 큰 자산은 축적된 맥락입니다. 코드는 리팩토링할 수 있지만, "왜 이렇게 했는지"는 당시 사람들의 머릿속에만 있다가 사라지기 쉽습니다.
이 지식 DB가 그 간극을 조금이나마 메워주길 바랍니다.
여러분 팀은 과거의 논의 맥락을 어떻게 관리하고 계신가요?