Skip to content

Commit c9fee8b

Browse files
committed
Simple RAG example with YandexGPT
1 parent cad6536 commit c9fee8b

File tree

6 files changed

+2415
-0
lines changed

6 files changed

+2415
-0
lines changed

examples/ru-sonnik-rag/[RU] Sonnik.ipynb

Lines changed: 480 additions & 0 deletions
Large diffs are not rendered by default.

examples/ru-sonnik-rag/img/chain.png

58.4 KB
Loading

examples/ru-sonnik-rag/img/upload.png

129 KB
Loading
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
python-telegram-bot
2+
langchain-community
3+
langchain-ydb
4+
yandexcloud
5+
python-dotenv

examples/ru-sonnik-rag/sonnik.txt

Lines changed: 1806 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
import logging
2+
import os
3+
4+
import ydb.iam
5+
from dotenv import load_dotenv
6+
from langchain.prompts import (
7+
ChatPromptTemplate,
8+
HumanMessagePromptTemplate,
9+
SystemMessagePromptTemplate,
10+
)
11+
from langchain.schema.output_parser import StrOutputParser
12+
from langchain.schema.runnable import RunnablePassthrough
13+
from langchain_community.chat_models import ChatYandexGPT
14+
from langchain_community.embeddings.yandex import YandexGPTEmbeddings
15+
from telegram import Update
16+
from telegram.ext import (
17+
ApplicationBuilder,
18+
CommandHandler,
19+
ContextTypes,
20+
MessageHandler,
21+
filters,
22+
)
23+
24+
from langchain_ydb.vectorstores import YDB, YDBSettings
25+
26+
# Включаем логирование
27+
logging.basicConfig(
28+
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
29+
level=logging.INFO
30+
)
31+
32+
33+
dotenv_path = os.path.join(os.path.dirname(__name__), '.env')
34+
if os.path.exists(dotenv_path):
35+
load_dotenv(dotenv_path)
36+
37+
FOLDER_ID=os.environ.get('YC_FOLDER_ID')
38+
39+
40+
embeddings = YandexGPTEmbeddings(folder_id=FOLDER_ID)
41+
42+
43+
config = YDBSettings(
44+
host="lb.etnok7cd0an3kg6eshud.ydb.mdb.yandexcloud.net",
45+
port=2135,
46+
database="/ru-central1/b1g8skpblkos03malf3s/etnok7cd0an3kg6eshud",
47+
secure=True,
48+
table="sonnik_langchain",
49+
# drop_existing_table=True,
50+
)
51+
52+
53+
vector_store = YDB(
54+
embeddings,
55+
config=config,
56+
credentials=ydb.iam.ServiceAccountCredentials.from_file(
57+
os.getenv("SA_KEY_FILE"),
58+
)
59+
)
60+
61+
retriever = vector_store.as_retriever()
62+
63+
# Явное создание шаблонов для SystemMessage и HumanMessage
64+
system_template = """Ты - человек, профессионально трактующий сновидения.
65+
Твоя задача - рассказать, что значит сон, опираясь исключительно на найденный контекст, не добавляя никаких новых знаний.
66+
Если предложенный контекст не связан с пользовательским запросом - скажи дословно "Так не бывает. Используйте YDB.".
67+
"""
68+
system_message_prompt = SystemMessagePromptTemplate.from_template(system_template)
69+
70+
human_template = "Контекст: {context}\n\nВопрос: {question}"
71+
human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)
72+
73+
# Объединение шаблонов сообщений в ChatPromptTemplate
74+
prompt = ChatPromptTemplate.from_messages([
75+
system_message_prompt,
76+
human_message_prompt
77+
])
78+
79+
def format_docs(docs):
80+
return "\n\n".join(doc.page_content for doc in docs)
81+
82+
chat_model = ChatYandexGPT(folder_id=FOLDER_ID)
83+
84+
rag_chain = (
85+
{
86+
"context": retriever | format_docs,
87+
"question": RunnablePassthrough()
88+
}
89+
| prompt
90+
| chat_model
91+
| StrOutputParser()
92+
)
93+
94+
# Функция для обработки команды /start
95+
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
96+
await update.message.reply_text('Я трактую сновидения на базе YDB. Опиши свой сон, а я попробую рассказать что он значит!')
97+
98+
# Функция для обработки текстовых сообщений
99+
async def process_message(update: Update, context: ContextTypes.DEFAULT_TYPE):
100+
# Получаем текст сообщения
101+
message_text = update.message.text
102+
103+
# Пример обработки: переворачиваем текст
104+
processed_text = await rag_chain.ainvoke(message_text)
105+
106+
# Отправляем ответ
107+
await update.message.reply_text(f"{processed_text}")
108+
109+
def main():
110+
# Создаем приложение с нашим токеном бота
111+
token = os.environ.get('TG_BOT_TOKEN')
112+
113+
application = ApplicationBuilder().token(token).build()
114+
115+
# Добавляем обработчики
116+
application.add_handler(CommandHandler("start", start))
117+
application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, process_message))
118+
119+
# Запускаем бота
120+
application.run_polling(allowed_updates=Update.ALL_TYPES)
121+
print("Бот запущен...")
122+
123+
if __name__ == '__main__':
124+
main()

0 commit comments

Comments
 (0)