Do Conceito à Arquitetura: Construindo um Agente de IA para Testes com LangChain (Desafio DIO)
O Desafio de Automatizar
Olá, comunidade DIO!
Recentemente, concluí o desafio "Gerando Testes Unitários com LangChain e Azure ChatGPT". O objetivo era empolgante: construir um agente de IA em Python capaz de ler um código e gerar, magicamente, os testes unitários pytest
para ele.
Qualquer desenvolvedor sabe que escrever testes é crucial, mas é uma das tarefas mais demoradas do dia a dia. A ideia de ter uma IA para fazer esse trabalho pesado é, sem dúvida, o futuro da engenharia de software.
No entanto, no meio do caminho, me deparei com um desafio que muitos de vocês também podem encontrar.
O "Desafio Dentro do Desafio": O que Fazer Quando Falta a Chave da API?
Para conectar nosso agente ao "cérebro" do Azure OpenAI, precisaríamos de chaves de API. Como elas não foram fornecidas (e o processo para obtê-las individualmente é complexo), me vi diante de uma escolha: parar ou mudar o foco.
Felizmente, a própria DIO nos deu o caminho:
"Atenção: Este desafio é flexível! Você pode optar por implementar o agente completo... ou documentar em detalhes o que aprendeu..."
Decidi abraçar essa segunda opção. Afinal, o valor de um projeto não está apenas em rodar o script e ver o "play" funcionar. O verdadeiro aprendizado está em entender a arquitetura: saber quais peças são necessárias, como elas se conectam e o que deveria acontecer.
Meu objetivo mudou de "executar" para "projetar". Criei um repositório que serve como a "planta baixa" completa do agente de IA.
A Arquitetura da Solução: O "Como Faria"
Para provar o conceito, dividi o projeto em três partes lógicas que simulam o fluxo de trabalho completo.
1. A Entrada: funcoes_exemplo.py
Primeiro, criei as "iscas" para a IA. Duas funções simples em Python que nosso agente precisaria analisar:
Python
# funcoes_exemplo.py
def soma(a: int, b: int) -> int:
"""Soma dois numeros inteiros."""
return a + b
def divisao(a: int, b: int) -> float:
"""Divide dois numeros. Lança um erro se dividir por zero."""
if b == 0:
raise ValueError("Nao e possivel dividir por zero")
return a / b
2. O Cérebro: agente_teorico.py
Este é o coração do projeto. É o script Python que, se tivesse as chaves, realizaria todo o trabalho pesado. O código foi escrito para:
- Carregar as chaves de API de um arquivo
.env
(usandopython-dotenv
). - Ler o conteúdo do arquivo
funcoes_exemplo.py
. - Construir um Prompt (um comando) detalhado para a IA, explicando as regras (ex: "comece com
import pytest
", "crie testes de sucesso e falha", "usepytest.raises
para erros"). - Conectar ao Azure OpenAI usando a biblioteca
LangChain
. - Invocar a IA com o prompt e receber o código de teste gerado.
- Salvar esse código em um novo arquivo.
3. O Produto Final: testes_exemplo.py
Como eu não podia gerar o arquivo final, eu o criei manualmente. Este arquivo serve como o "gabarito", mostrando exatamente o que a IA deveria ter produzido. Isso foi crucial para eu entender os fundamentos do pytest
.
Python
# testes_exemplo.py (O que a IA deveria gerar)
import pytest
from funcoes_exemplo import soma, divisao
# Teste de sucesso para soma
def test_soma_sucesso():
assert soma(5, 5) == 10
# Teste de falha para divisao
def test_divisao_por_zero_falha():
"""Testa se a divisão por zero levanta o erro correto."""
with pytest.raises(ValueError, match="Nao e possivel dividir por zero"):
divisao(100, 0)
Conclusão: O Valor Está na Arquitetura
Este desafio foi uma lição valiosa. Às vezes, o maior aprendizado não vem de executar um comando com sucesso, mas de entender profundamente cada etapa do processo. Documentar o projeto, explicar os conceitos (conceitos.md
) e construir o "molde" teórico do agente me forçou a entender LangChain e pytest
em um nível que eu talvez não tivesse alcançado se apenas apertasse "play".
Para quem está começando, lembre-se: não deixe que uma barreira (como uma chave de API) pare seu aprendizado. Foque em entender o "porquê" e o "como".
Obrigado, DIO, pelo desafio flexível!