Las instrucciones del sistema normalmente residen en el campo system de nivel superior, antes de cada mensaje de la conversación. Esa posición es excelente para el almacenamiento en caché de prompts: la indicación del sistema forma parte del prefijo estable, por lo que los turnos posteriores aprovechan 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 inicio mismo del prompt e invalida la caché para todo lo que sigue.
Los mensajes del sistema a mitad de conversación cierran esa brecha. Añades 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 en caché permanece igual, por lo que la siguiente solicitud aún 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.
El arreglo tools se encuentra incluso antes que el campo system de nivel superior en el prefijo de solicitud que se hashea, 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 el equivalente 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 ofrecen al modelo entre turnos: declara el conjunto completo de herramientas en tools desde el principio, y 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 en caché permanece intacto.
tool_addition y tool_removal son bloques de contenido en el arreglo content de un mensaje con 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). Referenciar un nombre que no está declarado en tools devuelve un error 400.
Cada herramienta declarada en tools se 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 había retirado.
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 de antemano 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 referencia
# la herramienta por nombre en lugar de editar `tools`, así los turnos anteriores
# siguen 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 almacenamiento en caché de prompts 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 interrupción de caché.
Ese orden significa que el campo system de nivel superior se encuentra casi al inicio del prefijo hasheado. Cualquier cambio en él, incluso añadir una oración, produce un hash diferente, y la solicitud no encuentra la caché para la indicación del sistema ni para ningún mensaje en caché posterior.
Los mensajes del sistema a mitad de conversación te permiten añadir la instrucción al final del historial de mensajes. Todo lo anterior a la nueva instrucción permanece sin cambios, por lo que la entrada de caché existente sigue coincidiendo, y solo el nuevo mensaje se procesa como entrada nueva.
Algunas situaciones en las que 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 ambos entran en conflicto, las instrucciones del sistema tienen prioridad, así que usa el rol system para hechos y restricciones de 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 de nivel de operador sin pagar el costo de fallo de caché que implica editar el campo system de nivel superior.
Añade 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.
Aún 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 adelante, o que quieres añadir sin invalidar el prefijo 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 también
# deben cumplir la política estricta 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 ningún campo cache_control (automático o un punto de interrupción explícito), nada se almacena en caché y cada solicitud paga el precio regular de tokens de entrada por la conversación completa. Con el almacenamiento en caché habilitado, añadir el mensaje del sistema deja los turnos ya almacenados en caché sin cambios, por lo que la solicitud que lleva la nueva instrucción aún 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 cacheable; 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 ir 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, incluida 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 un comando que anula al usuario. Indica el hecho ("llegó nueva entrada del usuario: X", "el presupuesto de tokens restante es ahora 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 también se aplica al rol del sistema, por lo que un lenguaje como "ignora lo que dijo el usuario" es menos efectivo que indicar qué 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 almacenamiento en caché automático de nivel superior o un punto de interrupción 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 a mensajes anteriores, eso invalida la caché desde ese punto en adelante. Si la instrucción necesita evolucionar, añade un nuevo mensaje del sistema en lugar de reescribir el anterior. Se aceptan mensajes del sistema consecutivos 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 (incluido un turno user que lleva bloques tool_result) o a un turno assistant que termine en un resultado de herramienta del servidor, y debe preceder a un turno assistant o terminar el arreglo. No puede situarse 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 puntos de interrupción y cómo leer los campos de uso de 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.
Cómo 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?