Como Desenvolver um Chatbot com Claude Code
Aprenda a desenvolver um chatbot usando o Claude Code. Inclui exemplos práticos de código e orientação passo a passo.
Desenvolvendo um Chatbot com Claude Code
O desenvolvimento de chatbots com IA envolve muitos elementos, como implementação de UI, integração com API, gerenciamento de conversas e processamento de streaming. Com o Claude Code, você pode construir chatbots que integram todos esses elementos em pouco tempo.
Implementação da UI Básica de Chat
> Crie um componente de chatbot em React.
> Com suporte a resposta em streaming, exibição de histórico de conversas e formulário de entrada.
import { useState, useRef, useEffect } from "react";
interface Message {
id: string;
role: "user" | "assistant";
content: string;
}
export function ChatBot() {
const [messages, setMessages] = useState<Message[]>([]);
const [input, setInput] = useState("");
const [isLoading, setIsLoading] = useState(false);
const messagesEndRef = useRef<HTMLDivElement>(null);
useEffect(() => {
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
}, [messages]);
const sendMessage = async () => {
if (!input.trim() || isLoading) return;
const userMessage: Message = {
id: crypto.randomUUID(),
role: "user",
content: input,
};
setMessages((prev) => [...prev, userMessage]);
setInput("");
setIsLoading(true);
const assistantId = crypto.randomUUID();
setMessages((prev) => [
...prev,
{ id: assistantId, role: "assistant", content: "" },
]);
try {
const response = await fetch("/api/chat", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
messages: [...messages, userMessage].map(({ role, content }) => ({
role,
content,
})),
}),
});
const reader = response.body!.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
const chunk = decoder.decode(value);
setMessages((prev) =>
prev.map((m) =>
m.id === assistantId
? { ...m, content: m.content + chunk }
: m
)
);
}
} catch (error) {
setMessages((prev) =>
prev.map((m) =>
m.id === assistantId
? { ...m, content: "Ocorreu um erro. Por favor, tente novamente." }
: m
)
);
}
setIsLoading(false);
};
return (
<div className="flex flex-col h-[600px] border rounded-lg">
<div className="flex-1 overflow-y-auto p-4 space-y-4">
{messages.map((msg) => (
<div
key={msg.id}
className={`flex ${msg.role === "user" ? "justify-end" : "justify-start"}`}
>
<div
className={`max-w-[70%] p-3 rounded-lg ${
msg.role === "user"
? "bg-blue-600 text-white"
: "bg-gray-100 text-gray-900"
}`}
>
{msg.content}
</div>
</div>
))}
<div ref={messagesEndRef} />
</div>
<div className="border-t p-4 flex gap-2">
<input
value={input}
onChange={(e) => setInput(e.target.value)}
onKeyDown={(e) => e.key === "Enter" && !e.shiftKey && sendMessage()}
placeholder="Digite uma mensagem..."
className="flex-1 p-2 border rounded-lg"
disabled={isLoading}
/>
<button
onClick={sendMessage}
disabled={isLoading}
className="px-4 py-2 bg-blue-600 text-white rounded-lg disabled:opacity-50"
>
Enviar
</button>
</div>
</div>
);
}
Rota de API com Suporte a Streaming
Rota de API que chama a API da Anthropic no backend e retorna via streaming.
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
export async function POST(request: Request) {
const { messages } = await request.json();
const stream = await client.messages.stream({
model: "claude-sonnet-4-20250514",
max_tokens: 1024,
system: "Você é um assistente gentil e educado. Responda em português.",
messages,
});
const encoder = new TextEncoder();
const readable = new ReadableStream({
async start(controller) {
for await (const event of stream) {
if (
event.type === "content_block_delta" &&
event.delta.type === "text_delta"
) {
controller.enqueue(encoder.encode(event.delta.text));
}
}
controller.close();
},
});
return new Response(readable, {
headers: { "Content-Type": "text/plain; charset=utf-8" },
});
}
Persistência do Histórico de Conversas
Salvando conversas no banco de dados para poder retomá-las depois.
import { db } from "@/lib/database";
export async function saveConversation(
userId: string,
messages: Message[]
) {
return db.conversation.upsert({
where: { id: `${userId}-current` },
update: {
messages: JSON.stringify(messages),
updatedAt: new Date(),
},
create: {
id: `${userId}-current`,
userId,
messages: JSON.stringify(messages),
},
});
}
export async function loadConversation(userId: string): Promise<Message[]> {
const conv = await db.conversation.findUnique({
where: { id: `${userId}-current` },
});
return conv ? JSON.parse(conv.messages as string) : [];
}
Incorporando RAG (Geração Aumentada por Recuperação)
Para criar um chatbot que responde com base em documentos internos, a arquitetura RAG é eficaz.
import { searchDocuments } from "@/lib/vector-search";
async function generateRAGResponse(query: string, conversationHistory: Message[]) {
// Buscar documentos relacionados
const relevantDocs = await searchDocuments(query, { limit: 5 });
const context = relevantDocs
.map((doc) => `---\n${doc.title}\n${doc.content}\n---`)
.join("\n");
const systemPrompt = `Responda às perguntas com base nos documentos abaixo.
Se a informação não estiver nos documentos, responda "Essa informação não foi encontrada".
${context}`;
return client.messages.stream({
model: "claude-sonnet-4-20250514",
max_tokens: 1024,
system: systemPrompt,
messages: conversationHistory,
});
}
Para expandir funcionalidades com integração de servidor MCP, consulte o Guia de Servidor MCP, e para design eficaz de prompts, confira 5 Dicas para Melhorar seus Prompts.
Resumo
Com o Claude Code, você pode desenvolver eficientemente chatbots completos incluindo UI de chat, API com streaming, gerenciamento de conversas e arquitetura RAG. A abordagem de adicionar funcionalidades gradualmente é eficaz.
Para mais detalhes, consulte a documentação oficial do Claude Code e a referência da API Anthropic.
Atualização 2026 para produção
Um chatbot é uma aplicação que recebe uma mensagem, mantém o contexto necessário e responde em formato de conversa. Na prática, ele funciona como uma porta de entrada para suporte, vendas, busca em documentos ou orientação de usuários. O desafio real não é desenhar a caixa de chat, mas definir o que o bot pode responder, quando deve admitir incerteza e para onde envia a pessoa quando a automação não é suficiente.
Com Claude Code, comece pequeno. Um bot que responde às dez perguntas mais frequentes pode ser testado, medido e monetizado com muito mais segurança do que um assistente genérico. Escopo claro reduz custo, protege dados sensíveis e deixa evidente se o projeto melhora conversão, retenção ou produtividade.
Tabela de arquitetura
| Camada | Responsabilidade | Nota de produção |
|---|---|---|
| UI React | Entrada, histórico, carregamento e retry | O estado básico está na documentação do React useState |
| Rota API | Protege chaves e normaliza requisições | Inclua limite de tamanho, autenticação e timeout |
| Streaming | Mostra resposta parcial durante a geração | Veja os fundamentos em MDN Streams API |
| Persistência | Retoma conversas e permite auditoria | Guarde apenas o necessário e planeje exclusão |
| RAG | Busca documentos, políticas ou páginas de produto | Sem evidência forte, o bot não deve inventar |
| Webhooks | Envia eventos para CRM, tickets ou Slack | Use Claude Code Webhook Implementation |
| Analytics | Mede sucesso, escalonamento e cliques de CTA | Complete com Claude Code Analytics Implementation |
Para o contrato de API, siga o padrão de Claude Code API Development: mensagens com papel e conteúdo, instrução de sistema no servidor e resposta em stream. Isso facilita trocar a interface, adicionar novos canais ou evoluir o modelo sem refazer tudo.
Demo executável de streaming
Salve como chatbot-stream-demo.mjs e rode node chatbot-stream-demo.mjs. O exemplo não chama Claude; ele valida histórico e streaming antes da integração real.
const encoder = new TextEncoder();
const decoder = new TextDecoder();
const faq = new Map([
["password", "Open the account page, choose Reset password, and follow the email link."],
["pricing", "The pricing page explains plans. For a custom quote, collect team size and required features."],
["refund", "Refund requests should be routed to support with the order id and purchase email."],
]);
const history = [];
function chooseAnswer(question) {
const normalized = question.toLowerCase();
for (const [keyword, answer] of faq) {
if (normalized.includes(keyword)) return answer;
}
return "I could not find a safe answer in the FAQ. I will hand this to a human operator.";
}
async function* streamText(text) {
for (const token of text.split(/(\s+)/)) {
await new Promise((resolve) => setTimeout(resolve, 15));
yield encoder.encode(token);
}
}
async function ask(question) {
history.push({ role: "user", content: question });
const answer = chooseAnswer(question);
process.stdout.write(`\nUser: ${question}\nAssistant: `);
let fullAnswer = "";
for await (const chunk of streamText(answer)) {
const token = decoder.decode(chunk);
fullAnswer += token;
process.stdout.write(token);
}
history.push({ role: "assistant", content: fullAnswer });
}
await ask("How do I reset my password?");
await ask("Can I see pricing before talking to sales?");
console.log(`\n\nSaved ${history.length} messages.`);
Na aplicação real, troque chooseAnswer pela chamada ao Claude. Mantenha a ordem: salvar pergunta, transmitir resposta parcial e salvar resposta final. Isso evita o failure mode em que a tela mostra texto, mas o banco grava uma resposta vazia.
Casos de uso reais
Primeiro use case: qualificação comercial para SaaS. O chatbot responde sobre preço, segurança, integrações e compra, e só envia para conversa humana quando há intenção forte. O resultado é menos triagem manual e mais reuniões com contexto.
Segundo caso: help desk interno. Férias, reembolso, VPN, troca de equipamento e onboarding são perguntas repetidas. Com RAG, o bot cita a política correta e abre um ticket quando precisa de aprovação.
Terceiro caso: site educacional ou de conteúdo. O leitor pergunta se deve estudar API, webhooks ou analytics. O bot recomenda o próximo artigo e leva para training quando a pessoa precisa de orientação prática. Esse workflow monetiza sem interromper a leitura.
Quarto caso: coleta inicial de incidentes. O bot pergunta erro, horário, navegador, conta e passos de reprodução. O sucesso aqui é entregar um ticket completo, não fingir que resolve tudo.
Erros e riscos concretos
Não envie histórico ilimitado ao modelo. Conversas longas aumentam custo, reduzem velocidade e podem misturar instruções antigas com a pergunta atual. Resuma turnos antigos e guarde apenas o necessário.
Não transforme busca fraca em resposta confiante. Se o RAG não encontra fonte forte, o bot deve avisar e oferecer atendimento humano. Essa regra protege suporte, conformidade e confiança.
Não trate streaming como detalhe visual. Queda de rede, envio duplo, bolha vazia e carregamento infinito quebram a experiência. Use botão desabilitado, cancelamento, timeout e mensagem de retry.
Não publique sem métricas. Meça perguntas sem resposta, escalonamentos, cliques em CTA e conversas que viram compra ou consultoria. Volume de mensagens sozinho não prova valor.
CTA de monetização
Um chatbot comercial precisa levar a uma próxima ação clara: revisão de implementação, diagnóstico, treinamento ou template. Na ClaudeCodeLab, o caminho recomendado é training, porque transforma o interesse do artigo em uma conversa prática.
O roteiro para o leitor é: entender o conceito aqui, construir a API com Claude Code API Development, integrar eventos com webhooks e medir conversão com analytics.
PDF grátis: cheatsheet do Claude Code
Informe seu e-mail e baixe uma página com comandos, hábitos de revisão e workflows seguros.
Cuidamos dos seus dados e não enviamos spam.
Sobre o autor
Masa
Engenheiro focado em workflows práticos com Claude Code.
Artigos relacionados
Workflow Obsidian para CLAUDE.md com Claude Code
Transforme notas de trabalho do Obsidian em notas operacionais CLAUDE.md para preservar contexto.
Claude Code Revenue CTA Routing: artigos para PDF, Gumroad e consultoria
Um fluxo com Claude Code para levar leitores ao PDF grátis, Gumroad ou consultoria conforme intenção.
Regras de handoff para equipes com Claude Code: evidências, permissões, rollback e receita
Formato prático para entregar trabalho do Claude Code com prova, permissões, rollback, PDF grátis, Gumroad e consultoria.