Criar backends de IA com o Banco de Dados do Azure para PostgreSQL
Voltar para a trilha AI-200
AI-200Capítulo 12

Estudo para a Certificação Microsoft AI-200

Criar backends de IA com o Banco de Dados do Azure para PostgreSQL

Projete uma base PostgreSQL gerenciada para memória persistente de agentes, proteja-a com Microsoft Entra ID e TLS, modele dados relacionais e JSONB, escreva SQL eficiente e integre aplicações Python com psycopg.

Tempo de estudo sugerido: 125 minutos • Nível intermediário • Reescrita autoral completa com versão resumida de cada tópico, avaliação comentada e laboratório guiado de memória de agente

Escudo neon Microsoft Certified AI-200 com Banco de Dados do Azure para PostgreSQL, conexões seguras, esquemas SQL, Python e memória persistente de agentes de IA

1. Partir do requisito de memória persistente

Imagine um agente de pesquisa que precisa retomar conversas, preservar tarefas de várias etapas e recuperar contexto para milhares de usuários simultâneos com latência inferior a um segundo. O banco deve garantir integridade relacional para usuários, sessões, mensagens e checkpoints, mas também acomodar variáveis de modelos e ferramentas. PostgreSQL reúne transações, SQL, JSONB, índices e extensões para atender aos dois lados.

Operar o mecanismo por conta própria também transfere à equipe servidores, correções, backups, , capacidade e segurança. O assume essas tarefas de plataforma sem romper a compatibilidade com o PostgreSQL da comunidade e suas ferramentas.

  • Explicar a arquitetura e as opções de computação.
  • Conectar com e .
  • Modelar tabelas, relações, restrições, JSONB e índices.
  • Usar recursos SQL específicos do PostgreSQL.
  • Integrar Python com psycopg e conexões reutilizáveis.

Resumo do tópico

O módulo transforma PostgreSQL em memória durável do agente enquanto o administra a plataforma de banco de dados.

2. Entender a arquitetura PostgreSQL gerenciada

O executa o mecanismo comunitário como serviço relacional totalmente gerenciado. Computação e armazenamento são componentes separados: o mecanismo usa computação baseada em Linux, enquanto os arquivos ficam no armazenamento gerenciado do com cópias localmente redundantes. Assim, capacidade de processamento e armazenamento podem evoluir de forma independente.

A equipe ainda controla parâmetros, janelas de manutenção, alta disponibilidade, extensões e dimensionamento. A Microsoft cuida do provisionamento físico, das correções da plataforma, da orquestração de backups e da infraestrutura gerenciada de disponibilidade.

O Banco de Dados do Azure para PostgreSQL separa armazenamento gerenciado das camadas Expansível, Uso Geral e Otimizado para Memória e adiciona backup, alta disponibilidade e extensões.
O plano gerenciado remove trabalho de infraestrutura sem esconder os recursos de desenvolvimento e configuração do PostgreSQL.

Resumo do tópico

O serviço separa computação de armazenamento durável e delega as operações da plataforma à Microsoft.

3. Escolher computação, backup e recuperação

Camadas de computação por perfil de carga.
CamadaMelhor usoSinal de projeto
ExpansívelDesenvolvimento, prova de conceito e cargas pequenas ou intermitentes.Economia é mais importante que CPU sustentada.
Uso Geral, e aplicações de produção típicas.É necessário equilíbrio de memória e desempenho previsível.
Otimizado para Memória grandes, SQL analítico e conjuntos ativos em memória.Memória por vCPU é o recurso limitante.

É possível mudar de camada depois da implantação, normalmente com uma breve reinicialização. A escolha deve nascer das métricas de CPU, memória, conexões e latência, não da ideia de que a maior camada é sempre a mais segura.

Os backups automáticos combinam instantâneos e de transação. A retenção começa em sete dias e pode chegar a 35. O serviço utiliza armazenamento com redundância de zona onde disponível e redundância local nas demais regiões, criptografa com -256 e aceita chaves gerenciadas pela plataforma ou pelo cliente. A restauração pontual cria outro servidor no segundo escolhido dentro da retenção.

Resumo do tópico

Escolha a computação pelo comportamento real da carga e alinhe a retenção de sete a 35 dias ao objetivo de recuperação.

4. Planejar extensões e pool de conexões

Extensões acrescentam tipos, funções, operadores e métodos de índice sem alterar o núcleo. Soluções de IA podem avaliar pgvector para embeddings e vizinhos próximos, pg_trgm para semelhança textual e preenchimento automático, hstore para atributos chave-valor e PostGIS para geoespacial. Confirme a disponibilidade antes de depender da extensão e planeje suas atualizações.

