Agentes LangChain: guia técnico completo para 2026

Surya Pratap
By Surya Pratap

20 de junho de 2026

14 min de leitura

IA e tecnologia
Agentes LangChain a correr em produçãoAgentes LangChainHover to explore
Um agente não é um prompt: é um ciclo. Observar, raciocinar, agir e repetir até concluir.

Um LLM que responde a perguntas é útil. Um LLM capaz de fazer coisas — consultar a base de dados, enviar uma mensagem no Slack, processar um reembolso e depois reportar o que fez — é um produto. Os agentes LangChain são a forma padrão de montar esse ciclo em 2026. Este guia percorre todo o caminho, do modelo mental ao código de produção: o ciclo do agente, como escrever ferramentas, memória e estado, saída estruturada, streaming, tratamento de erros e o que funciona (ou não) segundo o r/LangChain, o r/LocalLLaMA e a comunidade do X.

Este guia assenta na documentação de agentes do LangChain v1, na documentação do LangGraph e nas discussões recorrentes do r/LangChain e do @LangChainAI no X.

1. O ciclo do agente: o que acontece mesmo em execução

Todos os agentes LangChain executam o mesmo ciclo, independentemente do modelo:

  1. Observar — o LLM recebe o histórico da conversa e a lista de ferramentas disponíveis (nome, descrição e esquema JSON dos argumentos).
  2. Raciocinar — o modelo decide se chama uma ferramenta ou se devolve a resposta final. Os modelos atuais usam tool calling nativo em vez de interpretar JSON dentro de texto livre.
  3. Agir — se for pedida uma chamada, o LangChain executa-a e acrescenta o resultado à conversa como ToolMessage.
  4. Repetir — o ciclo continua até o modelo devolver uma resposta sem chamadas ou até se atingir o limite de iterações configurado.

É só isto. A sofisticação está nas ferramentas que disponibiliza e na forma como limita o ciclo, não em magia dentro da framework.

2. O seu primeiro agente LangChain em 15 linhas

Com o create_agent do LangChain v1, o código repetitivo é mínimo:

from langchain.agents import create_agent
from langchain.tools import tool

@tool
def search_orders(order_id: str) -> str:
    """Look up an order by ID and return its current status."""
    # Replace with your real DB call
    return f"Order {order_id}: Shipped, arriving 2026-06-23."

@tool
def issue_refund(order_id: str, reason: str) -> str:
    """Issue a full refund for an order given a reason."""
    return f"Refund issued for order {order_id}. Reason: {reason}."

agent = create_agent(
    model="anthropic:claude-sonnet-4-6",
    tools=[search_orders, issue_refund],
    system_prompt=(
        "You are a helpful customer support agent. "
        "Always look up the order before issuing a refund."
    ),
)

result = agent.invoke({
    "messages": [{"role": "user", "content": "Refund order #4821 — it arrived broken."}]
})
print(result["messages"][-1].content)

Nos bastidores, o agente chama search_orders("4821"), lê o resultado, chama issue_refund("4821", "arrived broken") e devolve a confirmação ao utilizador — tudo numa única chamada a invoke, sem orquestração manual.

3. Escrever boas ferramentas: onde a maioria dos agentes falha

A alavanca com maior impacto na qualidade de um agente é o desenho das ferramentas, não a escolha do modelo. O modelo decide qual chamar apenas a partir do nome da função, da docstring e do esquema de argumentos. Se isso estiver mal feito, nenhuma engenharia de prompts o salva.

Regras que se confirmam na prática:

  • Uma ação por ferramenta. search_and_refund() é uma armadilha: separe-a. O modelo tem de conseguir chamar cada passo de forma independente.
  • Escreva a docstring para o modelo, não para uma pessoa. Indique quando chamar a ferramenta, o que devolve e quaisquer pré-condições rígidas («Chame isto apenas depois de confirmar que a encomenda existe»).
  • Devolva strings ou JSON simples. O modelo lê o valor de retorno como texto. Um objecto muito aninhado confunde-o; um resumo de uma frase funciona melhor.
  • Trate os erros dentro da ferramenta, não fora. Devolva "Error: order not found" em vez de lançar uma exceção — assim o agente pode tentar de novo ou explicar a falha em vez de rebentar.
