humanda5 commited on
Commit
19c2d2e
·
1 Parent(s): d505821

코드 리팩토링ver2

Browse files
npc_social_network/README.txt CHANGED
@@ -185,7 +185,7 @@ NPC 상세 정보 패널: 특정 NPC를 클릭하면, 해당 NPC의 현재 감
185
 
186
  '플레이어'의 요약된 기억 개입 도구: 특정 NPC 또는 모든 NPC에게 인위적인 이벤트를 과거의 기억으로 주입하여, 특별한 상황에 대한 NPC의 반응을 테스트할 수 있는 기능을 구현합니다.
187
 
188
- Phase 3: 사회적 상호작용 심화 (Social Interaction Deepening) - 🎯 다음 목표
189
  이제 개별 NPC의 내면을 넘어, NPC들이 서로 영향을 주고받으며 하나의 '사회'를 형성하는 고차원적인 상호작용을 구현합니다.
190
 
191
  1단계: 소문 및 평판 시스템 (Gossip & Reputation System):
@@ -196,12 +196,28 @@ Phase 3: 사회적 상호작용 심화 (Social Interaction Deepening) - 🎯 다
196
  2-A. 멀티턴(Multi-turn) 대화 시스템: 여러 턴에 걸쳐 깊이 있는 대화를 나누는 기능. (가장 시급하고 효과가 큼)
197
  2-B. 지능적 사회적 행동: '돕기', '선물 주기' 등 대화 외의 상호작용 추가.
198
 
199
- 3단계: 사회적 그룹 형성 (Clique Formation):
 
200
  구현 목표: 관계 유형(friend, rival)과 평판을 기반으로 NPC들이 자동으로 그룹이나 파벌을 형성하는 시스템을 구현합니다.
201
  기대 효과: NPC들은 자신이 속한 그룹의 구성원과 더 자주 긍정적인 상호작용을 하고, 경쟁 그룹의 구성원은 피하거나 부정적인 상호작용을 하는 등, 더욱 복잡하고 현실적인 사회적 행동을 보여주게 됩니다.
202
 
 
 
 
 
 
 
 
 
203
  4단계: 고차원적 자아 기능 활성화
204
  - 그룹 활동 등을 통해 얻은 새로운 경험을 바탕으로, NPC가 자신의 관계를 정리하거나 새로운 깨달음을 획득.
 
 
 
 
 
 
 
205
 
206
  Phase 4: 자아와 윤리의 탐구 (Self & Ethics Exploration) - 🚀 장기 과제
207
  NPC가 단순한 반응을 넘어, 스스로를 이해하고 도덕적인 판단을 내리는 고차원적인 자아를 탐구합니다.
 
185
 
186
  '플레이어'의 요약된 기억 개입 도구: 특정 NPC 또는 모든 NPC에게 인위적인 이벤트를 과거의 기억으로 주입하여, 특별한 상황에 대한 NPC의 반응을 테스트할 수 있는 기능을 구현합니다.
187
 
188
+ Phase 3: 사회적 상호작용 심화 (Social Interaction Deepening) - 완료
189
  이제 개별 NPC의 내면을 넘어, NPC들이 서로 영향을 주고받으며 하나의 '사회'를 형성하는 고차원적인 상호작용을 구현합니다.
190
 
191
  1단계: 소문 및 평판 시스템 (Gossip & Reputation System):
 
196
  2-A. 멀티턴(Multi-turn) 대화 시스템: 여러 턴에 걸쳐 깊이 있는 대화를 나누는 기능. (가장 시급하고 효과가 큼)
197
  2-B. 지능적 사회적 행동: '돕기', '선물 주기' 등 대화 외의 상호작용 추가.
198
 
199
+ 3단계: 기능 추가 개선 사항 정리
200
+ 3-A. 사회적 그룹 형성 (Clique Formation) - 나중에 진행
201
  구현 목표: 관계 유형(friend, rival)과 평판을 기반으로 NPC들이 자동으로 그룹이나 파벌을 형성하는 시스템을 구현합니다.
