Prácticas recomendadas para SDK de TypeScript/JavaScript
Una lista de verificación práctica para tipado, streaming, reintentos y despliegue en el borde con @anthropic-ai/sdk. Úsala al configurar una nueva integración o al revisar una existente para garantizar la seguridad de tipos y la preparación para producción.
Cómo usar esta lista
- Trabaja en cada grupo con letras en orden: primero la configuración, luego el tipado, y después las preocupaciones de tiempo de ejecución (streaming, reintentos, errores, despliegue).
- Trata cada elemento como una casilla de verificación durante la revisión de código, no solo como una lectura única.
- Revisa los grupos de reintentos/tiempos de espera y manejo de errores cada vez que agregues un nuevo sitio de llamada o muevas una función a un entorno de ejecución de borde (edge runtime).
- Empareja esta lista con la Referencia de tipos para bloques de contenido y la Referencia de clases de error para conocer los tipos exactos detrás de cada regla.
A - Configuración e Instalación
- Instala con
npm install @anthropic-ai/sdky fija una versión en producción. El SDK se basa enfetch, por lo que se ejecuta sin modificaciones en Node.js y en entornos de ejecución de borde (edge runtimes) como Vercel Edge, Cloudflare Workers y Deno Deploy. - Usa TypeScript 5 o superior. El SDK proporciona sus propios tipos, y los compiladores más antiguos pueden resolver incorrectamente las uniones discriminadas que exporta.
- Lee la clave de API desde una variable de entorno, nunca la codifiques. Establece
ANTHROPIC_API_KEYy deja que el cliente la recoja automáticamente. - Confirma el entorno de ejecución de destino antes de escribir código específico de la plataforma. Tanto los entornos Node como los de borde funcionan, pero solo Node tiene acceso a APIs exclusivas de Node; mantén el código de integración agnóstico al entorno de ejecución siempre que sea posible.
B - Seguridad de tipos sobre any
- Usa los tipos exportados por el SDK en lugar de interfaces creadas manualmente. Tipar las solicitudes y respuestas tú mismo provoca desviaciones en el momento en que el SDK agrega un campo.
- Estrecha los bloques de contenido por
.typeantes de tocar campos específicos del bloque.TextBlock,ToolUseBlockyThinkingBlockson una unión discriminada; unswitchoifsobre.typees lo que hace que los campos más estrechos sean seguros para acceder. - Nunca hagas un
castde la entrada (input) de un bloquetool_useaany. Analízala a través del mismo esquema que usaste para definir la herramienta, de modo que una entrada mal formada falle una verificación en tiempo de ejecución en lugar de pasar silenciosamente. - Deja que la inferencia transmita los tipos de contenido de mensajes a través de tus propias funciones. Volver a tipar
MessageParamoContentBlockmanualmente es una fuente común de errores de tipo que solo aparecen en el sitio de llamada, no en la definición.
C - Streaming con iteradores asíncronos
- Consume respuestas transmitidas con un bucle
for await, no con listeners de eventos manuales.client.messages.stream()devuelve un iterable asíncrono; iterar sobre él es más fácil de leer y más fácil de cancelar que configurar manejadores.on(). - Sal del bucle limpiamente cuando tengas lo que necesitas. Un bucle
for awaitsale y se limpia conbreak, lo cual es más predecible que desmantelar múltiples listeners de eventos manualmente. - Llama a
stream.finalMessage()cuando necesites la respuesta completamente ensamblada. Usa esto después del bucle cuando tu UI quiera tanto los deltas token a token como el mensaje combinado final.
D - Definiciones de herramientas basadas en Zod
- Define esquemas de entrada de herramientas como objetos Zod y genera JSON Schema a partir de ellos. Esto mantiene una única fuente de verdad en lugar de mantener un JSON Schema escrito a mano junto con un tipo TypeScript escrito a mano.
- Reutiliza el mismo esquema Zod para validar
tool_use.inputen tiempo de ejecución. El tipo de compilación y la verificación en tiempo de ejecución provienen de la misma definición, por lo que no pueden divergir. - Mantén los esquemas de herramientas pequeños y de propósito único. Un objeto Zod de alcance limitado es más fácil de validar correctamente y más fácil de completar con precisión por el modelo.
E - Reintentos, Tiempos de espera y Cancelación
- Establece
timeouten milisegundos, no en segundos. La opcióntimeoutdel SDK de TypeScript está en milisegundos, a diferencia de los SDK de Python y Ruby, que usan segundos; mezclar esto produce silenciosamente un tiempo de espera que es 1000 veces demasiado corto o demasiado largo. - Configura los reintentos deliberadamente en lugar de aceptar un valor predeterminado en todas partes. Establece
maxRetriesa nivel de cliente para llamadas típicas, y anúlalo por solicitud para llamadas que son costosas de repetir. - Conecta un
AbortControllera cualquier solicitud que el usuario pueda cancelar. Pasar susignala una solicitud te permite cancelar llamadas en curso de forma limpia, y funciona de la misma manera en Node y en el navegador. - Establece anulaciones de tiempo de espera y reintento por solicitud para llamadas de larga duración o de streaming. Una única configuración global del cliente rara vez se adapta tanto a una llamada de clasificación rápida como a una respuesta transmitida larga.
F - Manejo de errores tipificado
- Captura primero la clase de error más específica. Verifica
BadRequestError,RateLimitErrory clases específicas similares antes de recurrir aAPIErrorbase. - Verifica
APIConnectionErrorantes de la verificación base deAPIError.APIConnectionErrores una subclase deAPIErroren el SDK de TypeScript, por lo que un bloquecatchque verifica la clase base primero tragará errores de conexión en la rama incorrecta. - Usa verificaciones
instanceofcontra las clases de error del SDK, no coincidencias de cadenas enerror.message. Esto le da al bloquecatchacceso tipificado a campos como.statusy.erroren lugar de analizar texto libre. - Registra el nombre de la clase de error junto con el mensaje. Al investigar incidentes, saber si un fallo fue
RateLimitErroren lugar deAPIConnectionErrorcambia la solución.
G - Despliegue en entorno de ejecución de borde
- Despliega en Vercel Edge, Cloudflare Workers o Deno Deploy sin un shim de compatibilidad. El cliente se basa en
fetch, por lo que funciona en estos entornos de ejecución de la misma manera que funciona en Node. - Conecta
client.messages.stream()a un manejador de rutas para UIs de chat token a token. Este es el patrón común para un endpoint de chat de streaming de Next.js: el manejador de rutas transmite los deltas directamente al cliente. - Mantén
ANTHROPIC_API_KEYsolo en el lado del servidor. Las funciones de borde todavía se ejecutan en el servidor; nunca envíes la clave a un paquete del cliente ni la expongas a través de un endpoint público sin una capa de proxy delante. - Prueba el comportamiento de arranque en frío en tu plataforma de borde elegida antes de confiar en ella para endpoints sensibles a la latencia. Los entornos de ejecución de borde intercambian algunas APIs exclusivas de Node por arranques en frío más rápidos; confirma que el intercambio funciona para tu patrón de tráfico.
Preguntas frecuentes
¿Por qué la unidad de tiempo de espera importa tanto?
El timeout del SDK de TypeScript son milisegundos. Si copias un valor de la documentación de Python o Ruby (segundos) sin convertir, las solicitudes expiran casi inmediatamente o, en la práctica, nunca expiran.
¿Necesito Zod, o puedo escribir JSON Schema manualmente para las herramientas?
El JSON Schema escrito a mano funciona, pero con el tiempo se desvía de tus tipos de TypeScript. Generar el esquema a partir de un objeto Zod mantiene la validación y el tipado sincronizados a partir de una sola definición.
¿Cuál es la diferencia entre `APIConnectionError` y `APIError`?
APIConnectionError es una subclase de APIError en el SDK de TypeScript. Verifícala primero en un bloque catch, o una verificación base de APIError la capturará antes de que se ejecute tu manejo más específico.
¿Puedo usar `for await` y listeners de eventos juntos?
Puedes, pero rara vez es necesario. El iterador asíncrono ya expone cada delta en orden, por lo que un bucle for await cubre la mayoría de las necesidades de streaming sin cableado de eventos adicional.
¿Es seguro usar el SDK directamente en un navegador?
Técnicamente funciona, pero enviar ANTHROPIC_API_KEY a un paquete del navegador lo expone. Mantén las llamadas a la API detrás de una ruta del servidor o una función de borde, y solo envía la transmisión resultante al navegador.
¿Por qué evitar hacer `cast` de `tool_use.input` a `any`?
El modelo puede devolver entradas mal formadas o inesperadas. Analizarlas a través del mismo esquema Zod utilizado para definir la herramienta las detecta en tiempo de ejecución en lugar de permitir que un valor incorrecto fluya silenciosamente a la lógica de tu aplicación.
¿Qué sucede si no establezco `maxRetries`?
El SDK aplica una política de reintentos predeterminada. Es razonable para la mayoría de las llamadas, pero las llamadas costosas o con efectos secundarios (como las que activan una acción de pago posterior) a menudo justifican un valor más bajo o un manejo explícito de idempotencia.
¿Debería cada solicitud pasar una señal `AbortController`?
No todas las solicitudes la necesitan, pero cualquier solicitud de la que un usuario pueda alejarse o cancelar (un mensaje de chat, una llamada de herramienta larga) debería tenerla, para que no pagues ni esperes por un trabajo que ya nadie necesita.
¿Qué grupo debería revisar primero al revisar una integración existente?
Comienza con el grupo F (manejo de errores tipificado) y el grupo E (reintentos/tiempos de espera). Los problemas de tipado generalmente solo causan ruido en el compilador; el manejo de errores omitido y las unidades de tiempo de espera incorrectas causan incidentes en producción.
¿Los entornos de ejecución de borde admiten el streaming de la misma manera que Node?
Sí. Dado que el cliente se basa en fetch, client.messages.stream() se comporta de la misma manera en Vercel Edge, Cloudflare Workers y Deno Deploy que en Node.
¿Por qué estrechar los bloques de contenido por `.type` en lugar de verificar la existencia de un campo?
Verificar la existencia de un campo (como block.input) puede ser verdadero para más de un tipo de bloque en el futuro a medida que la unión crece. Estrechar por el campo discriminatorio .type es lo que el análisis de flujo de control de TypeScript realmente entiende.
¿Cuál es el error más común que cometen los equipos con este SDK?
Mezclar la unidad de tiempo de espera (segundos frente a milisegundos) y verificar APIError antes de APIConnectionError en un bloque catch son los dos más comunes, ambos porque son silenciosos hasta que algo sale mal en producción.
Relacionados
- Conceptos básicos del SDK de TypeScript/JavaScript - instala y envía tu primera llamada tipificada
- El modelo mental del SDK de TypeScript de Anthropic - cómo encajan el streaming, el tipado y los errores
- Referencia de tipos del SDK de TypeScript para bloques de contenido - la unión discriminada en detalle
- Referencia de clases de error del SDK de TypeScript - la jerarquía completa de clases de error
- Patrones de reintentos, tiempos de espera y AbortController en el SDK de TypeScript - cobertura más profunda del grupo E
- Creación de un endpoint de chat de streaming con Next.js y el SDK de TypeScript - el patrón detrás del grupo G
Versiones de pila: Escrito contra la línea de modelos Claude actual a partir de ~junio de 2026 - Claude Fable 5, Claude Opus 4.8, Claude Sonnet 5 (el predeterminado), y Claude Haiku 4.5 - y el SDK oficial de TypeScript
@anthropic-ai/sdk(última versión). Los nombres de los modelos, las versiones del SDK y los precios cambian rápidamente; verifica los detalles actuales en platform.claude.com/docs antes de confiar en ellos.