Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Azure Database for PostgreSQL se integra perfectamente con paquetes de orquestación líderes del modelo de lenguaje grande (LLM), como LangChain, lo que permite a los desarrolladores aprovechar la eficacia de las funcionalidades avanzadas de inteligencia artificial dentro de sus aplicaciones. LangChain puede simplificar la administración y el uso de LLMs, insertar modelos y bases de datos, lo que facilita aún más el desarrollo de aplicaciones de inteligencia artificial generativa.
En este tutorial se muestra cómo usar la base de datos vectorial integrada de Azure Database for PostgreSQL para almacenar y administrar documentos en colecciones con LangChain. También muestra cómo crear índices y realizar consultas de búsqueda vectorial utilizando algoritmos de vecinos más cercanos aproximados, como Distancia del coseno, L2 (distancia euclidiana) e IP (producto interno) para localizar documentos cercanos a los vectores de consulta.
Compatibilidad con vectores
Azure Database for PostgreSQL: Servidor Flexible le permite almacenar y consultar de forma eficaz millones de representaciones vectoriales en PostgreSQL y escalar los casos de uso de IA desde PoC (Prueba de Concepto) hasta la producción.
- Proporciona una interfaz SQL conocida para consultar incrustaciones de vectores y datos relacionales.
pgvector
Aumenta con una búsqueda de similitud más rápida y precisa en 100 M+ vectores mediante el algoritmo de indexación DiskANN.- Simplifica las operaciones mediante la integración de metadatos relacionales, incrustaciones de vectores y datos de serie temporal en una base de datos única.
- Usa la eficacia del sólido ecosistema de PostgreSQL y las características de nivel empresarial de Azure Cloud for Enterprise, incluida la replicación y la alta disponibilidad.
Autenticación
Azure Database for PostgreSQL: servidor flexible admite la autenticación basada en contraseñas, así como Microsoft Entra (anteriormente Azure Active Directory). La autenticación entra permite usar la identidad entra para autenticarse en el servidor de PostgreSQL. Entra ID elimina la necesidad de administrar nombres de usuario y contraseña independientes para los usuarios de la base de datos y permite usar los mismos mecanismos de seguridad que usa para otros servicios de Azure.
Este cuaderno está configurado para usar cualquiera de los métodos de autenticación. Puede configurar si va a usar o no la autenticación Entra en el cuaderno más adelante.
Configuración
Azure Database for PostgreSQL utiliza el soporte de Postgres de LangChain de código abierto para conectarse a Azure Database for PostgreSQL. En primer lugar, descargue el paquete del asociado:
%pip install -qU langchain_postgres
%pip install -qU langchain-openai
%pip install -qU azure-identity
Habilitación de pgvector en Azure Database for PostgreSQL: servidor flexible
Consulte las instrucciones de habilitación de Azure Database for PostgreSQL.
Credenciales
Necesita los detalles de conexión de Azure Database for PostgreSQL y agréguelos como variables de entorno para ejecutar este cuaderno.
Establezca el indicador USE_ENTRA_AUTH
en True
si desea usar autenticación de Microsoft Entra. Si usa la autenticación Entra, solo tiene que proporcionar el nombre del host y de la base de datos. Si usa la autenticación de contraseña, también deberá establecer el nombre de usuario y la contraseña.
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:")
Configuración de las incrustaciones de 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",
)
Inicialización
Autenticación de Microsoft Entra
La celda siguiente contiene funciones que configuran LangChain para usar la autenticación Entra. Proporciona una función get_token_and_username
que recupera tokens para el servicio Azure Databases for PostgreSQL mediante DefaultAzureCredential
desde la azure.identity
biblioteca. Garantiza que el motor de sqlalchemy tenga un token válido con el que crear nuevas conexiones. También analiza el token, que es un token web de Java (JWT), para extraer el nombre de usuario que se usa para conectarse a la base de datos.
La función create_postgres_engine crea una sqlalchemy Engine
que establece dinámicamente el nombre de usuario y la contraseña en función del token capturado de TokenManager. Esto Engine
se puede pasar al connection
parámetro de PGVector
LangChain VectorStore.
Inicio de sesión en Azure
Para iniciar sesión en Azure, asegúrese de que tiene instalada la CLI de Azure . Debe ejecutar el siguiente comando en el terminal:
az login
Una vez que inicie sesión, el código siguiente captura el 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
Autenticación de contraseñas
Si no usa la autenticación entra, get_connection_uri
proporciona un URI de conexión que extrae el nombre de usuario y la contraseña de las variables de entorno.
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
Creación del almacén vectorial
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,
)
Administrar el almacén de vectores
Agregar elementos al almacén de vectores
Agregar documentos por identificador sobreescribe los documentos existentes que coincidan con ese identificador.
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])
Actualizar elementos en el almacén de vectores
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])
Eliminar elementos del almacén de vectores
vector_store.delete(ids=["3"])
Almacén de vectores de consulta
Cuando se ha creado el almacén de vectores y se han agregado los documentos pertinentes, puede consultar el almacén de vectores en la cadena o agente.
Compatibilidad con el filtrado
El almacén de vectores admite un conjunto de filtros que se pueden aplicar a los campos de metadatos de los documentos.
Operator | Significado/Categoría |
---|---|
$eq | Igualdad (==) |
$ne | Desigualdad (!=) |
$lt | Menor que (<) |
$lte | Menor o igual que (<=) |
$gt | Mayor que (>) |
$gte | Mayor o igual que (>=) |
$in | Cased especial (en) |
$nin | Cased especial (no en) |
$between | Cased especial (entre) |
$like | Texto (como) |
$ilike | Texto (sin distinción entre mayúsculas y minúsculas, como) |
$and | Lógico (y) |
$or | Lógico (o) |
Consulta directamente
Realizar una búsqueda de similitud simple se puede realizar de la siguiente manera:
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'}]
Si proporciona un dict con varios campos, pero ningún operador, el nivel superior se interpreta como un filtro AND lógico.
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')]
Si desea ejecutar una búsqueda de similitud y recibir las puntuaciones correspondientes, puede ejecutar:
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'}]
Para obtener una lista completa de las distintas búsquedas que puede ejecutar en un PGVector
almacén de vectores, consulte la referencia de API.
Consulta mediante la flexión en el recuperador
También puede transformar el almacén de vectores en un recuperador para facilitar el uso en las cadenas.
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')]
Limitaciones actuales
- langchain_postgres solo funciona con psycopg3. Actualización de las cadenas de conexión de
postgresql+psycopg2://...
apostgresql+psycopg://langchain:langchain@...
- El esquema del almacén de inserción y la colección ha cambiado para que add_documents funcionen correctamente con identificadores especificados por el usuario.
- Ahora hay que pasar un objeto de conexión explícito.
Actualmente, no hay ningún mecanismo que admita la migración de datos sencilla en los cambios de esquema. Por lo tanto, los cambios de esquema en el almacén de vectores requieren que el usuario vuelva a crear las tablas y lea los documentos.
Contenido relacionado
- Más información sobre la compatibilidad con LANGChain PGVector
- GenAI Frameworks y Azure Database for PostgreSQL
- Agentes de IA en Azure Database for PostgreSQL
- Más información sobre la integración de Azure OpenAI Service
- Inteligencia artificial generativa con el servidor flexible de Azure Database for PostgreSQL.
- Habilite y use pgvector en el servidor flexible de Azure Database for PostgreSQL.