from langchain.tools import tool
from pydantic import BaseModel, Field

class SearchInput(BaseModel):
    order_id: str = Field(description="The numeric order ID, e.g. '4821'")
    include_history: bool = Field(
        default=False,
        description="Set True to include the full shipment history"
    )

@tool(args_schema=SearchInput)
def search_orders(order_id: str, include_history: bool = False) -> str:
    """
    Look up an order's current status by order ID.
    Call this FIRST before any action that modifies the order.
    Returns: status string, or an error message if not found.
    """
    try:
        order = db.get_order(order_id)
        if not order:
            return f"Error: order {order_id} not found."
        base = f"Order {order_id}: {order.status}, ETA {order.eta}."
        if include_history:
            base += f" History: {order.shipment_history}"
        return base
    except Exception as e:
        return f"Error fetching order: {str(e)}"

4. Memória e estado persistente

Por omissão, cada chamada a agent.invoke() não guarda estado: o agente esquece o turno anterior assim que termina. Para conversas com vários turnos é preciso passar o estado explicitamente. O LangChain oferece dois padrões:

Padrão A — checkpointing por thread com LangGraph (recomendado em produção)

from langchain.agents import create_agent
from langgraph.checkpoint.memory import MemorySaver

# MemorySaver keeps state in RAM; swap for PostgresSaver in production
checkpointer = MemorySaver()

agent = create_agent(
    model="anthropic:claude-sonnet-4-6",
    tools=[search_orders, issue_refund],
    checkpointer=checkpointer,
)

# Same thread_id = same conversation memory
config = {"configurable": {"thread_id": "user-123-session-456"}}

# Turn 1
agent.invoke(
    {"messages": [{"role": "user", "content": "What is the status of order 4821?"}]},
    config=config,
)

# Turn 2 — agent remembers turn 1
agent.invoke(
    {"messages": [{"role": "user", "content": "Go ahead and refund it."}]},
    config=config,
)

Padrão B — sumarização para contextos longos

Quando um thread ultrapassa a janela de contexto do modelo, use o SummarizationMiddleware para comprimir automaticamente as mensagens antigas num resumo acumulado antes de cada chamada. O agente perde o histórico literal mas mantém o sentido — suficiente para a maioria dos casos de apoio ao cliente ou de assistente.

Grafo de estado de um agente LangGraphCom estado por omissãoHover to explore
O sistema de checkpoints do LangGraph transforma qualquer agente numa conversa retomável de vários turnos, mesmo depois de reiniciar o servidor.

5. Saída estruturada: obter dados tipados do agente

Muitas vezes quer que o agente reúna informação e devolva um objecto validado, e não um resumo em texto livre. Passe um modelo Pydantic a response_format e o agente devolve um objecto tipado dentro do mesmo ciclo, sem passo extra de parsing:

from pydantic import BaseModel
from langchain.agents import create_agent

class SupportTicket(BaseModel):
    order_id: str
    issue_type: str          # "refund" | "late_delivery" | "wrong_item"
    recommended_action: str
    confidence: float        # 0.0 – 1.0

agent = create_agent(
    model="anthropic:claude-sonnet-4-6",
    tools=[search_orders],
    response_format=SupportTicket,
    system_prompt=(
        "Classify the customer's issue and recommend an action. "
        "Always search the order before classifying."
    ),
)

result = agent.invoke({"messages": [
    {"role": "user", "content": "My order 4821 never arrived — it's been 3 weeks."}
]})

ticket: SupportTicket = result["structured_response"]
print(ticket.issue_type)           # "late_delivery"
print(ticket.recommended_action)   # "escalate to carrier"
print(ticket.confidence)           # 0.92

6. Streaming: fazer o agente parecer rápido

O maior problema de experiência de utilização num agente é a latência: quem o usa não vê nada até o ciclo terminar. O streaming resolve isso ao mostrar tokens e eventos de ferramentas à medida que acontecem. O LangChain suporta dois modos:

