rorshi commited on
Commit
069b24e
·
1 Parent(s): 96692cf

오류: LLM 연결 테스트

Browse files
npc_social_network/models/llm_helper.py ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # npc_social_network/models/llm_helper.py
2
+
3
+ from npc_social_network.npc.emotion_config import EMOTION_LIST
4
+
5
+ # 임시 LLM 호출 함수 예시 (Gemini / GPT 연결 가능)
6
+ def query_llm_for_response(npc_name, npc_job, user_input):
7
+ """
8
+ LLM을 통해 NPC 응답 생성
9
+ """
10
+
11
+ # 실제 구현시 Gemini API 호출 코드 사용 가능
12
+ prompt = f"""
13
+ NPC 이름: {npc_name}
14
+ NPC 직업: {npc_job}
15
+ 플레이어가 다음과 같이 말했습니다. "{user_input}"
16
+
17
+ 이에 대해 자연스럽고 친근한 한국어로 응답을 작성하세요.
18
+ """
19
+ # 예시 응답 (추후 LLM 연결 시 교체)
20
+ return f"{npc_name}이(가) 대답했습니다: '네, 정말 흥미롭네요!'"
21
+
22
+ def query_llm_for_emotion(user_input):
23
+ """
24
+ LLM을 통해 플레이어 입력에서 감정 추출
25
+ """
26
+ prompt = f"""
27
+ 플레이어 입력: "{user_input}"
28
+
29
+ 아래 감정 리스트 중 가장 잘 해당되는 감정을 한 개만 골라 반환하세요.
30
+ 감정 리스트: {', '.join(EMOTION_LIST)}
31
+
32
+ 반드시 감정 이름을 한 개만 출력하세요. (예: joy)
33
+ """
34
+ # 예시 결과 (추후 LLM 연결 시 교체)
35
+ return "joy"
npc_social_network/npc/emotion_config.py CHANGED
@@ -135,4 +135,17 @@ PERSONALITY_TEMPLATE = {
135
  "complex_bias": 1.0, # Complex emotion 영향
136
  "sensitive": 1.0, # 전체 감정 반응 강도
137
  "stoic": 0.0 # 전체 감정 둔화 정도 (감쇠 가속도에 영향)
138
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
135
  "complex_bias": 1.0, # Complex emotion 영향
136
  "sensitive": 1.0, # 전체 감정 반응 강도
137
  "stoic": 0.0 # 전체 감정 둔화 정도 (감쇠 가속도에 영향)
138
+ }
139
+
140
+ # 관계에 긍/부정 영향으로 해석할 감정 매핑 정의 (논문 설계 기반 적용)
141
+ POSITIVE_RELATION_EMOTIONS = [
142
+ "joy", "surprise", "gratitude", "pride", "love",
143
+ "admiration", "empathy", "comfort", "hope", "anticipatory_joy",
144
+ "calm", "engagement", "relief", "interest",
145
+ ]
146
+
147
+ NEGATIVE_RELATION_EMOTIONS = [
148
+ "sadness", "anger", "fear", "disgust", "shame",
149
+ "guilt", "jealousy", "resentment", "regret", "schadenfreude",
150
+ "anxiety", "confusion", "skepticism", "boredom",
151
+ ]
npc_social_network/npc/npc_base.py CHANGED
@@ -2,22 +2,9 @@
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
6
  from .npc_relationship import RelationshipManager
7
- import random
8
-
9
- # 관계에 긍/부정 영향으로 해석할 감정 매핑 정의 (논문 설계 기반 적용)
10
- POSITIVE_RELATION_EMOTIONS = [
11
- "joy", "surprise", "gratitude", "pride", "love",
12
- "admiration", "empathy", "comfort", "hope", "anticipatory_joy",
13
- "calm", "engagement", "relief", "interest",
14
- ]
15
-
16
- NEGATIVE_RELATION_EMOTIONS = [
17
- "sadness", "anger", "fear", "disgust", "shame",
18
- "guilt", "jealousy", "resentment", "regret", "schadenfreude",
19
- "anxiety", "confusion", "skepticism", "boredom",
20
- ]
21
 
22
  # NPC 클래스 정의
23
  class NPC:
@@ -249,4 +236,31 @@ class NPC:
249
  """
250
  현재 NPC 감정 상태 상위 N개 반환
251
  """
252
- return self.emotion.get_top_emotions(top_n=top_n)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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, POSITIVE_RELATION_EMOTIONS, NEGATIVE_RELATION_EMOTIONS
6
  from .npc_relationship import RelationshipManager
