File size: 5,312 Bytes
5545b9a
 
 
 
 
 
 
 
 
 
e1d7e7b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
fe1ffb2
 
e1d7e7b
fe1ffb2
 
 
 
e1d7e7b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
361d672
 
 
 
 
 
 
 
 
 
 
 
 
 
e1d7e7b
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
---
title: PersonaChatEngine Ai Server
emoji: πŸ‘€
colorFrom: green
colorTo: green
sdk: docker
pinned: false
license: mit
---

## βš™οΈ AI μ„œλ²„ (ai_server/)

### μ—­ν•  & 데이터 흐름

1. **κ²Œμž„ μ„œλ²„ μš”μ²­ μˆ˜μ‹ (`app.py`)**
   - μ΅œμ†Œ μž…λ ₯만 와도 λ™μž‘: `{ text, npc_id, player_id, ... }`
   - μ˜΅μ…˜: μƒνƒœ/μ»¨ν…μŠ€νŠΈ λΆ€μ‘± μ‹œ `rag/docs/npc_config.json` λ“±μ—μ„œ NPC 메타λ₯Ό μ‘°νšŒν•΄ 보강

2. **μ „μ²˜λ¦¬Β·ν”„λ‘¬ν”„νŠΈ ꡬ성(`pipeline/preprocess.py`, `utils/context_parser.py`, `manager/prompt_builder.py`)**
   - νƒœκ·Έ/μ»¨ν…μŠ€νŠΈ/ν”Œλ ˆμ΄μ–΄ λ°œν™”λ₯Ό λ¬Άμ–΄ `<SYS>`, `<CTX>`, `<PLAYER>`, `<NPC>` 포맷으둜 ꡬ성

3. **μΆ”λ‘  μš”μ²­(`utils/hf_client.py`, `models/fallback_model.py`, `pipeline/generator.py`)**
   - 쑰건 뢈좩쑱 input β†’ `fallback_model.py`μ—μ„œ λŒ€μ²΄ 응닡 생성
   - 쑰건 μΆ©μ‘± input β†’ `generator.py`μ—μ„œ payload ꡬ성 ν›„ HF Space `/predict_main` POST

4. **ν›„μ²˜λ¦¬(`pipeline/postprocess.py`)**
   - λͺ¨λΈ μ‘λ‹΅μ—μ„œ **λŒ€μ‚¬ ν…μŠ€νŠΈ, delta, flag**λ₯Ό νŒŒμ‹±Β·μ •κ·œν™”
   - flags β†’ μ‹œκ·Έλͺ¨μ΄λ“œ+threshold, delta β†’ λ²”μœ„ ν΄λž¨ν”„Β·λΌμš΄λ”©

5. **κ²Œμž„ μ„œλ²„ 응닡(`schemas.py`)**
   - ν‘œμ€€ JSON으둜 λ°˜ν™˜
   ```json
   {
     "text": "NPC의 λŒ€λ‹΅...",
     "delta": {"trust": 0.10, "relationship": 0.08},
     "flags": {"give_item": true, "npc_main_story": false},
     "meta": {"npc_id": "mother_abandoned_factory"}
   }
   ```

---

### πŸ“ 디렉토리 ꡬ쑰

```bash
ai-server/
β”œβ”€β”€ app.py                  # FastAPI μ—”νŠΈλ¦¬ν¬μΈνŠΈ
β”œβ”€β”€ config.py               # μ„œλ²„ μ„€μ • 및 λͺ¨λΈ 경둜 관리
β”œβ”€β”€ schemas.py              # μš”μ²­/응닡 데이터 ꡬ쑰 μ •μ˜
β”œβ”€β”€ requirements.txt        # μ˜μ‘΄μ„± νŒ¨ν‚€μ§€ λͺ©λ‘
β”œβ”€β”€ pipeline/               # λŒ€ν™” 흐름 처리 λͺ¨λ“ˆ
β”‚   β”œβ”€β”€ preprocess.py       # μž…λ ₯ μ „μ²˜λ¦¬ 및 ν”„λ‘¬ν”„νŠΈ ꡬ성
β”‚   β”œβ”€β”€ postprocess.py      # λͺ¨λΈ 좜λ ₯ ν›„μ²˜λ¦¬
β”‚   └── generator.py        # λͺ¨λΈ μΆ”λ‘  μš”μ²­ 처리
β”œβ”€β”€ rag/                    # RAG 기반 flag 해석 λͺ¨λ“ˆ
β”‚   β”œβ”€β”€ rag_manager.py
β”‚   └── docs/npc_config.json
β”œβ”€β”€ utils/                  # μœ ν‹Έλ¦¬ν‹° λͺ¨λ“ˆ
β”‚   β”œβ”€β”€ hf_client.py        # HF API 톡신
β”‚   └── context_parser.py   # λŒ€ν™” λ§₯락 νŒŒμ‹±
β”œβ”€β”€ models/                 # λͺ¨λΈ λ‘œλ”© 및 fallback 처리
β”‚   β”œβ”€β”€ emotion_model.py    # emotion model을 μ΄μš©ν•œ inference μ§„ν–‰
β”‚   β”œβ”€β”€ fallback_model.py   # fallback model을 μ΄μš©ν•œ inference μ§„ν–‰
β”‚   └── model_loader.py
└── manager/
    β”œβ”€β”€ agent_manager.py    
    β”œβ”€β”€ dialogue_manager.py # 전체 pipeline λͺ¨λ“ˆ 관리
    └── prompt_builder.py
```

