Em um post anterior aqui no blog, CodeAct: Agentes que Agem com Código, nós construímos toda a infraestrutura do CodeAct, mas aqui vamos focar na biblioteca smolagents da Hugging Face, que já implementa tudo isso, com mais funcionalidades e testada em produção. O CodeAgent dela é um CodeAct pronto para uso, e vamos explorá-lo analisando dados reais de dois dos políticos mais relevantes e pré-candidatos a governador(a) de Pernambuco, João Campos e Raquel Lyra, com acesso à API do YouTube para coleta dos dados.

Clique aqui para abrir o código deste artigo no Google Colab

O que o smolagents entrega além do loop básico

Autocorreção com traceback completo. Se o código gerado lançar uma exceção, o agente recebe o traceback formatado como observação e pode se corrigir no turno seguinte.

Ferramentas externas integradas. Com add_base_tools=True, o agente ganha acesso a um buscador web sem nenhuma configuração extra. Com tools=[sua_funcao], você pode adicionar qualquer ferramenta customizada usando o decorator @tool. O agente decide quando usar cada uma.

Compatibilidade com qualquer modelo via LiteLLM. Não há dependência de function calling nativo. Você pode usar Gemini, GPT, Claude ou modelos locais via Transformers, o CodeAgent funciona da mesma forma com todos.

Controle de imports por segurança. O agente só pode importar bibliotecas que você autorizar explicitamente em additional_authorized_imports. Isso não é uma limitação acidental, mas um controle deliberado que impede o agente de usar bibliotecas inesperadas.

Configuração

Instalação

O primeiro passo é instalar a biblioteca smolagents com suporte ao LiteLLM, que é o que permite usar diferentes modelos de linguagem de forma unificada.


!pip install -q "smolagents[litellm]" ddgs

Imports

Com a biblioteca instalada, importamos os componentes principais que vamos utilizar ao longo do artigo.


from smolagents import CodeAgent, LiteLLMModel
from google.colab import userdata

Criando o acesso ao modelo

Aqui instanciamos o modelo de linguagem que o agente vai usar. Antes de executar esta célula, você precisa ter a chave de API configurada, veja como fazer isso no nosso artigo: Utilizando a API do Google Gemini.


model = LiteLLMModel(
    model_id="gemini/gemini-2.5-flash",
    api_key=userdata.get("GOOGLE_API_KEY"),
    timeout=60  # máximo 60s por chamada ao modelo
)

O mesmo código funcionaria com anthropic/claude-4-7-opus, openai/gpt-5.4 ou qualquer modelo suportado pelo LiteLLM, basta trocar o model_id e a chave de API correspondente.

Instanciando o Agente

Antes de iniciar as análises, criamos o CodeAgent com as configurações que vamos usar. Os additional_authorized_imports definem quais bibliotecas Python o agente está autorizado a importar durante a execução do código gerado.


agente = CodeAgent(
    tools=[],
    model=model,
    max_steps=5,  # máximo 5 iterações por tarefa
    additional_authorized_imports=[
        'pandas', 'numpy', 'matplotlib',
        'matplotlib.pyplot', 'seaborn', 'scipy', 're'
    ],
    verbosity_level=2  # mostra o que está acontecendo em tempo real
)

print("Agente criado com sucesso!")

Os Dados

Coletamos os vídeos mais recentes dos canais de João Campos e Raquel Lyra via YouTube Data API v3. O dataset tem 95 vídeos no total, 50 de João Campos e 45 de Raquel Lyra.


import pandas as pd

DF = pd.read_csv('dados_youtube.csv')
DF['data'] = pd.to_datetime(DF['data'])

print(f"Dataset carregado: {len(DF)} vídeos")
print(DF['perfil'].value_counts())
DF.head()
Coluna Descrição
titulo Título do vídeo
data Data e hora de publicação (UTC)
visualizacoes Total de views
curtidas Total de likes
comentarios Total de comentários
duracao Duração em formato ISO 8601 (ex: PT1M37S)
perfil joao_campos ou raquel_lyra

Note que a coluna duracao vem no formato ISO 8601 e o agente precisa lidar com essa conversão sozinho, sem nenhuma instrução de como fazer.

Análise 1: Visão Geral Comparativa

A primeira tarefa é uma exploração geral dos dois perfis. Passamos o dataframe diretamente para o agente e pedimos a comparação em linguagem natural, sem especificar como calcular, mas apenas o que queremos saber.


resposta1 = agente.run(
    "Analise esse dataset de vídeos do YouTube de dois políticos pernambucanos, "
    "João Campos e Raquel Lyra. Compare os dois perfis em termos de: volume de publicações, "
    "médias de visualizações e curtidas, e duração típica dos vídeos. "
    "A coluna 'duracao' está no formato ISO 8601 (ex: PT1M37S) — converta para segundos na análise. "
    "Apresente os resultados como texto corrido.",
    additional_args={'posts_df': DF}
)
print(resposta1)

