검색 결과
출처 표시가 포함된 검색 결과를 제공하여 RAG 애플리케이션에서 자연스러운 인용을 활성화합니다
검색 결과 콘텐츠 블록을 사용하면 Claude가 웹 검색 결과를 인용하는 것과 동일한 방식으로 여러분의 자체 콘텐츠를 인용할 수 있습니다. 각 인용에는 여러분이 제공한 출처와 제목이 포함됩니다. Claude가 답변의 출처를 여러분의 문서로 표시해야 하는 "Retrieval-Augmented Generation"(검색 증강 생성), 즉 RAG 애플리케이션에서 사용하세요.
Claude Haiku 3을 제외한 모든 활성 모델이 인용이 포함된 검색 결과를 지원합니다. 베타 헤더는 필요하지 않습니다. 검색 결과는 표준 Messages API의 일부입니다.
작동 방식
검색 결과는 두 가지 방법으로 제공할 수 있습니다:
- 도구 호출에서: 사용자 정의 도구가 검색 결과를 반환하여 동적 RAG 애플리케이션을 구현할 수 있습니다
- 최상위 콘텐츠로: 미리 가져온 콘텐츠나 캐시된 콘텐츠를 위해 사용자 메시지에 검색 결과를 직접 제공합니다
두 경우 모두 인용이 활성화되어 있으면 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 배열 내에서 이미지 및 기타 미디어는 지원되지 않습니다.
방법 1: 도구 호출에서 검색 결과 반환
사용자 정의 도구에서 검색 결과를 반환하면 동적 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)방법 2: 최상위 콘텐츠로 검색 결과 제공
사용자 메시지에 검색 결과를 직접 제공할 수도 있습니다. 이는 다음과 같은 경우에 유용합니다:
- 검색 인프라에서 미리 가져온 콘텐츠
- 이전 쿼리에서 캐시된 검색 결과
- 외부 검색 서비스의 콘텐츠
- 테스트 및 개발
예제: 직접 검색 결과
from anthropic.types import MessageParam, TextBlockParam, SearchResultBlockParam
client = Anthropic()
# 사용자 메시지에 검색 결과를 직접 제공합니다
response = client.messages.create(
model="claude-opus-5-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의 응답
검색 결과가 어떤 방식으로 제공되든, 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 배열에서 인용된 블록 범위의 배타적(exclusive) 끝 인덱스. 항상 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에게 더 세밀한 인용 경계를 제공하며, 콘텐츠를 하나의 블록으로 합치면 모든 인용이 전체 텍스트를 반환합니다. 이는 인용 기능의 사용자 정의 콘텐츠 문서에서 사용하는 것과 동일한 모델입니다.
고급 사용법
두 방법 결합하기
같은 대화에서 두 방법을 혼합할 수 있습니다. 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"],
},
}
# 검색 결과를 두 가지 방식으로 모두 제공하는 대화를 재현합니다. 첫 번째
# 사용자 메시지에는 미리 가져온 결과가 담기고, 도구 결과는 또 다른 결과를 반환합니다
response = client.messages.create(
model="claude-opus-5-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는 검색 결과를 참고한 텍스트 블록에 인용 참조를 첨부합니다.
모범 사례
도구 기반 검색(방법 1)의 경우
- 동적 콘텐츠: 실시간 검색 및 동적 RAG 애플리케이션에 사용하세요
- 오류 처리: 검색이 실패하면 적절한 메시지를 반환하세요
- 결과 제한: 컨텍스트 오버플로를 방지하기 위해 가장 관련성 높은 결과만 반환하세요
최상위 검색(방법 2)의 경우
- 미리 가져온 콘텐츠: 이미 검색 결과가 있을 때 사용하세요
- 배치 처리: 여러 검색 결과를 한 번에 처리하는 데 이상적입니다
- 테스트: 알려진 콘텐츠로 인용 동작을 테스트하는 데 적합합니다
일반 모범 사례
-
결과를 효과적으로 구조화하세요:
- 명확하고 영구적인 출처 URL을 사용하세요
- 설명적인 제목을 제공하세요
- 긴 콘텐츠를 논리적인 텍스트 블록으로 나누어 Claude에게 더 세밀한 인용 경계를 제공하세요
-
일관성을 유지하세요:
- 애플리케이션 전반에서 일관된 출처 형식을 사용하세요
- 제목이 콘텐츠를 정확히 반영하도록 하세요
- 형식을 일관되게 유지하세요
-
오류를 우아하게 처리하세요: 검색이 실패하거나 아무것도 반환하지 않을 때, 오류를 발생시키는 대신 결과를 설명하는 일반 텍스트 블록(예:
{"type": "text", "text": "No results found."})을 반환하세요. Claude가 사용자에게 빈 결과를 설명하고 대화가 계속됩니다.
제한 사항
- 검색 결과 콘텐츠 블록은 Claude API, Amazon Bedrock, Google Cloud에서 사용할 수 있습니다.
- 검색 결과 내에서는 텍스트 콘텐츠만 지원됩니다(이미지나 기타 미디어는 지원되지 않음).
search_result블록은 사용자 메시지(도구 결과 내부 포함)에만 나타날 수 있습니다. 검색 결과가 포함된 어시스턴트 메시지는 거부됩니다.- 같은 요청에서 웹 검색 도구가 활성화되어 있으면 모든
search_result블록에서 인용이 활성화되어야 합니다.
다음 단계
스트리밍 응답에서 거부 중단 사유를 감지하고 처리하며, 거부된 요청을 대체 모델에서 재시도합니다.
Claude의 응답을 여러분의 원본 문서에 근거하도록 합니다. 인용은 각 주장을 뒷받침하는 정확한 구절을 반환하므로, 답변을 검증하고 사용자에게 출처를 표시할 수 있습니다.
인용된 출처, 선택적 동적 필터링, 도메인 제어와 함께 Claude에게 최신 웹 콘텐츠에 대한 접근 권한을 부여합니다.
콘텐츠 블록 타입을 포함한 전체 Messages API 문서를 확인하세요.
cache_control로 검색 결과를 캐시하여 반복 요청 시 비용과 지연 시간을 줄이세요.
Was this page helpful?