---

### 🧩 μ΅œμ‹  RAG νƒ€μž…λ³„ λ§€ν•‘ (11μ’…)

| **type** | **쑰회 μ‹œμ ** | **쑰회 쑰건** | **μ‚¬μš© λͺ¨λ“ˆ/ν•¨μˆ˜** | **μ£Όμš” λͺ©μ ** |
|----------|--------------|---------------|--------------------|---------------|
| `trigger_def` | preprocess_input | npc_id, quest_stage | retrieve(...) | 메인 경둜 쑰건 νŒμ • |
| `fallback` | preprocess_input | npc_id, quest_stage | retrieve(...) | fallback prompt ꡬ성 |
| `forbidden_trigger_list` | preprocess_input | npc_id | _load_forbidden_trigger_data | κΈˆμ§€ 트리거 감지 |
| `trigger_meta` | preprocess_input | npc_id, trigger | _load_trigger_meta | 특수 fallback μ‹œ delta/action ν™•μ • |
| `lore` | build_main_prompt | npc_id, quest_stage/any | RAG main docs | 세계관/λ°°κ²½ μ„€λͺ… |
| `description` | build_main_prompt | npc_id, quest_stage | RAG main docs | ν˜„μž¬ 상황 μ„€λͺ… |
| `flag_def` | postprocess_pipeline | npc_id, quest_stage, flag_name | pre_data["rag_main_docs"] | flag threshold/μ˜ˆμ‹œ λ¬Έμž₯ |
| `main_res_validate` | postprocess_pipeline | npc_id, quest_stage | pre_data["rag_main_docs"] | 응닡 검증 κΈ°μ€€ |
| `npc_persona` | build_main_prompt | npc_id | retrieve(...) | NPC μ„±κ²©Β·νŠΉμ„± 반영 |
| `dialogue_turn` | postprocess_pipeline | npc_id, quest_stage | retrieve(...) | λŒ€ν™” μ˜ˆμ‹œ μ°Έμ‘° |
| *(μ—†μŒ)* | fallback_final_check | pre_data["trigger_meta"] | - | 응닡 의미 일치 검증 |

---

### πŸ“Œ 데이터 흐름 μš”μ•½

1. **preprocess_input()**
   - trigger_def β†’ 메인 쑰건 νŒμ •
   - forbidden_trigger_list + trigger_meta β†’ 특수 fallback 감지
   - fallback β†’ 일반 fallback μŠ€νƒ€μΌ

2. **build_main_prompt()**
   - lore + description + npc_persona β†’ 메인 prompt μ»¨ν…μŠ€νŠΈ ꡬ성

3. **build_fallback_prompt()**
   - fallback_style + trigger_meta β†’ fallback prompt ꡬ성

4. **postprocess_pipeline()**
   - flag_def β†’ flag threshold/μ˜ˆμ‹œ
   - main_res_validate β†’ 응닡 검증

5. **fallback_final_check()**
   - trigger_meta β†’ delta/action 의미 일치 검증

---

### πŸ”— ν…ŒμŠ€νŠΈ
μ—…λ°μ΄νŠΈ μ˜ˆμ •

---

<!-- app-tab:start -->
# πŸ‘€ PersonaChatEngine AI Server

κ²Œμž„ λ‚΄ NPC λŒ€ν™” μ—”μ§„ API μ„œλ²„μž…λ‹ˆλ‹€.  
μ΅œμ†Œ μž…λ ₯λ§ŒμœΌλ‘œλ„ λ™μž‘ν•˜λ©°, RAG 기반 λ¬Έμ„œμ™€ NPC 메타데이터λ₯Ό ν™œμš©ν•΄ λŒ€ν™”λ₯Ό λ³΄κ°•ν•©λ‹ˆλ‹€.

### βš™οΈ μ£Όμš” κΈ°λŠ₯
- κ²Œμž„ μ„œλ²„ μš”μ²­ μˆ˜μ‹  및 μ „μ²˜λ¦¬
- 쑰건 νŒμ • ν›„ 메인/폴백 λͺ¨λΈ μΆ”λ‘ 
- RAG 기반 세계관·상황·NPC 성격 반영
- 응닡 ν›„μ²˜λ¦¬ 및 JSON ν‘œμ€€ 응닡 λ°˜ν™˜
<!-- app-tab:end -->
---