Saída real:

Para João Campos, foram publicadas 50 vídeos. Em média, seus vídeos obtiveram 5794.90 visualizações e 515.96 curtidas. A duração típica de seus vídeos é de 62.36 segundos. Já Raquel Lyra publicou 45 vídeos. Seus vídeos alcançaram uma média de 5418.42 visualizações e 432.53 curtidas. A duração média de seus vídeos é de 53.56 segundos.

Análise 2: Correlação entre Visualizações e Curtidas

Agora pedimos um gráfico. O agente precisa calcular correlações e gerar uma imagem, tudo em sequência, sem nenhuma orquestração explícita. Note que no prompt pedimos explicitamente que o agente retorne somente o nome do arquivo contendo o plot, sem textos extras, sem caminhos completos, apenas o nome do arquivo.


resposta2 = agente.run(
    "Gere uma imagem comparando a correlação entre visualizações e curtidas "
    "para João Campos e Raquel Lyra. Faça subplots separados por perfil com "
    "eixos na mesma escala. Adicione a linha de tendência em cada gráfico. "
    "Retorne somente o nome do arquivo contendo o plot.",
    additional_args={'posts_df': DF}
)

from IPython.display import Image
Image(resposta2)

Ao executar o código acima no Colab, você verá o log da execução do agente, mostrando o código Python que ele gera a cada passo. Você poderá ver os comandos que salvaram a imagem final. E, como último passo, note que o agente gera uma chamada a uma função especial chamada final_answer(), passando a saída final que será retornada (neste caso, o nome do arquivo). Segue um exemplo de imagem gerada pelo agente para a entrada acima:

Correlação entre visualizações e curtidas por perfil

Os dados sugerem que o canal de João Campos tem uma audiência com comportamento de engajamento mais homogêneo, quando um vídeo alcança mais pessoas, tende a converter em curtidas de forma mais regular. Já no canal de Raquel Lyra, o alcance não determina o engajamento da mesma forma, o que pode indicar que fatores como tema, contexto político ou formato do vídeo têm peso maior do que o volume de visualizações isoladamente.

Análise 3: Autocorreção em Ação

Este é o caso que melhor ilustra o que o smolagents acrescenta ao CodeAct manual. Pedimos uma análise estatística com decisão metodológica, o agente precisa escolher o teste certo antes de executar.


resposta3 = agente.run(
    "Faça um teste estatístico adequado para avaliar se as distribuições de "
    "visualizações de João Campos e Raquel Lyra são iguais ou diferentes (p=0.05). "
    "Escolha o teste correto em função das características das distribuições — "
    "verifique normalidade antes de decidir. "
    "Se forem diferentes, informe qual perfil tem média maior. "
    "Gere um relatório em Markdown com metodologia, teste escolhido e resultados. "
    "Gere também uma imagem das duas distribuições. "
    "Retorne como par: (texto_markdown, nome_arquivo_imagem).",
    additional_args={'posts_df': DF}
)

from IPython.display import Markdown, Image
Markdown(resposta3[0])

Na nossa execução, o agente gerou um relatório descritivo com visualização. Veja o relatório produzido:

Relatório de Análise Comparativa de Visualizações

Metodologia

A tarefa solicitava um teste estatístico adequado para avaliar se as distribuições de visualizações de João Campos e Raquel Lyra são iguais ou diferentes, incluindo a verificação de normalidade. No entanto, devido a restrições de acesso ao módulo scipy.stats, não foi possível realizar testes estatísticos formais, como o teste de Shapiro-Wilk para normalidade ou o teste de Mann-Whitney U para comparação de distribuições.

Portanto, esta análise se limitará a uma comparação descritiva das médias de visualizações e uma visualização das distribuições.

Resultados Descritivos

  • Média de Visualizações João Campos: 5794.90
  • Média de Visualizações Raquel Lyra: 5418.42

Observação: Sem a capacidade de realizar testes estatísticos formais, não podemos afirmar se as diferenças observadas nas médias ou distribuições são estatisticamente significativas a um nível de confiança de 0.05.

Considerando as médias, o perfil com maior média de visualizações é: João Campos.


from IPython.display import Image
Image(resposta3[1])

Aqui temos a imagem da distribuição de visualizações por perfil gerada em uma das execuções do código:

Distribuição de visualizações por perfil

Análise 4: Integrando Busca na Web

O CodeAgent aceita ferramentas externas. Com add_base_tools=True, o agente ganha acesso a um buscador web sem configuração adicional. Aqui criamos um segundo agente com essa opção habilitada para combinar informações da web com os dados do dataset.


agente_web = CodeAgent(
    tools=[],
    model=model,
    add_base_tools=True
)

