Use thread for invoke

This commit is contained in:
estromenko 2025-10-21 21:32:18 +03:00
parent ff46f32260
commit a697b7764a
2 changed files with 13 additions and 9 deletions

View File

@ -5,7 +5,8 @@ from langgraph.checkpoint.memory import InMemorySaver
from langchain_community.tools import DuckDuckGoSearchRun from langchain_community.tools import DuckDuckGoSearchRun
from langchain_community.vectorstores import Clickhouse, ClickhouseSettings from langchain_community.vectorstores import Clickhouse, ClickhouseSettings
from langchain_community.embeddings import DeepInfraEmbeddings from langchain_community.embeddings import DeepInfraEmbeddings
from redis.asyncio import Redis from redis import Redis
from redis.asyncio import Redis as AsyncRedis
SYSTEM_PROMPT = """ SYSTEM_PROMPT = """
Ты карьерный копилот для ИТ. Ты карьерный копилот для ИТ.
@ -24,6 +25,7 @@ SYSTEM_PROMPT = """
""" """
redis = Redis(host=os.getenv("REDIS_HOST", "127.0.0.1")) 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") llm = ChatOpenAI(model_name="gpt-5")
embedding = DeepInfraEmbeddings(model_id="Qwen/Qwen3-Embedding-8B") embedding = DeepInfraEmbeddings(model_id="Qwen/Qwen3-Embedding-8B")
vectorstore = Clickhouse(embedding, ClickhouseSettings( vectorstore = Clickhouse(embedding, ClickhouseSettings(
@ -36,18 +38,18 @@ vectorstore = Clickhouse(embedding, ClickhouseSettings(
search_tool = DuckDuckGoSearchRun() search_tool = DuckDuckGoSearchRun()
async def get_relevant_vacancies(requirements: str): def get_relevant_vacancies(requirements: str):
"""Получает релевантные вакансии из базы данных по переданным требованиям.""" """Получает релевантные вакансии из базы данных по переданным требованиям."""
formatted_vacancies = "" formatted_vacancies = ""
for document in await vectorstore.asimilarity_search(requirements, k=5): for document in vectorstore.similarity_search(requirements, k=5):
metadata = document.metadata metadata = document.metadata
formatted_vacancies += f"chat_id = {metadata['chat_id']}\ntelegram_id = {metadata['telegram_id']}\n{document.page_content}" formatted_vacancies += f"chat_id = {metadata['chat_id']}\ntelegram_id = {metadata['telegram_id']}\n{document.page_content}"
return formatted_vacancies 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 "" return resume_bytes.decode("utf-8") if resume_bytes else ""

View File

@ -2,12 +2,13 @@ import sys
sys.path.append(".") sys.path.append(".")
import asyncio
import os import os
import io import io
import traceback import traceback
from telegram import Update, ReplyKeyboardMarkup from telegram import Update, ReplyKeyboardMarkup
from telegram.ext import filters, ApplicationBuilder, MessageHandler, CommandHandler, ContextTypes 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 from pypdf import PdfReader
VACANCIES = "👥 Вакансии" VACANCIES = "👥 Вакансии"
@ -21,7 +22,7 @@ async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
async def prompt(update: Update, context: ContextTypes.DEFAULT_TYPE): async def prompt(update: Update, context: ContextTypes.DEFAULT_TYPE):
if update.message.text == RESUME: if update.message.text == RESUME:
resume = await redis.get(update.effective_user.id) resume = await async_redis.get(update.effective_user.id)
text = "Пришли мне файл с твоим резюме, чтобы я смог найти подходящие вакансии на основе твоих компетенций!" text = "Пришли мне файл с твоим резюме, чтобы я смог найти подходящие вакансии на основе твоих компетенций!"
if resume: if resume:
text = "Я уже получил твое резюме. Если хочешь его обновить, пришли мне новый файл!" text = "Я уже получил твое резюме. Если хочешь его обновить, пришли мне новый файл!"
@ -34,7 +35,8 @@ async def prompt(update: Update, context: ContextTypes.DEFAULT_TYPE):
message = await context.bot.send_message(update.effective_chat.id, "📝 Обрабатываю твой запрос. Пожалуйста, подождите...") 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}"}]}, input={"messages": [{"role": "user", "content": f"user_id = {update.effective_user.id}\n{user_prompt}"}]},
config={"configurable": {"thread_id": update.effective_user.id}}, 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) await file.download_to_memory(buffer)
reader = PdfReader(buffer) reader = PdfReader(buffer)
resume = "\n".join(page.extract_text() for page in reader.pages) 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="Отлично! Запомнил Ваше резюме.") await context.bot.send_message(chat_id=update.effective_chat.id, text="Отлично! Запомнил Ваше резюме.")