Udostępnij za pomocą


Używanie biblioteki LangChain z usługą Azure Database for PostgreSQL

Usługa Azure Database for PostgreSQL bezproblemowo integruje się z wiodącymi pakietami aranżacji modelu języka (LLM), takimi jak LangChain. Ta integracja umożliwia deweloperom korzystanie z zaawansowanych funkcji sztucznej inteligencji w swoich aplikacjach. LangChain może usprawnić zarządzanie maszynami LLM i korzystanie z nich, osadzanie modeli i baz danych, dzięki czemu generowanie aplikacji sztucznej inteligencji jest łatwiejsze do opracowania.

W tym artykule pokazano, jak używać zintegrowanej bazy danych wektorowej w usłudze Azure Database for PostgreSQL do przechowywania dokumentów w kolekcjach i zarządzania nimi za pomocą biblioteki LangChain. Pokazuje również, jak tworzyć indeksy i wykonywać zapytania wyszukiwania wektorów przy użyciu algorytmów najbliższych sąsiadów, takich jak odległość kosinusowa, odległość L2 (odległość euklidesowa) i wewnętrzny iloczyn, aby lokalizować dokumenty blisko wektorów zapytań.

Obsługa wektorów

Można użyć Azure Database for PostgreSQL, aby efektywnie przechowywać miliony osadzeń wektorów i wykonywać zapytania w bazie PostgreSQL. Usługa może pomóc w skalowaniu przypadków użycia sztucznej inteligencji z weryfikacji koncepcji do środowiska produkcyjnego. Oferuje następujące korzyści:

  • Udostępnia znany interfejs SQL do wykonywania zapytań dotyczących osadzania wektorów i danych relacyjnych.
  • Zwiększa wydajność pgvector dzięki szybszemu i bardziej precyzyjnemu wyszukiwaniu podobieństw ponad 100 milionów wektorów przy użyciu algorytmu indeksowania DiskANN.
  • Upraszcza operacje dzięki integracji metadanych relacyjnych, osadzania wektorów i danych szeregów czasowych w jednej bazie danych.
  • Korzysta z możliwości niezawodnego ekosystemu PostgreSQL i platformy w chmurze platformy Azure na potrzeby funkcji klasy korporacyjnej, w tym replikacji i wysokiej dostępności.

Uwierzytelnianie

Usługa Azure Database for PostgreSQL obsługuje uwierzytelnianie oparte na hasłach oraz uwierzytelnianie przy użyciu Microsoft Entra (dawniej Azure Active Directory).

Uwierzytelnianie Microsoft Entra umożliwia użycie Microsoft Entra ID do uwierzytelniania na serwerze PostgreSQL. Microsoft Entra ID eliminuje konieczność zarządzania oddzielnymi nazwami użytkowników i hasłami użytkowników bazy danych. Umożliwia korzystanie z tych samych mechanizmów zabezpieczeń, które są używane w przypadku innych usług platformy Azure.

W tym artykule można użyć jednej z metod uwierzytelniania.

Konfiguracja

Usługa Azure Database for PostgreSQL używa obsługi języka LangChain Postgres typu open source w celu nawiązania połączenia z usługą Azure Database for PostgreSQL. Najpierw pobierz pakiet partnerski:

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

Włączanie narzędzia pgvector w usłudze Azure Database for PostgreSQL

Zobacz Włącz i używaj pgvector w usłudze Azure Database for PostgreSQL.

Konfigurowanie poświadczeń

Musisz uzyskać szczegóły połączenia usługi Azure Database for PostgreSQL i dodać je jako zmienne środowiskowe.

Ustaw flagę USE_ENTRA_AUTH na True , jeśli chcesz użyć uwierzytelniania firmy Microsoft Entra. Jeśli używasz uwierzytelniania firmy Microsoft Entra, musisz podać jedyne nazwy hostów i baz danych. Jeśli używasz uwierzytelniania za pomocą hasła, musisz również ustawić nazwę użytkownika i hasło.

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:")

Konfigurowanie osadzania w usłudze 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",
)

Inicjalizacja

Korzystanie z uwierzytelniania Microsoft Entra

W poniższych sekcjach pokazano, jak skonfigurować aplikację LangChain do korzystania z uwierzytelniania firmy Microsoft Entra. Klasa AzurePGConnectionPool w pakiecie LangChain azure Postgres pobiera tokeny dla usługi Azure Database for PostgreSQL przy użyciu biblioteki DefaultAzureCredentialazure.identity .

Połączenie można przekazać do connection parametru AzurePGVectorStore magazynu wektorów LangChain.

Zaloguj się do Azure

Aby zalogować się na platformie Azure, upewnij się, że masz zainstalowany interfejs wiersza polecenia platformy Azure . Uruchom następujące polecenie w terminalu:

az login

Po zalogowaniu się następujący kod pobiera token:

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"]
        )
    )

Korzystanie z uwierzytelniania za pomocą hasła

Jeśli nie używasz uwierzytelniania microsoft Entra, BasicAuth klasa zezwala na używanie nazwy użytkownika i hasła:

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"],
        )
    )
)

Tworzenie magazynu wektorów

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,
)

Zarządzanie magazynem wektorów

Dodawanie elementów do magazynu wektorów

Dodawanie dokumentów według identyfikatora zastępuje wszystkie istniejące dokumenty zgodne z tym identyfikatorem.

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

Zaktualizuj elementy w magazynie wektorów

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)

Wyświetlanie elementów z magazynu wektorów

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

Usuwanie elementów z magazynu wektorów

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

Zapytania do repozytorium wektorów

Po utworzeniu magazynu wektorów i dodaniu odpowiednich dokumentów można wykonywać zapytania dotyczące magazynu wektorów w łańcuchu lub agencie.

Obsługa filtrowania

Magazyn wektorów obsługuje zestaw filtrów, które można zastosować względem pól metadanych dokumentów za pośrednictwem FilterConditionelementu , OrFilteri AndFilter w pakiecie LangChain Azure PostgreSQL :

Obsługujący Znaczenie/Kategoria
= Równość (==)
!= Nierówności (!=)
< Mniejsze niż (<)
<= Mniejsze niż lub równe (<=)
> Większe niż (>)
>= Większe niż lub równe (>=)
in Przypadek specjalny (w)
not in Przypadki specjalne (wyłączone)
is null Specjalne litery (ma wartość null)
is not null Przypadek specjalny (nie ma wartości null)
between Przypadek specjalny (między)
not between Przypadek specjalny (nie między)
like Tekst (na przykład)
ilike Tekst (bez uwzględniania wielkości liter, na przykład)
AND Logiczne (i)
OR Logiczne (lub)

Zapytanie bezpośrednie

Możesz wykonać proste wyszukiwanie podobieństwa w następujący sposób:

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'}]

Jeśli podasz słownik z wieloma polami, ale nie operatory, najwyższy poziom zostanie zinterpretowany jako filtr logiczny 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'}]

Jeśli chcesz wykonać wyszukiwanie podobieństwa i otrzymać odpowiednie wyniki, możesz uruchomić następujące polecenie:

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'}]

Jeśli chcesz użyć wyszukiwania maksymalnej marginalnej istotności w magazynie wektorów:

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'}]

Aby uzyskać pełną listę wyszukiwań, które można wykonać w magazynie wektorów, zapoznaj się z dokumentacją PGVectorinterfejsu API.

Przekształcanie w mechanizm pobierający

Przechowalnię wektorów można również przekształcić w pośrednika, aby ułatwić stosowanie w twoich łańcuchach:

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')]