# Mode 1 — stream final output tokens only
for chunk in agent.stream(
    {"messages": [{"role": "user", "content": "Status of order 4821?"}]},
    stream_mode="messages",
):
    if chunk[1].get("langgraph_node") == "agent":
        print(chunk[0].content, end="", flush=True)

# Mode 2 — stream every event (tool calls, results, tokens)
for event in agent.stream(
    {"messages": [{"role": "user", "content": "Status of order 4821?"}]},
    stream_mode="updates",
):
    kind = list(event.keys())[0]
    if kind == "tools":
        print(f"[tool] {event['tools']['messages'][0].name}")
    elif kind == "agent":
        for msg in event["agent"]["messages"]:
            print(msg.content, end="", flush=True)

Na prática, use stream_mode="updates" em qualquer interface com um painel «a pensar» em direto: permite mostrar que ferramenta o agente está a chamar sem esperar pela resposta final.

7. Aprovação humana: a única salvaguarda que não pode saltar

Qualquer agente que possa gastar dinheiro, enviar uma mensagem ou escrever numa base de dados precisa de aprovação humana para ações irreversíveis. O LangChain v1 dá-lhe duas vias: middleware para casos simples e interrupções do LangGraph para controlo total.

# Simple approach — middleware
from langchain.agents.middleware import HumanInTheLoopMiddleware

agent = create_agent(
    model="anthropic:claude-sonnet-4-6",
    tools=[search_orders, issue_refund, send_email],
    middleware=[
        HumanInTheLoopMiddleware(
            interrupt_on={"issue_refund": True, "send_email": True}
        )
    ],
)

# Advanced approach — LangGraph interrupt node
from langgraph.types import interrupt

def human_approval_node(state):
    last_tool_call = state["messages"][-1]
    # Pause execution and surface the tool call to your UI
    decision = interrupt({
        "tool": last_tool_call.name,
        "args": last_tool_call.tool_input,
        "prompt": "Approve this action?",
    })
    if decision["approved"]:
        return state  # continue
    # Inject a rejection message back into the graph
    return {"messages": [ToolMessage(content="Action rejected by user.", ...)]}

O middleware entra em produção mais depressa. A interrupção do LangGraph é mais flexível: permite alterar argumentos, e não apenas aprovar ou rejeitar. Em projetos com clientes começamos quase sempre pelo middleware e só recorremos às interrupções quando é preciso deixar o utilizador editar uma chamada antes de ser executada.

8. ReAct ou tool calling: qual está mesmo a usar

Esta distinção baralha muita gente. No LangChain de 2022–2023, o ReAct (Reason + Act) era o padrão principal: pedia-se ao modelo que escrevesse um rascunho «Thought / Action / Observation» em texto simples, que o LangChain interpretava para saber o que chamar. Funcionava, mas era frágil — qualquer desvio no formato partia o parser.

Em 2026, o create_agent usa tool calling nativo: o modelo emite a chamada estruturada na resposta da API, e não em texto livre. É mais fiável, mais barato (não há duplo prompt) e é suportado por todos os grandes fornecedores. O ReAct passou a ser alternativa para modelos sem tool calling nativo, não o caminho por omissão.

CaracterísticaReAct (legado)Tool calling nativo (omissão na v1)
FormatoRascunho em texto livreResposta estruturada da API
FiabilidadeSensível ao formatoValidado por esquema
Chamadas em paraleloNãoSim (onde é suportado)
Indicado paraModelos locais sem tool callingTudo o resto

9. Checklist de produção antes de lançar

  1. Ligue o LangSmith desde o dia zero. Defina LANGSMITH_API_KEY e LANGSMITH_TRACING=true. Cada invoke, cada chamada a ferramenta e cada token ficam registados automaticamente. Vai agradecer às duas da manhã, quando algo falhar em produção.
  2. Defina max_iterations. Um agente sem limite pode entrar em ciclo infinito por causa de uma ferramenta mal descrita. Comece em 10 e ajuste em baixa quando souber a profundidade habitual do seu ciclo.
  3. Proteja todas as ferramentas destrutivas com aprovação humana. Sem exceções. Um único reembolso mal encaminhado em produção custa mais do que uma semana de engenharia.
  4. Teste as ferramentas isoladamente primeiro. Faça testes unitários a cada função com entradas simuladas. O comportamento do agente é difícil de prever; a correção de uma ferramenta não é.
  5. Crie um conjunto de avaliação. Os LangSmith Datasets permitem registar entradas reais e saídas esperadas e correr avaliações de regressão a cada actualização de modelo. Sem isso, cada mudança de versão é às escuras.
  6. Use um checkpointer duradouro em produção. O MemorySaver serve para desenvolvimento local, mas troque-o por PostgresSaver ou RedisSaver antes de ir para o ar — caso contrário, um reinício do servidor apaga todo o estado da conversa.

