En resumen
La fuga del código fuente de Claude expuso una base de código TypeScript de 512,000 líneas el 31 de marzo de 2026. La arquitectura se reduce a un bucle `while` que llama a la API de Claude, despacha las llamadas a herramientas y devuelve los resultados. Puedes construir tu propia versión con Python, el SDK de Anthropic y unas 200 líneas de código para el bucle principal. Esta guía desglosa cada componente y te muestra cómo recrearlos.
Introducción
El 31 de marzo de 2026, Anthropic lanzó un archivo de mapa de origen de 59.8 MB dentro de la versión 2.1.88 de su paquete npm `@anthropic-ai/claude-code`. Los mapas de origen son artefactos de depuración que revierten el JavaScript minificado a su código fuente original. Dado que la herramienta de compilación de Anthropic (el empaquetador de Bun) los genera por defecto, toda la base de código TypeScript fue recuperable.
En cuestión de horas, los desarrolladores habían replicado el código en docenas de repositorios de GitHub. La comunidad diseccionó rápidamente cada módulo, desde el bucle principal del agente hasta características ocultas como el “modo encubierto” y la inyección de herramientas falsas.
La reacción fue dividida. Algunos criticaron las prácticas de seguridad de Anthropic. Otros quedaron fascinados por la arquitectura. Pero la respuesta más productiva provino de desarrolladores que preguntaron: “¿Puedo construir esto yo mismo?”
La respuesta es sí. Los patrones centrales son sencillos. Esta guía recorre cada capa arquitectónica, explica por qué Anthropic tomó las decisiones que tomó y proporciona código funcional que puedes usar como punto de partida. También aprenderás cómo probar las interacciones de la API de tu agente personalizado con Apidog, lo que facilita mucho la depuración de conversaciones de API de múltiples turnos que los comandos curl sin procesar.
Lo que la fuga reveló sobre la arquitectura de Claude Code
La base de código de un vistazo
Claude Code, con nombre en clave interno “Tengu”, abarca alrededor de 1,900 archivos. La organización de módulos se divide en capas claras:
cli/ - Interfaz de usuario de terminal (React + Ink)
tools/ - Más de 40 implementaciones de herramientas
core/ - Prompts del sistema, permisos, constantes
assistant/ - Orquestación del agente
services/ - Llamadas API, compactación, OAuth, telemetría
La propia CLI es una aplicación React renderizada a través de Ink, un renderizador de React para la salida de la terminal. Utiliza Yoga (un motor flexbox CSS) para el diseño y códigos de escape ANSI para el estilo. Cada vista de conversación, área de entrada, visualización de llamada a herramienta y diálogo de permisos es un componente de React.
Esto está sobredimensionado para la mayoría de los proyectos de bricolaje. No necesitas una interfaz de usuario de terminal basada en React para construir un agente de codificación funcional. Un simple bucle REPL funciona bien.
El bucle principal del agente
Si eliminas la interfaz de usuario, la telemetría y las banderas de características, el núcleo de Claude Code es un bucle `while`. Anthropic lo llama internamente “nO”. Esto es lo que hace:
- Enviar mensajes a la API de Claude (prompt del sistema + definiciones de herramientas)
- Recibir una respuesta que contenga texto y/o bloques `tool_use`
- Ejecutar cada herramienta solicitada a través de un mapa de despacho de nombre a manejador
- Añadir los resultados de las herramientas de nuevo a la lista de mensajes
- Si la respuesta contiene más llamadas a herramientas, volver al paso 1
- Si la respuesta es texto plano sin llamadas a herramientas, devolverlo al usuario
Un “turno” es un ciclo completo de ida y vuelta. Los turnos continúan hasta que Claude produce texto sin invocaciones de herramientas. Ese es el patrón completo del agente.
Aquí hay una versión mínima en Python que captura el núcleo:
import anthropic
client = anthropic.Anthropic()
MODEL = "claude-sonnet-4-6"
def agent_loop(system_prompt: str, tools: list, messages: list) -> str:
"""El bucle principal del agente: seguir llamando hasta que no haya más uso de herramientas."""
while True:
response = client.messages.create(
model=MODEL,
max_tokens=16384,
system=system_prompt,
tools=tools,
messages=messages,
)
# Añadir respuesta del asistente a la conversación
messages.append({"role": "assistant", "content": response.content})
# Si el modelo se detuvo sin solicitar herramientas, hemos terminado
if response.stop_reason != "tool_use":
# Extraer el texto final
return "".join(
block.text for block in response.content
if hasattr(block, "text")
)
# Ejecutar cada llamada a herramienta y recolectar resultados
tool_results = []
for block in response.content:
if block.type == "tool_use":
result = execute_tool(block.name, block.input)
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": result,
})
# Devolver los resultados como un mensaje de usuario
messages.append({"role": "user", "content": tool_results})
Eso son unas 30 líneas. El resto de la complejidad de Claude Code proviene de las propias herramientas, el sistema de permisos, la gestión del contexto y la memoria.
Construyendo el sistema de herramientas
Por qué las herramientas dedicadas superan a un solo comando bash
Una de las decisiones arquitectónicas más claras en la fuga: Claude Code utiliza herramientas dedicadas para operaciones de archivos en lugar de enrutar todo a través de bash.
Hay una herramienta `Read` (no `cat`), una herramienta `Edit` (no `sed`), una herramienta `Grep` (no `grep`) y una herramienta `Glob` (no `find`). El prompt del sistema le dice explícitamente al modelo que prefiera estas en lugar de sus equivalentes de bash.
¿Por qué? Tres razones:
- Salida estructurada. Una herramienta `Grep` dedicada devuelve los resultados en un formato consistente que el modelo puede analizar. La canalización de comandos bash produce una salida impredecible que el modelo tiene dificultades para interpretar.
- Seguridad. La `BashTool` en Claude Code bloquea los backticks y la sintaxis de subshell `$()` para evitar la inyección. Las herramientas dedicadas evitan este riesgo por completo.
- Eficiencia de tokens. Los resultados de las herramientas pueden truncarse, muestrearse o descargarse en el disco. Las grandes salidas de `cat` desperdician tokens de la ventana de contexto.
El conjunto de herramientas esenciales
De la fuga, Claude Code expone menos de 20 herramientas por defecto, con más de 60 detrás de banderas de características. Para un agente DIY, necesitas cinco:
TOOLS = [
{
"name": "read_file",
"description": "Lee un archivo del sistema de archivos. Devuelve el contenido con números de línea.",
"input_schema": {
"type": "object",
"properties": {
"file_path": {
"type": "string",
"description": "Ruta absoluta al archivo"
},
"offset": {
"type": "integer",
"description": "Número de línea desde donde empezar a leer (base 0)"
},
"limit": {
"type": "integer",
"description": "Número máximo de líneas a leer. Por defecto 2000."
}
},
"required": ["file_path"]
}
},
{
"name": "write_file",
"description": "Escribe contenido en un archivo. Crea el archivo si no existe.",
"input_schema": {
"type": "object",
"properties": {
"file_path": {"type": "string", "description": "Ruta absoluta"},
"content": {"type": "string", "description": "Contenido del archivo a escribir"}
},
"required": ["file_path", "content"]
}
},
{
"name": "edit_file",
"description": "Reemplaza una cadena específica en un archivo. La cadena antigua debe ser única.",
"input_schema": {
"type": "object",
"properties": {
"file_path": {"type": "string", "description": "Ruta absoluta"},
"old_string": {"type": "string", "description": "Texto a buscar"},
"new_string": {"type": "string", "description": "Texto de reemplazo"}
},
"required": ["file_path", "old_string", "new_string"]
}
},
{
"name": "run_command",
"description": "Ejecuta un comando de shell y devuelve stdout/stderr.",
"input_schema": {
"type": "object",
"properties": {
"command": {"type": "string", "description": "Comando de shell a ejecutar"},
"timeout": {"type": "integer", "description": "Tiempo de espera en segundos. Por defecto 120."}
},
"required": ["command"]
}
},
{
"name": "search_code",
"description": "Busca un patrón regex en archivos dentro de un directorio.",
"input_schema": {
"type": "object",
"properties": {
"pattern": {"type": "string", "description": "Patrón Regex"},
"path": {"type": "string", "description": "Directorio donde buscar"},
"file_glob": {"type": "string", "description": "Filtro de patrón de archivo, ej. '*.py'"}
},
"required": ["pattern"]
}
}
]
Despacho de manejadores de herramientas
La función de ejecución de herramientas mapea los nombres de las herramientas a las funciones manejadoras:
import subprocess
import os
import re
def execute_tool(name: str, params: dict) -> str:
"""Despacha las llamadas a herramientas a sus manejadores."""
handlers = {
"read_file": handle_read_file,
"write_file": handle_write_file,
"edit_file": handle_edit_file,
"run_command": handle_run_command,
"search_code": handle_search_code,
}
handler = handlers.get(name)
if not handler:
return f"Error: Herramienta desconocida '{name}'"
try:
return handler(params)
except Exception as e:
return f"Error: {str(e)}"
def handle_read_file(params: dict) -> str:
path = params["file_path"]
offset = params.get("offset", 0)
limit = params.get("limit", 2000)
with open(path, "r") as f:
lines = f.readlines()
selected = lines[offset:offset + limit]
numbered = [f"{i + offset + 1}\t{line}" for i, line in enumerate(selected)]
return "".join(numbered)
def handle_write_file(params: dict) -> str:
path = params["file_path"]
os.makedirs(os.path.dirname(path), exist_ok=True)
with open(path, "w") as f:
f.write(params["content"])
return f"Escrito correctamente en {path}"
def handle_edit_file(params: dict) -> str:
path = params["file_path"]
with open(path, "r") as f:
content = f.read()
old = params["old_string"]
if content.count(old) == 0:
return f"Error: '{old[:50]}...' no encontrado en {path}"
if content.count(old) > 1:
return f"Error: '{old[:50]}...' coincide con {content.count(old)} ubicaciones. Sea más específico."
new_content = content.replace(old, params["new_string"], 1)
with open(path, "w") as f:
f.write(new_content)
return f"Editado correctamente {path}"
def handle_run_command(params: dict) -> str:
cmd = params["command"]
timeout = params.get("timeout", 120)
# Seguridad básica: bloquear patrones peligrosos
blocked = ["rm -rf /", "mkfs", "> /dev/"]
for pattern in blocked:
if pattern in cmd:
return f"Error: Patrón de comando peligroso bloqueado: {pattern}"
result = subprocess.run(
cmd, shell=True, capture_output=True, text=True,
timeout=timeout, cwd=os.getcwd()
)
output = ""
if result.stdout:
output += result.stdout
if result.stderr:
output += f"\nSTDERR:\n{result.stderr}"
if not output.strip():
output = f"Comando completado con código de salida {result.returncode}"
# Truncar grandes salidas para ahorrar tokens de contexto
if len(output) > 30000:
output = output[:15000] + "\n\n... [truncado] ...\n\n" + output[-15000:]
return output
def handle_search_code(params: dict) -> str:
pattern = params["pattern"]
path = params.get("path", os.getcwd())
file_glob = params.get("file_glob", "")
cmd = ["grep", "-rn", "--include", file_glob, pattern, path] if file_glob else \
["grep", "-rn", pattern, path]
result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
if not result.stdout.strip():
return f"No se encontraron coincidencias para el patrón: {pattern}"
lines = result.stdout.strip().split("\n")
if len(lines) > 50:
return "\n".join(lines[:50]) + f"\n\n... ({len(lines) - 50} coincidencias más)"
return result.stdout
Gestión del contexto: el problema difícil
Por qué el contexto importa más que la ingeniería de prompts
El código fuente filtrado revela que Claude Code dedica más esfuerzo de ingeniería a la gestión del contexto que al propio prompt del sistema. El compresor de contexto (llamado internamente “wU2”) tiene cinco estrategias.
Para una construcción DIY, necesitas dos:
La autocompactación se activa cuando la conversación se acerca al límite de la ventana de contexto. Claude Code se activa aproximadamente al 92% de uso, reservando un búfer de 13,000 tokens para el propio resumen.
La reinyección de CLAUDE.md asegura que las directrices del proyecto no se desvíen durante sesiones largas. Claude Code reinjecta la configuración del proyecto en cada turno, no en la inicialización. Este es el patrón más impactante para mantener un agente de codificación en el camino correcto.
Construyendo un compresor simple
def maybe_compact(messages: list, system_prompt: str, max_tokens: int = 180000) -> list:
"""Compacta la conversación cuando se alarga demasiado."""
# Estimación aproximada: 4 caracteres por token
total_chars = sum(
len(str(m.get("content", ""))) for m in messages
)
estimated_tokens = total_chars // 4
if estimated_tokens < max_tokens * 0.85:
return messages # Aún no ha llegado al límite
# Pedir al modelo que resuma la conversación hasta ahora
summary_response = client.messages.create(
model=MODEL,
max_tokens=4096,
system="Resume esta conversación. Mantén todas las rutas de archivo, decisiones tomadas, errores encontrados y el estado actual de la tarea. Sé específico sobre qué se cambió y por qué.",
messages=messages,
)
summary_text = summary_response.content[0].text
# Reemplazar conversación con resumen + mensajes recientes
compacted = [
{"role": "user", "content": f"[Resumen de la conversación]\n{summary_text}"},
{"role": "assistant", "content": "Tengo el contexto de nuestra conversación anterior. ¿En qué debería trabajar ahora?"},
]
# Mantener los últimos 4 mensajes para contexto inmediato
compacted.extend(messages[-4:])
return compacted
Reinyectando el contexto del proyecto
Claude Code lee `.claude/CLAUDE.md` y lo inyecta en cada turno. Así es como se replica:
def build_system_prompt(project_dir: str) -> str:
"""Construye un prompt del sistema con reinyección del contexto del proyecto."""
base_prompt = """Eres un asistente de codificación que ayuda con tareas de ingeniería de software.
Tienes acceso a herramientas para leer, escribir, editar archivos, ejecutar comandos y buscar código.
Siempre lee los archivos antes de modificarlos. Prefiere edit_file sobre write_file para archivos existentes.
Mantén las respuestas concisas. Céntrate en el código, no en las explicaciones."""
# Buscar directrices del proyecto
claude_md_path = os.path.join(project_dir, ".claude", "CLAUDE.md")
if os.path.exists(claude_md_path):
with open(claude_md_path, "r") as f:
project_context = f.read()
base_prompt += f"\n\n# Directrices del proyecto\n{project_context}"
# También buscar un CLAUDE.md raíz
root_md = os.path.join(project_dir, "CLAUDE.md")
if os.path.exists(root_md):
with open(root_md, "r") as f:
root_context = f.read()
base_prompt += f"\n\n# Directrices del repositorio\n{root_context}"
return base_prompt
El sistema de memoria de tres capas
El código fuente filtrado muestra que Claude Code utiliza una arquitectura de memoria de tres niveles. Esta es una de las partes más subestimadas del sistema.
Capa 1: MEMORY.md (siempre cargado)
Un índice ligero que permanece en el prompt del sistema en todo momento. Cada entrada es una línea, de menos de 150 caracteres. Actúa como una tabla de contenido que apunta a un conocimiento más profundo. Limitado a 200 líneas / 25KB.
- [Preferencias de usuario](memory/user-prefs.md) - prefiere TypeScript, usa atajos de teclado de Vim
- [Convenciones de API](memory/api-conventions.md) - REST con especificación JSON:API, snake_case
- [Proceso de despliegue](memory/deploy.md) - usa Acciones de GitHub, despliega en AWS EKS
Capa 2: archivos de tema (cargados bajo demanda)
Archivos de conocimiento detallados cargados cuando el índice sugiere relevancia. Estos contienen convenciones del proyecto, decisiones arquitectónicas y patrones aprendidos.
Capa 3: transcripciones de sesión (buscadas, nunca leídas)
Registros completos de sesión que nunca se cargan por completo. El agente los busca con `grep` para identificadores específicos. Esto evita la sobrecarga del contexto mientras se mantiene la capacidad de búsqueda.
Construyendo un sistema de memoria mínimo
import json
MEMORY_DIR = ".agent/memory"
def load_memory_index() -> str:
"""Carga el índice de memoria para la inyección del prompt del sistema."""
index_path = os.path.join(MEMORY_DIR, "MEMORY.md")
if os.path.exists(index_path):
with open(index_path, "r") as f:
return f.read()
return ""
def save_memory(key: str, content: str, description: str):
"""Guarda una entrada de memoria y actualiza el índice."""
os.makedirs(MEMORY_DIR, exist_ok=True)
# Escribir el archivo de memoria
filename = f"{key.replace(' ', '-').lower()}.md"
filepath = os.path.join(MEMORY_DIR, filename)
with open(filepath, "w") as f:
f.write(f"---\nname: {key}\ndescription: {description}\n---\n\n{content}")
# Actualizar el índice
index_path = os.path.join(MEMORY_DIR, "MEMORY.md")
index_lines = []
if os.path.exists(index_path):
with open(index_path, "r") as f:
index_lines = f.readlines()
# Añadir o actualizar entrada
new_entry = f"- [{key}]({filename}) - {description}\n"
updated = False
for i, line in enumerate(index_lines):
if filename in line:
index_lines[i] = new_entry
updated = True
break
if not updated:
index_lines.append(new_entry)
with open(index_path, "w") as f:
f.writelines(index_lines)
Añade una herramienta `save_memory` a tu lista de herramientas para que el agente pueda persistir el conocimiento entre sesiones.
Añadiendo un sistema de permisos
La fuga revela cinco modos de permiso: `default` (prompts interactivos), `auto` (aprobación basada en ML), `bypass`, `yolo` (aprobar todo) y `deny`. Cada acción de herramienta se clasifica como de riesgo BAJO, MEDIO o ALTO.
Para un agente DIY, un sistema simple de tres niveles funciona:
# Niveles de riesgo para operaciones
RISK_LEVELS = {
"read_file": "bajo",
"search_code": "bajo",
"edit_file": "medio",
"write_file": "medio",
"run_command": "alto",
}
def check_permission(tool_name: str, params: dict, auto_approve_low: bool = True) -> bool:
"""Verifica si el usuario aprueba esta llamada a herramienta."""
risk = RISK_LEVELS.get(tool_name, "alto")
if risk == "bajo" and auto_approve_low:
return True
# Mostrar al usuario lo que está a punto de suceder
print(f"\n--- Verificación de permisos ({risk.upper()} riesgo) ---")
print(f"Herramienta: {tool_name}")
for key, value in params.items():
display = str(value)[:200]
print(f" {key}: {display}")
response = input("¿Permitir? [s/n/siempre]: ").strip().lower()
if response == "siempre":
RISK_LEVELS[tool_name] = "bajo" # Aprobar automáticamente esta herramienta en el futuro
return True
return response == "s"
Probando las llamadas API de tu agente con Apidog
Construir un agente de codificación significa realizar cientos de llamadas API a Claude. Depurar estas interacciones, especialmente conversaciones de múltiples turnos con uso de herramientas, es doloroso con registros en bruto.

