Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Database di Azure per PostgreSQL si integra perfettamente con i principali pacchetti di orchestrazione LLM (Large Language Model), ad esempio LangChain, consentendo agli sviluppatori di sfruttare la potenza delle funzionalità avanzate di intelligenza artificiale all'interno delle applicazioni. LangChain può semplificare la gestione e l'uso di VM, modelli di incorporamento e database, semplificando lo sviluppo di applicazioni di intelligenza artificiale generative.
Questa esercitazione illustra come usare il database vettoriale integrato di Database di Azure per PostgreSQL per archiviare e gestire documenti nelle raccolte con LangChain. Viene inoltre illustrato come creare indici ed eseguire query di ricerca vettoriali usando algoritmi vicini approssimativi, ad esempio Distanza coseno, L2 (distanza euclidea) e IP (prodotto interno) per individuare i documenti vicini ai vettori di query.
Supporto vettoriale
Database di Azure per PostgreSQL - Il server flessibile consente di archiviare ed eseguire query in modo efficiente su milioni di incorporamenti vettoriali in PostgreSQL e ridimensionare i casi d'uso di intelligenza artificiale dal modello di verifica alla produzione:
- Fornisce un'interfaccia SQL familiare per l'esecuzione di query su incorporamenti vettoriali e dati relazionali.
- Aumenta
pgvector
con una ricerca di somiglianza più rapida e precisa in più di 100 milioni di vettori usando l'algoritmo di indicizzazione DiskANN. - Semplifica le operazioni integrando metadati relazionali, incorporamenti vettoriali e dati di serie temporali in un singolo database.
- Usa la potenza dell'ecosistema PostgreSQL affidabile e del cloud di Azure per le funzionalità di livello aziendale, tra cui la replica e la disponibilità elevata.
Autenticazione
Database di Azure per PostgreSQL : il server flessibile supporta l'autenticazione basata su password e Microsoft Entra (in precedenza Azure Active Directory). L'autenticazione Entra consente di usare l'identità Entra per eseguire l'autenticazione nel server PostgreSQL. L'ID Entra elimina la necessità di gestire nomi utente e password separati per gli utenti del database e consente di usare gli stessi meccanismi di sicurezza usati per altri servizi di Azure.
Questo notebook è configurato per l'uso di entrambi i metodi di autenticazione. È possibile configurare se usare o meno l'autenticazione Entra in un secondo momento nel notebook.
Configurazione
Azure Database per PostgreSQL utilizza il supporto Postgres open-source di LangChain per connettersi ad Azure Database per PostgreSQL. Scaricare innanzitutto il pacchetto partner:
%pip install -qU langchain_postgres
%pip install -qU langchain-openai
%pip install -qU azure-identity
Abilitare pgvector in Database di Azure per PostgreSQL - Server flessibile
Vedere le istruzioni di abilitazione per Database di Azure per PostgreSQL.
Credenziali
Per eseguire questo notebook sono necessari i dettagli della connessione di Database di Azure per PostgreSQL e di aggiungerli come variabili di ambiente.
Impostare il USE_ENTRA_AUTH
flag su True
se si vuole usare l'autenticazione di Microsoft Entra. Se si usa l'autenticazione Entra, è sufficiente specificare l'host e il nome del database. Se si usa l'autenticazione della password, sarà necessario impostare anche il nome utente e la password.
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:")
Configurare incorporamenti OpenAI di Azure
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",
)
Inizializzazione
Autenticazione Microsoft Entra
La cella seguente contiene funzioni che configurano LangChain per l'uso dell'autenticazione Entra. Fornisce una funzione get_token_and_username
che recupera i token per il servizio Database di Azure per PostgreSQL usando DefaultAzureCredential
dalla azure.identity
libreria. Garantisce che il motore sqlalchemy abbia un token valido con cui creare nuove connessioni. Analizza anche il token, ovvero un token Web Java (JWT), per estrarre il nome utente usato per connettersi al database.
La funzione create_postgres_engine crea un'istanza di sqlalchemy Engine
che imposta dinamicamente il nome utente e la password in base al token recuperato da TokenManager. Questo Engine
valore può essere passato al connection
parametro di PGVector
LangChain VectorStore.
Accesso ad Azure
Per accedere ad Azure, assicurarsi di avere installato l'Azure CLI. È necessario eseguire il comando seguente nel terminale:
az login
Dopo l'accesso, il codice seguente recupera il token.
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
Autenticazione della password
Se non si usa l'autenticazione Entra, fornisce get_connection_uri
un URI di connessione che esegue il pull del nome utente e della password dalle variabili di ambiente.
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
Creazione dell'archivio vettoriale
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,
)
Gestire l'archivio vettoriale
Aggiungere elementi all'archivio vettoriale
L'aggiunta di documenti per ID sovrascrive tutti i documenti esistenti che corrispondono a tale ID.
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])
Aggiornare gli elementi nell'archivio vettoriale
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])
Eliminare elementi dall'archivio vettoriale
vector_store.delete(ids=["3"])
Eseguire un query nell'archivio vettoriale
Dopo che il tuo archivio vettoriale è stato creato e i documenti pertinenti sono stati aggiunti, puoi eseguire una query sull'archivio vettoriale nella tua catena o agente.
Supporto per i filtri
L'archivio vettoriale supporta un set di filtri che possono essere applicati ai campi di metadati dei documenti.
Operatore | Significato/Categoria |
---|---|
$eq | Uguaglianza (==) |
$ne | Disuguaglianza (!=) |
$lt | Minore di (<) |
$lte | Minore o uguale (<=) |
$gt | Maggiore di (>) |
$gte | Maggiore o uguale a (>=) |
$in | Combinazione di maiuscole/minuscole speciale (in) |
$nin | Combinazione di maiuscole/minuscole speciale (non in) |
$between | Combinazione di maiuscole/minuscole speciale (tra) |
$like | Testo (ad esempio) |
$ilike | Testo (senza distinzione tra maiuscole e minuscole) |
$and | Logico (e) |
$or | Logico (o) |
Eseguire una query direttamente
L'esecuzione di una semplice ricerca di somiglianza può essere eseguita nel modo seguente:
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'}]
Se si specifica un dict con più campi, ma nessun operatore, il livello superiore viene interpretato come filtro AND logico
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')]
Se si vuole eseguire una ricerca di somiglianza e ricevere i punteggi corrispondenti, è possibile eseguire:
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'}]
Per un elenco completo delle diverse ricerche che è possibile eseguire in un PGVector
archivio vettoriale, vedere le informazioni di riferimento sulle API.
Eseguire una query utilizzando una funzione di recupero
È anche possibile trasformare l'archivio vettoriale in un retriever per semplificare l'utilizzo nelle catene.
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')]
Limitazioni correnti
- langchain_postgres funziona solo con psycopg3. Aggiornare le stringhe di connessione da
postgresql+psycopg2://...
apostgresql+psycopg://langchain:langchain@...
- Lo schema dell'archivio di embedding e della raccolta è stato modificato per consentire a add_documents di funzionare correttamente con gli ID specificati dall'utente.
- È ora necessario passare un oggetto di connessione esplicito.
Attualmente , non esiste alcun meccanismo che supporta una semplice migrazione dei dati sulle modifiche dello schema. Qualsiasi modifica dello schema nell'archivio vettoriale richiede quindi all'utente di ricreare le tabelle e di leggere i documenti.
Contenuti correlati
- Altre informazioni sul supporto PGVector di LangChain
- Framework GenAI e Database di Azure per PostgreSQL
- Agenti di intelligenza artificiale in Database di Azure per PostgreSQL
- Altre informazioni sull'integrazione del servizio Azure OpenAI
- Intelligenza artificiale generativa con il server flessibile di Database di Azure per PostgreSQL.
- Abilitare e usare pgvector nel server flessibile di Database di Azure per PostgreSQL.