원본 소설·정리한 설정·꺼내 쓰는 저장소, 3단계로 나눈다
소설 전체를 AI 입력창에 한꺼번에 밀어 넣지 않는다. 그러면 분량이 넘쳐 앞부분을 잊어버리기 때문이다. 대신 소설을 분석해 뽑아낸 정리된 핵심 사실만 폴더에 파일로 적어 둔다. 그 폴더를 프로젝트 단위 사실로 memory-bank에 동기화(sync)해 두면, 나중에 그림·대사를 만드는 순간 search_facts라는 도구로
그때 필요한 사실만 골라 꺼내 온다. 원본 소설은 계속 저장소 밖에 남는다.
원본 소설은 저장소 밖에
가공하지 않은 원본 소설 파일은 --source 옵션으로 파일 위치(전체 경로)만 알려 준다. 파일 자체는 복사하지 않는다. 프로젝트 폴더 안의 source/·uploads/·private/ 폴더는 git 추적에서 제외한다. memory-bank에도 올리지 않는다.
정리한 설정은 폴더에
소설 한 편마다 폴더 하나(memory-bank/novels/{novel_id}/)를 둔다. 확정된 이야기 사실·인물 설정·세계관·그림체 고정값을, 사람이 직접 읽고 고칠 수 있는 텍스트 파일로 쌓아 둔다. 무엇이 언제 바뀌었는지는 변경 기록 장부(ledger)에 남긴다.
꺼내 쓰는 저장소는 memory-bank에
동기화 스크립트가 이 폴더 내용을 프로젝트 단위 사실로 memory-bank에 올린다(있으면 갱신, 없으면 추가). memory-bank는 AI를 외부 저장소에 연결하는 표준 방식인 MCP로 붙는다. 그림 콘티를 짜거나 이미지를 그리는 순간 search_facts / trace_fact 같은 도구로 필요한 사실만 꺼내 온다.
원본 소설 → 빌더 → memory-bank 저장소 → 사용처로 흐른다
novel-builder.py라는 빌더 프로그램이 원본 소설을 잘게 나눠 분석하고,
memory-bank/novels/{novel_id}/설정 폴더를 채운 뒤,
novel-memory-bank-mcp-sync.mjs라는 동기화 프로그램이 그 내용을 memory-bank에 저장한다(있으면 갱신, 없으면 추가).
저장된 사실을 실제로 쓰는 곳은 네 군데다 — 그림 콘티 짜기(storyboard), 말풍선에 글자 얹기(lettering), 그림체 고정값 맞추기, 앞뒤 설정이 어긋나지 않는지 검사하기.
빌더 프로그램(novel-builder.py)이 소설을 처리하는 단계
extract_title → extract_characters → extract_chapters 순서로 제목·등장인물·챕터를 뽑아 원본 소설을 분해한다. 그다음 미리 정의해 둔 인물·세계관 정보와 합쳐, build_* 단계가 설정 데이터를 만든다. 이때 그림체 고정값(seed)은 같은 입력이면 늘 같은 값이 나오도록 계산한다.
마지막으로 run_sync가 동기화 프로그램을 불러 memory-bank에 저장한다(있으면 갱신, 없으면 추가).
10개 설정 영역과 memory-bank 저장 주소 대응표
각 영역은 딱 한 가지 역할만 맡는다. 확정된 사실은 canon.md에,
무엇이 언제 바뀌었는지는 continuity-ledger.md에,
아직 확실하지 않은 추측은 research/analysis-log.md에 나눠 적는다. 저장 주소(네임스페이스)는 “영역 이름 + 항목 고유 ID”로 자동으로 정해진다.
| Area | Path | Role | MCP namespace |
|---|---|---|---|
| manifest | manifest.json | 소설 ID·버전·소유자·분석 진행 상태·설정 목차 | novel-toon:{id}:manifest:root |
| canon | context/canon.md | 한번 정하면 안 바꾸는 이야기 사실. 분석 근거가 있을 때만 추가 | novel-toon:{id}:canon:{fact_id} |
| timeline | context/timeline.md | 챕터·회차·시대·실제 날짜 단위로 정리한 사건 | novel-toon:{id}:timeline:{event_id} |
| ledger | context/continuity-ledger.md | 결정 사항·설정 소급 변경(retcon)·모순·수정 이력 | novel-toon:{id}:ledger:{decision_id} |
| unresolved | context/unresolved-questions.md | 아직 못 푼 조사 질문·애매한 부분 | novel-toon:{id}:unresolved:{q_id} |
| characters | characters/{char_id}.json | 성격·목표·두려움·말투·외모 기준·인물 관계 | novel-toon:{id}:character:{char_id} |
| world | world/{eras,settings,culture} | era · setting · culture · technology · magic · politics | novel-toon:{id}:world:{entity_id} |
| visual | visual/style-bible.md + image-seeds.json | 그림체 기준·이미지 고정값·사진 고정값·제외할 요소 지시(negative prompt) | novel-toon:{id}:visual:{seed_id} |
| production | production/episodes/* · panels/* | 회차 기획·그림 콘티(storyboard)·컷(panel) 정보 | novel-toon:{id}:production:{ep_id} |
| research | research/{analysis-log,source-notes} | 분석 진행 기록·확정 전 추측 | novel-toon:{id}:research:{note_id} |
| source · uploads · private | source/ · uploads/ · private/ | 가공 전 원본 소설·이미지 등 참고 파일·비공개 자료 | — 추적·저장 안 함 — |
저장은 늘 같은 결과로, 조회는 프로젝트 범위 안에서만
동기화는 몇 번을 돌려도 결과가 같다. 폴더 상태가 같으면 저장되는 사실도 똑같다. 꺼내 올 때는 memory-bank의 도구 4개로 필요한 부분만 조회한다. 저장해 둔 설정 전체를 통째로 가져오지 않는다.
# 1) 원본 소설 → 설정 폴더 생성 + memory-bank 동기화 python3 scripts/novel-builder.py \ --project-root . \ --source /Users/me/blood-inheritance.md \ --novel-id blood-inheritance \ --sync --json # 2) 완료 검사 — 통과 못하면 “완료” 선언 금지 python3 scripts/validate-novel-builder.py \ --project-root . \ --source /Users/me/blood-inheritance.md \ --novel-id blood-inheritance \ --require-mcp-sync --json # 3) 웹툰 만들 때 — search_facts 도구로 필요한 사실만 조회 project=/Users/jung-wankim/Project/novel-toon query="novel_id=blood-inheritance character=han-seoyun visual seed"
설정이 조금씩 어긋나는 것을 막는 운영 규칙
오래 연재할수록 가장 뼈아픈 실패는, 인물 설정과 그림체 고정값이 회차를 거치며 조금씩 어긋나는 것이다(drift). 규칙은 간단하다 — 무언가 바뀌면 변경 기록 장부(ledger)에 적고, 가공 전 원본은 이 저장소에 들이지 않는다.
인물·그림체가 어긋나지 않게
- 인물 설정이나 이미지 고정값을 바꾸면 반드시
continuity-ledger.md에 한 줄 남긴다 - 고정값(seed)은
stable_seed(parts...)함수로 계산해 만든다 → 같은 입력이면 다시 돌려도 같은 값 - 고정값에
locked=true(잠금)이 걸린 항목은 장부 기록 없이 못 바꾼다 - 그림체 지침(style-bible)을 바꾸면, 이후 모든 회차를 다시 검토하게 된다
확실한 것과 추측을 구분
- 근거로 확정된 사실 →
canon.md - 분석 중인 가설 →
research/analysis-log.md - 아직 답 못 낸 질문 →
unresolved-questions.md - 추측을 확정 사실(canon)로 올리려면 근거 인용이 반드시 필요하다
privacy boundary (HARD)
memory-bank/novels/*/source/·uploads/·private/·visual/references/*폴더는 git 추적에서 제외한다- 가공 전 원본 소설은 저장소에 올리지 않는다 (설정값
sync_raw_manuscripts: false) - 사람이 정리한 요약(확정 사실·인물·세계관·그림체 정보)만 올린다
- 비공개 이미지는 파일이 아니라 ID(식별 번호)로만 가리킨다
작품끼리 섞이지 않게 분리
- 소설 한 편에 폴더 하나 — 여러 작품이 공유하는 인물·고정값 파일은 쓰지 않는다
- 저장 범위를
project(프로젝트 단위)로 고정 → 다른 작품으로 설정이 새는 것을 막는다 - 저장 주소에
novel_id(소설 ID)를 반드시 넣는다 - 꺼내 올 때 쿼리에도
novel_id=를 적어 주길 권장한다
그림·영상으로 나가기 전 지켜야 할 두 가지 약속
memory-bank에서 꺼낸 설정은 먼저 그림 콘티 데이터(storyboard JSON)로 굳어진다. 그 뒤 아래 두 가지 약속을 지켜야만 이미지와 영상으로 나갈 수 있다.
한국 웹툰식 손글씨 말풍선 규칙
- 일반 문서·자막·UI·세리프(꺾임 있는) 서체는 금지. 한국 웹툰 손글씨 느낌만 쓴다.
- 말풍선 안에는 대사만 넣는다. 화자 이름·콜론·괄호·설명·부가정보는 넣지 않는다.
- 데이터의
speaker는 화자 이름을 담아 두는 참고 항목이고, 말풍선에 실제로 그리는 것은text(대사) 값뿐이다. - 흰색 둥근 말풍선 + 짧은 꼬리 + 넉넉한 여백.
- 말풍선은 빈 공간에 놓는다 — 얼굴·눈·중요한 손·핵심 소품 위에 겹치지 않게.
- 짧고 자연스러운 한국어 문장을 쓴다. 길면 한 말풍선 안에서 두 줄로 나눈다.
- 최종 한국어 글자는 영상 편집 도구(Remotion)로 그림 위에 얹는다 — AI 이미지 생성에 맡기지 않는다.
컷마다 화면이 달라야 한다는 규칙
- 컷(panel)을 2개 이상 만들 때는 각 컷마다 서로 다른 화면 특징(
visual_signature)을 반드시 준다. - 이웃한 두 컷은 배경·카메라 거리·등장인물 조합·핵심 동작·감정 흐름 중 적어도 1가지는 달라야 한다.
- 연달아 나오는 컷에서 똑같은 “책상에 앉은 사무실” 구도를 반복하지 않는다.
- 한국어 대사는 영상 편집 도구(Remotion)로 말풍선을 얹는다 — 이미지가 직접 글자를 그리지 않는다.
- 영상으로 낼 때는 글자 없는 배경 이미지 + 그 위에 얹는 말풍선 방식을 선호한다.