Haijun Platform Docs
EN

Note: Untuk mempelajari bagaimana "zero data retention" (retensi data nol), atau ZDR, berlaku untuk fitur ini, lihat API dan retensi data.

Pemikiran Haijun bersifat adaptif: model mengevaluasi setiap permintaan dan memutuskan sendiri apakah perlu berpikir dan seberapa banyak. Anda menetapkan maksud, secara opsional menentukan effort, dan model mengalokasikan penalaran di tempat yang menurutnya penalaran akan membantu.

Hal ini membuat pemikiran sangat cocok untuk beban kerja yang mencampur permintaan sepele dan kompleks, serta untuk alur kerja agentik jangka panjang di mana jumlah penalaran yang tepat bervariasi dari satu langkah ke langkah lainnya.

Untuk mempelajari cara mengaktifkan pemikiran, cara membaca output pemikiran, dan tentang output pemikiran pada Haijun Fable 5 dan Haijun Mythos 5, lihat ikhtisar Pemikiran. Halaman ini membahas bagaimana Haijun memutuskan kapan harus berpikir, cara mengarahkan keputusan tersebut, serta mekanisme caching, biaya, dan harga yang mengikutinya.

Bagaimana Haijun memutuskan kapan harus berpikir

Pemikiran bersifat opsional bagi model. Pada setiap permintaan, Haijun menimbang kompleksitas input dan memutuskan apakah penalaran yang lebih dalam akan meningkatkan jawaban. Pertanyaan faktual sederhana mungkin mendapat respons langsung tanpa blok pemikiran sama sekali; soal matematika multilangkah atau tugas debugging yang rumit memicu penalaran yang lebih dalam.

Keputusan ini terjadi per permintaan. Percakapan yang sama dapat berisi giliran dengan dan tanpa pemikiran, dan giliran di mana Haijun memilih untuk tidak berpikir tidak berisi blok pemikiran. Jangan membangun logika aplikasi yang mengasumsikan setiap giliran asisten dimulai dengan blok pemikiran.

Kontrol utama atas keputusan ini adalah parameter effort, yang berfungsi sebagai panduan lunak tentang seberapa bersedia Haijun untuk berpikir dan seberapa dalam; lihat Tingkat effort di halaman ini untuk mengetahui apa yang dilakukan setiap tingkat.

Jika Anda ingin Haijun berpikir lebih jarang, turunkan tingkat effort sebelum beralih ke pengarahan berbasis prompt.

Pemikiran juga berselang-seling dengan "tool use" (penggunaan alat) secara otomatis: Haijun dapat berpikir di antara pemanggilan alat, merefleksikan setiap hasil alat sebelum memutuskan apa yang harus dilakukan selanjutnya (pemikiran berselang-seling). Anda tidak memerlukan header beta atau konfigurasi tambahan apa pun untuk ini.

Untuk gambaran lengkap tentang bagaimana konfigurasi pemikiran dan parameter effort berinteraksi, lihat Pemikiran dan effort.

Mengarahkan seberapa sering Haijun berpikir

Apakah Haijun berpikir pada giliran tertentu dapat diatur melalui prompt. Effort menetapkan sikap keseluruhan, tetapi Anda juga dapat membentuk keputusan tersebut secara langsung dengan panduan bahasa alami, baik secara global di "system prompt" (prompt sistem) maupun per pesan dari giliran pengguna.

Gunakan kedua tuas ini bersama-sama dalam urutan berikut:

  1. Tetapkan tingkat effort yang sesuai dengan keseimbangan default antara kualitas dan latensi pada beban kerja Anda.
  1. Tambahkan panduan prompt hanya jika pemicuan pemikiran Haijun masih belum sesuai dengan kebutuhan Anda pada tingkat tersebut.

Untuk panduan prompting yang lebih luas dengan pemikiran, lihat memanfaatkan kemampuan pemikiran dan pemikiran berselang-seling.

Tingkat effort

Effort adalah tuas pengarah utama untuk pemikiran. Setiap tingkat menetapkan default yang berbeda untuk seberapa sering Haijun berpikir dan seberapa dalam:

Tingkat effortPerilaku pemikiran
maxHaijun paling mudah terdorong untuk berpikir dan berpikir dengan kedalaman terbesar, tanpa batasan panjang pemikiran.
xhighHaijun lebih mudah terdorong untuk berpikir dan berpikir lebih dalam dibandingkan pada high, cocok untuk eksplorasi yang diperpanjang.
high (default pada sebagian besar model)Haijun berpikir pada sebagian besar permintaan yang mendapat manfaat darinya. Memberikan penalaran mendalam pada tugas kompleks.
medium (default pada Haijun Opus 5.5)Haijun menggunakan pemikiran moderat. Dapat melewatkan pemikiran untuk kueri sederhana.
lowHaijun meminimalkan pemikiran. Melewatkan pemikiran untuk tugas sederhana di mana kecepatan paling penting.