202
  기대 효과: NPC들은 자신이 속한 그룹의 구성원과 더 자주 긍정적인 상호작용을 하고, 경쟁 그룹의 구성원은 피하거나 부정적인 상호작용을 하는 등, 더욱 복잡하고 현실적인 사회적 행동을 보여주게 됩니다.
203
 
204
+ 3-B. 플레이어 개입 및 관계 형성 시스템
205
+ 구현 목표: 플레이어가 '신'의 관점에서 시뮬레이션에 직접 개입하여 새로운 관계나 사건을 만들어내는 기능을 구현.
206
+ 주요 기능: '소개' 기능, 관계 강제 설정, 특정 상황 연출 등.
207
+
208
+ 3-C. UI/UX 안정성 개선
209
+ 구현 목표: 대시보드의 사용 경험을 개선합니다.
210
+ 주요 기능: 관계도 그래프의 떨림 현상 해결, CSS 레이아웃 정리.
211
+
212
  4단계: 고차원적 자아 기능 활성화
213
  - 그룹 활동 등을 통해 얻은 새로운 경험을 바탕으로, NPC가 자신의 관계를 정리하거나 새로운 깨달음을 획득.
214
+ - 1단계: 관계 재정의 (Relationship Redefinition)
215
+ - 구현 목표: NPC가 특정 인물과의 관계를 스스로 되돌아보고, "A는 나에게 이런 존재야" 라고 자신만의 한 줄 요약 정의를 내리도록 합니다.
216
+ - 동작 방식: 시뮬레이션 루프에서 낮은 확률로 이 함수를 호출합니다. 함수가 호출되면, NPC는 특정 대상과의 핵심 기억들을 다시 살펴보고, 그 관계에 대한 새로운 요약(summary)을 생성하여 자신의 내면에 저장합니다.
217
+
218
+ - 2단계: 가치관 형성 (Value Formation)
219
+ - 구현 목표: 수많은 경험(기억)을 통해, "정직이 최고의 가치이다" 또는 "가족을 지키는 것이 가장 중요하다"와 같은 **자신만의 신념이나 좌우명(상징 기억)**을 형성하도록 합니다.
220
+ - 동작 방식: NPC가 충분한 경험(예: 기억 30개 이상)을 쌓았을 때, 시뮬레이션 루프에서 극히 낮은 확률로 이 함수를 호출합니다. 함수가 호출되면, NPC는 자신의 전체 기억을 종합하여 가장 핵심적인 깨달음을 하나의 '상징 기억'으로 만들어 저장합니다.
221
 
222
  Phase 4: 자아와 윤리의 탐구 (Self & Ethics Exploration) - 🚀 장기 과제
223
  NPC가 단순한 반응을 넘어, 스스로를 이해하고 도덕적인 판단을 내리는 고차원적인 자아를 탐구합니다.
npc_social_network/manager/conversation_manager.py CHANGED
@@ -1,8 +1,9 @@
1
  # portfolio/npc_social_network/manager/conversation_manager.py
2
  # 대화의 시작, 진행, 종료를 총괄하는 역할
3
- from ..models.llm_helper import summarize_memories, summarize_text, query_llm_for_emotion
 
4
  from ..npc.npc_manager import get_korean_postposition
5
- from ..npc.emotion_config import EMOTION_RELATION_IMPACT
6
  import threading
7
  from typing import List, Optional, TYPE_CHECKING
8
  if TYPE_CHECKING:
@@ -44,7 +45,7 @@ class ConversationManager:
44
  simulation_core.add_log(log_message)
45
 
46
  def _summarize_and_remember_in_background(self, conv: "Conversation"):
47
- """백그라운드 스레드 대화를 요약하고 기억하며, 관계와 성격에 반영하는 함수"""
48
  from .. import simulation_core
49
  try:
50
  if not conv.conversation_history:
@@ -59,19 +60,37 @@ class ConversationManager:
59
  # 2. 대화의 전반적인 감정 톤 분석
60
  overall_emotion = query_llm_for_emotion(summary)
61
 
 
 
 
 
 
 
 
 
