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, AGE_PROFILE
 
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 = personality_profile[profile_type]
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
- # ์ธ์ƒ ๋‹จ๊ณ„ profile ์ถ”๊ฐ€
100
- self.personality_stage = "adolescence" # ๊ธฐ๋ณธ "adolescence", NPC๋งˆ๋‹ค ๋‹ค๋ฅด๊ฒŒ ์„ค์ • ๊ฐ€๋Šฅ
 
 
 
 
 
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
+ }