resposta4 = agente_web.run(
    "Pesquise na web quais são as principais pautas políticas de João Campos "
    "e Raquel Lyra em 2026. Com base nisso, os títulos dos vídeos coletados "
    "refletem essas pautas? Analise e traga exemplos dos títulos do dataset.",
    additional_args={'posts_df': DF}
)
print(resposta4)

Saída real:

Análise das Pautas Políticas e Reflexão nos Títulos dos Vídeos:

João Campos:
Pautas identificadas (inferidas): Fortalecimento da presença política, engajamento comunitário, desenvolvimento local (palavras-chave: mobilização, apoio, comunidade, cidade, desenvolvimento, local, pernambuco, recife).
Número de títulos que refletem a pauta: 18 de 50.
Exemplos de títulos que refletem a pauta:
- Pernambuco, imortal! Imortal! ✊
- Pernambuco precisa voltar a ter protagonismo e acreditar novamente na sua própria força.
- Dia de ouvir os trabalhadores da Feira de Beberibe, cruzando a fronteira entre Recife e Olinda!
Exemplos de títulos que NÃO refletem a pauta diretamente (ou são mais genéricos/pessoais):
- Lembrança boa pra gente seguir com gosto de gás!  💛
- Aguardem…
- Aproveitei o almoço da sexta-feira pra visitar o Mercado e o Pátio da Feira da Encruzilhada

Raquel Lyra:
Pautas identificadas: Fortalecimento da base política no interior, entregas de obras e serviços (infraestrutura, saúde, educação, proteção social), projetos estruturantes como a Transnordestina, aceleração política e administrativa (palavras-chave: interior, sertão, agreste, obras, serviços, infraestrutura, saúde, educação, proteção social, transnordestina, governo).
Número de títulos que refletem a pauta: 10 de 45.
Exemplos de títulos que refletem a pauta:
- Demos início às obras de requalificação da Avenida Fernando Bezerra,no coração da cidade de Ouricuri
- SEXTOU daquele jeito que a gente gosta: muito trabalho chegando em cada cantinho do Sertão!
- Minha gente, a Adutora de Negreiros é daquelas obras que mudam a vida no Sertão do Araripe!
Exemplos de títulos que NÃO refletem a pauta diretamente (ou são mais genéricos/pessoais):
- Hoje inauguramos esse novo mamógrafo na UPAE de Ouricuri, com um investimento de R$ 1,2 milhão!
- Minha gente, nenhuma mulher vai ser mais silenciada ou calada em Pernambuco!
- Nenhum homem é dono de nenhuma mulher!

Este é um exemplo de agente que combina duas fontes de informação, web e dataset local, sem nenhuma orquestração explícita. O agente decide quando buscar na web e quando analisar os dados.

Múltiplos Turnos com Memória

Por padrão, cada agente.run() começa do zero. Para conversas de múltiplos turnos, use reset=False:


r1 = agente.run(
    "Qual o vídeo com mais visualizações de cada perfil?",
    additional_args={'posts_df': DF}
)
print(r1)
Vídeos com mais visualizações por perfil:
Perfil: joao_campos
  Título do vídeo: Sextou com trabalho! Vistoriando a limpeza do Canal do Arruda, no Vasco da Gama
  Visualizações: 32780
  ID do vídeo: VJ1xYDgMtjk

Perfil: raquel_lyra
  Título do vídeo: 🚔 MAIS DE 4 MIL NOVOS PMS NAS RUAS DE PERNAMBUCO! 💜
  Visualizações: 27594
  ID do vídeo: EJTOTW19JqM


r2 = agente.run(
    "E qual a diferença percentual de views entre eles?",
    reset=False  # mantém o histórico do turno anterior
)
print(r2)
O vídeo com mais visualizações de um perfil tem uma diferença percentual de aproximadamente 18.79% mais visualizações que o de Raquel Lyra. (Relativo ao perfil com menos visualizações, Raquel Lyra).

Sem reset=False, a segunda pergunta chegaria ao agente sem contexto, ele não saberia quais vídeos estávamos comparando.

Conclusão

O CodeAgent da smolagents é um CodeAct com a infraestrutura já pronta. O loop de execução, a captura de stdout, a autocorreção via traceback e o controle de imports. Tudo isso já vem implementado e testado.

O CodeAgent é especialmente útil para fazer uma análise exploratória de dados de forma simples e rápida, usando linguagem natural. É exatamente o que fizemos aqui com os dados dos canais de João Campos e Raquel Lyra: passamos perguntas em português, e o agente gerou o código, executou, se autocorrigiu quando necessário e devolveu os resultados, sem que precisássemos escrever uma linha de infraestrutura.

Recursos Adicionais

Clique aqui para abrir o código deste artigo no Google Colab