Claude Platform Docs
Messages모델 기능

검색 결과

출처 표시가 포함된 검색 결과를 제공하여 RAG 애플리케이션에서 자연스러운 인용을 얻으세요

제품별로 사용법이 다릅니다

Messages API
도구 결과 또는 사용자 메시지에 직접 search_result 블록을 보내세요.
Managed Agents
user.custom_tool_result 이벤트와 같은 도구 결과에서만 허용되며, user.message 이벤트에서는 허용되지 않습니다.

검색 결과 콘텐츠 블록을 사용하면 Claude가 웹 검색 결과를 인용하는 것과 같은 방식으로 사용자의 자체 콘텐츠를 인용할 수 있습니다. 각 인용에는 사용자가 제공한 출처와 제목이 포함됩니다. Claude가 답변의 근거를 사용자의 문서에 귀속시켜야 하는 “Retrieval-Augmented Generation”(검색 증강 생성), 즉 RAG 애플리케이션에서 이를 사용하세요.

작동 방식

검색 결과는 두 가지 방법으로 제공할 수 있습니다:

  1. 도구 호출에서: 사용자 정의 도구가 검색 결과를 반환하므로 동적 RAG 애플리케이션을 구축할 수 있습니다.
  2. 최상위 콘텐츠로: 미리 가져왔거나 캐시된 콘텐츠의 경우 사용자 메시지에 검색 결과를 직접 제공합니다.

두 경우 모두 인용이 활성화되어 있으면 Claude가 검색 결과를 자동으로 인용합니다. 특별한 프롬프트는 필요하지 않습니다. 질문을 하면 사용자의 콘텐츠를 활용한 텍스트 블록에 인용이 나타납니다. 하지만 프롬프트에서 JSON만 요청하면 응답에 인용이 거의 또는 전혀 포함되지 않을 수 있습니다. 각 값에 대한 인용과 함께 구조화된 데이터를 추출하려면 인용과 함께 구조화된 데이터 가져오기를 참조하세요.

검색 결과 스키마

검색 결과는 다음 구조를 사용합니다:

{
  "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
  }
}

필수 필드

필드타입설명
typestring반드시 "search_result"여야 합니다
sourcestring콘텐츠의 출처입니다. 안정적인 문자열이면 무엇이든 사용할 수 있습니다: URL 또는 kb://article-1234와 같은 내부 식별자
titlestring검색 결과를 설명하는 제목
contentarray실제 콘텐츠를 담은 텍스트 블록의 배열

선택 필드

