Construir un agente de IA con Claude API: guía técnica completa
Los agentes de IA no son chatbots con esteroides: son programas que razonan, deciden qué herramientas usar y ejecutan tareas complejas de forma autónoma. Esta guía te lleva desde cero hasta un agente funcional con Claude API y TypeScript — con código real que puedes copiar, adaptar y desplegar. Si primero necesitas entender qué es un agente de IA a nivel conceptual, lee nuestra guía completa sobre agentes de IA.
Esta guía usa Claude API con @anthropic-ai/sdk, TypeScript y Node.js 20+. Los conceptos (function calling, RAG, bucle agente) son trasladables a cualquier modelo que soporte herramientas.
Qué es un agente de IA (versión técnica)
Un agente es un bucle: recibe un objetivo, razona sobre el siguiente paso, ejecuta una herramienta si es necesario, evalúa el resultado y repite hasta completar la tarea o alcanzar un límite. La diferencia con un simple prompt → respuesta es que el agente tiene autonomía para encadenar acciones.
| Componente | Qué hace | Implementación |
|---|---|---|
| LLM (Claude) | Razona y decide el siguiente paso | Claude API con system prompt |
| Herramientas | Ejecutan acciones en el mundo real | Function calling / tool use |
| Memoria | Mantiene contexto entre pasos | Array de mensajes + RAG |
| Orquestador | Gestiona el bucle y los límites | Bucle while con condición de parada |
1. Setup: instalar el SDK y configurar la API key
Empezamos con un proyecto TypeScript limpio y el SDK oficial de Anthropic.
mkdir mi-agente && cd mi-agente
npm init -y
npm install @anthropic-ai/sdk
npm install -D typescript @types/node tsx
npx tsc --initCrea un archivo .env con tu API key (obtenla en console.anthropic.com):
ANTHROPIC_API_KEY=sk-ant-api03-...tu-clave-aquíEl SDK lee ANTHROPIC_API_KEY automáticamente del entorno. Nunca la hardcodees en el código — si tu agente acaba en un repo, la clave se filtra.
2. Agente básico: system prompt + bucle de mensajes
El agente más simple es un bucle que envía mensajes a Claude y procesa las respuestas. El system prompt define la personalidad, las instrucciones y los límites del agente.
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
const SYSTEM_PROMPT = `Eres un asistente técnico especializado en desarrollo web.
Responde siempre en español. Sé directo y conciso.
Si no sabes algo, dilo claramente en lugar de inventar.`;
async function chat(userMessage: string): Promise<string> {
const response = await client.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 1024,
system: SYSTEM_PROMPT,
messages: [{ role: "user", content: userMessage }],
});
// Extraer texto de la respuesta
const textBlock = response.content.find((b) => b.type === "text");
return textBlock?.text ?? "Sin respuesta";
}Esto no es un agente todavía — es una llamada simple. Lo que lo convierte en agente es añadir herramientas y un bucle que permita a Claude decidir cuándo usarlas.
3. Function calling: dando herramientas al agente
Function calling es el mecanismo que convierte un chatbot en un agente. Defines las herramientas disponibles con un JSON Schema, y Claude decide cuándo y cómo invocarlas. Tú ejecutas la función y devuelves el resultado al modelo.
Definir herramientas
Cada herramienta tiene un nombre, una descripción (que Claude usa para decidir cuándo usarla) y un esquema de parámetros:
import Anthropic from "@anthropic-ai/sdk";
// Definición de herramientas para Claude
export const tools: Anthropic.Tool[] = [
{
name: "buscar_productos",
description:
"Busca productos en la base de datos por nombre o categoría. Usar cuando el usuario pregunta por productos disponibles, precios o stock.",
input_schema: {
type: "object" as const,
properties: {
query: {
type: "string",
description: "Término de búsqueda (nombre o categoría del producto)",
},
max_results: {
type: "number",
description: "Número máximo de resultados (por defecto 5)",
},
},
required: ["query"],
},
},
{
name: "consultar_pedido",
description:
"Consulta el estado de un pedido por su ID. Usar cuando el usuario pregunta por el estado de su pedido.",
input_schema: {
type: "object" as const,
properties: {
order_id: {
type: "string",
description: "ID del pedido (formato: ORD-XXXX)",
},
},
required: ["order_id"],
},
},
];Ejecutar herramientas
Necesitas un dispatcher que reciba el nombre de la herramienta y los argumentos, ejecute la lógica real y devuelva el resultado:
// Simula una base de datos — en producción sería tu API/DB real
async function buscarProductos(query: string, maxResults = 5) {
// Aquí iría tu consulta a PostgreSQL, Elasticsearch, etc.
return [
{ id: "PRD-001", nombre: "Camiseta técnica", precio: 29.90, stock: 142 },
{ id: "PRD-002", nombre: "Pantalón trail", precio: 59.90, stock: 38 },
].slice(0, maxResults);
}
async function consultarPedido(orderId: string) {
// Aquí iría tu consulta al sistema de pedidos
return {
id: orderId,
estado: "en_transito",
estimacion: "2026-04-30",
tracking: "https://tracking.example.com/abc123",
};
}
export async function executeTool(
name: string,
input: Record<string, unknown>
): Promise<string> {
switch (name) {
case "buscar_productos":
const productos = await buscarProductos(
input.query as string,
input.max_results as number
);
return JSON.stringify(productos);
case "consultar_pedido":
const pedido = await consultarPedido(input.order_id as string);
return JSON.stringify(pedido);
default:
return JSON.stringify({ error: `Herramienta '${name}' no encontrada` });
}
}El bucle agente completo
Aquí es donde todo se junta. El bucle envía el mensaje a Claude con las herramientas disponibles, detecta si Claude quiere usar una herramienta, la ejecuta, devuelve el resultado y repite hasta que Claude responde con texto final:
import Anthropic from "@anthropic-ai/sdk";
import { tools } from "./tools";
import { executeTool } from "./tool-executor";
const client = new Anthropic();
const MAX_ITERATIONS = 10;
export async function runAgent(userMessage: string): Promise<string> {
const messages: Anthropic.MessageParam[] = [
{ role: "user", content: userMessage },
];
for (let i = 0; i < MAX_ITERATIONS; i++) {
const response = await client.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 4096,
system: "Eres un asistente de e-commerce. Usa las herramientas disponibles para responder con datos reales. Responde en español.",
tools,
messages,
});
// Si Claude termina sin pedir herramientas → respuesta final
if (response.stop_reason === "end_of_turn") {
const text = response.content.find((b) => b.type === "text");
return text?.text ?? "Sin respuesta";
}
// Si Claude quiere usar herramientas → ejecutarlas
if (response.stop_reason === "tool_use") {
// Añadir la respuesta del asistente al historial
messages.push({ role: "assistant", content: response.content });
// Ejecutar cada herramienta solicitada
const toolResults: Anthropic.ToolResultBlockParam[] = [];
for (const block of response.content) {
if (block.type === "tool_use") {
const result = await executeTool(
block.name,
block.input as Record<string, unknown>
);
toolResults.push({
type: "tool_result",
tool_use_id: block.id,
content: result,
});
}
}
// Devolver resultados al modelo
messages.push({ role: "user", content: toolResults });
}
}
return "Límite de iteraciones alcanzado. El agente no pudo completar la tarea.";
}Este patrón — enviar → detectar tool_use → ejecutar → devolver → repetir — es el corazón de cualquier agente con Claude API.
4. RAG: conectar el agente a tus datos
Claude sabe mucho, pero no sabe nada de tus datos internos: productos, documentación, historial de clientes. RAG (Retrieval-Augmented Generation) resuelve esto buscando información relevante antes de generar la respuesta.
Cómo funciona RAG con un agente
- Indexación: conviertes tus documentos en embeddings vectoriales y los almacenas en una base de datos vectorial (Pinecone, Weaviate, pgvector, Chroma).
- Búsqueda: cuando el agente necesita información, busca los fragmentos más relevantes por similitud semántica.
- Inyección: los fragmentos recuperados se añaden al contexto de Claude como parte del mensaje, antes de que genere la respuesta.
Implementación como herramienta del agente
La forma más limpia de integrar RAG es como una herramienta más. Claude decide cuándo necesita buscar en la base de conocimiento:
// Herramienta RAG para el agente
{
name: "buscar_documentacion",
description:
"Busca en la base de conocimiento interna. Usar cuando el usuario pregunta sobre políticas, procedimientos, documentación técnica o información que no es conocimiento general.",
input_schema: {
type: "object" as const,
properties: {
query: {
type: "string",
description: "Pregunta o términos de búsqueda en lenguaje natural",
},
},
required: ["query"],
},
}
// Executor: busca en tu vector store
async function buscarDocumentacion(query: string): Promise<string> {
// 1. Generar embedding de la query
// (usa OpenAI embeddings, Cohere, o cualquier modelo de embeddings)
const embedding = await generateEmbedding(query);
// 2. Buscar los fragmentos más similares
const results = await vectorStore.query({
vector: embedding,
topK: 5,
includeMetadata: true,
});
// 3. Formatear para Claude
return results.matches
.map((m) => `[Fuente: ${m.metadata.source}]\n${m.metadata.text}`)
.join("\n\n---\n\n");
}La ventaja de RAG como herramienta es que Claude solo busca cuando lo necesita — no en cada mensaje. Esto ahorra tokens y mejora la relevancia.
5. Razonamiento multi-paso
Los agentes más útiles encadenan varias herramientas para resolver tareas complejas. Un ejemplo: "¿Cuánto costaría enviar 50 unidades del producto más vendido a Barcelona?" requiere:
- Buscar el producto más vendido (herramienta de búsqueda).
- Consultar stock disponible (herramienta de inventario).
- Calcular coste de envío (herramienta de logística).
- Combinar todo en una respuesta coherente.
Claude hace esto automáticamente si las herramientas están bien descritas. La clave está en las descripciones de las herramientas: cuanto más claras y específicas, mejor decide Claude cuándo y cómo usarlas.
Buenas prácticas para descripciones de herramientas
- Describe cuándo usar la herramienta, no solo qué hace. "Usar cuando el usuario pregunta por el estado de un pedido" es mejor que "Consulta pedidos".
- Incluye el formato esperado de los parámetros. "ID del pedido en formato ORD-XXXX" evita errores.
- Añade restricciones: "No llamar sin confirmación del usuario si la acción es destructiva".
- Máximo 10-15 herramientas. Con más, Claude tarda más en decidir y comete más errores de selección.
6. Gestión de errores en producción
Un agente en producción falla de formas que un chatbot simple nunca lo haría. Los tres tipos de error que debes manejar:
| Tipo de error | Ejemplo | Solución |
|---|---|---|
| Error de API | Rate limit (429), timeout, error de servidor (500) | Retry con backoff exponencial (el SDK lo incluye) |
| Error de herramienta | La API externa falla, datos inválidos, timeout | Devolver error como tool_result — Claude se adapta |
| Error de razonamiento | Bucle infinito, herramienta incorrecta, alucinación | Límite de iteraciones + validación de outputs |
| Error de seguridad | Inyección de prompt, acceso no autorizado | Validación de inputs + permisos por herramienta |
// Gestión de errores en el executor de herramientas
export async function safeExecuteTool(
name: string,
input: Record<string, unknown>
): Promise<string> {
try {
const result = await executeTool(name, input);
// Validar que el resultado no esté vacío
if (!result || result === "null" || result === "undefined") {
return JSON.stringify({
error: "La herramienta no devolvió resultados",
suggestion: "Intenta reformular la búsqueda",
});
}
return result;
} catch (error) {
// Devolver el error a Claude para que se adapte
return JSON.stringify({
error: `Error al ejecutar ${name}: ${(error as Error).message}`,
suggestion: "Informa al usuario de que hubo un problema técnico",
});
}
}Un punto crítico: cuando una herramienta falla, devuelve el error como resultado en lugar de lanzar una excepción. Claude sabe interpretar errores y puede informar al usuario o intentar una alternativa.
7. Seguridad del agente
Un agente que ejecuta herramientas es, por definición, una superficie de ataque. Las principales amenazas:
- Inyección de prompt: un usuario intenta que el agente ignore sus instrucciones. Mitiga con system prompt robusto y validación de inputs.
- Escalada de privilegios: el agente ejecuta acciones que no debería. Mitiga con permisos explícitos por herramienta y confirmación para acciones destructivas.
- Exfiltración de datos: el agente filtra información sensible del contexto. Mitiga sanitizando los datos que entran al contexto.
Para profundizar en seguridad de aplicaciones web, lee nuestra guía OWASP Top 10. Los principios aplican directamente a endpoints de agentes.
8. Optimización: prompt caching
En un agente, el system prompt y las definiciones de herramientas se envían en cada iteración del bucle. Con prompt caching, Anthropic cachea estos bloques estáticos y reduces el coste de tokens de entrada hasta un 90%:
// Activar cache en el system prompt (se repite en cada iteración)
const response = await client.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 4096,
system: [
{
type: "text",
text: SYSTEM_PROMPT, // Este bloque se cachea
cache_control: { type: "ephemeral" },
},
],
tools, // Las herramientas también se cachean automáticamente
messages,
});
// En un agente con 10 iteraciones:
// Sin cache: 10x coste del system prompt + tools
// Con cache: 1x creación + 9x lectura (90% más barato)9. Consideraciones de despliegue
Un agente no es un endpoint REST convencional. Consideraciones clave:
- Timeouts largos: un agente puede tardar 10-30 segundos en completar una tarea multi-paso. Configura timeouts acorde.
- Streaming: para UX, usa la API de streaming de Claude para mostrar progreso en tiempo real mientras el agente razona.
- Persistencia de contexto: si el agente mantiene conversaciones multi-turno, necesitas almacenar el historial de mensajes (Redis, base de datos).
- Rate limiting: protege tu endpoint con límites por usuario. Un agente sin límites es un vector de gasto descontrolado.
- Observabilidad: loguea cada paso del bucle agente — qué herramientas usó, qué devolvieron, cuántos tokens consumió. Sin esto, depurar problemas en producción es imposible.
Arquitectura completa del agente
Resumen visual de todos los componentes y cómo se conectan:
- Usuario envía mensaje al endpoint del agente.
- Orquestador construye el array de mensajes + system prompt + herramientas.
- Claude API recibe el contexto y responde: texto final o tool_use.
- Si tool_use → Dispatcher ejecuta la herramienta (API, DB, vector store).
- El resultado se añade al array de mensajes y se vuelve al paso 3.
- Si texto final → se devuelve al usuario.
- Logger registra cada paso para observabilidad.
Conclusión
Construir un agente con Claude API no es complejo si sigues el patrón correcto: system prompt claro, herramientas bien descritas, bucle con límite de iteraciones y gestión de errores robusta. El SDK de Anthropic hace el trabajo pesado — tu código se centra en la lógica de negocio de las herramientas.
Empieza simple: un agente con 2-3 herramientas que resuelva un problema real de tu negocio. Añade RAG cuando necesites datos propios. Escala herramientas cuando el caso de uso lo justifique. Y ante todo, loguea cada paso — los agentes son deterministas en su estructura, pero el razonamiento de cada ejecución es único.
Si quieres que diseñemos e implementemos un agente de IA adaptado a tu negocio, escríbenos a /contacto.
Preguntas frecuentes
¿Qué es un agente de IA?
Un agente de IA es un programa que recibe un objetivo, razona sobre los pasos necesarios, ejecuta herramientas (APIs, bases de datos, búsquedas) y devuelve un resultado sin que el usuario gestione cada paso. A diferencia de un chatbot, un agente puede encadenar varias acciones de forma autónoma para completar tareas complejas.
¿Qué diferencia hay entre Claude API y la interfaz de claude.ai?
La interfaz claude.ai es un producto de consumo para interacción directa. Claude API es la interfaz programática que permite integrar Claude en tus propias aplicaciones: controlas el system prompt, defines herramientas (function calling), gestionas el contexto y pagas por tokens consumidos. La API es lo que usas para construir agentes.
¿Cuánto cuesta usar Claude API para un agente?
Los precios varían según el modelo. Claude Sonnet 4 cuesta aproximadamente $3 por millón de tokens de entrada y $15 por millón de salida. Un agente típico que procesa 10.000 peticiones al mes con contextos medios (4K tokens entrada + 1K salida) costaría unos $150-200/mes. El prompt caching reduce costes hasta un 90% en tokens repetidos.
¿Qué es function calling en Claude API?
Function calling (o tool use) permite que Claude invoque funciones definidas por ti. Le describes las herramientas disponibles (nombre, descripción, parámetros JSON Schema) y Claude decide cuándo usarlas, genera los argumentos correctos y espera los resultados. Es el mecanismo clave para que un agente interactúe con el mundo real: APIs, bases de datos, sistemas externos.
¿Qué es RAG y por qué lo necesita un agente?
RAG (Retrieval-Augmented Generation) es el patrón de buscar información relevante en una base de datos vectorial antes de generar la respuesta. Un agente lo necesita para responder preguntas sobre datos propios (documentos internos, productos, historial) que no están en el entrenamiento de Claude. Sin RAG, el agente solo sabe lo que el modelo ya conoce.
¿Puedo usar Claude API con JavaScript en lugar de TypeScript?
Sí. El SDK oficial @anthropic-ai/sdk funciona con JavaScript y TypeScript. TypeScript es recomendable porque el tipado de las herramientas, los mensajes y las respuestas evita errores en tiempo de ejecución que son difíciles de depurar en agentes complejos con múltiples herramientas.
¿Cómo gestiono errores y reintentos en un agente de producción?
Tres capas: (1) retry con backoff exponencial para errores 429/500 de la API (el SDK lo incluye), (2) validación de las respuestas de herramientas antes de pasarlas al modelo, (3) límite máximo de iteraciones del bucle agente (típicamente 10-15 pasos) para evitar loops infinitos. Además, loguea cada paso del agente para poder depurar las cadenas de razonamiento.
¿Tienes un proyecto en mente?
Cuéntanos qué necesitas y te proponemos la mejor solución sin compromiso.
Hablar con el equipo →