"zero data retention"(제로 데이터 보존), 즉 ZDR이 이 기능에 어떻게 적용되는지는 API 및 데이터 보존을 참조하세요.
검색 결과 콘텐츠 블록을 사용하면 Claude가 웹 검색 결과를 인용하는 것과 동일한 방식으로 여러분의 콘텐츠를 인용할 수 있습니다. 각 인용에는 여러분이 제공한 소스와 제목이 포함됩니다. Claude가 여러분의 문서에 답변의 출처를 표시해야 하는 RAG(Retrieval-Augmented Generation, 검색 증강 생성) 애플리케이션에서 사용하세요.
Claude Haiku 3을 제외한 모든 활성 모델이 인용이 포함된 검색 결과를 지원합니다. 베타 헤더는 필요하지 않습니다. 검색 결과는 표준 Messages API의 일부입니다.
검색 결과는 두 가지 방법으로 제공할 수 있습니다:
두 경우 모두 인용이 활성화되면 Claude가 검색 결과를 자동으로 인용합니다. 특별한 프롬프팅은 필요하지 않습니다. 질문을 하면 여러분의 콘텐츠를 활용한 텍스트 블록에 인용이 나타납니다.
검색 결과는 다음 구조를 사용합니다:
{
"type": "search_result",
"source": "https://example.com/article", // Required: Source URL or identifier
"title": "Article Title", // Required: Title of the result
"content": [
// Required: Array of text blocks
{
"type": "text",
"text": "The actual content of the search result..."
}
],
"citations": {
// Optional: Citation configuration
"enabled": true // Enable/disable citations for this result
}
}| 필드 | 타입 | 설명 |
|---|---|---|
type | string | "search_result"여야 합니다 |
source | string | 콘텐츠의 소스입니다. 안정적인 문자열이면 무엇이든 가능합니다: URL 또는 kb://article-1234와 같은 내부 식별자 |
title | string | 검색 결과에 대한 설명적인 제목 |
content | array | 실제 콘텐츠를 포함하는 텍스트 블록의 배열 |
| 필드 | 타입 | 설명 |
|---|---|---|
citations | object | enabled Boolean 필드가 있는 인용 구성입니다. 인용은 기본적으로 비활성화되어 있으며, 이 페이지의 모든 예제는 "enabled": true를 명시적으로 설정합니다. 요청의 모든 검색 결과는 동일한 설정을 사용해야 합니다(인용 제어 참조) |
cache_control | object | 캐시 제어 설정(예: {"type": "ephemeral"}) |
content 배열의 각 항목은 다음을 포함하는 텍스트 블록이어야 합니다:
type: "text"여야 합니다text: 실제 텍스트 콘텐츠(비어 있지 않은 문자열)검색 결과는 텍스트만 포함합니다. 이미지 및 기타 미디어는 content 배열 내에서 지원되지 않습니다.
사용자 정의 도구에서 검색 결과를 반환하면 동적 RAG 애플리케이션이 가능해집니다. 도구가 런타임에 콘텐츠를 가져오고 Claude가 응답에서 이를 인용합니다. 다음 예제는 tool_choice로 도구 호출을 강제하므로 검색 단계가 매번 실행됩니다.
from anthropic.types import (
MessageParam,
TextBlockParam,
SearchResultBlockParam,
ToolResultBlockParam,
)
client = Anthropic()
# 지식 베이스 검색 도구 정의
knowledge_base_tool = {
"name": "search_knowledge_base",
"description": "Search the company knowledge base for information",
"input_schema": {
"type": "object",
"properties": {"query": {"type": "string", "description": "The search query"}},
"required": ["query"],
},
}
# 도구 호출을 처리하는 함수
def search_knowledge_base(query):
# 여기에 검색 로직을 작성하세요
# 올바른 형식으로 검색 결과를 반환합니다
return [
SearchResultBlockParam(
type="search_result",
source="https://docs.company.com/product-guide",
title="Product Configuration Guide",
content=[
TextBlockParam(
type="text",
text="To configure the product, navigate to Settings > Configuration. The default timeout is 30 seconds, but can be adjusted between 10-120 seconds based on your needs.",
)
],
citations={"enabled": True},
),
SearchResultBlockParam(
type="search_result",
source="https://docs.company.com/troubleshooting",
title="Troubleshooting Guide",
content=[
TextBlockParam(
type="text",
text="If you encounter timeout errors, first check the configuration settings. Common causes include network latency and incorrect timeout values.",
)
],
citations={"enabled": True},
),
]
# 사용자의 질문부터 시작하여 대화를 리스트로 구성합니다
messages = [
MessageParam(role="user", content="How do I configure the timeout settings?")
]
# 도구와 함께 메시지 생성
response = client.messages.create(
model="claude-opus-5",
max_tokens=1024,
tools=[knowledge_base_tool],
tool_choice={"type": "tool", "name": "search_knowledge_base"},
messages=messages,
)
# Claude가 도구를 호출하면 검색 결과를 제공합니다.
# tool_use 블록이 항상 첫 번째는 아니므로 반복하여 찾습니다.
tool_use = next((block for block in response.content if block.type == "tool_use"), None)
if tool_use is not None:
tool_result = search_knowledge_base(tool_use.input["query"])
# Claude의 턴과 도구 결과를 진행 중인 대화에 추가합니다
messages.append(MessageParam(role="assistant", content=response.content))
messages.append(
MessageParam(
role="user",
content=[
ToolResultBlockParam(
type="tool_result",
tool_use_id=tool_use.id,
content=tool_result, # Search results go here
)
],
)
)
# 도구 결과를 다시 전송합니다
final_response = client.messages.create(
model="claude-opus-5",
max_tokens=1024,
messages=messages,
)
print(final_response)사용자 메시지에 검색 결과를 직접 제공할 수도 있습니다. 이는 다음과 같은 경우에 유용합니다:
from anthropic.types import MessageParam, TextBlockParam, SearchResultBlockParam
client = Anthropic()
# 사용자 메시지에 검색 결과를 직접 제공합니다
response = client.messages.create(
model="claude-opus-5",
max_tokens=1024,
messages=[
MessageParam(
role="user",
content=[
SearchResultBlockParam(
type="search_result",
source="https://docs.company.com/api-reference",
title="API Reference - Authentication",
content=[
TextBlockParam(
type="text",
text="All API requests must include an API key in the Authorization header. Keys can be generated from the dashboard. Rate limits: 1000 requests per hour for standard tier, 10000 for premium.",
)
],
citations={"enabled": True},
),
SearchResultBlockParam(
type="search_result",
source="https://docs.company.com/quickstart",
title="Getting Started Guide",
content=[
TextBlockParam(
type="text",
text="To get started: 1) Sign up for an account, 2) Generate an API key from the dashboard, 3) Install our SDK using pip install company-sdk, 4) Initialize the client with your API key.",
)
],
citations={"enabled": True},
),
TextBlockParam(
type="text",
text="Based on these search results, how do I authenticate API requests and what are the rate limits?",
),
],
)
],
)
print(response)검색 결과가 어떻게 제공되든 관계없이, Claude는 검색 결과의 정보를 사용할 때 자동으로 인용을 포함합니다:
{
"role": "assistant",
"content": [
{
"type": "text",
"text": "All API requests must include an API key in the Authorization header. Keys can be generated from the dashboard.",
"citations": [
{
"type": "search_result_location",
"cited_text": "All API requests must include an API key in the Authorization header. Keys can be generated from the dashboard. Rate limits: 1000 requests per hour for standard tier, 10000 for premium.",
"source": "https://docs.company.com/api-reference",
"title": "API Reference - Authentication",
"search_result_index": 0,
"start_block_index": 0,
"end_block_index": 1
}
]
},
{
"type": "text",
"text": "\n\nTo set this up from scratch, you'll need to "
},
{
"type": "text",
"text": "sign up for an account, generate an API key from the dashboard, install the SDK using `pip install company-sdk`, and initialize the client with your API key.",
"citations": [
{
"type": "search_result_location",
"cited_text": "To get started: 1) Sign up for an account, 2) Generate an API key from the dashboard, 3) Install our SDK using pip install company-sdk, 4) Initialize the client with your API key.",
"source": "https://docs.company.com/quickstart",
"title": "Getting Started Guide",
"search_result_index": 1,
"start_block_index": 0,
"end_block_index": 1
}
]
}
]
}각 인용에는 다음이 포함됩니다:
| 필드 | 타입 | 설명 |
|---|---|---|
type | string | 검색 결과 인용의 경우 항상 "search_result_location" |
source | string | 원본 검색 결과의 소스 |
title | string 또는 null | 원본 검색 결과의 제목 |
cited_text | string | 인용된 블록의 전체 텍스트를 연결한 것입니다. content[start_block_index:end_block_index]의 내용을 합친 것과 같습니다. 출력 토큰에 포함되지 않습니다. |
search_result_index | integer | 요청의 모든 search_result 블록 중에서 인용된 검색 결과의 0 기반 인덱스로, 나타나는 순서대로입니다(모든 메시지 및 도구 결과에 걸쳐). |
start_block_index | integer | 검색 결과의 content 배열에서 첫 번째 인용된 블록의 0 기반 인덱스입니다. |
end_block_index | integer | 검색 결과의 content 배열에서 인용된 블록 범위의 배타적 끝 인덱스입니다. 항상 start_block_index보다 큽니다. |
블록 인덱스는 검색 결과의 content 배열의 슬라이스를 식별하며, cited_text는 해당 슬라이스의 전체 텍스트입니다. 텍스트 블록은 인용 가능한 최소 단위입니다. Claude는 블록 내의 부분 문자열이 아닌 전체 블록을 인용합니다. 더 세분화된 인용을 얻으려면 검색 결과 콘텐츠를 더 작은 블록으로 분할하세요(여러 콘텐츠 블록 참조).
검색 결과는 content 배열에 여러 텍스트 블록을 포함할 수 있습니다:
{
"type": "search_result",
"source": "https://docs.company.com/api-guide",
"title": "API Documentation",
"content": [
{
"type": "text",
"text": "Authentication: All API requests require an API key."
},
{
"type": "text",
"text": "Rate Limits: The API allows 1000 requests per hour per key."
},
{
"type": "text",
"text": "Error Handling: The API returns standard HTTP status codes."
}
],
"citations": { "enabled": true }
}속도 제한 블록을 참조하는 인용은 다음과 같습니다:
{
"type": "search_result_location",
"cited_text": "Rate Limits: The API allows 1000 requests per hour per key.",
"source": "https://docs.company.com/api-guide",
"title": "API Documentation",
"search_result_index": 0,
"start_block_index": 1,
"end_block_index": 2
}이 검색 결과가 인용되면 start_block_index와 end_block_index가 인용이 다루는 블록을 식별하고, cited_text에는 정확히 해당 블록들의 텍스트가 포함됩니다. 콘텐츠를 더 작고 집중된 블록으로 분할하면 Claude에게 더 세밀한 인용 경계를 제공합니다. 콘텐츠를 하나의 블록으로 결합하면 모든 인용이 전체 텍스트를 반환합니다. 이는 Citations 기능의 사용자 정의 콘텐츠 문서에서 사용되는 것과 동일한 모델입니다.
동일한 대화에서 두 방법을 혼합할 수 있습니다. Claude는 어느 소스에서든 인용하며, search_result_index는 소스에 관계없이 요청 순서대로 모든 search_result 블록을 계산합니다.
다음 예제는 완전한 대화를 재현합니다. 첫 번째 사용자 메시지는 미리 가져온 검색 결과를 포함하고, 어시스턴트 턴은 지식 베이스 도구를 호출하며, 도구 결과는 두 번째 검색 결과를 반환합니다. Claude의 답변은 두 소스를 모두 인용합니다:
from anthropic.types import (
MessageParam,
SearchResultBlockParam,
TextBlockParam,
ToolResultBlockParam,
ToolUseBlockParam,
)
client = Anthropic()
knowledge_base_tool = {
"name": "search_knowledge_base",
"description": "Search the company knowledge base for information",
"input_schema": {
"type": "object",
"properties": {"query": {"type": "string", "description": "The search query"}},
"required": ["query"],
},
}
# 검색 결과를 두 가지 방식으로 제공하는 대화를 재생합니다: 첫 번째
# 사용자 메시지는 미리 가져온 결과를 포함하고, 도구 결과(tool_result)는 또 다른 결과를 반환합니다
response = client.messages.create(
model="claude-opus-5",
max_tokens=1024,
tools=[knowledge_base_tool],
messages=[
MessageParam(
role="user",
content=[
SearchResultBlockParam(
type="search_result",
source="https://docs.company.com/overview",
title="Product Overview",
content=[
TextBlockParam(
type="text",
text="Acme Dashboard is a monitoring tool for distributed systems. It supports real-time alerting and custom metric dashboards.",
)
],
citations={"enabled": True},
),
TextBlockParam(
type="text",
text="What does Acme Dashboard do, and what plans is it available on?",
),
],
),
MessageParam(
role="assistant",
content=[
TextBlockParam(
type="text", text="Let me check the pricing information."
),
ToolUseBlockParam(
type="tool_use",
id="toolu_01A09q90qw90lq917835lq9",
name="search_knowledge_base",
input={"query": "Acme Dashboard pricing plans"},
),
],
),
MessageParam(
role="user",
content=[
ToolResultBlockParam(
type="tool_result",
tool_use_id="toolu_01A09q90qw90lq917835lq9",
content=[
SearchResultBlockParam(
type="search_result",
source="https://docs.company.com/pricing",
title="Pricing Plans",
content=[
TextBlockParam(
type="text",
text="Acme Dashboard is available on the Starter plan at $10 per user per month and the Enterprise plan with custom pricing.",
)
],
citations={"enabled": True},
)
],
)
],
),
],
)
print(response)응답은 두 소스를 모두 인용합니다. 미리 가져온 결과는 search_result_index: 0이고 도구가 반환한 결과는 search_result_index: 1로, 대화에서 search_result 블록이 나타나는 순서와 일치합니다:
{
"role": "assistant",
"content": [
{
"type": "text",
"text": "Here's what I found about Acme Dashboard:\n\n**What it does:** "
},
{
"type": "text",
"text": "Acme Dashboard is a monitoring tool for distributed systems. It supports real-time alerting and custom metric dashboards.",
"citations": [
{
"type": "search_result_location",
"cited_text": "Acme Dashboard is a monitoring tool for distributed systems. It supports real-time alerting and custom metric dashboards.",
"source": "https://docs.company.com/overview",
"title": "Product Overview",
"search_result_index": 0,
"start_block_index": 0,
"end_block_index": 1
}
]
},
{
"type": "text",
"text": "\n\n**Available plans:** "
},
{
"type": "text",
"text": "Acme Dashboard is available on the Starter plan at $10 per user per month and the Enterprise plan with custom pricing.",
"citations": [
{
"type": "search_result_location",
"cited_text": "Acme Dashboard is available on the Starter plan at $10 per user per month and the Enterprise plan with custom pricing.",
"source": "https://docs.company.com/pricing",
"title": "Pricing Plans",
"search_result_index": 1,
"start_block_index": 0,
"end_block_index": 1
}
]
}
]
}사용자 메시지에서 search_result 블록은 다른 모든 콘텐츠 블록과 함께 배치될 수 있습니다. 방법 2 예제는 검색 결과를 text 질문과 함께 사용하며, 이미지 또는 문서 블록도 같은 방식으로 함께 사용할 수 있습니다.
도구 결과는 더 엄격합니다. tool_result 콘텐츠 배열의 블록 중 하나라도 search_result이면 모든 블록이 search_result여야 합니다. 동일한 도구 결과에서 검색 결과를 다른 블록 타입과 혼합하면 유효성 검사 오류가 반환됩니다. 도구에서 가져온 검색 결과와 함께 보조 텍스트를 반환하려면, 검색 결과 중 하나의 content 배열 내에 텍스트 블록으로 포함하세요. 그러면 해당 텍스트도 인용 가능해집니다.
검색 결과 블록에 cache_control을 추가하여 요청 간 재사용을 위해 캐시할 수 있습니다. 이는 동일한 블록에서 citations와 함께 배치됩니다:
{
"type": "search_result",
"source": "https://docs.company.com/guide",
"title": "User Guide",
"content": [{ "type": "text", "text": "..." }],
"citations": { "enabled": true },
"cache_control": { "type": "ephemeral" }
}최소 캐시 가능 길이 및 기타 요구 사항은 프롬프트 캐싱을 참조하세요.
기본적으로 검색 결과에 대한 인용은 비활성화되어 있습니다. citations 구성을 명시적으로 설정하여 인용을 활성화할 수 있습니다:
{
"type": "search_result",
"source": "https://docs.company.com/guide",
"title": "User Guide",
"content": [{ "type": "text", "text": "Important documentation..." }],
"citations": {
"enabled": true // Enable citations for this result
}
}citations.enabled가 true로 설정되면 Claude는 검색 결과를 활용하는 텍스트 블록에 인용 참조를 첨부합니다.
인용은 전부 아니면 전무입니다. 요청의 모든 검색 결과에 인용이 활성화되어 있거나 모두 비활성화되어 있어야 합니다. 서로 다른 인용 설정을 가진 검색 결과를 혼합하면 오류가 발생합니다.
결과를 효과적으로 구조화하세요:
일관성을 유지하세요:
오류를 우아하게 처리하세요: 검색이 실패하거나 아무것도 반환하지 않을 때, 오류를 발생시키는 대신 결과를 설명하는 일반 텍스트 블록(예: {"type": "text", "text": "No results found."})을 반환하세요. Claude가 사용자에게 빈 결과를 설명하고 대화가 계속됩니다.
search_result 블록은 사용자 메시지(도구 결과 내부 포함)에만 나타날 수 있습니다. 검색 결과가 포함된 어시스턴트 메시지는 거부됩니다.search_result 블록에서 인용이 활성화되어야 합니다.스트리밍 응답에서 거부 중지 이유를 감지하고 처리하며, 거부된 요청을 대체 모델에서 재시도하세요.
Claude의 응답을 소스 문서에 근거하게 하세요. 인용은 각 주장을 뒷받침하는 정확한 구절을 반환하므로 답변을 검증하고 사용자에게 소스를 표시할 수 있습니다.
인용된 소스, 선택적 동적 필터링 및 도메인 제어와 함께 Claude에게 최신 웹 콘텐츠에 대한 액세스를 제공하세요.
콘텐츠 블록 타입을 포함한 전체 Messages API 문서를 확인하세요.
cache_control로 검색 결과를 캐시하여 반복 요청의 비용과 지연 시간을 줄이세요.
Was this page helpful?