es / app.py
ll7098ll's picture
Update app.py
9102cb6 verified
import os
import time
import streamlit as st
import google.generativeai as genai
from streamlit_extras.colored_header import colored_header
import markdown
# Google Gemini API Key 설정
genai.configure(api_key=os.environ["GEMINI_API_KEY"])
# 모델 설정
generation_config = {
"temperature": 0.75,
"top_p": 0.8,
"top_k": 40,
"max_output_tokens": 8192,
}
model = genai.GenerativeModel(
model_name="gemini-2.0-flash",
generation_config=generation_config,
)
# 에니어그램 유형 정보 (상세 설명 고도화)
enneagram_types = {
"1": "완벽주의자 (Reformer) - 높은 도덕적 기준을 가지고 있으며, 스스로와 타인을 개선하려는 강한 의지가 있습니다. 이들은 옳고 그름에 대한 분명한 기준을 가지고 있으며, 세상을 더 나은 곳으로 만들기 위해 노력합니다. 때로는 비판적일 수 있으나, 이는 개선과 진보를 위한 것입니다.",
"2": "도우미 (Helper) - 타인을 돕고 지원하는 데서 큰 만족을 느끼며, 관계에서 사랑과 관심을 중시합니다. 타인의 필요에 민감하며, 때로는 자신의 욕구를 무시하고 다른 사람을 먼저 돌보려는 경향이 있습니다. 이들의 궁극적인 목표는 진정한 연결과 타인으로부터의 인정입니다.",
"3": "성과자 (Achiever) - 목표 달성과 성공을 가장 중요하게 생각하며, 실용적이고 효율적인 접근을 선호합니다. 이미지와 자기 관리를 잘하며, 인정받고자 하는 욕구가 큽니다. 사회적 성공을 통해 자신을 가치 있게 여기지만, 내면의 진정한 가치를 발견하는 것이 이들의 중요한 과제입니다.",
"4": "개인주의자 (Individualist) - 개성과 독창성을 중시하고, 자신의 감정에 깊이 몰입합니다. 특별하고 의미 있는 존재가 되기를 갈망하며, 다른 사람과의 차별성을 중요하게 생각합니다. 감수성이 풍부하고 예술적인 면이 강하지만, 때로는 자신이 이해받지 못한다고 느끼며 고독감을 느낄 수 있습니다.",
"5": "탐구자 (Investigator) - 지식과 통찰력을 얻는 데 관심이 많고, 분석적이며 객관적인 태도를 유지합니다. 개인적인 공간과 시간을 중요하게 생각하며, 지적 호기심을 바탕으로 세상을 이해하려고 합니다. 이들은 자립적이며 정보와 지식을 통해 자신을 보호하려는 경향이 있습니다.",
"6": "충직한 사람 (Loyalist) - 안전과 안정에 대한 욕구가 강하며, 신뢰할 수 있는 대상을 찾고자 합니다. 이들은 공동체에 대한 충성심이 강하고, 불확실한 상황에서 계획을 세워 안전을 확보하려 합니다. 의심과 신뢰 사이에서 균형을 유지하려는 노력을 기울이며, 주변 사람들에게 신뢰할 수 있는 존재가 되고자 합니다.",
"7": "열광자 (Enthusiast) - 즐거움과 모험을 추구하며, 다양한 경험을 통해 만족을 얻습니다. 긍정적이고 열정적이며, 고통이나 부정적인 감정을 피하려는 경향이 있습니다. 미래의 가능성에 집중하며, 항상 새로운 기회를 탐색하고자 합니다.",
"8": "보호자 (Challenger) - 강하고 자기주장이 강하며, 불의에 맞서 싸우는 경향이 있습니다. 자신과 타인을 보호하려 하며, 권위를 두려워하지 않고 자신의 영향력을 행사하려 합니다. 연약함을 드러내는 것을 꺼리며, 강한 모습을 유지하려 합니다.",
"9": "중재자 (Peacemaker) - 조화와 평화를 중시하며, 타인과의 갈등을 피하려고 노력합니다. 내면의 평온을 유지하고자 하며, 수용적이고 이해심이 많습니다. 때로는 자신의 욕구를 무시하고 타인에게 맞추려는 경향이 있으며, 갈등 없는 조화로운 환경을 만들기 위해 노력합니다."
}
# 날개 유형 정보 (설명 고도화 및 형식 변경)
wing_types = {
"1": "w1 - 완벽주의자 날개: 원칙과 기준을 더욱 강조하며, 자기 훈련과 윤리적 행동에 집중합니다.",
"2": "w2 - 도우미 날개: 타인을 돕고 지원하는 경향이 강해지며, 사랑받고 인정받고자 하는 욕구가 더욱 두드러집니다.",
"3": "w3 - 성과자 날개: 목표 달성과 성공에 더욱 집중하며, 성과와 사회적 인정을 중시합니다.",
"4": "w4 - 개인주의자 날개: 개성과 감정의 깊이가 더욱 풍부해지며, 자신만의 독창성을 강하게 추구합니다.",
"5": "w5 - 탐구자 날개: 지적 탐구와 분석적 사고가 강화되며, 정보와 지식을 통해 자신을 보호하려는 경향이 있습니다.",
"6": "w6 - 충직한 사람 날개: 안전과 책임감이 더욱 중요해지며, 신뢰할 수 있는 관계를 구축하려고 합니다.",
"7": "w7 - 열광자 날개: 즐거움과 모험을 더욱 추구하며, 새로운 경험을 통해 만족을 얻으려는 욕구가 커집니다.",
"8": "w8 - 보호자 날개: 자기주장과 통제력이 강해지며, 타인을 보호하고 자신의 권리를 주장하는 데 집중합니다.",
"9": "w9 - 중재자 날개: 조화와 평온을 더욱 중시하며, 갈등을 피하고 타인과의 관계에서 균형을 유지하려고 합니다."
}
# 본능 유형 정보 (설명 고도화)
instinct_variants = {
"sp": "자기보존 본능 - 개인의 안전, 건강, 안락함에 초점을 맞춥니다. 자원 확보와 생존에 관심이 많으며, 안정된 생활을 유지하려고 합니다. 자기 관리를 통해 외부의 위협으로부터 자신을 보호하려 합니다.",
"so": "사회적 본능 - 사회적 관계와 소속감에 중점을 둡니다. 집단 내에서의 역할과 기여를 중요하게 생각하며, 공동체와의 연결을 통해 안정감을 얻으려 합니다. 소속된 그룹에서의 지위와 상호작용이 중요합니다.",
"sx": "성적 본능 - 친밀감과 강렬한 연결을 추구합니다. 매력과 경쟁을 통해 중요한 타인과의 관계를 형성하려 하며, 강한 에너지와 친밀한 관계를 통해 깊이 있는 연결을 갈망합니다."
}
# 관계 유형 (2인 관계와 다인 관계 분리)
relationship_types_two = {
"연인": "Romantic Couple",
"부부": "Married Couple",
"친구": "Friends",
"가족": "Family",
"직장 동료": "Coworkers",
"기타": "Others"
}
relationship_types_multiple = {
"친구": "Friends",
"가족": "Family",
"직장 동료": "Coworkers",
"프로젝트 팀": "Project Team",
"스터디 그룹": "Study Group",
"기타": "Others"
}
# 추가된 기능: 대화형 입력 및 결과 다운로드
def download_results(full_text):
st.download_button(
label="시나리오 다운로드",
data=full_text,
file_name="relationship_scenario.txt",
mime="text/plain"
)
def generate_relationship_scenario(people, relationship, situation):
def create_type_info(person):
type_info = f"{person['name']} ({person['gender']}): {person['type']} ({enneagram_types.get(person['type'], '알 수 없는 유형')})"
# 날개 유형 정보 추가 (값이 있고 빈 문자열이 아닌 경우에만)
if person.get('wing') and person['wing'] not in ["", "없음"]:
wing_description = wing_types.get(person['wing'][0], '알 수 없는 날개 유형')
type_info += f" 날개: {person['wing']} ({wing_description})"
# 본능 유형 정보 추가 (값이 있고 빈 문자열이 아닌 경우에만)
if person.get('instinct') and person['instinct'] not in ["", "없음"]:
type_info += f", 본능: {person['instinct']} ({instinct_variants.get(person['instinct'], '알 수 없는 본능 유형')})"
return type_info
people_info = "\n".join([f"- {create_type_info(person)}" for person in people])
system_prompt = f"""
당신은 에니어그램 전문가이자 관계 코치입니다. 아래 제공된 정보를 바탕으로 관계 시나리오를 작성해주세요. 각 유형의 이름은 해당 유형의 대표적인 성격을 나타내므로, 이름에 지나치게 얽매이지 않고 전체적인 맥락을 반영하여 시나리오를 작성해 주세요.
[대상자 정보]
{people_info}
[관계]
- {relationship}
[상황]
- {situation}
[요청 사항]
1. **각 대상자의 에니어그램 유형에 대한 심층 설명:**
- 각 대상자의 핵심 가치, 성격적 특징, 행동 패턴, 강점과 약점, 그리고 주의할 점 등을 자세히 설명해주세요.
- 에니어그램 유형에 따른 동기와 두려움, 주요 행동 경향 등을 심도 있게 서술해주세요.
2. **에니어그램 유형을 바탕으로 한 구체적인 시나리오 작성:**
- 상황에 맞는 시나리오를 단계별로 작성하고, 각 단계를 구체적인 대화 장면으로 묘사해주세요.
- 각 단계에서 등장인물들의 감정 변화와 반응을 상세히 묘사하고, 각 인물의 말과 행동이 에니어그램 특성과 어떻게 연결되는지 부가 설명해주세요.
- 등장인물 간의 상호작용과 그들이 각자의 유형에서 어떻게 행동하고 반응하는지를 상세히 설명해주세요.
3. **서로 이해하기 위한 실질적인 조언:**
- 각 대상자가 서로의 에니어그램 유형을 이해하고, 더 나은 관계를 형성하기 위한 구체적인 조언을 제시해주세요.
- 조언에 모든 등장인물의 이름, 성별, 에니어그램 유형이 모두 반영되어야 합니다.
- 각 대상자가 다른 대상자에게 해주면 좋은 말과 행동의 구체적인 예와 그 이유도 상세히 설명해주세요.
"""
full_text = ""
try:
response = model.generate_content([system_prompt], stream=True)
for chunk in response:
full_text += chunk.text
html_text = markdown.markdown(full_text)
scenario_output_area.markdown(html_text, unsafe_allow_html=True)
time.sleep(0.05)
except Exception as e:
st.error(f"Error: {str(e)}")
return ""
return full_text
# Streamlit UI
st.set_page_config(page_title="에니어그램 관계 시뮬레이터", page_icon="🤝")
st.title("🤝 에니어그램 관계 시뮬레이터")
st.write("참여자들의 에니어그램 유형, 관계, 상황을 입력하여 관계 시나리오를 생성해보세요.")
# 사이드바에 탭 생성
with st.sidebar:
tabs = st.tabs(["참여자 정보", "관계 및 상황 설정"])
# 참여자 정보 탭
with tabs[0]:
num_people = st.number_input("참여자 수", min_value=2, value=2)
people = []
for i in range(num_people):
with st.expander(f"참여자 {i+1} 정보"):
person = {}
person['name'] = st.text_input(f"이름/닉네임", key=f"name_{i}")
person['gender'] = st.radio("성별", ["남성", "여성"], key=f"gender_{i}")
person['type'] = st.selectbox("에니어그램 유형", list(enneagram_types.keys()), key=f"type_{i}")
person['wing'] = st.selectbox("날개 유형 (선택)", ["없음"] + list(wing_types.keys()), key=f"wing_{i}") # "없음" 선택지 추가
person['instinct'] = st.selectbox("본능 유형 (선택)", ["없음"] + list(instinct_variants.keys()), key=f"instinct_{i}") # "없음" 선택지 추가
people.append(person)
# 관계 및 상황 설정 탭
with tabs[1]:
if num_people == 2:
relationship = st.selectbox("관계 유형", list(relationship_types_two.keys()))
else:
relationship = st.selectbox("관계 유형", list(relationship_types_multiple.keys()))
situation = st.text_area("상황 (예: 갈등 상황, 특별한 이벤트 등)", height=150)
# 메인 영역 - 출력 및 버튼
generate_button = st.button("시나리오 생성 ➡️")
scenario_output_area = st.empty()
if generate_button:
full_text = generate_relationship_scenario(people, relationship, situation)
if full_text:
scenario_output_area.markdown(markdown.markdown(full_text), unsafe_allow_html=True)
download_results(full_text)