대화 중간 시스템 메시지 및 도구 변경
이전에 캐시된 프리픽스를 무효화하지 않고 대화 도중에 시스템 지침이나 도구 가용성을 변경합니다.
시스템 지침은 일반적으로 대화의 모든 메시지보다 앞에 있는 최상위 system 필드에 위치합니다. 이 위치는 "prompt caching"(프롬프트 캐싱)에 매우 적합합니다. 시스템 프롬프트가 안정적인 프리픽스의 일부이므로 이후 턴에서 캐시 적중이 발생하기 때문입니다. 하지만 세션 도중에야 필요하다는 것을 알게 되는 지침에는 좋지 않은 위치입니다. 최상위 system 필드를 편집하면 프롬프트의 맨 앞부분이 변경되어 그 뒤에 오는 모든 내용에 대한 캐시가 무효화되기 때문입니다.
"Mid-conversation system message"(대화 중간 시스템 메시지)는 이러한 격차를 해소합니다. 최상위 system 필드를 편집하는 대신, 새 지침이 관련성을 갖게 되는 대화 지점에 {"role": "system"} 메시지를 추가합니다. 캐시된 프리픽스는 그대로 유지되므로 다음 요청도 여전히 캐시에서 이를 읽어오며, 새 지침은 일반 사용자 텍스트가 아닌 시스템 지침으로 적용됩니다.
대화 중간 도구 변경
tools 배열은 해시되는 요청 접두사에서 최상위 system 필드보다도 앞에 위치하므로, 이를 편집하면 대화 전체의 프롬프트 캐시가 무효화됩니다. "Mid-conversation tool changes"(대화 중간 도구 변경)는 대화 중간 시스템 메시지에 대응하는 도구 기능입니다. 대화 전체 기간 동안 도구 목록을 고정하는 대신, 턴 사이에 모델에 제공되는 도구를 변경합니다. 전체 도구 세트를 처음부터 tools에 선언한 다음, tool_addition 및 tool_removal 블록을 사용하여 대화의 특정 지점부터 모델에 도구를 제공하거나 철회합니다. tools 배열 자체는 절대 변경되지 않으므로 캐시된 접두사가 그대로 유지됩니다. 대화 중간 도구 변경은 베타로 제공되며 Claude API에서 inline-tools-2026-09-15 베타 헤더를 사용합니다.
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 오류가 반환됩니다(Claude API에서는 error.details.error_code가 tool_reference_unresolved로 설정됨). 대신 tool_addition 블록에 도구의 전체 정의를 담을 수도 있지만, mid-conversation-tool-changes-2026-07-01 헤더는 이를 지원하지 않습니다.
tools에 선언된 모든 도구는 defer_loading: true로 선언되지 않는 한 대화 시작부터 모델에 제공됩니다. defer_loading: true로 선언된 도구는 tool_addition 블록이 이를 노출할 때까지 보류됩니다. tool_addition은 이전 tool_removal이 철회한 도구를 다시 제공하기도 합니다.
다음 요청은 tools에 get_weather를 선언한 다음, 첫 번째 사용자 턴 이후 tool_removal 블록으로 이를 철회합니다. 이 요청은 inline-tools-2026-09-15 베타 헤더를 전송합니다.
client = anthropic.Anthropic()
response = client.beta.messages.create(
model="claude-opus-5-5",
max_tokens=1024,
betas=["inline-tools-2026-09-15"],
# 전체 도구 세트를 처음에 선언하고 이후 변경하지 않으므로
# 캐시된 접두사가 그대로 유지됩니다.
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)메시지에서 도구 정의하기 (베타)
inline-tools-2026-09-15 베타 헤더를 사용하면 tool_addition 블록이 도구를 참조로 지정하는 대신 전체 정의를 담아 값으로 도구를 정의할 수 있습니다. 이를 통해 대화 시작 시점에는 알 수 없었던 도구나 나중에 스키마가 변경되는 도구를 role: "system" 메시지를 추가하여 도입할 수 있습니다. tools 배열과 이전의 모든 메시지는 전송된 그대로 유지되므로 캐시가 여전히 적중하며, 추가된 메시지만 새 입력으로 처리됩니다. 유일한 예외인, 지연되지 않은 도구가 하나도 없는 tools 배열의 경우는 아래 규칙에서 다룹니다. 이 헤더는 참조를 통한 도구 추가 및 제거도 포함하므로 mid-conversation-tool-changes-2026-07-01을 함께 보낼 필요가 없습니다.
정의를 tool_definition 유형의 tool 객체로 감싸세요. definition은 사용자 정의 도구나 Anthropic 정의 클라이언트 또는 서버 도구와 같은 tools 항목이며, cache_control 및 defer_loading을 포함한 일반적인 구성을 갖습니다. 베타 기간 동안 일부 도구 유형(컴퓨터 사용 도구 포함)은 아직 메시지에서 정의할 수 없으며, 그렇다는 내용의 400 오류를 반환합니다. 이러한 도구는 tools에 선언하고 참조로 추가하세요. 예를 들어, 대화 중간에 사용자 정의 도구를 정의하려면 다음과 같이 합니다:
{
"role": "system",
"content": [
{
"type": "tool_addition",
"tool": {
"type": "tool_definition",
"definition": {
"name": "db_query",
"description": "Run a read-only SQL query against the analytics database.",
"input_schema": {
"type": "object",
"properties": { "sql": { "type": "string" } },
"required": ["sql"]
}
}
}
}
]
}해당 위치부터 모델은 tools에 선언된 도구를 호출하는 것과 같은 방식으로 이 도구를 호출할 수 있습니다. 동일한 정의를 다시 보내도 아무것도 변경되지 않으므로, 클라이언트는 재시도 시 등에 안전하게 다시 보낼 수 있습니다.
다음 요청은 get_weather를 tools에 유지하고 첫 번째 사용자 턴 이후에 db_query를 정의합니다:
client = anthropic.Anthropic()
response = client.beta.messages.create(
model="claude-opus-5-5",
max_tokens=1024,
betas=["inline-tools-2026-09-15"],
# 나중에 정의되는 도구가 렌더링된 프롬프트의 시작 부분을 바꾸지 않도록,
# `tools`에 지연되지 않은 도구를 하나 이상 유지하세요.
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": "How many orders shipped yesterday?"},
# 이 시점부터 db_query를 값으로 정의합니다. `tools`와
# 이전 메시지는 보낸 그대로 유지되므로 캐시가 계속 적중합니다.
{
"role": "system",
"content": [
{
"type": "tool_addition",
"tool": {
"type": "tool_definition",
"definition": {
"name": "db_query",
"description": "Run a read-only SQL query against the analytics database.",
"input_schema": {
"type": "object",
"properties": {"sql": {"type": "string"}},
"required": ["sql"],
},
},
},
},
],
},
],
)
for block in response.content:
if block.type == "tool_use":
print(block.name, block.input)응답의 content에는 새 도구에 대한 tool_use 블록이 포함됩니다. 예를 들면 다음과 같습니다:
{
"type": "tool_use",
"id": "toolu_01A09q90qw90lq917835lq9",
"name": "db_query",
"input": {
"sql": "SELECT COUNT(*) FROM orders WHERE shipped_at::date = CURRENT_DATE - 1"
}
}도구의 스키마를 변경하거나 서버 도구를 최신 버전으로 옮기려면 같은 이름으로 다른 정의를 보내세요. 새 정의는 해당 위치부터 이전 정의를 대체합니다. 다른 유형의 도구 이름을 재사용하는 정의는 error.details.error_code가 tool_name_conflict로 설정된 400 오류를 반환합니다. 같은 도구의 최신 버전은 다른 유형으로 간주되지 않습니다. tool_removal은 여전히 참조를 사용하며, 제거된 도구는 나중에 다시 정의하거나 다시 제공할 수 있습니다.
정의가 렌더링되는 위치에 따라 몇 가지 규칙이 적용됩니다:
- 알고 있는 것은 미리 선언하세요. 첫 번째 요청 시점에 알고 있는 도구는
tools에 넣어야 하며, 모델이 아직 보지 않아야 한다면defer_loading: true와 이후의tool_addition참조를 사용하세요. 첫 번째 요청 시점에 알 수 없거나 나중에 변경되는 것만 값으로 정의하세요. tools에 지연되지 않은 도구를 최소 하나 유지하세요.tools배열에 지연되지 않은 도구가 없는 대화도 허용되지만, 값으로 정의하는 첫 번째 도구가 렌더링된 프롬프트의 시작 부분을 변경하므로 해당 요청에서 전체 캐시 미스가 한 번 발생합니다. 도구 검색 도구는 지연되지 않은 도구로 간주됩니다.- 날짜가 지정된 도구 유형은 자체 베타 헤더를 유지합니다. 값으로 정의하는 서버 도구에 자체 베타 헤더가 필요한 경우, 대화의 이후 모든 요청에 해당 헤더를 보내세요.
cache_control은 블록 또는 정의 중 한 곳에만 두고 둘 다에 두지 않으며, 요청의 중단점 제한에 포함됩니다. 지연된 정의에는cache_control을 지정할 수 없습니다.
다음 제한 중 하나라도 초과하면 요청은 error.details.error_code가 available_tools_limit_exceeded로 설정된 400 오류를 반환합니다:
- 어떤 메시지 이후에든 10,000개를 초과하는 지연된 도구가 사용 가능한 경우.
- 첫 번째 사용자 메시지 이후에 정의된 도구 중 10,000개를 초과하는 도구가 어떤 메시지 이후에든 사용 가능한 경우.
- 첫 번째 사용자 메시지 이후에 전송되어 어떤 메시지 이후에든 여전히 사용 가능한 도구 정의의 합계가 4 MB(4,194,304바이트)를 초과하는 경우.
- 렌더링된 도구 텍스트가 4 MB(4,194,304바이트)보다 큰 경우.
대화 중간에 MCP 서버 추가하기 (베타)
대화 도중에 MCP 커넥터 서버를 추가하려면 inline-tools-2026-09-15와 함께 mcp-client-2026-09-15 베타 헤더를 보내세요. 그러면 tool_addition 블록의 definition이 mcp_toolset이 될 수 있으므로, tools를 편집하지 않고도 서버의 도구를 사용할 수 있게 됩니다. 평소처럼 mcp_servers에 서버의 연결 세부 정보를 나열한 다음, 서버가 사용 가능해진 위치에 도구 세트를 추가하세요:
{
"role": "system",
"content": [
{
"type": "tool_addition",
"tool": {
"type": "tool_definition",
"definition": { "type": "mcp_toolset", "mcp_server_name": "calendar" }
}
}
]
}mcp_toolset 객체는 default_config 및 configs를 포함하여 tools에 넣는 것과 동일한 객체입니다. tool_addition 블록에는 서버 URL이나 토큰이 절대 포함되지 않습니다. 이러한 정보는 mcp_servers에 유지됩니다.
다음 요청은 get_weather를 tools에 유지하고, mcp_servers에 캘린더 서버를 나열하며, 첫 번째 사용자 턴 이후에 서버의 도구 세트를 추가합니다:
client = anthropic.Anthropic()
response = client.beta.messages.create(
model="claude-opus-5-5",
max_tokens=1024,
betas=["inline-tools-2026-09-15", "mcp-client-2026-09-15"],
mcp_servers=[
{
"type": "url",
"url": "https://mcp.example.com/calendar",
"name": "calendar",
"authorization_token": "YOUR_TOKEN",
},
],
tools=[
{
"name": "get_weather",
"description": "Get the current weather for a location.",
"input_schema": {
"type": "object",
"properties": {
"location": {"type": "string", "description"