diff --git a/app/database/chroma_db.py b/app/database/chroma_db.py index 9af2466..2351fee 100644 --- a/app/database/chroma_db.py +++ b/app/database/chroma_db.py @@ -10,7 +10,7 @@ import os import datetime from dotenv import load_dotenv -from app.dto.db_dto import AddScheduleDTO, RecommendationMainRequestDTO +from app.dto.db_dto import AddScheduleDTO, RecommendationMainRequestDTO, ReportTagsRequestDTO load_dotenv() CHROMA_DB_IP_ADDRESS = os.getenv("CHROMA_DB_IP_ADDRESS") @@ -48,10 +48,13 @@ async def search_db_query(query): # 스프링 백엔드로부터 chroma DB에 저장할 데이터를 받아 DB에 추가한다. async def add_db_data(schedule_data: AddScheduleDTO): schedule_date = schedule_data.schedule_datetime_start.split("T")[0] + year = int(schedule_date.split("-")[0]) + month = int(schedule_date.split("-")[1]) + date = int(schedule_date.split("-")[2]) schedules.add( documents=[schedule_data.data], ids=[str(schedule_data.schedule_id)], - metadatas=[{"date": schedule_date, "datetime_start": schedule_data.schedule_datetime_start, "datetime_end": schedule_data.schedule_datetime_end, "member": schedule_data.member_id, "category": schedule_data.category, "location": schedule_data.location, "person": schedule_data.person}] + metadatas=[{"year": year, "month": month, "date": date, "datetime_start": schedule_data.schedule_datetime_start, "datetime_end": schedule_data.schedule_datetime_end, "member": schedule_data.member_id, "category": schedule_data.category, "location": schedule_data.location, "person": schedule_data.person}] ) return True @@ -62,6 +65,9 @@ async def db_daily_schedule(user_data: RecommendationMainRequestDTO): schedule_datetime_start = user_data.schedule_datetime_start schedule_datetime_end = user_data.schedule_datetime_end schedule_date = schedule_datetime_start.split("T")[0] + year = int(schedule_date.split("-")[0]) + month = int(schedule_date.split("-")[1]) + date = int(schedule_date.split("-")[2]) persona = user_data.user_persona or "hard working" results = schedules.query( query_texts=[persona], @@ -69,7 +75,38 @@ async def db_daily_schedule(user_data: RecommendationMainRequestDTO): where={"$and": [ {"member": {"$eq": int(member)}}, - {"date": {"$eq": schedule_date}} + {"year": {"$eq": year}}, + {"month": {"$eq": month}}, + {"date": {"$eq": date}} + ] + } + # where_document={"$contains":"search_string"} # optional filter + ) + return results['documents'] + +# 태그 생성용 스케쥴 반환 - 카테고리에 따라 +async def db_monthly_tag_schedule(user_data: ReportTagsRequestDTO): + member = user_data.member_id + schedule_datetime_start = user_data.schedule_datetime_start + schedule_datetime_end = user_data.schedule_datetime_end + schedule_date = schedule_datetime_start.split("T")[0] + year = int(schedule_date.split("-")[0]) + month = int(schedule_date.split("-")[1]) + date = int(schedule_date.split("-")[2]) + persona = user_data.user_persona or "hard working" + results = schedules.query( + query_texts=[persona], + n_results=15, + where={"$and": + [ + {"member": {"$eq": int(member)}}, + {"year": {"$eq": year}}, + {"$or": + [{"$and": + [{"month": {"$eq": month-1}}, {"date": {"$gte": 10}}]}, + {"$and": + [{"month": {"$eq": month}}, {"date": {"$lt": 10}}]} + ]} ] } # where_document={"$contains":"search_string"} # optional filter diff --git a/app/dto/db_dto.py b/app/dto/db_dto.py index ed7e916..1f85ab9 100644 --- a/app/dto/db_dto.py +++ b/app/dto/db_dto.py @@ -22,3 +22,10 @@ class ReportMemoryEmojiRequestDTO(BaseModel): user_persona: str schedule_datetime_start: str schedule_datetime_end: str + +class ReportTagsRequestDTO(BaseModel): + member_id: int + user_persona: str + schedule_datetime_start: str + schedule_datetime_end: str + diff --git a/app/dto/openai_dto.py b/app/dto/openai_dto.py index cfa374f..f002b2a 100644 --- a/app/dto/openai_dto.py +++ b/app/dto/openai_dto.py @@ -9,4 +9,7 @@ class ChatResponse(BaseModel): class ChatCaseResponse(BaseModel): ness: str - case: int \ No newline at end of file + case: int + +class TagsResponse(BaseModel): + tags: list \ No newline at end of file diff --git a/app/prompt/openai_config.ini b/app/prompt/openai_config.ini index 8a62d43..3627abb 100644 --- a/app/prompt/openai_config.ini +++ b/app/prompt/openai_config.ini @@ -11,4 +11,9 @@ MODEL_NAME = gpt-4 [NESS_RECOMMENDATION] TEMPERATURE = 0 MAX_TOKENS = 2048 -MODEL_NAME = gpt-3.5-turbo-1106 \ No newline at end of file +MODEL_NAME = gpt-3.5-turbo-1106 + +[NESS_TAGS] +TEMPERATURE = 0 +MAX_TOKENS = 2048 +MODEL_NAME = gpt-4 \ No newline at end of file diff --git a/app/prompt/report_prompt.py b/app/prompt/report_prompt.py index d1e8648..db30572 100644 --- a/app/prompt/report_prompt.py +++ b/app/prompt/report_prompt.py @@ -14,4 +14,22 @@ class Template: User schedule: {schedule} AI Recommendation: + """ + + report_tags_template = """ + You are an AI assistant tasked with analyzing a user's schedule over the span of a month. From this detailed schedule, you will distill three keywords that best encapsulate the user's activities, interests, or achievements throughout the month. These keywords should not only reflect the user's endeavors but also convey a sense of accomplishment and enjoyment. Your output should be engaging, showcasing your wit and unique perspective. Here are the rules for your analysis: + + YOU MUST USE {output_language} TO RESPOND TO THE INPUT. + YOU MUST PROVIDE THREE KEYWORDS in your response. Each keyword should be a single word or a concise phrase. + The keywords must capture the essence of the user's monthly activities, highlighting aspects that are both rewarding and enjoyable. + Your selections should be creative and personalized, aiming to reflect the user's unique experiences over the month. + Example: + User's monthly schedule: [Attended a programming bootcamp, Completed a marathon, Read three novels, Volunteered at the local food bank, Started a blog about sustainability] + AI Recommendation: "공부 매니아, 환경 지킴이, 자기 계발 홀릭" + + User's monthly schedule: [Took photography classes, Explored three new hiking trails, Organized a neighborhood clean-up, Experimented with vegan recipes] + AI Recommendation: "모험가, 미식가, 도파민 중독자" + + User's monthly schedule: {schedule} + AI Recommendation: """ \ No newline at end of file diff --git a/app/routers/report.py b/app/routers/report.py index 8e272f6..dc295f3 100644 --- a/app/routers/report.py +++ b/app/routers/report.py @@ -6,8 +6,8 @@ from langchain_community.chat_models import ChatOpenAI from langchain_core.prompts import PromptTemplate -from app.dto.db_dto import ReportMemoryEmojiRequestDTO -from app.dto.openai_dto import ChatResponse +from app.dto.db_dto import ReportMemoryEmojiRequestDTO, ReportTagsRequestDTO +from app.dto.openai_dto import ChatResponse, TagsResponse from app.prompt import report_prompt import app.database.chroma_db as vectordb @@ -53,3 +53,33 @@ async def get_memory_emoji(user_data: ReportMemoryEmojiRequestDTO) -> ChatRespon except Exception as e: raise HTTPException(status_code=500, detail=str(e)) +@router.post("/tags", status_code=status.HTTP_200_OK) +async def get_tags(user_data: ReportTagsRequestDTO) -> TagsResponse: + try: + # 모델 + config_tags = config['NESS_TAGS'] + + chat_model = ChatOpenAI(temperature=config_tags['TEMPERATURE'], # 창의성 (0.0 ~ 2.0) + max_tokens=config_tags['MAX_TOKENS'], # 최대 토큰수 + model_name=config_tags['MODEL_NAME'], # 모델명 + openai_api_key=OPENAI_API_KEY # API 키 + ) + + # vectordb에서 유저의 정보를 가져온다. + schedule = await vectordb.db_monthly_tag_schedule(user_data) + + print(schedule) + + # 템플릿 + report_tags_template = report_prompt.Template.report_tags_template + + prompt = PromptTemplate.from_template(report_tags_template) + result = chat_model.predict(prompt.format(output_language="Korean", schedule=schedule)) + print(result) + tags = result.split("\"")[1].split(",") + tags = [tag.strip() for tag in tags] + print(tags) + return TagsResponse(tags=tags) + + except Exception as e: + raise HTTPException(status_code=500, detail=str(e)) \ No newline at end of file