обработка вопросов
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
import aiohttp
|
||||
from tg_bot.infrastructure.external.deepseek_client import DeepSeekClient
|
||||
from tg_bot.config.settings import settings
|
||||
|
||||
BACKEND_URL = "http://localhost:8001/api/v1"
|
||||
|
||||
|
||||
class RAGService:
|
||||
|
||||
def __init__(self):
|
||||
self.deepseek_client = DeepSeekClient()
|
||||
|
||||
async def search_documents_in_collections(
|
||||
self,
|
||||
user_telegram_id: str,
|
||||
query: str,
|
||||
limit_per_collection: int = 5
|
||||
) -> list[dict]:
|
||||
try:
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.get(
|
||||
f"{BACKEND_URL}/users/telegram/{user_telegram_id}"
|
||||
) as user_response:
|
||||
if user_response.status != 200:
|
||||
return []
|
||||
|
||||
user_data = await user_response.json()
|
||||
user_uuid = str(user_data.get("user_id"))
|
||||
|
||||
if not user_uuid:
|
||||
return []
|
||||
|
||||
async with session.get(
|
||||
f"{BACKEND_URL}/collections/",
|
||||
headers={"X-Telegram-ID": user_telegram_id}
|
||||
) as collections_response:
|
||||
if collections_response.status != 200:
|
||||
return []
|
||||
|
||||
collections = await collections_response.json()
|
||||
|
||||
all_documents = []
|
||||
for collection in collections:
|
||||
collection_id = collection.get("collection_id")
|
||||
if not collection_id:
|
||||
continue
|
||||
|
||||
try:
|
||||
async with aiohttp.ClientSession() as search_session:
|
||||
async with search_session.get(
|
||||
f"{BACKEND_URL}/documents/collection/{collection_id}",
|
||||
params={"search": query, "limit": limit_per_collection},
|
||||
headers={"X-Telegram-ID": user_telegram_id}
|
||||
) as search_response:
|
||||
if search_response.status == 200:
|
||||
documents = await search_response.json()
|
||||
for doc in documents:
|
||||
doc["collection_name"] = collection.get("name", "Unknown")
|
||||
all_documents.append(doc)
|
||||
except Exception as e:
|
||||
print(f"Error searching collection {collection_id}: {e}")
|
||||
continue
|
||||
|
||||
return all_documents[:20]
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error searching documents: {e}")
|
||||
return []
|
||||
|
||||
async def generate_answer_with_rag(
|
||||
self,
|
||||
question: str,
|
||||
user_telegram_id: str
|
||||
) -> dict:
|
||||
documents = await self.search_documents_in_collections(
|
||||
user_telegram_id,
|
||||
question
|
||||
)
|
||||
|
||||
context_parts = []
|
||||
sources = []
|
||||
|
||||
for doc in documents[:5]:
|
||||
title = doc.get("title", "Без названия")
|
||||
content = doc.get("content", "")[:1000]
|
||||
collection_name = doc.get("collection_name", "Unknown")
|
||||
|
||||
context_parts.append(f"Документ: {title}\nКоллекция: {collection_name}\nСодержание: {content[:500]}...")
|
||||
sources.append({
|
||||
"title": title,
|
||||
"collection": collection_name,
|
||||
"document_id": doc.get("document_id")
|
||||
})
|
||||
|
||||
context = "\n\n".join(context_parts) if context_parts else "Релевантные документы не найдены."
|
||||
|
||||
system_prompt = """Ты - помощник-юрист, который отвечает на вопросы на основе предоставленных документов.
|
||||
Используй информацию из документов для формирования точного и полезного ответа.
|
||||
Если в документах нет информации для ответа, честно скажи об этом."""
|
||||
|
||||
user_prompt = f"""Контекст из документов:
|
||||
{context}
|
||||
|
||||
Вопрос пользователя: {question}
|
||||
|
||||
Ответь на вопрос, используя информацию из предоставленных документов. Если информации недостаточно, укажи это."""
|
||||
|
||||
try:
|
||||
messages = [
|
||||
{"role": "system", "content": system_prompt},
|
||||
{"role": "user", "content": user_prompt}
|
||||
]
|
||||
|
||||
response = await self.deepseek_client.chat_completion(
|
||||
messages=messages,
|
||||
temperature=0.7,
|
||||
max_tokens=2000
|
||||
)
|
||||
|
||||
return {
|
||||
"answer": response.get("content", "Failed to generate answer"),
|
||||
"sources": sources,
|
||||
"usage": response.get("usage", {})
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error generating answer: {e}")
|
||||
if documents:
|
||||
return {
|
||||
"answer": f"Found {len(documents)} documents but failed to generate answer",
|
||||
"sources": sources[:3],
|
||||
"usage": {}
|
||||
}
|
||||
else:
|
||||
return {
|
||||
"answer": "No relevant documents found",
|
||||
"sources": [],
|
||||
"usage": {}
|
||||
}
|
||||
Reference in New Issue
Block a user