Системные инструкции обычно находятся в поле system верхнего уровня, перед всеми сообщениями в разговоре. Эта позиция отлично подходит для кэширования подсказок: системная подсказка является частью стабильного префикса, поэтому последующие ходы попадают в кэш. Однако эта позиция плохо подходит для инструкций, необходимость в которых вы обнаруживаете только в середине сессии, поскольку редактирование поля system верхнего уровня изменяет самое начало подсказки и аннулирует кэш для всего, что следует за ним.
Системные сообщения в середине разговора устраняют этот пробел. Вы добавляете сообщение {"role": "system"} в ту точку разговора, где новая инструкция становится актуальной, вместо редактирования поля system верхнего уровня. Кэшированный префикс остаётся прежним, поэтому следующий запрос по-прежнему считывает его из кэша, а новая инструкция всё равно применяется как системная инструкция, а не как обычный пользовательский текст.
На этой странице рассматриваются две функции: системные сообщения в середине разговора, которые общедоступны, и изменения инструментов в середине разговора — бета-функция, представленная вместе с Claude Opus 5, которая применяет тот же подход к массиву tools.
Массив tools располагается в хэшируемом префиксе запроса ещё раньше, чем поле system верхнего уровня, поэтому его редактирование аннулирует кэш подсказок для всего разговора. Изменения инструментов в середине разговора — бета-функция, представленная вместе с Claude Opus 5, — это аналог системных сообщений в середине разговора для инструментов. Вместо того чтобы фиксировать список инструментов на всё время разговора, вы меняете, какие инструменты предлагаются модели между ходами: объявите полный набор инструментов в tools заранее, а затем используйте блоки tool_addition и tool_removal, чтобы предложить инструмент модели или отозвать его, начиная с определённой точки разговора. Сам массив tools никогда не меняется, поэтому кэшированный префикс остаётся нетронутым.
tool_addition и tool_removal — это блоки контента в массиве content сообщения с role: "system", и их можно смешивать с блоками text в одном сообщении. Сообщение подчиняется тем же правилам размещения, что и любое системное сообщение в середине разговора (см. Ограничения), и изменение применяется начиная с этой точки разговора. Поле tool каждого блока ссылается на инструмент, а не определяет его: {"type": "tool_reference", "name": "..."} указывает на инструмент, объявленный в массиве tools запроса, а на инструменты MCP-коннектора можно ссылаться по отдельности с помощью mcp_tool_reference (server_name и name) или как на весь набор инструментов с помощью mcp_toolset_reference (server_name). Ссылка на имя, не объявленное в tools, возвращает ошибку 400.
Каждый инструмент, объявленный в tools, предлагается модели с начала разговора, если только он не объявлен с defer_loading: true, что удерживает его скрытым до тех пор, пока блок tool_addition не сделает его доступным. tool_addition также повторно предлагает инструмент, который ранее был отозван блоком tool_removal.
client = anthropic.Anthropic()
response = client.beta.messages.create(
model="claude-opus-5",
max_tokens=1024,
betas=["mid-conversation-tool-changes-2026-07-01"],
# Полный набор инструментов объявляется заранее и никогда не меняется,
# поэтому кэшированный префикс остаётся нетронутым.
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.",
},
# Отзываем get_weather начиная с этого момента. Блок ссылается на
# инструмент по имени, а не редактирует `tools`, поэтому предыдущие ходы
# остаются байт-в-байт идентичными, и кэш по-прежнему срабатывает.
{
"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)Изменения инструментов в середине разговора находятся в стадии бета-тестирования. Чтобы использовать их, включите бета-заголовок mid-conversation-tool-changes-2026-07-01 в свои запросы. Они доступны в Claude Fable 5, Claude Mythos 5, Claude Opus 4.8 и Claude Opus 5 в Claude API, Amazon Bedrock и Google Cloud.
Кэширование подсказок хэширует префикс запроса по порядку: tools, затем system, затем messages. Попадание в кэш требует, чтобы префикс точно совпадал с недавним запросом, байт в байт, вплоть до точки разрыва кэша.
Такой порядок означает, что поле system верхнего уровня находится почти в самом начале хэшируемого префикса. Любое его изменение, даже добавление одного предложения, создаёт другой хэш, и запрос не попадает в кэш для системной подсказки и всех кэшированных сообщений после неё.
Системные сообщения в середине разговора позволяют добавить инструкцию в конец истории сообщений. Всё, что находится перед новой инструкцией, остаётся неизменным, поэтому существующая запись кэша по-прежнему совпадает, и только новое сообщение обрабатывается как свежий ввод.
Несколько ситуаций, в которых это важно:
system верхнего уровня привело бы к повторной обработке всей истории.Во всех этих случаях вы могли бы поместить инструкцию в обычное сообщение user, и Claude действительно следует инструкциям, поступающим в пользовательских ходах. Разница в приоритете: сообщение user рассматривается как поступающее от конечного пользователя, тогда как сообщение system рассматривается как поступающее от вас, оператора приложения. Когда они конфликтуют, системные инструкции имеют приоритет, поэтому используйте роль system для фактов и ограничений уровня оператора, которые должны соблюдаться, даже если конечный пользователь просит о чём-то другом. Системное сообщение в середине разговора сохраняет этот приоритет уровня оператора без затрат на промах кэша при редактировании поля system верхнего уровня.
Добавьте сообщение с "role": "system" в массив messages. Используйте обычную строку или блоки контента для content, так же как для хода user или assistant. Инструкция применяется начиная с этой точки разговора. Когда инструкции конфликтуют, более поздние системные сообщения имеют приоритет над более ранними, а системные сообщения в середине разговора имеют приоритет над полем system верхнего уровня для ходов, которые следуют за ними.
Вы по-прежнему можете задать поле system верхнего уровня для инструкций, которые должны применяться ко всему разговору. Оставьте системные сообщения в середине разговора для инструкций, которые становятся актуальными только позже или которые вы хотите добавить, не аннулируя кэшированный префикс.
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-opus-5",
max_tokens=1024,
# Автоматическое кэширование подсказок: каждый запрос кэширует разговор на текущий момент,
# а следующий запрос читает неизменённый префикс из кэша.
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().",
},
# В середине сессии рецензент понимает, что все предложения должны
# также соответствовать строгой политике типизации команды. Добавление
# инструкции здесь сохраняет предыдущие реплики побайтово идентичными,
# поэтому префикс, кэшированный предыдущим запросом, по-прежнему читается из кэша.
{
"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)Этот пример включает автоматическое кэширование с помощью поля cache_control верхнего уровня. Кэширование подсказок требует явного включения: если запрос не содержит поля cache_control (автоматического или явной точки разрыва), ничего не кэшируется, и каждый запрос оплачивается по обычной цене входных токенов за весь разговор. При включённом кэшировании добавление системного сообщения оставляет уже кэшированные ходы неизменными, поэтому запрос, несущий новую инструкцию, по-прежнему считывает их из кэша вместо повторной обработки. Кэширование также требует, чтобы разговор соответствовал минимальной кэшируемой длине подсказки; такой короткий пример, как этот, не достигает её, поэтому cache_creation_input_tokens и cache_read_input_tokens остаются равными 0, пока разговор не вырастет.
Системное сообщение в середине разговора должно следовать непосредственно за ходом user (или ходом assistant, заканчивающимся результатом серверного инструмента), и должно быть либо последней записью в messages, либо непосредственно предшествовать ходу assistant. Сообщение user, несущее блоки tool_result, учитывается: в агентном цикле вы можете разместить системное сообщение сразу после результатов инструментов, перед следующим ходом Claude. Любая другая позиция, включая позицию между блоком tool_use в assistant и отвечающим на него tool_result, возвращает ошибку 400.
В агентном цикле системное сообщение размещается после сообщения user, которое доставляет результаты инструментов. Здесь же ваше приложение может передать ввод, который пользователь набрал, пока Claude работал, чтобы новый контекст был усвоен без перезапуска хода:
[
{ "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."
}
]Формулируйте системное содержимое как контекст, а не как команду, которая переопределяет пользователя. Изложите факт («от пользователя поступил новый ввод: X», «оставшийся бюджет токенов теперь составляет Y») и позвольте Claude действовать на его основе. Claude обучен сопротивляться инструкциям, которые, по всей видимости, работают против пользователя, и эта защита по-прежнему применяется к системной роли, поэтому формулировки вроде «игнорируй то, что сказал пользователь» менее эффективны, чем изложение того, что изменилось.
Этот паттерн предназначен для передачи ввода от собственного конечного пользователя разговора. Не используйте его для передачи вывода инструментов, извлечённых документов или другого стороннего контента; храните такой контент в блоках tool_result (см. Ограничения).
Системные сообщения в середине разговора и кэширование подсказок разработаны для совместного использования:
cache_control — либо поле автоматического кэширования верхнего уровня, либо явную точку разрыва на блоке контента. Системное сообщение в середине разговора само по себе не создаёт запись кэша, и без включённого кэширования нет экономии, которую можно было бы сохранить.cache_control на последнем блоке, который остаётся одинаковым между запросами, будь то конец поля system верхнего уровня, конец определений ваших инструментов или стабильная точка в истории сообщений.Избегайте редактирования или удаления системного сообщения в середине разговора, которое уже было отправлено. Как и любое другое изменение более ранних сообщений, это аннулирует кэш начиная с этой точки. Если инструкция должна измениться, добавьте новое системное сообщение, а не переписывайте старое. Последовательные системные сообщения принимаются и рассматриваются как единая системная секция, которая в целом подчиняется тому же правилу размещения.
system не может быть первой записью в messages. Используйте поле system верхнего уровня для инструкций, которые применяются с самого начала.system должно следовать непосредственно за ходом user (включая ход user, несущий блоки tool_result) или ходом assistant, заканчивающимся результатом серверного инструмента, и должно предшествовать ходу assistant или завершать массив. Оно не может находиться между блоком tool_use и его tool_result. Размещение в другом месте возвращает ошибку 400.tool_result и продолжайте следовать рекомендациям из раздела Предотвращение джейлбрейков и инъекций подсказок.Как работает кэширование, где размещать точки разрыва и как читать поля использования кэша.
Узнайте, где именно два запроса разошлись, когда ожидаемое попадание в кэш не происходит.
Структура сообщений, многоходовые разговоры и поле system.
Написание эффективных подсказок и системных инструкций.
Как блоки tool_use и tool_result структурированы в массиве messages.
Was this page helpful?