Поделиться через


Использование LangChain с базой данных Azure для PostgreSQL

База данных Azure для PostgreSQL легко интегрируется с ведущими пакетами оркестрации большой языковой модели (LLM), такими как LangChain. Эта интеграция позволяет разработчикам использовать расширенные возможности искусственного интеллекта в своих приложениях. LangChain может упростить управление и использование LLM, моделей встраивания и баз данных, чтобы разработка приложений ИИ стала проще.

В этой статье показано, как использовать интегрированную базу данных векторов в Базе данных Azure для PostgreSQL для хранения документов и управления ими в коллекциях с помощью LangChain. В нем также показано, как создавать индексы и выполнять векторные запросы на поиск, используя алгоритмы ближайшего соседа, такие как косинусное расстояние, Евклидово расстояние (расстояние L2), а также внутренний продукт, для поиска документов, похожих на запросные вектора.

Поддержка векторов

Базу данных Azure для PostgreSQL можно использовать для эффективного хранения и выполнения запросов миллионов векторных представлений в PostgreSQL. Данный сервис поможет вам масштабировать варианты использования ИИ от доказательства концепции до промышленной эксплуатации. Он предлагает следующие преимущества:

  • Предоставляет знакомый интерфейс SQL для запросов векторных представлений и реляционных данных.
  • Ускоряет pgvector благодаря более быстрому и более точному поиску сходства по более чем 100 миллионам векторов с использованием алгоритма индексирования DiskANN.
  • Упрощает операции за счет интеграции реляционных метаданных, векторных встраиваний и данных временных рядов в одну базу данных.
  • Использует возможности надежной экосистемы PostgreSQL и облачной платформы Azure для функций корпоративного уровня, включая репликацию и высокий уровень доступности.

Аутентификация

База данных Azure для PostgreSQL поддерживает проверку подлинности на основе паролей и Microsoft Entra (прежнее название — Azure Active Directory).

Проверка подлинности Microsoft Entra позволяет использовать идентификатор Microsoft Entra для проверки подлинности на сервере PostgreSQL. Идентификатор Microsoft Entra устраняет необходимость управления отдельными именами пользователей и паролями для пользователей базы данных. Он позволяет использовать те же механизмы безопасности, которые используются для других служб Azure.

В этой статье можно использовать любой метод проверки подлинности.

Настройка

Azure Database для PostgreSQL использует поддержку LangChain Postgres с открытым исходным кодом для подключения к Azure Database для PostgreSQL. Сначала скачайте пакет партнера:

%pip install -qU langchain-azure-postgresql
%pip install -qU langchain-openai
%pip install -qU azure-identity

Включение pgvector в Базе данных Azure для PostgreSQL

См. раздел "Включение и использование pgvector" в Базе данных Azure для PostgreSQL.

Настройка учетных данных

Необходимо получить сведения о подключении базы данных Azure для PostgreSQL и добавить их в качестве переменных среды.

Задайте для флага USE_ENTRA_AUTH значение True, если вы хотите использовать аутентификацию Microsoft Entra. Если вы используете проверку подлинности Microsoft Entra, необходимо указать только имена узлов и баз данных. Если вы используете проверку подлинности паролей, необходимо также задать имя пользователя и пароль.

import getpass
import os

USE_ENTRA_AUTH = True

# Supply the connection details for the database
os.environ["DBHOST"] = "<server-name>"
os.environ["DBNAME"] = "<database-name>"
os.environ["SSLMODE"] = "require"

if not USE_ENTRA_AUTH:
    # If you're using a username and password, supply them here
    os.environ["DBUSER"] = "<username>"
    os.environ["DBPASSWORD"] = getpass.getpass("Database Password:")

Настройка внедрения Azure OpenAI

os.environ["AZURE_OPENAI_ENDPOINT"] = "<azure-openai-endpoint>"
os.environ["AZURE_OPENAI_API_KEY"] = getpass.getpass("Azure OpenAI API Key:")
AZURE_OPENAI_ENDPOINT = os.environ["AZURE_OPENAI_ENDPOINT"]
AZURE_OPENAI_API_KEY = os.environ["AZURE_OPENAI_API_KEY"]

from langchain_openai import AzureOpenAIEmbeddings

