Última notícia há desconhecido
Tutorialavancado· Avançado· PT60M

Como criar Agentes de IA com Python e LangChain

Tutorial avançado de agentes de IA com LangChain e LangGraph. Aprenda a construir agentes que usam ferramentas (busca web, calculadora, código), têm memória e tomam decisões autônomas.

13 de maio de 2026· Atualizado em 14 de maio de 2026por Redação SWEN.AI

Agentes de IA vs Chatbots: A Diferença Fundamental

Se você já usou o ChatGPT ou qualquer LLM via API, você criou um chatbot. Mas um agente de IA é uma categoria completamente diferente.

Um chatbot recebe uma mensagem, processa, devolve uma resposta. Ponto final. O modelo não toma decisões sobre o que fazer a seguir, não acessa sistemas externos por conta própria, não executa código, não itera sobre um problema até resolvê-lo.

Um agente, por outro lado, é um sistema que:

1. Recebe um objetivo (não apenas uma pergunta)

2. Decide quais ações tomar para atingir esse objetivo

3. Executa essas ações usando ferramentas (tools)

4. Observa os resultados de cada ação

5. Itera até que o objetivo seja atingido

| Característica | Chatbot | Agente de IA |

|---|---|---|

| Tipo de input | Pergunta/mensagem | Objetivo/tarefa |

| Número de passos | Único | Múltiplos (plan → act → observe → repeat) |

| Acesso a ferramentas | Não (ou limitado) | Sim, dinâmico |

| Capacidade de iteração | Não | Sim |

| Exemplos de uso | FAQ, suporte básico | Pesquisa autônoma, execução de código |

A virada conceitual é esta: você não pergunta "qual a capital da França?" para um agente. Você diz "pesquise os 5 maiores aeroportos europeus, encontre as tarifas médias e gere um relatório CSV". O agente planeja, usa ferramentas de busca, executa código Python, e entrega o resultado.

---

A Arquitetura de um Agente: ReAct e Tool Use

O padrão de raciocínio mais usado é o ReAct (Reasoning + Acting). O modelo intercala raciocínio com ações reais:

Thought: Preciso saber o preço atual do Bitcoin.
Action: web_search
Action Input: "Bitcoin price USD today"
Observation: Bitcoin está cotado a $67.450 USD.
Thought: Agora tenho o preço. Posso responder ao usuário.
Final Answer: O preço atual do Bitcoin é $67.450 USD.

O padrão moderno é o Tool Calling (Function Calling), disponível em GPT-4o e Claude. Em vez de parsear texto livre, o modelo emite chamadas de função estruturadas em JSON. É mais confiável e é o padrão recomendado:

{
  "name": "web_search",
  "arguments": { "query": "Bitcoin price USD today" }
}

---

Configurando o Ambiente: LangChain + OpenAI

python -m venv venv && source venv/bin/activate

pip install langchain langchain-openai langchain-community \
            langchain-experimental duckduckgo-search \
            python-dotenv langgraph langsmith
# .env
OPENAI_API_KEY=sk-...
LANGCHAIN_API_KEY=ls__...
LANGCHAIN_TRACING_V2=true
LANGCHAIN_PROJECT=meu-agente
# config.py
from langchain_openai import ChatOpenAI

def get_llm(model="gpt-4o-mini", temperature=0):
    # temperature=0 para agentes: decisoes consistentes, nao criativas
    return ChatOpenAI(model=model, temperature=temperature)

---

Suas Primeiras Tools: Web Search e Python REPL

Tools são funções Python decoradas com metadados que o LLM usa para decidir quando e como chamá-las. A docstring é literalmente o que o modelo lê para decidir se deve usar a tool.

DuckDuckGo Search Tool

from langchain_community.tools import DuckDuckGoSearchResults

def get_search_tool(max_results: int = 5):
    return DuckDuckGoSearchResults(
        num_results=max_results,
        backend="text"
    )

# Testando isoladamente
if __name__ == "__main__":
    tool = get_search_tool()
    resultado = tool.run("LangChain agentes IA 2025")
    print(resultado)

Python REPL Tool

from langchain_experimental.tools import PythonREPLTool

def get_repl_tool():
    # ATENCAO: executa codigo real na sua maquina
    # Em producao, use sandboxing (Docker, subprocess com timeout)
    return PythonREPLTool()