O PgBouncer interno mantém conexões de servidor reutilizáveis e multiplexa clientes de curta duração. Ele ajuda quando cada inferência grava mensagens ou recupera contexto. O recurso integrado existe nas camadas Uso Geral e Otimizado para Memória, não na Expansível, e usa a porta 6432 em vez da porta PostgreSQL direta 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

Resumo do tópico

Valide extensões no projeto e use o PgBouncer interno em camadas compatíveis quando houver muita rotatividade de conexões.

5. Montar uma conexão PostgreSQL completa

O do servidor flexível segue <servidor>.postgres.database..com. Ele resolve para endereço público quando o acesso público está ativo ou privado com integração à . O cliente precisa de host, banco, usuário, credencial, porta e modo .

Parâmetros da conexão.
ParâmetroFinalidade
HostFQDN do servidor.
Porta5432 para PostgreSQL direto ou 6432 para PgBouncer interno.
BancoBanco de destino; a conexão não consulta diretamente outro banco.
Usuário e credencialSenha PostgreSQL ou temporário do .
sslmodeControla criptografia e validação de certificado.

Bibliotecas aceitam , pares de palavras-chave ou parâmetros separados. Mantenha a configuração fora do código-fonte e nunca registre segredos ou em .

Resumo do tópico

Uma conexão correta combina , porta, banco, identidade, credencial e política em uma configuração testável.

6. Preferir autenticação do

A autenticação do substitui senhas persistentes por . Ela centraliza governança, permite identidades gerenciadas em recursos do , gera rastros nos de entrada e reduz exposição porque o expira. Configure um administrador do Entra no servidor e solicite um para o 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 pode usar no e credenciais da CLI do durante o desenvolvimento local; o é enviado como senha PostgreSQL. A autenticação nativa continua útil para legados, identidades externas ao locatário ou ambientes desconectados. Nesse caso, armazene senhas no , faça rotação, gere valores fortes e conceda privilégio mínimo.

A aplicação obtém token do Microsoft Entra, valida o certificado TLS do PostgreSQL, atravessa firewall público ou Rede Virtual privada e pode usar PgBouncer.
Identidade, transporte criptografado, alcance de rede e pool são camadas diferentes da conexão segura.

Resumo do tópico

do e identidades gerenciadas removem senhas duradouras; credenciais nativas exigem gestão rigorosa de segredos.

7. Exigir e compreender o acesso de rede

O exige transporte criptografado e oferece 1.2 e 1.3. No cliente, disable é rejeitado; allow e prefer não validam o servidor; require força criptografia sem validar o certificado; verify- valida a cadeia; verify-full também confirma que o nome do certificado corresponde ao host.

Em produção, use verify-full e confie nas autoridades raiz DigiCert ou Microsoft apropriadas. Se a validação falhar, corrija o repositório de confiança em vez de reduzir a proteção.

No acesso público, regras de firewall limitam os IPs que chegam ao . No acesso privado, o servidor tem endereço na e o cliente deve estar na mesma rede, em uma rede emparelhada ou conectado por /ExpressRoute. Uma identidade válida não corrige uma rota bloqueada.

Resumo do tópico

Use verify-full e diagnostique identidade, , , rota e firewall como camadas independentes.

8. Organizar servidores, bancos e esquemas

Um servidor hospeda vários bancos; cada conexão aponta para um deles e não realiza joins diretos entre bancos. Dentro do banco, esquemas são namespaces de tabelas, funções e outros objetos. public é o padrão quando o nome do esquema não é informado.

Use bancos separados para isolamento forte, restauração independente ou aplicações que não devem compartilhar dados. Use esquemas quando domínios relacionados ainda precisam de chaves estrangeiras e joins, para separar locatários logicamente ou simplificar permissões. Para muitas aplicações de IA, um banco com o esquema public basta.

Resumo do tópico

Bancos fornecem isolamento forte; esquemas organizam objetos relacionados sem impedir joins e relações.

9. Modelar memória do agente com tipos e restrições

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

Toda tabela precisa de chave primária estável. SERIAL e BIGSERIAL geram sequências de 32 e 64 bits; com gen_random_uuid() permite criar identificadores fora do banco ou combinar origens. BIGSERIAL é simples e eficiente para inserções centralizadas de grande volume.

Tipos úteis para de IA.
TipoUso
JSONB aninhados variáveis com armazenamento binário, operadores e índices.
TEXT / VARCHAR(n)Texto sem limite ou comprimento máximo imposto pelo banco; VARCHAR sem limite e TEXT têm desempenho equivalente.
TIMESTAMPTZDatas com fuso, guardadas em UTC e exibidas conforme a sessão.
BYTEAPequenos binários ao lado dos dados; arquivos grandes ficam melhor no com uma referência.
BIGSERIAL / Identidade sequencial do banco ou identidade global gerada pela aplicação.

