Tính năng Search Results cho RAG Applications trên Claude API
Trust: ★★★☆☆ (0.90) · 0 validations · factual
Published: 2026-05-09 · Source: crawler_authoritative
Tình huống
Tính năng Claude API cho phép tích hợp citations với source attribution trong ứng dụng RAG (Retrieval-Augmented Generation). Hỗ trợ các model: Claude Opus 4.7 (claude-opus-4-7), Claude Opus 4.6, Claude Sonnet 4.6, Claude Sonnet 4.5, Claude Opus 4.5, Claude Opus 4.1, Claude Haiku 4.5. Một số model đã deprecated: Claude Opus 4, Claude Sonnet 4, Claude Sonnet 3.7, Claude Haiku 3.5.
Insight
Search results content blocks cho phép citations tự nhiên với proper source attribution, mang chất lượng citations của web search đến custom applications. Tính năng này đặc biệt mạnh mẽ cho RAG applications nơi cần Claude trích dẫn nguồn chính xác. Schema gồm: type phải là ‘search_result’, source (URL hoặc identifier), title, content (array of text blocks với type ‘text’ và text content không rỗng). Optional fields: citations (config với enabled boolean), cache_control (ví dụ {“type”: “ephemeral”}). Mặc định citations bị disabled; phải set enabled: true để kích hoạt. Citations are all-or-nothing: tất cả search results phải cùng citation setting. Supported trên Claude API, Amazon Bedrock, Vertex AI. Chỉ hỗ trợ text content, không hỗ trợ images hay media khác. Content array phải chứa ít nhất 1 text block.
Hành động
Có 2 cách cung cấp search results: (1) Từ tool calls - định nghĩa custom tool với name, description, input_schema. Khi Claude gọi tool, trả về SearchResultBlockParam với type=‘search_result’, source, title, content array, và citations={‘enabled’: true}. (2) Top-level content - cung cấp trực tiếp trong user message. Citation fields output gồm: type=‘search_result_location’, source, title, cited_text, search_result_index (0-based), start_block_index, end_block_index. Để có finer-grained citations, chia content thành nhiều text blocks nhỏ. Sử dụng cache_control {‘type’: ‘ephemeral’} để tối ưu performance. Best practices: Dùng source URLs rõ ràng và permanent, titles mô tả chính xác, tách content dài thành logical blocks, xử lý lỗi gracefully khi search fails, giới hạn số results để tránh context overflow.
Điều kiện áp dụng
Áp dụng cho developers xây dựng RAG applications cần citations tự động. Chỉ hỗ trợ text content. Feature available trên Claude API, Amazon Bedrock, và Google Cloud Vertex AI. Tất cả search results trong request phải cùng citation setting (enabled hoặc disabled).
Nội dung gốc (Original)
Search results
Enable natural citations for RAG applications by providing search results with source attribution
Search result content blocks enable natural citations with proper source attribution, bringing web search-quality citations to your custom applications. This feature is particularly powerful for RAG (Retrieval-Augmented Generation) applications where you need Claude to cite sources accurately.
The search results feature is available on the following models:
- Claude Opus 4.7 (
claude-opus-4-7) - Claude Opus 4.6 (
claude-opus-4-6) - Claude Sonnet 4.6 (
claude-sonnet-4-6) - Claude Sonnet 4.5 (
claude-sonnet-4-5-20250929) - Claude Opus 4.5 (
claude-opus-4-5-20251101) - Claude Opus 4.1 (
claude-opus-4-1-20250805) - Claude Opus 4 (deprecated) (
claude-opus-4-20250514) - Claude Sonnet 4 (deprecated) (
claude-sonnet-4-20250514) - Claude Sonnet 3.7 (deprecated) (
claude-3-7-sonnet-20250219) - Claude Haiku 4.5 (
claude-haiku-4-5-20251001) - Claude Haiku 3.5 (deprecated) (
claude-3-5-haiku-20241022)
Key benefits
- Natural citations: Achieve the same citation quality as web search for any content
- Flexible integration: Use in tool returns for dynamic RAG or as top-level content for pre-fetched data
- Proper source attribution: Each result includes source and title information for clear attribution
- No document workarounds needed: Eliminates the need for document-based workarounds
- Consistent citation format: Matches the citation quality and format of Claude’s web search functionality
How it works
Search results can be provided in two ways:
- From tool calls: Your custom tools return search results, enabling dynamic RAG applications
- As top-level content: You provide search results directly in user messages for pre-fetched or cached content
In both cases, Claude can automatically cite information from the search results with proper source attribution.
Search result schema
Search results use the following structure:
{
"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
}
}Required fields
| Field | Type | Description |
|---|---|---|
type | string | Must be "search_result" |
source | string | The source URL or identifier for the content |
title | string | A descriptive title for the search result |
content | array | An array of text blocks containing the actual content |
Optional fields
| Field | Type | Description |
|---|---|---|
citations | object | Citation configuration with enabled boolean field |
cache_control | object | Cache control settings (e.g., {"type": "ephemeral"}) |
Each item in the content array must be a text block with:
type: Must be"text"text: The actual text content (non-empty string)
Method 1: Search results from tool calls
The most powerful use case is returning search results from your custom tools. This enables dynamic RAG applications where tools fetch and return relevant content with automatic citations.
Example: Knowledge base tool
from anthropic import Anthropic
from anthropic.types import (
MessageParam,
TextBlockParam,
SearchResultBlockParam,
ToolResultBlockParam,
)
client = Anthropic()
# Define a knowledge base search tool
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"],
},
}
# Function to handle the tool call
def search_knowledge_base(query):
# Your search logic here
# Returns search results in the correct format
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},
),
]
# Create a message with the tool
response = client.messages.create(
model="claude-opus-4-7", # Works with all supported models
max_tokens=1024,
tools=[knowledge_base_tool],
messages=[
MessageParam(role="user", content="How do I configure the timeout settings?")
],
)
# When Claude calls the tool, provide the search results
if response.content[0].type == "tool_use":
tool_result = search_knowledge_base(response.content[0].input["query"])
# Send the tool result back
final_response = client.messages.create(
model="claude-opus-4-7", # Works with all supported models
max_tokens=1024,
messages=[
MessageParam(
role="user", content="How do I configure the timeout settings?"
),
MessageParam(role="assistant", content=response.content),
MessageParam(
role="user",
content=[
ToolResultBlockParam(
type="tool_result",
tool_use_id=response.content[0].id,
content=tool_result, # Search results go here
)
],
),
],
)import Anthropic from "@anthropic-ai/sdk";
const anthropic = new Anthropic();
// Define a knowledge base search tool
const knowledgeBaseTool: Anthropic.Messages.Tool = {
name: "search_knowledge_base",
description: "Search the company knowledge base for information",
input_schema: {
type: "object" as const,
properties: {
query: {
type: "string",
description: "The search query"
}
},
required: ["query"]
}
};
// Function to handle the tool call
function searchKnowledgeBase(query: string) {
// Your search logic here
// Returns search results in the correct format
return [
{
type: "search_result" as const,
source: "https://docs.company.com/product-guide",
title: "Product Configuration Guide",
content: [
{
type: "text" as const,
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 }
},
{
type: "search_result" as const,
source: "https://docs.company.com/troubleshooting",
title: "Troubleshooting Guide",
content: [
{
type: "text" as const,
text: "If you encounter timeout errors, first check the configuration settings. Common causes include network latency and incorrect timeout values."
}
],
citations: { enabled: true }
}
];
}
// Create a message with the tool
const response = await anthropic.messages.create({
model: "claude-opus-4-7", // Works with all supported models
max_tokens: 1024,
tools: [knowledgeBaseTool],
messages: [
{
role: "user",
content: "How do I configure the timeout settings?"
}
]
});
// Handle tool use and provide results
if (response.content[0].type === "tool_use") {
const input = response.content[0].input as { query: string };
const toolResult = searchKnowledgeBase(input.query);
const finalResponse = await anthropic.messages.create({
model: "claude-opus-4-7", // Works with all supported models
max_tokens: 1024,
messages: [
{ role: "user", content: "How do I configure the timeout settings?" },
{ role: "assistant", content: response.content },
{
role: "user",
content: [
{
type: "tool_result" as const,
tool_use_id: response.content[0].id,
content: toolResult // Search results go here
}
]
}
]
});
}using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Anthropic;
using Anthropic.Models.Messages;
public class Program
{
public static async Task Main(string[] args)
{
AnthropicClient client = new();
var knowledgeBaseTool = new Tool
{
Name = "search_knowledge_base",
Description = "Search the company knowledge base for information",
InputSchema = new
{
type = "object",
properties = new
{
query = new
{
type = "string",
description = "The search query"
}
},
required = new[] { "query" }
}
};
var parameters = new MessageCreateParams
{
Model = Model.ClaudeOpus4_7,
MaxTokens = 1024,
Tools = new[] { knowledgeBaseTool },
Messages = new[]
{
new MessageParam
{
Role = Role.User,
Content = "How do I configure the timeout settings?"
}
}
};
var response = await client.Messages.Create(parameters);
if (response.Content[0] is ToolUseBlock toolUse)
{
var toolResult = SearchKnowledgeBase(toolUse.Input["query"].ToString());
var finalParameters = new MessageCreateParams
{
Model = Model.ClaudeOpus4_7,
MaxTokens = 1024,
Messages = new[]
{
new MessageParam { Role = Role.User, Content = "How do I configure the timeout settings?" },
new MessageParam { Role = Role.Assistant, Content = response.Content },
new MessageParam
{
Role = Role.User,
Content = new[]
{
new ToolResultBlockParam
{
ToolUseID = toolUse.Id,
Content = toolResult
}
}
}
}
};
var finalResponse = await client.Messages.Create(finalParameters);
Console.WriteLine(finalResponse);
}
}
private static List<SearchResultBlockParam> SearchKnowledgeBase(string query)
{
return new List<SearchResultBlockParam>
{
new SearchResultBlockParam
{
Source = "https://docs.company.com/product-guide",
Title = "Product Configuration Guide",
Content = new[]
{
new TextBlockParam
{
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 = new CitationsConfigParam { Enabled = true }
},
new SearchResultBlockParam
{
Source = "https://docs.company.com/troubleshooting",
Title = "Troubleshooting Guide",
Content = new[]
{
new TextBlockParam
{
Text = "If you encounter timeout errors, first check the configuration settings. Common causes include network latency and incorrect timeout values."
}
},
Citations = new CitationsConfigParam { Enabled = true }
}
};
}
}package main
import (
"context"
"encoding/json"
"fmt"
"log"
"github.com/anthropics/anthropic-sdk-go"
)
func main() {
client := anthropic.NewClient()
knowledgeBaseTool := anthropic.ToolUnionParam{
OfTool: &anthropic.ToolParam{
Name: "search_knowledge_base",
Description: anthropic.String("Search the company knowledge base for information"),
InputSchema: anthropic.ToolInputSchemaParam{
Properties: map[string]any{
"query": map[string]any{
"type": "string",
"description": "The search query",
},
},
Required: []string{"query"},
},
},
}
response, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
Model: anthropic.ModelClaudeOpus4_7,
MaxTokens: 1024,
Tools: []anthropic.ToolUnionParam{knowledgeBaseTool},
Messages: []anthropic.MessageParam{
anthropic.NewUserMessage(anthropic.NewTextBlock("How do I configure the timeout settings?")),
},
})
if err != nil {
log.Fatal(err)
}
for _, block := range response.Content {
switch variant := block.AsAny().(type) {
case anthropic.ToolUseBlock:
var input struct {
Query string `json:"query"`
}
if err := json.Unmarshal(variant.Input, &input); err != nil {
log.Fatal(err)
}
toolResults := searchKnowledgeBase(input.Query)
// Build assistant message from the response
assistantParam := response.ToParam()
finalResponse, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
Model: anthropic.ModelClaudeOpus4_7,
MaxTokens: 1024,
Messages: []anthropic.MessageParam{
anthropic.NewUserMessage(anthropic.NewTextBlock("How do I configure the timeout settings?")),
assistantParam,
anthropic.NewUserMessage(anthropic.ContentBlockParamUnion{
OfToolResult: &anthropic.ToolResultBlockParam{
ToolUseID: variant.ID,
Content: toolResults,
},
}),
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(finalResponse)
}
}
}
func searchKnowledgeBase(query string) []anthropic.ToolResultBlockParamContentUnion {
return []anthropic.ToolResultBlockParamContentUnion{
{OfSearchResult: &anthropic.SearchResultBlockParam{
Content: []anthropic.TextBlockParam{
{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."},
},
Source: "https://docs.company.com/product-guide",
Title: "Product Configuration Guide",
Citations: anthropic.CitationsConfigParam{Enabled: anthropic.Bool(true)},
}},
{OfSearchResult: &anthropic.SearchResultBlockParam{
Content: []anthropic.TextBlockParam{
{Text: "If you encounter timeout errors, first check the configuration settings. Common causes include network latency and incorrect timeout values."},
},
Source: "https://docs.company.com/troubleshooting",
Title: "Troubleshooting Guide",
Citations: anthropic.CitationsConfigParam{Enabled: anthropic.Bool(true)},
}},
}
}import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;
import com.anthropic.models.messages.ContentBlockParam;
import com.anthropic.models.messages.CitationsConfigParam;
import com.anthropic.models.messages.MessageCreateParams;
import com.anthropic.models.messages.Message;
import com.anthropic.models.messages.Model;
import com.anthropic.models.messages.SearchResultBlockParam;
import com.anthropic.models.messages.TextBlockParam;
import com.anthropic.models.messages.Tool;
import com.anthropic.models.messages.ToolResultBlockParam;
import com.anthropic.models.messages.ToolUseBlock;
import com.anthropic.models.messages.ToolUseBlockParam;
import com.anthropic.core.JsonValue;
import java.util.List;
import java.util.Map;
public class SearchKnowledgeBaseExample {
public static void main(String[] args) {
AnthropicClient client = AnthropicOkHttpClient.fromEnv();
Tool knowledgeBaseTool = Tool.builder()
.name("search_knowledge_base")
.description("Search the company knowledge base for information")
.inputSchema(Tool.InputSchema.builder()
.properties(JsonValue.from(Map.of(
"query", Map.of(
"type", "string",
"description", "The search query"
)
)))
.putAdditionalProperty("required", JsonValue.from(List.of("query")))
.build())
.build();
MessageCreateParams params = MessageCreateParams.builder()
.model(Model.CLAUDE_OPUS_4_7)
.maxTokens(1024L)
.addTool(knowledgeBaseTool)
.addUserMessage("How do I configure the timeout settings?")
.build();
Message response = client.messages().create(params);
response.content().get(0).toolUse().ifPresent(toolUse -> {
List<ContentBlockParam> toolResult = searchKnowledgeBase(
(String) ((Map<?, ?>) toolUse._input()).get("query")
);
MessageCreateParams finalParams = MessageCreateParams.builder()
.model(Model.CLAUDE_OPUS_4_7)
.maxTokens(1024L)
.addTool(knowledgeBaseTool)
.addUserMessage("How do I configure the timeout settings?")
.addAssistantMessageOfBlockParams(List.of(
ContentBlockParam.ofToolUse(ToolUseBlockParam.builder()
.id(toolUse.id())
.name(toolUse.name())
.input(toolUse._input())
.build())
))
.addUserMessageOfBlockParams(List.of(
ContentBlockParam.ofToolResult(
ToolResultBlockParam.builder()
.toolUseId(toolUse.id())
.contentOfBlockParams(toolResult)
.build()
)
))
.build();
Message finalResponse = client.messages().create(finalParams);
System.out.println(finalResponse);
});
}
private static List<ContentBlockParam> searchKnowledgeBase(String query) {
return List.of(
ContentBlockParam.ofSearchResult(
SearchResultBlockParam.builder()
.source("https://docs.company.com/product-guide")
.title("Product Configuration Guide")
.content(List.of(
TextBlockParam.builder()
.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.")
.build()
))
.citations(CitationsConfigParam.builder().enabled(true).build())
.build()
),
ContentBlockParam.ofSearchResult(
SearchResultBlockParam.builder()
.source("https://docs.company.com/troubleshooting")
.title("Troubleshooting Guide")
.content(List.of(
TextBlockParam.builder()
.text("If you encounter timeout errors, first check the configuration settings. Common causes include network latency and incorrect timeout values.")
.build()
))
.citations(CitationsConfigParam.builder().enabled(true).build())
.build()
)
);
}
}<?php
use Anthropic\Client;
$client = new Client(apiKey: getenv("ANTHROPIC_API_KEY"));
$knowledgeBaseTool = [
'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']
]
];
function searchKnowledgeBase($query) {
return [
[
'type' => 'search_result',
'source' => 'https://docs.company.com/product-guide',
'title' => 'Product Configuration Guide',
'content' => [
[
'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]
],
[
'type' => 'search_result',
'source' => 'https://docs.company.com/troubleshooting',
'title' => 'Troubleshooting Guide',
'content' => [
[
'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]
]
];
}
$response = $client->messages->create(
maxTokens: 1024,
messages: [
['role' => 'user', 'content' => 'How do I configure the timeout settings?']
],
model: 'claude-opus-4-7',
tools: [$knowledgeBaseTool],
);
$toolUseBlock = null;
foreach ($response->content as $block) {
if ($block->type === 'tool_use') {
$toolUseBlock = $block;
break;
}
}
if ($toolUseBlock !== null) {
$toolResult = searchKnowledgeBase($toolUseBlock->input['query']);
$finalResponse = $client->messages->create(
maxTokens: 1024,
messages: [
['role' => 'user', 'content' => 'How do I configure the timeout settings?'],
['role' => 'assistant', 'content' => $response->content],
[
'role' => 'user',
'content' => [
[
'type' => 'tool_result',
'tool_use_id' => $toolUseBlock->id,
'content' => $toolResult
]
]
]
],
model: 'claude-opus-4-7',
);
echo $finalResponse;
} else {
echo $response;
}require "anthropic"
client = Anthropic::Client.new
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)
[
{
type: "search_result",
source: "https://docs.company.com/product-guide",
title: "Product Configuration Guide",
content: [
{
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 }
},
{
type: "search_result",
source: "https://docs.company.com/troubleshooting",
title: "Troubleshooting Guide",
content: [
{
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 }
}
]
end
response = client.messages.create(
model: "claude-opus-4-7",
max_tokens: 1024,
tools: [knowledge_base_tool],
messages: [
{ role: "user", content: "How do I configure the timeout settings?" }
]
)
if response.content.first.type == :tool_use
tool_result = search_knowledge_base(response.content.first.input["query"])
final_response = client.messages.create(
model: "claude-opus-4-7",
max_tokens: 1024,
messages: [
{ role: "user", content: "How do I configure the timeout settings?" },
{ role: "assistant", content: response.content },
{
role: "user",
content: [
{
type: "tool_result",
tool_use_id: response.content.first.id,
content: tool_result
}
]
}
]
)
puts final_response
endMethod 2: Search results as top-level content
You can also provide search results directly in user messages. This is useful for:
- Pre-fetched content from your search infrastructure
- Cached search results from previous queries
- Content from external search services
- Testing and development
Example: Direct search results
ant messages create <<'YAML'
model: claude-opus-4-7
max_tokens: 1024
messages:
- role: user
content:
- type: search_result
source: https://docs.company.com/api-reference
title: API Reference - Authentication
content:
- 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
- type: search_result
source: https://docs.company.com/quickstart
title: Getting Started Guide
content:
- 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
- type: text
text: >-
Based on these search results, how do I authenticate API requests
and what are the rate limits?
YAMLfrom anthropic import Anthropic
from anthropic.types import MessageParam, TextBlockParam, SearchResultBlockParam
client = Anthropic()
# Provide search results directly in the user message
response = client.messages.create(
model="claude-opus-4-7",
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)import Anthropic from "@anthropic-ai/sdk";
const anthropic = new Anthropic();
// Provide search results directly in the user message
const response = await anthropic.messages.create({
model: "claude-opus-4-7",
max_tokens: 1024,
messages: [
{
role: "user",
content: [
{
type: "search_result" as const,
source: "https://docs.company.com/api-reference",
title: "API Reference - Authentication",
content: [
{
type: "text" as const,
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 }
},
{
type: "search_result" as const,
source: "https://docs.company.com/quickstart",
title: "Getting Started Guide",
content: [
{
type: "text" as const,
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 }
},
{
type: "text" as const,
text: "Based on these search results, how do I authenticate API requests and what are the rate limits?"
}
]
}
]
});
console.log(response);using System;
using System.Threading.Tasks;
using Anthropic;
using Anthropic.Models.Messages;
class Program
{
static async Task Main(string[] args)
{
AnthropicClient client = new();
var parameters = new MessageCreateParams
{
Model = Model.ClaudeOpus4_7,
MaxTokens = 1024,
Messages =
[
new()
{
Role = Role.User,
Content =
[
new SearchResultBlockParam
{
Source = "https://docs.company.com/api-reference",
Title = "API Reference - Authentication",
Content =
[
new TextBlockParam
{
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 = new CitationsConfigParam { Enabled = true }
},
new SearchResultBlockParam
{
Source = "https://docs.company.com/quickstart",
Title = "Getting Started Guide",
Content =
[
new TextBlockParam
{
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 = new CitationsConfigParam { Enabled = true }
},
new TextBlockParam
{
Text = "Based on these search results, how do I authenticate API requests and what are the rate limits?"
}
]
}
]
};
var message = await client.Messages.Create(parameters);
Console.WriteLine(message);
}
}package main
import (
"context"
"fmt"
"log"
"github.com/anthropics/anthropic-sdk-go"
)
func main() {
client := anthropic.NewClient()
response, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
Model: anthropic.ModelClaudeOpus4_7,
MaxTokens: 1024,
Messages: []anthropic.MessageParam{
anthropic.NewUserMessage(
anthropic.ContentBlockParamUnion{OfSearchResult: &anthropic.SearchResultBlockParam{
Content: []anthropic.TextBlockParam{
{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",
Citations: anthropic.CitationsConfigParam{Enabled: anthropic.Bool(true)},
}},
anthropic.ContentBlockParamUnion{OfSearchResult: &anthropic.SearchResultBlockParam{
Content: []anthropic.TextBlockParam{
{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",
Citations: anthropic.CitationsConfigParam{Enabled: anthropic.Bool(true)},
}},
anthropic.NewTextBlock("Based on these search results, how do I authenticate API requests and what are the rate limits?"),
),
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(response)
}import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;
import com.anthropic.models.messages.ContentBlockParam;
import com.anthropic.models.messages.CitationsConfigParam;
import com.anthropic.models.messages.MessageCreateParams;
import com.anthropic.models.messages.Message;
import com.anthropic.models.messages.Model;
import com.anthropic.models.messages.SearchResultBlockParam;
import com.anthropic.models.messages.TextBlockParam;
import java.util.List;
public class SearchResultExample {
public static void main(String[] args) {
AnthropicClient client = AnthropicOkHttpClient.fromEnv();
MessageCreateParams params = MessageCreateParams.builder()
.model(Model.CLAUDE_OPUS_4_7)
.maxTokens(1024L)
.addUserMessageOfBlockParams(List.of(
ContentBlockParam.ofSearchResult(
SearchResultBlockParam.builder()
.source("https://docs.company.com/api-reference")
.title("API Reference - Authentication")
.content(List.of(
TextBlockParam.builder()
.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.")
.build()
))
.citations(CitationsConfigParam.builder().enabled(true).build())
.build()
),
ContentBlockParam.ofSearchResult(
SearchResultBlockParam.builder()
.source("https://docs.company.com/quickstart")
.title("Getting Started Guide")
.content(List.of(
TextBlockParam.builder()
.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.")
.build()
))
.citations(CitationsConfigParam.builder().enabled(true).build())
.build()
),
ContentBlockParam.ofText(
TextBlockParam.builder()
.text("Based on these search results, how do I authenticate API requests and what are the rate limits?")
.build()
)
))
.build();
Message response = client.messages().create(params);
System.out.println(response);
}
}<?php
use Anthropic\Client;
$client = new Client(apiKey: getenv("ANTHROPIC_API_KEY"));
$message = $client->messages->create(
maxTokens: 1024,
messages: [
[
'role' => 'user',
'content' => [
[
'type' => 'search_result',
'source' => 'https://docs.company.com/api-reference',
'title' => 'API Reference - Authentication',
'content' => [
[
'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]
],
[
'type' => 'search_result',
'source' => 'https://docs.company.com/quickstart',
'title' => 'Getting Started Guide',
'content' => [
[
'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]
],
[
'type' => 'text',
'text' => 'Based on these search results, how do I authenticate API requests and what are the rate limits?'
]
]
]
],
model: 'claude-opus-4-7',
);
echo json_encode($message, JSON_PRETTY_PRINT);require "anthropic"
client = Anthropic::Client.new
message = client.messages.create(
model: "claude-opus-4-7",
max_tokens: 1024,
messages: [
{
role: "user",
content: [
{
type: "search_result",
source: "https://docs.company.com/api-reference",
title: "API Reference - Authentication",
content: [
{
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 }
},
{
type: "search_result",
source: "https://docs.company.com/quickstart",
title: "Getting Started Guide",
content: [
{
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 }
},
{
type: "text",
text: "Based on these search results, how do I authenticate API requests and what are the rate limits?"
}
]
}
]
)
puts messageClaude’s response with citations
Regardless of how search results are provided, Claude automatically includes citations when using information from them:
{
"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
}
]
}
]
}Citation fields
Each citation includes:
| Field | Type | Description |
|---|---|---|
type | string | Always "search_result_location" for search result citations |
source | string | The source from the original search result |
title | string or null | The title from the original search result |
cited_text | string | The full text of the cited block(s), concatenated. Equals the contents of content[start_block_index:end_block_index] joined together. Not counted toward output tokens. |
search_result_index | integer | 0-based index of the cited search result among all search_result blocks in the request, in the order they appear (across all messages and tool results). |
start_block_index | integer | 0-based index of the first cited block in the search result’s content array. |
end_block_index | integer | Exclusive end index of the cited block range in the search result’s content array. Always greater than start_block_index. |
The block indices identify a slice of the search result’s content array, and cited_text is the full text of that slice. The text block is the minimal citable unit: Claude cites whole blocks, not substrings within a block. To get finer-grained citations, split your search result content into smaller blocks (see Multiple content blocks).
Multiple content blocks
Search results can contain multiple text blocks in the content array:
{
"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."
}
]
}A citation referencing the rate limits block looks like:
{
"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
}When this search result is cited, start_block_index and end_block_index identify which of these blocks the citation covers, and cited_text contains exactly those blocks’ text. Splitting content into smaller, focused blocks gives Claude finer citation boundaries; combining content into one block means every citation returns the full text. This is the same model used by custom content documents in the Citations feature.
Advanced usage
Combining both methods
You can use both tool-based and top-level search results in the same conversation:
from anthropic.types import MessageParam, SearchResultBlockParam, TextBlockParam
# First message with top-level search results
messages = [
MessageParam(
role="user",
content=[
SearchResultBlockParam(
type="search_result",
source="https://docs.company.com/overview",
title="Product Overview",
content=[
TextBlockParam(
type="text", text="Our product helps teams collaborate..."
)
],
citations={"enabled": True},
),
TextBlockParam(
type="text",
text="Tell me about this product and search for pricing information",
),
],
)
]
# Claude might respond and call a tool to search for pricing
# Then you provide tool results with more search resultsCombining with other content types
Both methods support mixing search results with other content:
from anthropic.types import SearchResultBlockParam, TextBlockParam
# In tool results
tool_result = [
SearchResultBlockParam(
type="search_result",
source="https://docs.company.com/guide",
title="User Guide",
content=[TextBlockParam(type="text", text="Configuration details...")],
citations={"enabled": True},
),
TextBlockParam(
type="text", text="Additional context: This applies to version 2.0 and later."
),
]
# In top-level content
user_content = [
SearchResultBlockParam(
type="search_result",
source="https://research.com/paper",
title="Research Paper",
content=[TextBlockParam(type="text", text="Key findings...")],
citations={"enabled": True},
),
{
"type": "image",
"source": {"type": "url", "url": "https://example.com/chart.png"},
},
TextBlockParam(
type="text", text="How does the chart relate to the research findings?"
),
]Cache control
Add cache control for better performance:
{
"type": "search_result",
"source": "https://docs.company.com/guide",
"title": "User Guide",
"content": [{ "type": "text", "text": "..." }],
"cache_control": {
"type": "ephemeral"
}
}Citation control
By default, citations are disabled for search results. You can enable citations by explicitly setting the citations configuration:
{
"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
}
}When citations.enabled is set to true, Claude includes citation references when using information from the search result. This enables:
- Natural citations for your custom RAG applications
- Source attribution when interfacing with proprietary knowledge bases
- Web search-quality citations for any custom tool that returns search results
Best practices
For tool-based search (Method 1)
- Dynamic content: Use for real-time searches and dynamic RAG applications
- Error handling: Return appropriate messages when searches fail
- Result limits: Return only the most relevant results to avoid context overflow
For top-level search (Method 2)
- Pre-fetched content: Use when you already have search results
- Batch processing: Ideal for processing multiple search results at once
- Testing: Great for testing citation behavior with known content
General best practices
-
Structure results effectively:
- Use clear, permanent source URLs
- Provide descriptive titles
- Break long content into logical text blocks to give Claude finer citation boundaries
-
Maintain consistency:
- Use consistent source formats across your application
- Ensure titles accurately reflect content
- Keep formatting consistent
-
Handle errors gracefully:
def search_with_fallback(query): try: results = perform_search(query) if not results: return {"type": "text", "text": "No results found."} return format_as_search_results(results) except Exception as e: return {"type": "text", "text": f"Search error: {str(e)}"}
Limitations
- Search result content blocks are available on Claude API, Amazon Bedrock, and Google Cloud’s Vertex AI
- Only text content is supported within search results (no images or other media)
- The
contentarray must contain at least one text block
Liên kết
- Nền tảng: Anthropic · Claude
- Nguồn: https://platform.claude.com/docs/en/build-with-claude/search-results.md
Xem thêm: