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ção | Herda de | Lançada Quando | Estratégia de Recuperação |
|---|---|---|---|
ChatFlowError | Exception | Classe base para todas as exceções do SDK. | Tratar nos pontos de entrada das requisições. |
DependencyError | ChatFlowError | Um extra opcional de canal (ex.: [telegram], [whatsapp]) não está instalado. | Instalar o extra necessário com pip install "chatflow-agent[extra]". |
ToolExecutionError | ChatFlowError | Uma 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) | ChatFlowError | Argumentos 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. |
AgentHandoffError | ChatFlowError | O 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. |
ProviderError | ChatFlowError | O 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, RuntimeError | Có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) | ChatFlowError | Uma 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
- O modelo invoca
process_refund(order_id="12345", amount=50.0). process_refundlançaValueError: Invalid order format. Order ID must begin with 'ORD-'..- O
Runneratribui umtrace_idexclusivo (UUID4) e anexa umToolResult:{ "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 } - O modelo recebe
is_error=Truena 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ãoExemplo 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:
- Todas as subtarefas assíncronas em execução são canceladas imediatamente.
- Execuções síncronas de ferramentas são aguardadas em threads de trabalho para prevenir deadlocks no SQLite.
- O histórico de conversas e os metadados são restaurados para o ponto de controle anterior ao turno.
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_iterationsoumax_handoffs_per_turncom valores ilimitados. - Retorne Erros Descritivos nas Ferramentas: Lance mensagens de
ValueErrorouKeyErrorclaras dentro das ferramentas para que o agente compreenda o erro e se autocorrija. - Registre IDs de Rastreamento: Capture o
trace_idgerado nos logs doRunnerpara correlacionar chamados de suporte com traces internos do sistema.
Webhooks e Canais Personalizados
Construa integrações de webhook e adaptadores de canal personalizados utilizando BaseChannel, FastAPI e despacho assíncrono.
Configuração e Ambiente
Gerencie variáveis de ambiente, predefinições de provedores, timeouts e configuração de aplicações Twelve-Factor em implantações do chatflow-agent.