ym88659208ym87991671
Векторные хранилища и ретриверы | Документация для разработчиков

Векторные хранилища и ретриверы

Обновлено 28 ноября 2024

В этом разделе вы узнаете, как использовать GigaChain для работы с векторными хранилищам и ретриверами. Ретриверы и векторные хранилища важны для приложений, которые извлекают данные для рассуждений в рамках инференса модели, например, в случае генерации с дополнением извлечения данных или RAG.

Основные понятия

В этом разделе основное внимание уделяется извлечению текстовых данных. Основные понятия:

  • документы;
  • векторные хранилища;
  • ретриверы.

Подготовка к разработке

Jupyter-блокноты

Как и большинство других руководств в документации, этот раздел использует Jupyter-блокнот. Блокноты отлично подходят для изучения работы с LLM-системами, так как предоставляют интерактивную среду для работы с руководствами и позволяют работать с непредвиденными ситуациями, например недоступностью API или нетипичным выводом.

Подробнее об установке Jupyter — в официальной документации.

Установка

Установите пакеты, которые понадобятся для работы с примерами:

pip install langchain-gigachat langchain-chroma

Подробнее об установке GigaChain — в разделе Установка.

Документы

GigaChain реализует класс Document, который представляет единицу текста и связанные с ним метаданные. У этого класса есть два атрибута:

  • page_content — строка, представляющая содержимое;
  • metadata — словарь, содержащий произвольные метаданные.

Атрибут metadata может содержать данные об источнике документа, его связи с другими документами и другую дополнительную информацию. Отдельный объект Document часто представляет фрагмент более крупного документа.

Создайте несколько образцов документов:

from langchain_core.documents import Document

documents = [
Document(
page_content="Собаки — отличные компаньоны, которые известны своей преданностью и дружелюбием.",
metadata={"source": "mammal-pets-doc"},
),
Document(
page_content="Кошки — независимые животные, которым нужно собственное пространство.",
metadata={"source": "mammal-pets-doc"},
),
Document(
page_content="Золотые рыбки — отличные домашние животные для начинающих. За ними достаточно просто ухаживать.",
metadata={"source": "fish-pets-doc"},
),
Document(
page_content="Попугаи — умные птицы, которые способны имитировать человеческую речь.",
metadata={"source": "bird-pets-doc"},
),
Document(
page_content="Кролики — социальные животные, которым нужно много места, чтобы прыгать.",
metadata={"source": "mammal-pets-doc"},
),
]

В примере выше представлено пять документов с дополнительными данными, которые указывают на три различных источника (source).

Векторные хранилища

Векторный поиск — это распространенный способ поиска по сохраненным неструктурированным данным, например, неструктурированному тексту. В основе поиска лежит работа с сохраненными числовыми векторами, которые ассоциированы с текстом. При запросе к хранилищу, вы можете представить текст запроса в виде вектора той же размерности и использовать метрики векторной схожести для поиска подходящих данных в хранилище.

Объекты VectorStore предоставляют методы для добавления текста и объектов Document в хранилище, а так же методы для поиска документов в хранилище с использованием различных метрик схожести. Как правило, хранилища инициализируются с использованием моделей, которые поддерживают векторное представление текста. Такие модели определяют, как текстовые данные переводятся в числовые векторы.

GigaChain предоставляет набор интеграций с различными векторными хранилищами. Некоторые из них могут требовать соответствующие учетные данные для использования. Другие, такие как Postgres, работают в отдельной инфраструктуре, которую можно запускать локально или через сторонние сервисы. Какие-то могут работать в памяти и используются для легких нагрузок.

В этом разделе показана работа объектов VectorStore с использованием Chroma — векторным хранилищем, которое поддерживает работу в памяти.

Как правило, для создания векторного хранилища нужно предоставить модель, которая будет отвечать за векторное представление текста.

Примере для создания векторного представления текста используется модель GigaChat Embeddings.

from langchain_chroma import Chroma
from langchain_gigachat.embeddings.gigachat import GigaChatEmbeddings

