Pular para o conteúdo
chatflow-agent logochatflow-agent
Padrões de Produção

Tratamento de Erros e Recuperação

Estratégias de tratamento de erros em produção no chatflow-agent, hierarquia de exceções do SDK, autocorreção de ferramentas e reversão transacional de turnos.

Construir sistemas multiagente resilientes exige tolerância a falhas estruturada. Indisponibilidades de provedores de LLM, timeouts de rede, argumentos inválidos de ferramentas e exceções imprevistas devem ser tratados adequadamente sem corromper o estado da conversa.

O chatflow-agent implementa um modelo de recuperação em camadas: falhas não fatais de ferramentas são retornadas ao LLM para autocorreção autônoma, enquanto falhas fatais no turno disparam reversões atômicas de estado (rollbacks).

Hierarquia de Exceções do SDK

Todas as exceções no chatflow-agent herdam de ChatFlowError. Isso permite que a sua aplicação diferencie erros do framework de exceções padrão do Python.

ChatFlowError (Base)
├── DependencyError (Dependências opcionais ausentes de canais)
├── ToolExecutionError (Erro não capturado durante a execução de ferramenta)
├── ToolSchemaError (Anotação de tipo de parâmetro inválida) [v0.4.0rc1]
├── AgentHandoffError (Destino de handoff desconhecido ou loop de transferências)
├── ProviderError (Erro de status de API de LLM, falha de rede ou timeout)
├── ReentrantTurnError (Invocação de turno concorrente em sessão bloqueada) [v0.4.0rc1]
└── SessionDeletedError (Mensagem despachada para uma sessão excluída) [v0.4.0rc1]

Tabela de Referência de Exceções

Classe de ExceçãoHerda deLançada QuandoEstratégia de Recuperação
ChatFlowErrorExceptionClasse base para todas as exceções do SDK.Tratar nos pontos de entrada das requisições.
DependencyErrorChatFlowErrorUm extra opcional de canal (ex.: [telegram], [whatsapp]) não está instalado.Instalar o extra necessário com pip install "chatflow-agent[extra]".
ToolExecutionErrorChatFlowErrorUma função de ferramenta lança uma exceção não tratada durante a execução.Encapsulada em ToolResult(is_error=True) para que o agente possa se autocorrigir.
ToolSchemaError Prerelease (0.4.0rc1)ChatFlowErrorArgumentos de função de ferramenta carecem de anotações de tipo Python válidas.Corrigir assinaturas de tipo da função em tempo de desenvolvimento.
AgentHandoffErrorChatFlowErrorO agente de destino não existe no registro do Runner ou o turno ultrapassa max_handoffs_per_turn.Verificar destinos de handoff e condições de loop de transferência.
ProviderErrorChatFlowErrorO provedor upstream do modelo retorna um código de erro HTTP (ex.: 429, 500, 503).Implementar retentativas com backoff exponencial ou fallback para outro motor.
ReentrantTurnError Prerelease (0.4.0rc1)ChatFlowError, RuntimeErrorCódigo executando dentro de um turno inicia outro turno na mesma sessão.Utilizar filas de processamento em segundo plano ou despachantes sequenciais.
SessionDeletedError Prerelease (0.4.0rc1)ChatFlowErrorUma mensagem é processada para uma sessão expurgada durante a execução.Recriar a sessão ou orientar o usuário a reiniciar o fluxo.

Autocorreção Autônoma de Ferramentas

Quando uma ferramenta registrada lança uma exceção ou recebe argumentos que falham na validação de esquema, o Runner captura a falha e retorna um erro estruturado ao modelo, em vez de interromper o turno:

import logging
from chatflow_agent import Agent, Runner, tool

logger = logging.getLogger("app.tools")

@tool
def process_refund(order_id: str, amount: float) -> str:
    """Issue a refund for an order.

    Args:
        order_id: Order identifier formatted as ORD-XXXX.
        amount: Positive monetary value to refund.
    """
    if not order_id.startswith("ORD-"):
        raise ValueError("Invalid order format. Order ID must begin with 'ORD-'.")
    if amount <= 0:
        raise ValueError("Refund amount must be strictly greater than 0.")
    return f"Refund of ${amount:.2f} processed for order {order_id}."

agent = Agent(
    name="RefundBot",
    model="gpt-4o",
    tools=[process_refund],
    instructions="Process refunds accurately. If an order ID format is invalid, clarify with the user.",
)

runner = Runner(starting_agent=agent)

