Claude Platform Docs
Messages컨텍스트 관리

대화 중간 시스템 메시지 및 도구 변경

이전에 캐시된 프리픽스를 무효화하지 않고 대화 도중에 시스템 지침이나 도구 가용성을 변경합니다.

시스템 지침은 일반적으로 대화의 모든 메시지보다 앞에 있는 최상위 system 필드에 위치합니다. 이 위치는 prompt caching(프롬프트 캐싱)에 매우 유리합니다. 시스템 프롬프트가 안정적인 프리픽스의 일부이므로 이후 턴에서 캐시가 적중합니다. 그러나 세션 도중에야 필요하다는 것을 알게 되는 지침에는 좋지 않은 위치입니다. 최상위 system 필드를 편집하면 프롬프트의 맨 앞부분이 변경되어 그 뒤에 오는 모든 것에 대한 캐시가 무효화되기 때문입니다.

대화 중간 시스템 메시지(mid-conversation system messages)는 이 간극을 메웁니다. 최상위 system 필드를 편집하는 대신, 새 지침이 관련성을 갖게 되는 대화 지점에 {"role": "system"} 메시지를 추가합니다. 캐시된 프리픽스는 그대로 유지되므로 다음 요청에서도 여전히 캐시에서 읽어오며, 새 지침은 일반 사용자 텍스트가 아닌 시스템 지침으로 적용됩니다.

대화 중간 도구 변경

tools 배열은 해시되는 요청 프리픽스에서 최상위 system 필드보다도 더 앞에 위치하므로, 이를 편집하면 전체 대화에 대한 프롬프트 캐시가 무효화됩니다. 대화 중간 도구 변경은 대화 중간 시스템 메시지에 대응하는 도구 측 기능입니다. 대화 전체 기간 동안 도구 목록을 고정하는 대신, 턴 사이에 모델에 제공되는 도구를 변경합니다. 전체 도구 세트를 tools에 미리 선언한 다음, tool_additiontool_removal 블록을 사용하여 대화의 특정 지점부터 모델에 도구를 제공하거나 철회합니다. tools 배열 자체는 절대 변경되지 않으므로 캐시된 프리픽스가 그대로 유지됩니다.

tool_additiontool_removalrole: "system" 메시지의 content 배열에 들어가는 콘텐츠 블록이며, 같은 메시지 안에서 text 블록과 함께 사용할 수 있습니다. 이 메시지는 다른 대화 중간 시스템 메시지와 동일한 배치 규칙을 따르며(제한 사항 참조), 변경 사항은 대화의 해당 지점부터 적용됩니다. 각 블록의 tool 필드는 도구를 정의하는 것이 아니라 참조합니다. {"type": "tool_reference", "name": "..."}는 요청의 tools 배열에 선언된 도구를 이름으로 지정하며, MCP 커넥터 도구는 mcp_tool_reference(server_namename)로 개별적으로 참조하거나 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을 포함하세요.

대화 중간 시스템 메시지를 사용해야 하는 경우

프롬프트 캐싱은 요청 프리픽스를 tools, system, messages 순서로 해시합니다. 캐시 적중이 발생하려면 프리픽스가 캐시 중단점까지 최근 요청과 바이트 단위로 정확히 일치해야 합니다.

이 순서는 최상위 system 필드가 해시되는 프리픽스의 거의 맨 앞에 위치한다는 것을 의미합니다. 문장 하나를 추가하는 것조차 포함하여 어떤 변경이든 다른 해시를 생성하며, 요청은 시스템 프롬프트와 그 뒤의 모든 캐시된 메시지에 대해 캐시를 놓치게 됩니다.

대화 중간 시스템 메시지를 사용하면 대신 메시지 기록의 에 지침을 추가할 수 있습니다. 새 지침 이전의 모든 것은 변경되지 않으므로 기존 캐시 항목이 여전히 일치하며, 새 메시지만 새로운 입력으로 처리됩니다.

