Skip to content

Commit 446f6ce

Browse files
authored
배포 v1.7.6
배포 v1.7.6
2 parents fe099c4 + c7cb91f commit 446f6ce

File tree

4 files changed

+41
-17
lines changed

4 files changed

+41
-17
lines changed

MLOps/app/routers/recommendation.py

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from fastapi import APIRouter, HTTPException
1+
from fastapi import APIRouter, HTTPException, Depends
22
from fastapi.responses import JSONResponse
33
import traceback
44
from app.schema.recommendation_schema import ReccomendRequest, ReccomendResponse
@@ -7,14 +7,30 @@
77

88
router = APIRouter(prefix="/api", tags=["recommendation"])
99

10-
# 서비스 초기화
11-
elk_client = ELKClient()
12-
deepctr_service = DeepCTRService()
10+
def services_provider():
11+
"""ELKClient, DeepCTRService 를 최초 호출 시 생성해 캐시합니다.
12+
생성 과정에서 예외가 나면 None 을 반환해 API 가 503 을 응답하도록 합니다."""
13+
if not hasattr(services_provider, "cache"):
14+
try:
15+
services_provider.cache = (ELKClient(), DeepCTRService())
16+
except Exception as e:
17+
print("[recommendation] 서비스 초기화 실패:", e)
18+
services_provider.cache = None
19+
return services_provider.cache
1320

1421
@router.get("/recommend", response_model=ReccomendResponse)
15-
async def recommend_places(userid: str, query: str):
22+
async def recommend_places(
23+
userid: str,
24+
query: str,
25+
services=Depends(services_provider)
26+
):
1627
"""Place ID 리스트 기반 추천 API"""
1728
try:
29+
if services is None:
30+
raise HTTPException(status_code=503, detail="Recommendation service not available")
31+
32+
elk_client, deepctr_service = services
33+
1834
top_places_data, other_places_data = await deepctr_service.rank_places_by_ctr(userid, query)
1935

2036
# 스키마에 맞게 데이터 형식 변환
@@ -41,9 +57,16 @@ async def recommend_places(userid: str, query: str):
4157
@router.get("/recommend/health")
4258
async def recommendation_health():
4359
"""추천 시스템 헬스체크"""
60+
services = services_provider()
61+
status = "healthy" if services else "unhealthy"
62+
elk_ready = deepctr_ready = "not ready"
63+
if services:
64+
elk_ready = "ready"
65+
deepctr_ready = "ready"
66+
4467
return {
45-
"status": "healthy" if (deepctr_service and elk_client) else "unhealthy",
46-
"elk_client": "ready" if elk_client else "not ready",
47-
"deepctr_service": "ready" if deepctr_service else "not ready",
68+
"status": status,
69+
"elk_client": elk_ready,
70+
"deepctr_service": deepctr_ready,
4871
"service": "recommendation"
4972
}

MLOps/app/services/deepctr_service.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,15 @@ async def rank_places_by_ctr(self, userid: str, query: str):
4040
places_df[col] = val
4141
else:
4242
# 사용자가 존재하지 않을 경우, 기본값으로 채움
43+
print("사용자가 존재하지 않습니다.")
4344
places_df['userid'] = userid
44-
places_df['place_name'] = 'unknown'
45+
places_df['name'] = 'unknown'
4546
places_df['age'] = 30 # 평균 또는 기본값
4647
places_df['gender'] = 1 # 남성을 기본값으로 가정
4748
places_df['like_list'] = "[]"
4849

4950
# 원본 데이터에서 응답에 필요한 컬럼 보존
50-
output_columns = ['place_id', 'category', 'subcategory']
51+
output_columns = ['place_id', 'place_name', 'category', 'subcategory']
5152
preserved_df = places_df[output_columns]
5253

5354
# 모델 예측

MLOps/app/services/langchain_agent_service.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,8 @@ async def search_with_filtering(query: str, place_uuids: List[str]) -> List[Dict
103103
"""
104104
임베딩 검색 도구
105105
106-
입력받은 UUID 리스트와 사용자의 쿼리문(query)을 기반으로,
107-
메타데이터 필터링 및 임베딩 유사도 검색을 수행하여 관련 장소 정보를 반환합니다.
106+
입력받은 UUID 리스트와 사용자의 쿼리문 만을 기반으로,
107+
임베딩 유사도 검색을 수행하여 관련 장소 정보를 반환합니다.
108108
109109
Args:
110110
query (str): 사용자가 입력한 쿼리문 (예: '홍대에서 감성 카페 갔다가 전시 보는 코스 추천')
@@ -164,15 +164,15 @@ def _create_prompt_template(self):
164164
- **3. 성공 시 코스 추천**:
165165
* 도구 검색에 성공하면, `placeid`에는 추천 장소들의 UUID를, `str` 필드에는 [str 필드 작성 규칙]에 따라 생성된 추천 코스 설명을 담아 JSON을 출력합니다.
166166
* 사용자가 할 일에 대해서, 각각 하나의 장소만을 추천해서 코스를 구성합니다. 예를 들어서, 사용자가 카페와 쇼핑을 하고 싶다면 카페 카테고리에서 하나를 추천하고, 쇼핑 카테고리에서 하나를 추천합니다.
167-
* 반드시 `placeid` 배열에 포함된 `UUID`와 `str` 필드에서 설명하는 장소가 정확히 일치해야 합니다.
167+
* 반드시 `placeid` 배열에 포함된 `UUID`와 `str` 필드에서 설명하는 장소가 정확히 일치해야 합니다. 이 조건이 충족되지 않을 경우, 매우 높은 확률로 사용자가 불만을 표시할 것입니다.
168168
* 반드시 카테고리 별로 하나씩만 추천합니다.
169-
- **4. 코스 수정 요청**:
170-
* 사용자가 코스 수정을 요청하면 장소 후보를 몇 군데 제시한 후 고르도록 하세요.
171-
* 이 경우, `placeid`는 항상 빈 리스트 `[]`입니다.
172169
173170
[도구 사용 규칙]
171+
- 도구 사용 전에 반드시 사용자의 쿼리문을 이해하고, 사용자가 원하는 할 일을 사용 가능한 전체 카테고리 중 하나로 매칭해야 합니다.
172+
- 이후, 카테고리가 다수인 경우, 카테고리 별로 다르게 도구를 사용해야 합니다.
174173
- **'지역'과 '할 일'이 대화 전체를 통해 명확하게 확정되었을 때만 도구를 사용합니다.**
175174
- 사용자가 이전에 말한 '할 일'을 기억했다가, 새로운 지역을 말하면 해당 지역에서 이전에 원했던 '할 일'을 찾아야 합니다.
175+
- 사용자가 수정을 원하면 장소 후보를 몇 군데 제시한 후 고르도록 하세요.
176176
177177
[str 필드 작성 규칙 - 중요: RAG 데이터만 사용]
178178
- **절대적 제약사항**: 장소에 대한 모든 정보(이름, 주소, 설명 등)는 반드시 도구 검색을 통해 얻은 데이터베이스 정보만을 사용해야 합니다. 당신의 사전 지식이나 추측으로 장소 정보를 보완하거나 추가해서는 안 됩니다.

data/chroma_db_bge.dvc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
outs:
2-
- md5: 132420dfd0e4858c9fa198af4c30eb0c.dir
2+
- md5: ccb19a5fbbeeba0a26668b071dd9b62d.dir
33
nfiles: 6
44
hash: md5
55
path: chroma_db_bge

0 commit comments

Comments
 (0)