Solucionado (ver solução)
Solucionado
(ver solução)
3
respostas

[Dúvida] Tratamento de Exceções

No conteúdo sobre "chamada de função paralela em agentes" foi mencionada a seguinte observação: "Se uma das chamadas falhar, o sistema pode retornar dados incompletos. A lógica precisa incluir tratamento de exceções, de forma que a falha de uma requisição não comprometa o resultado final."

Visto o risco mencionado acima, como seria possível incluir um tratamento de exceções no código do professor sobre o clima em SP e no RJ caso a ferramenta de busca do Tavily não conseguisse encontrar uma das cidades em suas buscas?

Grato desde já!

3 respostas
solução!

Olá, Nelson! Como vai?

Para lidar com possíveis falhas, como a impossibilidade de encontrar uma cidade, podemos implementar um tratamento de exceções.

Esse tratamento de exceções em Python podem garantir que a falha de uma requisição não comprometa o resultado final. No exemplo mencionado, podemos adicionar um tratamento de erro para cada chamada individual. Vou deixar aqui uma maneira de como você pode fazer isso:

import asyncio

# Suponha que esta função possa lançar exceção
async def busca_informacoes(cidade):
    # Exemplo fictício (substitua pela implementação real)
    if cidade == "São Paulo":
        return {"cidade": cidade, "previsao": "Ensolarado"}
    else:
        raise Exception("Erro na API")

async def busca_informacoes_com_tratamento(cidade):
    try:
        return await busca_informacoes(cidade)
    except Exception as error:
        print(f"Erro ao buscar informações para {cidade}: {error}")
        # Retorna None para indicar falha
        return None

async def obter_previsao():
    res_cidade1, res_cidade2 = await asyncio.gather(
        busca_informacoes_com_tratamento("São Paulo"),
        busca_informacoes_com_tratamento("Rio de Janeiro")
    )

    if res_cidade1:
        print("Previsão para São Paulo:", res_cidade1)
    else:
        print("Não foi possível obter a previsão para São Paulo.")

    if res_cidade2:
        print("Previsão para Rio de Janeiro:", res_cidade2)
    else:
        print("Não foi possível obter a previsão para Rio de Janeiro.")

# Executa a função assíncrona principal
asyncio.run(obter_previsao())

Neste exemplo, cada chamada para buscaInformacoes é envolvida em um bloco try except dentro da função buscaInformacoesComTratamento. Se ocorrer um erro, ele é capturado e tratado. Assim, permitindo que o programa continue a execução sem interrupções.

Além disso, você pode decidir como lidar com os erros: seja registrando uma mensagem, retornando um valor padrão ou qualquer outra ação que faça sentido para o seu caso de uso.

Espero ter ajudado e fico à disposição se precisar.

Abraço e bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado

Olá Daniel,

Entendi que seria possível fazer esse tratamento com o Python puro, da forma que conhecemos a linguagem.

Porém, no caso de agentes essa função faria parte de uma ferramenta. Neste caso, seria necessário apenas adicionar o @tool a função busca_informacoes_com_tratamento e documentar com docstring o objetivo, entradas e saída para o uso do agente?

Grato desde já!

Olá, Nelson! Tudo bem?

Boa observação, sua linha de raciocínio está correta.

No contexto de agentes (usando frameworks como LangChain ou similares), quando queremos disponibilizar uma função para que o agente possa utilizá-la como ferramenta, normalmente basta sim transformar essa função em uma tool, adicionando o decorador @tool e documentando adequadamente sua docstring com objetivo, parâmetros e retorno.

Nesse cenário, a função busca_informacoes_com_tratamento é uma boa candidata para virar ferramenta, porque ela já encapsula o tratamento de exceções, tornando o comportamento mais seguro e previsível para o agente. Agentes funcionam melhor quando as ferramentas retornam respostas consistentes (None, mensagens estruturadas ou objetos JSON), em vez de lançar exceções diretamente.

Um exemplo conceitual seria algo assim:

from langchain.tools import tool

@tool
async def busca_informacoes_com_tratamento(cidade: str):
    """
    Busca informações de previsão do tempo para uma cidade.

    Entrada:
        cidade (str): Nome da cidade a ser consultada.

    Saída:
        dict | None: Retorna um dicionário com os dados da previsão ou None em caso de erro.
    """
    try:
        return await busca_informacoes(cidade)
    except Exception as error:
        print(f"Erro ao buscar informações para {cidade}: {error}")
        return None

Ou seja, na prática:

  • o decorador @tool registra a função como ferramenta do agente;
  • a docstring orienta o agente sobre quando e como usar a ferramenta;
  • o tratamento de exceções evita que falhas interrompam o fluxo de execução;
  • o retorno estruturado melhora a tomada de decisão do agente.

Dependendo do framework utilizado, pode haver pequenas variações (por exemplo: StructuredTool, BaseTool ou schemas com pydantic), mas a ideia central permanece exatamente essa: encapsular a lógica + tratamento de erro + documentação clara.

Essa interpretação está bem alinhada com a forma recomendada de organizar as ferramentas para agentes.

Espero ter ajudado, abraço!