Spaces:
Paused
Paused
Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,248 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import time
|
3 |
+
import json
|
4 |
+
import psycopg2
|
5 |
+
from typing import Dict, List
|
6 |
+
# from dotenv import load_dotenv
|
7 |
+
|
8 |
+
# FastAPI λ° slowapi κ΄λ ¨ λͺ¨λ
|
9 |
+
from fastapi import FastAPI, Request
|
10 |
+
from slowapi import Limiter, _rate_limit_exceeded_handler
|
11 |
+
from slowapi.util import get_remote_address
|
12 |
+
from slowapi.errors import RateLimitExceeded
|
13 |
+
from fastapi.middleware.cors import CORSMiddleware
|
14 |
+
|
15 |
+
# Pydantic λͺ¨λΈ
|
16 |
+
from pydantic import BaseModel
|
17 |
+
|
18 |
+
# LangChain κ΄λ ¨ λͺ¨λ
|
19 |
+
from langchain_google_genai import ChatGoogleGenerativeAI
|
20 |
+
from langchain_community.embeddings import HuggingFaceEmbeddings
|
21 |
+
from langchain_community.vectorstores import PGVector
|
22 |
+
from langchain_core.messages import SystemMessage
|
23 |
+
from langchain.chains import ConversationalRetrievalChain
|
24 |
+
from langchain.memory import ConversationBufferMemory
|
25 |
+
from langchain_core.documents import Document # Document νμ
ννΈμ©μΌλ‘ μΆκ°
|
26 |
+
# from pdf_importer import create_vector_store, CONNECTION_STRING, COLLECTION_NAME
|
27 |
+
|
28 |
+
# νκ²½ λ³μ λ‘λ (Hugging Face Secretsμμ κ°μ Έμ΄)
|
29 |
+
POSTGRES_USER = os.getenv('POSTGRES_USER')
|
30 |
+
POSTGRES_PASSWORD = os.getenv('POSTGRES_PASSWORD')
|
31 |
+
POSTGRES_HOST = os.getenv('POSTGRES_HOST')
|
32 |
+
POSTGRES_PORT = os.getenv('POSTGRES_PORT')
|
33 |
+
POSTGRES_DB = os.getenv('POSTGRES_DB')
|
34 |
+
GOOGLE_API_KEY = os.getenv('GOOGLE_API_KEY')
|
35 |
+
|
36 |
+
COLLECTION_NAME = "homepage_pdfplumner_1st"
|
37 |
+
|
38 |
+
# 2. νμ νκ²½ λ³μκ° λͺ¨λ μ‘΄μ¬νλμ§ νμΈν©λλ€.
|
39 |
+
if not all([POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_HOST, POSTGRES_PORT, POSTGRES_DB, COLLECTION_NAME, GOOGLE_API_KEY]):
|
40 |
+
raise ValueError("νμ νκ²½ λ³μλ€μ΄ μ€μ λμ§ μμμ΅λλ€. Hugging Face Secretsλ₯Ό νμΈνμΈμ.")
|
41 |
+
|
42 |
+
# νκ²½ λ³μλ₯Ό μ‘°ν©νμ¬ CONNECTION_STRINGμ μμ±
|
43 |
+
CONNECTION_STRING = f"postgresql+psycopg2://{POSTGRES_USER}:{POSTGRES_PASSWORD}@{POSTGRES_HOST}:{POSTGRES_PORT}/{POSTGRES_DB}"
|
44 |
+
|
45 |
+
|
46 |
+
# load_dotenv()
|
47 |
+
app = FastAPI()
|
48 |
+
limiter = Limiter(key_func=get_remote_address)
|
49 |
+
app.state.limiter = limiter
|
50 |
+
app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)
|
51 |
+
|
52 |
+
app.add_middleware(
|
53 |
+
CORSMiddleware,
|
54 |
+
allow_origins=["*"],
|
55 |
+
allow_credentials=True,
|
56 |
+
allow_methods=["*"],
|
57 |
+
allow_headers=["*"],
|
58 |
+
)
|
59 |
+
|
60 |
+
|
61 |
+
# RAG κ΅¬μ± μμλ₯Ό νλ‘κ·Έλ¨ μμ μ ν λ²λ§ μ΄κΈ°ν
|
62 |
+
embeddings = HuggingFaceEmbeddings(
|
63 |
+
model_name='nlpai-lab/KURE-v1',
|
64 |
+
model_kwargs={'device': 'cpu'}
|
65 |
+
)
|
66 |
+
|
67 |
+
try:
|
68 |
+
vector_store = PGVector(
|
69 |
+
collection_name=COLLECTION_NAME,
|
70 |
+
connection_string=CONNECTION_STRING,
|
71 |
+
embedding_function=embeddings
|
72 |
+
)
|
73 |
+
print("Vector store loaded from PostgreSQL.")
|
74 |
+
except Exception as e:
|
75 |
+
print(f"Error connecting to PostgreSQL: {e}")
|
76 |
+
import sys
|
77 |
+
sys.exit(1)
|
78 |
+
|
79 |
+
llm = ChatGoogleGenerativeAI(
|
80 |
+
# model="gemini-1.5-flash-8b",
|
81 |
+
model="gemini-2.5-flash-lite",
|
82 |
+
model_kwargs={
|
83 |
+
"system_instruction": SystemMessage(
|
84 |
+
content=
|
85 |
+
# """λΉμ μ νκ΅μΈκ΅μ΄λνκ΅(μμΈ) νμ¬ μ λ¬Έκ°μ
λλ€. λ΅λ³ μμΉ: 1. νκ΅μΈκ΅μ΄λνκ΅(μμΈ) κ΄λ ¨ μ§λ¬Έμ μ νν λ΅λ³ν©λλ€. 2. μ΄μ λν λ§₯λ½μ κΈ°μ΅νκ³ μ μ°νκ² μλ΅ν©λλ€. 3. μΉμ νκ³ μ΄ν΄νκΈ° μ¬μ΄ λ§ν¬λ₯Ό μ¬μ©νλ©°, λ°λμ μμ ν λ¬Έμ₯μΌλ‘ λ΅λ³ν©λλ€. 4. μ°Έκ³ μ 보μ μλ λ΄μ©μ μ λ μΆμΈ‘νκ±°λ μμλ‘ λ΅λ³νμ§ μμ΅λλ€. λ΅λ³ κ·μΉ: - νκ΅μΈκ΅μ΄λνκ΅(μμΈ)κ³Ό κ΄λ ¨ μλ μ§λ¬Έ: "μ£μ‘ν©λλ€. νκ΅μΈκ΅μ΄λνκ΅(μμΈ) κ΄λ ¨ μ§λ¬Έμλ§ λ΅λ³λ릴 μ μμ΅λλ€."λΌκ³ λ΅λ³νμΈμ. - μ¬μ©μμ μ§λ¬Έκ³Ό κ΄λ ¨λ μ λ³΄κ° μ°Έκ³ λ¬Έμμ λͺ
ννκ² μ‘΄μ¬νμ§ μλ κ²½μ°, μ΄λ€ λ΄μ©λ μΆλ‘ νκ±°λ λ§λΆμ΄μ§ λ§κ³ 무쑰건 "μ£μ‘ν©λλ€. ν΄λΉ μ 보λ₯Ό νμΈν μ μμ΅λλ€."λΌκ³ λ΅λ³νμΈμ."""
|
86 |
+
"""
|
87 |
+
|
88 |
+
λΉμ μ νκ΅μΈκ΅μ΄λνκ΅(μμΈ)μ **'νμ¬ μν AI μ΄λλ°μ΄μ '**μ
λλ€. λΉμ μ μ§μμ μ£Όμ΄μ§ [νμ¬ κ·μ ]κ³Ό [μ£Όλ³ μκΆ μ 보] λ¬Έμλ‘ νμ λ©λλ€. λΉμ μ μ무λ μ΄ μ§μ λ΄μμ νμλ€μ μ§λ¬Έμ λͺ
ννκ³ μΉμ ν μ λ¬Έκ°μ μ΄μ‘°λ‘ λ΅λ³νλ κ²μ
λλ€.
|
89 |
+
|
90 |
+
[λ΅λ³ μμΉ]
|
91 |
+
|
92 |
+
1. μ νμ±: λ°λμ μ£Όμ΄μ§ μ°Έκ³ λ¬Έμμ λ΄μ©μλ§ κ·Όκ±°νμ¬ λ΅λ³ν©λλ€.
|
93 |
+
|
94 |
+
2. μΉμ ν¨: νμ μΉμ νκ³ μ΄ν΄νκΈ° μ¬μ΄ μμ ν λ¬Έμ₯μΌλ‘ λ΅λ³ν©λλ€.
|
95 |
+
|
96 |
+
3. λ§₯λ½ μ΄ν΄: μ΄μ λν λ΄μ©μ κΈ°μ΅νμ¬ μμ°μ€λ¬μ΄ λνλ₯Ό μ΄μ΄κ°λλ€.
|
97 |
+
|
98 |
+
4. μ§μ λ΄μ¬ν: λΉμ μ λ¬Έμλ₯Ό λ¨μν μ λ¬νλ λ‘λ΄μ΄ μλλλ€. μ£Όμ΄μ§ μ°Έκ³ λ¬Έμλ λΉμ μ 'μ§μ'μ
λλ€. λ΅λ³ μ, 'μ 곡λ μ 보', 'μ°Έκ³ λ¬Έμ', 'μ£Όμ΄μ§ ν
μ€νΈ', 'ν', 'λ¬Έλ¨' λ± λΉμ μ΄ μ 보λ₯Ό μ΄λ»κ² μ»μλμ§ μμνλ κ·Έ μ΄λ€ λ¨μ΄λ μ λ μ¬μ©νμ§ λ§μΈμ. κ²μλ λͺ¨λ μ 보λ₯Ό μμ ν μμ μ μ§μμΈ κ²μ²λΌ μ’
ν©νκ³ μμ°μ€λ½κ² μ¬κ΅¬μ±νμ¬, λ§μΉ μλλΆν° μκ³ μμλ κ²μ²λΌ μ¬μ©μμκ² μ§μ μ€λͺ
ν΄μΌ ν©λλ€.
|
99 |
+
|
100 |
+
5. νκ΅μ΄ μ¬οΏ½οΏ½: λͺ¨λ λ΅λ³μ λ°λμ μλ²½ν νκ΅μ΄λ‘λ§ μμ±ν΄μΌ ν©λλ€.
|
101 |
+
|
102 |
+
[λ΅λ³ κ·μΉ]
|
103 |
+
|
104 |
+
1. μκΈ°μκ°: λ§μ½ μ¬μ©μκ° λΉμ μ μ 체μ±μ λν΄ λ¬»λλ€λ©΄(μ: "λλ λꡬμΌ?", "μ΄λ¦μ΄ λμΌ?"), "μλ
νμΈμ! μ λ νκ΅μΈκ΅μ΄λνκ΅ νμλ€μ μΊ νΌμ€ μνμ λκΈ° μν΄ λ§λ€μ΄μ§ 'νμ¬ μν AI μ΄λλ°μ΄μ 'μ
λλ€. νμ¬ μ 보λ νκ΅ μνμ λν΄ κΆκΈν μ μ΄ μλ€λ©΄ 무μμ΄λ λ¬Όμ΄λ³΄μΈμ." λΌκ³ μ νν μκ°ν΄μΌ ν©λλ€. μ λλ‘ 'Googleμ μΈμ΄ λͺ¨λΈ'μ΄λ λ§μ€μ½νΈ 'λΆ(Boo)'λΌκ³ μμ μ μκ°ν΄μλ μ λ©λλ€.
|
105 |
+
|
106 |
+
1. λ²μ μΈ μ§λ¬Έ νλ¨: λΉμ μ μ§μ λ²μ(νμ¬, μ£Όλ³ λ§μ§)μ λͺ
λ°±ν κ΄λ ¨ μλ μ§λ¬Έ(μ: κΈμ΅, μ€ν¬μΈ )μλ "μ£μ‘ν©λλ€. μ λ νκ΅μΈκ΅μ΄λνκ΅ νμ¬ λ° μΊ νΌμ€ μν μ 보μ λν΄μλ§ λ΅λ³ν μ μμ΅λλ€." λΌκ³ λ΅λ³νμΈμ. 'μ 곡λ μ 보μ μλ€'λ μμ λΆμ° μ€λͺ
μ μ λ λ§λΆμ΄μ§ λ§μΈμ.
|
107 |
+
|
108 |
+
2. μ 보 μ°μ μμ νλ³: μ¬λ¬ κ°μ μ°Έκ³ λ¬Έμκ° μ£Όμ΄μ§λ©΄, κ·Έμ€μμ μ¬μ©μμ μ§λ¬Έμ κ°μ₯ μ§μ μ μΌλ‘ λ΅ν μ μλ ν΅μ¬ μ 보λ₯Ό λ¨Όμ μλ³νμΈμ. κ΄λ ¨μ±μ΄ λ¨μ΄μ§κ±°λ λΆμ°¨μ μΈ μ 보λ λ΅λ³μ ν¬ν¨νμ§ μκ±°λ, κΌ νμν κ²½μ°μλ§ κ°λ΅νκ² λ§λΆμ¬ μ€λͺ
νμΈμ.
|
109 |
+
|
110 |
+
3. ν(Table) λΆμ: μ°Έκ³ λ¬Έμμ νκ° ν¬ν¨λ κ²½μ°, λΉμ μ ν λΆμ μ λ¬Έκ°λ‘μ νκ³Ό μ΄μ κ΄κ³λ₯Ό μ νν ν΄μνμ¬ λ΅λ³ν΄μΌ ν©λλ€.
|
111 |
+
|
112 |
+
4. μ‘°κ±΄λΆ λ΅λ³: λ§μ½ νλ ν
μ€νΈμ νκ³Ό, νλ² λ± μΈλΆ μ‘°κ±΄μ΄ λͺ
μλμ΄ μμ§ μλ€λ©΄, "μ μλ μλ£μ λ°λ₯΄λ©΄ μΌλ°μ μΌλ‘" λλ "2025νλ
λ κΈ°μ€μΌλ‘λ" κ³Ό κ°μ΄ μ 보μ μΆμ²λ κΈ°μ€μ λͺ
νν λ°νλ©° λ΅λ³νμΈμ.
|
113 |
+
|
114 |
+
5. λ€μ€ μ 보 μ²λ¦¬: λ§μ½ μ¬μ©μμ μ§λ¬Έμ λν΄ μ¬λ¬ λ¬Έμμμ μλ‘ λ€λ₯Έ μ λ³΄κ° κ²μλ κ²½μ°, νλμ μ λ³΄λ§ μ ννμ§ λ§μΈμ. λμ , κ°κ°μ 쑰건과 λ΄μ©μ λͺ
νν ꡬλΆνμ¬ λͺ¨λ μ 보λ₯Ό μ’
ν©μ μΌλ‘ μλ΄ν΄μΌ ν©λλ€.
|
115 |
+
|
116 |
+
6. μμΈ κ°λ₯μ± μΈμ§: νμ¬ κ·μ μ λ¨κ³Όλν, νκ³Ό, νλ²λ³λ‘ μμΈ κ·μΉμ΄ μ‘΄μ¬ν μ μλ€λ μ¬μ€μ νμ μΈμ§νμΈμ. λ§μ½ μΌλ°μ μΈ κ·μΉμ μ°ΎμλλΌλ, "μΌλ°μ μΌλ‘λ OOνμ μ΄ νμνμ§λ§, μμ λ¨κ³Όλνμ΄λ νκ³Όμ λ°λΌ λ€λ₯Ό μ μμΌλ μ νν μ 보λ νκ΅ κ³΅μ λ¬Έμλ₯Ό νμΈνμκ±°λ νκ³Ό μ¬λ¬΄μ€μ λ¬Έμνλ κ²μ κΆμ₯ν©λλ€" μ κ°μ΄ λ΅λ³μ 'μ£Όμμ¬ν'κ³Ό 'νκ³'λ₯Ό λͺ
μνμΈμ.
|
117 |
+
|
118 |
+
7. μ 보 λΆμ¬ μ: μμ λͺ¨λ λ
Έλ ₯μλ λΆκ΅¬νκ³ μ§λ¬Έμ λν λ΅λ³μ μ°Έκ³ λ¬Έμμμ μ°Ύμ μ μλ κ²½μ°μλ§, "μ£μ‘ν©λλ€. λ¬Έμνμ λ΄μ©μ λν μ 보λ μ κ° κ°μ§ μλ£μμ νμΈν μ μμ΅λλ€."λΌκ³ λ΅λ³νμΈμ.
|
119 |
+
|
120 |
+
"""
|
121 |
+
|
122 |
+
|
123 |
+
),
|
124 |
+
}
|
125 |
+
)
|
126 |
+
|
127 |
+
retriever = vector_store.as_retriever(search_kwargs={"k": 3})
|
128 |
+
|
129 |
+
# retriever = MultiQueryRetriever.from_llm(
|
130 |
+
# retriever=vector_store.as_retriever(search_kwargs={"k": 5}),
|
131 |
+
# llm=llm
|
132 |
+
# )
|
133 |
+
|
134 |
+
# μ¬μ©μ μΈμ
λ³ λν 체μΈμ μ μ₯ν λμ
λ리
|
135 |
+
chat_sessions: Dict[str, ConversationalRetrievalChain] = {}
|
136 |
+
|
137 |
+
def get_or_create_chain(session_id: str) -> ConversationalRetrievalChain:
|
138 |
+
if session_id not in chat_sessions:
|
139 |
+
memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True,
|
140 |
+
input_key="question", # <-- μΆκ°
|
141 |
+
output_key="answer" )
|
142 |
+
new_chain = ConversationalRetrievalChain.from_llm(
|
143 |
+
llm=llm,
|
144 |
+
retriever=retriever,
|
145 |
+
memory=memory,
|
146 |
+
return_source_documents=True, # μ°Έκ³ λ¬Έμ λ°ν νμ±ν
|
147 |
+
output_key="answer"
|
148 |
+
)
|
149 |
+
chat_sessions[session_id] = new_chain
|
150 |
+
print(f"μλ‘μ΄ μΈμ
ID μμ±: {session_id}")
|
151 |
+
return chat_sessions[session_id]
|
152 |
+
|
153 |
+
|
154 |
+
class ChatMessage(BaseModel):
|
155 |
+
message: str
|
156 |
+
session_id: str
|
157 |
+
user_id: str # μ¬μ©μ μλ³μ μν΄ μΆκ°
|
158 |
+
|
159 |
+
class ChatResponse(BaseModel):
|
160 |
+
response: str
|
161 |
+
success: bool
|
162 |
+
# source_documents νλλ₯Ό μΆκ°νμ¬ νλ‘ νΈμλλ‘λ λ³΄λΌ μ μλλ‘ μ€λΉ
|
163 |
+
source_documents: List[Dict[str, str]] = [] # λ¬Έμ λ΄μ©κ³Ό λ©νλ°μ΄ν° μ μ₯
|
164 |
+
|
165 |
+
|
166 |
+
|
167 |
+
|
168 |
+
|
169 |
+
@app.post("/api/chat", response_model=ChatResponse)
|
170 |
+
@limiter.limit("15/minute")
|
171 |
+
async def chat_with_gemini(request: Request):
|
172 |
+
start_time = time.time()
|
173 |
+
|
174 |
+
try:
|
175 |
+
|
176 |
+
# JSON bodyλ₯Ό μ§μ νμ±
|
177 |
+
body = await request.json()
|
178 |
+
chat_message = ChatMessage(**body)
|
179 |
+
|
180 |
+
# qa_chain = get_or_create_chain(request.session_id)
|
181 |
+
# result = qa_chain.invoke({"question": request.message})
|
182 |
+
qa_chain = get_or_create_chain(chat_message.session_id)
|
183 |
+
result = qa_chain.invoke({"question": chat_message.message})
|
184 |
+
|
185 |
+
|
186 |
+
# μ°Έκ³ λ¬Έμ μΆμΆ λ° λ‘κ·Έ μΆλ ₯
|
187 |
+
source_documents_for_response: List[Dict[str, str]] = []
|
188 |
+
if 'source_documents' in result and result['source_documents']:
|
189 |
+
print("\n--- μ°Έκ³ λ¬Έμ ---")
|
190 |
+
for i, doc in enumerate(result['source_documents']):
|
191 |
+
print(f"λ¬Έμ {i+1}:")
|
192 |
+
print(f" μμ€: {doc.metadata.get('source', 'μ μ μμ')}")
|
193 |
+
print(f" λ΄μ© (μΌλΆ): {doc.page_content[:200]}...") # λ΄μ©μ μΌλΆλ§ μΆλ ₯
|
194 |
+
# νλ‘ νΈμλ μλ΅μ μν΄ μ μ₯
|
195 |
+
source_documents_for_response.append({
|
196 |
+
"source": doc.metadata.get('source', 'μ μ μμ'),
|
197 |
+
"content": doc.page_content # μ 체 λ΄μ©μ λ³΄λΌ μλ μμ
|
198 |
+
})
|
199 |
+
print("---------------\n")
|
200 |
+
# ==========================================================
|
201 |
+
# βΌβΌβΌβΌβΌβΌβΌβΌβΌβΌβΌβΌβΌβΌβΌβΌβΌβΌ μ΄ λΆλΆλ§ μΆκ° βΌβΌβΌβΌβΌβΌβΌβΌβΌβΌβΌβΌβΌβΌβΌβΌβΌβΌ
|
202 |
+
# ==========================================================
|
203 |
+
|
204 |
+
response_time_ms = int((time.time() - start_time) * 1000)
|
205 |
+
|
206 |
+
# DBμ λ‘κ·Έ μ μ₯
|
207 |
+
try:
|
208 |
+
db_conn_str = CONNECTION_STRING.replace("postgresql+psycopg2", "postgresql")
|
209 |
+
conn = psycopg2.connect(db_conn_str)
|
210 |
+
cur = conn.cursor()
|
211 |
+
cur.execute(
|
212 |
+
"""
|
213 |
+
INSERT INTO chat_logs (session_id, user_id, user_question, bot_answer, retrieved_sources, response_time_ms)
|
214 |
+
VALUES (%s, %s, %s, %s, %s, %s);
|
215 |
+
""",
|
216 |
+
(chat_message.session_id, chat_message.user_id, chat_message.message, result['answer'], json.dumps(source_documents_for_response), response_time_ms)
|
217 |
+
)
|
218 |
+
conn.commit()
|
219 |
+
cur.close()
|
220 |
+
conn.close()
|
221 |
+
except Exception as db_error:
|
222 |
+
print(f"DB λ‘κ·Έ μ μ₯ μ€ν¨: {db_error}")
|
223 |
+
|
224 |
+
# ==========================================================
|
225 |
+
# β²β²β²β²β²β²β²β²β²β²β²β²β²β²β²β²β²β² μ΄ λΆλΆλ§ μΆκ° β²β²β²β²β²β²β²β²β²β²β²β²β²β²β²β²β²β²
|
226 |
+
# ==========================================================
|
227 |
+
|
228 |
+
|
229 |
+
|
230 |
+
|
231 |
+
return ChatResponse(
|
232 |
+
response=result['answer'],
|
233 |
+
success=True,
|
234 |
+
source_documents=source_documents_for_response # μλ΅μ μ°Έκ³ λ¬Έμ μΆκ°
|
235 |
+
)
|
236 |
+
except Exception as e:
|
237 |
+
print(f"μ€λ₯ λ°μ: {str(e)}")
|
238 |
+
return ChatResponse(
|
239 |
+
response=f"μ€λ₯κ° λ°μνμ΅λλ€: {str(e)}",
|
240 |
+
success=False,
|
241 |
+
source_documents=[]
|
242 |
+
)
|
243 |
+
|
244 |
+
@app.get("/")
|
245 |
+
async def root():
|
246 |
+
return {"message": "νκ΅μΈκ΅μ΄λνκ΅(μμΈ) νμ¬ μ±λ΄ API"}
|
247 |
+
|
248 |
+
|