"zero data retention"(제로 데이터 보존), 즉 ZDR이 이 기능에 어떻게 적용되는지는 API 및 데이터 보존을 참조하세요.
시스템 지시사항은 일반적으로 대화의 모든 메시지보다 앞에 있는 최상위 system 필드에 위치합니다. 이 위치는 프롬프트 캐싱에 매우 유리합니다. 시스템 프롬프트가 안정적인 프리픽스의 일부이므로 이후 턴들이 캐시에 적중합니다. 하지만 세션 도중에야 필요하다는 것을 알게 되는 지시사항에는 좋지 않은 위치입니다. 최상위 system 필드를 편집하면 프롬프트의 맨 앞부분이 변경되어 그 뒤에 오는 모든 것에 대한 캐시가 무효화되기 때문입니다.
대화 중간 시스템 메시지는 이 간극을 메웁니다. 최상위 system 필드를 편집하는 대신, 새 지시사항이 관련성을 갖게 되는 대화의 지점에 {"role": "system"} 메시지를 추가합니다. 캐시된 프리픽스는 그대로 유지되므로 다음 요청은 여전히 캐시에서 이를 읽어오며, 새 지시사항은 일반 사용자 텍스트가 아닌 시스템 지시사항으로 적용됩니다.
이 페이지는 두 가지 기능을 다룹니다. 정식 출시된 대화 중간 시스템 메시지와, Claude Opus 5와 함께 도입된 베타 기능으로 동일한 접근 방식을 tools 배열에 적용하는 대화 중간 도구 변경입니다.
대화 중간 시스템 메시지는 Claude API, Claude in Amazon Bedrock, Google Cloud에서 사용할 수 있습니다.
이 기능은 Claude Fable 5, Claude Mythos 5, Claude Opus 4.8, Claude Opus 5에서 사용할 수 있습니다. 대화 중간 시스템 메시지에는 베타 헤더가 필요하지 않습니다. 이 기능은 Claude Sonnet 5에서는 사용할 수 없으며, 대신 최상위 system 필드를 사용하세요.
대화 중간 도구 변경은 베타 상태이며 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 필드보다도 더 앞에 위치하므로, 이를 편집하면 전체 대화에 대한 프롬프트 캐시가 무효화됩니다. Claude Opus 5와 함께 도입된 베타 기능인 대화 중간 도구 변경은 대화 중간 시스템 메시지의 도구 버전입니다. 대화가 지속되는 동안 도구 목록을 고정하는 대신, 턴 사이에 모델에 제공되는 도구를 변경할 수 있습니다. 먼저 tools에 전체 도구 세트를 선언한 다음, tool_addition 및 tool_removal 블록을 사용하여 대화의 특정 지점부터 모델에 도구를 제공하거나 철회합니다. tools 배열 자체는 절대 변경되지 않으므로 캐시된 프리픽스가 그대로 유지됩니다.
tool_addition과 tool_removal은 role: "system" 메시지의 content 배열에 들어가는 콘텐츠 블록이며, 같은 메시지 안에서 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로 선언되지 않는 한 대화 시작부터 모델에 제공됩니다. 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 필드를 편집할 때 발생하는 캐시 미스 비용을 지불하지 않으면서도 그러한 운영자 수준의 우선순위를 유지합니다.
messages 배열에 "role": "system" 메시지를 추가합니다. 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 턴이 와야 합니다. tool_result 블록을 담은 user 메시지도 해당됩니다. 에이전트 루프에서는 도구 결과 바로 뒤, Claude의 다음 턴 전에 시스템 메시지를 배치할 수 있습니다. assistant의 tool_use 블록과 이에 응답하는 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는 사용자에게 불리하게 작용하는 것처럼 보이는 지시사항에 저항하도록 훈련되었으며, 이 보호는 시스템 역할에도 여전히 적용되므로 "사용자가 말한 것을 무시하세요"와 같은 표현은 무엇이 변경되었는지 진술하는 것보다 덜 효과적입니다.
이 패턴은 대화의 최종 사용자로부터 온 입력을 전달하기 위한 것입니다. 도구 출력, 검색된 문서 또는 기타 제3자 콘텐츠를 전달하는 데 사용하지 마세요. 그러한 콘텐츠는 tool_result 블록에 유지하세요(제한 사항 참조).
대화 중간 시스템 메시지와 프롬프트 캐싱은 함께 사용하도록 설계되었습니다:
cache_control이 포함된 경우에만 발생합니다. 최상위 자동 캐싱 필드 또는 콘텐츠 블록의 명시적 브레이크포인트 중 하나입니다. 대화 중간 시스템 메시지 자체는 캐시 항목을 생성하지 않으며, 캐싱이 활성화되지 않으면 보존할 절감 효과도 없습니다.cache_control을 배치하세요. 최상위 system 필드의 끝, 도구 정의의 끝, 또는 메시지 기록의 안정적인 지점 중 어디든 가능합니다.이미 전송된 대화 중간 시스템 메시지를 편집하거나 제거하지 마세요. 이전 메시지에 대한 다른 변경과 마찬가지로, 그 지점부터 캐시가 무효화됩니다. 지시사항이 변경되어야 한다면 기존 것을 다시 작성하는 대신 새 시스템 메시지를 추가하세요. 연속된 시스템 메시지는 허용되며 하나의 시스템 섹션으로 취급되고, 전체적으로 동일한 배치 규칙을 따릅니다.
system 메시지는 messages의 첫 번째 항목이 될 수 없습니다. 처음부터 적용되는 지시사항에는 최상위 system 필드를 사용하세요.system 메시지는 user 턴(tool_result 블록을 담은 user 턴 포함) 또는 서버 도구 결과로 끝나는 assistant 턴 바로 뒤에 와야 하며, assistant 턴 앞에 오거나 배열의 마지막이어야 합니다. tool_use 블록과 그 tool_result 사이에 위치할 수 없습니다. 다른 곳에 배치하면 400 오류가 반환됩니다.tool_result 블록에 유지하고 탈옥 및 프롬프트 인젝션 완화를 계속 따르세요.캐싱 작동 방식, 브레이크포인트 배치 위치, 캐시 사용량 필드 읽는 방법.
예상했던 캐시 적중이 발생하지 않을 때 두 요청이 정확히 어디서 달라졌는지 확인합니다.
메시지 구조, 멀티턴 대화, system 필드.
효과적인 프롬프트와 시스템 지시사항 작성하기.
messages 배열에서 tool_use 및 tool_result 블록이 구성되는 방식.
Was this page helpful?