62
  with simulation_core.simulation_lock:
 
 
 
 
 
63
  target_postposition = get_korean_postposition(target.korean_name, "과", "와")
64
- # 3. 요약된 내용을 바탕으로 기억 생성
 
 
 
 
 
65
  memory_content = f"'{conv.topic}'에 대해 대화하며 '{summary}'라는 결론을 내렸다."
66
  initiator.remember(content=f"{target.korean_name}{target_postposition} {memory_content}", importance=7, memory_type="Conversation")
67
  target.remember(content=f"{initiator.korean_name}{target_postposition} {memory_content}", importance=7, memory_type="Conversation")
68
 
69
- # 4. 대화의 감정을 바탕으로 관계 상태 업데이트
70
  if overall_emotion and overall_emotion in EMOTION_RELATION_IMPACT:
71
  initiator.relationships.update_relationship(target.name, overall_emotion, strength=3.0)
72
  target.relationships.update_relationship(initiator.name, overall_emotion, strength=3.0)
73
 
74
- # 5. 관계 변화를 바탕으로 양쪽 모두의 성격 업데이트
75
  initiator.update_personality()
76
  target.update_personality()
77
 
 
1
  # portfolio/npc_social_network/manager/conversation_manager.py
2
  # 대화의 시작, 진행, 종료를 총괄하는 역할
3
+ from ..models.llm_helper import (summarize_text, query_llm_for_emotion
4
+ , evaluate_goal_achievement)
5
  from ..npc.npc_manager import get_korean_postposition
6
+ from ..npc.emotion_config import EMOTION_RELATION_IMPACT, EMOTION_LIST
7
  import threading
8
  from typing import List, Optional, TYPE_CHECKING
9
  if TYPE_CHECKING:
 
45
  simulation_core.add_log(log_message)
46
 
47
  def _summarize_and_remember_in_background(self, conv: "Conversation"):
48
+ """백그라운드에서 대화를 요약하고 기억하며, 관계와 성격에 반영, 목표 달성 평가를 수행하는 함수"""
49
  from .. import simulation_core
50
  try:
51
  if not conv.conversation_history:
 
60
  # 2. 대화의 전반적인 감정 톤 분석
61
  overall_emotion = query_llm_for_emotion(summary)
62
 
63
+ # 3. 목표 달성 여부 평가
64
+ initiator = conv.participants[0]
65
+ evaluation = evaluate_goal_achievement(
66
+ initiator_name=initiator.korean_name,
67
+ goal=conv.topic,
68
+ conversation_transcript=full_conversation
69
+ )
70
+
71
  with simulation_core.simulation_lock:
72
+ # 4. 평가 결과 로그 추가
73
+ simulation_core.add_log(f"[{initiator.korean_name}의 목표 달성 평가]\n"
74
+ f"'{conv.topic}' -> 달성: {evaluation.get('goal_achieved')}.\n"
75
+ f"이유: {evaluation.get('reason')}")
76
+
77
  target_postposition = get_korean_postposition(target.korean_name, "과", "와")
78
+ # 5. 평가 결과에 따른 감정 업데이트
79
+ initiator_emotion = evaluation.get('initiator_emotion')
80
+ if initiator_emotion and initiator_emotion in EMOTION_LIST:
81
+ initiator.update_emotion(initiator_emotion, strength=5.0) # 목표 달성 여부는 강한 감정 유발
82
+
83
+ # 6. 요약된 내용을 바탕으로 기억 생성
84
  memory_content = f"'{conv.topic}'에 대해 대화하며 '{summary}'라는 결론을 내렸다."
85
  initiator.remember(content=f"{target.korean_name}{target_postposition} {memory_content}", importance=7, memory_type="Conversation")
86
  target.remember(content=f"{initiator.korean_name}{target_postposition} {memory_content}", importance=7, memory_type="Conversation")
87
 
88
+ # 7. 대화의 감정을 바탕으로 관계 상태 업데이트
89
  if overall_emotion and overall_emotion in EMOTION_RELATION_IMPACT:
