Эта функция соответствует требованиям Zero Data Retention (ZDR) (нулевого хранения данных). Если у вашей организации действует соглашение ZDR, данные, отправленные через эту функцию, не сохраняются после возврата ответа API.
Системные инструкции обычно находятся в поле system верхнего уровня, перед всеми сообщениями в разговоре. Эта позиция отлично подходит для кэширования подсказок: системная подсказка является частью стабильного префикса, поэтому последующие ходы попадают в кэш. Однако эта позиция плохо подходит для инструкций, необходимость в которых вы обнаруживаете только в середине сессии, поскольку редактирование поля system верхнего уровня изменяет самое начало подсказки и аннулирует кэш для всего, что следует далее.
Системные сообщения в середине разговора устраняют этот пробел. Вы добавляете сообщение {"role": "system"} в ту точку разговора, где новая инструкция становится актуальной, вместо редактирования поля system верхнего уровня. Кэшированный префикс остаётся прежним, поэтому следующий запрос по-прежнему читает его из кэша, а новая инструкция всё равно применяется как системная инструкция, а не как обычный пользовательский текст.
Системные сообщения в середине разговора доступны в Claude API и Claude Platform на AWS. Они недоступны в Amazon Bedrock, Vertex AI и Microsoft Foundry.
Эта функция доступна только в Claude Opus 4.8. Бета-заголовок не требуется.
Кэширование подсказок хэширует префикс запроса по порядку: tools, затем system, затем messages. Попадание в кэш требует, чтобы префикс точно совпадал с недавним запросом, байт в байт, вплоть до точки разрыва кэша.
Такой порядок означает, что поле system верхнего уровня находится почти в самом начале хэшируемого префикса. Любое его изменение, даже добавление одного предложения, даёт другой хэш, и запрос не попадает в кэш ни для системной подсказки, ни для всех кэшированных сообщений после неё.
Системные сообщения в середине разговора позволяют добавить инструкцию в конец истории сообщений. Всё, что находится до новой инструкции, остаётся неизменным, поэтому существующая запись кэша по-прежнему совпадает, и только новое сообщение обрабатывается как свежий ввод.
Несколько ситуаций, в которых это важно:
system верхнего уровня привело бы к повторной обработке всей истории.Во всех этих случаях вы могли бы поместить инструкцию в обычное сообщение user, и Claude действительно следует инструкциям, поступающим в пользовательских ходах. Разница в приоритете: сообщение user рассматривается как поступающее от конечного пользователя, а сообщение system — как поступающее от вас, оператора приложения. Когда они конфликтуют, системные инструкции имеют приоритет, поэтому используйте роль system для фактов и ограничений уровня оператора, которые должны соблюдаться, даже если конечный пользователь просит о чём-то другом. Системное сообщение в середине разговора сохраняет этот приоритет уровня оператора без затрат на промах кэша из-за редактирования поля system верхнего уровня.
Добавьте сообщение с "role": "system" в массив messages. Используйте обычную строку или блоки контента для content, так же как для хода user или assistant. Инструкция применяется с этой точки разговора и далее. Когда инструкции конфликтуют, более поздние системные сообщения имеют приоритет над более ранними, а системные сообщения в середине разговора имеют приоритет над полем system верхнего уровня для ходов, которые следуют за ними.
Вы по-прежнему можете задать поле system верхнего уровня для инструкций, которые должны применяться ко всему разговору. Оставьте системные сообщения в середине разговора для инструкций, которые становятся актуальными только позже или которые вы хотите добавить, не аннулируя кэшированный префикс.
В этом примере включено автоматическое кэширование с помощью поля 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.
В агентном цикле системное сообщение идёт после сообщения 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 и продолжайте следовать рекомендациям из раздела .Как работает кэширование, где размещать точки разрыва и как читать поля использования кэша.
Узнайте, где именно разошлись два запроса, когда ожидаемое попадание в кэш не происходит.
Was this page helpful?
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-opus-4-8",
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.",
},
],
)
print(response.content[0].text)Структура сообщений, многоходовые разговоры и поле system.