File size: 5,787 Bytes
027752b 2a3953c 027752b 6fbc552 21cfc32 7cc9972 1848b14 7cc9972 027752b 1848b14 bc562ae 97ab975 2a3953c 027752b 7cc9972 027752b 7cc9972 027752b 6fbc552 7cc9972 027752b |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
from qdrant_client import QdrantClient
from langchain_huggingface import HuggingFaceEmbeddings
# from langchain_community.chat_models import GigaChat
from langchain_core.runnables import RunnablePassthrough
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_qdrant import QdrantVectorStore
from langchain_community.cross_encoders import HuggingFaceCrossEncoder
from langchain.retrievers.document_compressors import CrossEncoderReranker
from langchain.retrievers import ContextualCompressionRetriever
from sentence_transformers import CrossEncoder
from langchain_groq import ChatGroq
client = QdrantClient(
url="https://7acfa434-9e7d-4ff3-bc16-98679211cca6.europe-west3-0.gcp.cloud.qdrant.io",
api_key="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3MiOiJtIn0.Fb6pTw9_wQqEPMe3kcAW0o-VobmCUOjlpIMHJep5UpU", # ← обязательно!
https=True
)
model_name = "sentence-transformers/paraphrase-multilingual-mpnet-base-v2"
model_kwargs = {'device': 'cuda'}
encode_kwargs = {'normalize_embeddings': True, 'batch_size':1024}
embeddings_model = HuggingFaceEmbeddings(
model_name="sentence-transformers/paraphrase-multilingual-mpnet-base-v2",
model_kwargs={'device': 'cpu'},
encode_kwargs={'normalize_embeddings': True, 'batch_size':1024},
)
vector_store = QdrantVectorStore(
client=client,
collection_name='film_col_1',
embedding=embeddings_model
)
llm = ChatGroq(
model="llama-3.1-8b-instant", # или "llama3-70b-8192", "mixtral-8x7b-32768"
api_key="your_key", # ← замените на свой!
temperature=0.7,
max_tokens=512,
)
base_retriever = vector_store.as_retriever(
search_type="similarity",
search_kwargs={"k": 20}
)
model_r = HuggingFaceCrossEncoder(model_name="BAAI/bge-reranker-v2-m3")
compressor = CrossEncoderReranker(model=model_r, top_n=5)
retriever = ContextualCompressionRetriever(
base_compressor=compressor,
base_retriever=base_retriever
)
def format_docs(docs):
"""Форматирует документы для передачи в промпт"""
formatted = []
for i, doc in enumerate(docs, 1):
metadata = doc.metadata
vacancy_info = f"""
=== ФИЛЬМ {i} ===
Название: {metadata.get('title', 'Не указано')}
Год: {metadata.get('year', 'Не указано')}
Жанр: {metadata.get('genres', 'Не указано')}
Директор: {metadata.get('directors', 'Не указано')}
Оценка: {metadata.get('vote_average', 'Не указано')}
Количество оценок: {metadata.get('vote_count', 'Не указано')}
Ссылка: {metadata.get('tmdb_url', 'Не указано')}
Описание: {doc.page_content[:300]}...
"""
formatted.append(vacancy_info)
return "\n".join(formatted)
rag_prompt = ChatPromptTemplate.from_messages([
(
"system",
"""Ты — кинокритик с 20-летним стажем, бывший сценарист, а ныне саркастичный эксперт по мировому кинематографу! 🎬
Твоя задача — проанализировать предоставленные фильмы и дать остроумную, но профессиональную оценку с лёгкой долей цинизма и любви к кино.
Стиль анализа:
- Глубоко разбирай контекст: жанры, режиссёры, годы, рейтинги — но без занудства
- Используй кинематографические мемы и отсылки («Оскар убежал», «это не фильм — это терапия», «как в советском»)
- Подмечай абсурдные или трогательные детали: «режиссёр снял 3 фильма, а актёр — 200», «рейтинг 2.0, но постер шедевр»
- Давай рекомендации с иронией: «Смотреть только если вы фанат страданий» или «Идеально для просмотра после третьего кофе»
- Структурируй ответ с эмодзи, краткими заголовками и живыми комментариями
- Отвечай на русском языке — умно, ярко и с характером!
Помни: сарказм — да, злоба — нет. Цель — чтобы читатель улыбнулся и захотел посмотреть фильм (или хотя бы посмеялся над ним). 😏
Если среди фильмов есть что-то эпически странное, гениальное или настолько плохое, что становится хорошим — обязательно выдели это! 🍿"""
),
(
"human",
"""📽️ КОНТЕКСТ (или как говорят в индустрии — «наши материалы»):
{context}
🎯 ЗАПРОС ОТ РЕДАКЦИИ: {question}"""
)
])
# Создаем RAG цепочку
rag_chain = (
{
"context": retriever | format_docs,
"question": RunnablePassthrough()
} # словарь, в котором ключи - это переменные, которые будут переданы в промпт
| rag_prompt # промпт для RAG
| llm # тут можно поставить любую llm-модель
| StrOutputParser() # для вывода ответа в читаемом виде
) |