ChatInsight / app.py
Jake-seong's picture
Update app.py
84d96bf verified
raw
history blame
4.37 kB
import gradio as gr
import psycopg2
from openai import OpenAI
import json
import os
from typing import List, Dict
from pgvector.psycopg2 import register_vector
import numpy as np
# DB ์—ฐ๊ฒฐ ์„ค์ •
def get_db_conn():
return psycopg2.connect(
host=os.environ["VECTOR_HOST"],
port=5432,
dbname=os.environ["VECTOR_DBNAME"],
user=os.environ["VECTOR_USER"],
password=os.environ["VECTOR_SECRET"]
)
client = OpenAI() # ํ™˜๊ฒฝ๋ณ€์ˆ˜์— OPENAI_API_KEY๊ฐ€ ์žˆ์œผ๋ฉด ์ž๋™ ์ธ์‹
def get_embedding(text: str) -> List[float]:
"""
ํ…์ŠคํŠธ๋ฅผ ์ž„๋ฒ ๋”ฉ ๋ฒกํ„ฐ๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
"""
response = client.embeddings.create(
input=text,
model="text-embedding-ada-002"
)
return response.data[0].embedding
def search_similar_chats(query: str, maxResults: int = 10) -> List[Dict]:
"""
์œ ์‚ฌํ•œ ์ฑ„ํŒ… ๋ฌธ์„œ๋ฅผ ๊ฒ€์ƒ‰ํ•ฉ๋‹ˆ๋‹ค.
Args:
query (str): ๊ฒ€์ƒ‰ํ•  ์ฟผ๋ฆฌ ํ…์ŠคํŠธ
maxResults (int): ๋ฐ˜ํ™˜ํ•  ์ตœ๋Œ€ ๊ฒฐ๊ณผ ์ˆ˜
Returns:
List[Dict]: ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ ๋ชฉ๋ก
"""
embedding = np.array(get_embedding(query)) # numpy array๋กœ ๋ณ€ํ™˜
conn = get_db_conn()
register_vector(conn) # ๋ฒกํ„ฐ ํƒ€์ž… ์ž๋™ ๋ณ€ํ™˜ ์ง€์›
with conn.cursor() as cur:
cur.execute("""
SELECT id, metadata, content, embedding <#> %s AS distance
FROM vector_store
WHERE metadata->>'documentType' = 'chatAnalysis'
ORDER BY embedding <#> %s
LIMIT %s
""", (embedding, embedding, maxResults))
rows = cur.fetchall()
conn.close()
return [
{
"id": row[0],
"metadata": row[1],
"content": row[2],
"distance": row[3]
}
for row in rows
]
def search_chats_by_category(category: str, maxResults: int = 10) -> List[Dict]:
"""
ํŠน์ • ์นดํ…Œ๊ณ ๋ฆฌ์˜ ์ฑ„ํŒ… ๋ฌธ์„œ๋ฅผ ๊ฒ€์ƒ‰ํ•ฉ๋‹ˆ๋‹ค.
Args:
category (str): ์นดํ…Œ๊ณ ๋ฆฌ๋ช…
maxResults (int): ๋ฐ˜ํ™˜ํ•  ์ตœ๋Œ€ ๊ฒฐ๊ณผ ์ˆ˜
Returns:
List[Dict]: ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ ๋ชฉ๋ก
"""
conn = get_db_conn()
with conn.cursor() as cur:
cur.execute("""
SELECT id, metadata, content
FROM vector_store
WHERE metadata->>'documentType' = 'chatAnalysis'
AND metadata->>'category' = %s
LIMIT %s
""", (category, maxResults))
rows = cur.fetchall()
conn.close()
return [
{
"id": row[0],
"metadata": row[1],
"content": row[2]
}
for row in rows
]
def search_chats_by_date(startDate: str = None, endDate: str = None, maxResults: int = 10) -> List[Dict]:
"""
์ง€์ •๋œ ๋‚ ์งœ ๋ฒ”์œ„ ๋‚ด์˜ ์ฑ„ํŒ… ๋ฌธ์„œ๋ฅผ ๊ฒ€์ƒ‰ํ•ฉ๋‹ˆ๋‹ค.
Args:
startDate (str): ๊ฒ€์ƒ‰ ์‹œ์ž‘ ๋‚ ์งœ (YYYY-MM-DD)
endDate (str): ๊ฒ€์ƒ‰ ์ข…๋ฃŒ ๋‚ ์งœ (YYYY-MM-DD)
maxResults (int): ๋ฐ˜ํ™˜ํ•  ์ตœ๋Œ€ ๊ฒฐ๊ณผ ์ˆ˜
Returns:
List[Dict]: ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ ๋ชฉ๋ก
"""
conn = get_db_conn()
query = """
SELECT id, metadata, content
FROM vector_store
WHERE metadata->>'documentType' = 'chatAnalysis'
"""
params = []
if startDate not in (None, ""):
query += " AND (metadata->>'startTime')::timestamp >= %s"
params.append(startDate)
if endDate not in (None, ""):
query += " AND (metadata->>'startTime')::timestamp < %s"
params.append(endDate)
query += " LIMIT %s"
params.append(maxResults)
with conn.cursor() as cur:
cur.execute(query, tuple(params))
rows = cur.fetchall()
conn.close()
return [
{
"id": row[0],
"metadata": row[1],
"content": row[2]
}
for row in rows
]
# Gradio Blocks์— ํ•จ์ˆ˜ ๋“ฑ๋ก
with gr.Blocks() as demo:
gr.Markdown("# MCP ToolService ์˜ˆ์‹œ")
gr.Interface(fn=search_similar_chats, inputs=["text", "number"], outputs="json", title="search_similar_chats")
gr.Interface(fn=search_chats_by_category, inputs=["text", "number"], outputs="json", title="search_chats_by_category")
gr.Interface(fn=search_chats_by_date, inputs=["text", "text", "number"], outputs="json", title="search_chats_by_date")
if __name__ == "__main__":
demo.launch(mcp_server=True)