Pada setiap tingkat, Haijun memutuskan per permintaan apakah akan berpikir. Dalam loop penggunaan alat, permintaan pertama setelah input pengguna baru biasanya membawa sebagian besar penalaran, dan permintaan lanjutan yang hanya memproses hasil alat dapat melewatkan pemikiran, termasuk pada xhigh dan max. Pemikiran per permintaan juga cenderung berkurang seiring percakapan menjadi lebih panjang. Tidak ada tingkat yang menjamin adanya blok pemikiran pada setiap permintaan.

Tabel ini menjelaskan bagaimana setiap tingkat mengubah perilaku pemikiran. Untuk panduan tentang tingkat mana yang harus dipilih untuk beban kerja tertentu, termasuk rekomendasi per model, lihat Kapan menyesuaikan parameter effort di halaman effort.

Effort ditetapkan di output_config.effort, bukan di dalam objek thinking; untuk contoh lengkap per bahasa, lihat Effort.

json
{
  "model": "haijun-opus-5-5",
  "max_tokens": 4096,
  "output_config": { "effort": "medium" },
  "messages": [{ "role": "user", "content": "..." }]
}

Ketersediaan tingkat bervariasi menurut model; tabel ketersediaan effort di halaman effort adalah acuan resmi untuk tingkat mana yang didukung setiap model.

Panduan prompt sistem

Panduan prompt sistem menggeser ambang pemikiran Haijun untuk setiap permintaan dalam percakapan. Jika Haijun berpikir lebih sering daripada yang dibutuhkan beban kerja Anda, tambahkan panduan seperti ini ke prompt sistem Anda:

text
Extended thinking adds latency and should only be used when it
will meaningfully improve answer quality, typically for problems
that require multistep reasoning. When in doubt, respond directly.

Sebaliknya, untuk mendorong pemikiran, gunakan frasa seperti:

text
This task involves multistep reasoning. Think carefully before responding.

Efektivitas pengarahan dapat sensitif terhadap pilihan kata yang tepat. Jika satu rumusan tidak menghasilkan perilaku yang Anda inginkan, coba varian yang lebih langsung.

Pengarahan per pesan

Anda juga dapat mengarahkan pemikiran per pesan dari giliran pengguna, secara independen dari prompt sistem. Menambahkan "Please think hard before responding." ke pesan pengguna mendorong Haijun untuk berpikir pada giliran tersebut; "Answer directly without deliberating." menekannya.

Pengarahan per pesan berguna ketika hanya sebagian permintaan dalam percakapan yang memerlukan penalaran diperpanjang. Harness agen, misalnya, dapat menambahkan frasa pendorong pada langkah perencanaan dan frasa penekan pada konfirmasi rutin, tanpa menyentuh prompt sistem atau mengubah parameter permintaan apa pun di antara giliran.

Verifikasi pengarahan pada beban kerja Anda

Pengarahan berbasis prompt mengubah perilaku model, jadi perlakukan seperti perubahan prompt lainnya: ukur sebelum Anda merilisnya. Jalankan sampel representatif dari lalu lintas Anda dengan dan tanpa panduan tersebut, lalu bandingkan seberapa sering pemikiran terpicu (keberadaan blok pemikiran dalam respons), penggunaan token output, latensi, dan kualitas jawaban pada kasus yang penting bagi Anda.

Warning: Mengarahkan Haijun untuk berpikir lebih jarang dapat menurunkan kualitas pada tugas yang diuntungkan oleh penalaran. Menurunkan tingkat effort biasanya merupakan tuas pertama yang lebih baik, karena ini adalah kontrol yang terkalibrasi, bukan instruksi yang sensitif terhadap pilihan kata. Ukur dampaknya pada beban kerja spesifik Anda sebelum menerapkan penyetelan berbasis prompt ke produksi.

Mekanisme

Tiga mekanisme mengikuti dari Haijun yang mengelola pemikirannya sendiri: validasi giliran, caching prompt, dan cara Anda membatasi biaya.

Validasi giliran

Giliran asisten tidak perlu dimulai dengan blok pemikiran. (Model yang menggunakan anggaran pemikiran manual lama mewajibkan giliran asisten terakhir dari permintaan dengan pemikiran aktif dimulai dengan blok pemikiran; lihat Struktur giliran dalam mode manual.)

