Curso
Criar aplicações com IA muitas vezes resulta em saídas não estruturadas, incompatibilidades de tipos e problemas de confiabilidade em produção. Abordagens tradicionais para integrar LLMs em aplicações Python carecem da estrutura e validação necessárias para sistemas de produção. O Pydantic AI resolve isso ao combinar a validação de dados do Pydantic com um framework de agentes para interações com LLMs.
Neste tutorial, você vai aprender a criar agentes de IA estruturados que geram saídas validadas e mantêm segurança de tipos. Vamos abordar a configuração de agentes com prompts de sistema, a criação de ferramentas (funções) que os LLMs podem chamar durante as conversas e a implementação de validação de saídas estruturadas. Você também vai descobrir como gerenciar dependências entre componentes do agente e fazer streaming de respostas para aplicações em tempo real. No fim, você terá experiência prática construindo aplicações de IA que lidam com fluxos de trabalho complexos.
Se você busca um curso mão na massa sobre como construir sistemas de IA agentic, recomendo o curso Building Multi-Agent Systems with LangGraph.
O que é Pydantic AI?

Pydantic AI é um framework de agentes em Python que traz estrutura e segurança de tipos para aplicações com LLMs. Diferente de integrações básicas que retornam apenas texto bruto, o Pydantic AI trata as interações de IA como conversas estruturadas com entradas e saídas validadas, facilitando a construção de aplicações confiáveis.
Principais recursos e benefícios:
- Validação de saídas estruturadas — as respostas da IA seguem automaticamente modelos Pydantic, evitando erros de parsing e garantindo consistência dos dados
- Ferramentas de função — os LLMs podem chamar suas funções Python durante a conversa, acessando dados reais e computações
- Segurança de tipos — suporte completo a tipagem reduz erros em tempo de execução e melhora a assistência da IDE ao construir fluxos de trabalho complexos
- Prompts de sistema — defina instruções claras para seus agentes de IA que se mantêm consistentes em todas as interações
- Injeção de dependências — compartilhe contexto, conexões de banco de dados e preferências do usuário entre os componentes do agente de forma limpa
- Múltiplos modos de execução — execute agentes de forma síncrona, assíncrona ou faça streaming de respostas em tempo real conforme a necessidade
- Reutilização de agentes — crie agentes uma vez e reutilize-os em toda a aplicação, similar aos routers do FastAPI
Essa abordagem transforma a IA de uma geração de texto imprevisível em interações tipadas e confiáveis que se encaixam naturalmente em aplicações Python existentes. Em vez de lutar com prompt engineering e parsing de saídas, você pode focar em construir a funcionalidade que seus usuários realmente precisam.
Pré-requisitos
Antes de mergulhar neste tutorial, você vai precisar de algumas coisas:
Conhecimentos necessários:
- Fundamentos de Python: fique à vontade com classes e funções
- Noções de programação assíncrona em Python
- Noções de Pydantic: entenda modelos, validação de campos e anotações de tipos
- Familiaridade com LLMs: conhecimento básico de como modelos de linguagem funcionam e o que são prompts
Úteis, mas não obrigatórios:
- Conceitos de agentes: alguma exposição a agentes de IA e chamadas de ferramentas — vamos abordar isso também
Requisitos de setup:
- Python 3.9 ou superior
- Chaves de API da OpenAI e da Anthropic
- Noções de terminal/linha de comando para instalar pacotes
Se você é novo em Pydantic, a documentação oficial cobre bem o básico. Para fundamentos de LLMs, qualquer guia introdutório do ChatGPT ou modelos similares já dá contexto suficiente para acompanhar.
Primeiros passos com Pydantic AI
Ao longo deste tutorial, vamos construir um agente de análise de dados que ajuda a entender o desempenho de vendas em diferentes regiões e produtos. Esse agente vai começar simples e ficar mais sofisticado conforme adicionarmos recursos como ferramentas personalizadas, saídas estruturadas e capacidades de streaming.
Instalação e configuração
Antes de partir para o código, vamos instalar o Pydantic AI e preparar o ambiente:
pip install pydantic-aiVocê também vai precisar das chaves de API da OpenAI e da Anthropic. Defina-as como variáveis de ambiente:
export OPENAI_API_KEY="your-api-key-here"export ANTHROPIC_API_KEY="your-api-key-here"> Vamos usar modelos tanto da OpenAI quanto da Anthropic porque alguns recursos do Pydantic AI são suportados em um provedor e não no outro.
Para os exemplos de análise de dados, vamos usar também o pandas para manipulação de dados:
pip install pandasCriando seu primeiro agente
Vamos começar com o agente mais simples possível — um que responda perguntas básicas sobre dados de vendas. No Pydantic AI, um agente é sua principal interface para interações com LLMs (execute o código a seguir em um script Python):
from pydantic_ai import Agent# Create a basic sales analysis agentsales_agent = Agent( 'openai:gpt-4o', system_prompt=( "You are a data analyst specializing in sales performance. " "Provide clear, actionable insights based on the data provided." ))# Run the agent with a simple questionresult = sales_agent.run_sync("What are the key metrics I should track for sales performance? Answer in two sentences.")print(result.output)Saída:
Key metrics to track for sales performance include conversion rate, which measures the percentage of leads that result in sales, and average deal size, indicating the average revenue earned per transaction. Additionally, monitoring customer acquisition cost (CAC) and customer lifetime value (CLV) helps evaluate the efficiency and profitability of sales efforts.Isso cria um agente que entende seu papel como analista de vendas e consegue oferecer recomendações relevantes. O system_prompt dá ao LLM o contexto sobre o tipo de resposta que você espera, enquanto run_sync() executa o agente e retorna um resultado.
Aqui, a função run_sync() funciona apenas em scripts Python. Para rodar agentes em um Jupyter Notebook, use a seguinte sintaxe:
result = await agent.run("...")print(result.output)Mudando o LLM e seus ajustes
O Pydantic AI suporta vários provedores de LLM e permite personalizar o comportamento do modelo. Veja como experimentar diferentes opções:
# Creating agents with different modelsclaude_agent = Agent('anthropic:claude-3-5-sonnet-20241022', system_prompt="You are a sales analyst.")gpt_mini_agent = Agent('openai:gpt-4o-mini', system_prompt="You are a sales analyst.")Cada modelo traz capacidades diferentes para seu fluxo de análise de dados. Os modelos Claude se destacam em raciocínio detalhado e análises complexas, ideais quando você precisa de insights profundos a partir dos seus dados de vendas. O GPT-4o-mini oferece respostas mais rápidas e custo menor, perfeito para perguntas rápidas ou quando você precisa processar grandes volumes de consultas.
Além de escolher modelos diferentes, você pode ajustar o comportamento via configurações do modelo:
# Add model-specific settingsconfigured_agent = Agent( 'openai:gpt-4o', system_prompt="You are a sales analyst.", model_settings={ 'temperature': 0.3, # Respostas mais focadas, menos criativas 'max_tokens': 500, # Limita o tamanho da resposta })Configurações que você pode personalizar:
- temperature — controla a criatividade (0,0 = focado, 1,0 = criativo)
- max_tokens — limita o tamanho da resposta
- top_p — alternativa ao temperature para controlar aleatoriedade
Para tarefas de análise de dados, valores mais baixos de temperature (0,1–0,3) tendem a funcionar melhor, já que você quer respostas consistentes e factuais, não interpretações criativas. Definir max_tokens ajuda a controlar o comprimento da resposta, útil quando você precisa de resumos concisos ou tem preocupação com custo de API.
Usando ferramentas em agentes
Até aqui, nosso agente de análise de vendas só consegue trabalhar com as informações passadas no prompt. Mas análises reais costumam exigir acesso a dados externos, execução de cálculos ou conexão a sistemas de negócio. É aí que entram as ferramentas — elas dão ao seu agente a capacidade de agir e buscar informações durante a conversa.
Ferramentas nativas
Ferramentas nativas são funções prontas fornecidas pelos provedores de LLM. O Pydantic AI suporta ferramentas de busca na web e execução de código que rodam diretamente na infraestrutura do provedor.
Vamos começar com busca na web, perfeita para obter informações atualizadas de mercado:
from pydantic_ai import Agent, WebSearchTool# Create an agent with web search abilitiesmarket_research_agent = Agent( 'anthropic:claude-3-5-sonnet-20241022', builtin_tools=[WebSearchTool()], system_prompt=( "You are a sales analyst. Use web search to find current information. " "Keep responses to 3-4 sentences maximum." ))# Get current market informationresult = market_research_agent.run_sync( "Search for 2025 laptop sales trends and average selling prices. Give me the main trends.")print(result.output)Let me search for current laptop sales trends.Based on the search results, here are the key laptop market trends for 2025:…Isso muda sua análise de dados de algo baseado apenas em informações antigas para incluir dados de mercado em tempo real. Em vez de analisar os dados isoladamente, seu agente agora consegue comparar o desempenho da sua empresa com as tendências atuais do setor.
Agora, vamos adicionar execução de código para análises matemáticas e processamento de dados:
from pydantic_ai import Agent, CodeExecutionTool# Agent that can run calculations and data analysiscalculation_agent = Agent( 'anthropic:claude-sonnet-4-0', builtin_tools=[CodeExecutionTool()], system_prompt=( "You are a data analyst. Use code to perform calculations and create visualizations. " "Show your work and provide clear explanations." ))# Analyze sales data with calculationsresult = calculation_agent.run_sync("""I have sales data for Q1 2025:- North region: 150 laptops at $1,500 each, 320 phones at $500 each- South region: 89 laptops at $1,500 each, 245 phones at $500 each - East region: 201 laptops at $1,500 each, 180 phones at $500 each- West region: 167 laptops at $1,500 each, 290 phones at $500 eachCalculate total revenue by region and create a simple chart showing the results.""")print(result.output)```plaintext## SummaryBased on the Q1 2025 sales data analysis, here are the key findings:**Total Revenue by Region:**- **West Region**: $395,500 (highest)- **East Region**: $391,500- **North Region**: $385,000- **South Region**: $256,000 (lowest)A execução de código vai além de respostas em texto, permitindo análises computacionais reais. Seu agente pode realizar cálculos complexos, criar visualizações e processar dados — algo impossível apenas via conversa. O objeto de resultado contém tanto a análise do agente quanto quaisquer arquivos gerados durante a execução do código, que você pode baixar para uso posterior.
Escrevendo ferramentas personalizadas
Embora as ferramentas nativas sejam úteis, muitas vezes você vai precisar de ferramentas personalizadas que funcionem com os seus sistemas de negócio. Ferramentas personalizadas são funções Python que o seu agente pode chamar durante a conversa.
Vamos criar ferramentas que calculam métricas comuns de vendas:
from pydantic_ai import Agent# Create an agent with custom business toolssales_agent = Agent( 'anthropic:claude-sonnet-4-0', system_prompt=( "You are a sales analyst. Use tools to calculate metrics and analyze business data. " "Give concise answers in 3-4 sentences maximum." ))@sales_agent.tool_plaindef calculate_conversion_rate(leads: int, sales: int) -> str: """Calculate conversion rate from leads to sales.""" if leads == 0: return "Cannot calculate conversion rate: no leads provided" conversion_rate = (sales / leads) * 100 return f"Conversion rate: {conversion_rate:.2f}% ({sales} sales from {leads} leads)"@sales_agent.tool_plaindef calculate_average_order_value(total_revenue: float, total_orders: int) -> str: """Calculate average order value.""" if total_orders == 0: return "Cannot calculate AOV: no orders provided" aov = total_revenue / total_orders return f"Average Order Value: ${aov:.2f} (${total_revenue:,.0f} revenue from {total_orders} orders)"# Use the custom toolsresult = sales_agent.run_sync( "Calculate conversion rate for 500 leads that resulted in 75 sales, and AOV for $180,000 revenue from 120 orders")print(result.output)Your conversion rate is 15.00%, meaning you're successfully converting 75 out of every 500 leads into sales. The average order value is $1,500.00, indicating strong revenue per transaction. These metrics suggest effective sales processes with high-value customers, though there's room to improve lead conversion rates.Essas ferramentas personalizadas lidam com cálculos específicos de vendas que seu negócio usa com frequência. A ferramenta de taxa de conversão ajuda a medir performance de marketing, enquanto a de ticket médio acompanha o padrão de gasto dos clientes. Ferramentas personalizadas conectam seu agente à sua lógica e aos seus sistemas de negócio.
Para padrões mais avançados — incluindo injeção de dependências e tratamento de erros — confira a documentação completa de ferramentas.
Usando saídas estruturadas
Até agora, nossos agentes retornaram respostas em texto simples, o que é ótimo para exploração, mas causa problemas em aplicações de produção. Quando você precisa processar respostas do agente programaticamente, extrair pontos específicos ou integrar as saídas da IA a outros sistemas, é essencial ter estrutura garantida.
Digamos que você queira analisar dados de vendas e sempre receber de volta métricas específicas. Com texto simples, a IA pode retornar formatos diferentes a cada vez. Com saídas estruturadas, você define exatamente o que deseja:
from pydantic import BaseModelfrom pydantic_ai import Agentclass SalesInsight(BaseModel): total_revenue: float best_performing_region: str worst_performing_region: str recommendation: str# Create an agent that returns structured analysisanalysis_agent = Agent( 'anthropic:claude-sonnet-4-0', output_type=SalesInsight, system_prompt="Analyze sales data and provide structured insights with clear recommendations.")# Get structured analysisresult = analysis_agent.run_sync("""Q1 2025 sales data:- North: $385,000 revenue (470 units)- South: $256,000 revenue (334 units) - East: $391,500 revenue (381 units)- West: $395,500 revenue (457 units)Analyze this data and provide insights.""")print(f"Total Revenue: ${result.output.total_revenue:,.0f}")print(f"Best Region: {result.output.best_performing_region}")print(f"Recommendation: {result.output.recommendation}")Total Revenue: $1,428,000Best Region: WestRecommendation: Focus on improving South region performance through targeted marketing and sales training, as it significantly underperforms with only $256,000 revenue. The West region's success ($395,500) should be analyzed and replicated across other regions. Additionally, investigate why East region has the lowest average selling price per unit ($1,028) compared to West's highest ($865) - there may be pricing strategy opportunities.Perceba o parâmetro output_type=SalesInsight. Ele informa ao agente que a resposta deve ser um objeto SalesInsight com exatamente quatro campos. Nem mais, nem menos. O retorno chega em result.output, já validado e com tipagem.
Saídas estruturadas funcionam convertendo seu modelo Pydantic em um schema JSON seguido pelo LLM. A IA não pode fugir da sua estrutura — se tentar retornar algo diferente, o Pydantic AI pedirá para tentar novamente.
Para cenários mais complexos, você pode aninhar modelos e usar listas:
from typing import Listfrom pydantic import BaseModelclass RegionalMetrics(BaseModel): region: str revenue: float units_sold: int average_price: float performance_rating: str # "excellent", "good", "needs_improvement"class ComprehensiveAnalysis(BaseModel): total_revenue: float total_units: int regional_breakdown: List[RegionalMetrics] top_performer: str areas_for_improvement: List[str] quarterly_grade: str# Agent with detailed structured outputdetailed_agent = Agent( 'anthropic:claude-sonnet-4-0', output_type=ComprehensiveAnalysis, system_prompt=( "Provide comprehensive sales analysis with detailed regional metrics. " "Rate each region's performance and give an overall quarterly grade (A-F)." ))result = detailed_agent.run_sync("""Analyze Q1 2025 performance:- North: $385k revenue, 470 units- South: $256k revenue, 334 units- East: $391.5k revenue, 381 units - West: $395.5k revenue, 457 units""")# Access structured datafor region in result.output.regional_breakdown: print(f"{region.region}: {region.performance_rating} (${region.average_price:.2f} avg price)")print(f"Quarterly Grade: {result.output.quarterly_grade}")North: B ($819.15 avg price)South: C ($766.47 avg price)East: A ($1027.56 avg price)West: A- ($865.43 avg price)Quarterly Grade: B+Essa abordagem transforma a IA de geração de texto imprevisível em processamento de dados confiável. Você pode armazenar cada métrica regional em um banco de dados, disparar alertas com base nas avaliações de performance ou gerar dashboards executivos automaticamente. Nada de regex, nada de lidar com formatos de resposta diferentes — só dados limpos e validados, sempre.
O parâmetro output_type aceita qualquer modelo Pydantic, dataclass do Python, TypedDict ou até tipos simples como int ou list[str]. Para fluxos de análise de dados, isso significa construir pipelines confiáveis em que a análise da IA alimenta diretamente seus sistemas de negócio existentes.
Mensagens e histórico de chat em agentes Pydantic
Ao trabalhar com agentes de análise de dados, você frequentemente precisa de conversas que se estendam por várias interações. Talvez você comece pedindo tendências de vendas, depois queira aprofundar em regiões específicas ou comparar períodos. Mensagens e histórico de chat permitem manter o contexto ao longo dessas conversas.
Acessando o histórico de mensagens
Cada vez que você roda um agente, o Pydantic AI registra toda a conversa. Você pode acessar esse histórico para entender o que aconteceu ou continuar depois:
from pydantic_ai import Agent# Create our sales analysis agentsales_agent = Agent( 'anthropic:claude-sonnet-4-0', system_prompt="You are a sales analyst. Provide clear, concise analysis.")# First questionresult1 = sales_agent.run_sync("What are the main KPIs I should track for Q1 2025 sales?")print(result1.output)# Access the conversation historyall_messages = result1.all_messages()print(f"Total messages in conversation: {len(all_messages)}")# Just the new messages from this runnew_messages = result1.new_messages()print(f"New messages from this run: {len(new_messages)}")Here are the essential KPIs to track for Q1 2025 sales:...Total messages in conversation: 2New messages from this run: 2O método all_messages() traz tudo: prompts de sistema, perguntas do usuário e respostas do agente. Já o new_messages() retorna apenas o que ocorreu na execução atual. Isso é útil ao construir conversas mais longas e querer acompanhar o que mudou.
Dando continuidade com histórico de mensagens
Para dar sequência às conversas, passe o histórico de mensagens para a próxima execução do agente. Assim, ele se lembra do que foi discutido antes:
# Continue the conversation from where we left offresult2 = sales_agent.run_sync( "How should I calculate conversion rates for each of those KPIs?", message_history=result1.all_messages())print(result2.output)# The agent now has context from both interactionsprint(f"Full conversation length: {len(result2.all_messages())}")# Ask a follow-up that references the entire conversationresult3 = sales_agent.run_sync( "Which of these metrics would be most important for a monthly executive report?", message_history=result2.all_messages())print(result3.output)Cada nova execução aproveita o contexto anterior. O agente lembra não só das suas perguntas, mas também das próprias respostas, criando uma conversa analítica coerente.
Armazenando e carregando mensagens em JSON
Para armazenamento de longo prazo ou compartilhamento de conversas entre sistemas, você pode serializar o histórico para JSON:
import json# Get the conversation as JSONconversation_json = result3.all_messages_json()# Save to filewith open('sales_analysis_conversation.json', 'w') as f: f.write(conversation_json.decode('utf-8'))print("Conversation saved to JSON file")# Load it back laterwith open('sales_analysis_conversation.json', 'r') as f: loaded_conversation = f.read()# You can now use this loaded conversation in a new agent run# (Note: You'd need to convert back from JSON to message objects for actual use)print(f"Loaded conversation size: {len(loaded_conversation)} characters")O método all_messages_json() retorna a conversa como bytes JSON, ideal para salvar em bancos de dados, enviar por APIs ou arquivar sessões de análise. Há também o new_messages_json() se você quiser salvar apenas a parte mais recente da conversa.
Essa abordagem permite construir fluxos analíticos persistentes. Você pode salvar a sessão de análise de cada cliente, retomar investigações complexas ao longo de vários dias ou compartilhar o contexto da conversa entre diferentes membros do time trabalhando na mesma análise.
Trabalhando com imagens e documentos
Análises reais envolvem mais do que texto e números. Você pode precisar analisar gráficos de relatórios, extrair dados de PDFs ou interpretar visualizações. O Pydantic AI tem suporte a entrada de imagens e documentos, permitindo que seus agentes trabalhem diretamente com essas fontes ricas de dados.
Analisando imagens por URL
Quando você tem gráficos ou visualizações hospedados online, pode apontar seu agente diretamente para eles:
from pydantic_ai import Agent, ImageUrl# Create an agent that can analyze visual datavisual_agent = Agent( 'anthropic:claude-sonnet-4-0', system_prompt="You are a data analyst who can interpret charts, graphs, and business documents.")# Analyze a sales chart from a URLresult = visual_agent.run_sync([ "What are the main trends shown in this sales chart? Give me 3 key takeaways.", ImageUrl(url='https://example.com/q1-sales-chart.png')])print(result.output)O agente consegue identificar tipos de gráficos, ler valores dos eixos, detectar tendências e oferecer insights de negócio como um analista faria ao olhar a mesma visualização.
Trabalhando com imagens locais
Para imagens armazenadas localmente — como capturas de tela das suas ferramentas de BI ou gráficos exportados do Excel — use BinaryContent:
from pathlib import Pathfrom pydantic_ai import Agent, BinaryContent# Load a local sales dashboard screenshotdashboard_path = Path('sales_dashboard_jan_2025.png')result = visual_agent.run_sync([ "Analyze this sales dashboard. What metrics need attention based on what you see?", BinaryContent( data=dashboard_path.read_bytes(), media_type='image/png' )])print(result.output)Essa abordagem é ótima para fluxos de relatórios automatizados. Você pode fazer screenshots dos dashboards programaticamente e pedir para a IA gerar uma análise escrita para acompanhar as visuais.
Analisando documentos por URL
Muitos documentos de negócios são compartilhados por URL — relatórios em intranets, PDFs no armazenamento em nuvem ou artigos públicos que embasam sua análise:
from pydantic_ai import Agent, DocumentUrl# Create an agent for document analysisdoc_agent = Agent( 'anthropic:claude-sonnet-4-0', system_prompt="Extract and summarize business-relevant insights from documents.")# Analyze a quarterly report PDFresult = doc_agent.run_sync([ "Read this quarterly earnings report and summarize the revenue trends and outlook.", DocumentUrl(url='https://company.com/reports/q1-2025-earnings.pdf')])print(result.output)O agente consegue ler documentos inteiros, extrair dados relevantes e fornecer resumos que levariam muito mais tempo para um humano compilar.
Processando documentos locais
Para documentos no seu sistema — como relatórios exportados, contratos ou apresentações internas — use BinaryContent:
from pathlib import Pathfrom pydantic_ai import Agent, BinaryContent# Load a local Excel export saved as PDFreport_path = Path('monthly_sales_analysis_jan_2025.pdf')result = doc_agent.run_sync([ "Extract the key performance metrics from this monthly sales report and identify any concerning trends.", BinaryContent( data=report_path.read_bytes(), media_type='application/pdf' )])print(result.output)Isso abre possibilidades poderosas de automação. Você pode processar pilhas de relatórios, extrair dados de notas fiscais ou analisar termos de contratos — tarefas que normalmente exigem revisão manual.
Observações importantes:
Modelos diferentes suportam formatos de arquivo distintos. A maioria lida com imagens comuns (PNG, JPEG) e PDFs, mas verifique a documentação do seu modelo para detalhes. Alguns modelos, como o Vertex AI do Google, conseguem acessar URLs de armazenamento em nuvem diretamente, enquanto outros primeiro fazem o download do conteúdo.
Para fluxos de análise de dados, essa capacidade multimodal faz a ponte entre seus relatórios visuais e os insights gerados por IA, permitindo automatizar a análise de toda a variedade de documentos de negócio com que você lida no dia a dia.
Habilitando streaming no Pydantic AI
Ao lidar com tarefas complexas de análise de dados, é melhor ver os resultados conforme são gerados, em vez de esperar pela resposta completa. O streaming permite acompanhar a análise em tempo real — algo valioso ao fazer perguntas detalhadas sobre desempenho de vendas.
O Pydantic AI oferece streaming integrado por meio do método run_stream(). Veja como funciona:
import asynciofrom pydantic_ai import Agent# Create our sales analysis agentsales_agent = Agent( 'anthropic:claude-sonnet-4-0', system_prompt=( "You are a data analyst specializing in sales performance. " "Provide detailed, actionable insights based on the data provided." ))async def demo_streaming(): question = """ Analyze this sales scenario: Our company sold 1,200 laptops and 2,300 phones last quarter across 4 regions. Laptops average $1,500 each, phones $500 each. What are the key insights and recommendations? """ async with sales_agent.run_stream(question) as result: async for text in result.stream_text(): print(text, end='', flush=True)# Run the streaming analysisasyncio.run(demo_streaming())Entendendo a sintaxe de streaming:
O async with cria uma conexão com o LLM que fica aberta enquanto os trechos de texto chegam. Pense como uma ligação telefônica: você precisa abrir a conexão, ter a conversa e depois encerrar corretamente.
O loop async for processa cada trecho de texto à medida que chega. Note que o stream_text() regenera o texto completo a cada vez — você recebe "Olá", depois "Olá mundo", depois "Olá mundo, como". Isso dá o contexto completo, mas pode ser repetitivo para exibição.
Por que async e asyncio trabalham juntos:
Quando você faz uma pergunta a um LLM, leva um tempo para gerar a resposta — normalmente de 3 a 10 segundos. Durante esse período, o modelo envia pequenos pedaços de texto a cada 50–200 milissegundos.
Sem async, seu programa ficaria travado aguardando cada pedaço. Com async, o event loop do Python (o sistema que gerencia esses tempos de espera) pode alternar entre tarefas. Assim, seu programa continua responsivo e pode até rodar várias conversas ao mesmo tempo.
asyncio.run() é o que inicia tudo isso — ele cria o event loop que coordena tudo. Quando você chama asyncio.run(demo_streaming()), configura o ambiente onde suas funções assíncronas podem pausar e retomar conforme necessário enquanto aguardam as respostas do LLM.
Agora vamos criar uma função reutilizável que mostra apenas os deltas de texto novos para uma experiência de streaming melhor:
from pydantic_ai.messages import PartDeltaEvent, TextPartDeltaasync def stream_agent_response(agent: Agent, task: str): """ Stream a response from any Pydantic AI agent showing just new text deltas. """ async def event_handler(ctx, event_stream): async for event in event_stream: if isinstance(event, PartDeltaEvent) and isinstance( event.delta, TextPartDelta ): print(event.delta.content_delta, end="", flush=True) # Use agent.run() with event_stream_handler for proper streaming result = await agent.run(task, event_stream_handler=event_handler) print() # Add a newline when streaming is complete return result# Usage exampleresponse = asyncio.run(stream_agent_response( sales_agent, "What are the top 3 metrics I should track for quarterly sales analysis?"))Detalhando a função de streaming:
A função stream_agent_response() cria uma experiência mais natural ao exibir apenas o texto novo conforme ele chega. Como funciona:
- Configuração do event handler: a função interna
event_handler()escuta eventos específicos durante o processamento do agente. Ela filtra porPartDeltaEventcomTextPartDelta— que representam trechos novos sendo gerados. - Conteúdo delta: em vez de receber o texto completo regenerado a cada vez,
event.delta.content_deltaentrega apenas as palavras ou caracteres novos. Isso cria um efeito “máquina de escrever”, mostrando a resposta sendo escrita palavra por palavra. - Execução do agente: usamos
agent.run()com o parâmetroevent_stream_handler. Isso diz ao agente para chamar nosso handler personalizado a cada evento de streaming, dando controle fino sobre o que é exibido. - Saída em tempo real: o
print(event.delta.content_delta, end="", flush=True)mostra cada novo trecho imediatamente, sem quebras de linha, criando um fluxo contínuo de texto.
Essa abordagem dá a sensação natural de ver a IA pensar a análise em tempo real, em vez de esperar a resposta completa ou ver texto regenerado repetidamente. Vamos usar essa função nas próximas seções para mostrar respostas em streaming ao longo dos exemplos de análise de dados.
Conclusão
Ao longo deste tutorial, você construiu uma compreensão completa do Pydantic AI por meio de exemplos práticos de análise de dados. Você aprendeu a criar agentes com prompts de sistema, adicionar ferramentas nativas e personalizadas, estruturar saídas com modelos Pydantic e fazer streaming de respostas para feedback em tempo real. Esses componentes se combinam para criar sistemas de IA que atuam mais como parceiros analíticos do que simples chatbots.
As aplicações vão muito além dos exemplos de análise de vendas que vimos. Agora você pode construir agentes de IA que leem suas fontes de dados específicas, seguem suas regras de negócio e retornam resultados em formatos que funcionam com seus sistemas atuais. Seja para automatizar a geração de relatórios, analisar feedback de clientes ou processar dados financeiros, o Pydantic AI oferece a estrutura e a confiabilidade necessárias para aplicações em produção.
Se você se interessa por construir sistemas multiagente com LangGraph, não deixe de conferir nosso curso prático.

Sou um criador de conteúdo de ciência de dados com mais de 2 anos de experiência e um dos maiores seguidores no Medium. Gosto de escrever artigos detalhados sobre IA e ML com um estilo um pouco sarcástico, porque você precisa fazer algo para torná-los um pouco menos monótonos. Produzi mais de 130 artigos e um curso DataCamp, e estou preparando outro. Meu conteúdo foi visto por mais de 5 milhões de pessoas, das quais 20 mil se tornaram seguidores no Medium e no LinkedIn.


