donghakim.dev — zsh
← ls ../blog

팀 지식 저장소를 중앙화한 이야기

AI 부하직원에게 일을 잘 시키는 법

팀 지식 저장소를 중앙화한 이야기 · cover

요즘 유튜브 추천을 켜면 새 모델, 새 기능, 컨텍스트 관리, 토큰 효율 같은 키워드가 끝없이 깔립니다. 그런데 한 명의 개발자로서 매일 일을 시켜 보면 막상 병목은 모델 쪽이 아니라는 느낌이 점점 분명해집니다. 시킬 거리와 잘 했는지 확인할 거리를 양쪽 다 사람 머릿속에서 꺼내고 있는 한, 모델이 아무리 빨라져도 결과물의 천장은 결국 그 사람의 지식에서 결정되더군요.

이 글은 그 천장을 조금이라도 들어 올려 보려고 만든 작은 시스템에 대한 이야기입니다.


LLM 은 똑똑한 부하직원입니다

LLM 은 시키는 만큼 충실하게 일합니다. 결과의 품질은 결국 두 가지에 달려있다고 보고 있어요.

잘 시키기(Prompt) + 잘 했는지 확인하기(촘촘한 Test)

잘 시키는 일은 결국 논리적이고 명료하게 말하는 능력인데, 이건 시키는 사람에게 그 도메인의 지식이 있어야 가능합니다. 어디까지가 자명하고 어디부터 비자명한지, 어떤 가정이 깔려 있고 어떤 함정이 있는지를 짚어 줄 수 있어야 "논리적이고 명료한 지시" 가 됩니다. 이게 빠지면 모델은 그럴듯하지만 빗나간 코드를 짧은 시간 안에 잘도 만들어 냅니다.

잘 했는지 확인하는 일도 마찬가지입니다. 테스트 코드 자체는 AI 가 잘 짜줍니다. 그런데 의미 있는 테스트, 즉 도메인적으로 함정이 있는 경계 조건을 노리는 테스트는, knowledge 가 없으면 애초에 떠올릴 수가 없습니다. 통과해야 의미가 있는 케이스를 알지 못한 채로 짠 테스트는 통과해도 안심이 되지 않습니다.

예를 들어 저희 도메인에는 이런 상식들이 깔려 있습니다.

OTA 에서는 E/I 클래스를 노출하지 않습니다. INFANT 는 좌석수에 포함하지 않습니다. HOT 파일은 결제수단을 구분하지만 LIFT 파일에서는 결제수단이 구분되지 않습니다.

이 중 어느 하나라도 모르면, AI 가 만든 코드와 테스트는 자연스럽게 어색해집니다. 결국 매 대화마다 사람이 다시 받아 적어 주게 되고, 그 시간이 모이면 AI 가 가져다주는 효율을 절반 이상 깎아 먹습니다.


그런데 지금 우리의 knowledge 는 어디에 있나요

일부는 Notion 에 잘 정리되어 있습니다. 문제는 거기서부터 시작됩니다.

  • 그 문서의 존재를 알아야 쓸 수 있습니다.
  • 매번 경로를 명시적으로 알려줘야 AI 가 그 문서를 봅니다.
  • 무엇보다 Notion 페이지 구조는 LLM 이 읽기 좋은 형태가 아닙니다. MCP 같은 별도 셋업이 필요하고, 페이지가 산만하면 컨텍스트로도 잘 잡히지 않습니다.

그래서 같은 컨텍스트를 새 대화마다 다시 쏟아붓게 됩니다. "이런 게 있고, 저런 게 있고, 이건 이렇게 봐야 합니다…" 가 반복되면, 도구가 주는 효율은 빠르게 사라집니다.


아이디어 — 지식을 중앙으로 옮깁니다

최소한 "내가 몰라도, 내 부하직원은 알게" 만들자. 내 머릿속에만 남아 있는 지식을 자연스럽게 공유하는 시스템.

기존 방식과 비교해 보면 차이가 뚜렷합니다.

지금

  • "docs/api-guide.md 참고해서 구현해" — 매번 경로를 알려줘야 하고, 어디에 무엇이 있는지를 내가 기억하고 있어야 합니다.
  • "작업 내역을 /docs 에 저장해" — 며칠만 지나도 문서가 stale 해집니다. 잘못된 문서는 차라리 없는 게 낫습니다. 그 사이엔 AI 가 코드를 직접 탐색해 컨텍스트를 쌓는 편이 더 정확하기 때문입니다.

바뀌는 방식

  1. 작업 지시 → AI 가 먼저 문서고를 검색 → 관련 자료가 있으면 읽고 시작합니다.
  2. 작업 진행.
  3. 작업 마무리 → AI 가 새 문서 작성 또는 기존 문서 업데이트 를 제안합니다.

핵심은 양방향 이라는 점이에요. 기록만 강조하면 백업 폴더로 전락합니다. 조회가 같이 돌아야 비로소 가치가 회수됩니다.


구현 — team-knowledge 라는 공유 저장소

github.com/sum-air/team-knowledge 를 만들었습니다. trunk-based 로, 팀원이 함께 pull / push 합니다.

