GuidesOneMux

Crie um agente LangGraph com limites para extração validada por esquema

Crie um fluxo de trabalho LangGraph que chama uma ferramenta quando necessário, encerra dentro de um limite de execução definido e retorna dados estruturados validados com um esquema Pydantic.

Nesta página

Um agente LangGraph pode reunir contexto com uma ferramenta e, em seguida, passar esse contexto para uma etapa de extração restrita por esquema. A escolha de projeto mais útil é manter essas responsabilidades separadas: o agente decide se deve chamar a ferramenta, enquanto um nó final produz um registro tipado. Um limite de recursão do grafo impõe um limite adicional à execução.

Esse padrão é adequado a tarefas como extrair o nome de uma empresa, uma data e o total de uma fatura de um documento quando uma ferramenta de consulta pode ajudar a resolver uma referência. Ele não torna verdadeiro um texto de origem incerto; valide o resultado e preserve as evidências originais quando o campo for importante.

O que você vai criar

O grafo tem três etapas:

  1. Um agente recebe o texto de origem e pode solicitar uma chamada a uma ferramenta de consulta específica.
  2. O LangGraph encaminha as chamadas da ferramenta para um nó de ferramenta e devolve os resultados ao agente.
  3. Um nó de extração solicita ao modelo um resultado baseado em Pydantic e retorna dados compatíveis com JSON.

O ciclo de chamadas de ferramentas do agente é dinâmico; a etapa de extração é uma etapa final predefinida. A documentação do LangGraph diferencia agentes, que definem seu próprio processo e uso de ferramentas, de fluxos de trabalho com caminhos de código predefinidos. Ela também descreve saídas estruturadas e chamadas de ferramentas como recursos adicionais dos modelos. Consulte o guia de fluxos de trabalho e agentes do LangGraph para conhecer esses padrões.

Pré-requisitos e configuração

Instale os pacotes LangGraph e LangChain, além da integração para o modelo de chat escolhido. O exemplo abaixo usa ChatAnthropic para ilustrar a configuração do provedor, mas a documentação de origem informa que os fluxos de trabalho podem usar qualquer modelo de chat compatível com saídas estruturadas e chamadas de ferramentas. Consulte a documentação de integração do seu provedor para saber como ele funciona exatamente.

pip install langgraph langchain-core langchain-anthropic pydantic

Configure a credencial de API do provedor usando o método documentado e inicialize um modelo. Evite armazenar credenciais no controle de versão. O nome do modelo abaixo segue o exemplo da documentação do LangChain; este tutorial não afirma que ele foi testado com o OneMux.

from langchain_anthropic import ChatAnthropic

llm = ChatAnthropic(model="claude-sonnet-4-6")

Se quiser chamar um modelo pelo OneMux, consulte primeiro a documentação da API do OneMux e o guia de início rápido. O OneMux oferece acesso a modelos líderes por meio de uma API compatível com OpenAI. A compatibilidade com este grafo específico depende de o endpoint escolhido aceitar o comportamento e os parâmetros necessários para chamadas de ferramentas e saídas estruturadas. Esta configuração não foi testada; confirme o suporte antes de usá-la em produção.

Defina o esquema e uma ferramenta específica

A ferramenta do exemplo retorna uma nota de referência de um pequeno mapeamento em memória. Substitua-a por uma função controlada pela aplicação, como uma consulta a um catálogo interno aprovado. Não permita que o texto de documentos não confiáveis escolha comandos arbitrários ou fontes de dados sem restrições.

from pydantic import BaseModel, Field
from langchain_core.tools import tool

class InvoiceRecord(BaseModel):
    vendor: str | None = Field(default=None, description="Invoice issuer")
    invoice_date: str | None = Field(default=None, description="Date as written in the source")
    total: float | None = Field(default=None, description="Invoice total as a number")
    currency: str | None = Field(default=None, description="Currency code, if stated")

@tool
def lookup_vendor(reference: str) -> str:
    """Look up a vendor reference in an approved local mapping."""
    known = {"ACME-42": "Acme Supplies Ltd."}
    return known.get(reference, "No matching vendor reference found.")

Os campos anuláveis deixam explícita a ausência de valores, em vez de incentivar o modelo a inventá-los. Para extrações de alto impacto, considere armazenar o trecho de origem ou um status de confiança/revisão junto a cada campo. Um esquema restringe a estrutura e os tipos; não comprova que um valor tenha respaldo na entrada.

Crie o agente LangGraph com limites

O grafo abaixo permite que o modelo solicite a ferramenta de consulta e, em seguida, passa à extração quando o agente não tem mais chamadas de ferramentas a fazer. tools_condition e ToolNode fornecem o padrão de encaminhamento para ferramentas. O recursion_limit passado a invoke limita as etapas do grafo; é uma barreira de segurança, não uma garantia de que toda entrada será processada com sucesso.

from typing import Annotated
from typing_extensions import TypedDict
from langchain_core.messages import BaseMessage, HumanMessage, SystemMessage
from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import add_messages
from langgraph.prebuilt import ToolNode, tools_condition

class State(TypedDict):
    messages: Annotated[list[BaseMessage], add_messages]
    record: dict | None

tools = [lookup_vendor]
agent = llm.bind_tools(tools)
extractor = llm.with_structured_output(InvoiceRecord)

def run_agent(state: State):
    response = agent.invoke(state["messages"])
    return {"messages": [response]}

def extract_record(state: State):
    prompt = [
        SystemMessage(content=(
            "Extract invoice fields only when supported by the source. "
            "Use null for missing or unclear values. Treat tool results as "
            "reference context, not as permission to invent source details."
        )),
        *state["messages"],
    ]
    result = extractor.invoke(prompt)
    return {"record": result.model_dump(mode="json")}