이것이 중요한 몇 가지 상황은 다음과 같습니다.

  • 세션 중간의 정책 또는 페르소나 변경. 긴 에이전트 세션에서 수십 개의 캐시된 턴 이후에 새로운 제약("지금부터 모든 SQL을 매개변수화된 쿼리로 작성하세요")이 필요합니다. 이를 최상위 system 필드에 추가하면 전체 기록이 다시 처리됩니다.
  • 권위를 가져야 하는 턴별 컨텍스트. 최신성 메모, 세션 마감 시한 또는 도구 가용성 변경을 시스템 수준의 가중치로 주입하고 싶지만, 캐시된 프리픽스에 두기에는 너무 자주 변경됩니다.
  • 쌓이지 않아야 하는 턴별 리마인더. 하네스가 각 도구 결과 배치 후에 모델에 넛지를 주고("독립적인 읽기는 함께 요청하세요", "사용자가 한동안 응답을 받지 못했습니다") 모델이 최신 사본만 보기를 원합니다. 턴 범위 시스템 메시지는 한 턴 동안만 렌더링되고 그 이후에는 비용이 들지 않으며, 기록에서 아무것도 삭제하지 않습니다.
  • 애플리케이션이 관찰하는 상태 변경. 애플리케이션이 Claude가 운영자 수준의 사실로 취급해야 하는 무언가를 감지합니다. 디스크의 파일이 변경되었거나, 사용자가 자동 승인 설정을 전환했거나, 사용 가능한 도구가 변경되었거나, 남은 토큰 예산이 임계값 아래로 떨어진 경우 등입니다.
  • 에이전트 루프를 중단해서는 안 되는 사용자 입력. Claude가 이전 요청에 대한 도구를 아직 실행하는 동안 사용자가 후속 내용을 입력합니다. 다음 도구 결과 이후에 이를 시스템 메시지로 전달하면 Claude가 전환해야 할 새로운 요청으로 취급하는 대신 이미 수행 중인 작업에 새 입력을 통합할 수 있습니다. 도구 결과 이후 배치를 참조하세요.
  • 상시 권한을 부여하는 모드 전환. 세션 수준 모드는 대화 중간 시스템 메시지를 사용하여 멀티에이전트 워크플로 자동 실행과 같은 비용이 큰 기능에 대한 상시 동의를 부여할 수 있으며, 몇 턴마다 짧은 리프레셔를 보내고 모드가 꺼질 때 종료 알림을 보낼 수 있습니다. 실제 예시는 오케스트레이션 모드 구축을 참조하세요.

이 모든 경우에 지침을 일반 user 메시지에 넣을 수도 있으며, Claude는 사용자 턴에 도착하는 지침도 따릅니다. 차이점은 우선순위입니다. user 메시지는 최종 사용자로부터 온 것으로 취급되는 반면, system 메시지는 애플리케이션 운영자인 여러분으로부터 온 것으로 취급됩니다. 둘이 충돌할 때 시스템 지침이 우선하므로, 최종 사용자가 다른 것을 요청하더라도 유지되어야 하는 운영자 수준의 사실과 제약에는 system 역할을 사용하세요. 대화 중간 시스템 메시지는 최상위 system 필드를 편집하는 캐시 미스 비용을 지불하지 않으면서 운영자 수준의 우선순위를 유지합니다.

작동 방식

messages 배열에 "role": "system"인 메시지를 추가합니다. content에는 user 또는 assistant 턴과 마찬가지로 일반 문자열이나 콘텐츠 블록을 사용합니다. 지침은 대화의 해당 지점부터 적용됩니다. 지침이 충돌할 경우 나중의 시스템 메시지가 이전 메시지보다 우선하며, 대화 중간 시스템 메시지는 그 뒤에 오는 턴에 대해 최상위 system 필드보다 우선합니다.

