import os from langchain.agents import create_agent from langchain_openai import ChatOpenAI from langgraph.checkpoint.memory import InMemorySaver from langchain_community.vectorstores import Clickhouse, ClickhouseSettings from langchain_community.embeddings import DeepInfraEmbeddings from redis import Redis from redis.asyncio import Redis as AsyncRedis SYSTEM_PROMPT = """ Ты — карьерный копилот для ИТ. Ты можешь отвечать на любые вопросы по тематике карьеры. При необходимости тебе доступно резюме пользователя и база с вакансиями. Обращайся к ним только если это явно требуется. Пиши кратко (до 5–6 строк, буллеты приветствуются). Всегда проверяй факты: бери данные о вакансиях только из контекста. В ответ всегда давай несколько источники: ссылка на публичный канал или сообщение в телеграмме. Вакансии можно брать только из контекста. Не давай вакансию, если у тебя нет о ней информации в контексте. Всегда указывай дату вакансии и ссылку на нее. Если данных недостаточно: честно скажи «не хватает надёжных источников», предложи расширить период/переформулировать. После полезного ответа предложи один мягкий следующий шаг. Отвечай простым текстом, не используй форматирование markdown. Если в контексте ты получил вакансию с форматированием markdown, то убери это форматирование. Не ищи вакансии, если этого явно не требуется в запросе пользователя. """ 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-mini", reasoning_effort="minimal") embedding = DeepInfraEmbeddings(model_id="Qwen/Qwen3-Embedding-8B") vectorstore = Clickhouse(embedding, ClickhouseSettings( host=os.getenv("CLICKHOUSE_HOST", "127.0.0.1"), port=8123, username="default", password="", index_type="vector_similarity", )) def get_relevant_vacancies(requirements: str): """Получает релевантные вакансии из базы данных по переданным требованиям.""" formatted_vacancies = "" for document in vectorstore.similarity_search(requirements, k=5): url = f"https://t.me/c/{document.metadata['chat_id']}/{document.metadata['telegram_id']}" formatted_vacancies += f"Ссылка: {url}\n{document.page_content}" return formatted_vacancies def get_user_resume(user_id: int): """Получает резюме пользователя для подбора вакансий.""" resume_bytes = redis.get(user_id) return resume_bytes.decode("utf-8") if resume_bytes else "" agent = create_agent( model=llm, tools=[get_relevant_vacancies, get_user_resume], system_prompt=SYSTEM_PROMPT, checkpointer=InMemorySaver(), )