Spaces:
Sleeping
Sleeping
humanda5
commited on
Commit
ยท
f302085
1
Parent(s):
24c2c08
Complete step 14-1
Browse files
npc_social_network/npc/npc_base.py
CHANGED
@@ -3,9 +3,11 @@ 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 .npc_relationship import RelationshipManager
|
8 |
from ..models.llm_helper import query_llm_for_emotion, query_llm_for_response, query_llm_for_response_with_context
|
|
|
9 |
import random
|
10 |
import copy
|
11 |
|
@@ -62,29 +64,9 @@ class NPC:
|
|
62 |
# baseline buffer๋ฅผ EmotionManager์ ๋ฑ๋ก
|
63 |
self.emotion.set_baseline(baseline_buffer)
|
64 |
|
65 |
-
# Personality ์ฑ๊ฒฉ ํ๋กํ ๊ธฐ๋ฐ
|
66 |
-
# profile: stable / emotional / logical (์ถํ ๋ ์ถ๊ฐ)
|
67 |
-
personality_profile = {
|
68 |
-
"stable": {
|
69 |
-
"sensitive": (0.002, 0.004),
|
70 |
-
"stoic": (0.002, 0.004),
|
71 |
-
"cognitive_bias": (0.002, 0.004)
|
72 |
-
},
|
73 |
-
"emotional":{
|
74 |
-
"sensitive": (0.006, 0.01),
|
75 |
-
"stoic": (0.002, 0.004),
|
76 |
-
"cognitive_bias": (0.004, 0.006)
|
77 |
-
},
|
78 |
-
"logical":{
|
79 |
-
"sensitive": (0.002, 0.004),
|
80 |
-
"stoic": (0.004, 0.006),
|
81 |
-
"cognitive_bias":(0.006, 0.01)
|
82 |
-
},
|
83 |
-
}
|
84 |
-
|
85 |
# ํ๋กํ ์ง์ โ ๊ธฐ๋ณธ์ "stable", ๋์ค์ NPC๋ง๋ค ๋ค๋ฅด๊ฒ ๋ถ์ฌ
|
86 |
profile_type = "stable"
|
87 |
-
profile =
|
88 |
|
89 |
# Personality ๋ณํ ์๋ ๊ฐ๋ณ ์ค์
|
90 |
self.personality_change_rate = {
|
@@ -96,8 +78,13 @@ class NPC:
|
|
96 |
# Personality baseline ์ ์ฅ (์ด๊ธฐ๊ฐ ๋ณต์ฌ)
|
97 |
self.personality_baseline = copy.deepcopy(self.personality)
|
98 |
|
99 |
-
#
|
100 |
-
self.
|
|
|
|
|
|
|
|
|
|
|
101 |
|
102 |
def move(self):
|
103 |
"""
|
@@ -469,9 +456,13 @@ class NPC:
|
|
469 |
|
470 |
# ์ธ์ ๋จ๊ณ๋ณ ๋ณํ์จ ์ ์ฉ
|
471 |
stage_factor = AGE_PROFILE.get(self.personality_stage, 1.0)
|
|
|
|
|
|
|
|
|
472 |
|
473 |
# ์ต์ข
weight ๊ณ์ฐ
|
474 |
-
weight = stage_factor * (m.importance / 10.0) * type_weight * emotion_weight * emotion_bias_factor # importance 1~10 โ 0.1 ~ 1.0
|
475 |
if m.emotion in POSITIVE_RELATION_EMOTIONS:
|
476 |
self.personality["sensitive"] = min(1.0, self.personality["sensitive"] + self.personality_change_rate["sensitive"] * weight)
|
477 |
self.personality["stoic"] = max(0.0, self.personality["stoic"] - self.personality_change_rate["stoic"] * weight)
|
@@ -500,4 +491,43 @@ class NPC:
|
|
500 |
"""
|
501 |
์๊ฐ์ด ์ง๋จ์ ๋ฐ๋ผ ๊ธฐ์ต importance ๊ฐ์
|
502 |
"""
|
503 |
-
self.memory_store.decay_memories()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
9 |
from ..models.llm_helper import query_llm_for_emotion, query_llm_for_response, query_llm_for_response_with_context
|
10 |
+
from datetime import datetime
|
11 |
import random
|
12 |
import copy
|
13 |
|
|
|
64 |
# baseline buffer๋ฅผ EmotionManager์ ๋ฑ๋ก
|
65 |
self.emotion.set_baseline(baseline_buffer)
|
66 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
67 |
# ํ๋กํ ์ง์ โ ๊ธฐ๋ณธ์ "stable", ๋์ค์ NPC๋ง๋ค ๋ค๋ฅด๊ฒ ๋ถ์ฌ
|
68 |
profile_type = "stable"
|
69 |
+
profile = PERSONALITY_PROFILE[profile_type]
|
70 |
|
71 |
# Personality ๋ณํ ์๋ ๊ฐ๋ณ ์ค์
|
72 |
self.personality_change_rate = {
|
|
|
78 |
# Personality baseline ์ ์ฅ (์ด๊ธฐ๊ฐ ๋ณต์ฌ)
|
79 |
self.personality_baseline = copy.deepcopy(self.personality)
|
80 |
|
81 |
+
# ๋์ด ์ถ๊ฐ (0 ~ 80์ธ ๊ธฐ๋ณธ ๋๋ค ์ด๊ธฐํ โ ๋์ค์ ์์ฑ ์ age ์ง์ ๊ฐ๋ฅ)
|
82 |
+
self.age = random.randint(0, 80)
|
83 |
+
|
84 |
+
# ์ด๊ธฐ personality_stage๋ update_personality_stage()์์ ์๋ ์ค์
|
85 |
+
self.personality_stage = None
|
86 |
+
self.update_personality_stage()
|
87 |
+
|
88 |
|
89 |
def move(self):
|
90 |
"""
|
|
|
456 |
|
457 |
# ์ธ์ ๋จ๊ณ๋ณ ๋ณํ์จ ์ ์ฉ
|
458 |
stage_factor = AGE_PROFILE.get(self.personality_stage, 1.0)
|
459 |
+
# memory_age_in_days ๊ณ์ฐ (ํ์ฌ ์์ - memory timestamp)
|
460 |
+
memory_age_in_days = max(0, (datetime.now() - m.timestamp).days)
|
461 |
+
# importance scaling factor ๊ณ์ฐ
|
462 |
+
importance_scaling = self.get_memory_importance_scaling(memory_age_in_days)
|
463 |
|
464 |
# ์ต์ข
weight ๊ณ์ฐ
|
465 |
+
weight = stage_factor * (m.importance / 10.0) * type_weight * emotion_weight * emotion_bias_factor * importance_scaling # importance 1~10 โ 0.1 ~ 1.0
|
466 |
if m.emotion in POSITIVE_RELATION_EMOTIONS:
|
467 |
self.personality["sensitive"] = min(1.0, self.personality["sensitive"] + self.personality_change_rate["sensitive"] * weight)
|
468 |
self.personality["stoic"] = max(0.0, self.personality["stoic"] - self.personality_change_rate["stoic"] * weight)
|
|
|
491 |
"""
|
492 |
์๊ฐ์ด ์ง๋จ์ ๋ฐ๋ผ ๊ธฐ์ต importance ๊ฐ์
|
493 |
"""
|
494 |
+
self.memory_store.decay_memories()
|
495 |
+
|
496 |
+
def update_personality_stage(self):
|
497 |
+
"""
|
498 |
+
ํ์ฌ ๋์ด์ ๋ฐ๋ผ personality_stage ์๋ ์
๋ฐ์ดํธ
|
499 |
+
"""
|
500 |
+
if self.age < 3:
|
501 |
+
self.personality_stage = "infancy_and_toddlerhood"
|
502 |
+
elif self.age < 6:
|
503 |
+
self.personality_stage = "early_childhood"
|
504 |
+
elif self.age < 12:
|
505 |
+
self.personality_stage = "middle_childhood"
|
506 |
+
elif self.age < 18:
|
507 |
+
self.personality_stage = "adolescence"
|
508 |
+
elif self.age < 30:
|
509 |
+
self.personality_stage = "young_adulthood"
|
510 |
+
elif self.age < 65:
|
511 |
+
self.personality_stage = "middle_adulthood"
|
512 |
+
else:
|
513 |
+
self.personality_stage = "older_adulthood"
|
514 |
+
|
515 |
+
def get_memory_importance_scaling(self, memory_age_in_days: float) -> float:
|
516 |
+
"""
|
517 |
+
NPC์ ๋์ด์ ๋ฐ๋ผ memory_age_in_days ๊ธฐ๋ฐ scaling factor ๋ฐํ
|
518 |
+
- ์ ์ NPC โ ์ต๊ทผ ๊ธฐ์ต ๋ ๊ฐ์กฐ
|
519 |
+
- ๋
ธ๋
NPC โ ์ค๋๋ ๊ธฐ์ต ๋ ๊ฐ์กฐ
|
520 |
+
"""
|
521 |
+
if self.personality_stage in [
|
522 |
+
"infancy_and_toddlerhood", "early_choldhood", "middle_childhood",
|
523 |
+
"adolescence", "young_adulthood"
|
524 |
+
]:
|
525 |
+
# ์ต๊ทผ ๊ธฐ์ต ๊ฐ์กฐ โ ์ค๋๋ ๊ธฐ์ต ์ํฅ ์ฝํ
|
526 |
+
return max(0.5, 1.5 - 0.05 * memory_age_in_days) # ์ต๋ 1.5, ์ ์ ๊ฐ์
|
527 |
+
elif self.personality_stage in [
|
528 |
+
"middle_adulthood", "older_adulthood"
|
529 |
+
]:
|
530 |
+
return min(1.5, 0.5 + 0.05 * memory_age_in_days) # ์ต์ 0.5, ์ ์ ์ฆ๊ฐ
|
531 |
+
else:
|
532 |
+
# fallback โ ์ ์ํ
|
533 |
+
return 1.0
|
npc_social_network/npc/npc_memory_embedder.py
ADDED
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# portfolio/npc_social_network/npc/npc_memory_embedder.py
|
2 |
+
|
3 |
+
from sentence_transformers import SentenceTransformer
|
4 |
+
import numpy as np
|
5 |
+
import faiss
|
6 |
+
import os
|
7 |
+
from .npc_memory import MemoryStore
|
8 |
+
from .npc_base import NPC
|
9 |
+
|
10 |
+
# ์ฌ์ ํ๋ จ๋ ๋ฌธ์ฅ ์๋ฒ ๋ฉ ๋ชจ๋ธ
|
11 |
+
model = SentenceTransformer("all-MiniLM-L6-v2")
|
12 |
+
|
13 |
+
# ๋ฌธ์ฅ ์๋ฒ ๋ฉ ์ ์ฅ ์ฅ์
|
14 |
+
VECTOR_DIR = "portfolio/npc_social_network/data/vectorstores"
|
15 |
+
|
16 |
+
def memory_to_text(memory):
|
17 |
+
"""
|
18 |
+
Memoty ๊ฐ์ฒด๋ฅผ ์๋ฒ ๋ฉ ๊ฐ๋ฅํ ํ
์คํธ ํํ๋ก ๋ณํ
|
19 |
+
"""
|
20 |
+
lines = [f"Content: {memory.content}"]
|
21 |
+
if memory.emotion:
|
22 |
+
emotion_str = ", ".join([f"{k}:{v:.2f}" for k, v in memory.emotion.items()])
|
23 |
+
lines.append(f"Emotion: {emotion_str}")
|
24 |
+
lines.append(f"Importance: {memory.importance}")
|
25 |
+
return " | ".join(lines)
|
26 |
+
|
27 |
+
def embed_memory(memory):
|
28 |
+
"""
|
29 |
+
Memory ๊ฐ์ฒด 1๊ฐ๋ฅผ ๋ฒกํฐ๋ก ์๋ฒ ๋ฉ
|
30 |
+
"""
|
31 |
+
text = memory_to_text(memory)
|
32 |
+
embedding = model.encode(text)
|
33 |
+
return embedding
|
34 |
+
|
35 |
+
def embed_npc_memories(npc: NPC):
|
36 |
+
"""
|
37 |
+
ํน์ NPC์ ๊ธฐ์ต ์ ์ฒด๋ฅผ ์๋ฒ ๋ฉํ๊ณ FAISS index๋ก ์ ์ฅ
|
38 |
+
"""
|
39 |
+
if not os.path.exists(VECTOR_DIR):
|
40 |
+
os.makedirs(VECTOR_DIR)
|
41 |
+
|
42 |
+
memories = npc.memory.get_all()
|
43 |
+
texts = [memory_to_text(mem) for mem in memories]
|
44 |
+
embeddings = model.encode(texts)
|
45 |
+
|
46 |
+
index = faiss.IndexFlatL2(len(embeddings[0]))
|
47 |
+
index.add(np.array(embeddings, dtype=np.float32))
|
48 |
+
|
49 |
+
faiss.write_index(index, f"{VECTOR_DIR}/{npc.name}")
|
50 |
+
|
51 |
+
print(f"[์๋ฒ ๋ฉ ์๋ฃ] {npc.name}์ ๊ธฐ์ต {len(memories)}๊ฐ๋ฅผ ๋ฒกํฐํํ์ฌ ์ ์ฅํ์ต๋๋ค.")
|
npc_social_network/npc/personality_config.py
ADDED
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# portfolio/npc_social_network/npc/personality_config.py
|
2 |
+
|
3 |
+
# ์ธ์ ๋จ๊ณ๋ณ Personality ๋ณํ์จ ์ ์
|
4 |
+
AGE_PROFILE = {
|
5 |
+
"infancy_and_toddlerhood": 3.0, # (0-3 ์ธ) Temperament & attachment foundation โ change rate very high
|
6 |
+
"early_childhood": 2.0, # (3-6 ์ธ) Initial personality structure emergence โ high change rate
|
7 |
+
"middle_childhood": 1.5, # (6-12 ์ธ) Personality structure solidification โ still high change rate
|
8 |
+
"adolescence": 1.0, # (12-18 ์ธ) Identity formation โ moderate to high change rate
|
9 |
+
"young_adulthood": 0.5, # (18-30 ์ธ) Personality stabilization โ moderate change rate
|
10 |
+
"middle_adulthood": 0.2, # (30-65 ์ธ) Personality highly stable โ low change rate
|
11 |
+
"older_adulthood": 0.02 # (65- ์ธ) Personality largely fixed โ minimal change
|
12 |
+
}
|
13 |
+
|
14 |
+
# Personality ์ฑ๊ฒฉ ํ๋กํ ๊ธฐ๋ฐ
|
15 |
+
# profile: stable / emotional / logical (์ถํ ๋ ์ถ๊ฐ)
|
16 |
+
PERSONALITY_PROFILE = {
|
17 |
+
"stable": {
|
18 |
+
"sensitive": (0.002, 0.004),
|
19 |
+
"stoic": (0.002, 0.004),
|
20 |
+
"cognitive_bias": (0.002, 0.004)
|
21 |
+
},
|
22 |
+
"emotional":{
|
23 |
+
"sensitive": (0.006, 0.01),
|
24 |
+
"stoic": (0.002, 0.004),
|
25 |
+
"cognitive_bias": (0.004, 0.006)
|
26 |
+
},
|
27 |
+
"logical":{
|
28 |
+
"sensitive": (0.002, 0.004),
|
29 |
+
"stoic": (0.004, 0.006),
|
30 |
+
"cognitive_bias":(0.006, 0.01)
|
31 |
+
},
|
32 |
+
}
|