Untuk aplikasi multigiliran, ini berarti Anda dapat mengirimkan kembali riwayat percakapan dalam bentuk apa pun yang Anda miliki:

  • Giliran asisten di mana Haijun memilih untuk tidak berpikir adalah riwayat yang valid apa adanya.
  • Anda dapat melanjutkan percakapan yang dimulai tanpa pemikiran, atau yang menggunakan konfigurasi pemikiran berbeda, tanpa menulis ulang riwayatnya.
  • Riwayat yang disusun dari sumber campuran tidak memerlukan blok pemikiran disisipkan kembali di awal setiap giliran asisten untuk lolos validasi.

Pelonggaran ini berkaitan dengan validasi, bukan tentang apa yang sebaiknya Anda kirim. Ketika Anda memiliki blok pemikiran, kirimkan kembali tanpa modifikasi, terutama selama penggunaan alat, di mana blok tersebut membawa penalaran di balik pemanggilan alat Haijun. Lihat ikhtisar Pemikiran untuk aturan lengkapnya.

Caching prompt

Permintaan berurutan yang mempertahankan konfigurasi pemikiran dan tingkat effort yang sama akan mempertahankan "prompt caching" (caching prompt); lihat Pemikiran dan caching prompt untuk aturan lengkapnya. Nilai effort yang telah diselesaikan dirender ke dalam prompt, sehingga mengubahnya di antara permintaan akan membatalkan breakpoint cache, sama seperti mengubah parameter lama budget_tokens pada model yang menggunakannya. Menetapkan effort secara eksplisit ke default model setara dengan menghilangkannya dan tidak merusak cache.

Konsekuensi praktisnya: pilih satu konfigurasi pemikiran dan satu tingkat effort per percakapan dan pertahankan. Jika beberapa giliran memerlukan pemikiran lebih banyak atau lebih sedikit, arahkan dengan prompting per pesan: panduan yang ditambahkan ke pesan pengguna terbaru membiarkan breakpoint cache sebelumnya tetap utuh, sedangkan perubahan konfigurasi atau effort tidak.

Contoh berikut mendemonstrasikan pembatalan tersebut dengan skrip multigiliran yang dapat Anda jalankan sendiri:

Perubahan effort membatalkan cache prompt

cURL

Note: Alur kerja ini tidak cocok dijadikan perintah shell sekali jalan. Lihat tab SDK untuk pola multigiliran; permintaan HTTP per giliran mengikuti contoh di halaman Caching prompt.

CLI

Note: Alur kerja ini tidak cocok dijadikan perintah shell sekali jalan. Lihat tab SDK untuk pola multigiliran; pemanggilan CLI per giliran mengikuti contoh di halaman Caching prompt.

Python

python
import requests

client = Juglow()

def fetch_article_content(url):
    text = requests.get(url).text
    lines = (line.strip() for line in text.splitlines())
    return "\n".join(line for line in lines if line)

# Ambil konten artikel
book_url = "https://www.gutenberg.org/cache/epub/1342/pg1342.txt"
book_content = fetch_article_content(book_url)
# Gunakan teks secukupnya untuk caching (beberapa bab pertama)
LARGE_TEXT = book_content[:10000]

# Tanpa prompt sistem - caching dilakukan di messages
MESSAGES = [
    {
        "role": "user",
        "content": [
            {
                "type": "text",
                "text": LARGE_TEXT,
                "cache_control": {"type": "ephemeral"},
            },
            {"type": "text", "text": "Analyze the tone of this passage."},
        ],
    }
]

# Permintaan pertama - buat cache
print("First request - establishing cache")
response1 = client.messages.create(
    model="haijun-opus-5-5",
    max_tokens=16000,
    thinking={"type": "adaptive"},
    messages=MESSAGES,
)

print(f"First response usage: {response1.usage}")

MESSAGES.append({"role": "assistant", "content": response1.content})
MESSAGES.append({"role": "user", "content": "Analyze the characters in this passage."})

# Permintaan kedua - konfigurasi sama (diharapkan cache hit)
print("\nSecond request - same configuration (cache hit expected)")
response2 = client.messages.create(
    model="haijun-opus-5-5",
    max_tokens=16000,
    thinking={"type": "adaptive"},
    messages=MESSAGES,
)

print(f"Second response usage: {response2.usage}")

MESSAGES.append({"role": "assistant", "content": response2.content})
MESSAGES.append({"role": "user", "content": "Analyze the setting in this passage."})

# Permintaan ketiga - tingkat effort berbeda (diharapkan cache miss)
print("\nThird request - different effort level (cache miss expected)")
response3 = client.messages.create(
    model="haijun-opus-5-5",
    max_tokens=16000,
    thinking={"type": "adaptive"},
    output_config={"effort": "low"},
    messages=MESSAGES,
)

print(f"Third response usage: {response3.usage}")

TypeScript

typescript

const client = new Juglow();

