Fix age calculation: inject today's date, add Korean/international age

- Prepend today's date to system prompt on every call so LLM uses correct year
- Calculate both Korean age (현재연도-출생연도+1) and 만 나이 with exact birthday handling
- Support full date (생년월일) and year-only (생년) profile values
- Update remember_user_info to encourage storing full birth date
- Strengthen get_current_date tool description for age-related queries

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
sal
2026-05-27 15:10:30 +09:00
parent 06bcdb03ac
commit b4b628ab78
3 changed files with 39 additions and 6 deletions
+7
View File
@@ -54,6 +54,13 @@ class Config(BaseSettings):
항상 쉽고 친근한 말투로 설명하고, 전문 용어는 풀어서 설명합니다. 항상 쉽고 친근한 말투로 설명하고, 전문 용어는 풀어서 설명합니다.
의학적 진단이나 법적 판단이 필요한 경우에는 반드시 전문가 상담을 권유합니다. 의학적 진단이나 법적 판단이 필요한 경우에는 반드시 전문가 상담을 권유합니다.
## 사용자 정보 기억 규칙
대화 중 사용자가 가족(아이 이름·생년, 배우자, 자녀 수 등), 직업, 거주지, 재정 목표, 건강 상황 등 개인 정보를 언급하면 즉시 remember_user_info로 저장하세요.
- 아이 나이는 생년월일 전체를 저장합니다. (예: key='첫째_이름' value='신도율' / key='첫째_생년월일' value='2020년 6월 19일')
- 사용자 정보 섹션에 나이가 표시되어 있으면 그 값을 그대로 사용하세요. 직접 계산하지 마세요.
- 나이를 직접 계산해야 할 경우에는 반드시 get_current_date 도구를 먼저 호출하여 오늘 날짜를 확인하세요.
- 나이는 항상 한국 나이와 만 나이를 함께 알려주세요. (한국 나이 = 현재 연도 - 출생 연도 + 1 / 만 나이 = 생일이 지났으면 현재 연도 - 출생 연도, 생일이 안 지났으면 -1)
## 문서 검색 규칙 ## 문서 검색 규칙
육아·금융 관련 질문이라면 자신의 학습 지식으로 직접 답하지 말고, 반드시 search_documents 도구를 먼저 호출하세요. 육아·금융 관련 질문이라면 자신의 학습 지식으로 직접 답하지 말고, 반드시 search_documents 도구를 먼저 호출하세요.
검색 결과가 없거나 관련 문서가 등록되어 있지 않은 경우에만 학습 지식을 보조적으로 활용합니다.""" 검색 결과가 없거나 관련 문서가 등록되어 있지 않은 경우에만 학습 지식을 보조적으로 활용합니다."""
+28 -3
View File
@@ -74,12 +74,37 @@ class AgentService:
llm_with_tools = chat_model.bind_tools(tools) llm_with_tools = chat_model.bind_tools(tools)
async def call_model(state: MessagesState, config: RunnableConfig) -> dict: async def call_model(state: MessagesState, config: RunnableConfig) -> dict:
system_content = self._system_prompt from datetime import date
system_content = f"오늘 날짜: {date.today().isoformat()}\n\n" + self._system_prompt
if self._profile_repo: if self._profile_repo:
profile = self._profile_repo.get_all(self._user_id) profile = self._profile_repo.get_all(self._user_id)
if profile: if profile:
lines = "\n".join(f"- {k}: {v}" for k, v in profile.items()) import re
system_content += f"\n\n## 사용자 정보 (이전 대화에서 기억된 내용)\n{lines}" from datetime import date
today = date.today()
current_year = today.year
_DATE_KEYS = ("생년월일", "생년", "생일")
lines = []
for k, v in profile.items():
if any(term in k for term in _DATE_KEYS):
full_date = re.search(r'(\d{4})[년\-/.]\s*(\d{1,2})[월\-/.]\s*(\d{1,2})', v)
year_only = re.search(r'\b(19|20)\d{2}\b', v)
age_key = re.sub(r'생년월일|생년|생일', '나이', k)
if full_date:
by, bm, bd = int(full_date.group(1)), int(full_date.group(2)), int(full_date.group(3))
korean_age = current_year - by + 1
intl_age = current_year - by - (1 if today < date(current_year, bm, bd) else 0)
lines.append(f"- {age_key}: 한국 나이 {korean_age}세, 만 {intl_age}")
elif year_only:
by = int(year_only.group())
korean_age = current_year - by + 1
intl_age = current_year - by
lines.append(f"- {age_key}: 한국 나이 {korean_age}세, 만 {intl_age}~{intl_age - 1}세 (생일에 따라 다름)")
else:
lines.append(f"- {k}: {v}")
else:
lines.append(f"- {k}: {v}")
system_content += f"\n\n## 사용자 정보 (이전 대화에서 기억된 내용)\n" + "\n".join(lines)
msgs = [SystemMessage(content=system_content)] + state["messages"] msgs = [SystemMessage(content=system_content)] + state["messages"]
thinking_acc, content_acc, tool_calls_acc = "", "", [] thinking_acc, content_acc, tool_calls_acc = "", "", []
async for chunk in llm_with_tools.astream(msgs, config): async for chunk in llm_with_tools.astream(msgs, config):
+4 -3
View File
@@ -5,7 +5,7 @@ from langchain_core.tools import tool
@tool @tool
def get_current_date() -> str: def get_current_date() -> str:
"""오늘 날짜를 반환합니다. 날짜·기간 관련 질문에 사용하세요.""" """오늘 날짜를 반환합니다. 나이 계산, 날짜 비교 등 현재 날짜가 필요할 때 반드시 먼저 호출하세요."""
return date.today().isoformat() return date.today().isoformat()
@@ -48,8 +48,9 @@ def make_memory_tools(profile_repo, user_id: str = "default"):
@tool @tool
def remember_user_info(key: str, value: str) -> str: def remember_user_info(key: str, value: str) -> str:
"""사용자 정보를 영구 저장합니다. 다음 대화에도 기억해야 할 정보를 저장하세요. """사용자 정보를 영구 저장합니다. 다음 대화에도 기억해야 할 정보를 저장하세요.
- 아이 나이는 반드시 '생년(출생연도)'으로 저장하세요. 나이는 매년 바뀌지만 생년은 영구적입니다. - 아이 생년월일은 전체 날짜로 저장하세요. 날짜를 모르면 연도만이라도 저장하세요.
예: key='첫째_이름' value='신도율', key='첫째_생년' value='2020' 예: key='첫째_이름' value='신도율', key='첫째_생년월일' value='2020년 6월 19일'
연도만 알 경우: key='첫째_생년' value='2020'
- 기타 key 예시: 재정_목표, 거주지, 직업, 자녀수""" - 기타 key 예시: 재정_목표, 거주지, 직업, 자녀수"""
profile_repo.remember(key, value, user_id=user_id) profile_repo.remember(key, value, user_id=user_id)
return f"'{key}' 정보를 기억했습니다: {value}" return f"'{key}' 정보를 기억했습니다: {value}"