embeddings = AzureOpenAIEmbeddings(
    model="text-embedding-3-small",
    api_key=AZURE_OPENAI_API_KEY,
    azure_endpoint=AZURE_OPENAI_ENDPOINT,
    azure_deployment="text-embedding-3-small",
)

Инициализация

Используйте проверку подлинности Microsoft Entra

В следующих разделах показано, как настроить LangChain для использования проверки подлинности Microsoft Entra. Класс AzurePGConnectionPool в пакете LangChain Azure Postgres извлекает маркеры для службы Базы данных Azure для PostgreSQL с помощью DefaultAzureCredential библиотеки azure.identity .

Соединение можно передать в connection параметр векторного AzurePGVectorStore хранилища LangChain.

Вход в Azure

Чтобы войти в Azure, убедитесь, что у вас установлен Azure CLI . Выполните следующую команду в терминале:

az login

После входа в систему следующий код извлекает маркер:

from langchain_azure_postgresql.common import (
    BasicAuth,
    AzurePGConnectionPool,
    ConnectionInfo,
)
from langchain_azure_postgresql.langchain import AzurePGVectorStore
entra_connection_pool = AzurePGConnectionPool(
        azure_conn_info=ConnectionInfo(
            host=os.environ["DBHOST"],
            dbname=os.environ["DBNAME"]
        )
    )

Использование проверки подлинности паролей

Если вы не используете проверку подлинности Microsoft Entra, BasicAuth класс позволяет использовать имя пользователя и пароль:

basic_auth_connection_pool = AzurePGConnectionPool(
    azure_conn_info=ConnectionInfo(
        host=os.environ["DBHOST"],
        dbname=os.environ["DBNAME"],
        credentials=BasicAuth(
            username=os.environ["DBUSER"],
            password=os.environ["DBPASSWORD"],
        )
    )
)

Создание хранилища векторов

from langchain_core.documents import Document
from langchain_azure_postgresql.langchain import AzurePGVectorStore

collection_name = "my_docs"

# The connection is either using Entra ID or Basic Auth
connection = entra_connection_pool if USE_ENTRA_AUTH else basic_auth_connection_pool

vector_store = AzurePGVectorStore(
    embeddings=embeddings,
    table_name=table_name,
    connection=connection,
)

Управление хранилищем векторов

Добавление элементов в векторное хранилище

Добавление документов по идентификатору перезаписывает все существующие документы, соответствующие идентификатору.

docs = [
    Document(
        page_content="there are cats in the pond",
        metadata={"doc_id": 1, "location": "pond", "topic": "animals"},
    ),
    Document(
        page_content="ducks are also found in the pond",
        metadata={"doc_id": 2, "location": "pond", "topic": "animals"},
    ),
    Document(
        page_content="fresh apples are available at the market",
        metadata={"doc_id": 3, "location": "market", "topic": "food"},
    ),
    Document(
        page_content="the market also sells fresh oranges",
        metadata={"doc_id": 4, "location": "market", "topic": "food"},
    ),
    Document(
        page_content="the new art exhibit is fascinating",
        metadata={"doc_id": 5, "location": "museum", "topic": "art"},
    ),
    Document(
        page_content="a sculpture exhibit is also at the museum",
        metadata={"doc_id": 6, "location": "museum", "topic": "art"},
    ),
    Document(
        page_content="a new coffee shop opened on Main Street",
        metadata={"doc_id": 7, "location": "Main Street", "topic": "food"},
    ),
    Document(
        page_content="the book club meets at the library",
        metadata={"doc_id": 8, "location": "library", "topic": "reading"},
    ),
    Document(
        page_content="the library hosts a weekly story time for kids",
        metadata={"doc_id": 9, "location": "library", "topic": "reading"},
    ),
    Document(
        page_content="a cooking class for beginners is offered at the community center",
        metadata={"doc_id": 10, "location": "community center", "topic": "classes"},
    ),
]

uuids = vector_store.add_documents(docs)
uuids

Обновление элементов в хранилище векторов

updated_docs = [
    Document(
        page_content="Updated - cooking class for beginners is offered at the community center",
        metadata={"doc_id": 10, "location": "community center", "topic": "classes"},
        id=uuids[-1],
    )
]
vector_store.add_documents(docs, ids=[uuids[-1]], on_conflict_update=True)

Просмотр элементов из векторного хранилища

vector_store.get_by_ids([str(uuids[-1])])

Удаление элементов из хранилища векторов