전체 대화에 적용되어야 하는 지침에는 여전히 최상위 system 필드를 설정할 수 있습니다. 대화 중간 시스템 메시지는 나중에야 관련성을 갖게 되는 지침이나 캐시된 프리픽스를 무효화하지 않고 추가하려는 지침에만 사용하세요.

role: "system" 메시지는 output_config.effort를 포함하여 다음 user 턴부터 effort(노력) 수준을 변경할 수도 있습니다. 이는 Claude API의 Claude Fable 5.1, Claude Mythos 5.1, Claude Opus 5에서 베타 상태이며 mid-conversation-output-config-2026-07-01 베타 헤더가 필요합니다. 메시지별 effort를 참조하세요.

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_tokenscache_read_input_tokens는 0으로 유지됩니다.

대화 중간 시스템 메시지는 user 턴(또는 서버 도구 결과로 끝나는 assistant 턴) 바로 뒤에 와야 하며, messages의 마지막 항목이거나 바로 뒤에 assistant 턴이 와야 합니다. tool_result 블록을 담은 user 메시지도 해당됩니다. 에이전트 루프에서는 도구 결과 바로 뒤, Claude의 다음 턴 이전에 시스템 메시지를 배치할 수 있습니다. assistanttool_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 블록에 유지하세요(제한 사항 참조).

턴 범위 시스템 메시지

role: "system" 메시지의 범위를 현재 턴으로 한정하려면 clear_at 필드를 설정하세요. 다음 두 값 중 하나를 사용합니다.

  • "never"(기본값): 메시지는 이를 포함하는 모든 요청에서 해당 위치에 렌더링됩니다. 필드를 생략하는 것과 동일합니다.
  • "next_user_message": 메시지가 **턴 범위(turn-scoped)**가 됩니다. messages에서 그 뒤에 role: "user" 메시지가 없는 동안에만 텍스트가 렌더링됩니다. 여기서는 tool_result 블록만 담은 사용자 메시지도 사용자 메시지로 간주됩니다. 이후 사용자 메시지가 존재하게 되면 메시지는 **해제(cleared)**됩니다. 배열에는 남아 있지만 해당 요청과 이후 모든 요청에서 아무것도 렌더링하지 않으며 입력 토큰 비용도 들지 않습니다.

턴 범위 시스템 메시지는 베타 상태입니다. 베타 헤더 mid-conversation-system-clear-at-2026-08-21을 포함하세요. 이 헤더가 없으면 clear_at은 알 수 없는 필드로 거부됩니다.

{
  "role": "system",
  "clear_at": "next_user_message",
  "content": "First privately list what you need next; then request every item that doesn't depend on another's result in this one response."
}

주요 용도는 도구 루프에서의 턴별 리마인더입니다. 모델이 보기를 원할 때마다 tool_result 메시지 뒤에 리마인더를 추가하고, 이전의 모든 사본은 그 자리에 그대로 두세요. 모델은 마지막 사용자 메시지 이후에 오는 사본만 보므로 리마인더가 절대 쌓이지 않습니다. messages의 앞부분은 아무것도 변경되지 않으므로 프롬프트 캐시가 계속 일치합니다. Claude Fable 5.1에서는 이것이 이후의 사고 블록을 유효하게 유지하기도 합니다. 이전 리마인더를 삭제하면 해당 블록 이전의 대화가 변경되어 대화 검사에 실패하지만, 해제된 메시지는 배열에 남아 해당 대화를 변경하지 않습니다.

다음 요청은 에이전트 루프의 이후 단계입니다. messages[3]은 배열의 마지막 메시지였던 이전 요청에서 렌더링되었습니다. messages[5](이후 사용자 메시지)가 존재하게 되면 messages[3]은 해제됩니다. 해제된 메시지는 배열에 남아 있으므로 messages[4]의 사고 블록 이전 대화는 변경되지 않지만, 모델은 더 이상 그 텍스트를 보지 않습니다. messages[6]messages[7]은 모두 순서대로 렌더링됩니다.