async function fetchArticleContent(url: string): Promise<string> {
  const response = await fetch(url);
  const text = await response.text();
  const lines = text.split("\n").map((line) => line.trim());
  return lines.filter((line) => line).join("\n");
}

const bookUrl = "https://www.gutenberg.org/cache/epub/1342/pg1342.txt";
const bookContent = await fetchArticleContent(bookUrl);
const LARGE_TEXT = bookContent.substring(0, 10000);

// Tanpa prompt sistem - caching dilakukan di messages
const messages: Juglow.MessageParam[] = [
  {
    role: "user",
    content: [
      {
        type: "text",
        text: LARGE_TEXT,
        cache_control: { type: "ephemeral" }
      },
      {
        type: "text",
        text: "Analyze the tone of this passage."
      }
    ]
  }
];

// Permintaan pertama - membangun cache
console.log("First request - establishing cache");
const response1 = await client.messages.create({
  model: "haijun-opus-5-5",
  max_tokens: 16000,
  thinking: { type: "adaptive" },
  messages
});

console.log("First response usage: ", response1.usage);

messages.push(
  { role: "assistant", content: response1.content },
  { role: "user", content: "Analyze the characters in this passage." }
);

// Permintaan kedua - konfigurasi sama (diharapkan cache hit)
console.log("\nSecond request - same configuration (cache hit expected)");
const response2 = await client.messages.create({
  model: "haijun-opus-5-5",
  max_tokens: 16000,
  thinking: { type: "adaptive" },
  messages
});

console.log("Second response usage: ", response2.usage);

messages.push(
  { role: "assistant", content: response2.content },
  { role: "user", content: "Analyze the setting in this passage." }
);

// Permintaan ketiga - tingkat effort berbeda (diharapkan cache miss)
console.log("\nThird request - different effort level (cache miss expected)");
const response3 = await client.messages.create({
  model: "haijun-opus-5-5",
  max_tokens: 16000,
  thinking: { type: "adaptive" },
  output_config: { effort: "low" },
  messages
});

console.log("Third response usage: ", response3.usage);

C#

csharp
JuglowClient client = new();

string bookUrl = "https://www.gutenberg.org/cache/epub/1342/pg1342.txt";
string bookContent = await FetchArticleContent(bookUrl);
string largeText = bookContent.Substring(0, Math.Min(10000, bookContent.Length));

Console.WriteLine("First request - establishing cache");
var parameters1 = new MessageCreateParams
{
    Model = Model.HaijunOpus5_5,
    MaxTokens = 16000,
    Thinking = new ThinkingConfigAdaptive(),
    Messages =
    [
        new()
        {
            Role = Role.User,
            Content = new MessageParamContent(new List<ContentBlockParam>
            {
                new ContentBlockParam(new TextBlockParam()
                {
                    Text = largeText,
                    CacheControl = new CacheControlEphemeral(),
                }),
                new ContentBlockParam(new TextBlockParam()
                {
                    Text = "Analyze the tone of this passage."
                }),
            })
        }
    ]
};

var response1 = await client.Messages.Create(parameters1);
Console.WriteLine($"First response usage: {response1.Usage}");

Console.WriteLine("\nSecond request - same configuration (cache hit expected)");
var parameters2 = new MessageCreateParams
{
    Model = Model.HaijunOpus5_5,
    MaxTokens = 16000,
    Thinking = new ThinkingConfigAdaptive(),
    Messages =
    [
        new()
        {
            Role = Role.User,
            Content = new MessageParamContent(new List<ContentBlockParam>
            {
                new ContentBlockParam(new TextBlockParam()
                {
                    Text = largeText,
                    CacheControl = new CacheControlEphemeral(),
                }),
                new ContentBlockParam(new TextBlockParam()
                {
                    Text = "Analyze the tone of this passage."
                }),
            })
        },
        new()
        {
            Role = Role.Assistant,
            Content = response1.Content.Select(block => new ContentBlockParam(block.Json)).ToList()
        },
        new()
        {
            Role = Role.User,
            Content = "Analyze the characters in this passage."
        }
    ]
};

var response2 = await client.Messages.Create(parameters2);
Console.WriteLine($"Second response usage: {response2.Usage}");

