Switch bot agent to Postgres checkpointer

This commit is contained in:
estromenko 2025-11-01 17:39:17 +03:00
parent ac3b2a27d5
commit c8a9a1123c
5 changed files with 645 additions and 603 deletions

View File

@ -11,6 +11,7 @@ dependencies = [
"langchain>=0.3.27", "langchain>=0.3.27",
"langchain-openai>=0.3.35", "langchain-openai>=0.3.35",
"langchain-qdrant>=1.1.0", "langchain-qdrant>=1.1.0",
"langgraph-checkpoint-postgres>=3.0.0",
"psycopg[binary]>=3.2.12", "psycopg[binary]>=3.2.12",
"pydantic>=2.0", "pydantic>=2.0",
"pypdf>=6.1.2", "pypdf>=6.1.2",

1204
uv.lock

File diff suppressed because it is too large Load Diff

View File

@ -90,6 +90,8 @@ DATABASES = {
}, },
} }
DB_URI = f"postgres://{DATABASES['default']['USER']}:{DATABASES['default']['PASSWORD']}@{DATABASES['default']['HOST']}:{DATABASES['default']['PORT']}/{DATABASES['default']['NAME']}?sslmode=disable"
# Password validation # Password validation
# https://docs.djangoproject.com/en/5.2/ref/settings/#auth-password-validators # https://docs.djangoproject.com/en/5.2/ref/settings/#auth-password-validators

View File

@ -7,8 +7,9 @@ from pypdf import PdfReader
from vacancies.main.models import Customer, CustomerCV from vacancies.main.models import Customer, CustomerCV
from langchain.agents import create_agent from langchain.agents import create_agent
from langchain_openai import ChatOpenAI from langchain_openai import ChatOpenAI
from langgraph.checkpoint.memory import InMemorySaver from langgraph.checkpoint.postgres.aio import AsyncPostgresSaver
from vacancies.main.vector_store import add_vectors, extract_features from vacancies.main.vector_store import add_vectors, extract_features
from vacancies.conf.settings import DB_URI
SYSTEM_PROMPT = """ SYSTEM_PROMPT = """
Ты карьерный копилот для ИТ. Ты можешь отвечать на любые вопросы по тематике карьеры. Ты карьерный копилот для ИТ. Ты можешь отвечать на любые вопросы по тематике карьеры.
@ -25,14 +26,6 @@ async def get_user_resume(user_id: int):
return customer_cv.content if customer_cv else "" return customer_cv.content if customer_cv else ""
agent = create_agent(
model=ChatOpenAI(model_name="gpt-5-mini", reasoning_effort="minimal"),
tools=[get_user_resume],
system_prompt=SYSTEM_PROMPT,
checkpointer=InMemorySaver(),
)
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE): async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
await Customer.objects.aget_or_create( await Customer.objects.aget_or_create(
telegram_id=update.effective_user.id, telegram_id=update.effective_user.id,
@ -46,6 +39,14 @@ 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):
async with AsyncPostgresSaver.from_conn_string(DB_URI) as checkpointer:
agent = create_agent(
model=ChatOpenAI(model_name="gpt-5-mini", reasoning_effort="minimal"),
tools=[get_user_resume],
system_prompt=SYSTEM_PROMPT,
checkpointer=checkpointer,
)
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 agent.ainvoke(

View File

@ -1,9 +1,19 @@
import sys
import asyncio
from django.core.management import BaseCommand from django.core.management import BaseCommand
from vacancies.main.bot import application from vacancies.main.bot import application
from langgraph.checkpoint.postgres import PostgresSaver
from vacancies.conf.settings import DB_URI
class Command(BaseCommand): class Command(BaseCommand):
help = "Run bot" help = "Run bot"
def handle(self, *args, **options): def handle(self, *args, **options):
with PostgresSaver.from_conn_string(DB_URI) as checkpointer:
checkpointer.setup()
if sys.platform == "win32":
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
application.run_polling() application.run_polling()