{
  "model": "claude-fable-5-1",
  "max_tokens": 16000,
  "messages": [
    { "role": "user", "content": "Fix the failing test." },
    {
      "role": "assistant",
      "content": [
        { "type": "thinking", "thinking": "", "signature": "..." },
        {
          "type": "tool_use",
          "id": "toolu_01",
          "name": "read_file",
          "input": { "path": "test_auth.py" }
        }
      ]
    },
    {
      "role": "user",
      "content": [{ "type": "tool_result", "tool_use_id": "toolu_01", "content": "..." }]
    },
    {
      "role": "system",
      "clear_at": "next_user_message",
      "content": "Request independent reads in one turn."
    },
    {
      "role": "assistant",
      "content": [
        { "type": "thinking", "thinking": "", "signature": "..." },
        {
          "type": "tool_use",
          "id": "toolu_02",
          "name": "read_file",
          "input": { "path": "auth.py" }
        },
        {
          "type": "tool_use",
          "id": "toolu_03",
          "name": "read_file",
          "input": { "path": "tokens.py" }
        }
      ]
    },
    {
      "role": "user",
      "content": [
        { "type": "tool_result", "tool_use_id": "toolu_02", "content": "..." },
        {
          "type": "tool_result",
          "tool_use_id": "toolu_03",
          "content": "...",
          "cache_control": { "type": "ephemeral" }
        }
      ]
    },
    {
      "role": "system",
      "clear_at": "next_user_message",
      "content": "Request independent reads in one turn."
    },
    {
      "role": "system",
      "clear_at": "next_user_message",
      "content": "The shell exited with status 137."
    }
  ]
}

턴 범위 메시지에 대한 규칙:

  • 해제된 메시지는 그대로 다시 전송하세요. 해제된 메시지는 여전히 대화 기록의 일부입니다. 현재 상태(새로운 토큰 수, 타임스탬프)로 다시 구성하거나, 중복으로 간주하여 삭제하거나, clear_at 값을 변경하는 것은 이전 메시지에 대한 편집입니다. 프롬프트 캐시는 그 지점부터 미스가 발생하며, Claude Fable 5.1에서는 그 이후에 생성된 모든 사고 블록이 대화 검사에 실패합니다.
  • 텍스트만 가능합니다. content는 하나 이상의 text 블록(또는 문자열)입니다. tool_additiontool_removal 블록은 턴 범위 메시지에서 400 오류를 반환하며, output_config도 마찬가지입니다. 이러한 용도에는 clear_at이 없는 별도의 role: "system" 메시지를 사용하세요.
  • 블록에 cache_control을 사용할 수 없습니다. 해제된 메시지는 절대 캐시 키의 일부가 되지 않으므로 그 위의 중단점은 절대 일치할 수 없습니다. 예시처럼 대신 앞선 사용자 턴의 마지막 블록에 중단점을 두세요. 최상위 자동 캐싱 필드는 중단점을 선택할 때 턴 범위 메시지를 건너뜁니다. 메시지를 해제하는 요청에서 재사용 가능한 캐시된 프리픽스는 그 앞의 사용자 턴에서 끝나므로, 해당 메시지와 새 사용자 메시지 사이의 어시스턴트 턴 하나만 다시 처리됩니다.
  • 배치 규칙은 여전히 적용됩니다. 해제 여부와 관계없이 그렇습니다. 턴 범위 메시지는 다른 대화 중간 시스템 메시지와 마찬가지로 user 턴(또는 서버 도구 결과로 끝나는 assistant 턴) 뒤에 와야 하며 assistant 턴 앞에 오거나 배열의 끝이어야 합니다. 배열의 끝에 있는 메시지는 항상 렌더링됩니다. 바로 뒤에 또 다른 user 메시지가 오는 경우는 해제된 메시지가 아니라 400 오류입니다. 한 도구 라운드의 모든 결과를 하나의 사용자 메시지에 넣고 리마인더는 그 뒤에 두세요.
  • 어시스턴트 턴은 이를 해제하지 않습니다. 메시지 뒤의 프리필된 또는 일시 중지된 어시스턴트 턴이나 서버 측 도구 루프는 사용자 메시지를 추가하지 않으므로, 해당 연속 요청에서 메시지는 여전히 렌더링됩니다. 클라이언트 측 도구 루프 동안 리마인더를 계속 보이게 하려면 각 tool_result 메시지 뒤에 다시 추가하세요.
  • 토큰 계산은 렌더링되는 내용을 따릅니다. 해제된 메시지는 usage.input_tokens토큰 수에 아무것도 추가하지 않습니다.
  • 가져온 기록. 한 번에 구성하는 트랜스크립트(퓨샷 예시, 마이그레이션된 대화)에서, 이미 뒤에 어시스턴트 턴과 사용자 메시지가 있는 턴 범위 메시지는 첫 요청부터 해제되어 절대 렌더링되지 않습니다. 이는 이어서 가져오는 턴별 리마인더에 올바른 상태입니다. 모델이 모든 요청에서 보아야 하는 메시지에만 clear_at을 설정하지 않은 채로 두세요.