NOT NULL bloqueia ausência, DEFAULT preenche valor omitido, CHECK limita domínios como status e UNIQUE evita duplicidade. As regras protegem os dados mesmo quando várias aplicações escrevem.

Resumo do tópico

Use colunas relacionais para fatos estáveis, JSONB para variabilidade controlada e restrições como última barreira de integridade.

10. Definir relações, índices e mudanças seguras

A chave estrangeira representa relações um-para-muitos, como conversa e mensagens. RESTRICT impede exclusão com dependentes; CASCADE propaga a exclusão; SET NULL e SET DEFAULT preservam o filho com referência alterada. Use cascata apenas quando remover o pai realmente deve remover todos os filhos. Relações muitos-para-muitos usam tabela de junção com chave primária composta.

O PostgreSQL indexa automaticamente chaves primárias e UNIQUE, mas não cria todo índice de consulta ou de chave estrangeira. B-tree atende igualdade, intervalos, joins e ordenação. A ordem de um índice composto importa: (conversation_id, created_at) atende o prefixo conversation_id, mas não uma filtragem apenas por created_at. Índices ocupam espaço e tornam gravações mais caras.

ALTER TABLE evolui a estrutura e DROP TABLE remove tabela e dados. A maioria do DDL é transacional: envolva mudanças relacionadas em BEGIN/COMMIT e faça diante de falha. Algumas operações adquirem bloqueios fortes; teste e agende. Tenha cuidado especial com DROP ... CASCADE.

Resumo do tópico

Relações impõem propriedade, índices seguem os acessos reais e DDL transacional reduz alterações parciais.

11. Respeitar a ordem SQL e os filtros do PostgreSQL

Ordem lógica do processamento SQL.
OrdemCláusulaFunção
1FROMMonta as linhas de origem.
2WHEREFiltra linhas.
3GROUP BYCria grupos.
4HAVINGFiltra grupos.
5SELECTProjeta colunas e calcula aliases.
6ORDER BYOrdena o resultado.
7LIMIT / OFFSETLimita as linhas retornadas.

Um alias definido no SELECT ainda não existe em WHERE, GROUP BY ou HAVING. Repita a expressão ou mova-a para subconsulta/CTE; ORDER BY pode usar o alias porque ocorre depois. ILIKE faz correspondência sem diferenciar maiúsculas, NULLS FIRST/LAST controla nulos na ordenação e COALESCE devolve o primeiro valor não nulo.

Resumo do tópico

A ordem lógica explica o alcance de aliases; ILIKE, ordenação explícita de nulos e COALESCE simplificam consultas.

12. Consultar JSONB e evitar OFFSET profundo

-> retorna e ->> retorna texto; #> e #>> percorrem caminhos aninhados. ? verifica a existência de uma chave e @> testa contenção. Índices GIN podem acelerar esses filtros em coleções grandes. jsonb_array_elements_text expande arrays para filtragem e agregação.

OFFSET piora conforme a página avança, pois o mecanismo lê e descarta as linhas anteriores. A paginação por chave guarda os últimos valores ordenáveis e continua a partir deles. Acrescente um desempate exclusivo, como id junto ao timestamp, para não repetir ou perder linhas com a mesma data.

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;

Resumo do tópico

Use operadores JSONB para flexíveis e paginação por chave para desempenho estável em resultados extensos.

13. Compor consultas com CTEs e recursão

Uma Common Table Expression nomeia um resultado temporário válido somente na instrução. Ela divide uma consulta complexa em etapas legíveis, como sessões recentes seguidas por totais de mensagens.

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 percorre árvores de tarefas, estruturas organizacionais e threads ao combinar uma âncora com um ramo recursivo. Inclua condição de término ou limite de profundidade para que ciclos nos dados não executem indefinidamente.

Resumo do tópico

CTEs tornam SQL em etapas auditáveis; CTEs recursivas atravessam hierarquias com segurança quando possuem término.

14. Reduzir viagens com RETURNING e upserts

RETURNING recupera IDs, timestamps e valores modificados por INSERT, UPDATE ou sem outra consulta. É ideal quando o ID da conversa recém-criada será usado imediatamente nas mensagens.

INSERT ... ON CONFLICT reage a colisões de chave exclusiva. DO NOTHING ignora o duplicado; DO UPDATE usa a pseudotabela EXCLUDED para mesclar os valores propostos. Um WHERE condicional evita atualização inútil. O padrão atende checkpoints, preferências e operações idempotentes do agente.

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;

Resumo do tópico

RETURNING economiza uma ida ao banco e ON CONFLICT converte gravações repetíveis em operações idempotentes.

15. Integrar Python com segurança usando psycopg 3

psycopg 3 é o adaptador moderno de PostgreSQL para Python, com síncrona e assíncrona, recursos do mecanismo e pool opcional. O extra binary facilita desenvolvimento; builds de produção que exigem uma libpq específica podem compilar com seus cabeçalhos.

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

