Spaces:
Sleeping
Sleeping
File size: 6,234 Bytes
7d46a91 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | # ์นด๋ฅด๋ฐ๋ผ ์ธํฐ๋ํฐ๋ธ ๋
ธ๋ฒจ โ MVP ๊ตฌํ ๊ณํ
> ์น์ธ์ผ: 2026-07-03 ยท ์ํ: **M0~M6 ์ ์ฒด ์๋ฃ = MVP ์์ฑ** (2026-07-03, feature/mvp-m1-m4)
> ์คํ: `.venv/bin/uvicorn engine.router:app --port 8777` โ http://localhost:8777 (์น ๋ฆฌ๋)
> `.venv/bin/python scripts/play.py` (CLI) ยท `adk web .` โ engine (ํฌ์ผ ๋จ๋
)
> LLM: ๋ฃจํธ `.env`์ OPENAI_API_KEY ์๋ ๋ก๋ฉ. ์ค LLM์ผ๋ก ํํผ์ฌ๋ค๋ฆฌยท์ฌ์ธตํด๊ธยท์๋ ด E2E ๊ฒ์ฆ ์๋ฃ
> follow-up: SequentialAgent โ google.adk.workflow ๋ง์ด๊ทธ๋ ์ด์
๊ฒํ ยท E06-09 ์ ๋ณด(์ค๋ฆฝ) 3์
> ์ ํ์ง ๋ฏธ๋
ธ์ถ ยท R-์ฝ์ ๋ฐ์ ๊ตฌ์กฐํ(ํ์ฌ raw ์ฃผ์
) ยท ํ ํ์(์๋ฒ์ง ๋ฑ) ์ฑํ
ํฌ์ผ ยท ์ธ์
์์ํ
> ์์น: CLAUDE.md ์ค์ (google-adk ๊ณต์ ํจํด, ์์ฌ ์งํ์ ์ฝ๋๊ฐยท๋์ฌ๋ LLM์ด, ์คํฌ์ผ๋ฌ ํํฐ ๊ฐ์ )
## MVP ์ ์
**E01~E06(์ฑํฐ1)์ ์ฒ์๋ถํฐ ๋๊น์ง ํ๋ ์ด ๊ฐ๋ฅํ ์์ง ์ฌ๋ผ์ด์ค.**
- ์นด๋ ๋จ์ ์ฝ๊ธฐ(L0, ์บ๋
ผ ๊ณ ์ ) โ ์ ํ์ง/์์ ์ฑํ
๊ฐ์
ํฌ์ผ(L1) โ ์จ์ ์ํ ๋์ โ ์๋ฉ 3์ข
์๋ ด(L2)
- ์์ง: google-adk. ์คํ: CLI + `adk web`. ๋ฆฌ๋ฉ UI๋ MVP ์ดํ(M5)
- GraphRAG/Neo4j๋ MVP ์ ์ธ โ `kb_query`๋ pre_kb ์ ์ง, repository ์ธํฐํ์ด์ค๋ง ์ค๋น
- `reference/`๋ ๊ฐ๋
๊ฒ์ฆ ํ๋กํ ํ์
. **์ฐธ๊ณ ๋ง ํ๊ณ ์ฝ๋๋ ADK๋ก ์๋ก ๊ตฌ์ถ** (์ ์ ํ์ )
## ๋ฐ์ดํฐ ๋ชจ๋ธ (A์ ์ํคํ
์ฒ โ reference v10์์ ๊ฒ์ฆ๋ ๊ฐ๋
)
| ๋ ์ด์ด | ํ์ผ | ๋ด์ฉ |
|---|---|---|
| ์ ์ฒด์ฑ (๋ถ๋ณ) | `content/characters.yaml` | ์ธ๋ฌผ ์ํธ(ENOS), player=laura, ์ง์๊ฒฝ๊ณ, kb_query ํ
|
| ์ฑํฐ ๋ฉํ | `content/chapters/*.yaml` | entry/exit beats, beat_range, ์๋ฉ 3์ข
๊ท์น, R์นด๋ ๋ฑ๋ก |
| ๋ด๋ฌํฐ๋ธ | `content/beatcards/E0*/*.yaml` | ์นด๋: narration ๋ธ๋ก/choices/next/canon/๋ณต์ ํ๊ทธ/์ฐ์ถ |
- **์ฝํ
์ธ ์์ฒ(๊ถ์)**: `์นด๋ฅด๋ฐ๋ผ/0701_์นด๋ฅด๋ฐ๋ผ/๋นํธ์นด๋/` MD (๋ํ๋ ์์ )
- ๋ณํ YAML์ ํ์๋ฌผ: `scripts/beatcard_convert.py`(๊ฐ๋ฐํ ์์ )๋ก ์์ฑ
- ์จ์ ์ํ 3๊ฐ (P0 4์ข
์์ง ๋ช
์ธ): **์ ๋ขฐ์ถ**(์์) ยท **์ ์ฝ๋**(๋จ์กฐ ์ฆ๊ฐ, ์ ๋ขฐ์ ๋
๋ฆฝ) ยท **์**(์ ์ , ๋์
1ํ ํ๋ฆฝ ํ ๋ถ๋ณ). ์ซ์/๊ฒ์ด์ง ์ ์ ๋น๋
ธ์ถ
- ์๋ฉ ๊ท์น: `doubtโฅ30โ์ฒ๋จ(์บ๋
ผ)` / `trustโฅ60โงdoubt<20โ์์` / `defaultโ๊ตฌ์`
## ์ฝ๋ vs LLM ๊ฒฝ๊ณ
| ๊ฐ๋
| ๊ตฌํ | ํ์
|
|---|---|---|
| ์นด๋ ์งํ(next ๋งํฌ, canon ์ฝ๊ธฐ) | `services/story.py` ์ํ๋จธ์ | ๊ฒฐ์ ์ ์ฝ๋ |
| ์ ํ์ง โ ์ ๋ขฐ์ถ ๋ฐ์ | ์ ํ ๋งคํ + state ์ปค๋ฐ | ๊ฒฐ์ ์ ์ฝ๋ |
| ์์ ์ฑํ
๊ฐ์
ํฌ์ผ | guard โ character โ director | ADK ํ์ดํ๋ผ์ธ |
| R-ํํผ์ฌ๋ค๋ฆฌ/์ฝ์ ๋ฐ์ | guard ๊ท์น + character instruction ์ฃผ์
| BaseAgent + instruction |
| ์จ์ ์ํ | session.state + FunctionTool โ ํฌ์ผ ์ข
๋ฃ ์ ์ปค๋ฐ | ADK state |
| ์๋ ด ํ์ | director ๊ตฌ์กฐํ ์ถ๋ ฅ + `services/pocket.py` ์ฝ๋ ์ฌ๊ฒ์ฆ | LlmAgent + ์ฝ๋ |
| ์๋ฉ ๋ถ๊ธฐ | ending_rules ์กฐ๊ฑด์ ํ๊ฐ | ๊ฒฐ์ ์ ์ฝ๋ |
| ์คํฌ์ผ๋ฌ ๋ฐฉ์ด | `beat_id โค ํ์ฌ` ํํฐ + before_model ์ฝ๋ฐฑ | ์ฝ๋ฐฑ |
## ๊ฐ์
ํฌ์ผ ํ์ดํ๋ผ์ธ (escalate ๊ฒฉ๋ฆฌ ๊ท์น ์ ์ฉ)
```
pocket_session (SequentialAgent)
โโโ pocket_context_loader โ BaseAgent: ์นด๋ ๋ธ๋ฆฌํ + ์ ๋ขฐ ๋ ๋ฒจ ๊ฒฐ ๋ก๋
โโโ turn_loop (LoopAgent max=์นด๋๋ณ ์ํ)
โ โโโ input_guard โ BaseAgent: ์ธ๊ณ๊ด ์ดํ/์ ์ฒด์ง๊ฒฉ/์ฝ์ ๊ฐ์ง
โ โโโ character โ LlmAgent: ์นด๋ฅด๋ฐ๋ผ (์ํธ+ํ๋ฒ6๊ท์น+R์นด๋+์ ๋ขฐ๋ณ ๊ฒฐ)
โ โโโ director โ LlmAgent: ๋นํธ ๋ฌ์ฑ/์ดํ/์ ๋ขฐ๋ฐ์/์๋ ด โ escalate
โโโ pocket_closer (LoopAgent max=1) โ ๊ฐ์ ์๋ ด ๋ด๋ ์ด์
+ ์ํ ์ปค๋ฐ โ ๋ค์ ์นด๋ ๋ณต๊ท
```
## ๋ง์ผ์คํค
- **M0 โ ์ค์บํด๋** (0.5์ผ): git init(๋ก์ปฌ๋ง, ์๊ฒฉ ํธ์๋ ์ถํ) ยท engine/ ๋ผ๋ ยท ์์กด์ฑ ยท CLAUDE.md ๋ฐ์ดํฐ ๋ชจ๋ธ ์น์
๊ฐฑ์ ยท ๋ณธ ๋ฌธ์
- **M1 โ ์ฝํ
์ธ ๊ณ์ฝ** (1์ผ): ๋นํธ์นด๋/์ฑํฐ/์บ๋ฆญํฐ Pydantic ์คํค๋ง + `python -m engine.schemas.validate content/` ยท ๋ณํ ์คํฌ๋ฆฝํธ ยท next ๋งํฌ ๋ฌด๊ฒฐ์ฑ ๊ฒ์ฌ(๊ณ ์/๋๊ธด ์ฒด์ธ). ๊ฒ์ฆ ๊ธฐ์ค: ๊ธฐ์กด 61์นด๋ ํต๊ณผ
- **M2 โ ๊ฒฐ์ ์ ๋ฆฌ๋ฉ ๋ฃจํ** (1์ผ): entry_beat๋ถํฐ canon ํ์ด์ง ยท ์ ํ์ง ์ ๋ขฐ์ถ ๋ฐ์ ยท ์ ์ฝ๋ ๋จ์กฐ ์ฆ๊ฐ ยท **LLM ์์ด** CLI๋ก E01~E06 ํต๋
+ ์๋ฉ 3์ข
๋๋ฌ ํ์ธ
- **M3 โ ADK ๊ฐ์
ํฌ์ผ** (2~3์ผ, ํต์ฌ): ํด ํ์ดํ๋ผ์ธ ยท ์นด๋ฅด๋ฐ๋ผ instruction ยท director ๊ตฌ์กฐํ ํ์ (FunctionToolโstate) ยท guard ยท `adk web`์ผ๋ก ํฌ์ผ 1๊ฐ(E06-09 ๊ถ์ฅ) ์ง์ค ๊ฒ์ฆ
- **M4 โ ์ ์ฒด ๊ดํต** (1~2์ผ): ๋ฆฌ๋ฉ ๋ฃจํ โ ํฌ์ผ ์ฐ๊ฒฐ ยท E01โ์๋ฉ ์ ์ฒด ํ๋ ์ด ยท ํด ๋ก๊น
ํ๋ฌ๊ทธ์ธ ยท ์์ฐ(CLI + adk web)
- **M5 โ MVP ์ดํ**: FastAPI router + ๋ฆฌ๋ฉ UI ยท GraphRAG(kb_query ํ์ฑํ) ยท ํ๊ฐ ํ๋ค์ค ยท style_critic ๋ฃจํ
## ํด๋ ๊ตฌ์กฐ
```
sorac/
โโโ engine/
โ โโโ agent.py / app.py / model.py / router.py
โ โโโ schemas/ beatcard.py ยท chapter.py ยท character.py ยท validate.py
โ โโโ services/ story.py ยท pocket.py ยท state.py ยท retrieval.py(2๋จ๊ณ ์คํ
)
โ โโโ repositories/ content.py ยท playlog.py
โ โโโ agents/ input_guard.py ยท pocket_context_loader.py
โ โโโ sub_agents/ character/ ยท director/
โ โโโ tools/ state/ (update_trust.py, mark_beat.py) ยท retrieval/(์คํ
)
โ โโโ callbacks/ ยท plugins/logging.py ยท instructions/
โโโ content/ beatcards/ ยท chapters/ ยท characters.yaml (M1์์ ์ ์ฌ)
โโโ scripts/ beatcard_convert.py
โโโ tests/
โโโ docs/plans/mvp.md (๋ณธ ๋ฌธ์)
```
## ๊ฒฐ์ ๋ก๊ทธ
- ๋ฐ๋ชจ ํ๋ก ํธ: ์์ง ์ฐ์ , UI ์ต์ (์ ์ ํ์ )
- E01_๊ตฌํ๊ณํ.drawio ๋ฌด์ (์ ์ ์ง์) โ ์ฌ ์ค๊ณ ๊ทผ๊ฑฐ๋ก ์ฐ์ง ์์
- ๋นํธ์นด๋ MD๊ฐ ์ฝํ
์ธ ๊ถ์, reference ๋ด YAML์ ํ์๋ฌผ (์น์ธ)
- CLAUDE.md "YAML 4์ข
" ์น์
โ A์ 3๋ ์ด์ด๋ก ๊ฐฑ์ (์น์ธ)
- E07~E15: MD๋ง ์กด์ฌ, MVP ๋ฒ์ ๋ฐ
|