Comprender los roles y los turnos en la API de Mensajes
Cada solicitud a la API de Mensajes de Claude se construye a partir de dos ingredientes: un prompt del sistema y una lista de mensajes.
El prompt del sistema prepara el escenario una vez, en el nivel superior de la solicitud.
La lista de mensajes es donde vive la conversación real, y sigue una estructura estricta: un turno de user, luego un turno de assistant, luego user de nuevo, y así sucesivamente.
Comprender esta estructura alternante es el modelo mental más importante para trabajar con la API, porque casi todos los errores en una integración de la API de Mensajes se remontan a una incomprensión de los roles y los turnos.
Resumen
- Idea central: Una conversación es un array de
messagesde turnos estrictamente alternantes deuseryassistant, más un promptsystemseparado de nivel superior que no forma parte de ese array. - Por qué importa: La API valida el orden de los turnos y la alternancia de roles; si se equivoca, la solicitud falla antes de que Claude la vea.
- Conceptos clave: role (rol), turn (turno), system prompt (prompt del sistema), conversation state (estado de la conversación), statelessness (ausencia de estado).
- Cuándo usarlo: Cada vez que envíe una solicitud a
client.messages.create(), ya sea una sola pregunta o una larga conversación de ida y vuelta. - Limitaciones / Compensaciones: La API en sí misma no recuerda nada entre solicitudes; la estructura alternante es un contrato que usted mismo debe cumplir en cada llamada.
- Temas relacionados: el array de mensajes como estado de la conversación, tipos de bloques de contenido, formato del prompt del sistema.
Fundamentos
Un rol es una etiqueta en cada entrada del array messages que indica quién está "hablando" en ese turno.
Hay dos roles que usted envía: user, que representa la entrada de una persona o su aplicación, y assistant, que representa las respuestas previas de Claude.
Un turno es una entrada completa en el array, etiquetada con un rol y que contiene contenido.
El prompt del sistema es un concepto completamente separado: es un parámetro system de nivel superior en la solicitud, no un mensaje con un rol, y establece la persona, las restricciones o el formato de salida para toda la conversación en lugar de representar un intercambio de ida y vuelta.
Aquí está la solicitud más pequeña posible, que muestra dónde encajan los roles y los turnos:
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-opus-4-8",
max_tokens=1024,
system="Eres un asistente conciso y amigable.",
messages=[
{"role": "user", "content": "¿Cuál es la capital de Francia?"},
],
)Observe que system está completamente fuera de messages.
El array messages aquí tiene exactamente un turno, con el rol user.
Esa es la forma válida más simple: un solo turno de usuario, sin turnos de asistente todavía, porque Claude aún no ha respondido.
Mecánica e Interacciones
La API aplica una regla estricta de alternancia al array messages: el primer mensaje debe tener el rol user, y los roles deben alternar estrictamente a partir de ahí.
No puede enviar dos turnos user seguidos, y no puede enviar un turno assistant como la primera entrada.
Si viola esto, la solicitud falla con un error 400 antes de que ocurra cualquier inferencia del modelo: la validación es puramente estructural, comprobada contra la forma del array, no contra el contenido dentro de él.
Un segundo detalle, fácil de pasar por alto, es que la API no tiene estado.
Claude no recuerda su solicitud anterior la próxima vez que llame al endpoint.
Cada solicitud se evalúa de forma independiente, utilizando solo lo que hay en el array messages de esa solicitud.
Esto significa que después de que Claude responda, si desea continuar la conversación, debe agregar la respuesta de Claude como un nuevo turno assistant y luego agregar su próxima pregunta como un nuevo turno user, todo en el mismo array, enviado nuevamente en la próxima llamada.
Solicitud 1: system: "..."
messages: [ user: "¿Cuál es la capital de Francia?" ]
-> respuesta: respuesta del assistant ("París.")
Solicitud 2: system: "..." (mismo prompt del sistema)
messages: [ user: "¿Cuál es la capital de Francia?",
assistant: "París.", (respuesta previa de Claude, ahora en el array)
user: "¿Cuál es su población?" ] (nueva pregunta)
-> respuesta: respuesta del assistant, consciente de "París" por el contextoCada solicitud lleva todo el historial hasta el momento.
El array crece en dos entradas por cada viaje de ida y vuelta: una entrada assistant agregada de la respuesta anterior y una nueva entrada user con su próxima entrada.
Es por eso que el modelo mental es tan importante: si piensa en la API como si "recordara" la conversación, se sorprenderá cuando Claude no tenga idea de qué hablaron hace un momento.
La verdad se acerca más a entregarle a Claude una transcripción desde cero en cada llamada, y la transcripción solo es tan completa como lo que usted elija reenviar.
Consideraciones y Aplicaciones Avanzadas
Una sutileza que vale la pena internalizar temprano: el content de un turno no tiene que ser una cadena única.
Puede ser una lista de bloques de contenido, y esos bloques pueden ser de diferentes tipos: text, image, tool_use o tool_result, mezclados dentro de un turno.
Un turno user que responde a una llamada a una herramienta, por ejemplo, típicamente lleva un bloque tool_result en lugar de texto plano.
Un turno assistant que decide llamar a una herramienta lleva un bloque tool_use en lugar de, o junto con, texto.
La regla de alternancia de rol/turno sigue aplicándose independientemente de los tipos de contenido que haya dentro de cada turno: la alternancia se trata de la etiqueta del rol, no de la forma del contenido.
| Enfoque | Fortaleza | Debilidad | Mejor ajuste |
|---|---|---|---|
| Contenido de cadena simple | Más fácil de leer y escribir | No puede mezclar tipos de contenido en un turno | Intercambios simples solo de texto |
| Lista de bloques de contenido | Admite texto, imágenes, tool_use, tool_result juntos | Más verboso, requiere comprender los tipos de bloque | Visión, uso de herramientas o cualquier turno de contenido mixto |
La otra consecuencia de la ausencia de estado que vale la pena planificar desde el principio es el costo y el crecimiento del contexto: dado que reenvía todo el historial cada vez, una conversación larga significa un cuerpo de solicitud creciente y un uso de tokens creciente en cada llamada, incluso aunque la mayor parte del contenido sea idéntico a la llamada anterior.
Ese crecimiento es manejable para intercambios cortos y se convierte en una preocupación de diseño real para conversaciones de larga duración, que es un tema que se cubre por sí solo en otra parte de esta sección.
Conceptos erróneos comunes
- "Claude recuerda nuestra conversación anterior automáticamente." No lo hace: la API de Mensajes no tiene memoria del lado del servidor. Cada respuesta que Claude da se basa únicamente en lo que usted incluye en el array
messagesde esa solicitud. - "El prompt del sistema es solo el primer turno del usuario." Es un parámetro de nivel superior genuinamente separado, no forma parte del array
messagesalternante, y no está sujeto a la regla de alternancia de roles en absoluto. - "Puedo enviar dos mensajes de usuario seguidos si tengo dos cosas que decir." No puede enviarlos como dos entradas de array separadas con el rol
user: combínelos en el contenido de un solo turnouser, o espere un turnoassistanten medio. - "Los turnos y los bloques de contenido son lo mismo." Un turno es la entrada etiquetada con rol en
messages; un bloque de contenido es una pieza del contenido de ese turno. Un turno puede contener varios bloques de diferentes tipos.
Preguntas frecuentes
¿Cuáles son los únicos dos roles permitidos en el array de mensajes?
user y assistant. El prompt del sistema se configura por separado a través del parámetro system de nivel superior, no como un rol dentro de messages.
¿Necesita el array de mensajes comenzar con un turno de usuario?
Sí. La primera entrada debe tener el rol user, y los roles deben alternar estrictamente user, assistant, user, assistant, y así sucesivamente a partir de ahí.
¿Qué sucede si envío dos turnos consecutivos con el mismo rol?
La API rechaza la solicitud con un error 400 antes de ejecutar la inferencia, porque la secuencia de roles viola la alternancia requerida.
¿Claude recuerda lo que dije en una llamada API anterior?
No. La API de Mensajes no tiene estado en el lado del servidor. Claude solo "recuerda" lo que se incluye en el array messages de la solicitud actual, por lo que reenvía los turnos anteriores en cada llamada.
¿Dónde encaja el prompt del sistema en relación con el array de mensajes?
Es un parámetro system de nivel superior separado en la solicitud, no un turno dentro de messages. Se aplica a toda la conversación en lugar de representar un lado de un intercambio.
¿Puede un solo turno contener más que texto plano?
Sí. El content de un turno puede ser una lista de bloques de contenido: text, image, tool_use o tool_result, y un solo turno puede mezclar varios tipos de bloques.
Si quiero continuar una conversación, ¿qué agrego exactamente al array?
Agregue la respuesta previa de Claude como un nuevo turno assistant, luego agregue su próxima entrada como un nuevo turno user, y envíe todo el array nuevamente en su próxima solicitud.
¿Hay un costo de rendimiento por reenviar toda la conversación cada vez?
Sí, dado que cada solicitud lleva todo el historial, tanto el tamaño de la solicitud como el uso de tokens crecen a medida que una conversación se alarga, a pesar de que la mayor parte del contenido no cambia respecto a la llamada anterior.
¿Puede un turno de asistente ser la primera entrada en el array de mensajes?
No. El array debe comenzar con un turno user. Enviar un turno assistant primero es una violación estructural y la solicitud falla la validación.
¿La alternancia de roles se verifica según el contenido del mensaje o la estructura del mensaje?
Es puramente estructural: la API verifica la secuencia de etiquetas de role en el array, independientemente de los tipos de contenido o el texto que esos turnos contengan realmente.
¿Por qué un turno de asistente a veces contiene un bloque `tool_use` en lugar de texto?
Cuando Claude decide llamar a una herramienta, expresa esa decisión como un bloque de contenido tool_use dentro de su turno assistant, en lugar de (o junto con) una respuesta de texto plano.
¿Bajo qué rol se devuelve un resultado de herramienta?
Los resultados de las herramientas se devuelven como un bloque de contenido tool_result dentro de un turno user; la regla de alternancia de roles aún se aplica, por lo que esto sigue al turno assistant anterior que solicitó la herramienta.
Relacionados
- Fundamentos de la API de Mensajes - envíe su primera solicitud de varios turnos de principio a fin.
- Construcción de conversaciones de varios turnos con el array de mensajes - la mecánica de reenviar el historial en cada llamada.
- Referencia de roles y tipos de bloques de contenido de la API de Mensajes - una tabla de referencia de cada tipo de bloque de contenido.
- Formateo de prompts del sistema para un comportamiento consistente de Claude - cómo escribir bien el parámetro del sistema separado.
Versiones de Stack: Escrito contra la línea de modelos de 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
anthropicde Python (última versión 0.x). Los nombres de los modelos, las versiones del SDK y los precios cambian rápidamente; verifique los detalles actuales en platform.claude.com/docs antes de confiar en ellos.