vectorstore = Chroma.from_documents(
documents,
embedding=GigaChatEmbeddings(
credentials="ключ_авторизации",
scope="GIGACHAT_API_PERS",
verify_ssl_certs=False,
),
)

Авторизационные данные — строка, полученная в результате кодирования в Base64 клиентского идентификатора (Client ID) и ключа (Client Secret) API. Вы можете использовать готовые данные из личного кабинета или самостоятельно закодировать идентификатор и ключ.

Пример строки авторизационных данных:

MjIzODA0YTktMDU3OC00MTZmLWI4MWYtYzUwNjg3Njk4MzMzOjljMTI2MGQyLTFkNTEtNGRkOS05ZGVhLTBhNjAzZTdjZjQ3Mw==

Идентификатор, ключ и авторизационные данные вы можете получить после создания проекта GigaChat API:

Вызов метода .from_documents добавляет документы в векторное хранилище. Объект VectorStore предоставляет методы для добавления документов, которые также можно вызвать после создания объекта. Большинство интеграций позволяет подключаться к существующему векторному хранилищу, например, предоставив клиент, название индекса или другую информацию.

После создания объекта VectorStore с необходимыми документами, вы можете выполнять поиск по ним. Объект VectorStore включает методы для выполнения запросов:

  • синхронно и асинхронно;
  • по текстовому запросу и по его вектору;
  • с возвращением и без возвращения оценок схожести;
  • по схожести и максимальной маржинальной релевантности, которая позволяет сбалансировать схожесть с разнообразием в извлеченных результатах.

В общем случае результат работы методов будет содержать объектов Document.

Примеры

Возврат документов на основе схожести с текстовым запросом:

vectorstore.similarity_search("кошка")
    [Document(metadata={'source': 'mammal-pets-doc'}, page_content='Кошки — независимые животные, которым нужно собственное пространство.'),
Document(metadata={'source': 'mammal-pets-doc'}, page_content='Собаки — отличные компаньоны, которые известны своей преданностью и дружелюбием.'),
Document(metadata={'source': 'mammal-pets-doc'}, page_content='Кролики — социальные животные, которым нужно много места, чтобы прыгать.'),
Document(metadata={'source': 'bird-pets-doc'}, page_content='Попугаи — умные птицы, которые способны имитировать человеческую речь.')]

Асинхронный запрос:

await vectorstore.asimilarity_search("кошка")
    [Document(metadata={'source': 'mammal-pets-doc'}, page_content='Кошки — независимые животные, которым нужно собственное пространство.'),
Document(metadata={'source': 'mammal-pets-doc'}, page_content='Собаки — отличные компаньоны, которые известны своей преданностью и дружелюбием.'),
Document(metadata={'source': 'mammal-pets-doc'}, page_content='Кролики — социальные животные, которым нужно много места, чтобы прыгать.'),
Document(metadata={'source': 'bird-pets-doc'}, page_content='Попугаи — умные птицы, которые способны имитировать человеческую речь.')]

Оценка схожести запроса и содержимого хранилища:

# Оценка зависит от выбранного векторного хранилища.
# Chroma возвращает метрику расстояния, которая должна варьироваться обратно пропорционально схожести.

vectorstore.similarity_search_with_score("кошка")
    [(Document(metadata={'source': 'mammal-pets-doc'}, page_content='Кошки — независимые животные, которым нужно собственное пространство.'),
218.2356719970703),
(Document(metadata={'source': 'mammal-pets-doc'}, page_content='Собаки — отличные компаньоны, которые известны своей преданностью и дружелюбием.'),
319.75384521484375),
(Document(metadata={'source': 'mammal-pets-doc'}, page_content='Кролики — социальные животные, которым нужно много места, чтобы прыгать.'),
349.84930419921875),
(Document(metadata={'source': 'bird-pets-doc'}, page_content='Попугаи — умные птицы, которые способны имитировать человеческую речь.'),
352.6993103027344)]

Возврат документов на основе схожести с запросом, представленным в виде вектора:

