Use Cases

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.

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.

#Claude Code #chatbot #AI #streaming #RAG