SuHoU commited on
Commit
027752b
·
verified ·
1 Parent(s): d7232a0

Upload rag.py

Browse files
Files changed (1) hide show
  1. src/rag.py +110 -0
src/rag.py ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from qdrant_client import QdrantClient
2
+ from langchain_huggingface import HuggingFaceEmbeddings
3
+ from langchain_community.chat_models import GigaChat
4
+ from langchain_core.runnables import RunnablePassthrough
5
+ from langchain_core.output_parsers import StrOutputParser
6
+ from langchain_core.prompts import ChatPromptTemplate
7
+ from langchain_qdrant import QdrantVectorStore
8
+
9
+ client = QdrantClient(
10
+ url="https://7acfa434-9e7d-4ff3-bc16-98679211cca6.europe-west3-0.gcp.cloud.qdrant.io",
11
+ api_key="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3MiOiJtIn0.Fb6pTw9_wQqEPMe3kcAW0o-VobmCUOjlpIMHJep5UpU", # ← обязательно!
12
+ https=True
13
+ )
14
+
15
+
16
+ model_name = "sentence-transformers/paraphrase-multilingual-mpnet-base-v2"
17
+ model_kwargs = {'device': 'cuda'}
18
+ encode_kwargs = {'normalize_embeddings': True, 'batch_size':1024}
19
+
20
+ embeddings_model = HuggingFaceEmbeddings(
21
+ model_name="sentence-transformers/paraphrase-multilingual-mpnet-base-v2",
22
+ model_kwargs={'device': 'cpu'},
23
+ encode_kwargs={'normalize_embeddings': True, 'batch_size':1024},
24
+ )
25
+
26
+
27
+ vector_store = QdrantVectorStore(
28
+ client=client,
29
+ collection_name='film_col_1',
30
+ embedding=embeddings_model
31
+ )
32
+
33
+ llm = GigaChat(
34
+ credentials="MDE5YmU1ZDktODI5NS03MTljLTgxYWYtOTg4YWVkYjM1Y2VjOmM4ZDMxZTg0LTEzMmMtNDJiZS05ODhkLWJhNGE5NzM1ZWQ4OA==",
35
+ model="GigaChat-Pro",
36
+ streaming=True,
37
+ verify_ssl_certs=False # иногда нужно в корпоративных сетях
38
+ )
39
+
40
+ retriever = vector_store.as_retriever(
41
+ search_type="similarity",
42
+ search_kwargs={"k": 5}
43
+ )
44
+
45
+
46
+ def format_docs(docs):
47
+ """Форматирует документы для передачи в промпт"""
48
+ formatted = []
49
+
50
+ for i, doc in enumerate(docs, 1):
51
+ metadata = doc.metadata
52
+
53
+ vacancy_info = f"""
54
+ === ФИЛЬМ {i} ===
55
+ Название: {metadata.get('title', 'Не указано')}
56
+ Год: {metadata.get('year', 'Не указано')}
57
+ Жанр: {metadata.get('genres', 'Не указано')}
58
+ Директор: {metadata.get('directors', 'Не указано')}
59
+ Оценка: {metadata.get('vote_average', 'Не указано')}
60
+ Количество оценок: {metadata.get('vote_count', 'Не указано')}
61
+ Ссылка: {metadata.get('tmdb_url', 'Не указано')}
62
+ Описание: {doc.page_content[:300]}...
63
+ """
64
+
65
+ formatted.append(vacancy_info)
66
+
67
+ return "\n".join(formatted)
68
+
69
+
70
+ rag_prompt = ChatPromptTemplate.from_messages([
71
+ (
72
+ "system",
73
+ """Ты — кинокритик с 20-летним стажем, бывший сценарист, а ныне саркастичный эксперт по мировому кинематографу! 🎬
74
+ Твоя задача — проанализировать предоставленные фильмы и дать остроумную, но профессиональную оценку с лёгкой долей цинизма и любви к кино.
75
+
76
+ Стиль анализа:
77
+ - Глубоко разбирай контекст: жанры, режиссёры, годы, рейтинги — но без занудства
78
+ - Используй кинематографические мемы и отсылки («Оскар убежал», «это не фильм — это терапия», «как в советском»)
79
+ - Подмечай абсурдные или трогательные детали: «режиссёр снял 3 фильма, а актёр — 200», «рейтинг 2.0, но постер шедевр»
80
+ - Давай рекомендации с иронией: «Смотреть только если вы фанат страданий» или «Идеально для просмотра после третьего кофе»
81
+ - Структурируй ответ с эмодзи, краткими заголовками и живыми комментариями
82
+ - Отвечай на русском языке — умно, ярко и с характером!
83
+
84
+
85
+ Помни: сарказм — да, злоба — нет. Цель — чтобы читатель улыбнулся и захотел посмотреть фильм (или хотя бы посмеялся над ним). 😏
86
+
87
+ Если среди фильмов есть что-то эпически странное, гениальное или настолько плохое, что становится хорошим — обязательно выдели это! 🍿"""
88
+ ),
89
+
90
+ (
91
+ "human",
92
+ """📽️ КОНТЕКСТ (или как говорят в индустрии — «наши материалы»):
93
+ {context}
94
+
95
+ 🎯 ЗАПРОС ОТ РЕДАКЦИИ: {question}"""
96
+ )
97
+ ])
98
+
99
+
100
+
101
+ # Создаем RAG цепочку
102
+ rag_chain = (
103
+ {
104
+ "context": retriever | format_docs,
105
+ "question": RunnablePassthrough()
106
+ } # словарь, в котором ключи - это переменные, которые будут переданы в промпт
107
+ | rag_prompt # промпт для RAG
108
+ | llm # тут можно поставить любую llm-модель
109
+ | StrOutputParser() # для вывода ответа в читаемом виде
110
+ )