Use Cases (Actualizado: 2/6/2026)

Como desarrollar un chatbot con Claude Code

Aprende a desarrollar un chatbot usando Claude Code. Incluye ejemplos de codigo practicos y guia paso a paso.

Como desarrollar un chatbot con Claude Code

Desarrollando un chatbot con Claude Code

El desarrollo de un chatbot de IA involucra muchos elementos como la implementacion de UI, integracion con API, gestion de conversaciones y procesamiento de streaming. Con Claude Code, puedes construir un chatbot que integre todos estos componentes en poco tiempo.

Implementacion basica de la UI de chat

> Crea un componente de chatbot en React.
> Con soporte para respuestas en streaming, visualizacion del historial de conversacion y formulario 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: "Ocurrio un error. Por favor, intentalo de nuevo." }
            : 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="Escribe un mensaje..."
          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>
  );
}

Ruta de API con soporte de streaming

Una ruta de API que llama a la API de Anthropic en el backend y devuelve la respuesta en 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: "Eres un asistente amable y educado. Responde en espanol.",
    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" },
  });
}

Persistencia del historial de conversacion

Guarda las conversaciones en la base de datos para poder reanudarlas posteriormente.

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) : [];
}

Integracion de RAG (Generacion Aumentada por Recuperacion)

Cuando se quiere crear un chatbot que responda basandose en documentos internos, la arquitectura RAG es efectiva.

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 = `Responde a las preguntas basandote en los siguientes documentos.
Si la informacion no se encuentra en los documentos, responde "No se encontro esa informacion".

${context}`;

  return client.messages.stream({
    model: "claude-sonnet-4-20250514",
    max_tokens: 1024,
    system: systemPrompt,
    messages: conversationHistory,
  });
}

Para ampliar la funcionalidad con la integracion de servidores MCP, consulta la guia de servidores MCP, y para el diseno efectivo de prompts, consulta los 5 tips para mejorar tus prompts.

Resumen

Con Claude Code, puedes desarrollar eficientemente un chatbot que incluye UI de chat, API de streaming, gestion de conversaciones y arquitectura RAG. Un enfoque de agregar funcionalidades de forma gradual es lo mas efectivo.

Para mas informacion, consulta la documentacion oficial de Claude Code y la referencia de la API de Anthropic.

Actualización 2026 para producción

Un chatbot es una aplicación que recibe un mensaje, conserva el contexto necesario y responde como si fuera una conversación. En términos sencillos, es una puerta de entrada para soporte, ventas, búsqueda interna o formación. El valor no está solo en mostrar una burbuja de chat, sino en reducir una tarea concreta: responder preguntas repetidas, clasificar contactos, buscar documentación o reunir datos antes de abrir un ticket.

Con Claude Code conviene empezar con un alcance pequeño. Un bot que responde diez preguntas frecuentes puede revisarse, medirse y mejorar en una semana. Un asistente que promete resolverlo todo suele fallar por coste, permisos, datos sensibles y respuestas difíciles de verificar. Antes de escribir más prompts, define qué puede contestar, cuándo debe decir “no lo sé” y a qué flujo humano debe enviar al usuario.

Tabla de arquitectura

CapaResponsabilidadNota de producción
UI en ReactEntrada, historial, estado de carga y reintentoRevisa el patrón de estado en la documentación de React useState
Ruta APIOculta claves y normaliza la petición al backendAñade límites de tamaño, autenticación y timeout
StreamingEnvía texto parcial mientras se genera la respuestaUsa Web Streams con cuidado; consulta MDN Streams API
PersistenciaGuarda conversaciones para reanudar y auditarMinimiza datos personales y define borrado
RAGBusca en documentos, políticas o páginas de productoSi no hay evidencia, el bot no debe inventar
WebhooksEnvía eventos a CRM, tickets o SlackConecta con Claude Code Webhook Implementation
AnalíticaMide éxito, escalado, abandono y CTAComplementa con Claude Code Analytics Implementation

Para la forma de la petición, usa una estructura estable como la de Claude Code API Development: lista de mensajes con rol y contenido, instrucción del sistema en el servidor y una respuesta en streaming. Así puedes cambiar la interfaz o añadir canales sin rehacer todo.

Demo ejecutable de streaming

Guarda este archivo como chatbot-stream-demo.mjs y ejecútalo con node chatbot-stream-demo.mjs. No llama a Claude; sirve para verificar historial y streaming antes de conectar la ruta 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.`);

Cuando lo lleves a producción, sustituye chooseAnswer por la llamada a Claude y conserva la secuencia: guardar mensaje del usuario, emitir respuesta parcial, guardar respuesta final. Evita así un fallo común donde la UI muestra texto, pero la base de datos queda vacía.

Casos de uso reales

Primer use case: cualificación comercial para SaaS. El bot responde sobre precios, seguridad, integraciones y requisitos, y solo envía a una consulta cuando detecta intención real. Esto mejora la monetización porque el equipo humano recibe conversaciones más preparadas.

Segundo caso: mesa de ayuda interna. Preguntas sobre vacaciones, gastos, VPN o alta de equipos suelen repetirse. Con RAG, el bot cita la política correcta y, si hace falta aprobación, abre un ticket por webhook.

Tercer caso: sitio educativo o de contenidos. El lector pregunta qué aprender después y el bot recomienda API, webhooks o analítica, enlazando a training cuando necesita acompañamiento. Es un workflow más natural que mostrar un banner genérico.

Cuarto caso: intake de incidentes. El bot recopila error, hora, navegador, cuenta y pasos de reproducción antes de crear el ticket. La meta no es resolverlo todo, sino entregar un informe completo.

Errores y riesgos concretos

No envíes historial ilimitado al modelo. Sube el coste, ralentiza la respuesta y puede mezclar instrucciones antiguas con la pregunta actual. Resume conversaciones largas y guarda solo lo necesario.

No conviertas una búsqueda débil en una respuesta segura. Si RAG no encuentra evidencia, el bot debe decirlo y ofrecer una ruta humana. Esta regla reduce muchos problemas de soporte.

No ignores el failure mode del streaming. Puede haber doble envío, conexión cortada, burbujas vacías o estado de carga infinito. Usa botón deshabilitado, cancelación, timeout y mensaje de reintento.

No publiques sin medición. Mide preguntas sin resolver, clics en CTA, escalados y conversaciones que terminan en compra o consulta. Los mensajes totales no bastan para saber si el bot genera negocio.

CTA de monetización

Si quieres convertir este chatbot en un activo comercial, conecta el final de la conversación con una oferta clara: diagnóstico, revisión de implementación, curso o plantilla. En ClaudeCodeLab, la ruta recomendada es training, porque permite pasar de leer el artículo a revisar una implementación real.

La secuencia útil para el lector es: entender el concepto aquí, profundizar en Claude Code API Development, automatizar eventos con webhooks y medir conversión con analytics.

#Claude Code #chatbot #AI #streaming #RAG
Gratis

PDF gratis: cheatsheet de Claude Code

Introduce tu email y descarga una hoja con comandos, hábitos de revisión y flujos seguros.

Cuidamos tus datos y no enviamos spam.

Masa

Sobre el autor

Masa

Ingeniero enfocado en workflows prácticos con Claude Code.