필드타입설명
citationsobjectenabled boolean 필드가 있는 인용 구성입니다. 인용은 기본적으로 비활성화되어 있으며, 이 페이지의 모든 예제는 "enabled": true를 명시적으로 설정합니다. 요청 내의 모든 검색 결과는 동일한 설정을 사용해야 합니다(인용 제어 참조)
cache_controlobject캐시 제어 설정(예: {"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: list[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",
        "disable_parallel_tool_use": True,
    },
    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({"role": "assistant", "content": response.content})
    messages.append(
        {
            "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 TextBlockParam, SearchResultBlockParam

client = Anthropic()

# 사용자 메시지에 검색 결과를 직접 제공합니다
response = client.messages.create(
    model="claude-opus-5-5",
    max_tokens=1024,
    messages=[
        {
            "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
        }
      ]
    }
  ]
}

인용 필드

각 인용에는 다음이 포함됩니다:

필드타입설명
typestring검색 결과 인용의 경우 항상 "search_result_location"입니다
sourcestring원본 검색 결과의 출처
titlestring 또는 null원본 검색 결과의 제목
cited_textstring인용된 블록들의 전체 텍스트를 이어 붙인 것입니다. content[start_block_index:end_block_index]의 내용을 합친 것과 같습니다. 출력 토큰에 포함되지 않습니다.
search_result_indexinteger요청 내 모든 search_result 블록 중에서 인용된 검색 결과의 0부터 시작하는 인덱스이며, 나타나는 순서를 따릅니다(모든 메시지와 도구 결과 전체에 걸쳐).
start_block_indexinteger검색 결과의 content 배열에서 인용된 첫 번째 블록의 0부터 시작하는 인덱스입니다.
end_block_indexinteger검색 결과의 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가 더 세밀한 인용 경계를 가질 수 있고, 콘텐츠를 하나의 블록으로 합치면 모든 인용이 전체 텍스트를 반환합니다. 이는 인용 기능의 사용자 정의 콘텐츠 문서에서 사용하는 것과 동일한 모델입니다.

고급 사용법

두 방법 결합하기

같은 대화에서 두 방법을 함께 사용할 수 있습니다. Claude는 어느 출처에서든 인용하며, search_result_index는 출처와 관계없이 요청 순서대로 모든 search_result 블록을 셉니다.

다음 예제는 전체 대화를 재현합니다. 첫 번째 사용자 메시지에는 미리 가져온 검색 결과가 담겨 있고, 어시스턴트 턴은 지식 베이스 도구를 호출하며, 도구 결과는 두 번째 검색 결과를 반환합니다. Claude의 답변은 두 출처를 모두 인용합니다:

from anthropic.types import (
    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=[
        {
            "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?",
                ),
            ],
        },
        {
            "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"},
                ),
            ],
        },
        {
            "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)

  • 미리 가져온 콘텐츠: 이미 검색 결과가 있을 때 사용하세요
  • 배치 처리: 여러 검색 결과를 한 번에 처리할 때 사용하세요
  • 테스트: 알려진 콘텐츠로 인용 동작을 테스트할 때 사용하세요

일반 모범 사례

  1. 결과를 효과적으로 구조화하세요:

    • 명확하고 영구적인 출처 URL을 사용하세요
    • 설명적인 제목을 제공하세요
    • Claude가 더 세밀한 인용 경계를 가질 수 있도록 긴 콘텐츠를 논리적인 텍스트 블록으로 나누세요
  2. 일관성을 유지하세요:

    • 애플리케이션 전반에서 일관된 출처 형식을 사용하세요
    • 제목이 콘텐츠를 정확하게 반영하도록 하세요
    • 서식을 일관되게 유지하세요
  3. 오류를 원활하게 처리하세요: 검색이 실패하거나 아무것도 반환하지 않으면, 오류를 발생시키는 대신 결과를 설명하는 일반 텍스트 블록(예: {"type": "text", "text": "No results found."})을 반환하세요. 그러면 Claude가 사용자에게 빈 결과를 설명하고 대화가 계속됩니다.

제한 사항

  • 검색 결과 내에서는 텍스트 콘텐츠만 지원됩니다(이미지나 기타 미디어는 지원되지 않음).
  • search_result 블록은 사용자 메시지(도구 결과 내부 포함)에만 나타날 수 있습니다. 검색 결과가 포함된 어시스턴트 메시지는 거부됩니다.
  • 같은 요청에서 웹 검색 도구가 활성화된 경우, 모든 search_result 블록에서 인용이 활성화되어 있어야 합니다.

다음 단계

스트리밍 응답에서 거부 중지 사유를 감지 및 처리하고, 거부된 요청을 대체 모델에서 재시도하세요.

Claude의 응답을 여러분의 소스 문서에 근거하도록 하세요. 인용은 각 주장을 뒷받침하는 정확한 구절을 반환하므로 답변을 검증하고 사용자에게 출처를 보여줄 수 있습니다.

인용된 출처, 선택적 동적 필터링 및 도메인 제어와 함께 Claude가 최신 웹 콘텐츠에 접근할 수 있도록 하세요.

콘텐츠 블록 유형을 포함한 전체 Messages API 문서를 확인하세요.

cache_control로 검색 결과를 캐시하여 반복 요청의 비용과 지연 시간을 줄이세요.

제공 여부

검색 결과은(는) 모든 모델에서 사용 가능 상태이며 제로 데이터 보존 및 HIPAA 대비에 적격합니다.

API 지원

사용법

도구 결과 또는 사용자 메시지에 직접 search_result 블록을 보내세요.

상태사용 가능
클라우드 플랫폼

사용법

user.custom_tool_result 이벤트와 같은 도구 결과에서만 허용되며, user.message 이벤트에서는 허용되지 않습니다.

상태사용 가능
클라우드 플랫폼

데이터 처리

데이터 처리 개요

적용 엔드포인트

  • /v1/messages search_results 소스 사용 시
제로 데이터 보존적격

적용 모델 제외

HIPAA적격

이 페이지가 도움이 되었나요?