셋업은 Claude Code 에 한 줄을 던지면 끝납니다.

https://github.com/sum-air/team-knowledge 의 SETUP_FOR_AGENT.md 따라서 셋업해줘

그러면 에이전트가 알아서 다음 작업을 처리합니다.

  • ~/playground/team-knowledge/ (또는 사용자가 원하는 경로) 에 clone
  • ~/.claude/settings.json 에 PreToolUse hook 등록 (기존 hook 은 보존하면서 jq 로 병합)
  • 동작 검증 — 차단 / 우회 / repo 내부 세 가지 케이스의 exit 코드 확인
  • 자동 메모리에 트리거 등록

폴더 구조, 파일명, frontmatter, 작성 템플릿 같은 세부 규칙은 모두 저장소의 CLAUDE.md 가 관리합니다. 사람이 직접 외울 필요가 없도록 의도적으로 그쪽에 몰아 두었습니다.


동작 원리 — 두 가지 트리거

전체 흐름을 그림으로 그리면 다음과 같습니다.

loading diagram…

핵심 트리거는 두 개입니다.

1) 조회 — 새 작업이 시작되는 시점

세션이 시작되면 ~/.claude/CLAUDE.md 와 워크스페이스 단위의 CLAUDE.md, 그리고 자동 메모리가 같이 로드됩니다. 거기에 "새 작업이나 대화가 시작되면 team-knowledge/CLAUDE.md 를 먼저 읽고 그 규약을 이 세션에 적용한다" 한 줄을 심어 두면, 에이전트는 작업 키워드를 추출해 먼저 grep / glob 으로 기존 문서를 검색합니다.

관련 문서가 있으면 "이런 게 있어요. 참고하시겠어요?" 한 줄로 제안하는 식입니다. 사람이 "노션 어디 봤더라…" 를 반복하던 단계가 통째로 사라집니다.

2) 기록 — 커밋 / PR 직전의 강제 게이트

조회만 켜 두면 "읽기만 하고 적지는 않는" 시스템이 되기 쉽습니다. 그래서 PreToolUse hook 으로 한 번 강제합니다.

team-knowledge/hooks/team-knowledge-gate.shgit commit 이나 gh pr create 가 호출되기 직전에 발동해서, 이 작업에서 "저장할 만한 것이 있는지를 사용자에게 한 번이라도 제안했는지" 를 점검합니다. 그 단계 없이 그냥 넘어가려고 하면 exit 2 로 차단하고, stderr 로 체크포인트 메시지를 내려보냅니다.

# git commit / gh pr create 가 아니면 통과
if ! grep -qE '(^|[[:space:]|;&])(git[[:space:]]+commit|gh[[:space:]]+pr[[:space:]]+create)\b' <<<"$CMD"; then
  exit 0
fi

