Spaces:
Sleeping
Sleeping
File size: 13,305 Bytes
5581923 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 |
import os
import json
import time
from datetime import datetime
# 디렉터리 경로 설정
PERSONAS_DIR = "data/user_personas"
CONVERSATIONS_DIR = "data/conversation_logs"
def ensure_directories():
"""필요한 디렉터리가 존재하는지 확인하고, 없으면 생성합니다."""
for dir_path in [PERSONAS_DIR, CONVERSATIONS_DIR]:
try:
os.makedirs(dir_path, exist_ok=True)
except Exception as e:
print(f"디렉토리 생성 중 오류: {str(e)}")
# 허깅페이스 환경에서는 임시 디렉토리 사용
temp_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "temp_data")
os.makedirs(temp_dir, exist_ok=True)
return False
return True
def save_persona(persona_data):
"""
페르소나 데이터를 JSON 파일로 저장합니다.
Args:
persona_data: 저장할 페르소나 데이터
Returns:
저장된 파일 경로
"""
if not ensure_directories():
print("경고: 디렉토리 생성에 실패했습니다. 세션 데이터만 유지됩니다.")
persona_data["_temp_storage_warning"] = "임시 스토리지만 사용 가능합니다. 페르소나는 세션이 종료되면 사라집니다."
return "temp_persona"
# 파일명 생성 (이름_타임스탬프.json)
name = persona_data.get("기본정보", {}).get("이름", "unnamed").replace(" ", "_")
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"{name}_{timestamp}.json"
file_path = os.path.join(PERSONAS_DIR, filename)
try:
# JSON 파일로 저장
with open(file_path, "w", encoding="utf-8") as f:
json.dump(persona_data, f, ensure_ascii=False, indent=2)
return file_path
except Exception as e:
print(f"페르소나 저장 오류: {str(e)}")
persona_data["_storage_error"] = str(e)
return "failed_to_save"
def load_persona(file_path):
"""
JSON 파일에서 페르소나 데이터를 로드합니다.
Args:
file_path: 페르소나 파일 경로
Returns:
로드된 페르소나 데이터
"""
# 임시 저장 케이스 처리
if file_path == "temp_persona" or file_path == "failed_to_save":
return None
try:
with open(file_path, "r", encoding="utf-8") as f:
data = json.load(f)
return data
except Exception as e:
print(f"페르소나 로딩 오류: {str(e)}")
return None
def list_personas():
"""
저장된 모든 페르소나 목록을 가져옵니다.
Returns:
페르소나 목록 (테이블 형식)
"""
ensure_directories()
personas = []
# 디렉터리 내 모든 JSON 파일 확인
for filename in os.listdir(PERSONAS_DIR):
if filename.endswith(".json"):
file_path = os.path.join(PERSONAS_DIR, filename)
try:
with open(file_path, "r", encoding="utf-8") as f:
data = json.load(f)
# 필요한 정보 추출
name = data.get("기본정보", {}).get("이름", "무명")
object_type = data.get("기본정보", {}).get("유형", "")
created = data.get("기본정보", {}).get("생성일시", "")
personas.append([name, object_type, created, filename])
except Exception as e:
print(f"파일 읽기 오류 ({filename}): {str(e)}")
# 최신 순으로 정렬
personas.sort(key=lambda x: x[2], reverse=True)
return personas
def save_conversation(conversation_data):
"""
대화 데이터를 JSON 파일로 저장합니다.
Args:
conversation_data: 저장할 대화 데이터
Returns:
저장된 파일 경로
"""
if not ensure_directories():
print("경고: 디렉토리 생성에 실패했습니다. 대화 데이터를 저장할 수 없습니다.")
return "temp_conversation"
# 페르소나 정보 추출
persona = conversation_data.get("persona", {})
name = persona.get("기본정보", {}).get("이름", "unnamed").replace(" ", "_")
# 페르소나별 대화 저장 디렉터리
persona_conv_dir = os.path.join(CONVERSATIONS_DIR, name)
try:
os.makedirs(persona_conv_dir, exist_ok=True)
except Exception as e:
print(f"대화 저장 디렉토리 생성 오류: {str(e)}")
return "failed_to_save_conv"
# 파일명 생성 (타임스탬프.json)
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"conversation_{timestamp}.json"
file_path = os.path.join(persona_conv_dir, filename)
try:
# JSON 파일로 저장
with open(file_path, "w", encoding="utf-8") as f:
# 메시지 내용만 저장하여 파일 크기 최적화
simplified_data = {
"persona_name": name,
"persona_type": persona.get("기본정보", {}).get("유형", ""),
"start_time": conversation_data.get("start_time", ""),
"current_time": conversation_data.get("current_time", ""),
"duration_seconds": conversation_data.get("duration_seconds", 0),
"messages": [{
"role": msg["role"],
"content": msg["content"],
"timestamp": msg.get("timestamp", "")
} for msg in conversation_data.get("messages", [])]
}
json.dump(simplified_data, f, ensure_ascii=False, indent=2)
return file_path
except Exception as e:
print(f"대화 저장 오류: {str(e)}")
return "failed_to_save_conv"
def list_conversations(persona_name=None):
"""
저장된 대화 목록을 가져옵니다.
Args:
persona_name: 특정 페르소나의 대화만 필터링 (선택 사항)
Returns:
대화 목록 (테이블 형식)
"""
ensure_directories()
conversations = []
# 모든 페르소나 디렉터리 탐색
for persona_dir in os.listdir(CONVERSATIONS_DIR):
# 특정 페르소나만 필터링
if persona_name and persona_name != persona_dir:
continue
persona_path = os.path.join(CONVERSATIONS_DIR, persona_dir)
if os.path.isdir(persona_path):
# 디렉터리 내 모든 대화 파일 확인
for filename in os.listdir(persona_path):
if filename.endswith(".json"):
file_path = os.path.join(persona_path, filename)
try:
with open(file_path, "r", encoding="utf-8") as f:
data = json.load(f)
# 필요한 정보 추출
persona_name = data.get("persona_name", "무명")
start_time = data.get("start_time", "")
duration = data.get("duration_seconds", 0)
msg_count = len(data.get("messages", []))
conversations.append([
persona_name,
start_time,
f"{int(duration // 60)}분 {int(duration % 60)}초",
msg_count,
file_path
])
except Exception as e:
print(f"대화 파일 읽기 오류 ({file_path}): {str(e)}")
# 최신 순으로 정렬
conversations.sort(key=lambda x: x[1], reverse=True)
return conversations
def load_conversation(file_path):
"""
JSON 파일에서 대화 데이터를 로드합니다.
Args:
file_path: 대화 파일 경로
Returns:
로드된 대화 데이터
"""
try:
with open(file_path, "r", encoding="utf-8") as f:
data = json.load(f)
return data
except Exception as e:
print(f"대화 로딩 오류: {str(e)}")
return None
def analyze_persona_trait_distribution():
"""
저장된 모든 페르소나의 성격 특성 분포를 분석합니다.
Returns:
특성별 평균값, 최소값, 최대값, 중앙값을 포함한 분석 결과
"""
ensure_directories()
traits_data = {
"온기": [],
"능력": [],
"신뢰성": [],
"친화성": [],
"창의성": [],
"유머감각": []
}
# 모든 페르소나 파일에서 성격 특성 수집
for filename in os.listdir(PERSONAS_DIR):
if filename.endswith(".json"):
file_path = os.path.join(PERSONAS_DIR, filename)
try:
with open(file_path, "r", encoding="utf-8") as f:
data = json.load(f)
# 성격 특성 값 추출
for trait, values in traits_data.items():
trait_value = data.get("성격특성", {}).get(trait)
if trait_value is not None:
values.append(trait_value)
except Exception as e:
print(f"파일 분석 오류 ({filename}): {str(e)}")
# 분석 결과 계산
analysis = {}
for trait, values in traits_data.items():
if values:
analysis[trait] = {
"평균": sum(values) / len(values),
"최소": min(values),
"최대": max(values),
"중앙값": sorted(values)[len(values) // 2],
"페르소나 수": len(values)
}
else:
analysis[trait] = {
"평균": 0,
"최소": 0,
"최대": 0,
"중앙값": 0,
"페르소나 수": 0
}
return analysis
def get_conversation_statistics(persona_name=None):
"""
대화 데이터의 통계 정보를 분석합니다.
Args:
persona_name: 특정 페르소나의 대화만 필터링 (선택 사항)
Returns:
대화 통계 정보
"""
ensure_directories()
stats = {
"총_대화_수": 0,
"총_메시지_수": 0,
"평균_대화_시간": 0,
"평균_메시지_수": 0,
"페르소나별_대화": {}
}
total_duration = 0
# 모든 페르소나 디렉터리 탐색
for persona_dir in os.listdir(CONVERSATIONS_DIR):
# 특정 페르소나만 필터링
if persona_name and persona_name != persona_dir:
continue
persona_path = os.path.join(CONVERSATIONS_DIR, persona_dir)
if os.path.isdir(persona_path):
persona_stats = {
"대화_수": 0,
"메시지_수": 0,
"총_대화_시간": 0
}
# 디렉터리 내 모든 대화 파일 확인
for filename in os.listdir(persona_path):
if filename.endswith(".json"):
file_path = os.path.join(persona_path, filename)
try:
with open(file_path, "r", encoding="utf-8") as f:
data = json.load(f)
# 통계 누적
msg_count = len(data.get("messages", []))
duration = data.get("duration_seconds", 0)
stats["총_대화_수"] += 1
stats["총_메시지_수"] += msg_count
total_duration += duration
persona_stats["대화_수"] += 1
persona_stats["메시지_수"] += msg_count
persona_stats["총_대화_시간"] += duration
except Exception as e:
print(f"대화 파일 분석 오류 ({file_path}): {str(e)}")
# 페르소나별 평균 계산
if persona_stats["대화_수"] > 0:
persona_stats["평균_메시지_수"] = persona_stats["메시지_수"] / persona_stats["대화_수"]
persona_stats["평균_대화_시간"] = persona_stats["총_대화_시간"] / persona_stats["대화_수"]
stats["페르소나별_대화"][persona_dir] = persona_stats
# 전체 평균 계산
if stats["총_대화_수"] > 0:
stats["평균_대화_시간"] = total_duration / stats["총_대화_수"]
stats["평균_메시지_수"] = stats["총_메시지_수"] / stats["총_대화_수"]
return stats |