Spaces:
Paused
Paused
로그 제거
Browse files
app.py
CHANGED
|
@@ -12,14 +12,13 @@ DEFAULT_FULL_WEIGHT = 0.2
|
|
| 12 |
DEFAULT_TOPIC_WEIGHT = 0.5
|
| 13 |
DEFAULT_CUSTOMER_WEIGHT = 0.2
|
| 14 |
DEFAULT_AGENT_WEIGHT = 0.1
|
| 15 |
-
DEFAULT_SIMILARITY_THRESHOLD = 0
|
| 16 |
|
| 17 |
# OpenAI 클라이언트 초기화
|
| 18 |
client = OpenAI()
|
| 19 |
|
| 20 |
# DB 연결 설정
|
| 21 |
def get_db_conn():
|
| 22 |
-
"""PostgreSQL 데이터베이스에 연결합니다."""
|
| 23 |
return psycopg2.connect(
|
| 24 |
host=os.environ["VECTOR_HOST"],
|
| 25 |
port=5432,
|
|
@@ -30,7 +29,7 @@ def get_db_conn():
|
|
| 30 |
|
| 31 |
def get_embedding(text: str) -> List[float]:
|
| 32 |
"""
|
| 33 |
-
텍스트를 OpenAI의 text-embedding-
|
| 34 |
Java의 float[](float32)와 호환되도록 명시적으로 float32로 변환합니다.
|
| 35 |
|
| 36 |
Args:
|
|
@@ -54,7 +53,6 @@ def get_embedding(text: str) -> List[float]:
|
|
| 54 |
def format_vector_for_pg(vector: List[float]) -> str:
|
| 55 |
"""
|
| 56 |
임베딩 벡터를 PostgreSQL 포맷으로 변환합니다.
|
| 57 |
-
Java의 formatVectorForPg() 메소드와 동일한 기능입니다.
|
| 58 |
입력된 벡터가 float32 타입인지 확인합니다.
|
| 59 |
"""
|
| 60 |
# 벡터가 float32 타입인지 확인하고, 아니면 변환
|
|
@@ -63,8 +61,6 @@ def format_vector_for_pg(vector: List[float]) -> str:
|
|
| 63 |
vector = np.array(vector, dtype=np.float32)
|
| 64 |
elif vector.dtype != np.float32:
|
| 65 |
vector = vector.astype(np.float32)
|
| 66 |
-
|
| 67 |
-
# 자바 구현과 동일하게 StringBuilder 방식으로 구현
|
| 68 |
vector_str = ','.join([f"{x}" for x in vector])
|
| 69 |
return f"[{vector_str}]"
|
| 70 |
|
|
@@ -97,8 +93,6 @@ def search_similar_chat(query: str, max_results: int = 100) -> List[Dict]:
|
|
| 97 |
agent_w = DEFAULT_AGENT_WEIGHT
|
| 98 |
threshold = DEFAULT_SIMILARITY_THRESHOLD
|
| 99 |
|
| 100 |
-
print(f"다중 임베딩 검색 시작: 쿼리='{query}', 가중치=(full={full_w}, topic={topic_w}, customer={customer_w}, agent={agent_w}), 최대 결과={limit}")
|
| 101 |
-
|
| 102 |
try:
|
| 103 |
# 쿼리 임베딩 생성
|
| 104 |
query_embedding = get_embedding(query)
|
|
@@ -138,14 +132,9 @@ def search_similar_chat(query: str, max_results: int = 100) -> List[Dict]:
|
|
| 138 |
""" % (query_vector, full_w, query_vector, topic_w, query_vector, customer_w, query_vector, agent_w, limit)
|
| 139 |
|
| 140 |
with conn.cursor() as cur:
|
| 141 |
-
print(f"쿼리 실행: 자바 구현과 동일하게 수정")
|
| 142 |
cur.execute(sql)
|
| 143 |
rows = cur.fetchall()
|
| 144 |
|
| 145 |
-
print(f"검색 결과: 총 {len(rows)}개 데이터 조회됨")
|
| 146 |
-
if len(rows) > 0:
|
| 147 |
-
print(f"첫 번째 결과 ID: {rows[0][0]}, 유사도: {float(rows[0][3])}")
|
| 148 |
-
|
| 149 |
results = []
|
| 150 |
for row in rows:
|
| 151 |
id_val = row[0]
|
|
@@ -175,19 +164,11 @@ def search_similar_chat(query: str, max_results: int = 100) -> List[Dict]:
|
|
| 175 |
results.append(result)
|
| 176 |
except Exception as e:
|
| 177 |
print(f"메타데이터 파싱 오류: {e}")
|
| 178 |
-
print(f"문제가 발생한 메타데이터: {metadata_json[:200]}...")
|
| 179 |
continue
|
| 180 |
|
| 181 |
# 임계값 필터링
|
| 182 |
filtered_results = [r for r in results if r["similarityScore"] >= threshold]
|
| 183 |
|
| 184 |
-
if len(filtered_results) > 0:
|
| 185 |
-
print(f"임계값({threshold}) 이상 결과: {len(filtered_results)}개 / 전체 {len(results)}개")
|
| 186 |
-
print(f"가장 높은 유사도 점수: {filtered_results[0]['similarityScore']}")
|
| 187 |
-
print(f"상위 결과 챗ID: {filtered_results[0].get('chatId')}, 주제: {filtered_results[0].get('topic', '')[:50]}...")
|
| 188 |
-
else:
|
| 189 |
-
print(f"임계값({threshold}) 이상의 결과가 없습니다")
|
| 190 |
-
|
| 191 |
return filtered_results
|
| 192 |
|
| 193 |
except Exception as e:
|
|
@@ -225,11 +206,7 @@ def search_similar_chat_by_date(
|
|
| 225 |
agent_w = DEFAULT_AGENT_WEIGHT
|
| 226 |
threshold = DEFAULT_SIMILARITY_THRESHOLD
|
| 227 |
|
| 228 |
-
print(f"다중 임베딩 날짜 검색 시작: 쿼리='{query}', 시작일={start_date}, 종료일={end_date}, 최대 결과={limit}")
|
| 229 |
-
|
| 230 |
try:
|
| 231 |
-
# 날짜 필터 생성
|
| 232 |
-
|
| 233 |
# 쿼리 임베딩 생성
|
| 234 |
query_embedding = get_embedding(query)
|
| 235 |
|
|
@@ -282,15 +259,10 @@ def search_similar_chat_by_date(
|
|
| 282 |
"""
|
| 283 |
|
| 284 |
with conn.cursor() as cur:
|
| 285 |
-
print(f"날짜 검색 쿼리 실행: 시작일={start_date}, 종료일={end_date}")
|
| 286 |
# 여기서는 limit를 파라미터로 전달
|
| 287 |
cur.execute(sql, (limit,))
|
| 288 |
rows = cur.fetchall()
|
| 289 |
|
| 290 |
-
print(f"날짜 필터링 검색 결과: 총 {len(rows)}개 데이터 조회됨")
|
| 291 |
-
if len(rows) > 0:
|
| 292 |
-
print(f"첫 번째 결과 ID: {rows[0][0]}, 유사도: {float(rows[0][3])}")
|
| 293 |
-
|
| 294 |
results = []
|
| 295 |
for row in rows:
|
| 296 |
id_val = row[0]
|
|
@@ -320,19 +292,11 @@ def search_similar_chat_by_date(
|
|
| 320 |
results.append(result)
|
| 321 |
except Exception as e:
|
| 322 |
print(f"메타데이터 파싱 오류: {e}")
|
| 323 |
-
print(f"문제가 발생한 메타데이터: {metadata_json[:200]}...")
|
| 324 |
continue
|
| 325 |
|
| 326 |
# 임계값 필터링 (자바 코드와 동일하게 구현)
|
| 327 |
filtered_results = [r for r in results if r["similarityScore"] >= threshold]
|
| 328 |
|
| 329 |
-
if len(filtered_results) > 0:
|
| 330 |
-
print(f"날짜 검색 - 임계값({threshold}) 이상 결과: {len(filtered_results)}개 / 전체 {len(results)}개")
|
| 331 |
-
print(f"날짜 검색 - 가장 높은 유사도 점수: {filtered_results[0]['similarityScore']}")
|
| 332 |
-
print(f"날짜 검색 - 상위 결과 챗ID: {filtered_results[0].get('chatId')}, 시작시간: {filtered_results[0].get('startTime')}")
|
| 333 |
-
else:
|
| 334 |
-
print(f"날짜 검색 - 임계값({threshold}) 이상의 결과가 없습니다")
|
| 335 |
-
|
| 336 |
return filtered_results
|
| 337 |
|
| 338 |
except Exception as e:
|
|
|
|
| 12 |
DEFAULT_TOPIC_WEIGHT = 0.5
|
| 13 |
DEFAULT_CUSTOMER_WEIGHT = 0.2
|
| 14 |
DEFAULT_AGENT_WEIGHT = 0.1
|
| 15 |
+
DEFAULT_SIMILARITY_THRESHOLD = 0.5
|
| 16 |
|
| 17 |
# OpenAI 클라이언트 초기화
|
| 18 |
client = OpenAI()
|
| 19 |
|
| 20 |
# DB 연결 설정
|
| 21 |
def get_db_conn():
|
|
|
|
| 22 |
return psycopg2.connect(
|
| 23 |
host=os.environ["VECTOR_HOST"],
|
| 24 |
port=5432,
|
|
|
|
| 29 |
|
| 30 |
def get_embedding(text: str) -> List[float]:
|
| 31 |
"""
|
| 32 |
+
텍스트를 OpenAI의 text-embedding-ada-002 모델을 사용하여 임베딩 벡터로 변환합니다.
|
| 33 |
Java의 float[](float32)와 호환되도록 명시적으로 float32로 변환합니다.
|
| 34 |
|
| 35 |
Args:
|
|
|
|
| 53 |
def format_vector_for_pg(vector: List[float]) -> str:
|
| 54 |
"""
|
| 55 |
임베딩 벡터를 PostgreSQL 포맷으로 변환합니다.
|
|
|
|
| 56 |
입력된 벡터가 float32 타입인지 확인합니다.
|
| 57 |
"""
|
| 58 |
# 벡터가 float32 타입인지 확인하고, 아니면 변환
|
|
|
|
| 61 |
vector = np.array(vector, dtype=np.float32)
|
| 62 |
elif vector.dtype != np.float32:
|
| 63 |
vector = vector.astype(np.float32)
|
|
|
|
|
|
|
| 64 |
vector_str = ','.join([f"{x}" for x in vector])
|
| 65 |
return f"[{vector_str}]"
|
| 66 |
|
|
|
|
| 93 |
agent_w = DEFAULT_AGENT_WEIGHT
|
| 94 |
threshold = DEFAULT_SIMILARITY_THRESHOLD
|
| 95 |
|
|
|
|
|
|
|
| 96 |
try:
|
| 97 |
# 쿼리 임베딩 생성
|
| 98 |
query_embedding = get_embedding(query)
|
|
|
|
| 132 |
""" % (query_vector, full_w, query_vector, topic_w, query_vector, customer_w, query_vector, agent_w, limit)
|
| 133 |
|
| 134 |
with conn.cursor() as cur:
|
|
|
|
| 135 |
cur.execute(sql)
|
| 136 |
rows = cur.fetchall()
|
| 137 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 138 |
results = []
|
| 139 |
for row in rows:
|
| 140 |
id_val = row[0]
|
|
|
|
| 164 |
results.append(result)
|
| 165 |
except Exception as e:
|
| 166 |
print(f"메타데이터 파싱 오류: {e}")
|
|
|
|
| 167 |
continue
|
| 168 |
|
| 169 |
# 임계값 필터링
|
| 170 |
filtered_results = [r for r in results if r["similarityScore"] >= threshold]
|
| 171 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 172 |
return filtered_results
|
| 173 |
|
| 174 |
except Exception as e:
|
|
|
|
| 206 |
agent_w = DEFAULT_AGENT_WEIGHT
|
| 207 |
threshold = DEFAULT_SIMILARITY_THRESHOLD
|
| 208 |
|
|
|
|
|
|
|
| 209 |
try:
|
|
|
|
|
|
|
| 210 |
# 쿼리 임베딩 생성
|
| 211 |
query_embedding = get_embedding(query)
|
| 212 |
|
|
|
|
| 259 |
"""
|
| 260 |
|
| 261 |
with conn.cursor() as cur:
|
|
|
|
| 262 |
# 여기서는 limit를 파라미터로 전달
|
| 263 |
cur.execute(sql, (limit,))
|
| 264 |
rows = cur.fetchall()
|
| 265 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 266 |
results = []
|
| 267 |
for row in rows:
|
| 268 |
id_val = row[0]
|
|
|
|
| 292 |
results.append(result)
|
| 293 |
except Exception as e:
|
| 294 |
print(f"메타데이터 파싱 오류: {e}")
|
|
|
|
| 295 |
continue
|
| 296 |
|
| 297 |
# 임계값 필터링 (자바 코드와 동일하게 구현)
|
| 298 |
filtered_results = [r for r in results if r["similarityScore"] >= threshold]
|
| 299 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 300 |
return filtered_results
|
| 301 |
|
| 302 |
except Exception as e:
|