7
+ from ..models.llm_helper import query_llm_for_emotion, query_llm_for_response
 
 
 
 
 
 
 
 
 
 
 
 
 
8
 
9
  # NPC 클래스 정의
10
  class NPC:
 
236
  """
237
  현재 NPC 감정 상태 상위 N개 반환
238
  """
239
+ return self.emotion.get_top_emotions(top_n=top_n)
240
+
241
+ def interact_with_player(self, user_input:str, player_name:str="플레이어"):
242
+ """
243
+ 플레이어 입력에 반응 (LLM 기반 응답 생성 + Memory/Emotion/관계 반영)
244
+ """
245
+ # 1. LLM 응답 생성
246
+ npc_reply = query_llm_for_response(self.name, self.job, user_input)
247
+
248
+ # 2. LLM 감정 추출
249
+ dominant_emotion = query_llm_for_emotion(user_input)
250
+
251
+ # 3. Memory 기록
252
+ self.remember(
253
+ content = f"[플레이어:{player_name}] '{user_input}' → [NPC:{self.name}] '{npc_reply}'",
254
+ importance = 7, # 플레이어 상호작용은 높은 중요도로 저장(나중에 내용에 따라 변경하도록 수정)
255
+ emotion = dominant_emotion
256
+ )
257
+
258
+ # 4. Emotion 반영
259
+ if dominant_emotion:
260
+ self.update_emotion(dominant_emotion, strength=2.0)
261
+
262
+ # 5. 관계 반영 (상호작용 기반 - 지금 상태면 긍정적인 관계만 반영되는거 아닌가?)
263
+ positive = dominant_emotion in POSITIVE_RELATION_EMOTIONS
264
+ self.interact_with(player_name, dominant_emotion, positive)
265
+
266
+ return npc_reply, dominant_emotion
npc_social_network/routes/npc_route.py CHANGED
@@ -1,8 +1,6 @@
1
  # portfolio/npc_social_network/routes/npc_route.py
2
  from flask import Blueprint, render_template, request, jsonify
3
  from npc_social_network.models.npc_manager import npc_list
4
- from npc_social_network.models.deepseek_setup import load_deepseek
5
- from npc_social_network.models.openkollm_setup import load_openkollm
6
  from npc_social_network.models.gemini_setup import load_gemini
7
 