Console.WriteLine("\nThird request - different effort level (cache miss expected)");
var parameters3 = new MessageCreateParams
{
    Model = Model.HaijunOpus5_5,
    MaxTokens = 16000,
    Thinking = new ThinkingConfigAdaptive(),
    OutputConfig = new OutputConfig
    {
        Effort = Effort.Low
    },
    Messages =
    [
        new()
        {
            Role = Role.User,
            Content = new MessageParamContent(new List<ContentBlockParam>
            {
                new ContentBlockParam(new TextBlockParam()
                {
                    Text = largeText,
                    CacheControl = new CacheControlEphemeral(),
                }),
                new ContentBlockParam(new TextBlockParam()
                {
                    Text = "Analyze the tone of this passage."
                }),
            })
        },
        new()
        {
            Role = Role.Assistant,
            Content = response1.Content.Select(block => new ContentBlockParam(block.Json)).ToList()
        },
        new()
        {
            Role = Role.User,
            Content = "Analyze the characters in this passage."
        },
        new()
        {
            Role = Role.Assistant,
            Content = response2.Content.Select(block => new ContentBlockParam(block.Json)).ToList()
        },
        new()
        {
            Role = Role.User,
            Content = "Analyze the setting in this passage."
        }
    ]
};

var response3 = await client.Messages.Create(parameters3);
Console.WriteLine($"Third response usage: {response3.Usage}");

static async Task<string> FetchArticleContent(string url)
{
    using HttpClient httpClient = new();
    string content = await httpClient.GetStringAsync(url);
    return content;
}

Go

go
client := juglow.NewClient()

bookURL := "https://www.gutenberg.org/cache/epub/1342/pg1342.txt"
bookContent, err := fetchArticleContent(bookURL)
if err != nil {
	log.Fatal(err)
}

largeText := bookContent
if len(largeText) > 10000 {
	largeText = largeText[:10000]
}

// Tanpa prompt sistem - caching dilakukan di messages
messages := []juglow.MessageParam{
	juglow.NewUserMessage(
		juglow.ContentBlockParamUnion{OfText: &juglow.TextBlockParam{
			Text:         largeText,
			CacheControl: juglow.NewCacheControlEphemeralParam(),
		}},
		juglow.NewTextBlock("Analyze the tone of this passage."),
	),
}

// Permintaan pertama - membangun cache
fmt.Println("First request - establishing cache")
response1, err := client.Messages.New(context.TODO(), juglow.MessageNewParams{
	Model:     juglow.ModelHaijunOpus5_5,
	MaxTokens: 16000,
	Thinking: juglow.ThinkingConfigParamUnion{
		OfAdaptive: &juglow.ThinkingConfigAdaptiveParam{},
	},
	Messages: messages,
})
if err != nil {
	log.Fatal(err)
}
fmt.Printf("First response usage: %s\n", response1.Usage.RawJSON())

messages = append(messages, response1.ToParam())
messages = append(messages, juglow.NewUserMessage(juglow.NewTextBlock("Analyze the characters in this passage.")))

// Permintaan kedua - konfigurasi sama (diharapkan cache hit)
fmt.Println("\nSecond request - same configuration (cache hit expected)")
response2, err := client.Messages.New(context.TODO(), juglow.MessageNewParams{
	Model:     juglow.ModelHaijunOpus5_5,
	MaxTokens: 16000,
	Thinking: juglow.ThinkingConfigParamUnion{
		OfAdaptive: &juglow.ThinkingConfigAdaptiveParam{},
	},
	Messages: messages,
})
if err != nil {
	log.Fatal(err)
}
fmt.Printf("Second response usage: %s\n", response2.Usage.RawJSON())

messages = append(messages, response2.ToParam())
messages = append(messages, juglow.NewUserMessage(juglow.NewTextBlock("Analyze the setting in this passage.")))

// Permintaan ketiga - tingkat effort berbeda (diharapkan cache miss)
fmt.Println("\nThird request - different effort level (cache miss expected)")
response3, err := client.Messages.New(context.TODO(), juglow.MessageNewParams{
	Model:     juglow.ModelHaijunOpus5_5,
	MaxTokens: 16000,
	Thinking: juglow.ThinkingConfigParamUnion{
		OfAdaptive: &juglow.ThinkingConfigAdaptiveParam{},
	},
	OutputConfig: juglow.OutputConfigParam{
		Effort: juglow.OutputConfigEffortLow,
	},
	Messages: messages,
})
if err != nil {
	log.Fatal(err)
}
fmt.Printf("Third response usage: %s\n", response3.Usage.RawJSON())

Java