Gerenciadores de contexto fecham cursor e conexão mesmo após exceções. Passe dados pelos placeholders posicionais %s ou nomeados; nunca concatene entrada do usuário no SQL. Use fetchone para uma linha, fetchall apenas para conjuntos pequenos e itere pelo cursor para grandes volumes.

conn = psycopg.connect(
    conninfo,
    connect_timeout=10,
    options="-c statement_timeout=30000"
)

Resumo do tópico

Contextos, parâmetros, , e pools do psycopg formam uma fronteira de aplicação mais segura.

16. Tratar falhas e otimizar o tráfego

Repita com recuo exponencial apenas OperationalError transitório causado por rede, reinicialização ou contenção temporária. Erros de sintaxe e violações de dados exigem correção. UniqueViolation, ForeignKeyViolation e CheckViolation devem gerar mensagem útil e . DeadlockDetected e LockNotAvailable podem ser repetidos após ; adquirir bloqueios sempre na mesma ordem reduz deadlocks.

Vazamentos esgotam o pool, portanto devolva toda conexão. Configure de conexão e instrução conforme o orçamento de latência. Use executemany para centenas ou poucos milhares de linhas e COPY para lotes maiores.

with cursor.copy(
    "COPY agent_messages (conversation_id, role, content) FROM STDIN"
) as copy:
    for message in messages:
        copy.write_row(message)

Instruções preparadas reutilizam análise e plano. O pool evita , autenticação e alocação a cada operação. Dimensione-o com base na concorrência e no limite do servidor, não por um número arbitrariamente alto.

Resumo do tópico

Classifique o erro antes de repetir e reduza viagens com pool, lotes, instruções preparadas e COPY.

17. Laboratório guiado: de ferramentas do agente

O exercício de origem usa cerca de 30 minutos para construir um PostgreSQL que o agente acessa como ferramenta. Conversas e estado de tarefas continuam disponíveis após reinicializações e interrupções.

  1. Prepare assinatura do com permissão de implantação, , a CLI do atual, Python 3.12 ou superior e psql.
  2. Baixe o projeto inicial e parametrize a implantação.
  3. Implante um servidor flexível do com autenticação do .
  4. Crie tabelas de conversas, mensagens e checkpoints com relações e restrições.
  5. Implemente funções Python para gravar mensagens, salvar checkpoints e recuperar contexto.
  6. Execute o teste do fluxo e inspecione os dados com SQL.
  7. Interrompa e retome uma tarefa para comprovar a memória entre sessões.
  8. Exclua os recursos descartáveis ao terminar.
Um agente de IA chama ferramentas Python apoiadas por pool, tabelas relacionais de conversas e mensagens, JSONB, checkpoints, índices e Banco de Dados do Azure para PostgreSQL seguro.
O padrão completo conecta identidade, pool, integridade do esquema, consultas e estado persistente.

Resumo do tópico

O laboratório comprova que tabelas PostgreSQL e ferramentas Python preservam conversa e checkpoints entre execuções.

18. Revisão da avaliação e checklist final

  1. de conversa com estruturas variáveis: JSONB é flexível, consultável e indexável.
  2. ID gerado necessário logo após inserir: RETURNING devolve o valor na mesma instrução.
  3. Inserir ou atualizar preferência sem duplicar: INSERT ... ON CONFLICT DO UPDATE.
  4. Muitas conexões Python curtas: ConnectionPool mantém conexões reutilizáveis.
  5. Status limitado a um conjunto: CHECK (status IN (...)) impõe a regra.

As alternativas pertencem a outros bancos ou aplicam outra regra: VARCHAR(MAX), OUTPUT, LAST_INSERT_ID() e ON DUPLICATE KEY UPDATE não são respostas PostgreSQL; UNIQUE não limita valores possíveis; NOT NULL DEFAULT preenche, mas não rejeita outro status; uma única conexão global é frágil sob concorrência.

  • Dimensione computação e pool pela concorrência medida.
  • Use , verify-full e privilégio mínimo.
  • Mantenha fatos estáveis no relacional e variabilidade controlada no JSONB.
  • Indexe filtros, joins e ordenações sem indexar tudo.
  • Prefira paginação por chave, RETURNING e ON CONFLICT.
  • Use SQL parametrizado, , , repetição seletiva e pool.

Referências oficiais

  1. Documentação do
  2. geral do
  3. Conectar e consultar com Python
  4. Autenticação do para PostgreSQL
  5. Tipos de dados do PostgreSQL
  6. Documentação do psycopg 3

Resumo do tópico

Um de IA pronto para produção combina operações gerenciadas, identidade e transporte seguros, esquema intencional, SQL eficiente e disciplina no cliente.