diff --git a/backend/agent.py b/backend/agent.py index 12f1ac0..87cd197 100644 --- a/backend/agent.py +++ b/backend/agent.py @@ -5,7 +5,8 @@ from langgraph.checkpoint.memory import InMemorySaver from langchain_community.tools import DuckDuckGoSearchRun from langchain_community.vectorstores import Clickhouse, ClickhouseSettings from langchain_community.embeddings import DeepInfraEmbeddings -from redis.asyncio import Redis +from redis import Redis +from redis.asyncio import Redis as AsyncRedis SYSTEM_PROMPT = """ Ты — карьерный копилот для ИТ. @@ -24,6 +25,7 @@ SYSTEM_PROMPT = """ """ redis = Redis(host=os.getenv("REDIS_HOST", "127.0.0.1")) +async_redis = AsyncRedis(host=os.getenv("REDIS_HOST", "127.0.0.1")) llm = ChatOpenAI(model_name="gpt-5") embedding = DeepInfraEmbeddings(model_id="Qwen/Qwen3-Embedding-8B") vectorstore = Clickhouse(embedding, ClickhouseSettings( @@ -36,18 +38,18 @@ vectorstore = Clickhouse(embedding, ClickhouseSettings( search_tool = DuckDuckGoSearchRun() -async def get_relevant_vacancies(requirements: str): +def get_relevant_vacancies(requirements: str): """Получает релевантные вакансии из базы данных по переданным требованиям.""" formatted_vacancies = "" - for document in await vectorstore.asimilarity_search(requirements, k=5): + for document in vectorstore.similarity_search(requirements, k=5): metadata = document.metadata formatted_vacancies += f"chat_id = {metadata['chat_id']}\ntelegram_id = {metadata['telegram_id']}\n{document.page_content}" return formatted_vacancies -async def get_user_resume(user_id: int): +def get_user_resume(user_id: int): """Получает резюме пользователя для подбора вакансий.""" - resume_bytes = await redis.get(user_id) + resume_bytes = redis.get(user_id) return resume_bytes.decode("utf-8") if resume_bytes else "" diff --git a/backend/bot.py b/backend/bot.py index c5ee2bd..e69bc86 100644 --- a/backend/bot.py +++ b/backend/bot.py @@ -2,12 +2,13 @@ import sys sys.path.append(".") +import asyncio import os import io import traceback from telegram import Update, ReplyKeyboardMarkup from telegram.ext import filters, ApplicationBuilder, MessageHandler, CommandHandler, ContextTypes -from backend.agent import agent, redis +from backend.agent import agent, async_redis from pypdf import PdfReader VACANCIES = "👥 Вакансии" @@ -21,7 +22,7 @@ async def start(update: Update, context: ContextTypes.DEFAULT_TYPE): async def prompt(update: Update, context: ContextTypes.DEFAULT_TYPE): if update.message.text == RESUME: - resume = await redis.get(update.effective_user.id) + resume = await async_redis.get(update.effective_user.id) text = "Пришли мне файл с твоим резюме, чтобы я смог найти подходящие вакансии на основе твоих компетенций!" if resume: text = "Я уже получил твое резюме. Если хочешь его обновить, пришли мне новый файл!" @@ -34,7 +35,8 @@ async def prompt(update: Update, context: ContextTypes.DEFAULT_TYPE): message = await context.bot.send_message(update.effective_chat.id, "📝 Обрабатываю твой запрос. Пожалуйста, подождите...") - response = await agent.ainvoke( + response = await asyncio.to_thread( + agent.invoke, input={"messages": [{"role": "user", "content": f"user_id = {update.effective_user.id}\n{user_prompt}"}]}, config={"configurable": {"thread_id": update.effective_user.id}}, ) @@ -57,7 +59,7 @@ async def handle_document(update: Update, context: ContextTypes.DEFAULT_TYPE): await file.download_to_memory(buffer) reader = PdfReader(buffer) resume = "\n".join(page.extract_text() for page in reader.pages) - await redis.set(update.effective_user.id, resume) + await async_redis.set(update.effective_user.id, resume) await context.bot.send_message(chat_id=update.effective_chat.id, text="Отлично! Запомнил Ваше резюме.")