Pular para o conteúdo
Carlos Morais.
Trabalhos

Projeto solo · desafio técnico

Renova: chatbot de preços da Tabela FIPE

Um chatbot que consulta a Tabela FIPE: o modelo conversa, e quatro ferramentas buscam marca, modelo, ano e preço na API pública, na ordem que ela exige.

Renova

Consulta à Tabela FIPE

Reprodução

Escolha as respostas pelos botões abaixo. Cada escolha vira uma chamada de verdade à API da FIPE, e você vê a chamada ao lado.

Renova:

Olá! Eu consulto preços de veículos na Tabela FIPE. Que tipo de veículo você quer consultar?

Reprodução: as falas seguem um roteiro e as escolhas são por botões. As consultas à Tabela FIPE são de verdade, feitas agora pelo seu navegador. No Renova, quem conversa é o GPT-4o, que entende texto livre e decide sozinho quando chamar cada ferramenta.

Em 30 segundos

  • Projeto solo, feito em cerca de 10 dias como desafio de um processo seletivo.
  • Um chatbot com GPT-4o e quatro ferramentas que consultam a API da FIPE na ordem certa, num laço de chamadas próprio.
  • O processo seletivo terminou na minha contratação. A demonstração acima usa a FIPE de verdade.
Quando
fev — mar 2025 · 10 dias
Papel
Projeto solo · da ideia ao código
Origem
Desafio de processo seletivo
Stack
TypeScript, React, Vite, Tailwind, Node.js, Express, Prisma, PostgreSQL, LangChain, OpenAI (GPT-4o), Docker

Contexto

Em fevereiro de 2025, a Alpha EdTech me indicou para o processo seletivo de uma startup de IA conversacional. O Renova foi o projeto que eu fiz para esse processo: um chatbot que consulta preços na Tabela FIPE, a referência de preço de veículos no Brasil.

Fiz sozinho, em cerca de 10 dias: a ideia, o desenho da solução, o protótipo e o código, do banco de dados à interface.

O problema

A API da FIPE não responde a uma pergunta como “quanto vale um Palio 2012?”. Ela é uma sequência: tipo de veículo, marca, modelo, ano e preço, e cada passo pede o código exato que veio do passo anterior. Um modelo de linguagem conversa bem, mas inventa números e códigos com a mesma confiança.

O bot precisava juntar as duas coisas: deixar a pessoa falar do jeito dela e, por baixo, seguir a ordem da API sem nunca chutar um código ou um preço.

Minha parte

Projeto solo: todas as partes abaixo são minhas.

  • Backend em Express e TypeScript: rotas de conversas e mensagens, validação de entrada e Prisma sobre PostgreSQL.
  • O bot: GPT-4o pelo LangChain, quatro ferramentas tipadas com Zod e o laço que executa as chamadas.
  • O system prompt e a descrição de cada ferramenta.
  • Frontend em React, Vite e Tailwind: lista de conversas, chat com Markdown, animação de espera e o tempo de cada resposta.
  • Docker Compose com o banco, a API e o frontend servido pelo Nginx.

Decisões técnicas

Ferramentas no lugar de chute

Cada passo da API virou uma ferramenta (getMarcas, getModelos, getAnos e getValor) com os argumentos validados por Zod. As descrições dizem a ordem e proíbem códigos inventados, e o prompt deixa claro que a Tabela FIPE é a única fonte de preço.

Um laço de ferramentas próprio

Na primeira versão, o bot fazia uma chamada e respondia. Depois virou um laço: enquanto o modelo pedir ferramentas, o servidor executa e devolve o resultado, e ele pode encadear passos numa mesma resposta. Usei o bindTools do LangChain e escrevi o laço à mão, sem o AgentExecutor.

O histórico inclui as ferramentas

O modelo não guarda nada de uma mensagem para a outra. Sem as respostas da FIPE no histórico, o bot perdia os códigos que tinha acabado de mostrar. A solução foi salvar no banco também as chamadas de ferramenta e as respostas delas, como um tipo de mensagem próprio, e remontar a conversa inteira a cada mensagem. O prompt ainda pede para mostrar sempre “[código] Nome”, para a pessoa poder responder com o código exato.

Listas grandes, inteiras

Algumas respostas são enormes: só a Fiat tem 586 modelos, quase 39 mil caracteres. Cheguei a cortar cada lista em 100 itens, mas assim o modelo que a pessoa procurava podia ficar de fora. O corte saiu, e as listas vão inteiras.

Prompt de objetivos, não de passos

O primeiro system prompt ditava cada ação e quando chamar cada ferramenta: o bot ficou previsível, mas engessado. Reescrevi focando no objetivo e nas regras que não podem quebrar, como a ordem da API, e deixei o modelo escolher o caminho. A conversa ficou mais natural sem perder a consulta.

Erro vira resposta

Se a API falha ou um código não existe, a ferramenta não derruba a requisição: devolve ao modelo um texto de erro (“not found, check the identifiers”), e ele pode pedir à pessoa outro dado.

Arquitetura

O navegador lista as conversas e envia cada mensagem pela API REST. O Express remonta o histórico a partir do PostgreSQL, chama o GPT-4o com as quatro ferramentas e executa na API pública da FIPE as que ele pedir, até o modelo responder em texto. Tudo, inclusive as chamadas de ferramenta, volta para o banco.

Resultado

Entreguei em cerca de 10 dias: o chatbot funcionando de ponta a ponta, com as conversas salvas, o tempo de cada resposta e tudo subindo com Docker Compose.

O processo seletivo terminou na minha contratação: trabalhei nessa startup de abril de 2025 a janeiro de 2026.

O código está público no GitHub. A demonstração no topo desta página reproduz a conversa com as mesmas quatro ferramentas, chamando a API da FIPE de verdade.