# repo 내부면 통과 (재귀 방지)
if [[ "$CWD" == "$REPO_ROOT" || "$CWD" == "$REPO_ROOT"/* ]]; then
  exit 0
fi

# 우회: TEAM_KB_SKIP=1 prefix
if grep -qE 'TEAM_KB_SKIP=1' <<<"$CMD"; then
  exit 0
fi

# 문서 자체 커밋은 통과
if grep -qE 'docs\(knowledge\)' <<<"$CMD"; then
  exit 0
fi

차단되면 에이전트가 받게 되는 메시지는 이렇습니다.

[team-knowledge gate] 커밋/PR 직전 강제 체크포인트

이 작업에서 team-knowledge/ 에 저장할 만한 내용이 있는지 먼저 검토하세요:
  • 비자명한 트러블슈팅 (에러 메시지에서 바로 안 드러나는 원인/해결)
  • 외부 시스템 발견 (IBS / Infobip / HOT·LIFT / 결제 PG 등)
  • "왜 X 대신 Y" 류 기술 결정 (ADR 후보)
  • 반복될 가능성 있는 패턴 / 장애 대응 절차

행동 지침:
  1) Grep/Glob 으로 team-knowledge/ 에서 관련 기존 문서 먼저 검색
  2) 저장 가치 있는 항목을 사용자에게 한 줄 이내로 제안 → OK 받으면 작성
  3) 정말 저장할 게 없다고 판단했으면 그 근거를 한 줄로 사용자에게 보고 후,
     명령 앞에 TEAM_KB_SKIP=1 prefix 를 붙여 재실행

원칙은 단순합니다. "그냥 커밋 통과" 를 실패 모드로 못 박아 두는 것이 거의 전부입니다. 침묵하지 말고, 저장할 거리를 한 줄 제안하든 "이번엔 저장할 게 없습니다" 라는 근거를 한 줄로 보고하든 둘 중 하나는 반드시 출력하도록 했습니다. 재귀 방지를 위해 team-knowledge 자체 저장소 안에서의 커밋은 통과시키고, 우회가 필요할 땐 TEAM_KB_SKIP=1 git commit ... 또는 docs(knowledge): ... 메시지를 쓰는 식으로 빠져나갈 수 있게 두었습니다.


폴더 — 무엇을 어디에 적나요

team-knowledge/
├── CLAUDE.md            # AI 행동 규약 (가장 중요)
├── README.md
├── troubleshooting/     # 증상 → 원인 → 해결
├── systems/             # 외부 시스템·도메인 지식
├── patterns/            # 재사용 가능한 코딩 패턴
├── runbooks/            # 운영·배포·장애 대응
└── decisions/           # ADR — 왜 이렇게 결정했나

각 폴더가 받는 내용은 대략 이렇습니다.

폴더무엇을 넣나요
troubleshooting/증상 → 원인 → 해결. 가장 흔합니다. 도메인별 하위 폴더(db/, auth/, jvm/ …)로 더 나눕니다
systems/외부 시스템·컴포넌트 지식 (HOT/LIFT, IBS API, Infobip 등). 공식 문서에 없거나 묻혀 있는 부분이 주로 모입니다
patterns/재사용 가능한 코딩·설계 패턴 (언어 독립)
runbooks/운영 절차, 배포, 장애 대응 체크리스트
decisions/ADR — "왜 X 대신 Y" 류 기술 결정. 0001-… 같은 번호 prefix 를 붙입니다

판단이 애매할 땐 일단 troubleshooting/ 이나 systems/ 에 넣고, 쌓이면 분리하는 식으로 운영합니다.

모든 문서는 frontmatter 를 필수로 요구합니다.

---
title: DB 커넥션  고갈  체크포인트
tags: [hikari, mysql, incident]
related_projects: [sumair-be-home, sumair-be-pay]
created: 2026-05-08
updated: 2026-05-08
---

related_projects 는 한 지식이 여러 프로젝트에 영향을 줄 때 명시합니다. 에이전트가 검색할 때 이 필드까지 같이 보기 때문에, 프로젝트 경계를 넘는 지식이 자연스럽게 다시 모이도록 의도한 것입니다.

반대로 저장하지 않는 것도 명시해 두었습니다.

  • 코드에서 명백히 읽히는 것
  • 공식 문서에 잘 정리되어 있는 것
  • 일회성 디버깅 로그
  • 개인 작업 메모

특히 "잘못된 문서는 차라리 없는 게 낫다" 는 원칙을 분명히 적어 두었습니다. AI 가 코드를 직접 읽으면 보통은 정확한데, stale 문서가 있으면 그걸 우선해서 따라가버리는 게 더 위험하기 때문입니다.


커밋 규약 — 코드와 문서를 분리합니다

문서화 커밋은 코드 커밋과 분리합니다. 그래야 hook 우회와 히스토리 추적 양쪽이 깔끔하게 정리됩니다.

docs(knowledge): add troubleshooting/db/connection-pool-exhausted
docs(knowledge): update systems/ibs-hot-lift/data-reference
docs(knowledge): decide 0001-channel-dimension-in-hot-views

PR 은 강제하지 않습니다 (trunk-based). 다만 폴더 구조를 크게 바꾸거나 컨벤션을 흔드는 변경은 PR 로 가져가도록 권장하고 있습니다.


실제로 일이 어떻게 바뀌었나요

이 시스템을 켜 둔 채 작업을 하면 같은 함정에 두 번 빠지지 않게 됩니다. 가장 최근 사례가 prod 배치의 메모리 누수 사고였는데, 진단을 마쳤을 때 손에 남은 결과물은 fix PR 하나가 아니라 다음 세 가지였습니다.

  • troubleshooting/jvm/batch-memory-leak-2026-05.md — 사고 타임라인, JSch Session leak 으로 좁혀 간 과정, heap dump 분석 요약
  • runbooks/jvm-memory-leak-diagnosis.md — 다음 누수 진단에서 재사용할 절차 (CloudWatch → ECS Exec → jcmd → Eclipse MAT)
  • 필요하면 decisions/..."왜 WebClient 싱글톤화는 보류했나" 같은 결정의 회고

그 뒤로 "메모리 누수" 같은 키워드를 던지면, 에이전트가 위 두 문서를 먼저 들고 옵니다. 다음 한 명 — 그게 미래의 저든 동료든 — 이 처음부터 시작하지 않아도 되도록 만드는 것이 결국 이 저장소의 목적이라고 정리해 두었습니다.


마무리

Git 이 single source of truth. 이번 단계는 개발팀 내부 자산. (비개발 직군까지 닿게 하는 일은 v2 의 과제로 미뤄 두었습니다.)

복잡한 RAG 인덱서나 별도 위키 플랫폼을 들이지는 않았습니다. 마크다운 + git + 30 줄짜리 bash hook 정도의 작은 조합으로도 충분히 굴러갑니다. 핵심은 어떤 데이터 스토어를 쓰느냐가 아니라, 조회와 기록을 양방향으로 강제하는 워크플로우 그 자체에 있다고 보고 있어요.

AI 가 점점 빨라지고 있는데 사람만 같은 자리에 멈춰 있는 느낌이 든다면, 가장 먼저 손볼 곳은 모델이 아니라 지식의 동선 일지도 모릅니다.

#ai#claude-code#devops#hooks#knowledge-management