소설 집필을 위한 LLM 편집 파이프라인 구축 방법
요약
소설 집필 과정에서 발생하는 편집 부담을 줄이기 위해 LLM을 편집 에이전트로 활용하는 파이프라인 구축 방법을 소개합니다. Claude Code를 사용하여 가공되지 않은 초안을 세계관 설정에 맞춰 분류하고 다듬는 워크플로우를 제안합니다.
핵심 포인트
- LLM을 저자가 아닌 편집자와 기록 보관자로 활용할 것
- 엄격한 승인 게이트를 통해 AI와 인간의 작업 경계를 유지
- 디렉토리 컨벤션과 마크다운 지침을 결합한 에이전트 워크플로우 구축
- 세계관 설정(WORLD.md)을 참조하여 일관성 있는 편집 수행
저는 Applied Yarns라는 연재 소설 프로젝트(이 글을 쓰는 시점에서는 아직 사이트가 구축되지 않았지만, 프로젝트의 몇몇 측면을 어떻게 설정하고 있는지 이곳에 게시하고 싶었습니다)를 작업하고 있으며, 이곳에 몇몇 허구의 작품들을 출판하고자 합니다. 그곳에서 탐구할 첫 번째 세계는 Vvell이며, 곧 appliedyarns 사이트에서 이에 대해 읽으실 수 있기를 바랍니다.
아이디어는 많지만, 현재로서는 매일 또는 매주 업데이트를 게시할 시간이 없으며, 저에게 가장 큰 장애물은 편집에 소비되는 시간입니다. 비교적 짧은 세션 내에 해당 세계관을 바탕으로 약 1,000단어 정도의 블록을 생성하는 것은 가능하다고 생각하지만, 직장 및 가족에 대한 의무를 고려할 때 같은 날에 이를 다듬고 편집할 시간은 없습니다.
LLM (Large Language Model)을 편집자로 사용하거나 이야기를 다듬어진 상태에 가깝게 만드는 것이 좋은 아이디어인지는 완전히 확신할 수 없지만, 한 번 시도해보고 싶었습니다. 동시에, 독자들이 AI를 사용하여 글을 쓰는 사람들을 정말로 신뢰하지는 않을 것이라고 생각하기 때문에, LLM이 이야기를 함께 다듬는 데 사용하는 정확한 프리라이팅 (freewriting) 원문 자료도 함께 게시하고 있습니다.
편집 에이전트 (editor agent)가 사용하는 문구 나 은유의 선택이 마음에 들지 않을 때가 있어서, 에이전트의 작업이 끝난 후에 저만의 편집 과정을 거치기도 합니다. 이를 통해 저는 일주일에 한 번씩 작은 "소식 (dispatches)"을 게시하는 것이 가능할 것이라고 생각하며, 이는 연재 소설 분야에 발을 들이려는 저와 같은 사람에게 좋은 목표라고 생각합니다.
프리라이팅 (freewriting)을 하다 보면 분명히 내용이 엉망이 되거나, 스스로 모순되게 작성하거나, 심지어 캐릭터 이름을 틀리기도 합니다. 또한 때로는 이야기에만 집중하지 않고 세계관 자체에 대해 쓰기 시작하기도 합니다. 편집 에이전트는 이 모든 것을 가져와서, 1,000단어 덩어리에서 바로 작업하는 것보다 훨씬 더 쉽게 직접 다듬을 수 있도록 원문 자료를 분류된 버킷 (buckets)으로 나누는 첫 번째 패스 (first pass)를 수행할 수 있습니다.
그래서 저는 기본적으로 편집상의 문제인 상황에 직면했습니다. 즉, 가공되지 않은 자유 글쓰기 (freewrites) 더미를 원본 자료를 잃지 않으면서, 그리고 세계관 설정 (world canon)이 어긋나지 않으면서 일관된 출판 아카이브로 변환하는 문제입니다. 지금까지의 경험으로는, 어떤 부분을 넘겨줄지 주의하기만 한다면 LLM이 이 문제를 해결하는 데 도움을 줄 수 있을 것 같습니다. 이 포스트는 제가 Claude Code를 통해 구축하고 있는 파이프라인과, LLM을 루프 (loop) 안에 두고 창의적인 작업을 수행하는 모든 이들에게 적용될 수 있는 지금까지의 교훈에 관한 것입니다.
제가 테스트 중인 규칙: LLM을 편집자 (editor)이자 기록 보관자 (archivist)로 사용하되, 결코 저자로 사용하지 마십시오. 그리고 엄격한 승인 게이트 (approval gate)를 통해 그 경계를 강제하십시오.
파이프라인의 형태
전체 과정은 디렉토리 컨벤션 (directory convention)과 기술 (에이전트가 무엇인가를 수행하기 전에 읽는 지침이 담긴 마크다운 파일)의 결합입니다. 흐름은 다음과 같습니다:
- 저는 가공되지 않은 자유 글쓰기 (freewrites)를
freewrites/inbox/에 넣습니다. 이 디렉토리는 Hugo의content/디렉토리
_외부_에 존재하므로, 가공되지 않은 내용이 실수로 출판되는 일이 절대 없습니다. - 저는 에이전트에게 인박스 (inbox)를 처리하라고 명령합니다. 에이전트는 모든 인박스 파일, 세계관 설정 파일 (
WORLD.md), 그리고 자신이 작성할 수 있는 각 섹션의 최근 출판된 항목 몇 가지를 읽습니다 (이를 통해 문체 (voice)를 맞추고 중복 여부를 확인할 수 있습니다). - 에이전트는
freewrites/inbox/PROPOSAL.md에 제안서 (proposal)를 작성하고 멈춥니다. 완전히 멈춥니다. 이 시점에서 에이전트는 다른 어떤 파일도 건드리지 않았습니다. - 저는 제안서를 읽고, 수정하거나 승인합니다.
- 승인된 후에야 에이전트는 세계관 설정을 업데이트하고, 다듬어진 항목들을 작성하며, 가공되지 않은 자유 글쓰기를 있는 그대로 아카이브하고, 스스로 뒷정리를 합니다.
2단계와 3단계는 분석 단계 (analyze phase)이며, 5단계는 작성 단계 (write phase)입니다. 이 둘 사이의 간극이 가장 중요한 부분입니다.
승인 게이트가 핵심 비결입니다
사람들이 흔히 시도하는 "LLM이 내 글을 처리하는" 워크플로우의 첫 번째 버전은 원샷 (one shot) 방식입니다. 즉, "여기 내 원문이 있으니 사이트를 업데이트해"라고 하는 것이죠. 저는 창의적인 작업의 경우 모델이 제법 괜찮은 결과물을 내놓더라도 이것이 실수라고 생각합니다. 왜냐하면 자신의 세계관에 대해 스스로 판단력을 발휘할 수 있는 순간을 놓치게 되기 때문입니다.
제안서 (proposal document)는 그 순간이 반드시 존재하도록 강제합니다. 에이전트는 각 자유 글쓰기 (freewrite)에 대해 다음 사항들을 나열해야 합니다:
- 설정 추가 (Canon additions) — 모든 새로운 고유 명사, 장소, 사실 또는 관습을 포함하며,
WORLD.md에 추가하고자 하는 정확한 문장과 그것이 속할 카테고리를 명시합니다. - 설정 충돌 (Canon conflicts) — 자유 글쓰기 내용 중 기존 설정과 모순되는 모든 것을 포함하며, 양측의 내용을 모두 인용합니다. 기술 지침 (skill instructions)에는 충돌을 절대 조용히 해결하지 말라고 명시되어 있습니다. 설정을 수정할지, 새로운 내용을 외전 (apocrypha)으로 취급할지, 아니면 버릴지는 제가 결정합니다.
- 작성 예정 항목 (Planned entries) — 작성하고자 하는 각 항목에 대해 대상 섹션, 가제 (working title), 한 줄 요약 (one line pitch), 그리고 어떤 자유 글쓰기에서 가져왔는지를 명시합니다. 또한 자유 글쓰기의 일부가 아직 아무런 결과물도 내지 못한다고 제안하는 것도 허용되는데, 이는 놀라울 정도로 중요한 허용 사항입니다. 모든 세션이 반드시 콘텐츠가 될 필요는 없기 때문입니다.
제안서를 읽는 데는 몇 분 정도 걸립니다. 하지만 제가 직접 다듬어진 항목들을 직접 쓰는 데는 몇 시간이 걸릴 것입니다. 이것이 바로 거래(trade)입니다. LLM이 노동을 수행하고, 저는 저자로서의 결정권을 유지하는 것입니다.
한 가지 실질적인 세부 사항은, 제안서가 단순한 채팅 출력물이 아니라 파일이기 때문에 파이프라인을 재개할 수 있다는 점입니다. 기술은 재개 확인 (resume check) 단계부터 시작됩니다. 만약 이전 세션에서 생성된 PROPOSAL.md가 존재한다면, 이를 제시하고 계속 진행할지, 수정할지, 아니면 폐기할지를 묻습니다. 세션은 중단될 수 있고, 사용량 제한이 초기화될 수도 있으며, 현실적인 변수들이 발생합니다. 중간 상태를 파일로 만든다는 것은 그 어떤 상황에서도 작업 내용을 잃지 않는다는 것을 의미합니다.
설정은 파일이며, 충돌은 명확하게 드러납니다
WORLD.md는 세계관에 대한 단일 진실 공급원 (Single Source of Truth)입니다. 출판된 항목에 등장하는 모든 고유 명사는 반드시 그곳에 먼저 존재해야 하며, 스킬 (Skill)은 이를 명시적인 규칙으로 강제합니다. 이는 관료적으로 들릴 수 있지만, 몇 주 간격으로 작성된 의식의 흐름 (Stream-of-consciousness) 세션들을 통해 구축되는 허구의 세계가 일관성을 유지할 수 있게 해주는 핵심 요소입니다.
표면화되는 충돌은 제가 생성한 실제 모순들을 잡아냈으며, 스스로는 놓쳤을지도 모를 부분들을 잡아내기도 했습니다. 화요일에 작성한 자유 글쓰기 (Freewrite)가 3주 전에 작성한 설정 (Canon)과 충돌할 때, 여러분은 동의하기 쉽고 일관성 있게 들리는 텍스트를 생성하도록 훈련된 모델이 이를 매끄럽게 뭉개버리는 대신, 두 인용문을 나란히 배치하여 그 결정 사항을 눈앞에 보여주기를 원할 것입니다. 하지만 연재 소설을 계속 써 내려가다 보면 이러한 여유가 점점 줄어들기 때문에, 편집기가 "이봐요, 여기서 우리가 뭘 하고 있는 거죠?"라고 말해주는 것이 매우 유용합니다.
원본 자료를 바이트 단위로 그대로 아카이브하기
승인 후, 각 원본 자유 글쓰기 (Raw freewrite)는 프론트매터 (Frontmatter)가 추가된 '출판된 자유 글쓰기' 섹션으로 이동하지만, 본문은 바이트 단위로 토씨 하나 틀리지 않고 그대로 (Byte-for-byte verbatim) 복사됩니다. 오타 수정도, 재형식화도 없습니다. 스킬 (Skill)은 정확히 그렇게 명시하고 있는데, 이는 LLM의 본능이 친절하게 내용을 정리하려는 성향을 가지고 있기 때문입니다.
제가 이렇게 하고 싶은 이유는 두 가지입니다. 첫째, 원본 세션은 다듬어진 항목들과는 다른 정직함을 지니고 있으며, 관심 있는 독자들은 그 과정(B-roll)을 볼 수 있습니다. 둘째, 모든 다듬어진 항목은 프론트매터 (Frontmatter)에 해당 내용이 추출된 자유 글쓰기 슬러그 (Slug)를 가리키는 sources 목록을 포함하고 있어, 출판된 발신물부터 그것이 나온 원본 세션까지의 전체 출처 (Provenance)를 확인할 수 있습니다. 파이프라인 끝에 있는 작은 Hugo 빌드 체크를 통해 이러한 소스 링크 중 끊어진 것이 없는지 검증합니다.
여전히 일부(또는 대부분의) 독자들이 과정 중에 모델이 사용되었다는 아이디어 자체를 싫어할 가능성은 충분히 있지만, 저는 그러한 의견을 직접 들어보고 싶습니다.
에이전트 (Agent)가 잘못 행동할 때는 출력이 아닌 스킬 (Skill)을 수정하라
저는 자유롭게 글을 쓰기 위한 TUI(Terminal User Interface)인 저의 새로운 프로젝트 cassette를 사용하여 프리라이팅 (freewriting)을 하고 있습니다. 초기에는 프리라이팅 도중에 기록에 남기지 않을 내용들(나 자신에게 하는 메모, 확정하지 않은 아이디어, 혹은 단순히 "생각 안 나, 생각 안 나, 생각 안 나..."와 같이 프리라이팅을 이어가기 위해 잠시 멈추는 내용 등)을 작성할 방법이 필요했습니다. 그래서 TUI에 "B-sides" 기능을 추가했습니다. 이 기능은 제가 무엇이든 적어둔 뒤, 다시 흐름을 찾으면 A-side로 돌아올 수 있게 해줍니다. 하지만 에이전트 (Agent)는 포함하지 말라는 지침에도 불구하고 B-side의 내용을 계속해서 제안 (proposals)에 포함시켰습니다.
올바른 해결책은 스킬 (skill) 파일을 열고 다음과 같은 규칙을 추가하는 것입니다: "B side" 헤딩부터 다음 H2까지의 모든 내용은 기록 외 사항(off the record)이며, 캐논 (canon) 및 엔트리 (entries)에서 제외하되, 세션의 나머지 내용과 함께 있는 그대로 아카이브 (archive)한다. 단 한 번의 수정으로, 이 동작은 이번 세션뿐만 아니라 향후 모든 세션에서 수정된 상태로 유지됩니다.
또한, 이 스킬 하단에는 제가 수동으로 관리하며 상단의 기본 설정을 명시적으로 덮어쓰는 편집 노트 (Editorial notes) 섹션을 추가했습니다. 이곳에는 지속적인 창작 가이드라인이 담깁니다: "디스패치 (dispatches)는 주요 스토리 메커니즘이며, 주인공의 3인칭 제한 시점 (third person close)으로 작성한다", "짧은 캐릭터 이름을 선호하므로 제안 시 긴 이름은 표시한다"와 같은 내용들입니다. 제 취향이 바뀌면 해당 섹션을 수정하고, 그러면 파이프라인 (pipeline)도 함께 바뀝니다. 이는 코드베이스를 위해 CLAUDE.md를 유지 관리하는 것과 동일한 피드백 루프이며, 단지 코드 스타일 대신 편집적 판단 (editorial judgement)을 대상으로 할 뿐입니다.
일관성 검사 (The consistency sweep), 과소평가된 초능력
캐논을 파일로 관리하고 모든 콘텐츠를 리포지토리 (repo)에 두는 것의 부수적인 이점은 이름 변경 (rename) 비용이 저렴해진다는 것입니다. 저는 집필 중간에 캐릭터의 이름을 변경했고 (긴 이름이 계속 신경 쓰였기 때문입니다), 세력 (faction)의 이름도 변경했습니다. 모든 발행된 엔트리를 대상으로 이름 변경 작업을 수행하며, 각 출현 빈도를 WORLD.md의 명명법 (nomenclature)과 대조하는 작업은, LLM이 빠르고 (제 경험상 지금까지는) 잘 해내는, 바로 그러한 지루하고 기계적이며 판단력이 크게 필요 없는 작업입니다. 이것이 업무의 "기록 보관자 (archivist)"적인 측면이며, 제가 가장 기꺼이 넘겨줄 수 있는 부분입니다.
자신만의 시스템을 구축하려는 사람에게 해주고 싶은 말
- 원본 자료(raw material)를 발행(publish) 단계에서 볼 수 없는 곳에 두세요.
content/디렉토리 외부의 인박스(inbox) 디렉토리를 만드는 것은 비용이 들지 않으면서도 최악의 사고를 방지해 줍니다. - LLM이 제안 산출물(proposal artifact)을 생성하게 하고, 승인을 필수적인 관문(hard gate)으로 만드세요. 이 관문이 바로 작업의 주도권을 당신이 유지하게 해주는 장치입니다.
- 설정(canon)은 하나의 파일에 유지하고, 발행되는 모든 내용은 해당 파일로 추적(trace back)될 수 있도록 하세요.
- 원본 입력값은 출처(provenance) 링크와 함께 있는 그대로 아카이브(archive)하세요. 나중에 기록(paper trail)이 필요할 것입니다.
- 에이전트(agent)가 당신이 원하지 않는 행동을 두 번 반복한다면, 출력물을 다시 수정하는 대신 프로세스 문서(process doc)에 그 수정 사항을 인코딩(encode)하세요.
시작하기 전에 제가 걱정했던 점은, 창의적인 프로젝트 중간에 LLM을 투입하면 글쓰기가 평범한 LLM 산문(LLM prose)으로 평탄화(flatten)될 것이라는 점이었습니다. 저는 창작 과정에서 LLM을 어떻게 사용하는지 솔직하게 밝히고 원본 자료를 보여주는 것이 독자들과 소통하는 방법이라고 생각합니다. 또한 이러한 프로세스는 단순히 다른 생성된 텍스트처럼 들리지 않는(생성된 텍스트도 분명히 그들만의 스타일이 있습니다) 산문으로 이어질 것이라고 생각합니다. 그럼에도 불구하고, 이런 방식으로 "좋은" 작업물을 만들어낼 수 있는지에 대해서는 여전히 결론이 나지 않았습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기