YAML 기반 세계관/인물/에피소드를 바탕으로 시뮬레이션 로그를 만들고, 이를 소설 챕터로 변환하는 프로젝트입니다.
config/*.yaml로 스토리/세계관/인물 정의simulate.py또는trial_simulate.py로 턴 기반 상호작용 생성generate_chapter.py로 DB 로그를 장면 압축 후 prose 챕터 생성tools/*로 품질 점검/개선 루프 실행
simulate.py # 단일 에피소드 실행 CLI
trial_simulate.py # Trial-and-Learn 실행 CLI
generate_chapter.py # 챕터 생성 CLI
src/novel_writer/ # 코어 엔진 패키지
config_loader.py
database.py
director.py
llm_client.py
models.py
orchestrator.py
prose_generator.py
scene_distiller.py
trial_runner.py
tools/ # 품질 도구
quality_analyzer.py
quality_adaptive_generator.py
compare_quality.py
run_quality_pipeline.sh
tests/ # 테스트/검증 스크립트
config/ # YAML 설정
output/ # 생성 산출물
reports/ # 분석/리포트 문서
examples/Good_example/ # 레퍼런스 챕터
- Python 3.10+
- OpenAI API Key
pip install -r requirements.txt
cp .env.example .env
# then edit .env and set your real keyCLI scripts (simulate.py, trial_simulate.py, generate_chapter.py) auto-load .env from the project root.
python simulate.py \
--episode config/episodes/ep05_unexpected_visitors.yaml \
--characters config/characters.yaml \
--world config/world_facts.yaml \
--storyline config/storyline.yaml \
--budget 5.0python generate_chapter.py \
--episode ep05_unexpected_visitors \
--episode-config config/episodes/ep05_unexpected_visitors.yaml \
--protagonist kim_sumin \
--protagonist-name "Kim Sumin" \
--words 2000python trial_simulate.py \
--episode config/episodes/ep05_unexpected_visitors.yaml \
--characters config/characters.yaml \
--world config/world_facts.yaml \
--storyline config/storyline.yaml \
--max-trials 5 \
--budget 15.0bash tools/run_quality_pipeline.sh ep05_unexpected_visitorssimulate.py또는trial_simulate.py실행output/<episode_id>_simulation.json,output/<episode_id>_debug.log생성generate_chapter.py실행output/<episode_id>_scenes.json,output/<episode_id>_chapter.md생성- 필요 시
tools/quality_analyzer.py로 품질 분석
src/novel_writer/director.py에서 매 턴 다음을 검사합니다.
- 캐릭터 invariant 위반
- knowledge leak
- storyline/milestone alignment
- clue injection 필요 여부
- episode 종료 조건 충족 여부
episode.characters명시값- 에피소드 텍스트에서 명시적으로 언급된 인물
- 이전 에피소드 캐스팅 승계
- 최소 fallback cast
- 목적: 단일 에피소드 실행
- 주요 인자:
--episode--characters(필수)--world--storyline--model--premium--budget--output--db
- 목적: 실패 원인 학습 + 재시도
- 주요 인자:
--max-trials--success-threshold
- 산출물:
output/<episode_id>_trial_summary.jsonoutput/<episode_id>_trialN_simulation.jsonoutput/<episode_id>_trialN_debug.log
- 목적: DB 상호작용 로그 -> 장면 압축 -> 챕터 생성
- 주요 인자:
--episode--episode-config--protagonist--protagonist-name--words--scenes--style
output/<episode_id>_simulation.jsonoutput/<episode_id>_debug.logoutput/<episode_id>_scenes.jsonoutput/<episode_id>_chapter.mdoutput/<episode_id>_trial_summary.json(trial 사용 시)
- 스토리 데이터는 코드가 아니라
config/*.yaml에서 관리됩니다. - 품질 실험 스크립트는
tools/에 모아두었습니다. - 코어 로직은
src/novel_writer패키지에 통합되어 있습니다.
Discord에서 아래 3단계를 자동 반복하는 루프 봇입니다.
- Simulator Agent:
simulate.py+generate_chapter.py실행, 산출물 업로드 - Reviewer Agent: 품질분석 + LLM 리뷰(스토리 내용 비판 / 글 자체 비판)
- Fixer Agent: 리뷰를 기반으로 에피소드 YAML(
episode.pacing/max_turns/recommended_length/summary) 자동 수정
pip install -r requirements.txt
cp .env.example .env
# .env에 DISCORD_BOT_TOKEN 설정
# 선택: 에이전트별 LLM 키 분리 시 TOKEN / TOKEN2 / TOKEN3 설정Discord Developer Portal에서 Bot을 생성하고 서버에 초대한 뒤, Message Content Intent를 켜야 합니다.
메시지 커맨드:
!novel-loop!novel-loop-reset
python tools/discord_loop_bot.pyDiscord 채널에서:
!novel-loop ep01_academic_presentation --max-cycles 3 --target-words 2200 --scenes 6 --budget 4.0
상태 파일:
data/discord_loop_state.json