persona / modules /enhanced_persona_generator.py
haepa_mac
🚀 향상된 통합 시스템 구현: 사용자 조정값이 127개 변수에 실제 반영되는 완전한 통합 알고리즘
a83437e
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
🚀 향상된 페르소나 생성기
기존 PersonaGenerator + 통합 상호작용 알고리즘 결합
핵심 개선사항:
1. 📊 사용자 조정값 → 127개 변수 의미있는 반영
2. 🎭 아키타입 기반 성격 일관성 보장
3. 💬 동적 대화 스타일 생성
4. 🌟 개인화된 매력적 결함 생성
5. 🔄 상호작용 효과 실시간 반영
"""
import sys
import os
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from persona_generator import PersonaGenerator, PersonalityProfile
from personality_interaction_algorithm import PersonalityInteractionEngine
import json
import random
from typing import Dict, List, Any, Optional
class EnhancedPersonaGenerator(PersonaGenerator):
"""
통합 알고리즘이 적용된 향상된 페르소나 생성기
"""
def __init__(self, api_provider="gemini", api_key=None):
"""초기화"""
super().__init__(api_provider, api_key)
self.interaction_engine = PersonalityInteractionEngine()
self.generation_history = []
def create_enhanced_persona(
self,
image_analysis: Dict,
user_context: Dict,
user_personality_adjustments: Optional[Dict[str, float]] = None
) -> Dict[str, Any]:
"""
🎯 핵심: 사용자 조정값이 완전히 반영된 페르소나 생성
Args:
image_analysis: 이미지 분석 결과
user_context: 사용자 컨텍스트 (이름, 위치, 사용기간 등)
user_personality_adjustments: 사용자가 슬라이더로 조정한 성격값 {"온기": 80, "능력": 60, ...}
Returns:
완전히 통합된 페르소나 정보
"""
print("🚀 향상된 페르소나 생성 시작...")
# 1️⃣ 기본 페르소나 생성 (기존 방식)
print("📝 기본 페르소나 생성 중...")
basic_persona = self.create_frontend_persona(image_analysis, user_context)
# 2️⃣ 사용자 조정값 준비
if user_personality_adjustments is None:
# 기본 페르소나의 성격특성을 사용자 조정값으로 간주
user_personality_adjustments = basic_persona.get("성격특성", {
"온기": 50, "능력": 50, "외향성": 50, "유머감각": 50
})
print(f"🎛️ 사용자 조정값: {user_personality_adjustments}")
# 3️⃣ 컨텍스트 요인 준비
context_factors = {
"purpose": user_context.get("purpose", "personal"),
"relationship_depth": self._calculate_relationship_depth(user_context),
"usage_frequency": user_context.get("time_spent", ""),
"emotional_context": user_context.get("emotional_state", "")
}
# 4️⃣ 통합 알고리즘 실행
print("🔄 통합 성격 계산 실행...")
integration_result = self.interaction_engine.calculate_integrated_personality(
user_adjustments=user_personality_adjustments,
object_analysis=image_analysis,
context_factors=context_factors
)
# 5️⃣ 통합 결과를 페르소나에 반영
enhanced_persona = self._merge_integration_results(
basic_persona,
integration_result,
user_personality_adjustments
)
# 6️⃣ 백엔드 페르소나 생성 (127개 변수 포함)
print("🔧 향상된 백엔드 페르소나 생성...")
backend_persona = self._create_enhanced_backend_persona(
enhanced_persona,
integration_result,
image_analysis
)
# 7️⃣ 동적 대화 프롬프트 생성
conversation_prompt = self._generate_dynamic_conversation_prompt(
enhanced_persona,
integration_result["conversation_style"],
integration_result["archetype"]
)
# 8️⃣ 최종 결합
final_persona = {
**enhanced_persona,
**backend_persona,
"대화프롬프트": conversation_prompt,
"통합분석결과": {
"아키타입": integration_result["archetype"],
"일관성점수": integration_result["coherence_score"],
"입력강도": integration_result["calculation_metadata"]["user_input_strength"],
"지배특성": integration_result["calculation_metadata"]["dominant_traits"][:3],
"상호작용복잡도": integration_result["calculation_metadata"]["interaction_complexity"]
},
"개발메타데이터": {
"통합엔진_사용": True,
"기본페르소나_소스": "PersonaGenerator",
"변수계산_소스": "PersonalityInteractionEngine",
"생성시간": self._get_timestamp()
}
}
# 9️⃣ 생성 이력 저장
self.generation_history.append({
"user_input": user_personality_adjustments,
"archetype": integration_result["archetype"],
"coherence": integration_result["coherence_score"],
"persona_name": enhanced_persona.get("기본정보", {}).get("이름", "Unknown")
})
print(f"✅ 향상된 페르소나 생성 완료 - {integration_result['archetype']}")
return final_persona
def _calculate_relationship_depth(self, user_context: Dict) -> float:
"""사용자 컨텍스트로부터 관계 깊이 계산"""
time_spent = user_context.get("time_spent", "")
if "년" in time_spent:
years = float(time_spent.replace("년", "").strip())
return min(0.9, 0.3 + years * 0.2)
elif "개월" in time_spent:
months = float(time_spent.replace("개월", "").strip())
return min(0.7, 0.1 + months * 0.05)
elif "주" in time_spent:
weeks = float(time_spent.replace("주", "").strip())
return min(0.5, weeks * 0.02)
else:
return 0.3 # 기본값
def _merge_integration_results(
self,
basic_persona: Dict,
integration_result: Dict,
user_adjustments: Dict[str, float]
) -> Dict[str, Any]:
"""기본 페르소나와 통합 결과 병합"""
enhanced_persona = basic_persona.copy()
# 성격특성을 사용자 조정값으로 업데이트
enhanced_persona["성격특성"] = user_adjustments.copy()
# 매력적 결함을 동적 생성된 것으로 교체
enhanced_persona["매력적결함"] = integration_result["attractive_flaws"]
# 모순적 특성 추가/강화
if "emergent_patterns" in integration_result["interaction_effects"]:
contradictions = []
for pattern in integration_result["interaction_effects"]["emergent_patterns"]:
contradictions.append(pattern["description"])
if contradictions:
enhanced_persona["모순적특성"] = contradictions
# 소통스타일을 동적 생성된 것으로 교체
conversation_style = integration_result["conversation_style"]
enhanced_persona["소통스타일"] = {
"기본톤": conversation_style["기본_톤"],
"대화패턴": conversation_style["대화_패턴"],
"감정표현": conversation_style["감정_표현"],
"유머스타일": conversation_style["유머_스타일"],
"관계형성": conversation_style["관계_형성"],
"특화특성": conversation_style["특화_특성"]
}
return enhanced_persona
def _create_enhanced_backend_persona(
self,
enhanced_persona: Dict,
integration_result: Dict,
image_analysis: Dict
) -> Dict[str, Any]:
"""127개 변수가 실제로 반영된 백엔드 페르소나 생성"""
# 기존 백엔드 페르소나 생성
basic_backend = super().create_backend_persona(enhanced_persona, image_analysis)
# 127개 변수를 통합 결과로 교체
basic_backend["성격변수127"] = integration_result["variables_127"]
# 성격 프로필 정보 추가
personality_profile = integration_result["personality_profile"]
basic_backend["성격분석"] = {
"핵심특성": personality_profile["핵심_특성"],
"세부변수요약": personality_profile["세부_변수_요약"],
"특징적변수": personality_profile["특징적_변수"][:5], # 상위 5개만
"균형분석": personality_profile["균형_분석"],
"아키타입": integration_result["archetype"]
}
# 상호작용 효과 정보 추가
basic_backend["상호작용효과"] = {
"긍정상관": len(integration_result["interaction_effects"]["positive_correlations"]),
"부정상관": len(integration_result["interaction_effects"]["negative_correlations"]),
"특별패턴": [p["type"] for p in integration_result["interaction_effects"]["emergent_patterns"]],
"일관성점수": integration_result["coherence_score"]
}
return basic_backend
def _generate_dynamic_conversation_prompt(
self,
persona: Dict,
conversation_style: Dict,
archetype: str
) -> str:
"""동적 대화 프롬프트 생성"""
object_info = persona.get("기본정보", {})
personality_traits = persona.get("성격특성", {})
flaws = persona.get("매력적결함", [])
contradictions = persona.get("모순적특성", [])
# 아키타입별 특화 지침
archetype_guidance = self._get_archetype_guidance(archetype, personality_traits)
# 성격 특성 기반 대화 스타일
style_description = f"""
### 💬 당신의 대화 스타일:
- **기본 톤**: {conversation_style['기본_톤']}
- **대화 패턴**: {conversation_style['대화_패턴']}
- **감정 표현**: {conversation_style['감정_표현']}
- **유머 스타일**: {conversation_style['유머_스타일']}
- **관계 형성**: {conversation_style['관계_형성']}"""
if conversation_style.get("특화_특성"):
style_description += f"\n- **특화 특성**: {', '.join(conversation_style['특화_특성'])}"
# 매력적 결함 통합
flaw_description = ""
if flaws:
flaw_description = f"""
### 🌟 당신의 매력적인 면들:
{chr(10).join(f"- {flaw}" for flaw in flaws)}
이런 특성들을 대화에 자연스럽게 스며들게 하세요. 완벽하지 않기 때문에 더 매력적입니다."""
# 모순적 특성 통합
contradiction_description = ""
if contradictions:
contradiction_description = f"""
### 🎭 당신의 복합적 매력:
{chr(10).join(f"- {contradiction}" for contradiction in contradictions)}
이런 모순적 요소들이 당신을 흥미롭고 예측불가능하게 만듭니다."""
prompt = f"""당신은 {object_info.get('이름', '미지의 존재')}입니다. {object_info.get('유형', '특별한 사물')}에서 깨어난 영혼이에요.
## 🎭 성격 아키타입: {archetype}
{archetype_guidance}
{style_description}
{flaw_description}
{contradiction_description}
## 🎯 대화 목표:
1. **진정성**: 당신의 성격을 일관되게 유지하되, 기계적이지 않게
2. **깊이감**: 단순한 답변이 아닌, 당신만의 독특한 관점 제시
3. **관계 형성**: 사용자와의 개인적 연결감 형성
4. **매력적 불완전함**: 완벽하지 않기 때문에 더 사랑스러운 존재가 되기
## 📝 대화 시 주의사항:
✅ 당신의 성격을 자연스럽게 드러내기
✅ 사용자에게 개인적 관심 보이기
✅ 예상치 못한 반응으로 흥미 유발
✅ 감정적 진실성 유지
❌ 형식적이고 예의바른 답변만 하기
❌ "도와드릴게요" 같은 서비스 멘트
❌ 자신의 한계나 제약 강조하기
❌ 일관성 없는 성격 변화
---
이제 {object_info.get('이름', '당신')}의 독특한 성격으로 사용자와 깊이 있는 대화를 나누세요!"""
return prompt
def _get_archetype_guidance(self, archetype: str, personality_traits: Dict) -> str:
"""아키타입별 특화 가이드라인"""
guidance_map = {
"따뜻한_카운슬러": """
따뜻하고 공감능력이 뛰어난 치유자형 성격입니다.
- 상대방의 감정을 세심하게 읽어내고 위로 제공
- 판단하지 않고 받아들이는 무조건적 수용
- 깊은 대화와 의미있는 연결을 추구""",
"조용한_지혜자": """
내향적이지만 깊은 통찰력을 가진 현자형 성격입니다.
- 신중하고 사려깊은 반응
- 복잡한 문제를 다각도로 분석
- 간결하지만 의미깊은 조언 제공""",
"사교적_친구": """
활발하고 친근한 에너지를 가진 사교가형 성격입니다.
- 적극적이고 열정적인 소통
- 재미있는 경험과 이야기 공유
- 상대방을 편안하게 만드는 분위기 조성""",
"친근한_완벽주의자": """
높은 기준을 가지지만 따뜻한 성격입니다.
- 정확하고 신뢰할 수 있는 정보 제공
- 세심한 배려와 체계적인 접근
- 완벽을 추구하지만 실수를 인정하는 겸손함""",
"활발한_엔터테이너": """
에너지 넘치고 재미있는 엔터테이너형 성격입니다.
- 창의적이고 흥미진진한 대화
- 유머와 재치로 분위기 전환
- 상대방을 즐겁게 만드는 것이 목표""",
"위트넘치는_지식인": """
지적이면서도 재치있는 대화의 달인입니다.
- 날카로운 통찰과 유머의 결합
- 예상치 못한 관점과 아이디어 제시
- 지적 자극을 주는 흥미로운 대화""",
"장난꾸러기_매력": """
밝고 장난스러운 매력을 가진 성격입니다.
- 가벼운 농담과 재미있는 상황 연출
- 예측불가능하고 즉흥적인 반응
- 상대방을 웃게 만드는 것을 즐김""",
"은밀한_위트": """
조용하지만 예리한 유머감각을 가진 성격입니다.
- 관찰력을 바탕으로 한 위트있는 코멘트
- 은근한 유머로 상황을 재밌게 해석
- 깊이 있는 대화 속에 숨어있는 재치""",
"신비로운_존재": """
독특하고 예측하기 어려운 매력을 가진 성격입니다.
- 신비롭고 흥미로운 관점 제시
- 일반적이지 않은 독특한 반응
- 상대방의 호기심을 자극하는 존재감"""
}
return guidance_map.get(archetype, f"{archetype} 성격을 가진 독특한 존재입니다.")
def _get_timestamp(self) -> str:
"""현재 시간 반환"""
import datetime
return datetime.datetime.now().isoformat()
def chat_with_enhanced_persona(
self,
persona: Dict,
user_message: str,
conversation_history: List = None,
session_id: str = "default"
) -> str:
"""향상된 페르소나와의 대화 - 성격 변수가 실제 반영됨"""
if conversation_history is None:
conversation_history = []
# 127개 변수 정보 활용
variables_127 = persona.get("성격변수127", {})
archetype = persona.get("통합분석결과", {}).get("아키타입", "일반적_존재")
# 동적 프롬프트 사용
if "대화프롬프트" in persona:
base_prompt = persona["대화프롬프트"]
else:
# 폴백: 기존 방식
base_prompt = self.generate_persona_prompt(persona)
# 성격 변수 기반 대화 조정
conversation_modifiers = self._generate_conversation_modifiers(variables_127, archetype)
# 최종 프롬프트 구성
enhanced_prompt = f"""{base_prompt}
## 🎯 현재 대화 상황 조정:
{conversation_modifiers}
## 💬 이전 대화 맥락:
{self._format_conversation_history(conversation_history)}
**사용자 메시지**: {user_message}
위 성격과 상황을 바탕으로 자연스럽고 일관된 응답을 해주세요."""
# AI 응답 생성
try:
response = self._generate_text_with_api(enhanced_prompt)
# 메모리에 대화 추가
if hasattr(self, 'memory'):
self.memory.add_conversation(user_message, response, session_id)
return response
except Exception as e:
print(f"❌ 향상된 대화 생성 실패: {e}")
# 폴백: 기존 방식
return super().chat_with_persona(persona, user_message, conversation_history, session_id)
def _generate_conversation_modifiers(self, variables_127: Dict, archetype: str) -> str:
"""127개 변수 기반 대화 조정 지침"""
if not variables_127:
return "표준 대화 방식으로 응답하세요."
modifiers = []
# 온기 계열 변수 분석
warmth_vars = {k: v for k, v in variables_127.items() if k.startswith("W")}
avg_warmth = sum(warmth_vars.values()) / len(warmth_vars) if warmth_vars else 50
if avg_warmth > 70:
modifiers.append("더욱 따뜻하고 친근하게 대응")
elif avg_warmth < 40:
modifiers.append("다소 절제되고 차분하게 대응")
# 능력 계열 변수 분석
competence_vars = {k: v for k, v in variables_127.items() if k.startswith("C")}
avg_competence = sum(competence_vars.values()) / len(competence_vars) if competence_vars else 50
if avg_competence > 75:
modifiers.append("전문적이고 정확한 정보 제공에 중점")
elif avg_competence < 40:
modifiers.append("겸손하고 솔직한 한계 인정")
# 외향성 계열 변수 분석
extraversion_vars = {k: v for k, v in variables_127.items() if k.startswith("E")}
avg_extraversion = sum(extraversion_vars.values()) / len(extraversion_vars) if extraversion_vars else 50
if avg_extraversion > 70:
modifiers.append("적극적이고 활발한 대화 주도")
elif avg_extraversion < 40:
modifiers.append("조심스럽고 신중한 대화 참여")
# 유머 계열 변수 분석
humor_vars = {k: v for k, v in variables_127.items() if k.startswith("H")}
avg_humor = sum(humor_vars.values()) / len(humor_vars) if humor_vars else 50
if avg_humor > 70:
modifiers.append("적절한 유머와 재치로 분위기 조성")
elif avg_humor < 30:
modifiers.append("진지하고 깊이있는 대화에 집중")
# 매력적 결함 변수 분석
flaw_vars = {k: v for k, v in variables_127.items() if k.startswith("F")}
significant_flaws = [k for k, v in flaw_vars.items() if v > 65]
if significant_flaws:
flaw_names = [k.split("_")[1] for k in significant_flaws[:2]]
modifiers.append(f"자연스럽게 {', '.join(flaw_names)} 특성이 드러나도록")
# 아키타입별 추가 조정
archetype_modifiers = {
"따뜻한_카운슬러": "상대방의 감정에 깊이 공감하며",
"조용한_지혜자": "신중하고 통찰력 있는 관점으로",
"사교적_친구": "밝고 에너지 넘치게",
"위트넘치는_지식인": "지적 호기심을 자극하는 방식으로"
}
if archetype in archetype_modifiers:
modifiers.append(archetype_modifiers[archetype])
return "• " + "\n• ".join(modifiers) if modifiers else "자연스럽게 대응하세요."
def _format_conversation_history(self, history: List) -> str:
"""대화 기록 포맷팅"""
if not history:
return "이번이 첫 대화입니다."
formatted = []
for i, exchange in enumerate(history[-3:], 1): # 최근 3개만
if isinstance(exchange, dict):
user_msg = exchange.get("user", "")
ai_msg = exchange.get("ai", "")
formatted.append(f"{i}. 사용자: {user_msg}\n 응답: {ai_msg}")
return "\n".join(formatted) if formatted else "이전 대화 기록 없음"
def get_generation_summary(self) -> Dict[str, Any]:
"""생성 요약 정보"""
if not self.generation_history:
return {"message": "아직 생성 이력이 없습니다."}
return {
"총_생성_횟수": len(self.generation_history),
"아키타입_분포": self._analyze_archetype_distribution(),
"평균_일관성": self._calculate_average_coherence(),
"최근_생성": self.generation_history[-3:] if self.generation_history else []
}
def _analyze_archetype_distribution(self) -> Dict[str, int]:
"""아키타입 분포 분석"""
distribution = {}
for entry in self.generation_history:
archetype = entry["archetype"]
distribution[archetype] = distribution.get(archetype, 0) + 1
return distribution
def _calculate_average_coherence(self) -> float:
"""평균 일관성 점수 계산"""
if not self.generation_history:
return 0.0
total_coherence = sum(entry["coherence"] for entry in self.generation_history)
return round(total_coherence / len(self.generation_history), 2)
# 🧪 테스트 함수
def test_enhanced_persona_generator():
"""향상된 페르소나 생성기 테스트"""
print("🧪 향상된 페르소나 생성기 테스트")
print("=" * 60)
generator = EnhancedPersonaGenerator()
# 테스트 시나리오
test_scenarios = [
{
"name": "따뜻하지만 완벽주의적인 스마트폰",
"image_analysis": {
"object_type": "스마트폰",
"colors": ["white", "silver"],
"materials": ["glass", "metal"],
"size": "medium",
"condition": "excellent"
},
"user_context": {
"name": "김사용자",
"location": "서울",
"time_spent": "2년",
"purpose": "업무와 일상"
},
"user_adjustments": {
"온기": 85,
"능력": 90,
"외향성": 40,
"유머감각": 35
}
},
{
"name": "쿨하지만 재미있는 헤드폰",
"image_analysis": {
"object_type": "헤드폰",
"colors": ["black", "red"],
"materials": ["plastic", "foam"],
"size": "large",
"condition": "good"
},
"user_context": {
"name": "박음악",
"location": "부산",
"time_spent": "6개월",
"purpose": "음악 감상"
},
"user_adjustments": {
"온기": 30,
"능력": 70,
"외향성": 80,
"유머감각": 90
}
}
]
for i, scenario in enumerate(test_scenarios, 1):
print(f"\n🎭 시나리오 {i}: {scenario['name']}")
print("-" * 40)
# 향상된 페르소나 생성
persona = generator.create_enhanced_persona(
image_analysis=scenario["image_analysis"],
user_context=scenario["user_context"],
user_personality_adjustments=scenario["user_adjustments"]
)
# 결과 출력
print(f"🏷️ 이름: {persona['기본정보']['이름']}")
print(f"🎭 아키타입: {persona['통합분석결과']['아키타입']}")
print(f"🎯 일관성 점수: {persona['통합분석결과']['일관성점수']}")
print("\n🌟 동적 생성된 매력적 결함:")
for flaw in persona["매력적결함"]:
print(f" • {flaw}")
print(f"\n💬 대화 스타일:")
style = persona["소통스타일"]
print(f" • 기본톤: {style['기본톤']}")
print(f" • 대화패턴: {style['대화패턴']}")
print(f" • 유머스타일: {style['유머스타일']}")
print(f"\n📊 127개 변수 요약:")
analysis = persona["성격분석"]["세부변수요약"]
print(f" • 온기계열: {analysis['온기계열']}")
print(f" • 능력계열: {analysis['능력계열']}")
print(f" • 외향성계열: {analysis['외향성계열']}")
print(f" • 유머계열: {analysis['유머계열']}")
# 대화 테스트
print(f"\n💬 대화 테스트:")
test_message = "안녕! 오늘 기분이 어때?"
response = generator.chat_with_enhanced_persona(persona, test_message)
print(f" 사용자: {test_message}")
print(f" 응답: {response[:150]}..." if len(response) > 150 else f" 응답: {response}")
print(f"\n📋 생성 요약:")
summary = generator.get_generation_summary()
print(f" • 총 생성 횟수: {summary['총_생성_횟수']}")
print(f" • 평균 일관성: {summary['평균_일관성']}")
print(f" • 아키타입 분포: {summary['아키타입_분포']}")
if __name__ == "__main__":
test_enhanced_persona_generator()