rorshi commited on
Commit
1ab2ba0
ยท
1 Parent(s): 71fb1a6
.gitattributes CHANGED
@@ -1,4 +1,5 @@
1
  *.ipynb text eol=lf
2
- *.bat text eol=crlf
3
  *.sh text eol=lf
 
4
  *.png filter=lfs diff=lfs merge=lfs -text
 
1
  *.ipynb text eol=lf
2
+ *.bat text eol=lf
3
  *.sh text eol=lf
4
+ *.txt text eol=lf
5
  *.png filter=lfs diff=lfs merge=lfs -text
npc_social_network/README.txt ADDED
@@ -0,0 +1,212 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # ๐Ÿง  README - NPC ์†Œ์…œ ๋„คํŠธ์›Œํฌ AI ์‹œ๋ฎฌ๋ ˆ์ด์…˜
2
+
3
+ ๋ณธ ๋ฌธ์„œ๋Š” ๋ณธ ํ”„๋กœ์ ํŠธ๋ฅผ **์ œ๋กœ ๋ฒ ์ด์Šค์—์„œ ์™„์ „ ์žฌํ˜„**ํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
4
+ ์ง€๊ธˆ๊นŒ์ง€์˜ ๊ตฌ์กฐ, ์„ค๊ณ„ ์ฒ ํ•™, ๊ตฌํ˜„ ๋‹จ๊ณ„, ๊ฐ ํŒŒ์ผ ๊ธฐ๋Šฅ์„ **๋‹จ ํ•˜๋‚˜์˜ ๋ฌธ์„œ๋กœ ์™„์ „ํ•˜๊ฒŒ ์ •๋ฆฌ**ํ•œ ๊ณต์‹ ๋ฌธ์„œ์ž…๋‹ˆ๋‹ค.
5
+
6
+ ---
7
+
8
+ ## ๐Ÿ“Œ ํ”„๋กœ์ ํŠธ ๊ฐœ์š” (Overview)
9
+
10
+ ์ด ํ”„๋กœ์ ํŠธ๋Š” ๊ฐ์ •, ๊ธฐ์–ต, ์„ฑ๊ฒฉ, ๊ด€๊ณ„, ํ–‰๋™์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ **์ธ๊ฐ„ ์œ ์‚ฌ NPC ์‹œ๋ฎฌ๋ ˆ์ด์…˜**์ž…๋‹ˆ๋‹ค.
11
+ ํ”Œ๋ ˆ์ด์–ด์™€์˜ ๋Œ€ํ™”, NPC ๊ฐ„ ์ƒํ˜ธ์ž‘์šฉ, ์‹œ๊ฐ„ ํ๋ฆ„์— ๋”ฐ๋ฅธ ๊ฐ์ • ๋ณ€ํ™” ๋“ฑ์„ ๋ฐ˜์˜ํ•˜๋ฉฐ,
12
+ LLM๊ณผ embedding ๊ธฐ๋ฐ˜ ๊ธฐ์–ต ์‹œ์Šคํ…œ์„ ํ†ตํ•ด ์ •๊ตํ•œ NPC ๋ฐ˜์‘์„ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค.
13
+
14
+ ---
15
+
16
+ ## ๐Ÿ“ ํด๋” ๊ตฌ์กฐ
17
+
18
+ ```
19
+ portfolio/
20
+ โ”œโ”€โ”€ app.py # Flask ์ง„์ž…์ 
21
+ โ”œโ”€โ”€ requirements.txt
22
+ โ”œโ”€โ”€ run_npc_interactions.py
23
+ โ”œโ”€โ”€ test.ipynb
24
+ โ””โ”€โ”€ npc_social_network/
25
+ โ”œโ”€โ”€ README.txt
26
+ โ”œโ”€โ”€ routes/
27
+ โ”‚ โ””โ”€โ”€ npc_route.py # ์›น ๋ผ์šฐํŠธ (API)
28
+ โ”œโ”€โ”€ maps/
29
+ โ”‚ โ”œโ”€โ”€ villages/town_hall.py # Pygame ๋ฉ”์ธ ์‹คํ–‰
30
+ โ”‚ โ”œโ”€โ”€ engine/game_engine.py # ๊ฒŒ์ž„ ๋ฃจํ”„, ๊ฐ์ • HUD
31
+ โ”‚ โ””โ”€โ”€ manager/
32
+ โ”‚ โ”œโ”€โ”€ tile.py # Tile ํด๋ž˜์Šค
33
+ โ”‚ โ”œโ”€โ”€ building.py # ๊ฑด๋ฌผ ํด๋ž˜์Šค
34
+ โ”‚ โ”œโ”€โ”€ image_loader.py # ์ด๋ฏธ์ง€ ๋กœ๋”ฉ
35
+ โ”‚ โ”œโ”€โ”€ image_registry.py # ์ด๋ฏธ์ง€ ๊ฒฝ๋กœ ์‚ฌ์ „
36
+ โ”‚ โ””โ”€โ”€ village_map.py # Village ์ „์ฒด ๊ตฌ์„ฑ
37
+ โ”œโ”€โ”€ npc/
38
+ โ”‚ โ”œโ”€โ”€ npc_base.py # NPC ๋ณธ์ฒด (๊ฐ์ •/๊ธฐ์–ต/๊ด€๊ณ„ ํฌํ•จ)
39
+ โ”‚ โ”œโ”€โ”€ npc_manager.py # NPC ๋ฆฌ์ŠคํŠธ ๊ด€๋ฆฌ
40
+ โ”‚ โ”œโ”€โ”€ npc_emotion.py # EmotionManager
41
+ โ”‚ โ”œโ”€โ”€ npc_memory.py # Memory / MemoryStore
42
+ โ”‚ โ”œโ”€โ”€ npc_behavior.py # ๊ฐ์ • โ†’ ํ–‰๋™ ๋งคํ•‘
43
+ โ”‚ โ”œโ”€โ”€ npc_relationship.py # ๊ด€๊ณ„ ์ ์ˆ˜ ๊ด€๋ฆฌ
44
+ โ”‚ โ”œโ”€โ”€ npc_memory_embedder.py # ๊ธฐ์–ต ์ž„๋ฒ ๋”ฉ + FAISS ๊ฒ€์ƒ‰
45
+ โ”‚ โ”œโ”€โ”€ emotion_config.py # ๊ฐ์ • ๊ตฌ์กฐ ์ •์˜
46
+ โ”‚ โ””โ”€โ”€ personality_config.py # ์„ฑ๊ฒฉ ๋ฐ ๋‚˜์ด ํ”„๋กœํ•„
47
+ โ”œโ”€โ”€ models/
48
+ โ”‚ โ”œโ”€โ”€ llm_helper.py # ๊ฐ์ • ์ถ”๋ก , ์‘๋‹ต ์ƒ์„ฑ
49
+ โ”‚ โ””โ”€โ”€ llm_prompt_builder.py # ํ”„๋กฌํ”„ํŠธ ์ƒ์„ฑ
50
+ โ”œโ”€โ”€ templates/
51
+ โ”‚ โ”œโ”€โ”€ chat.html # ์ฑ„ํŒ… UI
52
+ โ”‚ โ”œโ”€โ”€ base.html # ๊ณตํ†ต ํ…œํ”Œ๋ฆฟ
53
+ โ”‚ โ””โ”€โ”€ test_memory_tools.html # ์ž„๋ฒ ๋”ฉ ํ…Œ์ŠคํŠธ์šฉ ํŽ˜์ด์ง€
54
+ โ””โ”€โ”€ static/
55
+ โ”œโ”€โ”€ css/style.css
56
+ โ””โ”€โ”€ js/npc_chat.js
57
+
58
+ ```
59
+
60
+ ---
61
+
62
+ ## ๐Ÿ’ก ๊ฐ์ • ๊ตฌ์กฐ (๊ณ ์ฐจ์› ๊ฐ์ • ๋ชจ๋ธ)
63
+
64
+ > โœ… โ€œGoEmotions ๊ธฐ๋ฐ˜โ€์ด ์•„๋‹˜์— ์ฃผ์˜!
65
+ > โœ… ๋Œ€์‹  **GoEmotions์—์„œ ์˜๊ฐ์„ ๋ฐ›์•„ ์ง์ ‘ ์žฌ์„ค๊ณ„ํ•œ 4๊ณ„์ธต ๊ฐ์ • ๋ชจ๋ธ (ComplexEmotions)**
66
+
67
+ | ๊ณ„์ธต (Layer) | ๊ฐ์ • ์˜ˆ์‹œ |
68
+ |--------------|------------|
69
+ | `core` | joy, sadness, anger, fear, disgust, surprise, neutral |
70
+ | `social` | gratitude, shame, empathy, pride, jealousy, compassion, love, admiration, awe, attachment, comfort |
71
+ | `cognitive` | anticipation, curiosity, confusion, interest, engagement, boredom, relief, anxiety, calm, skepticism |
72
+ | `complex` | nostalgia, bittersweet, schadenfreude, resentment, anticipatory_joy, regret, rumination, hope, groundedness |
73
+
74
+ - ๊ฐ์ •์€ ๊ฐœ์„ฑ(`sensitive`, `stoic`, `*_bias`)์— ๋”ฐ๋ผ ๊ฐ์ • ๋ฐ˜์‘ ๋ฐ decay ์†๋„๊ฐ€ ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค.
75
+ - ๊ฐ์ •์€ ํ–‰๋™, ๊ธฐ์–ต ์ƒ์„ฑ, ๊ด€๊ณ„ ๋ณ€ํ™”, ์„ฑ๊ฒฉ ๋ณ€ํ™”์— ์ง์ ‘ ๋ฐ˜์˜๋ฉ๋‹ˆ๋‹ค.
76
+
77
+ ---
78
+
79
+ ## ๐Ÿง  ํ•ต์‹ฌ ์‹œ์Šคํ…œ ์„ค๋ช…
80
+
81
+ ### โœ… ๊ฐ์ • ์‹œ์Šคํ…œ
82
+ - `EmotionManager`: ๊ฐ์ • ๋ฒ„ํผ ๊ด€๋ฆฌ, decay, ๊ฐ์ • ์—…๋ฐ์ดํŠธ
83
+ - ๊ฐ์ •์€ ์ตœ๋Œ€ 100.0๊นŒ์ง€ ๋ˆ„์ ๋˜๋ฉฐ, decay๋Š” personality์™€ ์—ฐ๊ณ„๋จ
84
+ - ๊ฐ์ •์€ ํ–‰๋™ ์ƒ์„ฑ, ๊ธฐ์–ต ์ €์žฅ ๊ฐ•๋„, ๊ด€๊ณ„ ์˜ํ–ฅ, ์„ฑ๊ฒฉ ๋ณ€ํ™”์˜ ๊ธฐ๋ฐ˜์ด ๋จ
85
+
86
+ ### โœ… ๊ธฐ์–ต ์‹œ์Šคํ…œ
87
+ - `Memory`: content, timestamp, importance, emotion, type ๋ณด์œ 
88
+ - `MemoryStore`: ๋‹จ๊ธฐ/์žฅ๊ธฐ ๊ธฐ์–ต ๋ถ„๋ฆฌ, decay, ์Šน๊ฒฉ, ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ ํฌํ•จ
89
+ - decay๋Š” memory_type๋ณ„๋กœ ๋‹ค๋ฅด๊ฒŒ ์ ์šฉ๋จ
90
+
91
+ ### โœ… ์„ฑ๊ฒฉ ์‹œ์Šคํ…œ
92
+ - `PERSONALITY_PROFILE`: stable/emotional/logical
93
+ - `AGE_PROFILE`: ์ธ์ƒ ๋‹จ๊ณ„๋ณ„ ๋ณ€ํ™”์œจ (์˜ˆ: ์–ด๋ฆฐ์ด๋Š” ๋น ๋ฆ„)
94
+ - ๊ธฐ์–ต์— ๊ธฐ๋ฐ˜ํ•ด personality gradually drift (ex: ๊ฐ์ •์ ์ด๊ฑฐ๋‚˜ ์ด์„ฑ์  ์„ฑํ–ฅ ๊ฐ•ํ™”)
95
+
96
+ ### โœ… ๊ด€๊ณ„ ์‹œ์Šคํ…œ
97
+ - `RelationshipManager`: -100 ~ +100 ๋ฒ”์œ„์˜ ๊ด€๊ณ„ ์ ์ˆ˜ ๊ด€๋ฆฌ
98
+ - ๊ฐ์ • ํ‘œํ˜„ ๋ฐ ๊ธฐ์–ต์ด ๊ด€๊ณ„์— ์˜ํ–ฅ์„ ์คŒ (`reflect_memory_on_relationship`)
99
+
100
+ ### โœ… ํ–‰๋™ ์‹œ์Šคํ…œ
101
+ - ๊ฐ์ • โ†’ ํ–‰๋™ ์‹œํ€€์Šค๋กœ ๋ณ€ํ™˜ (`BehaviorManager`)
102
+ - ํ–‰๋™์€ ๊ธฐ์–ต์— ๊ธฐ๋ก๋˜๊ณ , ๋‹ค์‹œ ๊ฐ์ •์— ์˜ํ–ฅ์„ ์คŒ (์—ญ๋งคํ•‘)
103
+
104
+ ### โœ… LLM ์‹œ์Šคํ…œ
105
+ - `query_llm_for_emotion`: ๊ฐ์ • ์ถ”๋ก ์šฉ LLM ํ˜ธ์ถœ
106
+ - `query_llm_with_prompt`: ๋Œ€์‚ฌ ์ƒ์„ฑ์šฉ LLM ํ˜ธ์ถœ
107
+ - `build_npc_prompt`: ๊ฐ์ •/๊ธฐ์–ต ๊ธฐ๋ฐ˜ ํ”„๋กฌํ”„ํŠธ ์ƒ์„ฑ
108
+ - `summarize_memories`: ์žฅ๊ธฐ ๏ฟฝ๏ฟฝ์–ต ์š”์•ฝ
109
+
110
+ ### โœ… ์ž„๋ฒ ๋”ฉ ์‹œ์Šคํ…œ
111
+ - `npc_memory_embedder.py`:
112
+ - `embed_npc_memories`: FAISS ์ €์žฅ
113
+ - `search_similar_memories`: ์งˆ์˜ ์œ ์‚ฌ๋„ ๊ฒ€์ƒ‰
114
+ - ๋ชจ๋ธ: `all-MiniLM-L6-v2` ์‚ฌ์šฉ ์ค‘
115
+
116
+ ---
117
+
118
+ ## ๐Ÿ” ์ฃผ์š” ์‹œํ€€์Šค ํ๋ฆ„
119
+
120
+ ### ๐Ÿ—จ๏ธ `interact_with_player()` ์ „์ฒด ํ๋ฆ„
121
+ 1. LLM์œผ๋กœ ๊ฐ์ • ์ถ”๋ก  (`query_llm_for_emotion`)
122
+ 2. ๊ธฐ์–ต ๊ฒ€์ƒ‰ (FAISS + embedding)
123
+ 3. LLM ํ”„๋กฌํ”„ํŠธ ์ƒ์„ฑ (`build_npc_prompt`)
124
+ 4. ์‘๋‹ต ์ƒ์„ฑ + ๊ธฐ์–ต ์ €์žฅ
125
+ 5. ๊ฐ์ • ์—…๋ฐ์ดํŠธ (`update_emotion`)
126
+ 6. ๊ด€๊ณ„ ๋ณ€ํ™” ๋ฐ˜์˜ (`reflect_memory_on_relationship`)
127
+ 7. ์„ฑ๊ฒฉ ๋ณ€ํ™” (`update_personality`)
128
+
129
+ ---
130
+
131
+ ## ๐Ÿ“ฆ ์‹คํ–‰ ๋ฐฉ๋ฒ•
132
+
133
+ ```bash
134
+ conda activate portfolio
135
+
136
+ # Flask ์›น ์„œ๋ฒ„ ์‹คํ–‰
137
+ python portfolio/app.py
138
+ # โ†’ http://127.0.0.1:5000/npc_social_network/
139
+
140
+ # ์‹œ๋ฎฌ๋ ˆ์ด์…˜ Pygame ์‹คํ–‰ (์›น ๋ผ์šฐํŠธ๋กœ ์‹คํ–‰๋จ)
141
+ GET /run_npc_simulation
142
+ โ†’ ๋˜๋Š” app.py ๋‚ด subprocess.Popen์œผ๋กœ ์‹คํ–‰๋จ
143
+ ```
144
+
145
+ ---
146
+
147
+ ## โœ… ํ˜„์žฌ๊นŒ์ง€ ๊ตฌํ˜„๋œ ๋‹จ๊ณ„ (์„ค๊ณ„ ๊ธฐ๋ฐ˜)
148
+
149
+ | ๋‹จ๊ณ„ | ๋‚ด์šฉ |
150
+ |------|------|
151
+ | 1๋‹จ๊ณ„ | ํƒ€์ผ/๊ฑด๋ฌผ/๋งˆ์„ ๊ตฌ์กฐ ์ƒ์„ฑ | โœ… ์™„๋ฃŒ | ๋งˆ์„ ๊ตฌ์กฐ ์ƒ์„ฑ ๋ฐ ๋งต ๋ Œ๋”๋ง
152
+ | 2๋‹จ๊ณ„ | NPC ๊ฐ์ • ์ƒํƒœ ๋ฐ ๊ฐ์ • HUD ๊ตฌํ˜„ | โœ… ์™„๋ฃŒ | ๊ฐ์ • ์ƒํƒœ ๋ฐ HUD ํ‘œ์‹œ (Pygame + ์›น)
153
+ | 3๋‹จ๊ณ„ | ๊ฐ์ • โ†” ํ–‰๋™ ์—ฐ๋™ ๊ตฌ์กฐ ๊ตฌํ˜„ | โœ… ์™„๋ฃŒ | ๊ฐ์ • โ†” ํ–‰๋™ ๋งคํ•‘ ๊ตฌํ˜„
154
+ | 4๋‹จ๊ณ„ | ๊ฐ์ • โ†” ๊ธฐ์–ต ์ €์žฅ ๋ฐ decay ๊ตฌํ˜„ | โœ… ์™„๋ฃŒ | Memory ๊ฐ์ • ๋ฐ decay ์ ์šฉ ๊ตฌ์กฐ
155
+ | 5๋‹จ๊ณ„ | ๊ฐ์ • โ†” ๊ด€๊ณ„ ๋ณ€ํ™” ๊ตฌ์กฐ ๊ตฌํ˜„ | ๐Ÿ”ธ ๋ถ€๋ถ„ ์™„๋ฃŒ | ๊ตฌ์กฐ๋Š” ๊ตฌํ˜„๋จ, ํ”Œ๋ ˆ์ด์–ด ๋Œ€์ƒ ๋ฐ˜์˜ ๋ณด์™„ ์ค‘
156
+ | 6๋‹จ๊ณ„ | ์„ฑ๊ฒฉ ์‹œ์Šคํ…œ ๋„์ž… | โœ… ์™„๋ฃŒ | ์„ฑ๊ฒฉ ๋ถ„๋ฆฌ + ์ดˆ๊ธฐ bias ์„ค๊ณ„
157
+ | 7๋‹จ๊ณ„ | NPC ๊ฐ„ ์ƒํ˜ธ์ž‘์šฉ ๊ตฌ์กฐํ™” | โœ… ์™„๋ฃŒ | NPC ์ƒํ˜ธ์ž‘์šฉ โ†’ ๊ฐ์ •/๊ด€๊ณ„ ๋ฐ˜์˜
158
+ | 8๋‹จ๊ณ„ | Memory ์ž„๋ฒ ๋”ฉ + FAISS ๊ธฐ๋ฐ˜ ๊ฒ€์ƒ‰ | โœ… ์™„๋ฃŒ | FAISS ๊ฒ€์ƒ‰ + ์ž„๋ฒ ๋”ฉ ์ €์žฅ ๊ตฌ์กฐ
159
+ | 9๋‹จ๊ณ„ | LLM ๊ธฐ๋ฐ˜ ํ”„๋กฌํ”„ํŠธ ๋Œ€์‚ฌ ์ƒ์„ฑ | โœ… ์™„๋ฃŒ | ํ”„๋กฌํ”„ํŠธ ์„ค๊ณ„ ๋ฐ LLM ์‘๋‹ต
160
+ | 10๋‹จ๊ณ„ | ๊ฐ์ • ์ƒํƒœ HUD ์‹œ๊ฐํ™” (์›น + ๊ฒŒ์ž„ ํ™”๋ฉด) | โœ… ์™„๋ฃŒ | ๊ฐ์ • ์ƒํƒœ HUD (์›น/๊ฒŒ์ž„ ์—ฐ๋™)
161
+
162
+ # ํ•ต์‹ฌ ์‹œ์Šคํ…œ ๊ณ ๋„ํ™”
163
+ | 11๋‹จ๊ณ„ | ๊ฐ์ •/๊ธฐ์–ต/๊ด€๊ณ„ ํ†ตํ•ฉ ์ •๋น„ | ๐Ÿ”„ ์ง„ํ–‰์ค‘ | ๊ด€๊ณ„ ํ†ตํ•ฉ, ๊ฐ์ •-๊ธฐ์–ต-๊ด€๊ณ„ ์—ฐ๊ฒฐ ์™„์„ฑ๋„ ํ–ฅ์ƒ ์ค‘
164
+ | 12๋‹จ๊ณ„ | LLM ๋Œ€์‚ฌ ์ƒ์„ฑ ๊ณ ๋„ํ™” | โœ… ์™„๋ฃŒ | LLM ๋Œ€์‚ฌ ์ƒ์„ฑ ๊ฐœ์„ , ํ”„๋กฌํ”„ํŠธ ์™„์„ฑ
165
+ | 13๋‹จ๊ณ„ | ๊ธฐ์–ต decay ์ •๊ตํ™” | โณ ๋ฏธ์ง„ํ–‰ | decay ์‹œ์ ๋ณ„ ๋ณ€ํ™”์œจ ์กฐ์ • ๋“ฑ ์ •๊ตํ™” ๋ฏธ์‹คํ–‰
166
+ | 14-1๋‹จ๊ณ„ | ๊ธฐ์–ต ์ž„๋ฒ ๋”ฉ ๊ตฌ์กฐ ํ™•์žฅ | โœ… ์™„๋ฃŒ | Memory ๊ฐ์ฒด ์ž„๋ฒ ๋”ฉ ๊ตฌ์กฐ ๋„์ž…
167
+ | 14-2๋‹จ๊ณ„ | ์ž„๋ฒ ๋”ฉ ๋ชจ๋ธ ๊ต์ฒด | โœ… ์™„๋ฃŒ | ๋ฒกํ„ฐ ์ž„๋ฒ ๋”ฉ ๋ชจ๋ธ ๊ต์ฒด ์˜ˆ์ • ์ƒํƒœ๋กœ ์ •๋ฆฌ
168
+ | 15๋‹จ๊ณ„ | ํ–‰๋™ ๊ณ„ํš ์ƒ์„ฑ๊ธฐ (LLM Planner ์—ฐ๋™) | โณ ๋ฏธ์ง„ํ–‰ | Planner ์—ฐ๋™์€ ์‹œ์ž‘ ์ „
169
+ | 16๋‹จ๊ณ„ | ์‚ฌํšŒ์  ํ”„๋กœํŒŒ์ผ ์‹œ์Šคํ…œ ๋„์ž… | โณ ๋ฏธ์ง„ํ–‰ | ๊ด€๊ณ„ ์„ค๋ช… โ†’ ์‹œ๊ฐํ™” ๊ตฌ์กฐ๋กœ ํ™•์žฅ ์˜ˆ์ •
170
+ | 17๋‹จ๊ณ„ | ์ƒ์ง• ๊ธฐ์–ต / ๋Œ€ํ‘œ ๊ธฐ์–ต ์ƒ์„ฑ | โณ ๋ฏธ์ง„ํ–‰ | ์ƒ์ง• ๊ธฐ์–ต ๋ถ„๋ฅ˜/์š”์•ฝ ์•„์ง ๋ฏธ์‹คํ–‰
171
+ | 18๋‹จ๊ณ„ | ๊ธฐ์–ต ์ฒด๊ณ„ ํ™•์žฅ: ์‹œ๊ฐ„ ๋งฅ๋ฝ ๋ถ€์—ฌ | โณ ๋ฏธ์ง„ํ–‰ | ๊ธฐ์–ต์— ์‹œ๊ฐ„ ๋งฅ๋ฝ/๊ณ„์ ˆ/์‹œ๊ธฐ ๋ถ€์—ฌ ๋ฏธ์™„๋ฃŒ
172
+ | 19๋‹จ๊ณ„ | ๊ฐ์ •-์„ฑ๊ฒฉ-ํ–‰๋™ ์ผ๊ด€์„ฑ ์œ ์ง€ ํ‰๊ฐ€ | โณ ๋ฏธ์ง„ํ–‰ | ์„ฑ๊ฒฉ ๊ธฐ๋ฐ˜ ๊ฐ์ •/ํ–‰๋™ ๋™๊ธฐ ์ผ๊ด€์„ฑ ํ™•์ธ ์„ค๊ณ„
173
+ | 20๋‹จ๊ณ„ | NPC ์‚ฌํšŒ ๋„คํŠธ์›Œํฌ ์‹œ๊ฐํ™” | โณ ๋ฏธ์ง„ํ–‰ |
174
+
175
+ # ๊ณ ๊ธ‰ ์ธ๊ฐ„ํ™” ๋ฐ ์ž๊ฐํ˜• NPC ํ™•์žฅ
176
+ | 21๋‹จ๊ณ„ | ์„ฑ๊ฒฉ ์ง€์†์  ๋ณ€ํ™” ์„ค๊ณ„ ์™„์„ฑ |
177
+ | 22๋‹จ๊ณ„ | ํ–‰๋™ ์œ ๋„ ๊ธฐ๋ฐ˜ ๊ณ„ํšํ˜• NPC |
178
+ | 23๋‹จ๊ณ„ | ์œค๋ฆฌ ์‹œ์Šคํ…œ ์‹คํ—˜ (์ž๊ฐํ˜• ๊ตฌ์กฐํ™”) |
179
+ | 24๋‹จ๊ณ„ | NPC ์ž์•„ ํ˜•์„ฑ ์‹œํ€€์Šค ํ…Œ์ŠคํŠธ |
180
+ | 25๋‹จ๊ณ„ | ํ”Œ๋ ˆ์ด์–ด ๊ธฐ์–ต ๋ฐ ๋ฐ˜์‘ ์‹œ์Šคํ…œ ๊ตฌ์ถ• |
181
+ | 26๋‹จ๊ณ„ | ๋ฉ€ํ‹ฐ์บ๋ฆญํ„ฐ ๋‹ค์ž ๊ฐ„ ์ƒํ˜ธ์ž‘์šฉ ๋ฃจํ”„ |
182
+ | 27๋‹จ๊ณ„ | ์‹œ๋ฎฌ๋ ˆ์ด์…˜ UI ์‹œ๊ฐํ™” ๊ณ ๋„ํ™” |
183
+ | 28๋‹จ๊ณ„ | ๋ฉ”ํƒ€๊ธฐ์–ต ์‹œ์Šคํ…œ |
184
+ | 29๋‹จ๊ณ„ | LLM+RAG+ํ”Œ๋ž˜๋„ˆ ์ข…ํ•ฉ ๊ตฌ์กฐ ํ†ตํ•ฉ |
185
+ | 30๋‹จ๊ณ„ | ๋…ผ๋ฌธ/์—ฐ๊ตฌ ๊ฒฐ๊ณผ ์ •๋ฆฌ ๊ตฌ์กฐํ™” |
186
+
187
+
188
+ ---
189
+
190
+ ## ๐Ÿ“Ž dependency ์˜ˆ์‹œ (requirements ์ผ๋ถ€)
191
+
192
+ ```txt
193
+ flask
194
+ pygame
195
+ sentence-transformers
196
+ faiss-cpu
197
+ numpy
198
+ ```
199
+ โ†’ ์‹ค์ œ ๋ชจ๋ธ ์‚ฌ์šฉ์„ ์œ„ํ•ด GPU ๋ฒ„์ „ ๋˜๋Š” `transformers`, `openai`, `google-generativeai` ๋“ฑ ์ถ”๊ฐ€ ๊ฐ€๋Šฅ
200
+
201
+ ---
202
+
203
+ ## ๐Ÿšจ ์ฃผ์˜ ์‚ฌํ•ญ
204
+
205
+ - ๋ชจ๋“  ๊ฐ์ •, ๊ธฐ์–ต, ํ–‰๋™, ๊ด€๊ณ„๋Š” ๊ฐ์ • ์นดํ…Œ๊ณ ๋ฆฌ ๊ธฐ๋ฐ˜ ๊ตฌ์กฐ๋ฅผ ์ฒ ์ €ํžˆ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค
206
+ - NPC ๋‚ด๋ถ€ ์ƒํƒœ ๋ณ€ํ™”๋Š” ์™„์ „ํžˆ ์„ค๊ณ„๋œ ์ˆœํ™˜๊ตฌ์กฐ (๊ฐ์ •โ†’๊ธฐ์–ตโ†’๊ด€๊ณ„โ†’์„ฑ๊ฒฉโ†’๊ฐ์ •...)๋กœ ๊ตฌํ˜„๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค
207
+ - ํ•จ์ˆ˜๋ช…, ๋ณ€์ˆ˜๋ช…์€ `npc_base.py`์˜ ๊ทœ์น™์— ๋”ฐ๋ผ ๋ณ€๊ฒฝ ๊ธˆ์ง€
208
+ - ํ˜„์žฌ ๋ชจ๋“  ๊ตฌ์กฐ๋Š” **์—ฐ๊ตฌ ๋…ผ๋ฌธ ๋˜๋Š” ์ปจํผ๋Ÿฐ์Šค ๋ชฉ์ **์œผ๋กœ ์„ค๊ณ„๋จ
209
+
210
+ ---
211
+
212
+ ยฉ 2025 NPC Social Network Simulation Project v2
npc_social_network/npc/emotion_config.py CHANGED
@@ -153,4 +153,23 @@ NEGATIVE_RELATION_EMOTIONS = [
153
  COGNITIVE_RELATION_EMOTIONS = [
154
  "compassion", "awe", "attachment", "anticipation", "curiosity",
155
  "nostalgia", "bittersweet", "rumination", "groundedness", "comfort",
156
- ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
153
  COGNITIVE_RELATION_EMOTIONS = [
154
  "compassion", "awe", "attachment", "anticipation", "curiosity",
155
  "nostalgia", "bittersweet", "rumination", "groundedness", "comfort",
156
+ ]
157
+
158
+ # ๊ฐ์ •๋ณ„ ๊ด€๊ณ„ ์˜ํ–ฅ๋„ ์ •์˜ (๊ด€๊ณ„์— ์˜ํ–ฅ ์ฃผ๋Š” ๊ฐ์ •๋งŒ ๋“ฑ๋ก, ์ •๊ทœํ™”๋œ [-2.0 ~ +2.0] ๋ฒ”์œ„ ์•ˆ์—์„œ ์ •์˜)
159
+ EMOTION_RELATION_IMPACT = {
160
+ "joy": +1.0,
161
+ "gratitude": +1.2,
162
+ "love": +2.0,
163
+ "admiration": +0.8,
164
+ "pride": +0.7,
165
+ "calm": +0.5,
166
+ "sadness": -0.8,
167
+ "anger": -1.5,
168
+ "disgust": -2.0,
169
+ "fear": -1.0,
170
+ "shame": -1.2,
171
+ "resentment": -1.5,
172
+ "regret": -0.9,
173
+ "hope": +0.9,
174
+ "comfort": +0.6,
175
+ }
npc_social_network/npc/npc_base.py CHANGED
@@ -2,7 +2,7 @@
2
  from .npc_memory import Memory, MemoryStore
3
  from .npc_emotion import EmotionManager
4
  from .npc_behavior import BehaviorManager
5
- from .emotion_config import EMOTION_LIST, EMOTION_CATEGORY_MAP, EMOTION_DECAY_RATE, PERSONALITY_TEMPLATE
6
  from .emotion_config import POSITIVE_RELATION_EMOTIONS, NEGATIVE_RELATION_EMOTIONS, COGNITIVE_RELATION_EMOTIONS
7
  from .personality_config import AGE_PROFILE, PERSONALITY_PROFILE
8
  from .npc_relationship import RelationshipManager
@@ -313,23 +313,34 @@ class NPC:
313
  self.update_emotion(emotion, strength=2.0)
314
 
315
  # STEP 2: ๊ด€๋ จ ๊ธฐ์–ต ๊ฒ€์ƒ‰
316
- _, _, matched_memories = search_similar_memories(self.name, player_input)
317
- # ์š”์•ฝ & ์žฅ๊ธฐ ๊ธฐ์–ตํ™” (3๊ฐœ ์ด์ƒ์ผ ๋•Œ๋งŒ)
318
- if len(matched_memories) >= 3:
319
- self.summarize_and_store_memories(matched_memories)
320
 
321
  # STEP 3: ํ”„๋กฌํ”„ํŠธ ์ƒ์„ฑ
322
- prompt = build_npc_prompt(self, player_input, matched_memories)
 
 
323
 
324
  # STEP 4: LLM ์‘๋‹ต ์ƒ์„ฑ
325
  npc_reply = query_llm_with_prompt(prompt)
326
 
327
  # STEP 5: ๊ธฐ์–ต ๊ธฐ๋ก
328
- self.remember(
329
  content=f"[ํ”Œ๋ ˆ์ด์–ด] '{player_input}' โ†’ [NPC:{self.name}] '{npc_reply}'",
330
  importance=6,
331
  emotion=emotion
332
  )
 
 
 
 
 
 
 
 
 
 
 
 
333
 
334
  return npc_reply
335
 
 
2
  from .npc_memory import Memory, MemoryStore
3
  from .npc_emotion import EmotionManager
4
  from .npc_behavior import BehaviorManager
5
+ from .emotion_config import EMOTION_CATEGORY_MAP, EMOTION_DECAY_RATE, PERSONALITY_TEMPLATE, EMOTION_RELATION_IMPACT
6
  from .emotion_config import POSITIVE_RELATION_EMOTIONS, NEGATIVE_RELATION_EMOTIONS, COGNITIVE_RELATION_EMOTIONS
7
  from .personality_config import AGE_PROFILE, PERSONALITY_PROFILE
8
  from .npc_relationship import RelationshipManager
 
313
  self.update_emotion(emotion, strength=2.0)
314
 
315
  # STEP 2: ๊ด€๋ จ ๊ธฐ์–ต ๊ฒ€์ƒ‰
316
+ matched_memories = search_similar_memories(self.name, player_input)
 
 
 
317
 
318
  # STEP 3: ํ”„๋กฌํ”„ํŠธ ์ƒ์„ฑ
319
+ prompt = build_npc_prompt(cnp=self,
320
+ user_input=player_input,
321
+ matched_memories=matched_memories)
322
 
323
  # STEP 4: LLM ์‘๋‹ต ์ƒ์„ฑ
324
  npc_reply = query_llm_with_prompt(prompt)
325
 
326
  # STEP 5: ๊ธฐ์–ต ๊ธฐ๋ก
327
+ memory = Memory(
328
  content=f"[ํ”Œ๋ ˆ์ด์–ด] '{player_input}' โ†’ [NPC:{self.name}] '{npc_reply}'",
329
  importance=6,
330
  emotion=emotion
331
  )
332
+ self.memory_store.add_memory(memory)
333
+
334
+ # STEP 6: ๊ฐ์ • ๊ธฐ๋ฐ˜ ๊ด€๊ณ„ ๋ณ€ํ™” ๋ฐ˜์˜
335
+ if isinstance(emotion, dict):
336
+ delta = 0.0
337
+ for emo, strength in emotion.items():
338
+ if emo in EMOTION_RELATION_IMPACT:
339
+ delta += EMOTION_RELATION_IMPACT[emo] * strength
340
+
341
+ if abs(delta) > 0.01: # ์˜ํ–ฅ์ด ์ถฉ๋ถ„ํžˆ ์žˆ์„ ๋•Œ๋งŒ ๋ฐ˜์˜
342
+ self.relationships.update_relationship("ํ”Œ๋ ˆ์ด์–ด", delta=delta)
343
+ print(f"[๊ด€๊ณ„ ๋ณ€ํ™”] '{self.name}' โ†’ ํ”Œ๋ ˆ์ด์–ด: {delta:+.2f}")
344
 
345
  return npc_reply
346