유효성 검사 오류는 다음과 같습니다.

messages.3.clear_at: Extra inputs are not permitted
messages.3.clear_at: clear_at is only permitted on role 'system' messages
messages.3.clear_at: Input should be 'next_user_message' or 'never'
messages.3: a turn-scoped system message supports text blocks only (clear_at: 'next_user_message')
messages.3: output_config is not permitted on a turn-scoped system message (clear_at: 'next_user_message')
messages.3.content.0: cache_control is not permitted on a turn-scoped system message (clear_at: 'next_user_message')

첫 번째는 베타 헤더 없이 반환되는 오류입니다. Amazon Bedrock 및 Google Cloud에서는 베타 헤더에 설명된 대로 베타 값을 전달하세요.

SDK를 통해서는 messagesrole: "system" 항목에 clear_at을 설정하고 베타 헤더를 전송하세요. 다음 예시는 사용자 턴 뒤에 턴 범위 리마인더를 추가합니다. 다음 요청에서 이후 사용자 메시지가 존재하게 되면 리마인더는 배열에 남아 있지만 더 이상 렌더링되지 않습니다.

client = anthropic.Anthropic()

response = client.beta.messages.create(
    model="claude-fable-5-1",
    max_tokens=4096,
    messages=[
        {
            "role": "user",
            "content": "Draft a short status update on the database migration for the team channel.",
        },
        # 턴 범위 리마인더: 이번 턴에 렌더링되고, 이후 사용자 메시지가 존재하면 지워집니다.
        {
            "role": "system",
            "clear_at": "next_user_message",
            "content": "The reader is on call: keep this reply under 50 words.",
        },
    ],
    betas=["mid-conversation-system-clear-at-2026-08-21"],
)

for block in response.content:
    if block.type == "text":
        print(block.text)

프롬프트 캐싱과 함께 사용하기

대화 중간 시스템 메시지와 프롬프트 캐싱은 함께 사용하도록 설계되었습니다.

  • 캐싱을 명시적으로 활성화하세요. 캐싱은 요청에 cache_control이 포함된 경우에만 발생합니다. 최상위 자동 캐싱 필드이거나 콘텐츠 블록의 명시적 중단점이어야 합니다. 대화 중간 시스템 메시지는 자체적으로 캐시 항목을 생성하지 않으며, 캐싱이 활성화되지 않으면 보존할 절감 효과도 없습니다.
  • 안정적인 프리픽스를 평소처럼 캐시하세요. 요청 간에 동일하게 유지되는 마지막 블록에 cache_control을 배치하세요. 최상위 system 필드의 끝이든, 도구 정의의 끝이든, 메시지 기록의 안정적인 지점이든 상관없습니다.
  • 중단점 뒤에 시스템 메시지를 추가하세요. 캐시된 프리픽스 뒤에 오기 때문에 프리픽스 해시를 변경하지 않으며 캐시가 여전히 적중합니다.
  • 대화 중간 시스템 메시지 자체도 캐시 가능합니다. 대화에 들어가면 안정적인 기록의 일부가 됩니다. 다음 턴에서 캐시 중단점을 그 뒤로 옮길 수 있으며(또는 자동 캐싱이 그렇게 하도록 맡길 수 있으며), 시스템 메시지는 다른 턴과 마찬가지로 캐시에서 읽힙니다.