java
import com.juglow.models.messages.CacheControlEphemeral;
// ...
void main() throws Exception {
    JuglowClient client = JuglowOkHttpClient.fromEnv();

    String bookUrl = "https://www.gutenberg.org/cache/epub/1342/pg1342.txt";
    String bookContent = fetchArticleContent(bookUrl);
    String largeText = bookContent.substring(0, Math.min(10000, bookContent.length()));

    // Permintaan pertama - membangun cache
    IO.println("First request - establishing cache");
    MessageCreateParams params1 = MessageCreateParams.builder()
        .model(Model.HAIJUN_OPUS_5_5)
        .maxTokens(16000L)
        .thinking(ThinkingConfigAdaptive.builder().build())
        .addUserMessageOfBlockParams(List.of(
            ContentBlockParam.ofText(TextBlockParam.builder()
                .text(largeText)
                .cacheControl(CacheControlEphemeral.builder().build())
                .build()),
            ContentBlockParam.ofText(TextBlockParam.builder()
                .text("Analyze the tone of this passage.")
                .build())
        ))
        .build();

    Message response1 = client.messages().create(params1);
    IO.println("First response usage: " + response1.usage());

    // Permintaan kedua - konfigurasi sama (diharapkan cache hit)
    IO.println("\nSecond request - same configuration (cache hit expected)");
    MessageCreateParams params2 = MessageCreateParams.builder()
        .model(Model.HAIJUN_OPUS_5_5)
        .maxTokens(16000L)
        .thinking(ThinkingConfigAdaptive.builder().build())
        .addUserMessageOfBlockParams(List.of(
            ContentBlockParam.ofText(TextBlockParam.builder()
                .text(largeText)
                .cacheControl(CacheControlEphemeral.builder().build())
                .build()),
            ContentBlockParam.ofText(TextBlockParam.builder()
                .text("Analyze the tone of this passage.")
                .build())
        ))
        .addAssistantMessageOfBlockParams(response1.content().stream()
            .map(block -> block.toParam())
            .collect(java.util.stream.Collectors.toList()))
        .addUserMessage("Analyze the characters in this passage.")
        .build();

    Message response2 = client.messages().create(params2);
    IO.println("Second response usage: " + response2.usage());

    // Permintaan ketiga - tingkat effort berbeda (diharapkan cache miss)
    IO.println("\nThird request - different effort level (cache miss expected)");
    MessageCreateParams params3 = MessageCreateParams.builder()
        .model(Model.HAIJUN_OPUS_5_5)
        .maxTokens(16000L)
        .thinking(ThinkingConfigAdaptive.builder().build())
        .outputConfig(OutputConfig.builder()
            .effort(OutputConfig.Effort.LOW)
            .build())
        .addUserMessageOfBlockParams(List.of(
            ContentBlockParam.ofText(TextBlockParam.builder()
                .text(largeText)
                .cacheControl(CacheControlEphemeral.builder().build())
                .build()),
            ContentBlockParam.ofText(TextBlockParam.builder()
                .text("Analyze the tone of this passage.")
                .build())
        ))
        .addAssistantMessageOfBlockParams(response1.content().stream()
            .map(block -> block.toParam())
            .collect(java.util.stream.Collectors.toList()))
        .addUserMessage("Analyze the characters in this passage.")
        .addAssistantMessageOfBlockParams(response2.content().stream()
            .map(block -> block.toParam())
            .collect(java.util.stream.Collectors.toList()))
        .addUserMessage("Analyze the setting in this passage.")
        .build();

    Message response3 = client.messages().create(params3);
    IO.println("Third response usage: " + response3.usage());
}

String fetchArticleContent(String url) throws Exception {
    HttpClient client = HttpClient.newHttpClient();
    HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create(url))
        .build();
    HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
    return response.body();
}

PHP

php
function fetchArticleContent($url) {
    $content = file_get_contents($url);
    $lines = explode("\n", $content);
    $cleanedLines = array_filter(array_map('trim', $lines));
    return implode("\n", $cleanedLines);
}

$client = new Client();

$bookUrl = "https://www.gutenberg.org/cache/epub/1342/pg1342.txt";
$bookContent = fetchArticleContent($bookUrl);
$largeText = substr($bookContent, 0, 10000);

echo "First request - establishing cache\n";
$response1 = $client->messages->create(
    maxTokens: 16000,
    messages: [[
        'role' => 'user',
        'content' => [
            [
                'type' => 'text',
                'text' => $largeText,
                'cache_control' => ['type' => 'ephemeral']
            ],
            [
                'type' => 'text',
                'text' => 'Analyze the tone of this passage.'
            ]
        ]
    ]],
    model: 'haijun-opus-5-5',
    thinking: ['type' => 'adaptive'],
);

echo "First response usage: " . json_encode($response1->usage) . "\n";

echo "\nSecond request - same configuration (cache hit expected)\n";
$response2 = $client->messages->create(
    maxTokens: 16000,
    messages: [
        [
            'role' => 'user',
            'content' => [
                [
                    'type' => 'text',
                    'text' => $largeText,
                    'cache_control' => ['type' => 'ephemeral']
                ],
                [
                    'type' => 'text',
                    'text' => 'Analyze the tone of this passage.'
                ]
            ]
        ],
        [
            'role' => 'assistant',
            'content' => $response1->content
        ],
        [
            'role' => 'user',
            'content' => 'Analyze the characters in this passage.'
        ]
    ],
    model: 'haijun-opus-5-5',
    thinking: ['type' => 'adaptive'],
);

