Construa um Cliente LLM Resiliente
Construa um cliente LLM assíncrono e tipado em Python puro (só `httpx` + `asyncio`) com timeout configurável, retry com backoff exponencial e jitter, streaming de resposta e logging estruturado — testado contra um provedor mock local que falha de propósito.
PremiumProblema
Todo agente, pipeline de RAG e feature de chat que você algum dia vai construir se apoia numa peça de infraestrutura nada glamourosa: o código que de fato conversa com a API HTTP do provedor de LLM. É tentador tratar essa chamada como uma linha só — `response = requests.post(url, json=payload)` — e seguir em frente. Em produção, essa linha única é a fonte mais comum de agentes instáveis: um provedor tendo um minuto lento, uma falha de rede, uma conexão que reseta no meio da requisição. Nada disso significa que seu prompt estava errado. Tudo isso vai derrubar um cliente ingênuo e, sem retries, falhar silenciosamente a requisição de um usuário real. Neste lab você vai construir `LLMClient`, um cliente assíncrono pequeno sem dependência de framework — só `httpx` para HTTP e o `asyncio` da biblioteca padrão — que trata as quatro coisas que todo cliente LLM de produção precisa: um **timeout configurável** para que uma requisição lenta não trave seu pipeline inteiro, **retry com backoff exponencial e jitter** para que falhas transitórias se resolvam sozinhas em vez de aparecerem para o usuário, **streaming** para que respostas longas possam ser mostradas token a token em vez de tudo de uma vez, e **logging estruturado** de cada tentativa para que, quando algo *realmente* der errado em produção, você tenha os dados para diagnosticar. Você vai testar tudo isso contra um pequeno provedor mock local (incluído neste lab, só biblioteca padrão) que consegue simular uma resposta lenta, uma instável que falha duas vezes antes de ter sucesso, e uma em streaming — para você provar que sua lógica de retry realmente funciona sem gastar um único crédito real de API ou depender de um provedor real estar instável sob demanda.
Objetivos
Ao final deste lab você será capaz de:
- Escrever um cliente LLM assíncrono usando
httpx.AsyncClientcom uma
interface limpa e tipadachat(messages) -> str. - Impor um timeout de requisição configurável com
asyncio.wait_fore
distinguir um timeout de uma falha de conexão. - Implementar retry com backoff exponencial e jitter para erros
transitórios, e explicar por que jitter importa quando múltiplos
clientes fazem retry ao mesmo tempo. - Implementar streaming de resposta como um gerador assíncrono sobre uma
resposta HTTP em chunks. - Adicionar logging estruturado (JSON) de cada tentativa — latência,
sucesso/falha, número da tentativa — para que falhas sejam
diagnosticáveis depois do fato. - Construir e usar um provedor HTTP mock local para testar a lógica de
retry e timeout de forma determinística, sem uma chave de API real.
Pré-requisitos
Para completar este lab você vai precisar de:
- Python 3.10+ instalado.
-
pip install httpx(nenhum outro pacote de terceiros necessário — o
provedor mock usa só a biblioteca padrão). - Um terminal capaz de rodar dois processos Python ao mesmo tempo (o
provedor mock em um, seu cliente em outro). - Familiaridade básica com a sintaxe
async/awaitdo Python. Se você
nunca escreveu Python assíncrono antes, ainda consegue completar este
lab — todo construto async usado é explicado inline.
O que você vai construir
Um único arquivo, llm_client.py, contendo uma classe LLMClient que
cresce em cinco passos: uma chamada simples, uma chamada com timeout,
uma chamada com retry + backoff + jitter, uma chamada em streaming, e
logging estruturado amarrando tudo. Você vai testar cada estágio contra
mock_provider.py, um pequeno servidor HTTP local (incluído, só
biblioteca padrão) que faz o papel de uma API LLM real e pode ser
configurado para ser lento, instável ou fazer streaming.
Por que isso importa além deste lab
Este é o formato de cliente que você vai reutilizar (ou reconhecer) em
todo framework de agente que você tocar profissionalmente — LangChain, o
SDK da OpenAI, o SDK da Anthropic todos implementam alguma versão
exatamente dessas quatro preocupações internamente. Construir você mesmo
uma vez significa que você vai conseguir ler, configurar e debugar essa
maquinaria em qualquer framework, em vez de tratá-la como uma caixa
preta.
Como trabalhar neste lab
Percorra os cinco passos em ordem — cada estágio se soma ao mesmo
arquivo llm_client.py. Mantenha o provedor mock rodando no seu próprio
terminal durante todo o lab; reinicie-o (Ctrl+C e rode de novo) sempre
que um passo mandar, já que o contador de falhas do modo instável tem
estado e precisa de um início limpo entre os testes.