-
코드 위키의 마지막 퍼즐, 모듈 문서 — AI 에이전트가 함수를 이해하는 방법IT 2026. 4. 26. 22:00
코드 위키 시리즈를 마무리하며
이 시리즈에서 지금까지 다룬 문서들이 있다:
- architecture.md — 레이어 구분, HLD, 데이터 모델, 외부 의존성, 설정 관리
- data-pipeline.md — 파이프라인 흐름도, 단계별 입출력, 캐시 전략
- ADR — 설계 결정의 맥락과 트레이드오프
이 문서들이 프로젝트의 숲을 보여준다면, 이번에 다룰 모듈 문서는 나무를 보여준다. 개별 모듈이 무엇을 하고, 어떤 함수가 핵심이며, 어떤 패턴으로 외부 자원을 사용하는지를 정리하는 문서다.
모듈 문서가 필요한 이유
"코드를 읽으면 되지, 왜 따로 문서를 쓰나?"라는 반론이 있을 수 있다. 사실 대부분의 모듈은 코드와 docstring만으로 충분하다. 모듈 문서가 필요한 건 다음 조건에 해당하는 모듈이다:
- 파이프라인의 진입점 — 전체 흐름의 시작이 되는 모듈
- 핵심 로직이 복잡한 모듈 — 알고리즘, 규칙 기반 분기, 다단계 처리
- 가장 큰 파일 — 500줄 이상이면 코드만으로 파악이 느려짐
- 고유한 외부 연동 패턴이 있는 모듈 — GPU 스케줄링, LLM 호출, 외부 API
15개 모듈이 있는 프로젝트에서 전부 문서를 쓸 필요는 없다. 핵심 모듈 5~6개만 골라서 쓰는 것이 현실적이다.
모듈 문서의 구조
실전에서 효과적인 모듈 문서는 다음 6가지 섹션으로 구성된다:
1. 한 줄 요약 + 목적
파일 이름과 역할을 한 줄로 요약하고, 2~3문장으로 목적을 서술한다.
# Narrator — LLM 내러티브 생성 > narrator.py — vLLM을 통해 각 이벤트에 자연어 내러티브를 생성한다. ## 목적 이벤트별 사진 메타데이터를 LLM에 제공하여, 가족 앨범에 어울리는 따뜻한 내러티브 텍스트를 자동 생성한다. 프로젝트에서 가장 큰 모듈(883줄).왜 LLM에게 중요한가: 에이전트가 "내러티브 생성 로직을 수정해줘"라는 요청을 받으면, 프로젝트 내 수십 개 파일 중 어느 파일을 열어야 하는지 한 줄 요약만으로 즉시 판단한다. "883줄"이라는 정보는 에이전트에게 "이 파일은 크니까 전체를 읽지 말고 필요한 함수만 찾아라"는 힌트가 된다.
2. 주요 함수 목록
모든 함수를 나열하는 게 아니라, 외부에서 호출하는 공개 함수만 정리한다. 함수 시그니처, 파라미터 의미, 반환 타입을 적는다.
## 주요 함수 ### detect_events(records, gap_hours, min_photos) → list[PhotoEvent] 핵심 클러스터링 함수. 2단계 알고리즘: 1. 시간 간격 분리: 인접 사진 간 gap_hours 이상이면 별도 클러스터 2. 소규모 병합: min_photos 미만은 "일상" 버퍼에 병합 ### group_by_year(records) → dict[int, list[PhotoRecord]] 연도별로 사진을 분류한다.왜 LLM에게 중요한가: 에이전트가 새 기능을 추가할 때 기존 함수를 재사용할지, 새로 만들지를 판단하는 핵심 근거다. 함수 목록이 없으면 에이전트는 코드 전체를 grep하면서 비슷한 함수를 찾아야 하고, 이미 있는 기능을 중복 구현할 확률이 높아진다.
3. 핵심 알고리즘/규칙
코드만으로는 "왜 이 규칙인지" 알기 어려운 비즈니스 로직을 표로 정리한다.
조건 결과 예시 dominant scene 존재 {년} {월} {scene}"2024년 5월 생일파티" scene 없고 dominant tag 존재 {년} {월} {tag}"2024년 5월 공원" 둘 다 없음 {년} {월} 일상"2024년 5월 일상" 왜 LLM에게 중요한가: 규칙이 표로 정리되어 있으면 에이전트는 규칙을 수정하거나 확장할 때 기존 패턴을 유지한다. "계절 정보도 라벨에 넣어줘"라는 요청이 오면, 기존 3가지 규칙에 자연스럽게 4번째를 추가할 수 있다. 코드에 if-elif 체인으로만 있으면 에이전트가 패턴을 놓치고 다른 스타일로 분기를 추가할 수 있다.
4. 외부 연동 패턴
GPU 스케줄링, LLM 호출, 외부 API 등 이 모듈만의 고유한 연동 방식이 있으면 코드 스니펫으로 보여준다.
## GPU 연동 패턴 def _gpu_acquire(): subprocess.run([str(GPU_SCHEDULER), "acquire", GPU_JOB_NAME], ...) def _gpu_release(): subprocess.run([str(GPU_SCHEDULER), "release", GPU_JOB_NAME], ...) GPU_JOB_NAME = "ollama" — vLLM과 Ollama가 같은 GPU를 공유하므로 동일 job name 사용.왜 LLM에게 중요한가: 에이전트가 GPU를 사용하는 새 기능을 추가할 때, 이 패턴을 따라 acquire/release를 반드시 포함시킨다. 패턴이 문서화되어 있지 않으면 에이전트가 GPU 스케줄러를 건너뛰는 코드를 작성할 수 있고, 이는 다른 작업과의 GPU 충돌로 이어진다.
5. 캐시 전략
이 모듈이 사용하는 캐시 파일, 캐시 키 형식, 캐시 hit 조건을 정리한다.
## 캐시 전략 - 캐시 파일: narrative_cache.json - 캐시 키: t{trip_id}|{날짜}|{순서} (예: t0|2024-05-15|0) - 캐시 hit이면 LLM 호출을 건너뛰어 GPU 시간 절약왜 LLM에게 중요한가: 캐시 키 형식을 알면 에이전트가 "캐시를 무효화하는 변경"과 "캐시에 영향 없는 변경"을 구분할 수 있다. 예를 들어 trip_id 생성 로직을 바꾸면 기존 캐시가 전부 무효화된다는 것을 미리 알 수 있다.
6. 의존성과 설정값
이 모듈이 import하는 내부/외부 의존성과 주요 상수를 표로 정리한다.
상수 값 설명 EVENT_GAP_HOURS48 이벤트 분리 기준 시간 MIN_EVENT_PHOTOS3 이 수 미만이면 "일상"으로 병합 LLM_MODELgoogle/gemma-4-26B-A4B-itvLLM 모델 왜 LLM에게 중요한가: "이벤트 분리 기준을 24시간으로 바꿔줘"라는 요청에 에이전트가 이 표에서 상수명과 현재 값을 찾아 정확히 변경한다. 상수명이 코드에만 흩어져 있으면 에이전트가 잘못된 변수를 수정하거나 하드코딩된 값을 놓칠 수 있다.
모듈 문서 작성 체크리스트
섹션 핵심 질문 LLM에게 주는 효과 한 줄 요약 이 파일이 무엇을 하는가? 올바른 파일을 즉시 찾음 주요 함수 외부에서 뭘 호출할 수 있는가? 기존 함수 재사용, 중복 방지 핵심 규칙 어떤 조건에서 어떤 결과가 나오는가? 규칙 확장 시 기존 패턴 유지 외부 연동 GPU, API 등 어떤 패턴으로 연동하는가? 새 연동 시 기존 패턴 따름 캐시 전략 무엇이 캐시되고 언제 무효화되는가? 캐시 영향 변경 사전 감지 설정값 조정 가능한 값은 무엇인가? 정확한 상수 변경 모든 모듈에 문서가 필요하지는 않다
15개 모듈이 있는 프로젝트에서 전부 문서를 쓰는 건 과잉이다. 다음 기준으로 5~6개만 선별하면 된다:
선별 기준 이유 예시 파이프라인 진입점 전체 흐름의 시작, 파라미터가 시스템 전체에 영향 extractor.py 복잡한 비즈니스 로직 조건 분기가 많아 코드만으로는 규칙 파악 어려움 grouper.py, narrator.py 가장 큰 파일 (500줄+) 코드 탐색에 시간이 오래 걸림 server.py (2,000줄) 고유한 외부 연동 GPU, LLM 등 특수한 패턴이 있는 모듈 narrator.py (GPU + vLLM) 나머지 모듈은 함수 docstring과 타입 힌트만으로 충분하다. 모듈 문서도 유지보수 대상이므로, 쓸수록 좋은 게 아니라 유지할 수 있는 만큼만 쓰는 게 맞다.
모듈 문서 vs docstring: 어디까지 문서에 쓰는가
모듈 문서와 docstring의 역할은 다르다:
모듈 문서 (modules/*.md) docstring (코드 내) 대상 사람 + AI 에이전트 개발자 (IDE에서 바로 봄) 범위 모듈 전체의 목적, 함수 간 관계, 외부 연동 개별 함수의 파라미터, 반환 타입 정보 "왜 이 모듈이 이렇게 구성되었는가" "이 함수를 어떻게 호출하는가" 유지보수 모듈 구조가 바뀔 때만 업데이트 함수 시그니처가 바뀔 때마다 업데이트 쉽게 말하면, docstring은 "이 함수가 무엇을 하는가"이고, 모듈 문서는 "이 함수들이 왜 이렇게 구성되어 있는가"다. 둘은 보완적이지 대체 관계가 아니다.
코드 위키 전체 구조 — 완성된 그림
이 시리즈에서 다룬 모든 문서를 디렉토리 구조로 보면 이렇다:
docs/ ├── architecture.md # 시스템의 숲 — 레이어, HLD, 의존성 ├── data-pipeline.md # 데이터의 여정 — 단계별 흐름과 캐시 ├── adr/ # 설계 결정의 맥락 │ ├── 0001-photo-backend.md │ ├── 0002-local-llm.md │ └── 0003-event-clustering.md ├── modules/ # 핵심 모듈의 깊은 이해 │ ├── extractor.md │ ├── grouper.md │ ├── narrator.md │ └── server.md └── contributing.md # 개발 가이드각 문서가 AI 에이전트에게 제공하는 맥락을 정리하면:
- architecture.md → "이 시스템이 어떻게 구성되어 있는가" (구조)
- data-pipeline.md → "데이터가 어떤 단계를 거치는가" (흐름)
- ADR → "왜 이런 선택을 했는가" (의도)
- modules/*.md → "이 모듈의 함수와 규칙이 어떻게 동작하는가" (구현)
숲에서 나무까지, 의도에서 구현까지. 이 네 가지가 갖춰지면 AI 에이전트는 프로젝트를 처음 보는 상태에서도 의미 있는 코드를 작성할 수 있는 맥락을 갖게 된다.
이 글은 생성형 AI의 도움을 받아 작성되었습니다. 원본 자료를 기반으로 AI가 초안을 생성하고, 작성자가 검토·편집하였습니다.
'IT' 카테고리의 다른 글
하네스 엔지니어링 9단계 베스트 프랙티스 #3. Skill 정의 (0) 2026.04.27 하네스 엔지니어링 9단계 베스트 프랙티스 #2. Code Wiki 작성 (0) 2026.04.27 하네스 엔지니어링 9단계 베스트 프랙티스 #1. 프로젝트 규칙 설정 (0) 2026.04.27 하네스 엔지니어링 9단계 베스트 프랙티스 #0. 업무 프로세스 매핑 (0) 2026.04.27 RAG 시스템에 코드 위키를 적용한 실전 사례 — 7개 문서로 11,000 벡터를 설명하다 (0) 2026.04.26 ADR, 설계 결정을 기록하는 가장 가벼운 방법 — AI 에이전트가 '왜'를 알게 되는 문서 (1) 2026.04.26 데이터 파이프라인 문서에는 뭘 써야 할까 — architecture.md가 다루지 않는 것 (1) 2026.04.25 아키텍처 문서에는 뭘 써야 할까 — AI 에이전트가 읽는 시대의 architecture.md (0) 2026.04.25 Docs-as-Code로 사이드 프로젝트 문서화하기 — 코드 위키 실전 적용기 (1) 2026.04.25 벡터 DB 온디맨드 관리 — Qdrant와 임베딩 서버의 cold start 실측 (0) 2026.04.24