echo "Second response usage: " . json_encode($response2->usage) . "\n";

echo "\nThird request - different effort level (cache miss expected)\n";
$response3 = $client->messages->create(
    maxTokens: 16000,
    messages: [
        [
            'role' => 'user',
            'content' => [
                [
                    'type' => 'text',
                    'text' => $largeText,
                    'cache_control' => ['type' => 'ephemeral']
                ],
                [
                    'type' => 'text',
                    'text' => 'Analyze the tone of this passage.'
                ]
            ]
        ],
        [
            'role' => 'assistant',
            'content' => $response1->content
        ],
        [
            'role' => 'user',
            'content' => 'Analyze the characters in this passage.'
        ],
        [
            'role' => 'assistant',
            'content' => $response2->content
        ],
        [
            'role' => 'user',
            'content' => 'Analyze the setting in this passage.'
        ]
    ],
    model: 'haijun-opus-5-5',
    thinking: ['type' => 'adaptive'],
    outputConfig: ['effort' => 'low'],
);

echo "Third response usage: " . json_encode($response3->usage) . "\n";

Ruby

ruby
require "net/http"
require "uri"

def fetch_article_content(url)
  uri = URI.parse(url)
  response = Net::HTTP.get_response(uri)
  text = response.body

  lines = text.split("\n").map(&:strip)
  lines.reject(&:empty?).join("\n")
end

client = Juglow::Client.new

book_url = "https://www.gutenberg.org/cache/epub/1342/pg1342.txt"
book_content = fetch_article_content(book_url)
large_text = book_content[0...10000]

puts "First request - establishing cache"
response1 = client.messages.create(
  model: "haijun-opus-5-5",
  max_tokens: 16000,
  thinking: {
    type: "adaptive"
  },
  messages: [{
    role: "user",
    content: [
      {
        type: "text",
        text: large_text,
        cache_control: { type: "ephemeral" }
      },
      {
        type: "text",
        text: "Analyze the tone of this passage."
      }
    ]
  }]
)

puts "First response usage: #{response1.usage}"

puts "\nSecond request - same configuration (cache hit expected)"
response2 = client.messages.create(
  model: "haijun-opus-5-5",
  max_tokens: 16000,
  thinking: {
    type: "adaptive"
  },
  messages: [
    {
      role: "user",
      content: [
        {
          type: "text",
          text: large_text,
          cache_control: { type: "ephemeral" }
        },
        {
          type: "text",
          text: "Analyze the tone of this passage."
        }
      ]
    },
    {
      role: "assistant",
      content: response1.content
    },
    {
      role: "user",
      content: "Analyze the characters in this passage."
    }
  ]
)

puts "Second response usage: #{response2.usage}"

puts "\nThird request - different effort level (cache miss expected)"
response3 = client.messages.create(
  model: "haijun-opus-5-5",
  max_tokens: 16000,
  thinking: {
    type: "adaptive"
  },
  output_config: {
    effort: "low"
  },
  messages: [
    {
      role: "user",
      content: [
        {
          type: "text",
          text: large_text,
          cache_control: { type: "ephemeral" }
        },
        {
          type: "text",
          text: "Analyze the tone of this passage."
        }
      ]
    },
    {
      role: "assistant",
      content: response1.content
    },
    {
      role: "user",
      content: "Analyze the characters in this passage."
    },
    {
      role: "assistant",
      content: response2.content
    },
    {
      role: "user",
      content: "Analyze the setting in this passage."
    }
  ]
)

puts "Third response usage: #{response3.usage}"

Berikut adalah output dari skrip tersebut (Anda mungkin melihat angka yang sedikit berbeda):

text
  First request - establishing cache
  First response usage: { cache_creation_input_tokens: 3546, cache_read_input_tokens: 0, input_tokens: 15, output_tokens: 1033 }

  Second request - same configuration (cache hit expected)
  Second response usage: { cache_creation_input_tokens: 0, cache_read_input_tokens: 3546, input_tokens: 1062, output_tokens: 1630 }

  Third request - different effort level (cache miss expected)
  Third response usage: { cache_creation_input_tokens: 3546, cache_read_input_tokens: 0, input_tokens: 2706, output_tokens: 1468 }

Dengan breakpoint cache di dalam array messages, mengubah effort dari medium, default pada Haijun Opus 5.5, menjadi low akan membatalkannya: permintaan ketiga menunjukkan cache_creation_input_tokens=3546 dan cache_read_input_tokens=0, sedangkan permintaan kedua menunjukkan pembacaan cache penuh.