embedding = GigaChatEmbeddings(
credentials="ключ_авторизации",
scope="GIGACHAT_API_PERS",
verify_ssl_certs=False,
).embed_query("кошка")

vectorstore.similarity_search_by_vector(embedding)
    [Document(metadata={'source': 'mammal-pets-doc'}, page_content='Кошки — независимые животные, которым нужно собственное пространство.'),
Document(metadata={'source': 'mammal-pets-doc'}, page_content='Собаки — отличные компаньоны, которые известны своей преданностью и дружелюбием.'),
Document(metadata={'source': 'mammal-pets-doc'}, page_content='Кролики — социальные животные, которым нужно много места, чтобы прыгать.'),
Document(metadata={'source': 'bird-pets-doc'}, page_content='Попугаи — умные птицы, которые способны имитировать человеческую речь.')]

Больше информации о векторных хранилищах:

Ретриверы

Объекты VectorStore не являются Runnable-объектами и поэтому их нельзя использовать в LCEL-цепочках напрямую.

В то же время ретриверы GigaChain (Retrievers) — являются экземплярами Runnable, поэтому они реализуют стандартный набор методов (например, синхронные и асинхронные операции invoke и batch) и предназначены для включения в цепочки LCEL.

Вы можете самостоятельно создать ретривер, не прибегая к классу Retriever. Для этого нужно выбрать метод, который будет использоваться для извлечения документов, и создать Runnable. Пример ниже показывает, как создать ретривер, который использует метод similarity_search, на основе Runnable:

from typing import List

from langchain_core.documents import Document
from langchain_core.runnables import RunnableLambda

retriever = RunnableLambda(vectorstore.similarity_search).bind(
k=1
) # выбор наиболе подходящего результата

retriever.batch(["кошка", "акула"])
    [[Document(metadata={'source': 'mammal-pets-doc'}, page_content='Кошки — независимые животные, которым нужно собственное пространство.')],
[Document(metadata={'source': 'mammal-pets-doc'}, page_content='Собаки — отличные компаньоны, которые известны своей преданностью и дружелюбием.')]]

Векторные хранилища предоставляют метод as_retriever, который создаст экземпляр класса Retriever, а именно VectorStoreRetriever. Эти ретриверы включают заданные атрибуты search_type и search_kwargs, которые определяют, какие методы базового векторного хранилища вызывать и как задавать их параметры. Так, вы можете повторить функциональность из примера выше с помощью следующего кода:

retriever = vectorstore.as_retriever(
search_type="similarity",
search_kwargs={"k": 1},
)

retriever.batch(["кошка", "акула"])
    [[Document(metadata={'source': 'mammal-pets-doc'}, page_content='Кошки — независимые животные, которым нужно собственное пространство.')],
[Document(metadata={'source': 'mammal-pets-doc'}, page_content='Собаки — отличные компаньоны, которые известны своей преданностью и дружелюбием.')]]

VectorStoreRetriever поддерживает типы поиска "similarity" (по умолчанию), "mmr" (maximum marginal relevance, описано выше) и "similarity_score_threshold". Последний тип можно использовать для отсечки документов, выводимых ретривером, на основе оценки схожести.

Ретриверы можно легко включить в более сложные RAG-приложения, которые объединяют заданный вопрос с извлеченным контекстом в промпт для модели.

# | output: false
# | echo: false

from langchain_gigachat.chat_models import GigaChat

model = GigaChat(
credentials="ключ_авторизации",
scope="GIGACHAT_API_PERS",
model="GigaChat-Pro",
verify_ssl_certs=False,
)
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough

message = """
Отвечай на вопросы только с помощью полученного контекста.

{question}

Контекст:
{context}
"""

prompt = ChatPromptTemplate.from_messages([("human", message)])

rag_chain = {"context": retriever, "question": RunnablePassthrough()} | prompt | model
response = rag_chain.invoke("Расскажи о кошках")

print(response.content)
    Кошки – это независимые животные, которым требуется свое собственное пространство.
ПАО Сбербанк использует cookie для персонализации сервисов и удобства пользователей.
Вы можете запретить сохранение cookie в настройках своего браузера.