O Que Acontece Durante a Execução

  1. O modelo invoca process_refund(order_id="12345", amount=50.0).
  2. process_refund lança ValueError: Invalid order format. Order ID must begin with 'ORD-'..
  3. O Runner atribui um trace_id exclusivo (UUID4) e anexa um ToolResult:
    {
      "tool_call_id": "call_abc123",
      "name": "process_refund",
      "content": "Tool execution failed [trace_id: a8c2...]. Invalid order format. Order ID must begin with 'ORD-'.",
      "is_error": true
    }
  4. O modelo recebe is_error=True na próxima iteração e informa ao usuário: "The order ID '12345' is missing the 'ORD-' prefix. Could you please confirm the full order number?"

Proteção Contra Loops de Retentativa

Para prevenir loops infinitos em que um agente falha repetidamente em chamadas de ferramenta, o Runner impõe max_tool_iterations (padrão: 10). Se o limite for atingido sem uma resposta de texto final, o runner retorna uma mensagem de fallback controlada sem travar a aplicação.

Reversão Transacional de Turnos (Rollback)

Turnos multiagente frequentemente alteram o histórico da conversa, transferem para especialistas e atualizam metadados de sessão. Caso ocorra uma falha irrecuperável durante o turno (como desconexão de rede ou rate limit do provedor), manter a sessão em estado parcial corromperia interações futuras.

O Runner assegura a semântica de reversão para ponto de controle:

Início do Turno
    ├── Capturar Ponto de Controle: (history, active_agent, metadata)
    ├── Anexar Mensagem de Entrada do Usuário
    ├── Executar Turnos de LLM e Ferramentas
    │     ├── Sucesso: Confirmar resposta final do assistente no SessionStore
    │     └── Falha / CancelledError: Restaurar (history, active_agent, metadata)
    └── Liberar Bloqueio da Sessão

Exemplo de Reversão em Código

import asyncio
from chatflow_agent import Agent, Runner
from chatflow_agent.exceptions import ProviderError

def build_resilient_runner(agent: Agent) -> Runner:
    """Configure a runner with bounded handoffs and tool iterations."""
    return Runner(
        starting_agent=agent,
        max_tool_iterations=6,
        max_handoffs_per_turn=3,
    )

async def execute_turn_with_recovery(
    runner: Runner,
    session_id: str,
    user_message: str,
) -> str:
    """Execute a turn with explicit exception handling and graceful fallback."""
    try:
        response = await runner.run_async(
            session_id=session_id,
            user_message=user_message,
        )
        return response.content
    except ProviderError as err:
        # O estado foi revertido automaticamente para antes do turno
        return "Our AI inference service is temporarily degraded. Please retry in a few moments."
    except TimeoutError:
        # Timeout do turno atingido; ponto de controle restaurado
        return "The request took too long to complete. Please try a simpler question."
    except Exception as err:
        return "An unexpected system error occurred. Our operations team has been notified."

Tempos Limite de Turno e Fronteiras de Recursos

No SDK v0.3.x, os timeouts são gerenciados no nível do turno assíncrono utilizando o utilitário padrão asyncio.wait_for do Python. Vale destacar que o parâmetro explícito turn_timeout em run_async é introduzido na versão prévia v0.4.0rc1:

# [no-exec: illustrative turn timeout call]
import asyncio

# No v0.3.x, aplique timeouts de turno via asyncio.wait_for
response = await asyncio.wait_for(
    runner.run_async(
        session_id="customer-1029",
        user_message="Analyze this quarterly financial audit report...",
    ),
    timeout=45.0,
)

Se o turn_timeout expirar:

  1. Todas as subtarefas assíncronas em execução são canceladas imediatamente.
  2. Execuções síncronas de ferramentas são aguardadas em threads de trabalho para prevenir deadlocks no SQLite.
  3. O histórico de conversas e os metadados são restaurados para o ponto de controle anterior ao turno.
  4. asyncio.TimeoutError é lançado para quem fez a chamada.

Lista de Verificação de Melhores Práticas

  • Trate ChatFlowError: Intercepte exceções do framework antes de permitir que propaguem para os endpoints HTTP.
  • Defina Limites de Iterações: Nunca configure max_tool_iterations ou max_handoffs_per_turn com valores ilimitados.
  • Retorne Erros Descritivos nas Ferramentas: Lance mensagens de ValueError ou KeyError claras dentro das ferramentas para que o agente compreenda o erro e se autocorrija.
  • Registre IDs de Rastreamento: Capture o trace_id gerado nos logs do Runner para correlacionar chamados de suporte com traces internos do sistema.

On this page