Apidog te ayuda a inspeccionar y probar las solicitudes API exactas que envía tu agente. Así es como se usa durante el desarrollo:
Capturar y reproducir solicitudes API
Configura Apidog como un proxy para interceptar las llamadas de tu agente a la API de Anthropic:
- Abre Apidog y crea un nuevo proyecto para tu agente
- Importa el endpoint de la API de Mensajes de Anthropic: `POST https://api.anthropic.com/v1/messages`
- Configura el cuerpo de la solicitud con tu prompt del sistema, array de herramientas y mensajes
- Prueba turnos individuales reproduciendo solicitudes capturadas con parámetros modificados
Esto te permite aislar turnos específicos de uso de herramientas sin ejecutar el bucle completo del agente. Cuando el modelo devuelve una llamada a herramienta inesperada o un parámetro alucinado, puedes modificar el cuerpo de la solicitud en el editor visual de Apidog y reenviarla para ver cómo diferentes entradas cambian la respuesta.
Depurar conversaciones de múltiples turnos
La parte más difícil de la depuración de agentes es reproducir el estado de una conversación. Las variables de entorno de Apidog te permiten guardar instantáneas de conversaciones:
- Guarda el array completo de `messages` como una variable de entorno después de cada turno
- Reproducir desde cualquier punto de la conversación
- Comparar los resultados de las herramientas entre ejecuciones para encontrar dónde diverge el comportamiento
Validar esquemas de herramientas
Tus definiciones de herramientas (los esquemas JSON que pasas a la API) determinan lo que el modelo puede solicitar. Los esquemas mal formados causan fallos silenciosos donde el modelo omite una herramienta o pasa parámetros incorrectos.
Importa tus esquemas de herramientas en Apidog y usa su validador de esquemas JSON para detectar problemas antes de que lleguen a la API. Descarga Apidog para empezar a depurar las interacciones de la API de tu agente.
Poniéndolo todo junto: el REPL completo
Aquí tienes el agente completo unido como un REPL funcional:
#!/usr/bin/env python3
"""Un agente de codificación minimalista al estilo de Claude Code."""
import anthropic
import os
import sys
client = anthropic.Anthropic()
MODEL = "claude-sonnet-4-6"
PROJECT_DIR = os.getcwd()
def main():
system_prompt = build_system_prompt(PROJECT_DIR)
memory = load_memory_index()
if memory:
system_prompt += f"\n\n# Memoria\n{memory}"
messages = []
print("Agente de codificación listo. Escribe 'quit' para salir.\n")
while True:
user_input = input("> ").strip()
if user_input.lower() in ("quit", "exit"):
break
if not user_input:
continue
messages.append({"role": "user", "content": user_input})
# Compactar si es necesario
messages = maybe_compact(messages, system_prompt)
# Reinjectar contexto del proyecto (Claude Code lo hace en cada turno)
current_system = build_system_prompt(PROJECT_DIR)
memory = load_memory_index()
if memory:
current_system += f"\n\n# Memoria\n{memory}"
# Ejecutar el bucle del agente
result = agent_loop(current_system, TOOLS, messages)
print(f"\n{result}\n")
if __name__ == "__main__":
main()
Esto te proporciona un agente de codificación funcional en menos de 300 líneas de Python. Lee archivos, edita código, ejecuta comandos, busca en bases de código, gestiona el contexto y persiste la memoria entre sesiones.
Qué añadir a continuación
El código fuente filtrado revela varias características que vale la pena construir una vez que tu bucle principal funcione:
Sub-agentes para trabajo paralelo
Claude Code genera sub-agentes (llamados agentes “bifurcados”) para tareas independientes. El sub-agente obtiene una copia del contexto padre, ejecuta su tarea y devuelve un resultado. Esto evita contaminar la conversación principal con trabajo exploratorio.
El patrón: generar un nuevo `agent_loop()` con una descripción de tarea enfocada y un subconjunto de herramientas. Devolver el resultado como una cadena.
Deduplicación de lectura de archivos
Claude Code rastrea qué archivos se leyeron y sus tiempos de modificación. Si un archivo no ha cambiado desde la última lectura, omite la lectura y le dice al modelo “archivo sin cambios desde la última lectura”. Esto ahorra tokens en re-lecturas durante sesiones largas.
Truncamiento y muestreo de salida
Cuando una herramienta devuelve una salida masiva (por ejemplo, más de 10,000 líneas de resultados de grep), Claude Code la trunca y le dice al modelo cuántos resultados fueron omitidos. Sin esto, un resultado grande de una herramienta puede consumir toda tu ventana de contexto.
Autocompactación con reinyección de archivos
El compresor filtrado no descarta el contenido de los archivos. Después de resumir la conversación, reinjecta el contenido de los archivos accedidos recientemente (hasta 5,000 tokens por archivo). Esto significa que el modelo mantiene el conocimiento funcional de la base de código incluso después de la compactación.
Lo que aprendimos de la fuga
La fuga de Claude Code confirmó varios patrones que la comunidad de agentes de IA había teorizado:
El bucle principal es simple. Todo el patrón del agente cabe en 30 líneas. La complejidad reside en las herramientas y la gestión del contexto, no en la ingeniería de prompts.
Las herramientas dedicadas superan a bash. Las herramientas estructuradas y construidas para un propósito específico le dan al modelo una mejor densidad de información por token que la canalización de comandos bash.
La memoria necesita capas. Un índice siempre cargado, archivos de tema bajo demanda y transcripciones solo para grep equilibran la recuperación con los costos de contexto.
La gestión del contexto es el verdadero producto. La autocompactación, la reinyección de directrices del proyecto y el truncamiento de la salida son lo que hace viables las sesiones de codificación largas.
El arnés es el producto, no el modelo. El modelo proporciona inteligencia. El arnés proporciona percepción (lectura de archivos, búsqueda de código), acción (escritura de archivos, ejecución de comandos) y memoria. Construir un agente de codificación es construir el arnés.
Si quieres probar y depurar las interacciones de la API de tu agente personalizado, incluyendo conversaciones de uso de herramientas de múltiples turnos, esquemas de solicitud complejos y validación de respuestas, prueba Apidog gratis. Se encarga de la depuración de la API para que puedas centrarte en la lógica del agente.
Preguntas frecuentes
¿Puedo usar legalmente patrones de la fuga de Claude Code?
La fuga expuso patrones arquitectónicos, no algoritmos propietarios. Construir un agente de codificación que utilice un bucle `while` con despacho de herramientas es un patrón estándar documentado en la propia documentación de la API de Anthropic. No debes copiar el código de Anthropic textualmente, pero recrear la arquitectura con tu propio código es una práctica estándar.
¿Qué modelo debo usar para un agente de codificación DIY?
Claude Sonnet 4.6 ofrece el equilibrio adecuado de velocidad y capacidad para tareas de codificación. Claude Opus 4.6 produce mejores resultados en decisiones de arquitectura complejas, pero cuesta más y funciona más lento. Para ediciones y búsquedas de archivos simples, Claude Haiku 4.5 funciona y cuesta un 90% menos.
¿Cuánto cuesta ejecutar tu propio agente de codificación?
Una sesión de codificación típica (30-50 turnos) con Claude Sonnet 4.6 cuesta entre $1 y $5 en tarifas de API. El principal factor de costo es el tamaño de la ventana de contexto; una compactación agresiva mantiene los costos bajos. El código fuente filtrado de Claude Code muestra que activa la compactación al 92% del uso del contexto para controlar esto.
¿Por qué Claude Code usa React para una aplicación de terminal?
Ink (React para terminales) permite al equipo reutilizar el modelo de componentes de React y la gestión de estado para interacciones complejas de la interfaz de usuario, como diálogos de permisos, salida en streaming y visualizaciones de llamadas a herramientas. Para un proyecto DIY, un simple REPL de `input()` / `print()` es suficiente.
¿Cuál es la característica más importante a construir después del bucle principal?
El sistema de permisos. Sin él, el modelo puede sobrescribir archivos y ejecutar comandos arbitrarios sin supervisión del usuario. Incluso una simple puerta de “confirmar antes de escribir/ejecutar” previene la mayoría de los daños accidentales.
¿Cómo maneja Claude Code los errores de las llamadas a herramientas?
Los errores de las herramientas se devuelven como contenido de texto en el mensaje `tool_result`. El modelo ve el error y decide si reintentar, intentar un enfoque diferente o preguntar al usuario. No hay un manejo de errores especial; el razonamiento del modelo se encarga de la recuperación.
¿Puedo usar esto con modelos que no sean Claude?
Sí. El patrón de uso de herramientas funciona con cualquier modelo que admita la llamada a funciones: GPT-4, Gemini, Llama y otros. Necesitarás adaptar el formato de llamada API, pero el bucle del agente, las herramientas y el sistema de memoria son agnósticos al modelo.
¿Cómo evito que el agente ejecute comandos peligrosos?
Comienza con una lista negra de patrones peligrosos (`rm -rf /`, `mkfs`, etc.) y exige aprobación explícita para todas las llamadas a `run_command`. Claude Code clasifica cada operación como de riesgo BAJO, MEDIO o ALTO y bloquea o pide confirmación basándose en la clasificación. Construye lo mismo para tus herramientas.