90
  initiator.relationships.update_relationship(target.name, overall_emotion, strength=3.0)
91
  target.relationships.update_relationship(initiator.name, overall_emotion, strength=3.0)
92
 
93
+ # 8. 관계 변화를 바탕으로 양쪽 모두의 성격 업데이트
94
  initiator.update_personality()
95
  target.update_personality()
96
 
npc_social_network/models/llm_helper.py CHANGED
@@ -310,9 +310,9 @@ def evaluate_social_action_outcome(initiator: "NPC", target: "NPC", action_type:
310
 
311
  # Outcome (JSON format only)
312
  {{
313
- "success": "true or false"
314
  "outcome_summary": "행동의 결과를 한 문장으로 요약 (예: '밥은 찰리의 서투른 도움에 고마워하면서도 조금 답답해했다.')",
315
- "initiator_emotion": "행동을 한 후 행동자가 느낄 감정 (아래 'Emotion_List에서 찾아서 한 단어로 표현)"
316
  "target_emotion": "행동을 받은 후 대상자가 느낄 감정 (아래 'Emotion_List에서 찾아서 한 단어로 표현)"
317
  }}
318
 
@@ -328,4 +328,38 @@ def evaluate_social_action_outcome(initiator: "NPC", target: "NPC", action_type:
328
  "outcome_summary": "행동의 결과를 평가하는 데 실패했습니다.",
329
  "initiator_emotion": "confusion",
330
  "target_emotion": "neutral"
331
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
310
 
311
  # Outcome (JSON format only)
312
  {{
313
+ "success": "True or False"
314
  "outcome_summary": "행동의 결과를 한 문장으로 요약 (예: '밥은 찰리의 서투른 도움에 고마워하면서도 조금 답답해했다.')",
315
+ "initiator_emotion": "행동을 한 후 행동자가 느낄 감정 (아래 'Emotion_List에서 찾아서 한 단어로 표현)",
316
  "target_emotion": "행동을 받은 후 대상자가 느낄 감정 (아래 'Emotion_List에서 찾아서 한 단어로 표현)"
317
  }}
318
 
 
328
  "outcome_summary": "행동의 결과를 평가하는 데 실패했습니다.",
329
  "initiator_emotion": "confusion",
330
  "target_emotion": "neutral"
331
+ }
332
+
333
+ def evaluate_goal_achievement(initiator_name: str, goal: str, conversation_transcript: str) -> dict:
334
+ """대화의 목표와 전체 내용을 바탕으로, 목표 달성 여부를 평가"""
335
+ prompt = f"""
336
+ # Context
337
+ - 대화 시작자: "{initiator_name}"
338
+ - 대화 시작자의 목표 (대화 주제): "{goal}"
339
+ - 실제 대화 내용:
340
+ {conversation_transcript}
341
+
342
+ # Your Task
343
+ 위 정보를 바탕으로, 대화 시작자("{initiator_name}")가 자신의 원래 목표를 성공적으로 달성했는지 평가해주세요.
344
+ 결과는 반드시 아래 JSON 형식이어야 합니다.
345
+
346
+ # Evaluation (JSON format only)
347
+ {{
348
+ "goal_achieved": True,
349
+ "reason": "목표 달성 또는 실패에 대한 간결한 이유 (예: '상대방을 위로하고 지지하며 긍정적인 반응을 이끌어냈다.)",
350
+ "initiator_emotion": "이 결과를 얻은 후 대화 시작자가 느낄 감정 (아래 'Emotion_List에서 찾아서 한 단어로 표현)
351
+ }}
352
+
353
+ # Emotion_List
354
+ {EMOTION_LIST}
355
+ """
356
+ result = _query_llm_for_json_robustly(prompt)
357
+
358
+ if isinstance(result, dict) and "goal_achieved" in result:
359
+ return result
360
+ return {
361
+ # 최종 실패 시 안전한 기본값 반환
362
+ "goal_achieved": False,
363
+ "reason": "목표 달성 여부 평가에 실패했습니다.",
364
+ "initiator_emotion": "confusion"
365
+ }