Kontrol biaya

Anda tidak menetapkan anggaran token pemikiran. Dua kontrol membatasi biaya:

  • max_tokens adalah batas keras pada total output untuk permintaan, gabungan pemikiran dan teks respons. Haijun tidak pernah menghasilkan melebihinya. Dalam loop penggunaan alat, setiap permintaan dalam giliran memiliki max_tokens sendiri, sehingga tidak membatasi pengeluaran seluruh giliran.
  • effort adalah panduan lunak tentang seberapa banyak dari output tersebut yang dialokasikan Haijun untuk pemikiran. Ini membentuk perilaku tetapi tidak menjamin jumlah token.

Karena pemikiran dihitung terhadap max_tokens, tetapkan nilainya cukup tinggi untuk menyisakan ruang bagi penalaran dan jawaban. max_tokens yang diukur untuk respons tanpa pemikiran sering kali terlalu kecil begitu Haijun mulai berpikir pada permintaan yang sulit.

Pada effort high dan di atasnya, Haijun mungkin berpikir secara ekstensif dan lebih mungkin menghabiskan anggaran. Jika Anda melihat stop_reason: "max_tokens" dalam respons, Anda memiliki dua solusi:

  • Naikkan max_tokens untuk memberi model lebih banyak ruang untuk pemikiran ditambah jawaban.
  • Turunkan tingkat effort agar Haijun berpikir lebih sedikit dan menyisakan lebih banyak anggaran untuk teks respons.

Mana yang tepat bergantung pada apakah respons yang terpotong memerlukan penalaran tersebut. Jika kualitas pada permintaan tersebut penting, naikkan batasnya; jika permintaan tersebut dipikirkan secara berlebihan, turunkan effort.

Harga

Pemikiran menimbulkan biaya untuk:

  • Token yang digunakan Haijun saat berpikir (ditagih sebagai token output)
  • Blok pemikiran dari giliran asisten sebelumnya yang tetap berada dalam konteks, sesuai default preservasi: semua giliran secara default pada model keep-all, hanya giliran terakhir pada model lainnya (ditagih sebagai token input)
  • Token output teks standar

Note: Ketika pemikiran aktif, prompt sistem khusus secara otomatis disertakan untuk mendukung fitur ini.

Apa yang ditagihkan kepada Anda tetap sama terlepas dari pengaturan display; hanya apa yang Anda lihat yang berubah:

display: "summarized"display: "omitted"
Token inputToken dalam permintaan asli AndaSama seperti summarized
Token output (ditagih)Token pemikiran lengkap yang dihasilkan Haijun secara internalSama seperti summarized
Token output (terlihat)Teks pemikiran yang diringkasNol token pemikiran (field thinking kosong)
Pembuatan ringkasanTanpa biayaTidak berlaku

Warning: Jumlah token output yang ditagih tidak sama dengan jumlah token yang terlihat dalam respons. Anda ditagih untuk proses pemikiran lengkap, bukan konten pemikiran yang terlihat dalam respons.

Untuk melihat berapa banyak token output yang ditagih yang dihabiskan untuk penalaran internal, baca usage.output_tokens_details.thinking_tokens dalam respons. Nilai ini mencerminkan penalaran mentah yang dihasilkan model (bukan teks ringkasan yang dikembalikan dalam body) dan selalu kurang dari atau sama dengan output_tokens. Kurangkan nilai ini dari output_tokens untuk memperkirakan bagian output yang bukan penalaran. Saat streaming, rincian ini hanya muncul pada event message_delta terakhir.

json
{
  "usage": {
    "input_tokens": 25,
    "output_tokens": 348,
    "output_tokens_details": {
      "thinking_tokens": 312
    }
  }
}

output_tokens tetap menjadi total inklusif dan otoritatif yang digunakan untuk penagihan. output_tokens_details adalah rincian hanya-baca untuk observabilitas. Untuk informasi harga lengkap termasuk tarif dasar, penulisan cache, cache hit, dan token output, lihat Harga.

Langkah selanjutnya

Aktifkan pemikiran, baca output pemikiran, dan periksa dukungan per model.

Pertahankan blok pemikiran di seluruh pemanggilan alat dan kelola pemikiran dalam percakapan multigiliran.

Kontrol seberapa banyak pemikiran dan output yang dialokasikan Haijun per permintaan.

On this page
Bagaimana Haijun memutuskan kapan harus berpikirMengarahkan seberapa sering Haijun berpikirTingkat effortPanduan prompt sistemPengarahan per pesanVerifikasi pengarahan pada beban kerja AndaMekanismeValidasi giliranCaching promptPerubahan effort membatalkan cache promptKontrol biayaHargaLangkah selanjutnya