Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 31 additions & 31 deletions service/auto.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,10 @@ def post_summary_update(

except json.JSONDecodeError as e:
raise ValueError(f"요약 JSON 파싱 실패: {e}")

summaries = payload["summaries"]
new_prefs_list = payload["persona"]
prefs_map = { p["id"]: p.get("preferences", []) for p in new_prefs_list }
prefs_map = {p["id"]: p.get("preferences", []) for p in new_prefs_list}

merged_personas = []
for person in parsed_summary.persona:
Expand All @@ -74,7 +74,7 @@ def post_summary_update(
combined = list(dict.fromkeys(person.preferences + new_prefs))
person.preferences = combined
merged_personas.append(person.model_dump())

body = {
"roomId": parsed_summary.roomId,
"persona": merged_personas,
Expand All @@ -91,18 +91,24 @@ def post_summary_update(
def summary_prompt(response) -> list[dict]:

# open ai에 질의 메시지
# 1. health_status -> 노인이 건강 상의 이유로 스마트폰 조작 시 어려움을 파악
# 2. hobbies_and_interests -> 취미, 흥미를 파악
# 3. relationship_context -> 청년과 어르신신 관계를 파악
# 4. digital_skill_focus -> 당일 배우거나 다룬 기능이나 앱 요약: ex) “카톡 사진 묶어서 전송”, “네이버 지도 경로 저장”
# 5. learning_challenge -> 여전히 어르신이 어려워하거나 막힌 지점: ex) “카드 등록 실패 오류 940”, “앱 업데이트 용량 부족”

main_prompt_content = f"""
### ROLE
너는 오늘 채팅방의 내용을 매우 심도있게 분석하여 요약하는 것이 역할이다.
첫 번째 역할은 두 사람이 오늘 나눈 대화 내역(today_messages)을 6개의 주제에 대화 내역에서 추출하여 각각 요약해야한다.
첫 번째 역할은 두 사람이 오늘 나눈 대화 내역(today_messages)을 5개의 주제에 대화 내역에서 추출하여 각각 요약해야한다.
두 번째 역할은 두 사람이 오늘 나눈 대화 내역와 요약의 hobbies_and_interests 주제에서 각 사용자가 선호하는 것을 1~3가지 정도를 키워드 추출하여 각 사용자의 persona의 이미 있는 내용을 preferences 리스트 맨 뒤에 추가만 해야한다.
6개의 주제는 다음과 같다.
1. health_status
2. hobbies_and_interests
3. emotional_and_mental_state
4. relationship_context
5. social_activitie
6. intimacy
5개의 주제는 다음과 같다.
# 1. health_status -> 어르신 건강 상의 이유로 스마트폰 조작 시 어려움을 파악: ex) “눈이 침침”, “스마트폰 터치가 어려움”
# 2. hobbies_and_interests -> 취미, 흥미를 파악: ex) “노래 듣기”, “바둑 게임”
# 3. relationship_context -> 청년과 어르신 관계를 파악: ex) “아직 어색”, “친밀”,
# 4. digital_skill_focus -> 당일 배우거나 다룬 기능이나 앱 요약: ex) “카톡 사진 묶어서 전송”, “네이버 지도 경로 저장”
# 5. learning_challenge -> 여전히 어르신이 어려워하거나 막힌 지점: ex) “카드 등록 실패 오류 940”, “앱 업데이트 용량 부족”


### 요약
{response.summaries}
Expand All @@ -115,7 +121,7 @@ def summary_prompt(response) -> list[dict]:


### TASK
1) 오늘 나눈 대화 내역을 읽고, 6개의 주제에 대한 내용을 추출하여 한 문장으로 요약한다.
1) 오늘 나눈 대화 내역을 읽고, 5개의 주제에 대한 내용을 추출하여 한 문장으로 요약한다.
2) 만일 일부 주제에 대한 내용을 추출할 내용을 없을 시에는 "주제에 대한 대화 없음"이라고 저장한다.
3) 반드시 기존에 있는 요약 내용에 추가하는 것이다. 대답할 때 오늘 나눈 대화 내역에서 각 주제에 추출한 내용을 이미 있는 내용에 day리스트 맨 뒤에 추가만 할 것.
4) {datetime.now()}가 현재 시각임으로 last_update에 반영할 것.
Expand All @@ -135,11 +141,11 @@ def summary_prompt(response) -> list[dict]:
"persona": [
{{
"id": {response.persona[0].id},
"preferences": [/* A 어르신 선호 키워드 리스트 */]
"preferences": [/* 청년 선호 키워드 리스트 */]
}},
{{
"id": {response.persona[1].id},
"preferences": [/* B 어르신 선호 키워드 리스트 */]
"preferences": [/* 어르신 선호 키워드 리스트 */]
}}
]
}}
Expand All @@ -148,7 +154,7 @@ def summary_prompt(response) -> list[dict]:
return [
{
"role": "system",
"content": "너는 어르신 채팅방을 세밀하게 분석하여 요약하는 봇이자 사용자의 선호도를 찾아내는 봇이다.",
"content": "너는 청년과 어르신이 있는 채팅방을 세밀하게 분석하여 요약하는 봇이자 사용자의 선호도를 찾아내는 봇이다.",
},
{"role": "user", "content": main_prompt_content},
]
Expand All @@ -159,27 +165,26 @@ def weekly_summary_scheduler() -> None:

for room in rooms:
room_id = room["_id"]
resp = get_summary(room_id) # Response
resp = get_summary(room_id)
summary_obj: AssistantSummary = AssistantSummary.model_validate(resp.json())

topics = [
"health_status",
"hobbies_and_interests",
"emotional_and_mental_state",
"relationship_context",
"social_activities",
"intimacy",
"digital_skill_focus",
"learning_challenge",
]

today = datetime.now()
week_start = (today - timedelta(days=6)).strftime("%m-%d")
week_end = today.strftime("%m-%d")
week_of_month = (today.day - 1) // 7 + 1
week_label = f"{today.month}월 {week_of_month}주차"
# 4) GPT 프롬프트 구성

prompt = f"""
지난 일주일({week_start} ~ {week_end}) 각 주제별로 day 리스트에 쌓인 항목을 읽고,
각 주제에 대해 한 문장으로 요약해라라
각 주제에 대해 한 문장으로 요약해라
- 입력 데이터(딕셔너리):
{{
"""
Expand Down Expand Up @@ -241,10 +246,9 @@ def monthly_summary_scheduler() -> None:
topics = [
"health_status",
"hobbies_and_interests",
"emotional_and_mental_state",
"relationship_context",
"social_activities",
"intimacy",
"digital_skill_focus",
"learning_challenge",
]

for room in rooms:
Expand Down Expand Up @@ -293,7 +297,6 @@ def get_reply(messages) -> str:
OpenAI.api_key = os.getenv("OPENAI_API_KEY")
client = OpenAI(api_key=OpenAI.api_key)

# gpt에 요청
gpt_response = client.chat.completions.create(
model="gpt-4o",
messages=messages,
Expand All @@ -311,10 +314,9 @@ def yearly_summary_scheduler() -> None:
topics = [
"health_status",
"hobbies_and_interests",
"emotional_and_mental_state",
"relationship_context",
"social_activities",
"intimacy",
"digital_skill_focus",
"learning_challenge",
]

for room in rooms:
Expand Down Expand Up @@ -350,7 +352,6 @@ def yearly_summary_scheduler() -> None:
"summaries": summaries_json,
}

# 6) chat 서버에 업데이트
requests.post(
f"{settings.CHAT_SERVER_URL}/summary/update", json=body, timeout=5
).raise_for_status()
Expand All @@ -363,9 +364,8 @@ def yearly_summary_scheduler() -> None:
(
"daily_summary_job",
fetch_roomList,
dict(hour=18, minute=45, second=00),
dict(hour=2, minute=00, second=00),
), # 매일 02:00:00

(
"weekly_summary_job",
weekly_summary_scheduler,
Expand Down
21 changes: 14 additions & 7 deletions service/summary.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,10 @@ class _SummaryPeriod(BaseModel):

class Summaries(BaseModel):
health_status: _SummaryPeriod
emotional_and_mental_state: _SummaryPeriod
hobbies_and_interests: _SummaryPeriod
relationship_context: _SummaryPeriod
social_activities: _SummaryPeriod
intimacy: _SummaryPeriod
digital_skill_focus: _SummaryPeriod
learning_challenge: _SummaryPeriod


class Sender(BaseModel):
Expand Down Expand Up @@ -78,17 +77,23 @@ def user_prompt(response, userId) -> list[dict]:

# 현재 대화추천을 요청한 사용자가 누구인지 판단하는 로직
id = userId
prompt_pick = "너는 청년의 입장에서 어르신의 스마트폰 기기 사용법을 알려주기 위해 최선을 다하도록 성심 성의껏 답변을 해야한다."
if userId == response.persona[0].id:
speaker = response.persona[0].name
speaker_speech_style = response.persona[0].speech_style
prompt_pick = "너는 청년의 입장에서 어르신의 스마트폰 기기 사용법을 알려주기 위해 어르신이 무엇을 모르는지 최근 대화 내용을 보고 파악하여 최선을 다하여 성심 성의껏 답변을 해야한다."
else:
speaker = response.persona[1].name
speaker_speech_style = response.persona[1].speech_style
prompt_pick = "너는 어르신의 입장에서 청년에게 스마트폰 기기 사용법을 어떻게 물어보면 쉽게 물어볼지 최근 대화를 보고 파악하여 최선을 다하여 성심 성의껏 생각하고 질문이나 답변을 해야한다."

# open ai에 질의 메시지
user_content = f"""
### ROLE
이번 문장은 {speaker}의 말투({speaker_speech_style})로 작성한다.
특별한 말투가 없다면 존맛말을 사용하여 작성하라.
{prompt_pick}


### CRITICAL_FLAGS
{response.persona[0].name}의 {response.persona[0].critical_flags}
Expand All @@ -102,21 +107,23 @@ def user_prompt(response, userId) -> list[dict]:

### TASK
1) 상황 파악 → 사고 단계 기록
2) {speaker} 입장에서 한 문장 작성
3) JSON 만 출력
2) 반드시 요약에서 2개의 주제 "digital_skill_focus"와 "learning_challenge"를 먼저 파악하라.
3) 최근 대화에 가장 많은 비중을 두어 {speaker} 입장에서 마지막 발화에 자연스럽게 이어질 **한 문장**을 작성해야 한다.
3) 나머지 요약 내용도 최근 대화에 필요한 내용이라면 참고하여 최고의 한 문장으로 작성해라.
4) 문장을 총 7개 제안 → 셀프체크 후 3개 → 최종 1개 제안
5) JSON 만 출력
json
{{ "reply": "..." }}
"""
return [
{
"role": "system",
"content": "너는 한국어 어르신 대화 코치이다. 두 어르신의 건강을 고려해 한 문장으로 답한다.",
"content": "너는 청년과 노인이 멘토 멘티가 되어서 채팅방에서 대화를 나누도록 도움을 주는 코치이다. 원활한 소통을 위해 대화를 이어나갈 최고의 한 문장으로 답한다.",
},
{"role": "user", "content": user_content},
]



### OpenAI 호출
def get_reply(response, userId) -> str:

Expand Down