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.
Artigos relacionados
Codex Automations para content ops: QA, deploy e conversão diária
Use Codex Automations para revisar analytics, escolher temas, fazer QA, verificar deploy e melhorar CTAs.
Claude Code × Amazon Bedrock: guia prático para rodar Claude em produção na AWS
Use Claude Code e Amazon Bedrock em produção: IAM, Converse API, logs, Guardrails e controle de custos.
Criar um Discord Bot com Claude Code: Slash Commands com discord.js
Crie um Discord Bot seguro com Claude Code, discord.js e três Slash Commands úteis para suporte.
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.