# Testando
if __name__ == "__main__":
    repl = get_repl_tool()
    resultado = repl.run("""
import statistics
dados = [23, 45, 12, 67, 34, 89, 56]
print(f"Media: {statistics.mean(dados):.2f}")
print(f"Desvio padrao: {statistics.stdev(dados):.2f}")
""")
    print(resultado)

Criando uma Tool Customizada

from langchain_core.tools import tool
import json
import datetime

@tool
def buscar_cotacao_moeda(moeda_origem: str, moeda_destino: str) -> str:
    """
    Busca a cotacao atual entre duas moedas.
    Use quando precisar converter valores monetarios ou verificar taxas de cambio.

    Args:
        moeda_origem: Codigo ISO da moeda de origem (ex: 'USD', 'BRL', 'EUR')
        moeda_destino: Codigo ISO da moeda de destino (ex: 'BRL', 'USD', 'EUR')
    """
    # Em producao: usar API real como exchangerate-api.com
    taxas = {
        ("USD", "BRL"): 5.12,
        ("EUR", "BRL"): 5.54,
        ("BRL", "USD"): 0.195,
    }

    par = (moeda_origem.upper(), moeda_destino.upper())
    if par in taxas:
        taxa = taxas[par]
        ts = datetime.datetime.now().strftime("%Y-%m-%d %H:%M")
        return f"1 {moeda_origem.upper()} = {taxa} {moeda_destino.upper()} (atualizado em {ts})"
    return f"Cotacao nao disponivel para {moeda_origem}/{moeda_destino}"

---

Construindo um Agente de Pesquisa Completo

from langchain_openai import ChatOpenAI
from langchain.agents import AgentExecutor, create_tool_calling_agent
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_community.tools import DuckDuckGoSearchResults
from langchain_core.tools import tool
from datetime import datetime

@tool
def formatar_relatorio(titulo: str, secoes: str) -> str:
    """
    Formata o relatorio final em Markdown. Use como ULTIMO passo da pesquisa.

    Args:
        titulo: Titulo principal do relatorio
        secoes: Conteudo das secoes em formato de texto corrido
    """
    data = datetime.now().strftime("%d/%m/%Y")
    return f"# {titulo}\n*Relatorio gerado em {data}*\n\n---\n\n{secoes}"


def criar_agente_pesquisa(verbose=True):
    llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)

    tools = [
        DuckDuckGoSearchResults(num_results=5),
        formatar_relatorio,
    ]

    system_prompt = """Voce e um agente de pesquisa especializado em tecnologia e IA.

Processo de trabalho:
1. Para cada topico, realize 2-3 buscas com queries diferentes e complementares
2. Sintetize as informacoes, eliminando redundancias
3. Use a tool formatar_relatorio para gerar o documento final

IMPORTANTE: Nunca invente dados. Use apenas o que encontrou nas buscas."""

    prompt = ChatPromptTemplate.from_messages([
        ("system", system_prompt),
        MessagesPlaceholder(variable_name="chat_history", optional=True),
        ("human", "{input}"),
        MessagesPlaceholder(variable_name="agent_scratchpad"),
    ])

    agent = create_tool_calling_agent(llm=llm, tools=tools, prompt=prompt)

    return AgentExecutor(
        agent=agent,
        tools=tools,
        verbose=verbose,
        max_iterations=10,
        handle_parsing_errors=True,
        return_intermediate_steps=True,
    )


if __name__ == "__main__":
    agente = criar_agente_pesquisa(verbose=True)

    resultado = agente.invoke({
        "input": "Pesquise sobre o estado atual dos agentes de IA em 2025."
    })

    print("\n=== RELATORIO FINAL ===")
    print(resultado["output"])
    print(f"\nPassos executados: {len(resultado['intermediate_steps'])}")

---

Memória em Agentes: Conversation, Entity e Summary

Por padrão, agentes LangChain são stateless — cada invocação começa do zero. Para criar agentes que lembram de conversas, adicione memória explicitamente.

| Tipo | Como funciona | Quando usar | Custo de tokens |

|---|---|---|---|

| ConversationBufferWindowMemory | Mantém últimas N trocas | Balance custo/contexto | Controlável |

| ConversationSummaryMemory | Resume o histórico com LLM | Conversas longas | Médio |

