Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Azure Database for PostgreSQL lässt sich nahtlos in führende Orchestrierungspakete für große Sprachmodelle (Large Language Model, LLM) wie LangChain integrieren, sodass Entwickler die Leistungsfähigkeit erweiterter KI-Funktionen in ihren Anwendungen nutzen können. LangChain kann die Verwaltung und Verwendung von LLMs, Einbettungsmodellen und Datenbanken optimieren, wodurch die Entwicklung von generativen KI-Anwendungen noch einfacher wird.
In diesem Lernprogramm erfahren Sie, wie Sie die integrierte Vektordatenbank azure Database for PostgreSQL verwenden, um Dokumente in Sammlungen mit LangChain zu speichern und zu verwalten. Außerdem wird gezeigt, wie Indizes erstellt und Vektorsuchabfragen mithilfe von Algorithmen der ungefähren nächsten Nachbarn wie Cosine Distanz, L2 (Euklidischer Abstand) und IP (inneres Produkt) verwendet werden können, um Dokumente zu finden, die den Abfragevektoren nahe sind.
Vektorunterstützung
Azure Database for PostgreSQL – Flexible Server ermöglicht es Ihnen, Millionen von Vektoreinbettungen in PostgreSQL effizient zu speichern und abzufragen und Ihre KI-Anwendungsfälle von POC (Machbarkeitsnachweis) auf die Produktion zu skalieren:
- Stellt eine vertraute SQL-Schnittstelle zum Abfragen von Vektoreinbettungen und relationalen Daten bereit.
- Steigert
pgvector
durch eine schnellere und präzisere Ähnlichkeitssuche über mehr als 100 Millionen Vektoren mithilfe des DiskANN-Indexierungsalgorithmus. - Vereinfacht Vorgänge, indem relationale Metadaten, Vektoreinbettungen und Zeitreihendaten in eine einzelne Datenbank integriert werden.
- Verwendet die Leistungsfähigkeit des robusten PostgreSQL-Ökosystems und der Azure Cloud for Enterprise-Funktionen, einschließlich Replikation und hoher Verfügbarkeit.
Authentifizierung
Azure-Datenbank für PostgreSQL – Flexible Server unterstützt kennwortbasierte sowie die Microsoft Entra-Authentifizierung (früher Azure Active Directory). Mit entra-Authentifizierung können Sie entra Identity verwenden, um sich bei Ihrem PostgreSQL-Server zu authentifizieren. Die Entra-ID beseitigt die Notwendigkeit, separate Benutzernamen und Kennwörter für Ihre Datenbankbenutzer zu verwalten, und ermöglicht es Ihnen, dieselben Sicherheitsmechanismen zu verwenden, die Sie für andere Azure-Dienste verwenden.
Dieses Notizbuch ist für die Verwendung einer Authentifizierungsmethode eingerichtet. Sie können konfigurieren, ob die Entra-Authentifizierung später im Notebook verwendet werden soll.
Konfiguration
Azure Database for PostgreSQL verwendet die Open-Source-Unterstützung für LangChain-Postgres, um eine Verbindung mit Azure Database for PostgreSQL herzustellen. Laden Sie zuerst das Partnerpaket herunter:
%pip install -qU langchain_postgres
%pip install -qU langchain-openai
%pip install -qU azure-identity
Aktivieren von pgvector auf Azure-Datenbank für PostgreSQL - Flexible Server
Siehe Aktivierungsanweisungen für Azure-Datenbank für PostgreSQL.
Anmeldeinformationen
Zum Ausführen dieses Notizbuchs benötigen Sie Ihre Azure-Datenbank für PostgreSQL-Verbindungsdetails und fügen sie als Umgebungsvariablen hinzu.
Setzen Sie die USE_ENTRA_AUTH
Flagge auf True
, wenn Sie die Microsoft Entra-Authentifizierung verwenden möchten. Bei Verwendung der Entra-Authentifizierung müssen Sie nur den Host- und Datenbanknamen angeben. Wenn Sie die Kennwortauthentifizierung verwenden, müssen Sie auch den Benutzernamen und das Kennwort festlegen.
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 using a username and password, supply them here
os.environ["DBUSER"] = "<username>"
os.environ["DBPASSWORD"] = getpass.getpass("Database Password:")
Einrichten von Azure OpenAI Embeddings
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",
)
Initialisierung
Microsoft Entra-Authentifizierung
Die folgende Zelle enthält Funktionen, die LangChain für die Verwendung der Entra-Authentifizierung einrichten. Sie stellt eine get_token_and_username
-Funktion bereit, die Token für den Azure Databases for PostgreSQL-Dienst mithilfe von DefaultAzureCredential
aus der azure.identity
Bibliothek abruft. Es stellt sicher, dass das sqlalchemy-Modul über ein gültiges Token verfügt, mit dem neue Verbindungen erstellt werden können. Außerdem analysiert es das Token, bei dem es sich um ein Java Web Token (JWT) handelt, um den Benutzernamen zu extrahieren, der zum Herstellen einer Verbindung mit der Datenbank verwendet wird.
Die create_postgres_engine-Funktion erstellt eine sqlalchemy Engine
, die den Benutzernamen und das Kennwort dynamisch basierend auf dem token festlegt, das vom TokenManager abgerufen wird. Dies Engine
kann an den connection
Parameter des PGVector
LangChain VectorStore übergeben werden.
Anmelden bei Azure
Um sich bei Azure anzumelden, stellen Sie sicher, dass die Azure CLI installiert ist. Sie müssen den folgenden Befehl in Ihrem Terminal ausführen:
az login
Sobald Sie sich angemeldet haben, ruft der folgende Code das Token ab.
import base64
import json
from functools import lru_cache
from azure.identity import DefaultAzureCredential
from sqlalchemy import create_engine, event
from sqlalchemy.engine.url import URL
@lru_cache(maxsize=1)
def get_credential():
"""Memoized function to create the Azure credential, which caches tokens."""
return DefaultAzureCredential()
def decode_jwt(token):
"""Decode the JWT payload to extract claims."""
payload = token.split(".")[1]
padding = "=" * (4 - len(payload) % 4)
decoded_payload = base64.urlsafe_b64decode(payload + padding)
return json.loads(decoded_payload)
def get_token_and_username():
"""Fetches a token returns the username and token."""
# Fetch a new token and extract the username
token = get_credential().get_token(
"https://ossrdbms-aad.database.windows.net/.default"
)
claims = decode_jwt(token.token)
username = claims.get("upn")
if not username:
raise ValueError("Could not extract username from token. Have you logged in?")
return username, token.token
def create_postgres_engine():
db_url = URL.create(
drivername="postgresql+psycopg",
username="", # This will be replaced dynamically
password="", # This will be replaced dynamically
host=os.environ["DBHOST"],
port=os.environ.get("DBPORT", 5432),
database=os.environ["DBNAME"],
)
# Create a sqlalchemy engine
engine = create_engine(db_url, echo=True)
# Listen for the connection event to inject dynamic credentials
@event.listens_for(engine, "do_connect")
def provide_dynamic_credentials(dialect, conn_rec, cargs, cparams):
# Fetch the dynamic username and token
username, token = get_token_and_username()
# Override the connection parameters
cparams["user"] = username
cparams["password"] = token
return engine
Kennwortauthentifizierung
Wenn die Entra-Authentifizierung nicht verwendet wird, stellt der get_connection_uri
einen Verbindungs-URI bereit, der den Benutzernamen und das Kennwort aus Umgebungsvariablen abruft.
import urllib.parse
def get_connection_uri():
# Read URI parameters from the environment
dbhost = os.environ["DBHOST"]
dbname = os.environ["DBNAME"]
dbuser = urllib.parse.quote(os.environ["DBUSER"])
password = os.environ["DBPASSWORD"]
sslmode = os.environ["SSLMODE"]
# Construct connection URI
# Use psycopg 3!
db_uri = (
f"postgresql+psycopg://{dbuser}:{password}@{dbhost}/{dbname}?sslmode={sslmode}"
)
return db_uri
Erstellen des Vektorspeichers
from langchain_core.documents import Document
from langchain_postgres import PGVector
from langchain_postgres.vectorstores import PGVector
collection_name = "my_docs"
# The connection is either a sqlalchemy engine or a connection URI
connection = create_postgres_engine() if USE_ENTRA_AUTH else get_connection_uri()
vector_store = PGVector(
embeddings=embeddings,
collection_name=collection_name,
connection=connection,
use_jsonb=True,
)
Verwalten des Vektorspeichers
Hinzufügen von Elementen zum Vektorspeicher
Das Hinzufügen von Dokumenten nach ID überschreibt alle vorhandenen Dokumente, die dieser ID entsprechen.
docs = [
Document(
page_content="there are cats in the pond",
metadata={"id": 1, "location": "pond", "topic": "animals"},
),
Document(
page_content="ducks are also found in the pond",
metadata={"id": 2, "location": "pond", "topic": "animals"},
),
Document(
page_content="fresh apples are available at the market",
metadata={"id": 3, "location": "market", "topic": "food"},
),
Document(
page_content="the market also sells fresh oranges",
metadata={"id": 4, "location": "market", "topic": "food"},
),
Document(
page_content="the new art exhibit is fascinating",
metadata={"id": 5, "location": "museum", "topic": "art"},
),
Document(
page_content="a sculpture exhibit is also at the museum",
metadata={"id": 6, "location": "museum", "topic": "art"},
),
Document(
page_content="a new coffee shop opened on Main Street",
metadata={"id": 7, "location": "Main Street", "topic": "food"},
),
Document(
page_content="the book club meets at the library",
metadata={"id": 8, "location": "library", "topic": "reading"},
),
Document(
page_content="the library hosts a weekly story time for kids",
metadata={"id": 9, "location": "library", "topic": "reading"},
),
Document(
page_content="a cooking class for beginners is offered at the community center",
metadata={"id": 10, "location": "community center", "topic": "classes"},
),
]
vector_store.add_documents(docs, ids=[doc.metadata["id"] for doc in docs])
Aktualisieren von Elementen im Vektorspeicher
docs = [
Document(
page_content="Updated - cooking class for beginners is offered at the community center",
metadata={"id": 10, "location": "community center", "topic": "classes"},
)
]
vector_store.add_documents(docs, ids=[doc.metadata["id"] for doc in docs])
Löschen von Elementen aus dem Vektorspeicher
vector_store.delete(ids=["3"])
Abfragevektorspeicher
Wenn Ihr Vektorspeicher erstellt wurde und die relevanten Dokumente hinzugefügt wurden, können Sie den Vektorspeicher in Ihrer Kette oder Ihrem Agent abfragen.
Filterunterstützung
Der Vektorspeicher unterstützt eine Reihe von Filtern, die für die Metadatenfelder der Dokumente angewendet werden können.
Bediener | Bedeutung/Kategorie |
---|---|
$eq | Gleichheit (==) |
$ne | Ungleichheit (!=) |
$lt | Kleiner als (<) |
$lte | Kleiner als oder gleich (<=) |
$gt | Größer als (>) |
$gte | Größer als oder gleich (>=) |
$in | Sonderfall (in) |
$nin | Sonderfall (not in) |
$between | Spezialfall (between) |
$like | Text (like) |
$ilike | Text (Groß-/Kleinschreibung wird nicht beachtet – ilike) |
$and | Logisch (and) |
$or | Logisch (oder) |
Direkte Abfrage
Die Durchführung einer einfachen Ähnlichkeitssuche kann wie folgt erfolgen:
results = vector_store.similarity_search(
"kitty", k=10, filter={"id": {"$in": [1, 5, 2, 9]}}
)
for doc in results:
print(f"* {doc.page_content} [{doc.metadata}]")
* there are cats in the pond [{'id': 1, 'topic': 'animals', 'location': 'pond'}]
* ducks are also found in the pond [{'id': 2, 'topic': 'animals', 'location': 'pond'}]
* the new art exhibit is fascinating [{'id': 5, 'topic': 'art', 'location': 'museum'}]
* the library hosts a weekly story time for kids [{'id': 9, 'topic': 'reading', 'location': 'library'}]
Wenn Sie ein Wörterbuch mit mehreren Feldern, aber keinen Operatoren bereitstellen, wird die höchste Ebene als logischer AND-Filter interpretiert.
vector_store.similarity_search(
"ducks",
k=10,
filter={"id": {"$in": [1, 5, 2, 9]}, "location": {"$in": ["pond", "market"]}},
)
[Document(id='2', metadata={'id': 2, 'topic': 'animals', 'location': 'pond'}, page_content='ducks are also found in the pond'),
Document(id='1', metadata={'id': 1, 'topic': 'animals', 'location': 'pond'}, page_content='there are cats in the pond')]
vector_store.similarity_search(
"ducks",
k=10,
filter={
"$and": [
{"id": {"$in": [1, 5, 2, 9]}},
{"location": {"$in": ["pond", "market"]}},
]
},
)
[Document(id='2', metadata={'id': 2, 'topic': 'animals', 'location': 'pond'}, page_content='ducks are also found in the pond'),
Document(id='1', metadata={'id': 1, 'topic': 'animals', 'location': 'pond'}, page_content='there are cats in the pond')]
Wenn Sie eine Ähnlichkeitssuche ausführen und die entsprechenden Bewertungen erhalten möchten, können Sie folgendes ausführen:
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 [{'id': 1, 'topic': 'animals', 'location': 'pond'}]
Eine vollständige Liste der verschiedenen Suchvorgänge, die Sie in einem PGVector
Vektorspeicher ausführen können, finden Sie in der API-Referenz.
Abfrage durch Umwandeln in Retriever
Sie können den Vektorspeicher auch in einen Retriever umwandeln, um die Verwendung in Ihren Ketten zu vereinfachen.
retriever = vector_store.as_retriever(search_type="mmr", search_kwargs={"k": 1})
retriever.invoke("kitty")
[Document(id='1', metadata={'id': 1, 'topic': 'animals', 'location': 'pond'}, page_content='there are cats in the pond')]
Aktuelle Einschränkungen
- langchain_postgres funktioniert nur mit psycopg3. Aktualisieren der Verbindungszeichenfolgen von
postgresql+psycopg2://...
zupostgresql+psycopg://langchain:langchain@...
- Das Schema des Einbettungsspeichers und der Sammlung wurde geändert, damit „add_documents“ ordnungsgemäß mit vom Benutzenden angegebenen IDs funktioniert.
- Man muss jetzt ein explizites Verbindungsobjekt übergeben.
Derzeit gibt es keinen Mechanismus , der einfache Datenmigration bei Schemaänderungen unterstützt. Daher erfordern alle Schemaänderungen im Vektorspeicher, dass der Benutzende die Tabellen neu erstellt und die Dokumente erneut hinzufügt.
Verwandte Inhalte
- Weitere Informationen zur Unterstützung von LangChain PGVector
- GenAI-Frameworks und Azure-Datenbank für PostgreSQL
- KI-Agents in Azure-Datenbank für PostgreSQL
- Weitere Informationen zur Azure OpenAI Service-Integration
- Generative KI mit Azure Database for PostgreSQL flexible Server.
- Aktivieren und verwenden Sie pgvector in Azure Database für flexiblen Server für PostgreSQL.