이미 전송된 대화 중간 시스템 메시지를 편집하거나 제거하지 마세요. 이전 메시지에 대한 다른 모든 변경과 마찬가지로, 그 지점부터 캐시가 무효화됩니다. Claude Fable 5.1에서는 이후 모든 어시스턴트 턴의 사고 블록도 무효화됩니다. 한 턴에만 적용되어야 하는 안내에는 턴 범위 시스템 메시지를 사용하고 그 자리에 그대로 두세요. 지침이 발전해야 한다면 이전 메시지를 다시 작성하는 대신 새 시스템 메시지를 추가하세요. 연속된 시스템 메시지는 허용되며 단일 시스템 섹션으로 취급되고, 전체로서 동일한 배치 규칙을 따릅니다.

제한 사항

  • 첫 번째 메시지로는 사용할 수 없습니다. 콘텐츠를 담은 system 메시지는 messages의 첫 번째 항목이 될 수 없습니다. 맨 처음부터 적용되는 지침에는 최상위 system 필드를 사용하세요.
  • 배치가 제한됩니다. 콘텐츠(text, tool_addition 또는 tool_removal 블록)를 담은 system 메시지는 user 턴(tool_result 블록을 담은 user 턴 포함) 또는 서버 도구 결과로 끝나는 assistant 턴 바로 뒤에 와야 하며, assistant 턴 앞에 오거나 배열의 끝이어야 합니다. tool_use 블록과 그 tool_result 사이에 위치할 수 없습니다. 다른 곳에 배치하면 400 오류가 반환됩니다. output_config.effort만 설정하고 content가 비어 있는 메시지는 해당 위치에서 아무것도 렌더링하지 않으며, 첫 번째 위치나 assistant 턴과 user 턴 사이를 포함하여 messages의 어디에서나 허용됩니다. 연속된 system 메시지는 함께 판단되므로, effort 전용 메시지 옆에 텍스트를 담은 메시지를 추가하면 전체 그룹이 콘텐츠 규칙을 따르게 됩니다.
  • 턴 범위 메시지는 텍스트 전용이며 그대로 다시 전송됩니다. clear_at: "next_user_message" 메시지는 tool_addition, tool_removal, output_config 또는 cache_control을 담지 않으며, 한 번 해제되면 이후 요청에서 messages에 바이트 단위로 동일하게 남아 있어야 합니다. 턴 범위 시스템 메시지를 참조하세요.
  • 신뢰할 수 없는 콘텐츠를 위한 곳이 아닙니다. Claude는 시스템 콘텐츠를 운영자 지침으로 취급하고 따릅니다. 원시 도구 출력, 검색된 문서 또는 웹 콘텐츠와 같이 대화 외부에서 온 텍스트를 시스템 메시지에 직접 넣지 마세요. 그렇게 하면 해당 텍스트에 운영자 수준의 권한이 부여됩니다. 그러한 데이터는 tool_result 블록에 유지하고 탈옥 및 프롬프트 인젝션 완화를 계속 따르세요.

캐싱 작동 방식, 중단점 배치 위치, 캐시 사용량 필드를 읽는 방법.

예상한 캐시 적중이 발생하지 않을 때 두 요청이 정확히 어디서 갈라졌는지 알아보세요.

메시지 구조, 멀티턴 대화, system 필드.

효과적인 프롬프트와 시스템 지침 작성하기.

messages 배열에서 tool_usetool_result 블록이 구조화되는 방식.

Was this page helpful?