vector_store.delete(ids=[uuids[-1]])

Запросы к хранилищу векторов

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

Поддержка фильтрации

Хранилище векторов поддерживает набор фильтров, которые можно применить к полям метаданных документов с помощью FilterConditionпакета OrFilterAndFilterLangChain Azure PostgreSQL:

Оператор Значение или категория
= Равенство (==)
!= Неравенство (!=)
< Меньше (<)
<= Меньше или равно (<=)
> Больше (>)
>= Больше или равно (>=)
in Особый регистр (в)
not in Особая обработка (не включено)
is null Особый регистр (имеет значение NULL)
is not null Особый регистр (не имеет значения NULL)
between Особая обработка регистров (между)
not between Особый регистр (не между)
like Текст (например)
ilike Текст (без учета регистра)
AND Логические (и)
OR Логический (или)

Прямой запрос

Вы можете выполнить простой поиск сходства следующим образом:

from langchain_azure_postgresql import FilterCondition, AndFilter

results = vector_store.similarity_search(
    "kitty",
    k=10,
    filter=FilterCondition(
        column="(metadata->>'doc_id')::int",
        operator="in",
        value=[1, 5, 2, 9],
    ),
)

for doc in results:
    print(f"* {doc.page_content} [{doc.metadata}]")
    * there are cats in the pond [{'doc_id': 1, 'topic': 'animals', 'location': 'pond'}]
    * ducks are also found in the pond [{'doc_id': 2, 'topic': 'animals', 'location': 'pond'}]
    * the new art exhibit is fascinating [{'doc_id': 5, 'topic': 'art', 'location': 'museum'}]
    * the library hosts a weekly story time for kids [{'doc_id': 9, 'topic': 'reading', 'location': 'library'}]

Если вы предоставляете словарь с несколькими полями, но без операторов, верхний уровень интерпретируется как логический AND фильтр:

results = vector_store.similarity_search(
    "ducks",
    k=10,
    filter=AndFilter(
        AND=[
            FilterCondition(
                column="(metadata->>'doc_id')::int",
                operator="in",
                value=[1, 5, 2, 9],
            ),
            FilterCondition(
                column="metadata->>'location'",
                operator="in",
                value=["pond", "market"],
            ),
        ]
    ),
)

for doc in results:
    print(f"* {doc.page_content} [{doc.metadata}]")
    * ducks are also found in the pond [{'topic': 'animals', 'doc_id': 2, 'location': 'pond'}]
    * there are cats in the pond [{'topic': 'animals', 'doc_id': 1, 'location': 'pond'}]

Если вы хотите выполнить поиск сходства и получить соответствующие оценки, можно выполнить следующее:

results = vector_store.similarity_search_with_score(query="cats", k=1)
for doc, score in results:
    print(f"* [SIM={score:3f}] {doc.page_content} [{doc.metadata}]")
* [SIM=0.528338] there are cats in the pond [{'doc_id': 1, 'topic': 'animals', 'location': 'pond'}]

Если вы хотите использовать поиск максимальной маргинальной релевантности в хранилище векторов:

results = vector_store.max_marginal_relevance_search(
    "query about cats",
    k=10,
    lambda_mult=0.5,
    filter=FilterCondition(
        column="(metadata->>'doc_id')::int",
        operator="in",
        value=[1, 2, 5, 9],
    ),
)

for doc in results:
    print(f"* {doc.page_content} [{doc.metadata}]")
    * there are cats in the pond [{'doc_id': 1, 'topic': 'animals', 'location': 'pond'}]
    * ducks are also found in the pond [{'doc_id': 2, 'topic': 'animals', 'location': 'pond'}]
    * the new art exhibit is fascinating [{'doc_id': 5, 'topic': 'art', 'location': 'museum'}]
    * the library hosts a weekly story time for kids [{'doc_id': 9, 'topic': 'reading', 'location': 'library'}]

Полный список поисковых запросов, которые можно выполнить в PGVector хранилище векторов, см. в справочнике по API.

Преобразование в ретривер

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

retriever = vector_store.as_retriever(search_type="mmr", search_kwargs={"k": 1})
retriever.invoke("kitty")
[Document(id='9fe8bc1c-9a8e-4f83-b546-9b64527aa79d', metadata={'doc_id': 1, 'topic': 'animals', 'location': 'pond'}, page_content='there are cats in the pond')]