Para saber cómo se aplica la retención cero de datos (ZDR) a esta función, consulta API y retención de datos.
Las instrucciones del sistema normalmente viven en el campo system de nivel superior, antes de cada mensaje de la conversación. Esa posición es excelente para el prompt caching (almacenamiento en caché de prompts): la indicación del sistema forma parte del prefijo estable, por lo que los turnos posteriores aciertan en la caché. Es una mala posición para instrucciones que solo descubres que necesitas a mitad de una sesión, porque editar el campo system de nivel superior cambia el comienzo mismo del prompt e invalida la caché para todo lo que sigue.
Los mensajes del sistema a mitad de conversación cierran esa brecha. Agregas un mensaje {"role": "system"} en el punto de la conversación donde la nueva instrucción se vuelve relevante, en lugar de editar el campo system de nivel superior. El prefijo almacenado en caché permanece igual, por lo que la siguiente solicitud todavía lo lee desde la caché, y la nueva instrucción se sigue aplicando como una instrucción del sistema en lugar de como texto ordinario del usuario.
Esta página cubre dos funcionalidades: los mensajes del sistema a mitad de conversación, que están disponibles de forma general, y los cambios de herramientas a mitad de conversación, una beta introducida con Claude Opus 5 que aplica el mismo enfoque al arreglo tools.
Los mensajes del sistema a mitad de conversación están disponibles en la API de Claude, Claude in Amazon Bedrock y Google Cloud.
Esta funcionalidad está disponible en Claude Fable 5, Claude Mythos 5, Claude Opus 4.8 y Claude Opus 5. No se requiere ningún encabezado beta para los mensajes del sistema a mitad de conversación. Esta funcionalidad no está disponible en Claude Sonnet 5; usa el campo system de nivel superior en su lugar.
Los cambios de herramientas a mitad de conversación están en beta y requieren el encabezado beta mid-conversation-tool-changes-2026-07-01. Están disponibles en Claude Fable 5, Claude Mythos 5, Claude Opus 4.8 y Claude Opus 5, en la API de Claude, Amazon Bedrock y Google Cloud.
El arreglo tools se encuentra incluso antes en el prefijo hasheado de la solicitud que el campo system de nivel superior, por lo que editarlo invalida la caché de prompts para toda la conversación. Los cambios de herramientas a mitad de conversación, una beta introducida con Claude Opus 5, son la contraparte para herramientas de los mensajes del sistema a mitad de conversación. En lugar de fijar la lista de herramientas durante toda la vida de la conversación, cambias qué herramientas se le ofrecen al modelo entre turnos: declara el conjunto completo de herramientas en tools desde el principio, luego usa bloques tool_addition y tool_removal para ofrecer una herramienta al modelo, o retirarla, desde un punto específico de la conversación en adelante. El arreglo tools en sí nunca cambia, por lo que el prefijo almacenado en caché permanece intacto.
tool_addition y tool_removal son bloques de contenido en el arreglo content de un mensaje role: "system", y pueden mezclarse con bloques text en el mismo mensaje. El mensaje sigue las mismas reglas de ubicación que cualquier mensaje del sistema a mitad de conversación (consulta Limitaciones), y el cambio se aplica desde ese punto de la conversación en adelante. El campo tool de cada bloque hace referencia a una herramienta en lugar de definirla: {"type": "tool_reference", "name": "..."} nombra una herramienta declarada en el arreglo tools de la solicitud, y las herramientas del conector MCP pueden referenciarse individualmente con mcp_tool_reference (server_name y name) o como un conjunto completo de herramientas con mcp_toolset_reference (server_name). Hacer referencia a un nombre que no está declarado en tools devuelve un error 400.
Cada herramienta declarada en tools se le ofrece al modelo desde el inicio de la conversación a menos que se declare con defer_loading: true, lo que la mantiene retenida hasta que un bloque tool_addition la haga aparecer. tool_addition también vuelve a ofrecer una herramienta que un tool_removal anterior retiró.
client = anthropic.Anthropic()
response = client.beta.messages.create(
model="claude-opus-5",
max_tokens=1024,
betas=["mid-conversation-tool-changes-2026-07-01"],
# El conjunto completo de herramientas se declara desde el inicio y nunca cambia, por lo que
# el prefijo en caché permanece intacto.
tools=[
{
"name": "get_weather",
"description": "Get the current weather for a location.",
"input_schema": {
"type": "object",
"properties": {
"location": {"type": "string", "description": "City name"},
},
"required": ["location"],
},
},
],
messages=[
{
"role": "user",
"content": "Say OK.",
},
# Retira get_weather de este punto en adelante. El bloque hace referencia
# a la herramienta por su nombre en lugar de editar `tools`, así que los turnos anteriores
# permanecen idénticos byte a byte y la caché sigue acertando.
{
"role": "system",
"content": [
{
"type": "tool_removal",
"tool": {"type": "tool_reference", "name": "get_weather"},
},
],
},
],
)
for block in response.content:
if block.type == "text":
print(block.text)Los cambios de herramientas a mitad de conversación están en beta. Para usarlos, incluye el encabezado beta mid-conversation-tool-changes-2026-07-01 en tus solicitudes. Están disponibles en Claude Fable 5, Claude Mythos 5, Claude Opus 4.8 y Claude Opus 5, en la API de Claude, Amazon Bedrock y Google Cloud.
El prompt caching hashea el prefijo de la solicitud en orden: tools, luego system, luego messages. Un acierto de caché requiere que el prefijo coincida exactamente con una solicitud reciente, byte por byte, hasta el punto de corte de la caché.
Ese orden significa que el campo system de nivel superior se encuentra cerca del inicio mismo del prefijo hasheado. Cualquier cambio en él, incluso agregar una oración, produce un hash diferente, y la solicitud falla la caché para la indicación del sistema y cada mensaje almacenado en caché después de ella.
Los mensajes del sistema a mitad de conversación te permiten agregar la instrucción al final del historial de mensajes en su lugar. Todo lo anterior a la nueva instrucción permanece sin cambios, por lo que la entrada de caché existente todavía coincide, y solo el nuevo mensaje se procesa como entrada nueva.
Algunas situaciones donde esto importa:
system de nivel superior volvería a procesar todo el historial.En todos estos casos podrías poner la instrucción en un mensaje user normal, y Claude sí sigue las instrucciones que llegan en turnos de usuario. La diferencia es la prioridad: un mensaje user se trata como proveniente del usuario final, mientras que un mensaje system se trata como proveniente de ti, el operador de la aplicación. Cuando los dos entran en conflicto, las instrucciones del sistema tienen prioridad, así que usa el rol system para hechos y restricciones a nivel de operador que deben mantenerse incluso si el usuario final pide algo diferente. Un mensaje del sistema a mitad de conversación mantiene esa prioridad a nivel de operador sin pagar el costo del fallo de caché de editar el campo system de nivel superior.
Agrega un mensaje con "role": "system" al arreglo messages. Usa una cadena simple o bloques de contenido para content, igual que en un turno user o assistant. La instrucción se aplica desde ese punto de la conversación en adelante. Cuando las instrucciones entran en conflicto, los mensajes del sistema posteriores tienen prioridad sobre los anteriores, y los mensajes del sistema a mitad de conversación tienen prioridad sobre el campo system de nivel superior para los turnos que los siguen.
Todavía puedes establecer el campo system de nivel superior para instrucciones que deben aplicarse a toda la conversación. Reserva los mensajes del sistema a mitad de conversación para instrucciones que solo se vuelven relevantes más tarde, o que quieres agregar sin invalidar el prefijo almacenado en caché.
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-opus-5",
max_tokens=1024,
# Almacenamiento en caché de prompts automático: cada solicitud almacena en caché la conversación hasta el momento,
# y la siguiente solicitud lee el prefijo sin cambios desde la caché.
cache_control={"type": "ephemeral"},
system="You are a code review assistant. Be concise.",
messages=[
{
"role": "user",
"content": "Review process() in utils.py for performance issues.",
},
{
"role": "assistant",
"content": "The list comprehension is fine for small inputs. For large inputs, consider a generator to avoid materializing the full list.",
},
{
"role": "user",
"content": "Now review the calling code that invokes process().",
},
# El revisor se da cuenta a mitad de la sesión de que todas las sugerencias deben
# cumplir también la estricta política de tipado del equipo. Agregar la
# instrucción aquí mantiene los turnos anteriores idénticos byte a byte, por lo que el
# prefijo almacenado en caché por la solicitud anterior aún se lee desde la caché.
{
"role": "system",
"content": "From now on, every suggestion must include explicit type annotations.",
},
],
)
for block in response.content:
if block.type == "text":
print(block.text)Este ejemplo habilita el almacenamiento en caché automático con el campo cache_control de nivel superior. El almacenamiento en caché de prompts es opcional: si una solicitud no tiene un campo cache_control (automático o un punto de corte explícito), no se almacena nada en caché y cada solicitud paga el precio regular de tokens de entrada por la conversación completa. Con el almacenamiento en caché habilitado, agregar el mensaje del sistema deja los turnos ya almacenados en caché sin cambios, por lo que la solicitud que lleva la nueva instrucción todavía los lee desde la caché en lugar de procesarlos de nuevo. El almacenamiento en caché también requiere que la conversación cumpla con la longitud mínima de prompt almacenable en caché; un ejemplo tan corto como este queda por debajo de ella, por lo que cache_creation_input_tokens y cache_read_input_tokens permanecen en 0 hasta que la conversación crezca.
Un mensaje del sistema a mitad de conversación debe seguir inmediatamente a un turno user (o a un turno assistant que termine en un resultado de herramienta del servidor), y debe ser la última entrada en messages o estar seguido inmediatamente por un turno assistant. Un mensaje user que lleva bloques tool_result cuenta: en un bucle agéntico puedes colocar el mensaje del sistema justo después de los resultados de herramientas, antes del siguiente turno de Claude. Cualquier otra posición, incluyendo entre un bloque tool_use de assistant y el tool_result que lo responde, devuelve un error 400.
En un bucle agéntico, el mensaje del sistema va después del mensaje user que entrega los resultados de herramientas. Aquí es también donde tu aplicación puede transmitir la entrada que el usuario escribió mientras Claude estaba trabajando, de modo que el nuevo contexto se absorba sin reiniciar el turno:
[
{ "role": "user", "content": "Run the test suite and fix any failures." },
{
"role": "assistant",
"content": [{ "type": "tool_use", "id": "toolu_01", "name": "run_tests", "input": {} }]
},
{
"role": "user",
"content": [
{ "type": "tool_result", "tool_use_id": "toolu_01", "content": "12 passed, 0 failed" }
]
},
{
"role": "system",
"content": "The user sent the following message while you were working: also update the changelog before you finish."
}
]Redacta el contenido del sistema como contexto en lugar de como una orden que anula al usuario. Enuncia el hecho ("llegó nueva entrada del usuario: X", "el presupuesto de tokens restante ahora es Y") y deja que Claude actúe en consecuencia. Claude está entrenado para resistir instrucciones que parecen ir en contra del usuario, y esa protección todavía se aplica al rol de sistema, por lo que un lenguaje como "ignora lo que dijo el usuario" es menos efectivo que enunciar lo que cambió.
Este patrón es para transmitir entrada del propio usuario final de la conversación. No lo uses para pasar salida de herramientas, documentos recuperados u otro contenido de terceros; mantén ese contenido en bloques tool_result (consulta Limitaciones).
Los mensajes del sistema a mitad de conversación y el almacenamiento en caché de prompts están diseñados para usarse juntos:
cache_control, ya sea el campo de nivel superior de almacenamiento en caché automático o un punto de corte explícito en un bloque de contenido. Un mensaje del sistema a mitad de conversación no crea una entrada de caché por sí solo, y sin el almacenamiento en caché habilitado no hay ahorros que preservar.cache_control en el último bloque que permanece igual entre solicitudes, ya sea el final del campo system de nivel superior, el final de tus definiciones de herramientas o un punto estable en el historial de mensajes.Evita editar o eliminar un mensaje del sistema a mitad de conversación que ya se haya enviado. Como cualquier otro cambio en mensajes anteriores, eso invalida la caché desde ese punto en adelante. Si la instrucción necesita evolucionar, agrega un nuevo mensaje del sistema en lugar de reescribir el anterior. Los mensajes del sistema consecutivos se aceptan y se tratan como una sola sección del sistema, que sigue la misma regla de ubicación en su conjunto.
system no puede ser la primera entrada en messages. Usa el campo system de nivel superior para instrucciones que se aplican desde el principio.system debe seguir inmediatamente a un turno user (incluyendo un turno user que lleva bloques tool_result) o a un turno assistant que termina en un resultado de herramienta del servidor, y debe preceder a un turno assistant o terminar el arreglo. No puede ubicarse entre un bloque tool_use y su tool_result. Colocarlo en otro lugar devuelve un error 400.tool_result y continúa siguiendo Mitigar jailbreaks e inyecciones de prompts.Cómo funciona el almacenamiento en caché, dónde colocar los puntos de corte y cómo leer los campos de uso de la caché.
Descubre exactamente dónde divergieron dos solicitudes cuando un acierto de caché que esperabas no ocurre.
Estructura de mensajes, conversaciones de múltiples turnos y el campo system.
Escribir prompts e instrucciones del sistema efectivos.
Cómo se estructuran los bloques tool_use y tool_result en el arreglo messages.
Was this page helpful?