| ConversationEntityMemory | Extrai e mantém entidades | Contexto com dados específicos | Baixo |

from langchain.memory import ConversationBufferWindowMemory

memory = ConversationBufferWindowMemory(
    k=5,                        # ultimas 5 trocas
    memory_key="chat_history",
    return_messages=True,
)

# Adicionando memoria ao executor
executor = AgentExecutor(
    agent=agent,
    tools=tools,
    memory=memory,
    verbose=True,
    max_iterations=8,
)

# Testando continuidade
r1 = executor.invoke({"input": "Pesquise sobre LangChain."})
r2 = executor.invoke({"input": "Quais as principais novidades que voce mencionou?"})
# O agente lembra do contexto anterior

---

Construindo um Agente com Múltiplas Tools

from langchain_experimental.tools import PythonREPLTool
from langchain.memory import ConversationBufferWindowMemory

def criar_agente_financeiro():
    llm = ChatOpenAI(model="gpt-4o", temperature=0)

    tools = [
        DuckDuckGoSearchResults(num_results=4, name="web_search"),
        PythonREPLTool(name="python_repl"),
        buscar_cotacao_moeda,
    ]

    memory = ConversationBufferWindowMemory(
        k=6, memory_key="chat_history", return_messages=True
    )

    system_prompt = """Voce e um analista financeiro especializado.

Capacidades:
- web_search: para buscar noticias e dados de mercado atualizados
- python_repl: para calculos, graficos e analises quantitativas
- buscar_cotacao_moeda: para obter taxas de cambio

SEMPRE inclua disclaimers: analises passadas nao garantem resultados futuros."""

    prompt = ChatPromptTemplate.from_messages([
        ("system", system_prompt),
        MessagesPlaceholder(variable_name="chat_history"),
        ("human", "{input}"),
        MessagesPlaceholder(variable_name="agent_scratchpad"),
    ])

    agent = create_tool_calling_agent(llm=llm, tools=tools, prompt=prompt)

    return AgentExecutor(
        agent=agent, tools=tools, memory=memory,
        verbose=True, max_iterations=12, handle_parsing_errors=True,
    )


if __name__ == "__main__":
    agente = criar_agente_financeiro()
    resposta = agente.invoke({
        "input": "Compare as perspectivas do dolar frente ao real para os "
                 "proximos 3 meses baseado em analises recentes."
    })
    print(resposta["output"])

---

Introdução ao LangGraph: Agentes Multi-Step

O LangGraph é a evolução natural para agentes complexos. Em vez de um único agente com N tools, você cria um grafo de agentes, onde cada nó é um agente especializado.

from langgraph.graph import StateGraph, END
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage
from typing import TypedDict, List, Annotated
import operator

class EstadoPesquisa(TypedDict):
    mensagens: Annotated[List, operator.add]
    topico: str
    dados_brutos: str
    relatorio_final: str

# Tres nos especializados
def no_pesquisa(estado):
    print("Pesquisando...")
    resultado = pesquisador.invoke({"input": f"Pesquise: {estado['topico']}"})
    return {"dados_brutos": resultado["output"]}

def no_analise(estado):
    print("Analisando...")
    resultado = analista.invoke({
        "input": f"Analise e extraia metricas:\n{estado['dados_brutos']}"
    })
    return {"analise": resultado["output"]}

def no_redacao(estado):
    print("Redigindo...")
    llm = ChatOpenAI(model="gpt-4o-mini", temperature=0.3)
    resposta = llm.invoke([HumanMessage(
        content=f"Escreva relatorio sobre '{estado['topico']}':\n{estado['dados_brutos'][:1500]}"
    )])
    return {"relatorio_final": resposta.content}

# Construindo o grafo
grafo = StateGraph(EstadoPesquisa)
grafo.add_node("pesquisa", no_pesquisa)
grafo.add_node("analise", no_analise)
grafo.add_node("redacao", no_redacao)
grafo.set_entry_point("pesquisa")
grafo.add_edge("pesquisa", "analise")
grafo.add_edge("analise", "redacao")
grafo.add_edge("redacao", END)

pipeline = grafo.compile()

resultado = pipeline.invoke({
    "mensagens": [],
    "topico": "Adocao de IA generativa em empresas brasileiras em 2025",
    "dados_brutos": "",
    "relatorio_final": "",
})
print(resultado["relatorio_final"])

