Note: Untuk mempelajari bagaimana "zero data retention" (retensi data nol), atau ZDR, berlaku untuk fitur ini, lihat API dan retensi data.
Blok konten hasil pencarian memungkinkan Haijun mengutip konten Anda sendiri dengan cara yang sama seperti mengutip hasil pencarian web: setiap sitasi membawa sumber dan judul yang Anda berikan. Gunakan blok ini dalam aplikasi "Retrieval-Augmented Generation" (generasi yang diperkaya pengambilan), atau RAG, di mana Haijun perlu mengatribusikan jawaban ke dokumen Anda.
Semua model aktif mendukung hasil pencarian dengan sitasi, kecuali Haijun Haiku 3. Tidak diperlukan header beta: hasil pencarian merupakan bagian dari Messages API standar.
Cara kerjanya
Hasil pencarian dapat disediakan dengan dua cara:
- Dari pemanggilan alat: Alat kustom Anda mengembalikan hasil pencarian, memungkinkan aplikasi RAG yang dinamis
- Sebagai konten tingkat atas: Anda menyediakan hasil pencarian langsung dalam pesan pengguna untuk konten yang telah diambil sebelumnya atau di-cache
Dalam kedua kasus, Haijun mengutip hasil pencarian secara otomatis ketika sitasi diaktifkan. Tidak diperlukan prompt khusus: ajukan pertanyaan Anda, dan sitasi akan muncul pada blok teks yang mengambil dari konten Anda.
Skema hasil pencarian
Hasil pencarian menggunakan struktur berikut:
{
"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
}
}Field wajib
| Field | Tipe | Deskripsi |
|---|---|---|
type | string | Harus "search_result" |
source | string | Sumber konten. String stabil apa pun dapat digunakan: URL, atau pengenal internal seperti kb://article-1234 |
title | string | Judul deskriptif untuk hasil pencarian |
content | array | Array blok teks yang berisi konten sebenarnya |
Field opsional
| Field | Tipe | Deskripsi |
|---|---|---|
citations | object | Konfigurasi sitasi dengan field Boolean enabled. Sitasi dinonaktifkan secara default; setiap contoh di halaman ini menetapkan "enabled": true secara eksplisit. Semua hasil pencarian dalam satu permintaan harus menggunakan pengaturan yang sama (lihat Kontrol sitasi) |
cache_control | object | Pengaturan kontrol cache (misalnya, {"type": "ephemeral"}) |
Setiap item dalam array content harus berupa blok teks dengan:
type: Harus"text"
text: Konten teks sebenarnya (string tidak kosong)
Hasil pencarian hanya memuat teks. Gambar dan media lain tidak didukung di dalam array content.
Metode 1: Hasil pencarian dari pemanggilan alat
Mengembalikan hasil pencarian dari alat kustom Anda memungkinkan aplikasi RAG yang dinamis: alat mengambil konten saat runtime, dan Haijun mengutipnya dalam respons. Contoh berikut memaksa pemanggilan alat dengan tool_choice, sehingga langkah pengambilan berjalan setiap kali.
Contoh: Alat basis pengetahuan
# Alur pemanggilan alat memerlukan logika pencarian di sisi aplikasi yang tidak
# dapat diterjemahkan menjadi satu perintah shell. Lihat tab SDK untuk alur lengkapnya.
# Bentuk mentah percakapan alat dengan hasil pencarian ditampilkan di
# tab cURL Menggabungkan kedua metode; Metode 2 menunjukkan bentuk tingkat atas. # Alur pemanggilan alat memerlukan logika pencarian di sisi aplikasi yang tidak
# dapat diterjemahkan menjadi satu perintah shell. Lihat tab SDK untuk alur lengkapnya.
# Bentuk mentah percakapan alat dengan hasil pencarian ditampilkan di
# tab cURL Menggabungkan kedua metode; Metode 2 menunjukkan bentuk tingkat atas. from juglow.types import (
MessageParam,
TextBlockParam,
SearchResultBlockParam,
ToolResultBlockParam,
)
client = Juglow()
# Definisikan alat pencarian basis pengetahuan
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"],
},
}
# Fungsi untuk menangani pemanggilan alat
def search_knowledge_base(query):
# Logika pencarian Anda di sini
# Mengembalikan hasil pencarian dalam format yang benar
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},
),
]
# Bangun percakapan dalam sebuah list, dimulai dengan pertanyaan pengguna
messages = [
MessageParam(role="user", content="How do I configure the timeout settings?")
]
# Buat pesan dengan alat tersebut
response = client.messages.create(
model="haijun-opus-5",
max_tokens=1024,
tools=[knowledge_base_tool],
tool_choice={"type": "tool", "name": "search_knowledge_base"},
messages=messages,
)
# Saat Haijun memanggil alat, berikan hasil pencariannya.
# Blok tool_use tidak selalu berada di urutan pertama: lakukan iterasi untuk menemukannya.
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"])
# Tambahkan giliran Haijun, lalu hasil alat, ke percakapan yang sedang berjalan
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
)
],
)
)
# Kirim kembali hasil alat
final_response = client.messages.create(
model="haijun-opus-5",
max_tokens=1024,
messages=messages,
)
print(final_response) const client = new Juglow();
// Definisikan alat pencarian basis pengetahuan
const knowledgeBaseTool: Juglow.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"]
}
};
// Fungsi untuk menangani pemanggilan alat
function searchKnowledgeBase(query: string) {
// Logika pencarian Anda di sini
// Mengembalikan hasil pencarian dalam format yang benar
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 }
}
];
}
// Bangun percakapan dalam sebuah list, dimulai dengan pertanyaan pengguna
const messages: Juglow.MessageParam[] = [
{ role: "user", content: "How do I configure the timeout settings?" }
];
// Buat pesan dengan alat tersebut
const response = await client.messages.create({
model: "haijun-opus-5",
max_tokens: 1024,
tools: [knowledgeBaseTool],
tool_choice: { type: "tool", name: "search_knowledge_base" },
messages
});
// Tangani penggunaan alat dan berikan hasilnya.
// Blok tool_use tidak selalu berada di urutan pertama: cari di dalam array content.
const toolUse = response.content.find(
(block): block is Juglow.ToolUseBlock => block.type === "tool_use"
);
if (toolUse) {
const input = toolUse.input as { query: string };
const toolResult = searchKnowledgeBase(input.query);
// Tambahkan giliran Haijun, lalu hasil alat, ke percakapan yang sedang berjalan
messages.push({ role: "assistant", content: response.content });
messages.push({
role: "user",
content: [
{
type: "tool_result" as const,
tool_use_id: toolUse.id,
content: toolResult // Search results go here
}
]
});
// Kirim kembali hasil alat
const finalResponse = await client.messages.create({
model: "haijun-opus-5",
max_tokens: 1024,
messages
});
console.log(finalResponse);
} JuglowClient client = new();
var tools = new List<ToolUnion>
{
new ToolUnion(new Tool()
{
Name = "search_knowledge_base",
Description = "Search the company knowledge base for information",
InputSchema = new InputSchema()
{
Properties = new Dictionary<string, JsonElement>
{
["query"] = JsonSerializer.SerializeToElement(new { type = "string", description = "The search query" }),
},
Required = ["query"],
},
}),
};
// Fungsi untuk menangani pemanggilan alat
static List<Block> SearchKnowledgeBase(string query)
{
// Logika pencarian Anda di sini
// Mengembalikan hasil pencarian dalam format yang benar
return
[
new SearchResultBlockParam
{
Source = "https://docs.company.com/product-guide",
Title = "Product Configuration Guide",
Content = [new() { 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() { Enabled = true },
},
new SearchResultBlockParam
{
Source = "https://docs.company.com/troubleshooting",
Title = "Troubleshooting Guide",
Content = [new() { Text = "If you encounter timeout errors, first check the configuration settings. Common causes include network latency and incorrect timeout values." }],
Citations = new() { Enabled = true },
},
];
}
// Bangun percakapan dalam sebuah list, dimulai dengan pertanyaan pengguna
List<MessageParam> messages = [new() { Role = Role.User, Content = "How do I configure the timeout settings?" }];
// Buat pesan dengan alat tersebut
var response = await client.Messages.Create(new()
{
Model = Model.HaijunOpus5,
MaxTokens = 1024,
Tools = tools,
ToolChoice = new ToolChoiceTool { Name = "search_knowledge_base" },
Messages = messages,
});
// Saat Haijun memanggil alat, berikan hasil pencariannya.
// Blok tool_use tidak selalu yang pertama: temukan yang pertama.
foreach (var block in response.Content)
{
if (block.TryPickToolUse(out var toolUse))
{
var query = toolUse.Input["query"].GetString() ?? "";
var toolResults = SearchKnowledgeBase(query);
// Tambahkan giliran Haijun, lalu hasil alat, ke percakapan yang sedang berjalan
messages.Add(new() { Role = Role.Assistant, Content = response.Content.Select(contentBlock => new ContentBlockParam(contentBlock.Json)).ToList() });
messages.Add(new()
{
Role = Role.User,
Content = new MessageParamContent(
[new ContentBlockParam(new ToolResultBlockParam() { ToolUseID = toolUse.ID, Content = new ToolResultBlockParamContent(toolResults) })]
),
});
// Kirim kembali hasil alat
var finalResponse = await client.Messages.Create(new()
{
Model = Model.HaijunOpus5,
MaxTokens = 1024,
Messages = messages,
});
Console.WriteLine(finalResponse);
break;
}
} client := juglow.NewClient()
knowledgeBaseTool := juglow.ToolUnionParam{
OfTool: &juglow.ToolParam{
Name: "search_knowledge_base",
Description: juglow.String("Search the company knowledge base for information"),
InputSchema: juglow.ToolInputSchemaParam{
Properties: map[string]any{
"query": map[string]any{
"type": "string",
"description": "The search query",
},
},
Required: []string{"query"},
},
},
}
// Bangun percakapan dalam sebuah slice, dimulai dengan pertanyaan pengguna
messages := []juglow.MessageParam{
juglow.NewUserMessage(juglow.NewTextBlock("How do I configure the timeout settings?")),
}
response, err := client.Messages.New(context.TODO(), juglow.MessageNewParams{
Model: juglow.ModelHaijunOpus5,
MaxTokens: 1024,
Tools: []juglow.ToolUnionParam{knowledgeBaseTool},
ToolChoice: juglow.ToolChoiceUnionParam{OfTool: &juglow.ToolChoiceToolParam{Name: "search_knowledge_base"}},
Messages: messages,
})
if err != nil {
log.Fatal(err)
}
// Blok tool_use tidak selalu berada di urutan pertama: cari di dalam daftar konten
var toolUse *juglow.ToolUseBlock
for _, block := range response.Content {
if variant, ok := block.AsAny().(juglow.ToolUseBlock); ok {
toolUse = &variant
break
}
}
if toolUse != nil {
var input struct {
Query string `json:"query"`
}
if err := json.Unmarshal(toolUse.Input, &input); err != nil {
log.Fatal(err)
}
toolResults := searchKnowledgeBase(input.Query)
// Tambahkan giliran Haijun, lalu hasil alat, ke percakapan yang sedang berjalan
messages = append(messages, response.ToParam())
messages = append(messages, juglow.NewUserMessage(juglow.ContentBlockParamUnion{
OfToolResult: &juglow.ToolResultBlockParam{
ToolUseID: toolUse.ID,
Content: toolResults,
},
}))
// Kirim kembali hasil alat
finalResponse, err := client.Messages.New(context.TODO(), juglow.MessageNewParams{
Model: juglow.ModelHaijunOpus5,
MaxTokens: 1024,
Messages: messages,
})
if err != nil {
log.Fatal(err)
}
fmt.Println(finalResponse)
}
// ...
func searchKnowledgeBase(query string) []juglow.ToolResultBlockParamContentUnion {
return []juglow.ToolResultBlockParamContentUnion{
{OfSearchResult: &juglow.SearchResultBlockParam{
Content: []juglow.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: juglow.CitationsConfigParam{Enabled: juglow.Bool(true)},
}},
{OfSearchResult: &juglow.SearchResultBlockParam{
Content: []juglow.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: juglow.CitationsConfigParam{Enabled: juglow.Bool(true)},
}},
}
} import com.juglow.models.messages.ContentBlockParam;
import com.juglow.models.messages.CitationsConfigParam;
// ...
import com.juglow.models.messages.MessageParam;
import com.juglow.models.messages.Model;
import com.juglow.models.messages.SearchResultBlockParam;
import com.juglow.models.messages.TextBlockParam;
import com.juglow.models.messages.Tool;
import com.juglow.models.messages.ToolChoice;
import com.juglow.models.messages.ToolChoiceTool;
import com.juglow.models.messages.ToolResultBlockParam;
import com.juglow.core.JsonValue;
// ...
void main() {
JuglowClient client = JuglowOkHttpClient.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();
// Bangun percakapan dalam sebuah list, dimulai dengan pertanyaan pengguna
List<MessageParam> messages = new ArrayList<>();
messages.add(MessageParam.builder()
.role(MessageParam.Role.USER)
.content("How do I configure the timeout settings?")
.build());
MessageCreateParams params = MessageCreateParams.builder()
.model(Model.HAIJUN_OPUS_5)
.maxTokens(1024L)
.addTool(knowledgeBaseTool)
.toolChoice(ToolChoice.ofTool(ToolChoiceTool.builder()
.name("search_knowledge_base")
.build()))
.messages(messages)
.build();
Message response = client.messages().create(params);
// Blok tool_use tidak selalu berada di urutan pertama: cari di dalam list content
response.content().stream()
.flatMap(contentBlock -> contentBlock.toolUse().stream())
.findFirst()
.ifPresent(toolUse -> {
Map<String, JsonValue> input =
(Map<String, JsonValue>) toolUse._input().asObject().get();
List<ToolResultBlockParam.Content.Block> toolResult = searchKnowledgeBase(
input.get("query").asStringOrThrow()
);
// Tambahkan seluruh giliran Haijun ke percakapan yang berjalan, lalu hasil alatnya.
// Membangun ulang hanya blok tool_use akan menghilangkan blok konten lain yang Haijun
// kembalikan (mis. teks awal saat pemanggilan alat tidak dipaksa) — tambahkan
// giliran lengkapnya, seperti yang dilakukan tab bahasa lainnya.
messages.add(MessageParam.builder()
.role(MessageParam.Role.ASSISTANT)
.contentOfBlockParams(
response.content().stream()
.map(block -> block.toParam())
.toList()
)
.build());
messages.add(MessageParam.builder()
.role(MessageParam.Role.USER)
.contentOfBlockParams(List.of(
ContentBlockParam.ofToolResult(
ToolResultBlockParam.builder()
.toolUseId(toolUse.id())
.contentOfBlocks(toolResult)
.build()
)
))
.build());
// Kirim kembali hasil alat
MessageCreateParams finalParams = MessageCreateParams.builder()
.model(Model.HAIJUN_OPUS_5)
.maxTokens(1024L)
.messages(messages)
.build();
Message finalResponse = client.messages().create(finalParams);
System.out.println(finalResponse);
});
}
static List<ToolResultBlockParam.Content.Block> searchKnowledgeBase(String query) {
return List.of(
ToolResultBlockParam.Content.Block.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()
),
ToolResultBlockParam.Content.Block.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()
)
);
} $client = new Client();
$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]
]
];
}
// Bangun percakapan dalam sebuah list, dimulai dengan pertanyaan pengguna
$messages = [
['role' => 'user', 'content' => 'How do I configure the timeout settings?']
];
$response = $client->messages->create(
maxTokens: 1024,
messages: $messages,
model: 'haijun-opus-5',
toolChoice: ['type' => 'tool', 'name' => 'search_knowledge_base'],
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']);
// Tambahkan giliran Haijun, lalu hasil alat, ke percakapan yang sedang berjalan
$messages[] = ['role' => 'assistant', 'content' => $response->content];
$messages[] = [
'role' => 'user',
'content' => [
[
'type' => 'tool_result',
'tool_use_id' => $toolUseBlock->id,
'content' => $toolResult
]
]
];
// Kirim kembali hasil alat
$finalResponse = $client->messages->create(
maxTokens: 1024,
messages: $messages,
model: 'haijun-opus-5',
);
echo $finalResponse;
} else {
echo $response;
} client = Juglow::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
# Bangun percakapan dalam sebuah list, dimulai dengan pertanyaan pengguna
messages = [
{ role: "user", content: "How do I configure the timeout settings?" }
]
response = client.messages.create(
model: "haijun-opus-5",
max_tokens: 1024,
tools: [knowledge_base_tool],
tool_choice: { type: "tool", name: "search_knowledge_base" },
messages: messages
)
# Blok tool_use tidak selalu berada di urutan pertama: cari di dalam array content
tool_use = response.content.find { |block| block.type == :tool_use }
if tool_use
tool_result = search_knowledge_base(tool_use.input[:query])
# Tambahkan giliran Haijun, lalu hasil alat, ke percakapan yang sedang berjalan
messages << { role: "assistant", content: response.content }
messages << {
role: "user",
content: [
{
type: "tool_result",
tool_use_id: tool_use.id,
content: tool_result
}
]
}
# Kirim kembali hasil alat
final_response = client.messages.create(
model: "haijun-opus-5",
max_tokens: 1024,
messages: messages
)
puts final_response
endMetode 2: Hasil pencarian sebagai konten tingkat atas
Anda juga dapat menyediakan hasil pencarian langsung dalam pesan pengguna. Ini berguna untuk:
- Konten yang telah diambil sebelumnya dari infrastruktur pencarian Anda
- Hasil pencarian yang di-cache dari kueri sebelumnya
- Konten dari layanan pencarian eksternal
- Pengujian dan pengembangan
Contoh: Hasil pencarian langsung
curl https://haijun.my.id/v1/messages \
-H "x-api-key: $JUGLOW_API_KEY" \
-H "juglow-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"model": "haijun-opus-5-5",
"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?"
}
]
}
]
}' ant messages create <<'YAML'
model: haijun-opus-5-5
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?
YAML from juglow.types import MessageParam, TextBlockParam, SearchResultBlockParam
client = Juglow()
# Berikan hasil pencarian langsung di pesan pengguna
response = client.messages.create(
model="haijun-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) const client = new Juglow();
// Berikan hasil pencarian langsung di pesan pengguna
const response = await client.messages.create({
model: "haijun-opus-5-5",
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); JuglowClient client = new();
// Berikan hasil pencarian langsung di pesan pengguna
var response = await client.Messages.Create(new()
{
Model = Model.HaijunOpus5_5,
MaxTokens = 1024,
Messages =
[
new()
{
Role = Role.User,
Content = new MessageParamContent(
[
new ContentBlockParam(new SearchResultBlockParam
{
Source = "https://docs.company.com/api-reference",
Title = "API Reference - Authentication",
Content = [new() { 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() { Enabled = true },
}),
new ContentBlockParam(new SearchResultBlockParam
{
Source = "https://docs.company.com/quickstart",
Title = "Getting Started Guide",
Content = [new() { 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() { Enabled = true },
}),
new ContentBlockParam(new TextBlockParam { Text = "Based on these search results, how do I authenticate API requests and what are the rate limits?" }),
]),
},
],
});
Console.WriteLine(response); client := juglow.NewClient()
response, err := client.Messages.New(context.TODO(), juglow.MessageNewParams{
Model: juglow.ModelHaijunOpus5_5,
MaxTokens: 1024,
Messages: []juglow.MessageParam{
juglow.NewUserMessage(
juglow.ContentBlockParamUnion{OfSearchResult: &juglow.SearchResultBlockParam{
Content: []juglow.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: juglow.CitationsConfigParam{Enabled: juglow.Bool(true)},
}},
juglow.ContentBlockParamUnion{OfSearchResult: &juglow.SearchResultBlockParam{
Content: []juglow.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: juglow.CitationsConfigParam{Enabled: juglow.Bool(true)},
}},
juglow.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.juglow.models.messages.ContentBlockParam;
import com.juglow.models.messages.CitationsConfigParam;
// ...
import com.juglow.models.messages.SearchResultBlockParam;
import com.juglow.models.messages.TextBlockParam;
// ...
void main() {
JuglowClient client = JuglowOkHttpClient.fromEnv();
MessageCreateParams params = MessageCreateParams.builder()
.model(Model.HAIJUN_OPUS_5_5)
.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);
} $client = new Client();
$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: 'haijun-opus-5-5',
);
echo json_encode($message, JSON_PRETTY_PRINT); client = Juglow::Client.new
message = client.messages.create(
model: "haijun-opus-5-5",
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 messageRespons Haijun dengan sitasi
Terlepas dari bagaimana hasil pencarian disediakan, Haijun secara otomatis menyertakan sitasi ketika menggunakan informasi dari hasil tersebut:
{
"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
}
]
}
]
}Field sitasi
Setiap sitasi mencakup:
| Field | Tipe | Deskripsi |
|---|---|---|
type | string | Selalu "search_result_location" untuk sitasi hasil pencarian |
source | string | Sumber dari hasil pencarian asli |
title | string atau null | Judul dari hasil pencarian asli |
cited_text | string | Teks lengkap dari blok yang dikutip, digabungkan. Sama dengan isi content[start_block_index:end_block_index] yang disatukan. Tidak dihitung sebagai token output. |
search_result_index | integer | Indeks berbasis 0 dari hasil pencarian yang dikutip di antara semua blok search_result dalam permintaan, sesuai urutan kemunculannya (di seluruh pesan dan hasil alat). |
start_block_index | integer | Indeks berbasis 0 dari blok pertama yang dikutip dalam array content hasil pencarian. |
end_block_index | integer | Indeks akhir eksklusif dari rentang blok yang dikutip dalam array content hasil pencarian. Selalu lebih besar dari start_block_index. |
Indeks blok mengidentifikasi sebuah irisan dari array content hasil pencarian, dan cited_text adalah teks lengkap dari irisan tersebut. Blok teks adalah unit terkecil yang dapat dikutip: Haijun mengutip blok secara utuh, bukan substring di dalam blok. Untuk mendapatkan sitasi yang lebih terperinci, pecah konten hasil pencarian Anda menjadi blok-blok yang lebih kecil (lihat Beberapa blok konten).
Beberapa blok konten
Hasil pencarian dapat berisi beberapa blok teks dalam array 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 }
}Sitasi yang merujuk pada blok batas laju terlihat seperti ini:
{
"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
}Ketika hasil pencarian ini dikutip, start_block_index dan end_block_index mengidentifikasi blok mana saja yang dicakup oleh sitasi, dan cited_text berisi persis teks dari blok-blok tersebut. Memecah konten menjadi blok yang lebih kecil dan terfokus memberi Haijun batas sitasi yang lebih halus; menggabungkan konten menjadi satu blok berarti setiap sitasi mengembalikan teks lengkap. Ini adalah model yang sama yang digunakan oleh dokumen konten kustom dalam fitur Citations.
Penggunaan lanjutan
Menggabungkan kedua metode
Anda dapat mencampur kedua metode dalam percakapan yang sama. Haijun mengutip dari sumber mana pun, dan search_result_index menghitung semua blok search_result sesuai urutan permintaan, terlepas dari sumbernya.
Contoh berikut memutar ulang sebuah percakapan lengkap. Pesan pengguna pertama membawa hasil pencarian yang telah diambil sebelumnya, giliran asisten memanggil alat basis pengetahuan, dan hasil alat mengembalikan hasil pencarian kedua. Jawaban Haijun mengutip kedua sumber:
curl https://haijun.my.id/v1/messages \
-H "x-api-key: $JUGLOW_API_KEY" \
-H "juglow-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"model": "haijun-opus-5-5",
"max_tokens": 1024,
"tools": [
{
"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"]
}
}
],
"messages": [
{
"role": "user",
"content": [
{
"type": "search_result",
"source": "https://docs.company.com/overview",
"title": "Product Overview",
"content": [
{
"type": "text",
"text": "Acme Dashboard is a monitoring tool for distributed systems. It supports real-time alerting and custom metric dashboards."
}
],
"citations": {"enabled": true}
},
{
"type": "text",
"text": "What does Acme Dashboard do, and what plans is it available on?"
}
]
},
{
"role": "assistant",
"content": [
{
"type": "text",
"text": "Let me check the pricing information."
},
{
"type": "tool_use",
"id": "toolu_01A09q90qw90lq917835lq9",
"name": "search_knowledge_base",
"input": {"query": "Acme Dashboard pricing plans"}
}
]
},
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_01A09q90qw90lq917835lq9",
"content": [
{
"type": "search_result",
"source": "https://docs.company.com/pricing",
"title": "Pricing Plans",
"content": [
{
"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}
}
]
}
]
}
]
}' ant messages create <<'YAML'
model: haijun-opus-5-5
max_tokens: 1024
tools:
- 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]
messages:
- role: user
content:
- type: search_result
source: https://docs.company.com/overview
title: Product Overview
content:
- type: text
text: >-
Acme Dashboard is a monitoring tool for distributed systems.
It supports real-time alerting and custom metric dashboards.
citations:
enabled: true
- type: text
text: What does Acme Dashboard do, and what plans is it available on?
- role: assistant
content:
- type: text
text: Let me check the pricing information.
- type: tool_use
id: toolu_01A09q90qw90lq917835lq9
name: search_knowledge_base
input:
query: Acme Dashboard pricing plans
- role: user
content:
- type: tool_result
tool_use_id: toolu_01A09q90qw90lq917835lq9
content:
- type: search_result
source: https://docs.company.com/pricing
title: Pricing Plans
content:
- 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
YAML from juglow.types import (
MessageParam,
SearchResultBlockParam,
TextBlockParam,
ToolResultBlockParam,
ToolUseBlockParam,
)
client = Juglow()
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"],
},
}
# Putar ulang percakapan yang memberikan hasil pencarian dengan dua cara: pesan
# pengguna pertama membawa hasil yang sudah diambil, hasil alat mengembalikan yang lain
response = client.messages.create(
model="haijun-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) const client = new Juglow();
const knowledgeBaseTool: Juglow.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"]
}
};
// Putar ulang percakapan yang menyediakan hasil pencarian dengan dua cara: pesan
// pengguna pertama membawa hasil yang sudah diambil, hasil alat mengembalikan hasil lain
const response = await client.messages.create({
model: "haijun-opus-5-5",
max_tokens: 1024,
tools: [knowledgeBaseTool],
messages: [
{
role: "user",
content: [
{
type: "search_result" as const,
source: "https://docs.company.com/overview",
title: "Product Overview",
content: [
{
type: "text" as const,
text: "Acme Dashboard is a monitoring tool for distributed systems. It supports real-time alerting and custom metric dashboards."
}
],
citations: { enabled: true }
},
{
type: "text" as const,
text: "What does Acme Dashboard do, and what plans is it available on?"
}
]
},
{
role: "assistant",
content: [
{ type: "text" as const, text: "Let me check the pricing information." },
{
type: "tool_use" as const,
id: "toolu_01A09q90qw90lq917835lq9",
name: "search_knowledge_base",
input: { query: "Acme Dashboard pricing plans" }
}
]
},
{
role: "user",
content: [
{
type: "tool_result" as const,
tool_use_id: "toolu_01A09q90qw90lq917835lq9",
content: [
{
type: "search_result" as const,
source: "https://docs.company.com/pricing",
title: "Pricing Plans",
content: [
{
type: "text" as const,
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 }
}
]
}
]
}
]
});
console.log(response); JuglowClient client = new();
// Putar ulang percakapan yang menyediakan hasil pencarian dengan dua cara: pesan
// pengguna pertama membawa hasil yang sudah diambil, hasil alat mengembalikan hasil lain
var response = await client.Messages.Create(new()
{
Model = Model.HaijunOpus5_5,
MaxTokens = 1024,
Tools =
[
new ToolUnion(new Tool()
{
Name = "search_knowledge_base",
Description = "Search the company knowledge base for information",
InputSchema = new InputSchema()
{
Properties = new Dictionary<string, JsonElement>
{
["query"] = JsonSerializer.SerializeToElement(new { type = "string", description = "The search query" }),
},
Required = ["query"],
},
}),
],
Messages =
[
new()
{
Role = Role.User,
Content = new MessageParamContent(
[
new ContentBlockParam(new SearchResultBlockParam
{
Source = "https://docs.company.com/overview",
Title = "Product Overview",
Content = [new() { Text = "Acme Dashboard is a monitoring tool for distributed systems. It supports real-time alerting and custom metric dashboards." }],
Citations = new() { Enabled = true },
}),
new ContentBlockParam(new TextBlockParam { Text = "What does Acme Dashboard do, and what plans is it available on?" }),
]),
},
new()
{
Role = Role.Assistant,
Content = new MessageParamContent(
[
new ContentBlockParam(new TextBlockParam { Text = "Let me check the pricing information." }),
new ContentBlockParam(new ToolUseBlockParam
{
ID = "toolu_01A09q90qw90lq917835lq9",
Name = "search_knowledge_base",
Input = new Dictionary<string, JsonElement>
{
["query"] = JsonSerializer.SerializeToElement("Acme Dashboard pricing plans"),
},
}),
]),
},
new()
{
Role = Role.User,
Content = new MessageParamContent(
[
new ContentBlockParam(new ToolResultBlockParam()
{
ToolUseID = "toolu_01A09q90qw90lq917835lq9",
Content = new ToolResultBlockParamContent(
[
new SearchResultBlockParam
{
Source = "https://docs.company.com/pricing",
Title = "Pricing Plans",
Content = [new() { Text = "Acme Dashboard is available on the Starter plan at $10 per user per month and the Enterprise plan with custom pricing." }],
Citations = new() { Enabled = true },
},
]),
}),
]),
},
],
});
Console.WriteLine(response); client := juglow.NewClient()
knowledgeBaseTool := juglow.ToolUnionParam{
OfTool: &juglow.ToolParam{
Name: "search_knowledge_base",
Description: juglow.String("Search the company knowledge base for information"),
InputSchema: juglow.ToolInputSchemaParam{
Properties: map[string]any{
"query": map[string]any{"type": "string", "description": "The search query"},
},
Required: []string{"query"},
},
},
}
// Putar ulang percakapan yang menyediakan hasil pencarian dengan dua cara: pesan
// pengguna pertama membawa hasil yang sudah diambil, hasil alat mengembalikan yang lain
response, err := client.Messages.New(context.TODO(), juglow.MessageNewParams{
Model: juglow.ModelHaijunOpus5_5,
MaxTokens: 1024,
Tools: []juglow.ToolUnionParam{knowledgeBaseTool},
Messages: []juglow.MessageParam{
juglow.NewUserMessage(
juglow.ContentBlockParamUnion{OfSearchResult: &juglow.SearchResultBlockParam{
Content: []juglow.TextBlockParam{
{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",
Citations: juglow.CitationsConfigParam{Enabled: juglow.Bool(true)},
}},
juglow.NewTextBlock("What does Acme Dashboard do, and what plans is it available on?"),
),
juglow.NewAssistantMessage(
juglow.NewTextBlock("Let me check the pricing information."),
juglow.ContentBlockParamUnion{OfToolUse: &juglow.ToolUseBlockParam{
ID: "toolu_01A09q90qw90lq917835lq9",
Name: "search_knowledge_base",
Input: map[string]any{"query": "Acme Dashboard pricing plans"},
}},
),
juglow.NewUserMessage(
juglow.ContentBlockParamUnion{OfToolResult: &juglow.ToolResultBlockParam{
ToolUseID: "toolu_01A09q90qw90lq917835lq9",
Content: []juglow.ToolResultBlockParamContentUnion{
{OfSearchResult: &juglow.SearchResultBlockParam{
Content: []juglow.TextBlockParam{
{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",
Citations: juglow.CitationsConfigParam{Enabled: juglow.Bool(true)},
}},
},
}},
),
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(response) import com.juglow.core.JsonValue;
import com.juglow.models.messages.CitationsConfigParam;
import com.juglow.models.messages.ContentBlockParam;
// ...
import com.juglow.models.messages.SearchResultBlockParam;
import com.juglow.models.messages.TextBlockParam;
import com.juglow.models.messages.Tool;
import com.juglow.models.messages.ToolResultBlockParam;
import com.juglow.models.messages.ToolUseBlockParam;
// ...
void main() {
JuglowClient client = JuglowOkHttpClient.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();
// Putar ulang percakapan yang menyediakan hasil pencarian dengan dua cara: pesan
// pengguna pertama membawa hasil yang sudah diambil, hasil alat mengembalikan yang lain
MessageCreateParams params = MessageCreateParams.builder()
.model(Model.HAIJUN_OPUS_5_5)
.maxTokens(1024L)
.addTool(knowledgeBaseTool)
.addUserMessageOfBlockParams(List.of(
ContentBlockParam.ofSearchResult(SearchResultBlockParam.builder()
.source("https://docs.company.com/overview")
.title("Product Overview")
.content(List.of(TextBlockParam.builder()
.text("Acme Dashboard is a monitoring tool for distributed systems. It supports real-time alerting and custom metric dashboards.")
.build()))
.citations(CitationsConfigParam.builder().enabled(true).build())
.build()),
ContentBlockParam.ofText(TextBlockParam.builder()
.text("What does Acme Dashboard do, and what plans is it available on?")
.build())
))
.addAssistantMessageOfBlockParams(List.of(
ContentBlockParam.ofText(TextBlockParam.builder()
.text("Let me check the pricing information.")
.build()),
ContentBlockParam.ofToolUse(ToolUseBlockParam.builder()
.id("toolu_01A09q90qw90lq917835lq9")
.name("search_knowledge_base")
.input(JsonValue.from(Map.of("query", "Acme Dashboard pricing plans")))
.build())
))
.addUserMessageOfBlockParams(List.of(
ContentBlockParam.ofToolResult(ToolResultBlockParam.builder()
.toolUseId("toolu_01A09q90qw90lq917835lq9")
.contentOfBlocks(List.of(
ToolResultBlockParam.Content.Block.ofSearchResult(SearchResultBlockParam.builder()
.source("https://docs.company.com/pricing")
.title("Pricing Plans")
.content(List.of(TextBlockParam.builder()
.text("Acme Dashboard is available on the Starter plan at $10 per user per month and the Enterprise plan with custom pricing.")
.build()))
.citations(CitationsConfigParam.builder().enabled(true).build())
.build())
))
.build())
))
.build();
Message response = client.messages().create(params);
System.out.println(response);
} $client = new Client();
$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']
]
];
// Putar ulang percakapan yang menyediakan hasil pencarian dengan dua cara: pesan
// pengguna pertama membawa hasil yang sudah diambil, hasil alat mengembalikan yang lain
$response = $client->messages->create(
maxTokens: 1024,
tools: [$knowledgeBaseTool],
messages: [
[
'role' => 'user',
'content' => [
[
'type' => 'search_result',
'source' => 'https://docs.company.com/overview',
'title' => 'Product Overview',
'content' => [
[
'type' => 'text',
'text' => 'Acme Dashboard is a monitoring tool for distributed systems. It supports real-time alerting and custom metric dashboards.'
]
],
'citations' => ['enabled' => true]
],
[
'type' => 'text',
'text' => 'What does Acme Dashboard do, and what plans is it available on?'
]
]
],
[
'role' => 'assistant',
'content' => [
['type' => 'text', 'text' => 'Let me check the pricing information.'],
[
'type' => 'tool_use',
'id' => 'toolu_01A09q90qw90lq917835lq9',
'name' => 'search_knowledge_base',
'input' => ['query' => 'Acme Dashboard pricing plans']
]
]
],
[
'role' => 'user',
'content' => [
[
'type' => 'tool_result',
'tool_use_id' => 'toolu_01A09q90qw90lq917835lq9',
'content' => [
[
'type' => 'search_result',
'source' => 'https://docs.company.com/pricing',
'title' => 'Pricing Plans',
'content' => [
[
'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]
]
]
]
]
]
],
model: 'haijun-opus-5-5',
);
echo json_encode($response, JSON_PRETTY_PRINT); client = Juglow::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"]
}
}
# Putar ulang percakapan yang memberikan hasil pencarian dengan dua cara: pesan
# pengguna pertama membawa hasil yang sudah diambil, hasil alat mengembalikan yang lain
response = client.messages.create(
model: "haijun-opus-5-5",
max_tokens: 1024,
tools: [knowledge_base_tool],
messages: [
{
role: "user",
content: [
{
type: "search_result",
source: "https://docs.company.com/overview",
title: "Product Overview",
content: [
{
type: "text",
text: "Acme Dashboard is a monitoring tool for distributed systems. It supports real-time alerting and custom metric dashboards."
}
],
citations: { enabled: true }
},
{
type: "text",
text: "What does Acme Dashboard do, and what plans is it available on?"
}
]
},
{
role: "assistant",
content: [
{ type: "text", text: "Let me check the pricing information." },
{
type: "tool_use",
id: "toolu_01A09q90qw90lq917835lq9",
name: "search_knowledge_base",
input: { query: "Acme Dashboard pricing plans" }
}
]
},
{
role: "user",
content: [
{
type: "tool_result",
tool_use_id: "toolu_01A09q90qw90lq917835lq9",
content: [
{
type: "search_result",
source: "https://docs.company.com/pricing",
title: "Pricing Plans",
content: [
{
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 }
}
]
}
]
}
]
)
puts responseRespons mengutip kedua sumber. Hasil yang telah diambil sebelumnya adalah search_result_index: 0 dan hasil yang dikembalikan alat adalah search_result_index: 1, sesuai dengan urutan kemunculan blok search_result dalam percakapan:
{
"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
}
]
}
]
}Mencampur dengan tipe konten lain
Dalam pesan pengguna, blok search_result dapat berdampingan dengan blok konten lain apa pun. Contoh Metode 2 memasangkan hasil pencarian dengan pertanyaan text, dan blok gambar atau dokumen dapat bergabung dengan cara yang sama.
Hasil alat lebih ketat: jika ada blok dalam array konten tool_result yang berupa search_result, semua bloknya harus berupa search_result. Mencampur hasil pencarian dengan tipe blok lain dalam hasil alat yang sama akan mengembalikan kesalahan validasi. Untuk mengembalikan teks pendukung bersama hasil pencarian yang bersumber dari alat, sertakan teks tersebut sebagai blok teks di dalam salah satu array content hasil pencarian, di mana teks itu juga menjadi dapat dikutip.
Kontrol cache
Tambahkan cache_control pada blok hasil pencarian untuk meng-cache-nya agar dapat digunakan kembali di berbagai permintaan. Pengaturan ini berdampingan dengan citations pada blok yang sama:
{
"type": "search_result",
"source": "https://docs.company.com/guide",
"title": "User Guide",
"content": [{ "type": "text", "text": "..." }],
"citations": { "enabled": true },
"cache_control": { "type": "ephemeral" }
}Lihat Caching prompt untuk panjang minimum yang dapat di-cache dan persyaratan lainnya.
Kontrol sitasi
Secara default, sitasi dinonaktifkan untuk hasil pencarian. Anda dapat mengaktifkan sitasi dengan menetapkan konfigurasi citations secara eksplisit:
{
"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
}
}Ketika citations.enabled diatur ke true, Haijun melampirkan referensi sitasi pada blok teks yang mengambil dari hasil pencarian.
Warning: Sitasi bersifat semua-atau-tidak-sama-sekali: semua hasil pencarian dalam satu permintaan harus mengaktifkan sitasi, atau semuanya harus menonaktifkannya. Mencampur hasil pencarian dengan pengaturan sitasi yang berbeda akan menghasilkan kesalahan.
Praktik terbaik
Untuk pencarian berbasis alat (Metode 1)
- Konten dinamis: Gunakan untuk pencarian real-time dan aplikasi RAG yang dinamis
- Penanganan kesalahan: Kembalikan pesan yang sesuai ketika pencarian gagal
- Batas hasil: Kembalikan hanya hasil yang paling relevan untuk menghindari luapan konteks
Untuk pencarian tingkat atas (Metode 2)
- Konten yang telah diambil sebelumnya: Gunakan ketika Anda sudah memiliki hasil pencarian
- Pemrosesan batch: Ideal untuk memproses beberapa hasil pencarian sekaligus
- Pengujian: Sangat baik untuk menguji perilaku sitasi dengan konten yang sudah diketahui
Praktik terbaik umum
- Susun hasil secara efektif:
- Gunakan URL sumber yang jelas dan permanen
- Berikan judul yang deskriptif
- Pecah konten panjang menjadi blok teks yang logis untuk memberi Haijun batas sitasi yang lebih halus
- Jaga konsistensi:
- Gunakan format sumber yang konsisten di seluruh aplikasi Anda
- Pastikan judul mencerminkan konten secara akurat
- Jaga konsistensi pemformatan
- Tangani kesalahan dengan baik: ketika pencarian gagal atau tidak mengembalikan apa pun, kembalikan blok teks biasa yang menjelaskan hasilnya (misalnya,
{"type": "text", "text": "No results found."}) alih-alih memunculkan kesalahan: Haijun menjelaskan hasil kosong tersebut kepada pengguna, dan percakapan berlanjut.
Keterbatasan
- Blok konten hasil pencarian tersedia di Haijun API, Amazon Bedrock, dan Google Cloud.
- Hanya konten teks yang didukung di dalam hasil pencarian (tanpa gambar atau media lain).
- Blok
search_resulthanya dapat muncul dalam pesan pengguna (termasuk di dalam hasil alat). Pesan asisten dengan hasil pencarian akan ditolak.
- Ketika alat pencarian web diaktifkan dalam permintaan yang sama, sitasi harus diaktifkan pada semua blok
search_result.
Langkah selanjutnya
Deteksi dan tangani alasan berhenti penolakan dalam respons streaming, dan coba ulang permintaan yang ditolak pada model cadangan.
Landaskan respons Haijun pada dokumen sumber Anda. Sitasi mengembalikan kutipan persis yang mendukung setiap klaim, sehingga Anda dapat memverifikasi jawaban dan menampilkan sumber kepada pengguna Anda.
Beri Haijun akses ke konten web terkini dengan sumber yang dikutip, pemfilteran dinamis opsional, dan kontrol domain.
Lihat dokumentasi lengkap Messages API, termasuk tipe blok konten.
Cache hasil pencarian dengan cache_control untuk mengurangi biaya dan latensi pada permintaan berulang.