Dela via


Använda LangChain med Azure Database for PostgreSQL

Azure Database for PostgreSQL integreras sömlöst med ledande llm-orkestreringspaket (large language model), till exempel LangChain. Med den här integreringen kan utvecklare använda avancerade AI-funktioner i sina program. LangChain kan effektivisera hanteringen och användningen av LLM:er, inbäddningsmodeller och databaser så att generativa AI-program blir enklare att utveckla.

Den här artikeln visar hur du använder den integrerade vektordatabasen i Azure Database for PostgreSQL för att lagra och hantera dokument i samlingar med LangChain. Den visar också hur du skapar index och utför vektorsökningsfrågor med hjälp av närmaste grannalgoritmer som cosinusavstånd, L2-avstånd (Euklidiska avstånd) och inre produkt för att hitta dokument nära frågevektorerna.

Stöd för vektor

Du kan använda Azure Database for PostgreSQL för att effektivt lagra och fråga miljontals vektorinbäddningar i PostgreSQL. Tjänsten kan hjälpa dig att skala dina AI-användningsfall från konceptbevis till produktion. Den erbjuder följande fördelar:

  • Tillhandahåller ett välbekant SQL-gränssnitt för att fråga vektorbäddningar och relationsdata.
  • pgvector Ökar med en snabbare och mer exakt likhetssökning över mer än 100 miljoner vektorer med hjälp av DiskANN-indexeringsalgoritmen.
  • Förenklar åtgärder genom att integrera relationsmetadata, vektorbäddningar och tidsseriedata i en enda databas.
  • Använder kraften i det robusta PostgreSQL-ekosystemet och Azure-molnplattformen för funktioner i företagsklass, inklusive replikering och hög tillgänglighet.

Autentisering

Azure Database for PostgreSQL stöder lösenordsbaserad och Microsoft Entra-autentisering (tidigare Azure Active Directory).

Med Microsoft Entra-autentisering kan du använda Microsoft Entra-ID för att autentisera till din PostgreSQL-server. Microsoft Entra-ID eliminerar behovet av att hantera separata användarnamn och lösenord för dina databasanvändare. Det gör att du kan använda samma säkerhetsmekanismer som du använder för andra Azure-tjänster.

I den här artikeln kan du använda någon av autentiseringsmetoderna.

Inställningar

Azure Database for PostgreSQL använder stöd för LangChain Postgres med öppen källkod för att ansluta till Azure Database for PostgreSQL. Ladda först ned partnerpaketet:

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

Aktivera pgvector i Azure Database for PostgreSQL

Se Aktivera och använda pgvector i Azure Database for PostgreSQL.

Konfigurera autentiseringsuppgifter

Du måste hämta anslutningsinformationen för Azure Database for PostgreSQL och lägga till dem som miljövariabler.

USE_ENTRA_AUTH Ange flaggan till True om du vill använda Microsoft Entra-autentisering. Om du använder Microsoft Entra-autentisering måste du ange de enda värd- och databasnamnen. Om du använder lösenordsautentisering måste du också ange användarnamnet och lösenordet.

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

Konfigurera Azure OpenAI-inbäddningar

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

Initialisering

Använd Microsoft Entra-autentisering

Följande avsnitt visar hur du konfigurerar LangChain för att använda Microsoft Entra-autentisering. Klassen AzurePGConnectionPool i LangChain Azure Postgres-paketet hämtar token för Azure Database for PostgreSQL-tjänsten med hjälp DefaultAzureCredential av från azure.identity biblioteket.

Anslutningen kan skickas till parametern connection för LangChain-vektorarkivet AzurePGVectorStore .

Logga in på Azure

Om du vill logga in på Azure kontrollerar du att Azure CLI är installerat. Kör följande kommando i terminalen:

az login

När du har loggat in hämtar följande kod 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"]
        )
    )

Använda lösenordsautentisering

Om du inte använder Microsoft Entra-autentisering BasicAuth tillåter klassen användning av användarnamn och lösenord:

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

Skapa vektorlagringsplatsen

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

Hantering av vektorarkivet

Lägga till objekt i vektorlagret

Om du lägger till dokument efter ID skrivs alla befintliga dokument som matchar det ID:t över.

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

Uppdatera objekt i vektorarkivet

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)

Se objekt från vektorarkivet

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

Ta bort objekt från vektorarkivet

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

Frågor till vektorarkivet

När du har skapat vektorarkivet och lagt till relevanta dokument kan du fråga vektorarkivet i kedjan eller agenten.

Stöd för filtrering

Vektorarkivet stöder en uppsättning filter som kan användas mot metadatafälten i dokumenten via FilterCondition, OrFilteroch AndFilter i LangChain Azure PostgreSQL-paketet :

Operatör Betydelse/kategori
= Likhet (==)
!= Ojämlikhet (!=)
< Mindre än (<)
<= Mindre än eller lika med (<=)
> Större än (>)
>= Större än eller lika med (>=)
in Speciell hantering (i)
not in Specialfall (inte i)
is null Specialfall (är null)
is not null Specialfall (är inte null)
between Specialbehandlad (mellan)
not between Specialfall (inte mellan)
like Text (liknande)
ilike Text (skiftlägesokänsligt som)
AND Logiskt (och)
OR Logiskt (eller)

Direktfråga

Du kan utföra en enkel likhetssökning på följande sätt:

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

Om du anger en ordlista med flera fält men inga operatorer tolkas den översta nivån som ett logiskt AND filter:

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

Om du vill köra en likhetssökning och ta emot motsvarande poäng kan du köra:

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

Om du vill använda maximal marginal relevanssökning i vektorarkivet:

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

En fullständig lista över sökningar som du kan köra i ett PGVector vektorlager finns i API-referensen.

Omvandling till retriever

Du kan också omvandla vektorlagret till en retriever för enklare användning i dina kedjor:

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