Preparación para la Certificación Microsoft AI-200
Crear backends de IA con Base de Datos de Azure para PostgreSQL
Diseña una base PostgreSQL administrada para memoria persistente de agentes, protégela con Microsoft Entra ID y TLS, modela datos relacionales y JSONB, escribe SQL eficiente e integra aplicaciones Python con psycopg.
Tiempo de estudio sugerido: 125 minutos • Nivel intermedio • Reescritura original completa con versión resumida de cada tema, evaluación comentada y laboratorio guiado de memoria de agente
Por João Ricardo Dutra••Contenido original completo
1. Empezar por la necesidad de memoria persistente
Imagina un agente de investigación que debe reanudar conversaciones, conservar tareas de varios pasos y recuperar contexto para miles de usuarios simultáneos con latencia inferior a un segundo. La base necesita integridad relacional para usuarios, sesiones, mensajes y puntos de control, además de variables de modelos y herramientas. PostgreSQL combina transacciones, SQL, JSONB, índices y extensiones para ambas necesidades.
Administrar el motor directamente también responsabiliza al equipo de servidores, revisiones, copias, conmutación por error, capacidad y seguridad. asume esas operaciones sin perder compatibilidad con PostgreSQL comunitario y sus herramientas.
Explicar la arquitectura y las opciones de proceso.
Conectar con y .
Modelar tablas, relaciones, restricciones, JSONB e índices.
Usar patrones SQL propios de PostgreSQL.
Integrar Python con psycopg y conexiones reutilizables.
Resumen del tema
El módulo convierte PostgreSQL en memoria duradera del agente mientras administra la plataforma de datos.
2. Comprender la arquitectura PostgreSQL administrada
ejecuta el motor comunitario como servicio relacional totalmente administrado. Proceso y almacenamiento están separados: el motor usa proceso basado en Linux y los archivos permanecen en almacenamiento administrado de con copias redundantes locales. Así, ambos recursos pueden escalar de forma independiente.
El equipo conserva el control de parámetros, ventanas de mantenimiento, alta disponibilidad, extensiones y capacidad. Microsoft se ocupa del aprovisionamiento físico, las revisiones de plataforma, la coordinación de copias de seguridad y la infraestructura administrada de disponibilidad.
El plano administrado elimina trabajo de infraestructura sin ocultar la configuración y las funciones de PostgreSQL.
Resumen del tema
El servicio separa proceso y almacenamiento duradero y delega las operaciones de plataforma a Microsoft.
3. Elegir proceso, copias de seguridad y recuperación
Niveles de proceso por perfil de carga.
Nivel
Mejor uso
Señal de diseño
Ampliable
Desarrollo, prueba de concepto y cargas pequeñas o intermitentes.
El costo importa más que la CPU sostenida.
Uso general
, y aplicaciones de producción habituales.
Se requiere equilibrio de memoria y rendimiento predecible.
Optimizado para memoria
Cachés grandes, SQL analítico y conjuntos activos en memoria.
La memoria por vCPU es el límite.
El nivel puede cambiarse después de la implementación, normalmente con un reinicio breve. La selección debe basarse en CPU, memoria, conexiones y latencia medidas, no en elegir siempre la opción más grande.
Las copias automáticas combinan instantáneas y registros de transacciones. La retención predeterminada es siete días y puede ampliarse a 35. El servicio usa redundancia de zona donde está disponible y redundancia local en otras regiones, cifra con -256 y admite claves administradas por plataforma o cliente. La restauración a un momento dado crea otro servidor en el segundo elegido dentro del período.
Resumen del tema
Elige proceso según la carga real y alinea la retención de siete a 35 días con el objetivo de recuperación.
4. Planificar extensiones y agrupación de conexiones
Las extensiones agregan tipos, funciones, operadores y métodos de índice. Las soluciones de IA pueden evaluar pgvector para embeddings, pg_trgm para similitud textual y autocompletado, hstore para atributos clave-valor y PostGIS para geoespacial. Confirma disponibilidad antes de depender de ellas y planifica sus actualizaciones.
PgBouncer integrado conserva conexiones reutilizables del servidor y multiplexa clientes de corta duración. Resulta útil cuando cada inferencia escribe mensajes o recupera contexto. Está disponible en Uso general y Optimizado para memoria, no en Ampliable, y escucha en el puerto 6432 en lugar del puerto PostgreSQL directo 5432.
az postgres flexible-server parameter set \
--resource-group rg-ai-agent \
--server-name pg-ai-agent \
--name pgbouncer.enabled \
--value true
# Direct PostgreSQL: 5432
# Built-in PgBouncer: 6432
Resumen del tema
Valida extensiones durante el diseño y usa PgBouncer integrado cuando un nivel compatible afronta mucha rotación de conexiones.
5. Construir una conexión PostgreSQL completa
El punto de conexión flexible sigue <servidor>.postgres.database..com. Resuelve a una dirección pública cuando se habilita acceso público o privada con integración en . El cliente necesita host, base, usuario, credencial, puerto y modo .
Parámetros de conexión.
Parámetro
Finalidad
Host
FQDN del servidor.
Puerto
5432 para PostgreSQL directo o 6432 para PgBouncer.
Base de datos
Destino de la conexión; no se consulta directamente otra base.
Usuario y credencial
Contraseña PostgreSQL o temporal de .
sslmode
Controla cifrado y validación del certificado.
Las bibliotecas aceptan , pares clave-valor o parámetros individuales. Mantén la configuración fuera del código fuente y nunca registres secretos ni .
Resumen del tema
Una conexión correcta reúne punto de conexión, puerto, base, identidad, credencial y en una configuración comprobable.
6. Preferir la autenticación de
La autenticación de reemplaza contraseñas persistentes por . Centraliza gobierno, admite identidades administradas en , crea trazas en los registros de inicio de sesión y reduce exposición porque el caduca. Configura un administrador de Entra en el servidor y solicita un para el recurso PostgreSQL.
from azure.identity import DefaultAzureCredential
credential = DefaultAzureCredential()
access_token = credential.get_token(
"https://ossrdbms-aad.database.windows.net/.default"
)
# Pass access_token.token as the PostgreSQL password.
DefaultAzureCredential puede usar en y credenciales de la CLI de en desarrollo local; el se pasa como contraseña PostgreSQL. La autenticación nativa sigue siendo útil para sistemas heredados, identidades externas o entornos desconectados. Guarda entonces las contraseñas en , rótalas, genera valores fuertes y asigna privilegio mínimo.
Identidad, transporte cifrado, conectividad de red y agrupación son capas distintas de una conexión segura.
Resumen del tema
Los de y las identidades administradas eliminan contraseñas duraderas; las credenciales nativas exigen gestión estricta.
7. Exigir y comprender la conectividad
exige transporte cifrado y admite 1.2 y 1.3. En el cliente, disable se rechaza; allow y prefer no validan el servidor; require cifra sin comprobar certificado; verify- valida la cadena; verify-full también confirma que el nombre del certificado coincide con el host.
En producción usa verify-full y confía en las autoridades raíz DigiCert o Microsoft adecuadas. Si falla, repara el almacén de confianza en vez de reducir la protección.
Con acceso público, las reglas de firewall limitan las que alcanzan el punto de conexión. Con acceso privado, el servidor tiene dirección en y el cliente debe estar en la misma red, una red emparejada o conectado por /ExpressRoute. Una identidad válida no arregla una ruta bloqueada.
Resumen del tema
Usa verify-full y diagnostica identidad, ,, rutas y firewall como capas independientes.
8. Organizar servidores, bases y esquemas
Un servidor aloja varias bases; cada conexión apunta a una y no realiza joins directos entre bases. Dentro de cada base, los esquemas son espacios de nombres para tablas, funciones y otros objetos. public es el esquema predeterminado.
Elige bases separadas para aislamiento fuerte, restauración independiente o aplicaciones que no deben compartir datos. Elige esquemas cuando dominios relacionados todavía necesitan claves externas y joins, para separación lógica de inquilinos o permisos. Una base con public basta para muchas aplicaciones de IA.
Resumen del tema
Las bases proporcionan aislamiento fuerte; los esquemas organizan objetos relacionados sin impedir relaciones y joins.
9. Modelar memoria del agente con tipos y restricciones
CREATE TABLE agent_conversations (
id BIGSERIAL PRIMARY KEY,
session_id UUID NOT NULL UNIQUE,
user_id VARCHAR(255) NOT NULL,
started_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
ended_at TIMESTAMPTZ,
metadata JSONB NOT NULL DEFAULT '{}'::jsonb
);
CREATE TABLE agent_messages (
id BIGSERIAL PRIMARY KEY,
conversation_id BIGINT NOT NULL
REFERENCES agent_conversations(id) ON DELETE CASCADE,
role VARCHAR(20) NOT NULL
CHECK (role IN ('user', 'assistant', 'system')),
content TEXT NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX ix_agent_messages_context
ON agent_messages(conversation_id, created_at, id);
Cada tabla necesita una clave primaria estable. SERIAL y BIGSERIAL generan secuencias de 32 y 64 bits; con gen_random_uuid() permite crear identificadores fuera de la base o combinar orígenes. BIGSERIAL es sencillo para inserciones centralizadas de gran volumen.
Tipos útiles para de IA.
Tipo
Uso
JSONB
anidados variables con almacenamiento binario, operadores e índices.
TEXT / VARCHAR(n)
Texto sin límite o longitud máxima impuesta; VARCHAR sin límite y TEXT rinden igual.
TIMESTAMPTZ
Fechas con zona, almacenadas en UTC y mostradas según la sesión.
BYTEA
Binarios pequeños junto a datos; archivos grandes suelen ir a con una referencia.
BIGSERIAL /
Identidad secuencial de la base o identidad global de la aplicación.
NOT NULL evita ausencia, DEFAULT aporta un valor omitido, CHECK limita dominios como estado y UNIQUE impide duplicados. Las reglas protegen los datos aunque varias aplicaciones escriban.
Resumen del tema
Usa columnas relacionales para hechos estables, JSONB para variación controlada y restricciones como última barrera de integridad.
10. Definir relaciones, índices y cambios seguros
Una clave externa representa relaciones uno-a-muchos. RESTRICT impide eliminar mientras existan dependientes; CASCADE propaga la eliminación; SET NULL y SET DEFAULT conservan el hijo con otra referencia. Usa cascada solo cuando borrar el padre deba borrar inequívocamente todos los hijos. Una tabla puente con clave primaria compuesta modela muchos-a-muchos.
PostgreSQL indexa automáticamente claves primarias y UNIQUE, pero no todos los filtros o claves externas. B-tree sirve igualdad, intervalos, joins y ordenación. El orden compuesto importa: (conversation_id, created_at) usa el prefijo conversation_id, pero no una consulta que solo filtra created_at. Cada índice ocupa espacio y encarece escrituras.
ALTER TABLE evoluciona la estructura y DROP TABLE la elimina. La mayoría del DDL es transaccional: agrupa cambios con BEGIN/COMMIT y usa si fallan. Algunas operaciones bloquean fuertemente; pruébalas y prográmalas. Trata DROP ... CASCADE con cautela.
Resumen del tema
Las relaciones imponen propiedad, los índices siguen accesos reales y el DDL transaccional evita cambios parciales.
11. Respetar el orden SQL y los filtros de PostgreSQL
Orden lógico de procesamiento SQL.
Orden
Cláusula
Función
1
FROM
Construye filas de origen.
2
WHERE
Filtra filas.
3
GROUP BY
Crea grupos.
4
HAVING
Filtra grupos.
5
SELECT
Proyecta columnas y calcula alias.
6
ORDER BY
Ordena el resultado.
7
LIMIT / OFFSET
Limita filas devueltas.
Un alias de SELECT todavía no existe en WHERE, GROUP BY o HAVING. Repite la expresión o llévala a una subconsulta/CTE; ORDER BY sí puede usarlo porque se ejecuta después. ILIKE compara sin distinguir mayúsculas, NULLS FIRST/LAST controla nulos y COALESCE devuelve el primer valor no nulo.
Resumen del tema
El orden lógico explica el alcance de alias; ILIKE, la ordenación explícita de nulos y COALESCE simplifican consultas.
12. Consultar JSONB y evitar OFFSET profundo
-> devuelve y ->> texto; #> y #>> recorren rutas anidadas. ? comprueba la existencia de una clave y @> prueba contención. Los índices GIN aceleran estos filtros a gran escala. jsonb_array_elements_text expande matrices para filtrar o agregar.
OFFSET empeora al avanzar porque el motor lee y descarta filas anteriores. La paginación por claves guarda los últimos valores ordenables y continúa desde ellos. Añade un desempate único, como id junto a la fecha, para no repetir ni perder filas.
SELECT id, session_id, metadata->>'model' AS model, started_at
FROM agent_conversations
WHERE user_id = $1
AND metadata @> $2::jsonb
AND (started_at, id) < ($3, $4)
ORDER BY started_at DESC, id DESC
LIMIT 20;
Resumen del tema
Usa operadores JSONB para flexibles y paginación por claves para mantener rendimiento en páginas profundas.
13. Componer consultas con CTE y recursión
Una Common Table Expression nombra un resultado temporal válido dentro de la instrucción. Divide SQL complejo en etapas legibles, por ejemplo sesiones recientes y totales de mensajes.
WITH recent_sessions AS (
SELECT id, user_id, started_at
FROM agent_conversations
WHERE started_at >= CURRENT_DATE - INTERVAL '7 days'
), message_totals AS (
SELECT conversation_id, COUNT(*) AS message_count
FROM agent_messages
GROUP BY conversation_id
)
SELECT r.user_id, r.started_at,
COALESCE(m.message_count, 0) AS message_count
FROM recent_sessions r
LEFT JOIN message_totals m ON m.conversation_id = r.id;
WITH RECURSIVE recorre árboles de tareas, organizaciones o conversaciones enlazadas combinando un ancla y una rama recursiva. Incluye una condición de terminación o límite de profundidad para que los ciclos no continúen indefinidamente.
Resumen del tema
Las CTE hacen auditables las etapas; las CTE recursivas recorren jerarquías con seguridad si tienen terminación.
14. Reducir viajes con RETURNING y upserts
RETURNING recupera identificadores, fechas y valores modificados por INSERT, UPDATE o sin otra consulta. Es ideal cuando el ID de una conversación nueva se usará inmediatamente al insertar mensajes.
INSERT ... ON CONFLICT responde a una colisión única. DO NOTHING ignora el duplicado; DO UPDATE usa EXCLUDED para combinar los valores propuestos. Un WHERE condicional evita actualizaciones innecesarias. Es apropiado para puntos de control, preferencias y operaciones idempotentes.
INSERT INTO task_checkpoints (task_id, step_number, state)
VALUES ($1, $2, $3::jsonb)
ON CONFLICT (task_id, step_number)
DO UPDATE SET state = EXCLUDED.state,
updated_at = CURRENT_TIMESTAMP
RETURNING id, updated_at;
Resumen del tema
RETURNING ahorra un viaje y ON CONFLICT convierte escrituras repetibles en operaciones idempotentes.
15. Integrar Python con psycopg 3 de forma segura
psycopg 3 es el adaptador moderno de PostgreSQL para Python, con síncrona y asíncrona, funciones del motor y agrupación opcional. El extra binary facilita el desarrollo; las compilaciones que requieren una libpq específica pueden usar sus encabezados.
import psycopg
from psycopg_pool import ConnectionPool
pool = ConnectionPool(conninfo, min_size=1, max_size=10)
def load_context(conversation_id: int):
with pool.connection() as conn:
with conn.cursor() as cursor:
cursor.execute(
"""SELECT role, content, created_at
FROM agent_messages
WHERE conversation_id = %s
ORDER BY created_at""",
(conversation_id,),
)
return cursor.fetchall()
Los administradores de contexto cierran cursor y conexión incluso tras una excepción. Pasa datos mediante marcadores %s o con nombre; nunca concatenes entrada del usuario. Usa fetchone para una fila, fetchall solo para conjuntos pequeños e itera el cursor para resultados grandes.
Contextos, parámetros, , tiempos de espera y pools de psycopg forman un límite de aplicación más seguro.
16. Tratar errores y optimizar el tráfico
Reintenta con espera exponencial solo OperationalError transitorio por red, reinicios o contención. Los errores de sintaxis y datos necesitan corrección. UniqueViolation, ForeignKeyViolation y CheckViolation requieren mensaje útil y . DeadlockDetected y LockNotAvailable pueden reintentarse después de revertir; adquirir bloqueos en orden consistente reduce interbloqueos.
Las conexiones filtradas agotan el pool, así que devuelve todas. Define tiempos de conexión e instrucción según la latencia permitida. Usa executemany para cientos o pocos miles de filas y COPY para cargas mayores.
with cursor.copy(
"COPY agent_messages (conversation_id, role, content) FROM STDIN"
) as copy:
for message in messages:
copy.write_row(message)
Las instrucciones preparadas reutilizan análisis y plan. El pool evita , autenticación y asignación por operación. Dimensiona el pool según concurrencia y límite del servidor, no con un número arbitrario.
Resumen del tema
Clasifica el error antes de reintentar y reduce viajes mediante pool, lotes, instrucciones preparadas y COPY.
17. Laboratorio guiado: de herramientas del agente
El ejercicio original dedica unos 30 minutos a construir un PostgreSQL que el agente usa como herramienta. Conversaciones y tareas sobreviven reinicios e interrupciones.
Prepara una suscripción de con permisos, , la CLI de reciente, Python 3.12 o superior y psql.
Descarga el proyecto inicial y configura la implementación.
Implementa un servidor flexible de con autenticación de .
Crea tablas de conversaciones, mensajes y puntos de control con relaciones y restricciones.
Implementa funciones Python para escribir mensajes, guardar puntos y cargar contexto.
Ejecuta la prueba y examina el estado mediante SQL.
Interrumpe y reanuda una tarea para demostrar memoria entre sesiones.
Elimina los recursos desechables al finalizar.
El patrón reúne identidad, pool, integridad del esquema, consultas y estado persistente.
Resumen del tema
El laboratorio demuestra que tablas PostgreSQL y herramientas Python conservan conversaciones y puntos de control entre ejecuciones.
18. Revisión de la evaluación y lista final
de conversación variables: JSONB admite estructuras distintas y sigue siendo consultable e indexable.
ID generado necesario al insertar: RETURNING lo devuelve en la misma instrucción.
Insertar o actualizar una preferencia sin duplicar: INSERT ... ON CONFLICT DO UPDATE.
Estado limitado a un conjunto: CHECK (status IN (...)) impone la regla.
Los distractores pertenecen a otros motores o resuelven otra regla: VARCHAR(MAX), OUTPUT, LAST_INSERT_ID() y ON DUPLICATE KEY UPDATE no son respuestas PostgreSQL; UNIQUE no limita valores; NOT NULL DEFAULT aporta un valor, pero no rechaza otro estado; una conexión global es frágil ante concurrencia.
Dimensiona proceso y pool con concurrencia medida.
Usa , verify-full y privilegio mínimo.
Mantén hechos estables en columnas y variación controlada en JSONB.
Indexa filtros, joins y ordenaciones sin indexarlo todo.
Prefiere paginación por claves, RETURNING y ON CONFLICT.
Usa SQL parametrizado, tiempos de espera, , reintentos selectivos y pool.
Un de IA para producción combina operaciones administradas, identidad y transporte seguros, esquema intencional, SQL eficiente y disciplina del cliente.