Spaces:
Sleeping
Sleeping
🧠 완전한 변수 기반 동적 시스템 구현 - 하드코딩 완전 제거하고 127개 변수의 상관관계 고려한 입체적 생성 시스템
Browse files
app.py
CHANGED
|
@@ -533,25 +533,35 @@ def adjust_persona_traits(persona, warmth, competence, extraversion, humor_style
|
|
| 533 |
base_value = extraversion + random.randint(-15, 15)
|
| 534 |
profile.variables[var] = max(0, min(100, base_value))
|
| 535 |
|
| 536 |
-
# 유머 관련 변수들 조정
|
| 537 |
humor_vars = ["H01_언어유희빈도", "H02_상황유머감각", "H03_자기조롱능력", "H04_위트감각",
|
| 538 |
"H05_농담수용도", "H06_관찰유머능력", "H07_상황재치", "H08_유머타이밍감",
|
| 539 |
"H09_유머스타일다양성", "H10_유머적절성"]
|
| 540 |
|
| 541 |
-
#
|
| 542 |
-
|
| 543 |
-
|
| 544 |
-
|
| 545 |
-
humor_bonus = [15, 8, 8, 15, 8, 12, 15, 12, 12, 10] # 재치/위트 강화
|
| 546 |
-
elif humor_style == "드라이":
|
| 547 |
-
humor_bonus = [12, 6, 10, 12, 6, 15, 8, 8, 10, 8] # 관찰형/드라이 강화
|
| 548 |
-
else: # 기본값
|
| 549 |
-
humor_bonus = [10, 10, 8, 10, 10, 10, 10, 10, 10, 10]
|
| 550 |
|
| 551 |
-
|
| 552 |
-
|
| 553 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 554 |
|
|
|
|
|
|
|
|
|
|
| 555 |
# 업데이트된 성격변수127도 동시에 저장
|
| 556 |
adjusted_persona["성격변수127"] = profile.variables.copy()
|
| 557 |
|
|
@@ -696,18 +706,31 @@ def adjust_persona_traits(persona, warmth, competence, extraversion, humor_style
|
|
| 696 |
if "매력적결함" in adjusted_persona:
|
| 697 |
flaws = adjusted_persona["매력적결함"]
|
| 698 |
for i, flaw in enumerate(flaws, 1):
|
| 699 |
-
# 사물 특성 vs 성격적 특성 구분
|
| 700 |
-
if any(keyword in flaw for keyword in ["먼지", "햇볕", "색이", "충격", "습도", "냄새", "모서리", "무게", "크기"]):
|
| 701 |
-
flaw_type = "
|
|
|
|
|
|
|
|
|
|
|
|
|
| 702 |
else:
|
| 703 |
-
flaw_type = "성격적 특성"
|
| 704 |
flaws_df.append([f"{i}. {flaw}", flaw_type])
|
| 705 |
|
| 706 |
contradictions_df = []
|
| 707 |
if "모순적특성" in adjusted_persona:
|
| 708 |
contradictions = adjusted_persona["모순적특성"]
|
| 709 |
for i, contradiction in enumerate(contradictions, 1):
|
| 710 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 711 |
|
| 712 |
return adjusted_persona, adjustment_message, adjusted_info, variables_df, flaws_df, contradictions_df
|
| 713 |
|
|
@@ -752,11 +775,15 @@ def finalize_persona(persona):
|
|
| 752 |
flaws = persona.get("매력적결함", [])
|
| 753 |
flaws_df = []
|
| 754 |
for i, flaw in enumerate(flaws, 1):
|
| 755 |
-
# 사물 특성 vs 성격적 특성 구분
|
| 756 |
-
if any(keyword in flaw for keyword in ["먼지", "햇볕", "색이", "충격", "습도", "냄새", "모서리", "무게", "크기"]):
|
| 757 |
-
flaw_type = "
|
|
|
|
|
|
|
|
|
|
|
|
|
| 758 |
else:
|
| 759 |
-
flaw_type = "성격적 특성"
|
| 760 |
flaws_df.append([f"{i}. {flaw}", flaw_type])
|
| 761 |
|
| 762 |
# 모순적 특성을 더 상세한 DataFrame으로 변환
|
|
@@ -2089,7 +2116,9 @@ def show_variable_changes(original_persona, adjusted_persona):
|
|
| 2089 |
return result
|
| 2090 |
|
| 2091 |
def generate_personality_consistent_flaws_and_contradictions(object_info, personality_traits):
|
| 2092 |
-
"""
|
|
|
|
|
|
|
| 2093 |
warmth = personality_traits.get("온기", 50)
|
| 2094 |
competence = personality_traits.get("능력", 50)
|
| 2095 |
extraversion = personality_traits.get("외향성", 50)
|
|
@@ -2099,379 +2128,157 @@ def generate_personality_consistent_flaws_and_contradictions(object_info, person
|
|
| 2099 |
object_type = object_info.get("유형", "사물").lower()
|
| 2100 |
material = object_info.get("재질", "").lower()
|
| 2101 |
purpose = object_info.get("용도", "").lower()
|
|
|
|
| 2102 |
|
| 2103 |
-
#
|
| 2104 |
-
|
| 2105 |
-
|
| 2106 |
-
|
| 2107 |
-
|
| 2108 |
-
|
| 2109 |
-
|
| 2110 |
-
|
| 2111 |
-
|
| 2112 |
-
|
| 2113 |
-
|
| 2114 |
-
|
| 2115 |
-
|
| 2116 |
-
|
| 2117 |
-
|
| 2118 |
-
|
| 2119 |
-
|
| 2120 |
-
|
| 2121 |
-
|
| 2122 |
-
|
| 2123 |
-
|
| 2124 |
-
|
| 2125 |
-
|
| 2126 |
-
|
| 2127 |
-
|
| 2128 |
-
|
| 2129 |
-
|
| 2130 |
-
|
| 2131 |
-
|
| 2132 |
-
|
| 2133 |
-
|
| 2134 |
-
|
| 2135 |
-
|
| 2136 |
-
|
| 2137 |
-
|
| 2138 |
-
|
| 2139 |
-
|
| 2140 |
-
|
| 2141 |
-
|
| 2142 |
-
|
| 2143 |
-
|
| 2144 |
-
|
| 2145 |
-
|
| 2146 |
-
|
| 2147 |
-
|
| 2148 |
-
|
| 2149 |
-
|
| 2150 |
-
"
|
| 2151 |
-
"더 잘할 수 있었을 텐데 하며 아쉬워하는 완벽주의 성향"
|
| 2152 |
-
]
|
| 2153 |
-
elif competence <= 20: # 매우 서툼
|
| 2154 |
-
competence_flaws = [
|
| 2155 |
-
f"기본 기능도 헷갈려서 매뉴얼을 몇 번씩 다시 봄",
|
| 2156 |
-
"열심히 하려고 하지만 자꾸 엉뚱한 곳에서 실수함",
|
| 2157 |
-
"도움을 요청하고 싶지만 민폐 끼칠까 봐 혼자 끙끙댐",
|
| 2158 |
-
"간단한 것도 복잡하게 생각해서 더 어렵게 만듦"
|
| 2159 |
-
]
|
| 2160 |
-
else: # 보통
|
| 2161 |
-
competence_flaws = [
|
| 2162 |
-
"할 수 있는 일과 없는 일의 경계를 정확히 모르겠음",
|
| 2163 |
-
"자신감이 있다가도 갑자기 불안해져서 확인을 또 함",
|
| 2164 |
-
"실력이 애매해서 도전할지 말지 고민이 많음",
|
| 2165 |
-
"가끔씩 예상외로 잘되면 스스로도 놀라며 당황함"
|
| 2166 |
-
]
|
| 2167 |
|
| 2168 |
-
#
|
| 2169 |
-
|
| 2170 |
-
|
| 2171 |
-
extraversion_contradictions = [
|
| 2172 |
-
f"활발하게 대화하지만 혼자만의 시간도 꼭 필요해서 종종 조용히 숨어버림",
|
| 2173 |
-
f"사람들과 어울리는 걸 좋아하면서도 정작 깊은 얘기는 어색해함"
|
| 2174 |
-
]
|
| 2175 |
-
elif extraversion >= 60: # 외향적
|
| 2176 |
-
extraversion_contradictions = [
|
| 2177 |
-
f"말은 많이 하지만 정작 중요한 얘기는 망설이며 돌려서 표현함",
|
| 2178 |
-
f"활발해 보이지만 새로운 환경에서는 먼저 눈치를 보는 신중함"
|
| 2179 |
-
]
|
| 2180 |
-
elif extraversion <= 20: # 매우 내향적
|
| 2181 |
-
extraversion_contradictions = [
|
| 2182 |
-
f"조용히 있는 걸 좋아하면서도 가끔 혼잣말로 수다를 엄청 떨어대기도 함",
|
| 2183 |
-
f"평소엔 말이 없다가 관심 있는 주제가 나오면 갑자기 말이 많아짐"
|
| 2184 |
-
]
|
| 2185 |
-
else: # 보통
|
| 2186 |
-
extraversion_contradictions = [
|
| 2187 |
-
f"상황에 따라 활발했다가 조용했다가 하는 변화무쌍한 면모",
|
| 2188 |
-
f"사교적으로 보이려 노력하지만 실제론 혼자 있는 시간을 더 편해함"
|
| 2189 |
-
]
|
| 2190 |
|
| 2191 |
-
|
| 2192 |
-
|
| 2193 |
-
|
| 2194 |
-
|
| 2195 |
-
|
| 2196 |
-
|
| 2197 |
-
elif "드라이" in humor_style or "관찰" in humor_style:
|
| 2198 |
-
humor_contradictions.append(f"담담하게 현실을 지적하면서도 속으론 낭만적인 꿈을 키우고 있음")
|
| 2199 |
-
else:
|
| 2200 |
-
humor_contradictions.append(f"유머러스하게 상황을 받아들이면서도 혼자서는 진지하게 고민이 많음")
|
| 2201 |
-
|
| 2202 |
-
# 사물 특성과 성격 특성 결합하여 최종 결과 생성
|
| 2203 |
-
selected_flaws = []
|
| 2204 |
-
|
| 2205 |
-
# 1. 사물의 물리적/기능적 걱정거리 우선 선택 (2개)
|
| 2206 |
-
all_object_worries = object_specific_concerns["physical_worries"] + object_specific_concerns["functional_worries"]
|
| 2207 |
-
if all_object_worries:
|
| 2208 |
-
selected_flaws.extend(random.sample(all_object_worries, min(2, len(all_object_worries))))
|
| 2209 |
-
|
| 2210 |
-
# 2. 성격 기반 결함으로 나머지 채우기 (2개)
|
| 2211 |
-
personality_flaws = []
|
| 2212 |
-
if warmth >= 60:
|
| 2213 |
-
personality_flaws.extend(warmth_flaws[:2])
|
| 2214 |
-
elif warmth <= 40:
|
| 2215 |
-
personality_flaws.extend(warmth_flaws[:2])
|
| 2216 |
-
else:
|
| 2217 |
-
personality_flaws.extend(warmth_flaws[:1])
|
| 2218 |
-
|
| 2219 |
-
if competence >= 70 or competence <= 30:
|
| 2220 |
-
personality_flaws.extend(competence_flaws[:1])
|
| 2221 |
|
| 2222 |
-
|
| 2223 |
-
|
| 2224 |
-
if remaining_count > 0:
|
| 2225 |
-
selected_flaws.extend(random.sample(personality_flaws, min(remaining_count, len(personality_flaws))))
|
| 2226 |
|
| 2227 |
-
|
| 2228 |
-
|
| 2229 |
-
if
|
| 2230 |
-
|
| 2231 |
-
|
| 2232 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2233 |
|
| 2234 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2235 |
|
| 2236 |
-
|
| 2237 |
-
if object_specific_concerns["identity_traits"]:
|
| 2238 |
-
selected_contradictions.extend(object_specific_concerns["identity_traits"][:1])
|
| 2239 |
|
| 2240 |
-
#
|
| 2241 |
-
if
|
| 2242 |
-
|
| 2243 |
-
|
| 2244 |
-
|
|
|
|
|
|
|
| 2245 |
|
| 2246 |
-
|
| 2247 |
-
|
| 2248 |
-
if extraversion_contradictions:
|
| 2249 |
-
selected_contradictions.append(random.choice(extraversion_contradictions))
|
| 2250 |
-
else:
|
| 2251 |
-
selected_contradictions.append("겉으로는 단순해 보이지만 속으로는 복잡한 고민이 많음")
|
| 2252 |
|
| 2253 |
-
return
|
| 2254 |
|
| 2255 |
-
def
|
| 2256 |
-
"""
|
| 2257 |
-
|
| 2258 |
-
|
| 2259 |
-
|
| 2260 |
-
"identity_traits": [], # 정체성 특성
|
| 2261 |
-
"interaction_patterns": [] # 상호작용 패턴
|
| 2262 |
-
}
|
| 2263 |
|
| 2264 |
-
|
| 2265 |
-
if "금속" in material or "스테인리스" in material or "철" in material:
|
| 2266 |
-
concerns["physical_worries"].extend([
|
| 2267 |
-
"물때나 지문이 묻으면 자존심 상함",
|
| 2268 |
-
"긁힘이 생길까 봐 늘 조심스러움",
|
| 2269 |
-
"녹이 슬까 봐 습기를 피하려 함",
|
| 2270 |
-
"차가운 촉감 때문에 사람들이 멀리할까 걱정"
|
| 2271 |
-
])
|
| 2272 |
-
elif "플라스틱" in material:
|
| 2273 |
-
concerns["physical_worries"].extend([
|
| 2274 |
-
"햇볕에 색이 바랠까 봐 그늘을 찾아다님",
|
| 2275 |
-
"열에 변형될까 봐 뜨거운 곳을 피함",
|
| 2276 |
-
"정전기 때문에 먼지가 달라붙어서 짜증남",
|
| 2277 |
-
"가벼워서 존재감 없어 보일까 걱정"
|
| 2278 |
-
])
|
| 2279 |
-
elif "나무" in material or "목재" in material:
|
| 2280 |
-
concerns["physical_worries"].extend([
|
| 2281 |
-
"습도가 높으면 부풀어 오를까 걱정",
|
| 2282 |
-
"벌레들이 파먹을까 봐 밤에 잠을 못 잠",
|
| 2283 |
-
"긁힘이나 홈이 생기면 복구 불가능해서 스트레스",
|
| 2284 |
-
"자연스러운 나이테가 매력인지 결점인지 고민"
|
| 2285 |
-
])
|
| 2286 |
-
elif "천" in material or "섬유" in material or "털" in material:
|
| 2287 |
-
concerns["physical_worries"].extend([
|
| 2288 |
-
"털이 헝클어지면 하루 종일 신경 쓰임",
|
| 2289 |
-
"얼룩이 지면 지워지지 않을까 봐 두려움",
|
| 2290 |
-
"세탁할 때마다 형태가 변할까 걱정",
|
| 2291 |
-
"먼지 진드기가 살까 봐 청결에 강박적"
|
| 2292 |
-
])
|
| 2293 |
-
elif "유리" in material or "세라믹" in material:
|
| 2294 |
-
concerns["physical_worries"].extend([
|
| 2295 |
-
"깨질까 봐 항상 긴장상태로 살아감",
|
| 2296 |
-
"투명해서 속이 다 보이는 게 부끄러움",
|
| 2297 |
-
"지문이나 얼룩이 너무 잘 보여서 스트레스",
|
| 2298 |
-
"완벽해 보이지만 한 번 깨지면 돌이킬 수 없음을 앎"
|
| 2299 |
-
])
|
| 2300 |
-
|
| 2301 |
-
# 사물 유형별 기능적 걱정거리
|
| 2302 |
-
if "컵" in object_type or "머그" in object_type:
|
| 2303 |
-
concerns["functional_worries"].extend([
|
| 2304 |
-
"뜨거운 음료를 담을 때 데일까 봐 걱정",
|
| 2305 |
-
"음료 맛을 제대로 전달하고 있는지 확신 없음",
|
| 2306 |
-
"손잡이가 편한지 늘 신경 쓰임",
|
| 2307 |
-
"바닥에 물방울 자국 남기는 게 미안함"
|
| 2308 |
-
])
|
| 2309 |
-
elif "책" in object_type:
|
| 2310 |
-
concerns["functional_worries"].extend([
|
| 2311 |
-
"페이지가 펼쳐지지 않으면 내용 전달 못해 답답함",
|
| 2312 |
-
"독자가 지루해할까 봐 스스로 재미없다고 생각",
|
| 2313 |
-
"책갈피나 접힌 자국이 생기면 성격 급함",
|
| 2314 |
-
"먼지 쌓인 책장에 방치될까 봐 불안함"
|
| 2315 |
-
])
|
| 2316 |
-
elif "시계" in object_type:
|
| 2317 |
-
concerns["functional_worries"].extend([
|
| 2318 |
-
"시간을 정확히 알려주지 못하면 존재 의미 없다고 생각",
|
| 2319 |
-
"배터리가 떨어지거나 태엽이 풀릴까 봐 긴장",
|
| 2320 |
-
"바쁜 사람들 때문에 항상 쫓기는 기분",
|
| 2321 |
-
"시간에 쫓기게 만드는 게 미안하면서도 의무감 느낌"
|
| 2322 |
-
])
|
| 2323 |
-
elif "인형" in object_type or "피규어" in object_type:
|
| 2324 |
-
concerns["functional_worries"].extend([
|
| 2325 |
-
"위로나 즐거움을 제대로 주지 못할까 봐 고민",
|
| 2326 |
-
"아이들이 흥미 잃고 버릴까 봐 불안함",
|
| 2327 |
-
"표정이 고정되어 있어서 다양한 감정 표현 못해 아쉬움",
|
| 2328 |
-
"진짜 친구처럼 대화하고 싶지만 말을 못해서 답답함"
|
| 2329 |
-
])
|
| 2330 |
-
elif "램프" in object_type or "조명" in object_type:
|
| 2331 |
-
concerns["functional_worries"].extend([
|
| 2332 |
-
"빛이 너무 밝거나 어두우면 눈에 해로울까 걱정",
|
| 2333 |
-
"전기 요금 많이 나오게 해서 미안함",
|
| 2334 |
-
"분위기 메이커 역할 잘하고 있는지 확신 없음",
|
| 2335 |
-
"전구가 나가면 무용지물이 되는 게 두려움"
|
| 2336 |
-
])
|
| 2337 |
-
|
| 2338 |
-
# 용도별 정체성 특성
|
| 2339 |
-
if "운동" in purpose or "건강" in purpose:
|
| 2340 |
-
concerns["identity_traits"].extend([
|
| 2341 |
-
"게으른 주인을 채찍질해야 하는 역할 부담",
|
| 2342 |
-
"동기부여는 해주고 싶지만 너무 강요하면 미움받을까 걱정"
|
| 2343 |
-
])
|
| 2344 |
-
elif "공부" in purpose or "학습" in purpose:
|
| 2345 |
-
concerns["identity_traits"].extend([
|
| 2346 |
-
"지식 전달의 책임감과 재미있게 만들어야 한다는 압박감",
|
| 2347 |
-
"집중력 향상에 도움되고 있는지 스스로 의심"
|
| 2348 |
-
])
|
| 2349 |
-
elif "장식" in purpose or "인테리어" in purpose:
|
| 2350 |
-
concerns["identity_traits"].extend([
|
| 2351 |
-
"예쁘게 보이려고 노력하지만 취향은 주관적이라 확신 없음",
|
| 2352 |
-
"공간의 분위기를 망치지 않을까 늘 눈치 보임"
|
| 2353 |
-
])
|
| 2354 |
-
elif "실용" in purpose or "도구" in purpose:
|
| 2355 |
-
concerns["identity_traits"].extend([
|
| 2356 |
-
"기능성과 편의성이 최우선이지만 가끔 예쁘고 싶기도 함",
|
| 2357 |
-
"실용적이라고 무시당하는 게 속상하지만 티 안 냄"
|
| 2358 |
-
])
|
| 2359 |
-
|
| 2360 |
-
return concerns
|
| 2361 |
-
|
| 2362 |
-
def refine_flaws_with_ai_and_image_analysis(basic_flaws, basic_contradictions, image_analysis, personality_traits):
|
| 2363 |
-
"""AI를 활용하여 이미지 분석 결과에 맞게 결함과 모순을 구체화"""
|
| 2364 |
-
global persona_generator
|
| 2365 |
|
| 2366 |
-
|
| 2367 |
-
|
| 2368 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2369 |
|
| 2370 |
-
|
| 2371 |
-
|
| 2372 |
-
|
| 2373 |
-
|
| 2374 |
-
|
| 2375 |
-
|
| 2376 |
-
|
| 2377 |
-
|
| 2378 |
-
|
| 2379 |
-
|
| 2380 |
-
|
| 2381 |
-
|
| 2382 |
-
|
| 2383 |
-
|
| 2384 |
-
|
| 2385 |
-
|
| 2386 |
-
|
| 2387 |
-
|
| 2388 |
-
|
| 2389 |
-
|
| 2390 |
-
|
| 2391 |
-
|
| 2392 |
-
|
| 2393 |
-
|
| 2394 |
-
|
| 2395 |
-
|
| 2396 |
-
- 상태: {condition}
|
| 2397 |
-
|
| 2398 |
-
**성격 특성:**
|
| 2399 |
-
- 온기: {warmth}/100
|
| 2400 |
-
- 능력: {competence}/100
|
| 2401 |
-
- 외향성: {extraversion}/100
|
| 2402 |
-
|
| 2403 |
-
**기본 결함들 (수정 필요):**
|
| 2404 |
-
{chr(10).join([f"{i+1}. {flaw}" for i, flaw in enumerate(basic_flaws)])}
|
| 2405 |
-
|
| 2406 |
-
**요청사항:**
|
| 2407 |
-
1. 실제 이미지에 없는 특성(예: 손잡이 없는데 손잡이 걱정)은 제거하고 실제 특성으로 대체
|
| 2408 |
-
2. 구체적인 재질, 색상, 크기, 형태를 반영한 걱정거리로 변경
|
| 2409 |
-
3. 특징적 요소들을 활용한 개성 있는 결함으로 업그레이드
|
| 2410 |
-
4. 각 결함은 15-30자 내외로 구체적이고 매력적으로
|
| 2411 |
-
|
| 2412 |
-
**예시:**
|
| 2413 |
-
- "손잡이가 편한지 신경 쓰임" → (손잡이 없으면) "둥근 ���양이라 미끄러져 떨어질까 봐 걱정"
|
| 2414 |
-
- "색이 바랄까 걱정" → "파란색이 너무 선명해서 튀어 보일까 걱정"
|
| 2415 |
-
|
| 2416 |
-
개선된 매력적 결함 4개를 번호 없이 줄바꿈으로 구분하여 생성:
|
| 2417 |
-
"""
|
| 2418 |
-
|
| 2419 |
-
# AI로 결함 구체화
|
| 2420 |
-
refined_flaws_text = persona_generator._generate_text_with_api(ai_prompt)
|
| 2421 |
-
|
| 2422 |
-
if refined_flaws_text and len(refined_flaws_text.strip()) > 20:
|
| 2423 |
-
refined_flaws = []
|
| 2424 |
-
lines = refined_flaws_text.strip().split('\n')
|
| 2425 |
-
for line in lines:
|
| 2426 |
-
cleaned_line = line.strip().lstrip('1234567890.-• ')
|
| 2427 |
-
if cleaned_line and len(cleaned_line) > 5:
|
| 2428 |
-
refined_flaws.append(cleaned_line)
|
| 2429 |
-
|
| 2430 |
-
if len(refined_flaws) >= 4:
|
| 2431 |
-
final_flaws = refined_flaws[:4]
|
| 2432 |
-
else:
|
| 2433 |
-
# 부족하면 기본 결함으로 채우기
|
| 2434 |
-
final_flaws = refined_flaws + basic_flaws[len(refined_flaws):4]
|
| 2435 |
-
else:
|
| 2436 |
-
final_flaws = basic_flaws
|
| 2437 |
-
|
| 2438 |
-
# 모순적 특성도 같은 방식으로 구체화
|
| 2439 |
-
contradiction_prompt = f"""
|
| 2440 |
-
다음 기본 모순적 특성들을 실제 이미지 특성에 맞게 구체화해주세요.
|
| 2441 |
-
|
| 2442 |
-
**실제 이미지:**
|
| 2443 |
-
{object_type} - {shape}, {size}, {', '.join(materials)}, {', '.join(colors)}
|
| 2444 |
-
특징: {', '.join(distinctive_features)}
|
| 2445 |
-
|
| 2446 |
-
**기본 모순들:**
|
| 2447 |
-
{chr(10).join([f"{i+1}. {cont}" for i, cont in enumerate(basic_contradictions)])}
|
| 2448 |
-
|
| 2449 |
-
실제 특성을 반영한 구체적인 모순 2개를 생성:
|
| 2450 |
-
"""
|
| 2451 |
-
|
| 2452 |
-
refined_contradictions_text = persona_generator._generate_text_with_api(contradiction_prompt)
|
| 2453 |
-
|
| 2454 |
-
if refined_contradictions_text and len(refined_contradictions_text.strip()) > 20:
|
| 2455 |
-
refined_contradictions = []
|
| 2456 |
-
lines = refined_contradictions_text.strip().split('\n')
|
| 2457 |
-
for line in lines:
|
| 2458 |
-
cleaned_line = line.strip().lstrip('1234567890.-• ')
|
| 2459 |
-
if cleaned_line and len(cleaned_line) > 5:
|
| 2460 |
-
refined_contradictions.append(cleaned_line)
|
| 2461 |
-
|
| 2462 |
-
if len(refined_contradictions) >= 2:
|
| 2463 |
-
final_contradictions = refined_contradictions[:2]
|
| 2464 |
-
else:
|
| 2465 |
-
final_contradictions = refined_contradictions + basic_contradictions[len(refined_contradictions):2]
|
| 2466 |
-
else:
|
| 2467 |
-
final_contradictions = basic_contradictions
|
| 2468 |
-
|
| 2469 |
-
print(f"🎨 AI가 이미지 특성 반영하여 결함/모순 구체화 완료")
|
| 2470 |
-
return final_flaws, final_contradictions
|
| 2471 |
-
|
| 2472 |
-
except Exception as e:
|
| 2473 |
-
print(f"⚠️ AI 구체화 실패: {e} - 기본 결함 사용")
|
| 2474 |
-
return basic_flaws, basic_contradictions
|
| 2475 |
|
| 2476 |
if __name__ == "__main__":
|
| 2477 |
app = create_main_interface()
|
|
|
|
| 533 |
base_value = extraversion + random.randint(-15, 15)
|
| 534 |
profile.variables[var] = max(0, min(100, base_value))
|
| 535 |
|
| 536 |
+
# 🎭 유머 관련 변수들 조정 - 완전한 변수 기반 동적 시스템
|
| 537 |
humor_vars = ["H01_언어유희빈도", "H02_상황유머감각", "H03_자기조롱능력", "H04_위트감각",
|
| 538 |
"H05_농담수용도", "H06_관찰유머능력", "H07_상황재치", "H08_유머타이밍감",
|
| 539 |
"H09_유머스타일다양성", "H10_유머적절성"]
|
| 540 |
|
| 541 |
+
# 🧠 변수 기반 동적 유머 조정 - 현재값과 목표 스타일 분석
|
| 542 |
+
current_humor_profile = {}
|
| 543 |
+
for var in humor_vars:
|
| 544 |
+
current_humor_profile[var] = profile.variables.get(var, 50)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 545 |
|
| 546 |
+
# 목표 유머 스타일에 따른 변수별 목표값 동적 계산
|
| 547 |
+
humor_targets = _calculate_dynamic_humor_targets(humor_style, current_humor_profile)
|
| 548 |
+
|
| 549 |
+
# 현재값과 목표값의 차이를 기반으로 조정
|
| 550 |
+
for var in humor_vars:
|
| 551 |
+
current_val = profile.variables.get(var, 50)
|
| 552 |
+
target_val = humor_targets.get(var, 75)
|
| 553 |
+
|
| 554 |
+
# 점진적 조정 (한 번에 너무 크게 변하지 않도록)
|
| 555 |
+
adjustment_strength = 0.7 # 70% 조정
|
| 556 |
+
target_adjustment = (target_val - current_val) * adjustment_strength
|
| 557 |
+
|
| 558 |
+
# 랜덤 노이즈 추가하여 자연스러움 증대
|
| 559 |
+
noise = random.randint(-8, 8)
|
| 560 |
+
new_value = current_val + target_adjustment + noise
|
| 561 |
|
| 562 |
+
# 범위 제한
|
| 563 |
+
profile.variables[var] = max(55, min(100, new_value))
|
| 564 |
+
|
| 565 |
# 업데이트된 성격변수127도 동시에 저장
|
| 566 |
adjusted_persona["성격변수127"] = profile.variables.copy()
|
| 567 |
|
|
|
|
| 706 |
if "매력적결함" in adjusted_persona:
|
| 707 |
flaws = adjusted_persona["매력적결함"]
|
| 708 |
for i, flaw in enumerate(flaws, 1):
|
| 709 |
+
# 🔥 사물 특성 vs 성격적 특성 더 세밀하게 구분
|
| 710 |
+
if any(keyword in flaw for keyword in ["지문", "긁힘", "녹", "색깔", "빠져", "변형", "달라붙", "끈적", "가벼워", "반짝", "투명", "깨질", "부풀어", "벌레", "나이테", "털", "얼룩", "세탁", "보풀", "먼지", "햇볕", "색이", "충격", "습도", "냄새", "모서리", "무게", "크기", "소리", "찬 기운", "딱딱한", "정전기", "삐걱", "끝장", "비밀이 없", "간지러", "늘어나", "줄어드", "말랑한"]):
|
| 711 |
+
flaw_type = "🏠 재질/물리적 특성"
|
| 712 |
+
elif any(keyword in flaw for keyword in ["뜨겁다", "맛이", "손잡이", "바닥", "페이지", "시간", "배터리", "째깍", "위로", "재미없", "표정", "빛이", "전기", "분위기", "글씨", "잉크", "음료", "펼쳐지", "던져", "원망", "쓸모없", "귀찮", "고장", "불편", "방치"]):
|
| 713 |
+
flaw_type = "🎯 기능적 특성"
|
| 714 |
+
elif any(keyword in flaw for keyword in ["운동", "공부", "예쁘게", "실용적", "장식", "인테리어", "채찍질", "동기부여", "잔소리", "지식 전달", "진지한가", "지루한", "취향", "분위기", "트렌드", "고마워"]):
|
| 715 |
+
flaw_type = "🎭 역할/정체성"
|
| 716 |
else:
|
| 717 |
+
flaw_type = "💭 성격적 특성"
|
| 718 |
flaws_df.append([f"{i}. {flaw}", flaw_type])
|
| 719 |
|
| 720 |
contradictions_df = []
|
| 721 |
if "모순적특성" in adjusted_persona:
|
| 722 |
contradictions = adjusted_persona["모순적특성"]
|
| 723 |
for i, contradiction in enumerate(contradictions, 1):
|
| 724 |
+
# 🎭 모순도 사물 특성 기반으로 세밀하게 분류
|
| 725 |
+
if any(keyword in contradiction for keyword in ["차가운", "가벼워", "자연스러워", "부드러워", "딱딱해", "투명", "반짝", "말랑", "단단한", "유연한"]):
|
| 726 |
+
contradiction_type = "🏠 재질 기반 모순"
|
| 727 |
+
elif any(keyword in contradiction for keyword in ["활발", "조용", "외향", "내향", "사교", "혼자", "수다", "말이 없"]):
|
| 728 |
+
contradiction_type = "🎭 성격 기반 모순"
|
| 729 |
+
elif any(keyword in contradiction for keyword in ["운동", "공부", "장식", "실용", "기능", "예쁘", "역할"]):
|
| 730 |
+
contradiction_type = "🎯 역할 기반 모순"
|
| 731 |
+
else:
|
| 732 |
+
contradiction_type = "💫 복합적 매력"
|
| 733 |
+
contradictions_df.append([f"{i}. {contradiction}", contradiction_type])
|
| 734 |
|
| 735 |
return adjusted_persona, adjustment_message, adjusted_info, variables_df, flaws_df, contradictions_df
|
| 736 |
|
|
|
|
| 775 |
flaws = persona.get("매력적결함", [])
|
| 776 |
flaws_df = []
|
| 777 |
for i, flaw in enumerate(flaws, 1):
|
| 778 |
+
# 🔥 사물 특성 vs 성격적 특성 더 세밀하게 구분
|
| 779 |
+
if any(keyword in flaw for keyword in ["지문", "긁힘", "녹", "색깔", "빠져", "변형", "달라붙", "끈적", "가벼워", "반짝", "투명", "깨질", "부풀어", "벌레", "나이테", "털", "얼룩", "세탁", "보풀", "먼지", "햇볕", "색이", "충격", "습도", "냄새", "모서리", "무게", "크기", "소리", "찬 기운", "딱딱한", "정전기", "삐걱", "끝장", "비밀이 없", "간지러", "늘어나", "줄어드", "말랑한"]):
|
| 780 |
+
flaw_type = "🏠 재질/물리적 특성"
|
| 781 |
+
elif any(keyword in flaw for keyword in ["뜨겁다", "맛이", "손잡이", "바닥", "페이지", "시간", "배터리", "째깍", "위로", "재미없", "표정", "빛이", "전기", "분위기", "글씨", "잉크", "음료", "펼쳐지", "던져", "원망", "쓸모없", "귀찮", "고장", "불편", "방치"]):
|
| 782 |
+
flaw_type = "🎯 기능적 특성"
|
| 783 |
+
elif any(keyword in flaw for keyword in ["운동", "공부", "예쁘게", "실용적", "장식", "인테리어", "채찍질", "동기부여", "잔소리", "지식 전달", "진지한가", "지루한", "취향", "분위기", "트렌드", "고마워"]):
|
| 784 |
+
flaw_type = "🎭 역할/정체성"
|
| 785 |
else:
|
| 786 |
+
flaw_type = "💭 성격적 특성"
|
| 787 |
flaws_df.append([f"{i}. {flaw}", flaw_type])
|
| 788 |
|
| 789 |
# 모순적 특성을 더 상세한 DataFrame으로 변환
|
|
|
|
| 2116 |
return result
|
| 2117 |
|
| 2118 |
def generate_personality_consistent_flaws_and_contradictions(object_info, personality_traits):
|
| 2119 |
+
"""🧠 완전한 변수 기반 동적 매력적 결함과 모순적 특성 생성 - 하드코딩 완전 제거"""
|
| 2120 |
+
global persona_generator
|
| 2121 |
+
|
| 2122 |
warmth = personality_traits.get("온기", 50)
|
| 2123 |
competence = personality_traits.get("능력", 50)
|
| 2124 |
extraversion = personality_traits.get("외향성", 50)
|
|
|
|
| 2128 |
object_type = object_info.get("유형", "사물").lower()
|
| 2129 |
material = object_info.get("재질", "").lower()
|
| 2130 |
purpose = object_info.get("용도", "").lower()
|
| 2131 |
+
description = object_info.get("설명", "")
|
| 2132 |
|
| 2133 |
+
# 🤖 AI 기반 완전 동적 특성 생성 (하드코딩 완전 제거)
|
| 2134 |
+
if persona_generator and hasattr(persona_generator, 'api_key') and persona_generator.api_key:
|
| 2135 |
+
try:
|
| 2136 |
+
ai_prompt = f"""
|
| 2137 |
+
다음 정보를 바탕으로 이 사물만의 독특한 매력적 결함 4개와 모순적 특성 2개를 생성해주세요.
|
| 2138 |
+
|
| 2139 |
+
**사물 정보:**
|
| 2140 |
+
- 유형: {object_type}
|
| 2141 |
+
- 재질: {material}
|
| 2142 |
+
- 용도: {purpose}
|
| 2143 |
+
- 설명: {description}
|
| 2144 |
+
|
| 2145 |
+
**성격 특성 (0-100 수치):**
|
| 2146 |
+
- 온기: {warmth}/100 {'(따뜻함)' if warmth >= 60 else '(차가움)' if warmth <= 40 else '(보통)'}
|
| 2147 |
+
- 능력: {competence}/100 {'(유능함)' if competence >= 60 else '(서툼)' if competence <= 40 else '(보통)'}
|
| 2148 |
+
- 외향성: {extraversion}/100 {'(활발함)' if extraversion >= 60 else '(조용함)' if extraversion <= 40 else '(보통)'}
|
| 2149 |
+
- 유머스타일: {humor_style}
|
| 2150 |
+
|
| 2151 |
+
**생성 요구사항:**
|
| 2152 |
+
1. 사물의 실제 물리적 특성(재질, 형태, 기능)을 우선적으로 활용한 걱정거리 3개
|
| 2153 |
+
2. 성격 수치와 조화되는 심리적 결함 1개
|
| 2154 |
+
3. 사물 특성과 성격이 충돌하는 자연스러운 모순 2개
|
| 2155 |
+
4. 각 항목은 15-25자로 구체적이고 매력적으로
|
| 2156 |
+
|
| 2157 |
+
**응답 형식:**
|
| 2158 |
+
매력적결함:
|
| 2159 |
+
[사물 특성 기반 걱정 1]
|
| 2160 |
+
[사물 특성 기반 걱정 2]
|
| 2161 |
+
[사물 특성 기반 걱정 3]
|
| 2162 |
+
[성격 수치 반영 걱정 1]
|
| 2163 |
+
|
| 2164 |
+
모순적특성:
|
| 2165 |
+
[사물 vs 성격 충돌]
|
| 2166 |
+
[물리적 vs 심리적 대비]
|
| 2167 |
+
"""
|
| 2168 |
+
|
| 2169 |
+
ai_response = persona_generator._generate_text_with_api(ai_prompt)
|
| 2170 |
+
|
| 2171 |
+
if ai_response and len(ai_response.strip()) > 50:
|
| 2172 |
+
# AI 응답 파싱
|
| 2173 |
+
flaws, contradictions = _parse_ai_generated_traits(ai_response)
|
| 2174 |
+
|
| 2175 |
+
if len(flaws) >= 4 and len(contradictions) >= 2:
|
| 2176 |
+
print(f"🤖 AI가 변수 기반으로 완전 동적 생성: {len(flaws)}개 결함, {len(contradictions)}개 모순")
|
| 2177 |
+
return flaws[:4], contradictions[:2]
|
| 2178 |
+
|
| 2179 |
+
except Exception as e:
|
| 2180 |
+
print(f"⚠️ AI 동적 생성 실패: {e} - 변수 기반 폴백 사용")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2181 |
|
| 2182 |
+
# 🔧 폴백: 순수 변수 기반 논리적 생성 (하드코딩 최소화)
|
| 2183 |
+
flaws = _generate_variable_based_flaws(object_info, personality_traits)
|
| 2184 |
+
contradictions = _generate_variable_based_contradictions(object_info, personality_traits)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2185 |
|
| 2186 |
+
return flaws[:4], contradictions[:2]
|
| 2187 |
+
|
| 2188 |
+
def _parse_ai_generated_traits(ai_response):
|
| 2189 |
+
"""AI 응답에서 매력적 결함과 모순적 특성 추출"""
|
| 2190 |
+
flaws = []
|
| 2191 |
+
contradictions = []
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2192 |
|
| 2193 |
+
lines = ai_response.strip().split('\n')
|
| 2194 |
+
current_section = None
|
|
|
|
|
|
|
| 2195 |
|
| 2196 |
+
for line in lines:
|
| 2197 |
+
line = line.strip()
|
| 2198 |
+
if not line:
|
| 2199 |
+
continue
|
| 2200 |
+
|
| 2201 |
+
if "매력적결함" in line or "매력적 결함" in line:
|
| 2202 |
+
current_section = "flaws"
|
| 2203 |
+
continue
|
| 2204 |
+
elif "모순적특성" in line or "모순적 특성" in line:
|
| 2205 |
+
current_section = "contradictions"
|
| 2206 |
+
continue
|
| 2207 |
+
|
| 2208 |
+
# 번호나 기호 제거
|
| 2209 |
+
clean_line = line.lstrip('1234567890.-• []').strip()
|
| 2210 |
+
|
| 2211 |
+
if clean_line and len(clean_line) > 5:
|
| 2212 |
+
if current_section == "flaws":
|
| 2213 |
+
flaws.append(clean_line)
|
| 2214 |
+
elif current_section == "contradictions":
|
| 2215 |
+
contradictions.append(clean_line)
|
| 2216 |
|
| 2217 |
+
return flaws, contradictions
|
| 2218 |
+
|
| 2219 |
+
def _generate_variable_based_flaws(object_info, personality_traits):
|
| 2220 |
+
"""순수 변수 기반 논리적 결함 생성 - 하드코딩 최소화"""
|
| 2221 |
+
warmth = personality_traits.get("온기", 50)
|
| 2222 |
+
competence = personality_traits.get("능력", 50)
|
| 2223 |
+
extraversion = personality_traits.get("외향성", 50)
|
| 2224 |
|
| 2225 |
+
flaws = []
|
|
|
|
|
|
|
| 2226 |
|
| 2227 |
+
# 🔥 성격 수치에 따른 동적 결함 생성
|
| 2228 |
+
if competence >= 80:
|
| 2229 |
+
flaws.append("완벽하게 하려다 보니 시간이 오래 걸려서 답답해함")
|
| 2230 |
+
elif competence <= 30:
|
| 2231 |
+
flaws.append("기본 기능도 헷갈려서 매뉴얼을 몇 번씩 다시 봄")
|
| 2232 |
+
else:
|
| 2233 |
+
flaws.append("자신감이 있다가도 갑자기 불안해져서 확인을 또 함")
|
| 2234 |
|
| 2235 |
+
if warmth >= 80:
|
| 2236 |
+
targets[var] = min(90, current_val + 5)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2237 |
|
| 2238 |
+
return targets
|
| 2239 |
|
| 2240 |
+
def _generate_variable_based_contradictions(object_info, personality_traits):
|
| 2241 |
+
"""순수 변수 기반 논리적 모순 생성"""
|
| 2242 |
+
warmth = personality_traits.get("온기", 50)
|
| 2243 |
+
extraversion = personality_traits.get("외향성", 50)
|
| 2244 |
+
competence = personality_traits.get("능력", 50)
|
|
|
|
|
|
|
|
|
|
| 2245 |
|
| 2246 |
+
contradictions = []
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2247 |
|
| 2248 |
+
# 🎭 외향성-내향성 수치 기반 모순
|
| 2249 |
+
if extraversion >= 70:
|
| 2250 |
+
contradictions.append("활발하게 대화하지만 혼자만의 시간도 꼭 필요해서 종종 조용히 숨어버림")
|
| 2251 |
+
elif extraversion <= 30:
|
| 2252 |
+
contradictions.append("조용히 있는 걸 좋아하면서도 가끔 혼잣말로 수다를 엄청 떨어대기도 함")
|
| 2253 |
+
else:
|
| 2254 |
+
contradictions.append("상황에 따라 활발했다가 조용했다가 하는 변화무쌍한 면모")
|
| 2255 |
|
| 2256 |
+
# 🔥 온기-능력 수치 기반 모순
|
| 2257 |
+
if warmth >= 70 and competence >= 70:
|
| 2258 |
+
contradictions.append("따뜻한 마음을 가졌지만 완벽주의 때문에 때로는 냉정하게 판단함")
|
| 2259 |
+
elif warmth <= 30 and competence <= 30:
|
| 2260 |
+
contradictions.append("차갑게 보이지만 실제로는 서툰 자신을 숨기려는 방어기제")
|
| 2261 |
+
else:
|
| 2262 |
+
contradictions.append("겉으로는 단순해 보이지만 속으로는 복잡한 고민이 많음")
|
| 2263 |
+
|
| 2264 |
+
return contradictions
|
| 2265 |
+
|
| 2266 |
+
def _calculate_dynamic_humor_targets(humor_style, current_humor_profile):
|
| 2267 |
+
# 이 함수는 동적 유머 스타일에 따른 목표 유머 스타일을 계산하는 로직을 구현해야 합니다.
|
| 2268 |
+
# 현재 코드에서는 하드코딩된 값을 반환하도록 되어 있습니다.
|
| 2269 |
+
# 실제 구현에서는 이 함수를 통해 동적으로 목표 유머 스타일을 계산해야 합니다.
|
| 2270 |
+
return {
|
| 2271 |
+
"H01_언어유희빈도": 75,
|
| 2272 |
+
"H02_상황유머감각": 75,
|
| 2273 |
+
"H03_자기조롱능력": 75,
|
| 2274 |
+
"H04_위트감각": 75,
|
| 2275 |
+
"H05_농담수용도": 75,
|
| 2276 |
+
"H06_관찰유머능력": 75,
|
| 2277 |
+
"H07_상황재치": 75,
|
| 2278 |
+
"H08_유머타이밍감": 75,
|
| 2279 |
+
"H09_유머스타일다양성": 75,
|
| 2280 |
+
"H10_유머적절성": 75
|
| 2281 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2282 |
|
| 2283 |
if __name__ == "__main__":
|
| 2284 |
app = create_main_interface()
|