8
  npc_bp = Blueprint(
@@ -22,45 +20,59 @@ def home():
22
  @npc_bp.route("/chat", methods=['POST'])
23
  def chat():
24
  user_input = request.json.get("message")
25
- npc_name = request.json.get('npc')
26
  npc = npc_list[npc_name]
27
 
28
- # 최근 기억과 성격, 관계 점수를 포함한 프롬프트 생성
29
- recent_memory = npc.get_latest_memory()
30
- memory_str = '\n'.join(
31
- [f"User: {m['user']}\n{npc_name}: {m['npc']}" for m in recent_memory]
32
- )
33
-
34
- # 프롬프트 구성
35
- prompt = f"""
36
- 당신은 이름이 {npc.name}이고, 성격은 "{npc.personality}"인 가상의 캐릭터입니다.
37
-
38
- 다음은 유저와 나눈 최근 대화입니다:
39
- {memory_str if memory_str else "(대화 기록 없음)"}
40
-
41
- 지금 유저가 이렇게 말했습니다: "{user_input}"
42
- 말에 대해 당신은 {npc.name}으로서 자연스럽게 한국어로 답변하세요.
43
- """
44
-
45
- try:
46
- response = llm.generate_content(prompt)
47
- npc_reply = response.text.strip()
48
- except Exception as e:
49
- npc_reply = f"[에러 발생: {str(e)}]"
50
-
51
- # NPC 기억에 대화 추가 및 관계 점수 업데이트
52
- npc.remember_conversation(user_input, npc_reply)
53
- npc.update_user_relationship(0.05) # 임시로 0.05 상승 (추후 감정 분석 등으로 조절)
54
-
55
- # 다른 NPC에게 유저에 대한 정보 전달
56
- for other_name, other_npc in npc_list.items():
57
- if other_name != npc.name:
58
- relation_score = npc.relationship_with_npcs.get(other_name, 0.0)
59
- if relation_score > 0.5:
60
- # 유저에 대한 인상이 전달됨
61
- other_npc.update_user_relationship(0.02 * relation_score)
62
-
63
- return jsonify({'response': npc_reply})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
 
65
  # npc 상태 정보 API
66
  @npc_bp.route('/npc_info', methods=['GET'])
 
1
  # portfolio/npc_social_network/routes/npc_route.py
2
  from flask import Blueprint, render_template, request, jsonify
3
  from npc_social_network.models.npc_manager import npc_list
 
 
4
  from npc_social_network.models.gemini_setup import load_gemini
5
 
6
  npc_bp = Blueprint(
 
20
  @npc_bp.route("/chat", methods=['POST'])
21
  def chat():
22
  user_input = request.json.get("message")
23
+ npc_name = request.json.get("npc")
24
  npc = npc_list[npc_name]
25
 
26
+ # 플레이어 상호 작용 진행
27
+ npc_reply, emotion = npc.interact_with_player(user_input, player_name = "플레이어")
28
+
29
+ return jsonify({
30
+ "npc_reply": npc_reply,
31
+ "dominant_emotion": emotion,
32
+ "memory_summary": npc.summarize_emotional_state(),
33
+ "relationship_with_player": npc.get_relationship_description("플레이어")
34
+ })
35
+
36
+ # user_input = request.json.get("message")
37
+ # npc_name = request.json.get('npc')
38
+ # npc = npc_list[npc_name]
39
+
40
+ # # 최근 기억과 성격, 관계 점수를 포함한 프롬프트 생성
41
+ # recent_memory = npc.get_latest_memory()
42
+ # memory_str = '\n'.join(
43
+ # [f"User: {m['user']}\n{npc_name}: {m['npc']}" for m in recent_memory]
44
+ # )
45
+
46
+ # # 프롬프트 구성
47
+ # prompt = f"""
48
+ # 당신은 이름이 {npc.name}이고, 성격은 "{npc.personality}"인 가상의 캐릭터입니다.
49
+
50
+ # 다음은 유저와 나눈 최근 대화입니다:
51
+ # {memory_str if memory_str else "(대화 기록 없음)"}
52
+
53
+ # 지금 유저가 이렇게 말했습니다: "{user_input}"
54
+ # 말에 대해 당신은 {npc.name}으로서 자연스럽게 한국어로 답변하세요.
55
+ # """
56
+
57
+ # try:
58
+ # response = llm.generate_content(prompt)
59
+ # npc_reply = response.text.strip()
60
+ # except Exception as e:
61
+ # npc_reply = f"[에러 발생: {str(e)}]"
62
+
63
+ # # NPC 기억에 대화 추가 및 관계 점수 업데이트
64
+ # npc.remember_conversation(user_input, npc_reply)
65
+ # npc.update_user_relationship(0.05) # 임시로 0.05 상승 (추후 감정 분석 등으로 조절)
66
+
67
+ # # 다른 NPC에게 유저에 대한 정보 전달
68
+ # for other_name, other_npc in npc_list.items():
69
+ # if other_name != npc.name:
70
+ # relation_score = npc.relationship_with_npcs.get(other_name, 0.0)
71
+ # if relation_score > 0.5:
72
+ # # 유저에 대한 인상이 전달됨
73
+ # other_npc.update_user_relationship(0.02 * relation_score)
74
+
75
+ # return jsonify({'response': npc_reply})
76
 
77
  # npc 상태 정보 API
78
  @npc_bp.route('/npc_info', methods=['GET'])
requirements.txt CHANGED
@@ -1,6 +1,5 @@
1
  accelerate==1.7.0
2
  annotated-types==0.7.0
3
- asttokens==3.0.0
4
  bitsandbytes==0.45.5
5
  blinker==1.9.0
6
  cachetools==5.5.2
@@ -8,82 +7,51 @@ certifi==2025.4.26
8
  charset-normalizer==3.4.2
9
  click==8.2.0
10
  colorama==0.4.6
11
- comm==0.2.2
12
- debugpy==1.8.13
13
- decorator==5.2.1
14
- exceptiongroup==1.3.0
15
- executing==2.2.0
16
  filelock==3.18.0
17
  Flask==3.1.1
18
  fsspec==2025.5.0
19
  google-ai-generativelanguage==0.6.15
20
- google-api-core==2.25.0rc1
21
- google-api-python-client==2.170.0
22
- google-auth==2.40.2
23
  google-auth-httplib2==0.2.0
24
  google-generativeai==0.8.5
25
  googleapis-common-protos==1.70.0
26
- grpcio==1.71.0
27
  grpcio-status==1.71.0
28
  httplib2==0.22.0
29
  huggingface-hub==0.32.0
30
  idna==3.10
31
- importlib_metadata==8.7.0
32
- ipykernel==6.29.5
33
- ipython==9.1.0
34
- ipython_pygments_lexers==1.1.1
35
  itsdangerous==2.2.0
36
- jedi==0.19.2
37
  Jinja2==3.1.6
38
- jupyter_client==8.6.3
39
- jupyter_core==5.7.2
40
  MarkupSafe==3.0.2
41
- matplotlib-inline==0.1.7
42
  mpmath==1.3.0
43
- nest-asyncio==1.6.0
44
  networkx==3.4.2
45
  numpy==2.2.6
46
- packaging==24.2
47
- parso==0.8.4
48
- pickleshare==0.7.5
49
  pillow==11.0.0
50
- platformdirs==4.3.7
51
- prompt_toolkit==3.0.50
52
  proto-plus==1.26.1
53
- protobuf==5.29.4
54
- psutil==7.0.0
55
- pure_eval==0.2.3
56
  pyasn1==0.6.1
57
  pyasn1_modules==0.4.2
58
  pydantic==2.11.5
59
  pydantic_core==2.33.2
60
  pygame==2.6.1
61
- Pygments==2.19.1
62
  pyparsing==3.2.3
63
- python-dateutil==2.9.0.post0
64
  python-dotenv==1.1.0
65
  pywin32==304
66
  PyYAML==6.0.2
67
- pyzmq==26.4.0
68
  regex==2024.11.6
69
  requests==2.32.3
70
  rsa==4.9.1
71
  safetensors==0.5.3
72
- six==1.17.0
73
- stack-data==0.6.3
74
  sympy==1.14.0
75
  tokenizers==0.21.1
76
  torch==2.7.0+cu118
77
  torchaudio==2.7.0+cu118
78
  torchvision==0.22.0+cu118
79
- tornado==6.4.2
80
  tqdm==4.67.1
81
- traitlets==5.14.3
82
  transformers==4.52.3
83
  typing-inspection==0.4.1
84
- typing_extensions==4.13.1
85
- uritemplate==4.1.1
86
  urllib3==2.4.0
87
- wcwidth==0.2.13
88
  Werkzeug==3.1.3
89
- zipp==3.21.0
 
1
  accelerate==1.7.0
2
  annotated-types==0.7.0
 
3
  bitsandbytes==0.45.5
4
  blinker==1.9.0
5
  cachetools==5.5.2
 
7
  charset-normalizer==3.4.2
8
  click==8.2.0
9
  colorama==0.4.6
 
 
 
 
 
10
  filelock==3.18.0
11
  Flask==3.1.1
12
  fsspec==2025.5.0
13
  google-ai-generativelanguage==0.6.15
14
+ google-api-core==2.25.0
15
+ google-api-python-client==2.171.0
16
+ google-auth==2.40.3
17
  google-auth-httplib2==0.2.0
18
  google-generativeai==0.8.5
19
  googleapis-common-protos==1.70.0
20
+ grpcio==1.73.0
21
  grpcio-status==1.71.0
22
  httplib2==0.22.0
23
  huggingface-hub==0.32.0
24
  idna==3.10
 
 
 
 
25
  itsdangerous==2.2.0
 
26
  Jinja2==3.1.6
 
 
27
  MarkupSafe==3.0.2
 
28
  mpmath==1.3.0
 
29
  networkx==3.4.2
30
  numpy==2.2.6
 
 
 
31
  pillow==11.0.0
 
 
32
  proto-plus==1.26.1
33
+ protobuf==5.29.5
 
 
34
  pyasn1==0.6.1
35
  pyasn1_modules==0.4.2
36
  pydantic==2.11.5
37
  pydantic_core==2.33.2
38
  pygame==2.6.1
 
39
  pyparsing==3.2.3
 
40
  python-dotenv==1.1.0
41
  pywin32==304
42
  PyYAML==6.0.2
 
43
  regex==2024.11.6
44
  requests==2.32.3
45
  rsa==4.9.1
46
  safetensors==0.5.3
 
 
47
  sympy==1.14.0
48
  tokenizers==0.21.1
49
  torch==2.7.0+cu118
50
  torchaudio==2.7.0+cu118
51
  torchvision==0.22.0+cu118
 
52
  tqdm==4.67.1
 
53
  transformers==4.52.3
54
  typing-inspection==0.4.1
55
+ uritemplate==4.2.0
 
56
  urllib3==2.4.0
 
57
  Werkzeug==3.1.3