이 기능은 Zero Data Retention (ZDR)의 적용 대상입니다. 조직에 ZDR 계약이 체결되어 있는 경우, 이 기능을 통해 전송된 데이터는 API 응답이 반환된 후 저장되지 않습니다.
시스템 지침은 일반적으로 대화의 모든 메시지보다 앞에 위치하는 최상위 system 필드에 들어갑니다. 이 위치는 프롬프트 캐싱에 적합합니다. 시스템 프롬프트가 안정적인 프리픽스의 일부이므로 이후 턴에서 캐시가 적중하기 때문입니다. 하지만 세션 도중에야 필요하다는 것을 알게 된 지침에는 적합하지 않은 위치입니다. 최상위 system 필드를 수정하면 프롬프트의 맨 처음이 바뀌어 그 뒤에 오는 모든 내용의 캐시가 무효화되기 때문입니다.
대화 중간 시스템 메시지는 이 간극을 메웁니다. 최상위 system 필드를 수정하는 대신, 새 지침이 필요해지는 대화 지점에 {"role": "system"} 메시지를 추가합니다. 캐시된 프리픽스는 그대로 유지되므로 다음 요청은 여전히 캐시에서 읽어오며, 새 지침은 일반 사용자 텍스트가 아니라 시스템 지침으로 적용됩니다.
대화 중간 시스템 메시지는 Claude API와 AWS의 Claude Platform에서 사용할 수 있습니다. Amazon Bedrock, Vertex AI, Microsoft Foundry에서는 사용할 수 없습니다.
이 기능은 Claude Opus 4.8에서만 사용할 수 있습니다. 베타 헤더는 필요하지 않습니다.
프롬프트 캐싱은 요청 프리픽스를 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-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)이 예시는 최상위 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 사이입니다.
에이전트 루프에서 시스템 메시지는 도구 결과를 전달하는 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?