O LangGraph brilha com fluxos condicionais — se a pesquisa retornar poucos dados, redirecionar para uma busca mais ampla antes de analisar. Isso se faz com add_conditional_edges.

---

Monitorando Agentes com LangSmith

import os

# Com estas variaveis, TODOS os agentes LangChain sao rastreados automaticamente
os.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_API_KEY"] = "ls__sua_chave_aqui"
os.environ["LANGCHAIN_PROJECT"] = "swen-agentes-producao"

Com o tracing ativo, acesse smith.langchain.com e veja cada execucao em tempo real: qual tool foi chamada, com que parametros, quanto demorou, e o custo exato em tokens.

---

Erros Comuns e Como Evitá-los em Produção

1. Loops Infinitos

Sempre configure:

executor = AgentExecutor(
    agent=agent,
    tools=tools,
    max_iterations=10,           # nunca deixe sem limite
    max_execution_time=60,       # timeout em segundos
    early_stopping_method="generate",
    handle_parsing_errors=True,
)

2. Custo de Tokens Explosivo

# RUIM: memoria cresce infinitamente
from langchain.memory import ConversationBufferMemory
memory = ConversationBufferMemory()

# BOM: janela controlada
memory = ConversationBufferWindowMemory(k=5)

3. Tools sem Tratamento de Erro

@tool
def buscar_api_externa(query: str) -> str:
    """Busca dados em API externa."""
    try:
        import httpx
        response = httpx.get("https://api.exemplo.com/search",
                             params={"q": query}, timeout=10.0)
        response.raise_for_status()
        return response.json()["result"]

    except httpx.TimeoutException:
        return "Erro: API nao respondeu em 10 segundos. Tente query mais especifica."

    except Exception as e:
        # Nunca deixe a excecao subir - retorne erro legivel para o LLM
        return f"Erro ao buscar dados: {str(e)[:200]}"

Quando NÃO Usar Agentes

| Situacao | Use Agente? | Alternativa |

|---|---|---|

| Transformacao simples de texto | Nao | LLM call direto |

| Pipeline ETL com passos fixos | Nao | LangChain Chain sequencial |

| Classificacao de intencao | Nao | Prompt engineering + JSON |

| Pesquisa com ferramentas externas | Sim | Agente |

| Execucao de codigo baseado em contexto | Sim | Agente |

Regra de ouro: use agentes quando o LLM precisa decidir quais ferramentas usar e em que ordem, com base em resultados intermediarios. Se o fluxo e fixo, uma Chain simples e mais barata, rapida e confiavel.

---

Perguntas Frequentes sobre Agentes IA

O agente pode usar quantas tools por iteracao?

Com Tool Calling (GPT-4o, Claude), o modelo pode chamar multiplas tools em paralelo numa unica iteracao. Habilite com parallel_tool_calls=True no ChatOpenAI.

Qual a diferenca entre create_tool_calling_agent e create_react_agent?

create_tool_calling_agent usa a API nativa de function calling do modelo (estruturado, confiavel, mais rapido). create_react_agent usa prompts de texto e parseia no formato Thought/Action/Observation (compativel com modelos sem function calling). Para GPT-4o e Claude, use sempre create_tool_calling_agent.

Como limitar o custo de um agente em producao?

Tres camadas: (1) max_iterations no AgentExecutor, (2) max_execution_time em segundos, (3) usar gpt-4o-mini para o agente e reservar gpt-4o apenas para o no de sintese final. Um agente de pesquisa bem otimizado com gpt-4o-mini custa menos de $0,01 por execucao.

Agentes LangChain funcionam com modelos open-source?

Sim, via ChatOllama (local) ou ChatGroq/ChatTogether (cloud). Para agentes complexos com muitas tools, use modelos de 70B+ ou os modelos comerciais.

Vale a pena usar LangGraph para todos os agentes?

Nao. Para agentes simples com 2-5 tools e fluxo linear, AgentExecutor e suficiente e mais simples de manter. LangGraph se justifica quando voce tem: multiplos agentes especializados, fluxos condicionais complexos, necessidade de paralelismo entre nos, ou checkpointing de estado para retomada de execucao.

Tutoriais relacionados