10. O que se diz no Reddit e no X em 2026

Depois de meses a ler tópicos no r/LangChain, no r/LocalLLaMA e nos cantos de engenharia de IA do X, a leitura da comunidade resume-se a estes temas recorrentes:

  • «O desenho das ferramentas é 80% do problema.» Os posts de depuração mais votados no r/LangChain são quase sempre sobre ferramentas mal nomeadas ou docstrings vagas, não sobre bugs da framework. Muda-se o nome e passa a funcionar.
  • «Passar de depurar com prints para o LangSmith foi o ponto de viragem.» Um comentário recorrente entre quem passou da demonstração ao produto real. A vista de trace mostra exactamente que chamada falhou e porquê.
  • «Substituí o LangChain por chamadas diretas ao SDK.» Continua a ser um tipo de post frequente, sobretudo em equipas focadas num só fornecedor ou com metas de latência abaixo dos 100 ms. Em pipelines simples de 1 a 3 passos, o custo da framework é real. Nem todos os casos precisam dela.
  • «A divisão de pacotes (langchain / langchain-core / langgraph) ainda confunde quem começa.» A própria equipa do LangChain reconhece-o. O modelo mental está mais limpo na v1, mas a instalação continua a fazer tropeçar à primeira.
  • «As chamadas em paralelo tornam finalmente rápidas as consultas complexas.» Quem antes encadeava chamadas sequenciais está a ver melhorias de latência de 2 a 3 vezes ao deixar o modelo disparar em simultâneo ferramentas independentes.

«A pergunta em 2026 não é "devo usar o LangChain?". É "preciso de checkpointing, observabilidade e tool calling portável entre fornecedores — ou tenho um fornecedor, três passos, e uma chamada direta chega?". Perceba que problema tem antes de escolher a framework.»

11. Quando usar agentes LangChain e quando não usar

Os agentes LangChain são a escolha certa quando precisa de pelo menos duas destas coisas:

  • Portabilidade entre fornecedores (o mesmo agente no Claude, no GPT ou no Gemini mudando uma linha)
  • Estado duradouro de vários turnos, com pausa e retoma
  • Aprovação humana para ações destrutivas
  • Tracing e avaliação integrados, sem logging próprio
  • Middleware reutilizável (anonimização de dados pessoais, sumarização, tentativas repetidas)

Prefira o SDK do fornecedor quando:

  • Trabalha com um só fornecedor e a latência é a principal restrição (ficar abaixo de <100ms é difícil com o custo da framework)
  • O seu «agente» são na verdade 2 ou 3 passos lineares sem ramificações — um pipeline é mais simples do que um grafo
  • A equipa tem posições fortes sobre abstracções e prefere controlar o ciclo por inteiro

Em resumo

Em 2026, os agentes LangChain deixaram de ser um brinquedo de tutorial. Com o create_agent, tool calling nativo, estado com checkpoints, saída estruturada, streaming e middleware, a framework cobre agora tudo o que um agente de produção precisa. A curva de aprendizagem é real — sobretudo no desenho de ferramentas e no modelo de checkpoints do LangGraph — mas em troca fica com um agente que pode observar, pausar, entregar a uma pessoa e migrar para outro modelo sem reescrever o código. É uma base sólida para qualquer MVP com IA.

IdeaToMVP Academy

Want to build with AI — not just read about it?

4-week live cohort for founders. Learn to ship AI agents, scope MVPs, and automate your business — taught by the same team that writes these guides.

Explore the Academy →
Share this post :