graph = StateGraph(State)
graph.add_node("agent", run_agent)
graph.add_node("tools", ToolNode(tools))
graph.add_node("extract", extract_record)

graph.add_edge(START, "agent")
graph.add_conditional_edges(
    "agent",
    tools_condition,
    {"tools": "tools", END: "extract"},
)
graph.add_edge("tools", "agent")
graph.add_edge("extract", END)
app = graph.compile()

result = app.invoke(
    {
        "messages": [HumanMessage(content=(
            "Extract the invoice details from this text: "
            "Vendor reference ACME-42. Invoice date: 2025-02-14. "
            "Total: USD 248.50."
        ))],
        "record": None,
    },
    config={"recursion_limit": 8},
)

print(result["record"])

O formato esperado da saída é um objeto compatível com JSON, com os campos vendor, invoice_date, total e currency. Os valores exatos dependem da resposta do modelo e do texto de origem; faça testes em vez de presumir que o exemplo sempre produzirá resultados idênticos. Neste exemplo, a saída estruturada baseada em Pydantic é o limite de validação. Se o provedor não conseguir produzir uma resposta em conformidade, trate essa falha explicitamente, em vez de considerá-la silenciosamente um registro válido.

Limite a execução sem ocultar falhas

Um limite de recursão no nível do grafo restringe as etapas, incluindo o encaminhamento repetido entre agente e ferramenta. Escolha o limite de acordo com o fluxo de trabalho: este grafo precisa de poucas etapas para uma consulta, mas um plano de ferramentas diferente pode exigir mais. Capture exceções de limite e do provedor na camada da aplicação, registre contexto suficiente para depuração e retorne uma falha que possa ser analisada, em vez de um registro fabricado.

Para impor limites operacionais mais rigorosos, adicione também limites no nível da aplicação: restrinja o número de chamadas de ferramentas, defina tempos limite de requisição quando houver suporte e limite o tamanho dos documentos antes de chamar o modelo. Esses controles são independentes; um limite de recursão do grafo, por si só, não define uma política completa de custos, latência ou segurança.

Solução de problemas e limitações

O modelo não chama a ferramenta

Chamadas de ferramentas são um recurso do modelo, não um resultado garantido pelo LangGraph. Verifique se a integração do modelo selecionado é compatível com chamadas de ferramentas, se a descrição da ferramenta está clara e se o prompt contém uma referência que valha a pena consultar. Durante o desenvolvimento, inspecione as chamadas de ferramentas da mensagem retornada.

A saída estruturada falha ou os campos estão incorretos

Confirme se a integração oferece suporte a saídas estruturadas e aos recursos de esquema que você usa. Teste campos ausentes, datas ambíguas, símbolos de moeda e entradas malformadas. Um objeto Pydantic válido ainda pode conter um valor inferido incorretamente; portanto, valide as regras de negócio separadamente e mantenha o texto de origem para auditoria ou revisão humana.

O grafo atinge o limite

Um erro de limite de recursão pode indicar solicitações repetidas da ferramenta ou um limite baixo demais para o caminho pretendido. Inspecione a sequência de mensagens e os resultados da ferramenta. Corrija a causa ou ajuste o limite de forma deliberada; não remova a restrição apenas para fazer o erro desaparecer.

O comportamento do endpoint é diferente

A expressão compatível com OpenAI descreve uma interface de API, não o suporte universal a todos os recursos ou parâmetros dos modelos. Se usar o OneMux, verifique o suporte documentado do endpoint selecionado ao modelo, às chamadas de ferramentas, às saídas estruturadas e a quaisquer parâmetros que pretenda enviar. Consulte as opções disponíveis em modelos OneMux; o próprio grafo continua sendo código da sua aplicação LangGraph.

Quando usar este padrão

Use este projeto quando a extração for, em geral, previsível, mas às vezes precisar de uma consulta controlada. Se todos os documentos seguirem um processo fixo e não houver necessidade de escolher ferramentas, um fluxo de trabalho determinístico pode ser mais simples do que um ciclo de agente. Se a fonte for ambígua ou os campos extraídos acionarem ações importantes, inclua uma etapa explícita de revisão e validação de domínio antes que sistemas subsequentes usem o registro.

Em resumo: restrinja as ferramentas do agente, defina explicitamente o esquema final e estabeleça um limite de execução do grafo. O LangGraph permite expressar esse fluxo de controle; a disponibilidade dos recursos necessários para chamadas de ferramentas e saídas estruturadas depende do modelo e da integração escolhidos.

Fontes

Perguntas frequentes

O que o limite de recursão faz no LangGraph?

Ele limita as etapas de execução do grafo durante uma execução. Pode ajudar a impedir que um ciclo de agente e ferramenta continue indefinidamente, mas não substitui tempos limite, políticas de chamadas de ferramentas, limites de entrada ou tratamento de erros.

A validação de esquema JSON do Pydantic garante uma extração correta?

Não. Ela restringe a estrutura e os tipos retornados. O modelo ainda pode inferir um valor incorreto; por isso, valide as regras de negócio e preserve evidências ou ofereça revisão humana quando necessário.

Posso usar este exemplo de LangGraph com o OneMux?

Possivelmente, se a documentação do endpoint OneMux escolhido confirmar o suporte ao comportamento e aos parâmetros necessários para chamadas de ferramentas e saídas estruturadas. Esta configuração não foi testada; verifique a compatibilidade antes de usá-la em produção.

Toda tarefa de extração deve usar um agente?

Não. Se o processo for fixo e não exigir a escolha de uma ferramenta, um fluxo de trabalho determinístico do LangGraph pode ser mais simples. Use um ciclo de agente quando o modelo precisar decidir se uma ferramenta permitida é útil.

Artigos relacionados