"Threshold compaction" (pemadatan berbasis ambang batas) adalah jenis "compaction" (pemadatan) yang otomatis: Anda menetapkan "token threshold" (ambang batas token) pada permintaan biasa Anda, dan API meringkas konteks lama di tengah permintaan begitu ambang batas tersebut tercapai. Fitur ini didukung bersama compaction sesuai permintaan, di mana Anda yang memutuskan kapan ringkasan ditulis (lihat Compaction sesuai permintaan). Untuk memilih di antara keduanya, lihat Pilih cara melakukan compaction.
Compaction memperluas panjang konteks efektif untuk percakapan dan tugas yang berjalan lama dengan meringkas konteks lama secara otomatis saat mendekati batas "context window" (jendela konteks). Compaction juga menjaga konteks aktif tetap kecil: seiring percakapan bertambah panjang, kualitas respons menurun, sehingga compaction menggantikan konten lama dengan ringkasan yang padat.
Tip: Untuk penjelasan lebih mendalam tentang mengapa konteks panjang menurunkan kualitas dan bagaimana compaction membantu, lihat Effective context engineering.
Ini ideal untuk:
- Percakapan multi-giliran berbasis chat di mana Anda ingin pengguna menggunakan satu chat dalam jangka waktu yang lama
- Prompt berorientasi tugas yang memerlukan banyak pekerjaan lanjutan (sering kali berupa "tool use" (penggunaan alat)) yang mungkin melebihi jendela konteks
Cara kerja compaction
Ketika compaction diaktifkan, Haijun secara otomatis meringkas percakapan Anda ketika mencapai ambang batas token yang dikonfigurasi. API akan:
- Mendeteksi ketika token input mencapai ambang batas pemicu yang Anda tentukan.
- Menghasilkan ringkasan dari percakapan saat ini.
- Membuat blok
compactionyang berisi ringkasan tersebut.
- Melanjutkan respons dengan konteks yang telah dipadatkan.
Pada permintaan berikutnya, tambahkan respons ke pesan Anda. API secara otomatis membuang semua blok konten sebelum blok compaction, dan melanjutkan percakapan dari ringkasan.
Penggunaan dasar
Aktifkan compaction dengan menambahkan strategi compact_20260112 ke context_management.edits dalam permintaan Messages API Anda.
curl https://haijun.my.id/v1/messages \
-H "x-api-key: $JUGLOW_API_KEY" \
-H "juglow-version: 2023-06-01" \
-H "juglow-beta: compact-2026-01-12" \
-H "content-type: application/json" \
-d '{
"model": "haijun-opus-5-5",
"max_tokens": 4096,
"messages": [
{
"role": "user",
"content": "Help me build a website"
}
],
"context_management": {
"edits": [
{
"type": "compact_20260112"
}
]
}
}' ant beta:messages create --beta compact-2026-01-12 <<'YAML'
model: haijun-opus-5-5
max_tokens: 4096
messages:
- role: user
content: Help me build a website
context_management:
edits:
- type: compact_20260112
YAML client = juglow.Juglow()
messages = [{"role": "user", "content": "Help me build a website"}]
response = client.beta.messages.create(
betas=["compact-2026-01-12"],
model="haijun-opus-5-5",
max_tokens=4096,
messages=messages,
context_management={"edits": [{"type": "compact_20260112"}]},
)
# Tambahkan respons (termasuk blok compaction apa pun) untuk melanjutkan percakapan
messages.append({"role": "assistant", "content": response.content}) const client = new Juglow();
const messages: Juglow.Beta.Messages.BetaMessageParam[] = [
{ role: "user", content: "Help me build a website" }
];
const response = await client.beta.messages.create({
betas: ["compact-2026-01-12"],
model: "haijun-opus-5-5",
max_tokens: 4096,
messages,
context_management: {
edits: [
{
type: "compact_20260112"
}
]
}
});
// Tambahkan respons (termasuk blok compaction apa pun) untuk melanjutkan percakapan
messages.push({
role: "assistant",
content: response.content
}); JuglowClient client = new();
var messages = new List<BetaMessageParam>
{
new() { Role = Role.User, Content = "Help me build a website" }
};
var parameters = new MessageCreateParams
{
Betas = ["compact-2026-01-12"],
Model = "haijun-opus-5-5",
MaxTokens = 4096,
Messages = messages,
ContextManagement = new BetaContextManagementConfig
{
Edits = [new BetaCompact20260112Edit()]
}
};
var response = await client.Beta.Messages.Create(parameters);
// Tambahkan respons (termasuk blok compaction apa pun) untuk melanjutkan percakapan
messages.Add(new BetaMessageParam
{
Role = Role.Assistant,
Content = response.Content.Select(block => new BetaContentBlockParam(block.Json)).ToList()
});
Console.WriteLine(response); client := juglow.NewClient()
messages := []juglow.BetaMessageParam{
juglow.NewBetaUserMessage(juglow.NewBetaTextBlock("Help me build a website")),
}
response, err := client.Beta.Messages.New(context.TODO(), juglow.BetaMessageNewParams{
Model: juglow.ModelHaijunOpus5_5,
MaxTokens: 4096,
Messages: messages,
ContextManagement: juglow.BetaContextManagementConfigParam{
Edits: []juglow.BetaContextManagementConfigEditUnionParam{
{OfCompact20260112: &juglow.BetaCompact20260112EditParam{}},
},
},
Betas: []juglow.JuglowBeta{"compact-2026-01-12"},
})
if err != nil {
log.Fatal(err)
}
// Tambahkan respons (termasuk blok compaction apa pun) untuk melanjutkan percakapan
messages = append(messages, response.ToParam())
fmt.Println(response) import com.juglow.models.beta.messages.BetaContextManagementConfig;
import com.juglow.models.beta.messages.BetaCompact20260112Edit;
// ...
JuglowClient client = JuglowOkHttpClient.fromEnv();
MessageCreateParams params = MessageCreateParams.builder()
.addBeta("compact-2026-01-12")
.model("haijun-opus-5-5")
.maxTokens(4096L)
.addUserMessage("Help me build a website")
.contextManagement(BetaContextManagementConfig.builder()
.addEdit(BetaCompact20260112Edit.builder().build())
.build())
.build();
BetaMessage response = client.beta().messages().create(params);
// Tambahkan respons (termasuk blok compaction apa pun) untuk melanjutkan percakapan
// dengan menyertakannya dalam messages pada permintaan berikutnya
System.out.println(response); $client = new Client();
$messages = [
['role' => 'user', 'content' => 'Help me build a website']
];
$response = $client->beta->messages->create(
maxTokens: 4096,
messages: $messages,
model: 'haijun-opus-5-5',
betas: ['compact-2026-01-12'],
contextManagement: [
'edits' => [
['type' => 'compact_20260112']
]
]
);
// Tambahkan respons (termasuk blok compaction apa pun) untuk melanjutkan percakapan
$messages[] = ['role' => 'assistant', 'content' => $response->content];
echo json_encode($response, JSON_PRETTY_PRINT), PHP_EOL; client = Juglow::Client.new
messages = [
{ role: "user", content: "Help me build a website" }
]
response = client.beta.messages.create(
betas: ["compact-2026-01-12"],
model: "haijun-opus-5-5",
max_tokens: 4096,
messages: messages,
context_management: {
edits: [{ type: "compact_20260112" }]
}
)
# Tambahkan respons (termasuk blok compaction apa pun) untuk melanjutkan percakapan
messages << { role: "assistant", content: response.content }
puts responseParameter
| Parameter | Tipe | Default | Deskripsi |
|---|---|---|---|
type | string | Wajib | Harus berupa "compact_20260112" |
trigger | object | {"type": "input_tokens", "value": 150000} | Kapan compaction dipicu. input_tokens adalah satu-satunya tipe pemicu yang didukung. value harus minimal 50.000 token. |
pause_after_compaction | boolean | false | Apakah akan berhenti sejenak setelah menghasilkan ringkasan compaction |
instructions | string | null | Prompt peringkasan kustom. Sepenuhnya menggantikan prompt default jika diberikan. |
Konfigurasi pemicu
Konfigurasikan kapan compaction dipicu menggunakan parameter trigger:
curl https://haijun.my.id/v1/messages \
-H "x-api-key: $JUGLOW_API_KEY" \
-H "juglow-version: 2023-06-01" \
-H "juglow-beta: compact-2026-01-12" \
-H "content-type: application/json" \
-d '{
"model": "haijun-opus-5-5",
"max_tokens": 4096,
"messages": [
{
"role": "user",
"content": "Hello, Haijun"
}
],
"context_management": {
"edits": [
{
"type": "compact_20260112",
"trigger": {
"type": "input_tokens",
"value": 150000
}
}
]
}
}' ant beta:messages create --beta compact-2026-01-12 <<'YAML'
model: haijun-opus-5-5
max_tokens: 4096
messages:
- role: user
content: Hello, Haijun
context_management:
edits:
- type: compact_20260112
trigger:
type: input_tokens
value: 150000
YAML client = juglow.Juglow()
messages = [{"role": "user", "content": "Hello, Haijun"}]
response = client.beta.messages.create(
betas=["compact-2026-01-12"],
model="haijun-opus-5-5",
max_tokens=4096,
messages=messages,
context_management={
"edits": [
{
"type": "compact_20260112",
"trigger": {"type": "input_tokens", "value": 150000},
}
]
},
) const client = new Juglow();
const messages: Juglow.Beta.Messages.BetaMessageParam[] = [
{ role: "user", content: "Hello, Haijun" }
];
const response = await client.beta.messages.create({
betas: ["compact-2026-01-12"],
model: "haijun-opus-5-5",
max_tokens: 4096,
messages,
context_management: {
edits: [
{
type: "compact_20260112",
trigger: {
type: "input_tokens",
value: 150000
}
}
]
}
}); JuglowClient client = new();
List<BetaMessageParam> messages = [new() { Role = Role.User, Content = "Hello" }];
var parameters = new MessageCreateParams
{
Model = "haijun-opus-5-5",
MaxTokens = 4096,
Betas = ["compact-2026-01-12"],
Messages = messages,
ContextManagement = new BetaContextManagementConfig
{
Edits = [new BetaCompact20260112Edit
{
Trigger = new BetaInputTokensTrigger(150000)
}]
}
};
var message = await client.Beta.Messages.Create(parameters);
Console.WriteLine(message); client := juglow.NewClient()
messages := []juglow.BetaMessageParam{juglow.NewBetaUserMessage(juglow.NewBetaTextBlock("Hello, Haijun"))}
response, err := client.Beta.Messages.New(context.TODO(), juglow.BetaMessageNewParams{
Model: juglow.ModelHaijunOpus5_5,
MaxTokens: 4096,
Messages: messages,
ContextManagement: juglow.BetaContextManagementConfigParam{
Edits: []juglow.BetaContextManagementConfigEditUnionParam{
{OfCompact20260112: &juglow.BetaCompact20260112EditParam{
Trigger: juglow.BetaInputTokensTriggerParam{Value: 150000},
}},
},
},
Betas: []juglow.JuglowBeta{"compact-2026-01-12"},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(response) import com.juglow.models.beta.messages.BetaContextManagementConfig;
import com.juglow.models.beta.messages.BetaCompact20260112Edit;
import com.juglow.models.beta.messages.BetaInputTokensTrigger;
// ...
JuglowClient client = JuglowOkHttpClient.fromEnv();
MessageCreateParams params = MessageCreateParams.builder()
.model("haijun-opus-5-5")
.maxTokens(4096L)
.addBeta("compact-2026-01-12")
.addUserMessage("Hello, Haijun")
.contextManagement(BetaContextManagementConfig.builder()
.addEdit(BetaCompact20260112Edit.builder()
.trigger(BetaInputTokensTrigger.builder()
.value(150000L)
.build())
.build())
.build())
.build();
BetaMessage response = client.beta().messages().create(params);
System.out.println(response); $client = new Client();
$messages = [['role' => 'user', 'content' => 'Hello, Haijun']];
$message = $client->beta->messages->create(
maxTokens: 4096,
messages: $messages,
model: 'haijun-opus-5-5',
betas: ['compact-2026-01-12'],
contextManagement: [
'edits' => [
[
'type' => 'compact_20260112',
'trigger' => [
'type' => 'input_tokens',
'value' => 150000
]
]
]
]
);
echo $message; client = Juglow::Client.new
messages = [{ role: "user", content: "Hello, Haijun" }]
response = client.beta.messages.create(
betas: ["compact-2026-01-12"],
model: "haijun-opus-5-5",
max_tokens: 4096,
messages: messages,
context_management: {
edits: [
{
type: "compact_20260112",
trigger: {
type: "input_tokens",
value: 150000
}
}
]
}
)
puts responseInstruksi peringkasan kustom
Prompt peringkasan default bervariasi menurut model. Setiap prompt default menginstruksikan Haijun untuk menulis ringkasan di dalam tag yang berisi informasi yang diperlukan untuk melanjutkan tugas dalam jendela konteks berikutnya. Sebagai contoh, beberapa model menggunakan prompt berikut:
You have written a partial transcript for the initial task above. Please write a summary of the transcript. The purpose of this summary is to provide continuity so you can continue to make progress towards solving the task in a future context, where the raw history above may not be accessible and will be replaced with this summary. Write down anything that would be helpful, including the state, next steps, learnings etc. You must wrap your summary in a <summary></summary> block.Anda dapat memberikan instruksi kustom melalui parameter instructions. Instruksi kustom tidak melengkapi prompt default. Instruksi tersebut menggantikannya sepenuhnya:
curl https://haijun.my.id/v1/messages \
-H "x-api-key: $JUGLOW_API_KEY" \
-H "juglow-version: 2023-06-01" \
-H "juglow-beta: compact-2026-01-12" \
-H "content-type: application/json" \
-d '{
"model": "haijun-opus-5-5",
"max_tokens": 4096,
"messages": [
{
"role": "user",
"content": "Hello, Haijun"
}
],
"context_management": {
"edits": [
{
"type": "compact_20260112",
"instructions": "Focus on preserving code snippets, variable names, and technical decisions."
}
]
}
}' ant beta:messages create --beta compact-2026-01-12 <<'YAML'
model: haijun-opus-5-5
max_tokens: 4096
messages:
- role: user
content: Hello, Haijun
context_management:
edits:
- type: compact_20260112
instructions: >-
Focus on preserving code snippets, variable names, and
technical decisions.
YAML client = juglow.Juglow()
messages = [{"role": "user", "content": "Hello, Haijun"}]
response = client.beta.messages.create(
betas=["compact-2026-01-12"],
model="haijun-opus-5-5",
max_tokens=4096,
messages=messages,
context_management={
"edits": [
{
"type": "compact_20260112",
"instructions": "Focus on preserving code snippets, variable names, and technical decisions.",
}
]
},
) const client = new Juglow();
const messages: Juglow.Beta.Messages.BetaMessageParam[] = [
{ role: "user", content: "Hello, Haijun" }
];
const response = await client.beta.messages.create({
betas: ["compact-2026-01-12"],
model: "haijun-opus-5-5",
max_tokens: 4096,
messages,
context_management: {
edits: [
{
type: "compact_20260112",
instructions:
"Focus on preserving code snippets, variable names, and technical decisions."
}
]
}
}); JuglowClient client = new();
var parameters = new MessageCreateParams
{
Betas = ["compact-2026-01-12"],
Model = "haijun-opus-5-5",
MaxTokens = 4096,
Messages =
[
new BetaMessageParam { Role = Role.User, Content = "Help me build a Python web scraper" },
new BetaMessageParam { Role = Role.Assistant, Content = "I'll help you build a web scraper..." },
new BetaMessageParam { Role = Role.User, Content = "Add support for JavaScript-rendered pages" }
],
ContextManagement = new BetaContextManagementConfig
{
Edits = [new BetaCompact20260112Edit
{
Instructions = "Focus on preserving code snippets, variable names, and technical decisions."
}]
}
};
var message = await client.Beta.Messages.Create(parameters);
Console.WriteLine(message); client := juglow.NewClient()
response, err := client.Beta.Messages.New(context.TODO(), juglow.BetaMessageNewParams{
Model: juglow.ModelHaijunOpus5_5,
MaxTokens: 4096,
Messages: []juglow.BetaMessageParam{
juglow.NewBetaUserMessage(juglow.NewBetaTextBlock("Help me build a Python web scraper")),
{Role: juglow.BetaMessageParamRoleAssistant, Content: []juglow.BetaContentBlockParamUnion{juglow.NewBetaTextBlock("I'll help you build a web scraper...")}},
juglow.NewBetaUserMessage(juglow.NewBetaTextBlock("Add support for JavaScript-rendered pages")),
},
ContextManagement: juglow.BetaContextManagementConfigParam{
Edits: []juglow.BetaContextManagementConfigEditUnionParam{
{OfCompact20260112: &juglow.BetaCompact20260112EditParam{
Instructions: juglow.String("Focus on preserving code snippets, variable names, and technical decisions."),
}},
},
},
Betas: []juglow.JuglowBeta{"compact-2026-01-12"},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(response) import com.juglow.models.beta.messages.BetaContextManagementConfig;
import com.juglow.models.beta.messages.BetaCompact20260112Edit;
// ...
JuglowClient client = JuglowOkHttpClient.fromEnv();
MessageCreateParams params = MessageCreateParams.builder()
.addBeta("compact-2026-01-12")
.model("haijun-opus-5-5")
.maxTokens(4096L)
.addUserMessage("Help me build a Python web scraper")
.addAssistantMessage("I'll help you build a web scraper...")
.addUserMessage("Add support for JavaScript-rendered pages")
.contextManagement(BetaContextManagementConfig.builder()
.addEdit(BetaCompact20260112Edit.builder()
.instructions("Focus on preserving code snippets, variable names, and technical decisions.")
.build())
.build())
.build();
BetaMessage response = client.beta().messages().create(params);
System.out.println(response); $client = new Client();
$response = $client->beta->messages->create(
maxTokens: 4096,
messages: [
['role' => 'user', 'content' => 'Help me build a Python web scraper'],
['role' => 'assistant', 'content' => "I'll help you build a web scraper..."],
['role' => 'user', 'content' => 'Add support for JavaScript-rendered pages']
],
model: 'haijun-opus-5-5',
betas: ['compact-2026-01-12'],
contextManagement: [
'edits' => [
[
'type' => 'compact_20260112',
'instructions' => 'Focus on preserving code snippets, variable names, and technical decisions.'
]
]
]
);
echo json_encode($response, JSON_PRETTY_PRINT), PHP_EOL; client = Juglow::Client.new
response = client.beta.messages.create(
betas: ["compact-2026-01-12"],
model: "haijun-opus-5-5",
max_tokens: 4096,
messages: [
{ role: "user", content: "Help me build a Python web scraper" },
{ role: "assistant", content: "I'll help you build a web scraper..." },
{ role: "user", content: "Add support for JavaScript-rendered pages" }
],
context_management: {
edits: [
{
type: "compact_20260112",
instructions:
"Focus on preserving code snippets, variable names, and technical decisions."
}
]
}
)
puts responsePada model Haijun 5.1 dan yang lebih baru, permintaan dengan instructions kustom hanya meringkas dari percakapan yang terlihat: blok thinking sebelumnya tidak menjadi bagian dari input peringkas.
Berhenti sejenak setelah compaction
Gunakan pause_after_compaction untuk menghentikan sejenak API setelah menghasilkan ringkasan compaction. Ini memungkinkan Anda menambahkan blok konten tambahan (seperti mempertahankan pesan terbaru atau pesan berorientasi instruksi tertentu) sebelum API melanjutkan respons.
Ketika diaktifkan, API mengembalikan pesan dengan stop reason compaction setelah menghasilkan blok compaction:
# pause_after_compaction menghentikan respons tepat setelah ringkasan
# compaction sehingga Anda dapat menyesuaikan pesan sebelum melanjutkan. Langkah
# lanjutan tidak cocok untuk perintah shell sekali jalan; lihat tab SDK
# untuk alur jeda-dan-lanjut lengkap. Satu permintaan yang dijeda:
curl https://haijun.my.id/v1/messages \
-H "x-api-key: $JUGLOW_API_KEY" \
-H "juglow-version: 2023-06-01" \
-H "juglow-beta: compact-2026-01-12" \
-H "content-type: application/json" \
-d '{
"model": "haijun-opus-5-5",
"max_tokens": 4096,
"messages": [
{
"role": "user",
"content": "Hello, Haijun"
}
],
"context_management": {
"edits": [
{
"type": "compact_20260112",
"pause_after_compaction": true
}
]
}
}' # pause_after_compaction menghentikan respons tepat setelah ringkasan
# compaction sehingga Anda dapat menyesuaikan pesan sebelum melanjutkan. Langkah
# lanjutan tidak cocok untuk perintah CLI sekali jalan; lihat tab SDK
# untuk alur jeda-dan-lanjut lengkap. Satu permintaan yang dijeda:
ant beta:messages create --beta compact-2026-01-12 --format jsonl <<'YAML'
model: haijun-opus-5-5
max_tokens: 4096
messages:
- role: user
content: Hello, Haijun
context_management:
edits:
- type: compact_20260112
pause_after_compaction: true
YAML client = juglow.Juglow()
messages = [{"role": "user", "content": "Hello, Haijun"}]
response = client.beta.messages.create(
betas=["compact-2026-01-12"],
model="haijun-opus-5-5",
max_tokens=4096,
messages=messages,
context_management={
"edits": [{"type": "compact_20260112", "pause_after_compaction": True}]
},
)
# Periksa apakah compaction (pemadatan) memicu jeda
if response.stop_reason == "compaction":
# Respons hanya berisi blok compaction
messages.append({"role": "assistant", "content": response.content})
# Lanjutkan permintaan
response = client.beta.messages.create(
betas=["compact-2026-01-12"],
model="haijun-opus-5-5",
max_tokens=4096,
messages=messages,
context_management={"edits": [{"type": "compact_20260112"}]},
) const client = new Juglow();
const messages: Juglow.Beta.Messages.BetaMessageParam[] = [
{ role: "user", content: "Hello, Haijun" }
];
let response = await client.beta.messages.create({
betas: ["compact-2026-01-12"],
model: "haijun-opus-5-5",
max_tokens: 4096,
messages,
context_management: {
edits: [
{
type: "compact_20260112",
pause_after_compaction: true
}
]
}
});
// Periksa apakah compaction memicu jeda
if (response.stop_reason === "compaction") {
// Respons hanya berisi blok compaction
messages.push({
role: "assistant",
content: response.content
});
// Lanjutkan permintaan
response = await client.beta.messages.create({
betas: ["compact-2026-01-12"],
model: "haijun-opus-5-5",
max_tokens: 4096,
messages,
context_management: {
edits: [{ type: "compact_20260112" }]
}
});
} var client = new JuglowClient();
var messages = new List<BetaMessageParam>
{
new() { Role = Role.User, Content = "Hello, Haijun" }
};
var parameters = new MessageCreateParams
{
Model = "haijun-opus-5-5",
MaxTokens = 4096,
Betas = ["compact-2026-01-12"],
Messages = messages,
ContextManagement = new BetaContextManagementConfig
{
Edits = [new BetaCompact20260112Edit
{
PauseAfterCompaction = true
}]
}
};
var response = await client.Beta.Messages.Create(parameters);
if (response.StopReason == BetaStopReason.Compaction)
{
messages.Add(new BetaMessageParam
{
Role = Role.Assistant,
Content = response.Content.Select(block => new BetaContentBlockParam(block.Json)).ToList()
});
parameters = new()
{
Model = "haijun-opus-5-5",
MaxTokens = 4096,
Betas = ["compact-2026-01-12"],
Messages = messages,
ContextManagement = new BetaContextManagementConfig
{
Edits = [new BetaCompact20260112Edit()]
}
};
response = await client.Beta.Messages.Create(parameters);
}
Console.WriteLine(response); client := juglow.NewClient()
messages := []juglow.BetaMessageParam{juglow.NewBetaUserMessage(juglow.NewBetaTextBlock("Hello, Haijun"))}
compactEdit := juglow.BetaContextManagementConfigParam{
Edits: []juglow.BetaContextManagementConfigEditUnionParam{
{OfCompact20260112: &juglow.BetaCompact20260112EditParam{
PauseAfterCompaction: juglow.Bool(true),
}},
},
}
response, err := client.Beta.Messages.New(context.TODO(), juglow.BetaMessageNewParams{
Model: juglow.ModelHaijunOpus5_5,
MaxTokens: 4096,
Messages: messages,
ContextManagement: compactEdit,
Betas: []juglow.JuglowBeta{"compact-2026-01-12"},
})
if err != nil {
log.Fatal(err)
}
if response.StopReason == "compaction" {
messages = append(messages, response.ToParam())
response, err = client.Beta.Messages.New(context.TODO(), juglow.BetaMessageNewParams{
Model: juglow.ModelHaijunOpus5_5,
MaxTokens: 4096,
Messages: messages,
ContextManagement: juglow.BetaContextManagementConfigParam{
Edits: []juglow.BetaContextManagementConfigEditUnionParam{
{OfCompact20260112: &juglow.BetaCompact20260112EditParam{}},
},
},
Betas: []juglow.JuglowBeta{"compact-2026-01-12"},
})
if err != nil {
log.Fatal(err)
}
}
fmt.Println(response) import com.juglow.models.beta.messages.BetaContextManagementConfig;
import com.juglow.models.beta.messages.BetaCompact20260112Edit;
import com.juglow.models.beta.messages.BetaStopReason;
// ...
JuglowClient client = JuglowOkHttpClient.fromEnv();
MessageCreateParams params = MessageCreateParams.builder()
.model("haijun-opus-5-5")
.maxTokens(4096L)
.addBeta("compact-2026-01-12")
.addUserMessage("Help me build a website")
.contextManagement(BetaContextManagementConfig.builder()
.addEdit(BetaCompact20260112Edit.builder()
.pauseAfterCompaction(true)
.build())
.build())
.build();
BetaMessage response = client.beta().messages().create(params);
// Periksa apakah compaction (pemadatan) memicu jeda
if (response.stopReason().isPresent()
&& response.stopReason().get().equals(BetaStopReason.COMPACTION)) {
// Tambahkan blok compaction dan lanjutkan permintaan
// dengan membuat permintaan baru menggunakan konteks yang telah dipadatkan
MessageCreateParams continueParams = MessageCreateParams.builder()
.model("haijun-opus-5-5")
.maxTokens(4096L)
.addBeta("compact-2026-01-12")
.addUserMessage("Help me build a website")
.addMessage(response)
.contextManagement(BetaContextManagementConfig.builder()
.addEdit(BetaCompact20260112Edit.builder().build())
.build())
.build();
response = client.beta().messages().create(continueParams);
}
System.out.println(response); $client = new Client();
$messages = [['role' => 'user', 'content' => 'Hello, Haijun']];
$response = $client->beta->messages->create(
maxTokens: 4096,
messages: $messages,
model: 'haijun-opus-5-5',
betas: ['compact-2026-01-12'],
contextManagement: [
'edits' => [
[
'type' => 'compact_20260112',
'pause_after_compaction' => true
]
]
]
);
if ($response->stopReason === 'compaction') {
$messages[] = [
'role' => 'assistant',
'content' => $response->content
];
$response = $client->beta->messages->create(
maxTokens: 4096,
messages: $messages,
model: 'haijun-opus-5-5',
betas: ['compact-2026-01-12'],
contextManagement: [
'edits' => [
['type' => 'compact_20260112']
]
]
);
}
echo $response; client = Juglow::Client.new
messages = [{ role: "user", content: "Hello, Haijun" }]
response = client.beta.messages.create(
betas: ["compact-2026-01-12"],
model: "haijun-opus-5-5",
max_tokens: 4096,
messages: messages,
context_management: {
edits: [
{
type: "compact_20260112",
pause_after_compaction: true
}
]
}
)
if response.stop_reason == :compaction
messages << { role: "assistant", content: response.content }
response = client.beta.messages.create(
betas: ["compact-2026-01-12"],
model: "haijun-opus-5-5",
max_tokens: 4096,
messages: messages,
context_management: {
edits: [{ type: "compact_20260112" }]
}
)
end
puts responseMenerapkan anggaran token total
Ketika model mengerjakan tugas panjang dengan banyak iterasi penggunaan alat, total konsumsi token dapat bertambah secara signifikan. Anda dapat menggabungkan pause_after_compaction dengan penghitung compaction untuk memperkirakan penggunaan kumulatif dan menyelesaikan tugas dengan baik begitu anggaran tercapai.
Contoh ini hanya muncul dalam bahasa SDK: nilainya terletak pada logika pelacakan anggaran di sekitar permintaan. Permintaan mentahnya menggabungkan trigger dari Konfigurasi pemicu dengan pause_after_compaction dari Berhenti sejenak setelah compaction.
client = juglow.Juglow()
messages = [{"role": "user", "content": "Hello, Haijun"}]
TRIGGER_THRESHOLD = 100_000
TOTAL_TOKEN_BUDGET = 3_000_000
n_compactions = 0
response = client.beta.messages.create(
betas=["compact-2026-01-12"],
model="haijun-opus-5-5",
max_tokens=4096,
messages=messages,
context_management={
"edits": [
{
"type": "compact_20260112",
"trigger": {"type": "input_tokens", "value": TRIGGER_THRESHOLD},
"pause_after_compaction": True,
}
]
},
)
if response.stop_reason == "compaction":
n_compactions += 1
messages.append({"role": "assistant", "content": response.content})
# Perkirakan total token yang terpakai; minta model menyelesaikan jika melebihi anggaran
if n_compactions * TRIGGER_THRESHOLD >= TOTAL_TOKEN_BUDGET:
messages.append(
{
"role": "user",
"content": "Please wrap up your current work and summarize the final state.",
}
) const client = new Juglow();
const messages: Juglow.Beta.Messages.BetaMessageParam[] = [
{ role: "user", content: "Hello, Haijun" }
];
const TRIGGER_THRESHOLD = 100_000;
const TOTAL_TOKEN_BUDGET = 3_000_000;
let compactionCount = 0;
const response = await client.beta.messages.create({
betas: ["compact-2026-01-12"],
model: "haijun-opus-5-5",
max_tokens: 4096,
messages,
context_management: {
edits: [
{
type: "compact_20260112",
trigger: { type: "input_tokens", value: TRIGGER_THRESHOLD },
pause_after_compaction: true
}
]
}
});
if (response.stop_reason === "compaction") {
compactionCount += 1;
messages.push({ role: "assistant", content: response.content });
// Perkirakan total token yang terpakai; minta model menyelesaikan jika melebihi anggaran
if (compactionCount * TRIGGER_THRESHOLD >= TOTAL_TOKEN_BUDGET) {
messages.push({
role: "user",
content: "Please wrap up your current work and summarize the final state."
});
}
} JuglowClient client = new();
List<BetaMessageParam> messages = [new() { Role = Role.User, Content = "Hello, Haijun" }];
const int TriggerThreshold = 100_000;
const int TotalTokenBudget = 3_000_000;
int compactionCount = 0;
var response = await client.Beta.Messages.Create(new()
{
Betas = ["compact-2026-01-12"],
Model = "haijun-opus-5-5",
MaxTokens = 4096,
Messages = messages,
ContextManagement = new BetaContextManagementConfig
{
Edits = [new BetaCompact20260112Edit
{
Trigger = new BetaInputTokensTrigger(TriggerThreshold),
PauseAfterCompaction = true
}]
}
});
if (response.StopReason == BetaStopReason.Compaction)
{
compactionCount += 1;
messages.Add(new()
{
Role = Role.Assistant,
Content = response.Content.Select(b => new BetaContentBlockParam(b.Json)).ToList()
});
// Perkirakan total token yang terpakai; minta model menyelesaikan jika melebihi anggaran
if (compactionCount * TriggerThreshold >= TotalTokenBudget)
{
messages.Add(new()
{
Role = Role.User,
Content = "Please wrap up your current work and summarize the final state."
});
}
}
Console.WriteLine(response); client := juglow.NewClient()
messages := []juglow.BetaMessageParam{juglow.NewBetaUserMessage(juglow.NewBetaTextBlock("Hello, Haijun"))}
const triggerThreshold = 100_000
const totalTokenBudget = 3_000_000
compactionCount := 0
response, err := client.Beta.Messages.New(context.TODO(), juglow.BetaMessageNewParams{
Model: juglow.ModelHaijunOpus5_5,
MaxTokens: 4096,
Messages: messages,
ContextManagement: juglow.BetaContextManagementConfigParam{
Edits: []juglow.BetaContextManagementConfigEditUnionParam{
{OfCompact20260112: &juglow.BetaCompact20260112EditParam{
Trigger: juglow.BetaInputTokensTriggerParam{Value: triggerThreshold},
PauseAfterCompaction: juglow.Bool(true),
}},
},
},
Betas: []juglow.JuglowBeta{"compact-2026-01-12"},
})
if err != nil {
log.Fatal(err)
}
if response.StopReason == "compaction" {
compactionCount++
messages = append(messages, response.ToParam())
// Perkirakan total token yang terpakai; minta model menyelesaikan jika melebihi anggaran
if compactionCount*triggerThreshold >= totalTokenBudget {
messages = append(messages, juglow.NewBetaUserMessage(juglow.NewBetaTextBlock("Please wrap up your current work and summarize the final state.")))
}
}
fmt.Println(response) import com.juglow.models.beta.messages.BetaContextManagementConfig;
import com.juglow.models.beta.messages.BetaCompact20260112Edit;
import com.juglow.models.beta.messages.BetaInputTokensTrigger;
import com.juglow.models.beta.messages.BetaStopReason;
// ...
JuglowClient client = JuglowOkHttpClient.fromEnv();
long triggerThreshold = 100_000;
long totalTokenBudget = 3_000_000;
int compactionCount = 0;
List<BetaMessageParam> messages = new ArrayList<>();
messages.add(BetaMessageParam.builder()
.role(BetaMessageParam.Role.USER)
.content("Hello, Haijun")
.build());
MessageCreateParams params = MessageCreateParams.builder()
.addBeta("compact-2026-01-12")
.model("haijun-opus-5-5")
.maxTokens(4096L)
.messages(messages)
.contextManagement(BetaContextManagementConfig.builder()
.addEdit(BetaCompact20260112Edit.builder()
.trigger(BetaInputTokensTrigger.builder()
.value(triggerThreshold)
.build())
.pauseAfterCompaction(true)
.build())
.build())
.build();
BetaMessage response = client.beta().messages().create(params);
if (response.stopReason().isPresent()
&& response.stopReason().get().equals(BetaStopReason.COMPACTION)) {
compactionCount += 1;
messages.add(response.toParam());
// Perkirakan total token yang terpakai; minta model menyelesaikan jika melebihi anggaran
if (compactionCount * triggerThreshold >= totalTokenBudget) {
messages.add(BetaMessageParam.builder()
.role(BetaMessageParam.Role.USER)
.content("Please wrap up your current work and summarize the final state.")
.build());
}
}
System.out.println(response); $client = new Client();
$triggerThreshold = 100_000;
$totalTokenBudget = 3_000_000;
$compactionCount = 0;
$messages = [['role' => 'user', 'content' => 'Hello, Haijun']];
$response = $client->beta->messages->create(
maxTokens: 4096,
messages: $messages,
model: 'haijun-opus-5-5',
betas: ['compact-2026-01-12'],
contextManagement: [
'edits' => [
[
'type' => 'compact_20260112',
'trigger' => ['type' => 'input_tokens', 'value' => $triggerThreshold],
'pause_after_compaction' => true
]
]
]
);
if ($response->stopReason === 'compaction') {
$compactionCount += 1;
$messages[] = ['role' => 'assistant', 'content' => $response->content];
// Perkirakan total token yang terpakai; minta penyelesaian jika melebihi anggaran
if ($compactionCount * $triggerThreshold >= $totalTokenBudget) {
$messages[] = [
'role' => 'user',
'content' => 'Please wrap up your current work and summarize the final state.'
];
}
} client = Juglow::Client.new
messages = [{ role: "user", content: "Hello, Haijun" }]
TRIGGER_THRESHOLD = 100_000
TOTAL_TOKEN_BUDGET = 3_000_000
compaction_count = 0
response = client.beta.messages.create(
betas: ["compact-2026-01-12"],
model: "haijun-opus-5-5",
max_tokens: 4096,
messages: messages,
context_management: {
edits: [
{
type: "compact_20260112",
trigger: { type: "input_tokens", value: TRIGGER_THRESHOLD },
pause_after_compaction: true
}
]
}
)
if response.stop_reason == :compaction
compaction_count += 1
messages << { role: "assistant", content: response.content }
# Perkirakan total token yang terpakai; minta model menyelesaikan jika melebihi anggaran
if compaction_count * TRIGGER_THRESHOLD >= TOTAL_TOKEN_BUDGET
messages << {
role: "user",
content: "Please wrap up your current work and summarize the final state."
}
end
endBekerja dengan blok compaction
Ketika compaction dipicu, API mengembalikan blok compaction di awal respons asisten.
Percakapan yang berjalan lama dapat menghasilkan beberapa compaction. Blok compaction terakhir mencerminkan status akhir prompt, menggantikan konten sebelumnya dengan ringkasan yang dihasilkan.
{
"content": [
{
"type": "compaction",
"content": "Summary of the conversation: The user requested help building a web scraper..."
},
{
"type": "text",
"text": "Based on our conversation so far..."
}
]
}Mengirimkan kembali blok compaction
Anda harus mengirimkan kembali blok compaction ke API pada permintaan berikutnya untuk melanjutkan percakapan dengan prompt yang telah dipersingkat. Pendekatan paling sederhana adalah menambahkan seluruh konten respons ke pesan Anda:
# Konten respons, termasuk blok compaction, harus dikirim kembali ke
# API sebagai giliran asisten pada permintaan berikutnya. Mengelola daftar pesan itu
# tidak cocok untuk perintah shell sekali jalan; lihat tab CLI dan SDK
# untuk alur lengkapnya. Permintaan pertama:
curl https://haijun.my.id/v1/messages \
-H "x-api-key: $JUGLOW_API_KEY" \
-H "juglow-version: 2023-06-01" \
-H "juglow-beta: compact-2026-01-12" \
-H "content-type: application/json" \
-d '{
"model": "haijun-opus-5-5",
"max_tokens": 4096,
"messages": [
{
"role": "user",
"content": "Hello, Haijun"
}
],
"context_management": {
"edits": [
{
"type": "compact_20260112"
}
]
}
}' ant beta:messages create \
--beta compact-2026-01-12 \
--transform content \
--format jsonl <<'YAML' > content.json
model: haijun-opus-5-5
max_tokens: 4096
messages:
- role: user
content: Hello, Haijun
context_management:
edits:
- type: compact_20260112
YAML
# Setelah menerima respons dengan blok compaction, tambahkan sebagai
# giliran asisten dan lanjutkan percakapan
ant beta:messages create --beta compact-2026-01-12 <<YAML
model: haijun-opus-5-5
max_tokens: 4096
messages:
- role: user
content: Hello, Haijun
- role: assistant
content: $(cat content.json)
- role: user
content: Now add error handling
context_management:
edits:
- type: compact_20260112
YAML client = juglow.Juglow()
messages = [{"role": "user", "content": "Hello, Haijun"}]
response = client.beta.messages.create(
betas=["compact-2026-01-12"],
model="haijun-opus-5-5",
max_tokens=4096,
messages=messages,
context_management={"edits": [{"type": "compact_20260112"}]},
)
# Setelah menerima respons yang berisi blok compaction
messages.append({"role": "assistant", "content": response.content})
# Lanjutkan percakapan
messages.append({"role": "user", "content": "Now add error handling"})
response = client.beta.messages.create(
betas=["compact-2026-01-12"],
model="haijun-opus-5-5",
max_tokens=4096,
messages=messages,
context_management={"edits": [{"type": "compact_20260112"}]},
) const client = new Juglow();
const messages: Juglow.Beta.Messages.BetaMessageParam[] = [
{ role: "user", content: "Hello, Haijun" }
];
const response = await client.beta.messages.create({
betas: ["compact-2026-01-12"],
model: "haijun-opus-5-5",
max_tokens: 4096,
messages,
context_management: {
edits: [{ type: "compact_20260112" }]
}
});
// Setelah menerima respons yang berisi blok compaction
messages.push({
role: "assistant",
content: response.content
});
// Lanjutkan percakapan
messages.push({ role: "user", content: "Now add error handling" });
const nextResponse = await client.beta.messages.create({
betas: ["compact-2026-01-12"],
model: "haijun-opus-5-5",
max_tokens: 4096,
messages,
context_management: {
edits: [{ type: "compact_20260112" }]
}
}); JuglowClient client = new();
var messages = new List<BetaMessageParam>
{
new() { Role = Role.User, Content = "Help me build a web scraper" }
};
var response = await client.Beta.Messages.Create(new()
{
Betas = ["compact-2026-01-12"],
Model = "haijun-opus-5-5",
MaxTokens = 4096,
Messages = messages,
ContextManagement = new BetaContextManagementConfig
{
Edits = [new BetaCompact20260112Edit()]
}
});
messages.Add(new BetaMessageParam
{
Role = Role.Assistant,
Content = response.Content.Select(block => new BetaContentBlockParam(block.Json)).ToList()
});
messages.Add(new BetaMessageParam { Role = Role.User, Content = "Now add error handling" });
var nextResponse = await client.Beta.Messages.Create(new()
{
Betas = ["compact-2026-01-12"],
Model = "haijun-opus-5-5",
MaxTokens = 4096,
Messages = messages,
ContextManagement = new BetaContextManagementConfig
{
Edits = [new BetaCompact20260112Edit()]
}
});
Console.WriteLine(nextResponse); client := juglow.NewClient()
messages := []juglow.BetaMessageParam{
juglow.NewBetaUserMessage(juglow.NewBetaTextBlock("Help me build a web scraper")),
}
compactEdit := juglow.BetaContextManagementConfigParam{
Edits: []juglow.BetaContextManagementConfigEditUnionParam{
{OfCompact20260112: &juglow.BetaCompact20260112EditParam{}},
},
}
response, err := client.Beta.Messages.New(context.TODO(), juglow.BetaMessageNewParams{
Model: juglow.ModelHaijunOpus5_5,
MaxTokens: 4096,
Messages: messages,
ContextManagement: compactEdit,
Betas: []juglow.JuglowBeta{"compact-2026-01-12"},
})
if err != nil {
log.Fatal(err)
}
messages = append(messages, response.ToParam())
messages = append(messages, juglow.NewBetaUserMessage(juglow.NewBetaTextBlock("Now add error handling")))
nextResponse, err := client.Beta.Messages.New(context.TODO(), juglow.BetaMessageNewParams{
Model: juglow.ModelHaijunOpus5_5,
MaxTokens: 4096,
Messages: messages,
ContextManagement: compactEdit,
Betas: []juglow.JuglowBeta{"compact-2026-01-12"},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(nextResponse) import com.juglow.models.beta.messages.BetaContextManagementConfig;
import com.juglow.models.beta.messages.BetaCompact20260112Edit;
// ...
JuglowClient client = JuglowOkHttpClient.fromEnv();
// Permintaan pertama
BetaMessage response = client.beta().messages().create(
MessageCreateParams.builder()
.addBeta("compact-2026-01-12")
.model("haijun-opus-5-5")
.maxTokens(4096L)
.addUserMessage("Help me build a web scraper")
.contextManagement(BetaContextManagementConfig.builder()
.addEdit(BetaCompact20260112Edit.builder().build())
.build())
.build());
// Setelah menerima respons dengan blok compaction, tambahkan seluruh
// konten (termasuk blok compaction) dan lanjutkan percakapan
BetaMessage nextResponse = client.beta().messages().create(
MessageCreateParams.builder()
.addBeta("compact-2026-01-12")
.model("haijun-opus-5-5")
.maxTokens(4096L)
.addUserMessage("Help me build a web scraper")
.addMessage(response)
.addUserMessage("Now add error handling")
.contextManagement(BetaContextManagementConfig.builder()
.addEdit(BetaCompact20260112Edit.builder().build())
.build())
.build());
System.out.println(nextResponse); $client = new Client();
$messages = [
['role' => 'user', 'content' => 'Help me build a web scraper']
];
$response = $client->beta->messages->create(
maxTokens: 4096,
messages: $messages,
model: 'haijun-opus-5-5',
betas: ['compact-2026-01-12'],
contextManagement: [
'edits' => [['type' => 'compact_20260112']]
]
);
$messages[] = ['role' => 'assistant', 'content' => $response->content];
$messages[] = ['role' => 'user', 'content' => 'Now add error handling'];
$nextResponse = $client->beta->messages->create(
maxTokens: 4096,
messages: $messages,
model: 'haijun-opus-5-5',
betas: ['compact-2026-01-12'],
contextManagement: [
'edits' => [['type' => 'compact_20260112']]
]
);
echo json_encode($nextResponse, JSON_PRETTY_PRINT), PHP_EOL; client = Juglow::Client.new
messages = [
{ role: "user", content: "Help me build a web scraper" }
]
response = client.beta.messages.create(
betas: ["compact-2026-01-12"],
model: "haijun-opus-5-5",
max_tokens: 4096,
messages: messages,
context_management: {
edits: [{ type: "compact_20260112" }]
}
)
messages << { role: "assistant", content: response.content }
messages << { role: "user", content: "Now add error handling" }
next_response = client.beta.messages.create(
betas: ["compact-2026-01-12"],
model: "haijun-opus-5-5",
max_tokens: 4096,
messages: messages,
context_management: {
edits: [{ type: "compact_20260112" }]
}
)
puts next_response.contentDi Python, gunakan client.beta.messages, seperti yang dilakukan contoh-contoh di halaman ini. Jika Anda memanggil client.messages dan melakukan serialisasi blok sendiri, model_dump() biasa akan menambahkan text: null dan citations: null ke blok compaction. API kemudian menolak permintaan tersebut dengan error 400 (Extra inputs are not permitted). Sebagai gantinya, gunakan to_dict() atau model_dump(exclude_none=True). Melanjutkan dari ringkasan memberikan saran yang sama untuk compaction sesuai permintaan.
Ketika API menerima blok compaction, semua blok konten sebelumnya diabaikan. Anda dapat memilih untuk:
- Mempertahankan pesan asli dalam daftar Anda dan membiarkan API menangani penghapusan konten yang telah dipadatkan
- Membuang pesan yang telah dipadatkan secara manual dan hanya menyertakan blok compaction dan seterusnya
Pada Haijun Fable 5.1, Haijun Mythos 5.1, dan Haijun Opus 5.5, blok thinking dari sebelum blok compaction tidak dibawa ke depan, sehingga ringkasan adalah satu-satunya yang dimiliki model dari pekerjaan sebelumnya tersebut. Jika Anda menulis instructions sendiri, beri tahu model apa yang harus dipertahankan dalam ringkasan; lihat Beri tahu model apa yang harus dipertahankan dalam ringkasan compaction.
Streaming
Blok compaction di-stream secara berbeda dari blok teks. Anda menerima event content_block_start, diikuti oleh satu content_block_delta dengan konten ringkasan lengkap (tanpa streaming bertahap), lalu event content_block_stop.
curl https://haijun.my.id/v1/messages \
-H "x-api-key: $JUGLOW_API_KEY" \
-H "juglow-version: 2023-06-01" \
-H "juglow-beta: compact-2026-01-12" \
-H "content-type: application/json" \
-d '{
"model": "haijun-opus-5-5",
"max_tokens": 4096,
"stream": true,
"messages": [
{
"role": "user",
"content": "Hello, Haijun"
}
],
"context_management": {
"edits": [
{
"type": "compact_20260112"
}
]
}
}' ant beta:messages create \
--stream \
--beta compact-2026-01-12 \
--format jsonl <<'YAML'
model: haijun-opus-5-5
max_tokens: 4096
messages:
- role: user
content: Hello, Haijun
context_management:
edits:
- type: compact_20260112
YAML client = juglow.Juglow()
messages = [{"role": "user", "content": "Hello, Haijun"}]
with client.beta.messages.stream(
betas=["compact-2026-01-12"],
model="haijun-opus-5-5",
max_tokens=4096,
messages=messages,
context_management={"edits": [{"type": "compact_20260112"}]},
) as stream:
for event in stream:
match event.type:
case "content_block_start":
block = event.content_block
match block.type:
case "compaction":
print("Compaction started...")
case "text":
print("Text response started...")
case "content_block_delta":
delta = event.delta
match delta.type:
case "compaction_delta":
print(f"Compaction complete: {len(delta.content or '')} chars")
case "text_delta":
print(delta.text, end="", flush=True)
# Dapatkan pesan akhir yang telah terakumulasi
message = stream.get_final_message()
messages.append({"role": "assistant", "content": message.content}) const client = new Juglow();
const messages: Juglow.Beta.Messages.BetaMessageParam[] = [
{ role: "user", content: "Hello, Haijun" }
];
const stream = await client.beta.messages.stream({
betas: ["compact-2026-01-12"],
model: "haijun-opus-5-5",
max_tokens: 4096,
messages,
context_management: {
edits: [{ type: "compact_20260112" }]
}
});
for await (const event of stream) {
switch (event.type) {
case "content_block_start":
switch (event.content_block.type) {
case "compaction":
console.log("Compaction started...");
break;
case "text":
console.log("Text response started...");
break;
}
break;
case "content_block_delta":
switch (event.delta.type) {
case "compaction_delta":
console.log(`Compaction complete: ${event.delta.content?.length ?? 0} chars`);
break;
case "text_delta":
process.stdout.write(event.delta.text);
break;
}
break;
}
}
// Dapatkan pesan akhir yang telah terakumulasi
const message = await stream.finalMessage();
messages.push({
role: "assistant",
content: message.content
}); var client = new JuglowClient();
List<BetaMessageParam> messages = [new() { Role = Role.User, Content = "Hello" }];
var parameters = new MessageCreateParams
{
Betas = ["compact-2026-01-12"],
Model = "haijun-opus-5-5",
MaxTokens = 4096,
Messages = messages,
ContextManagement = new BetaContextManagementConfig
{
Edits = [new BetaCompact20260112Edit()]
}
};
await foreach (var streamEvent in client.Beta.Messages.CreateStreaming(parameters))
{
if (streamEvent.TryPickContentBlockStart(out var startEvent))
{
if (startEvent.ContentBlock.TryPickBetaCompaction(out _))
{
Console.WriteLine("Compaction started...");
}
else if (startEvent.ContentBlock.TryPickBetaText(out _))
{
Console.WriteLine("Text response started...");
}
}
else if (streamEvent.TryPickContentBlockDelta(out var deltaEvent))
{
if (deltaEvent.Delta.TryPickCompaction(out var compactionDelta))
{
Console.WriteLine($"Compaction complete: {compactionDelta.Content?.Length ?? 0} chars");
}
else if (deltaEvent.Delta.TryPickText(out var textDelta))
{
Console.Write(textDelta.Text);
}
}
} client := juglow.NewClient()
messages := []juglow.BetaMessageParam{juglow.NewBetaUserMessage(juglow.NewBetaTextBlock("Hello, Haijun"))}
stream := client.Beta.Messages.NewStreaming(context.TODO(), juglow.BetaMessageNewParams{
Model: juglow.ModelHaijunOpus5_5,
MaxTokens: 4096,
Messages: messages,
ContextManagement: juglow.BetaContextManagementConfigParam{
Edits: []juglow.BetaContextManagementConfigEditUnionParam{
{OfCompact20260112: &juglow.BetaCompact20260112EditParam{}},
},
},
Betas: []juglow.JuglowBeta{"compact-2026-01-12"},
})
for stream.Next() {
event := stream.Current()
switch eventVariant := event.AsAny().(type) {
case juglow.BetaRawContentBlockStartEvent:
switch eventVariant.ContentBlock.AsAny().(type) {
case juglow.BetaCompactionBlock:
fmt.Println("Compaction started...")
case juglow.BetaTextBlock:
fmt.Println("Text response started...")
}
case juglow.BetaRawContentBlockDeltaEvent:
switch deltaVariant := eventVariant.Delta.AsAny().(type) {
case juglow.BetaCompactionContentBlockDelta:
fmt.Printf("Compaction complete: %d chars\n", len(deltaVariant.Content))
case juglow.BetaTextDelta:
fmt.Print(deltaVariant.Text)
}
}
}
if err := stream.Err(); err != nil {
log.Fatal(err)
} import com.juglow.models.beta.messages.BetaContextManagementConfig;
import com.juglow.models.beta.messages.BetaCompact20260112Edit;
// ...
JuglowClient client = JuglowOkHttpClient.fromEnv();
MessageCreateParams params = MessageCreateParams.builder()
.model("haijun-opus-5-5")
.maxTokens(4096L)
.addBeta("compact-2026-01-12")
.addUserMessage("Hello, Haijun")
.contextManagement(BetaContextManagementConfig.builder()
.addEdit(BetaCompact20260112Edit.builder().build())
.build())
.build();
try (var streamResponse = client.beta().messages().createStreaming(params)) {
streamResponse.stream().forEach(event -> {
event.contentBlockStart().ifPresent(startEvent -> {
startEvent.contentBlock().compaction().ifPresent(c ->
System.out.println("Compaction started...")
);
startEvent.contentBlock().text().ifPresent(t ->
System.out.println("Text response started...")
);
});
event.contentBlockDelta().ifPresent(deltaEvent -> {
deltaEvent.delta().compaction().ifPresent(cd ->
System.out.println("Compaction complete: " + cd.content().map(String::length).orElse(0) + " chars")
);
deltaEvent.delta().text().ifPresent(td ->
System.out.print(td.text())
);
});
});
} use Juglow\Beta\Messages\BetaCompactionBlock;
use Juglow\Beta\Messages\BetaCompactionContentBlockDelta;
use Juglow\Beta\Messages\BetaRawContentBlockDeltaEvent;
use Juglow\Beta\Messages\BetaRawContentBlockStartEvent;
use Juglow\Beta\Messages\BetaTextBlock;
use Juglow\Beta\Messages\BetaTextDelta;
$client = new Client();
$messages = [['role' => 'user', 'content' => 'Hello, Haijun']];
$stream = $client->beta->messages->createStream(
maxTokens: 4096,
messages: $messages,
model: 'haijun-opus-5-5',
betas: ['compact-2026-01-12'],
contextManagement: [
'edits' => [
['type' => 'compact_20260112']
]
]
);
foreach ($stream as $event) {
switch (true) {
case $event instanceof BetaRawContentBlockStartEvent:
switch (true) {
case $event->contentBlock instanceof BetaCompactionBlock:
echo "Compaction started...\n";
break;
case $event->contentBlock instanceof BetaTextBlock:
echo "Text response started...\n";
break;
}
break;
case $event instanceof BetaRawContentBlockDeltaEvent:
switch (true) {
case $event->delta instanceof BetaCompactionContentBlockDelta:
echo "Compaction complete: " . strlen($event->delta->content ?? '') . " chars\n";
break;
case $event->delta instanceof BetaTextDelta:
echo $event->delta->text;
break;
}
break;
}
} client = Juglow::Client.new
messages = [{ role: "user", content: "Hello, Haijun" }]
stream = client.beta.messages.stream(
betas: ["compact-2026-01-12"],
model: "haijun-opus-5-5",
max_tokens: 4096,
messages: messages,
context_management: {
edits: [{ type: "compact_20260112" }]
}
)
stream.each do |event|
case event
when Juglow::Models::BetaRawContentBlockStartEvent
case event.content_block
when Juglow::Models::BetaCompactionBlock
puts "Compaction started..."
when Juglow::Models::BetaTextBlock
puts "Text response started..."
end
when Juglow::Models::BetaRawContentBlockDeltaEvent
delta = event.delta
case delta
when Juglow::Models::BetaCompactionContentBlockDelta
puts "Compaction complete: #{(delta.content || "").length} chars"
when Juglow::Models::BetaTextDelta
print delta.text
end
end
endCaching prompt
Compaction bekerja dengan baik bersama "prompt caching" (caching prompt). Anda dapat menambahkan breakpoint cache_control pada blok compaction untuk melakukan cache terhadap konten yang telah diringkas.
{
"role": "assistant",
"content": [
{
"type": "compaction",
"content": "[summary text]",
"cache_control": { "type": "ephemeral" }
},
{
"type": "text",
"text": "Based on our conversation..."
}
]
}Memaksimalkan cache hit dengan prompt sistem
Ketika compaction terjadi, ringkasan menjadi konten baru yang perlu ditulis ke cache. Tanpa breakpoint cache tambahan, hal ini juga akan membatalkan "system prompt" (prompt sistem) yang telah di-cache, sehingga prompt tersebut harus di-cache ulang bersama ringkasan compaction.
Untuk memaksimalkan tingkat cache hit, tambahkan breakpoint cache_control di akhir prompt sistem Anda. Ini menjaga prompt sistem tetap di-cache secara terpisah dari percakapan, sehingga ketika compaction terjadi:
- Cache prompt sistem tetap valid dan dibaca dari cache
- Hanya ringkasan compaction yang perlu ditulis sebagai entri cache baru
curl https://haijun.my.id/v1/messages \
-H "x-api-key: $JUGLOW_API_KEY" \
-H "juglow-version: 2023-06-01" \
-H "juglow-beta: compact-2026-01-12" \
-H "content-type: application/json" \
-d '{
"model": "haijun-opus-5-5",
"max_tokens": 4096,
"system": [
{
"type": "text",
"text": "You are a helpful coding assistant...",
"cache_control": {
"type": "ephemeral"
}
}
],
"messages": [
{
"role": "user",
"content": "Hello, Haijun"
}
],
"context_management": {
"edits": [
{
"type": "compact_20260112"
}
]
}
}' ant beta:messages create --beta compact-2026-01-12 <<'YAML'
model: haijun-opus-5-5
max_tokens: 4096
system:
- type: text
text: You are a helpful coding assistant...
cache_control:
type: ephemeral
messages:
- role: user
content: Hello, Haijun
context_management:
edits:
- type: compact_20260112
YAML client = juglow.Juglow()
messages = [{"role": "user", "content": "Hello, Haijun"}]
response = client.beta.messages.create(
betas=["compact-2026-01-12"],
model="haijun-opus-5-5",
max_tokens=4096,
system=[
{
"type": "text",
"text": "You are a helpful coding assistant...",
"cache_control": {
"type": "ephemeral"
}, # Cache the system prompt separately
}
],
messages=messages,
context_management={"edits": [{"type": "compact_20260112"}]},
) const client = new Juglow();
const messages: Juglow.Beta.Messages.BetaMessageParam[] = [
{ role: "user", content: "Hello, Haijun" }
];
const response = await client.beta.messages.create({
betas: ["compact-2026-01-12"],
model: "haijun-opus-5-5",
max_tokens: 4096,
system: [
{
type: "text",
text: "You are a helpful coding assistant...",
cache_control: { type: "ephemeral" } // Cache the system prompt separately
}
],
messages,
context_management: {
edits: [{ type: "compact_20260112" }]
}
}); var client = new JuglowClient();
var parameters = new MessageCreateParams
{
Betas = ["compact-2026-01-12"],
Model = "haijun-opus-5-5",
MaxTokens = 4096,
System = new List<BetaTextBlockParam>
{
new()
{
Text = "You are a helpful coding assistant...",
CacheControl = new BetaCacheControlEphemeral()
}
},
Messages = [new() { Role = Role.User, Content = "Hello, Haijun" }],
ContextManagement = new BetaContextManagementConfig
{
Edits = [new BetaCompact20260112Edit()]
}
};
var response = await client.Beta.Messages.Create(parameters);
Console.WriteLine(response); client := juglow.NewClient()
response, err := client.Beta.Messages.New(context.TODO(), juglow.BetaMessageNewParams{
Model: juglow.ModelHaijunOpus5_5,
MaxTokens: 4096,
System: []juglow.BetaTextBlockParam{
{
Text: "You are a helpful coding assistant...",
CacheControl: juglow.NewBetaCacheControlEphemeralParam(),
},
},
Messages: []juglow.BetaMessageParam{juglow.NewBetaUserMessage(juglow.NewBetaTextBlock("Hello, Haijun"))},
ContextManagement: juglow.BetaContextManagementConfigParam{
Edits: []juglow.BetaContextManagementConfigEditUnionParam{
{OfCompact20260112: &juglow.BetaCompact20260112EditParam{}},
},
},
Betas: []juglow.JuglowBeta{"compact-2026-01-12"},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(response) import com.juglow.models.beta.messages.BetaContextManagementConfig;
import com.juglow.models.beta.messages.BetaCompact20260112Edit;
import com.juglow.models.beta.messages.BetaCacheControlEphemeral;
// ...
JuglowClient client = JuglowOkHttpClient.fromEnv();
MessageCreateParams params = MessageCreateParams.builder()
.model("haijun-opus-5-5")
.maxTokens(4096L)
.addBeta("compact-2026-01-12")
.systemOfBetaTextBlockParams(List.of(
BetaTextBlockParam.builder()
.text("You are a helpful coding assistant...")
.cacheControl(BetaCacheControlEphemeral.builder().build())
.build()
))
.addUserMessage("Hello, Haijun")
.contextManagement(BetaContextManagementConfig.builder()
.addEdit(BetaCompact20260112Edit.builder().build())
.build())
.build();
BetaMessage response = client.beta().messages().create(params);
System.out.println(response); $client = new Client();
$response = $client->beta->messages->create(
maxTokens: 4096,
messages: [['role' => 'user', 'content' => 'Hello, Haijun']],
model: 'haijun-opus-5-5',
betas: ['compact-2026-01-12'],
system: [
[
'type' => 'text',
'text' => 'You are a helpful coding assistant...',
'cache_control' => [
'type' => 'ephemeral'
]
]
],
contextManagement: [
'edits' => [
['type' => 'compact_20260112']
]
]
);
echo json_encode($response, JSON_PRETTY_PRINT), PHP_EOL; client = Juglow::Client.new
response = client.beta.messages.create(
betas: ["compact-2026-01-12"],
model: "haijun-opus-5-5",
max_tokens: 4096,
system: [
{
type: "text",
text: "You are a helpful coding assistant...",
cache_control: {
type: "ephemeral"
}
}
],
messages: [{ role: "user", content: "Hello, Haijun" }],
context_management: {
edits: [{ type: "compact_20260112" }]
}
)
puts responseIni menjaga prompt sistem yang panjang tetap di-cache di sepanjang beberapa event compaction selama percakapan.
Memahami penggunaan
Compaction memerlukan langkah sampling tambahan, yang turut diperhitungkan dalam "rate limit" (batas laju) dan penagihan. API mengembalikan informasi penggunaan yang terperinci dalam respons:
{
"usage": {
"input_tokens": 23000,
"output_tokens": 1000,
"iterations": [
{
"type": "compaction",
"input_tokens": 180000,
"output_tokens": 3500
},
{
"type": "message",
"input_tokens": 23000,
"output_tokens": 1000
}
]
}
}Array iterations menunjukkan penggunaan untuk setiap iterasi sampling. Ketika compaction terjadi, Anda akan melihat iterasi compaction diikuti oleh iterasi message utama. input_tokens dan output_tokens tingkat atas sama persis dengan iterasi message dalam contoh ini karena hanya ada satu iterasi non-compaction. Jumlah token pada iterasi terakhir mencerminkan ukuran konteks efektif setelah compaction.
Note:
input_tokensdanoutput_tokenstingkat atas tidak mencakup penggunaan iterasi compaction. Keduanya mencerminkan jumlah dari semua iterasi non-compaction. Untuk menghitung total token yang dikonsumsi dan ditagih untuk suatu permintaan, jumlahkan seluruh entri dalam arrayusage.iterations. Jika sebelumnya Anda mengandalkanusage.input_tokensdanusage.output_tokensuntuk pelacakan biaya atau audit, Anda perlu memperbarui logika pelacakan Anda untuk mengagregasi seluruhusage.iterationsketika compaction diaktifkan. Dengan beta compaction diaktifkan, setiap respons menyertakanusage.iterations, bahkan jika tidak ada compaction yang terjadi. Entricompactionhanya muncul ketika compaction baru dipicu selama permintaan. Menerapkan ulang blokcompactionsebelumnya tidak menimbulkan biaya compaction tambahan, dan kolom penggunaan tingkat atas tetap akurat dalam kasus tersebut.
Menggabungkan dengan fitur lain
Alat server
Saat menggunakan server tools (seperti pencarian web), pemicu compaction diperiksa di awal setiap iterasi sampling. Compaction dapat terjadi beberapa kali dalam satu permintaan, tergantung pada ambang batas pemicu Anda dan jumlah output yang dihasilkan.
Penghitungan token
Endpoint penghitungan token (/v1/messages/count_tokens) menerapkan blok compaction yang sudah ada dalam prompt Anda tetapi tidak memicu compaction baru. Gunakan endpoint ini untuk memeriksa jumlah token efektif Anda setelah compaction sebelumnya:
curl https://haijun.my.id/v1/messages/count_tokens \
-H "x-api-key: $JUGLOW_API_KEY" \
-H "juglow-version: 2023-06-01" \
-H "juglow-beta: compact-2026-01-12" \
-H "content-type: application/json" \
-d '{
"model": "haijun-opus-5-5",
"messages": [
{
"role": "user",
"content": "Hello, Haijun"
}
],
"context_management": {
"edits": [
{
"type": "compact_20260112"
}
]
}
}' CURRENT=$(ant beta:messages count-tokens \
--beta compact-2026-01-12 \
--transform input_tokens \
--raw-output <<'YAML'
model: haijun-opus-5-5
messages:
- role: user
content: Hello, Haijun
context_management:
edits:
- type: compact_20260112
YAML
)
ORIGINAL=$(ant beta:messages count-tokens \
--beta compact-2026-01-12 \
--transform context_management.original_input_tokens \
--raw-output <<'YAML'
model: haijun-opus-5-5
messages:
- role: user
content: Hello, Haijun
context_management:
edits:
- type: compact_20260112
YAML
)
printf 'Current tokens: %s\n' "$CURRENT"
printf 'Original tokens: %s\n' "$ORIGINAL" client = juglow.Juglow()
messages = [{"role": "user", "content": "Hello, Haijun"}]
count_response = client.beta.messages.count_tokens(
betas=["compact-2026-01-12"],
model="haijun-opus-5-5",
messages=messages,
context_management={"edits": [{"type": "compact_20260112"}]},
)
print(f"Current tokens: {count_response.input_tokens}")
print(f"Original tokens: {count_response.context_management.original_input_tokens}") const client = new Juglow();
const messages: Juglow.Beta.Messages.BetaMessageParam[] = [
{ role: "user", content: "Summarize the key points of our conversation so far." }
];
const countResponse = await client.beta.messages.countTokens({
betas: ["compact-2026-01-12"],
model: "haijun-opus-5-5",
messages,
context_management: {
edits: [{ type: "compact_20260112" }]
}
});
console.log(`Current tokens: ${countResponse.input_tokens}`);
console.log(`Original tokens: ${countResponse.context_management!.original_input_tokens}`); JuglowClient client = new();
List<BetaMessageParam> messages = [new() { Role = Role.User, Content = "Hello" }];
var countParams = new MessageCountTokensParams
{
Model = "haijun-opus-5-5",
Messages = messages,
ContextManagement = new BetaContextManagementConfig
{
Edits = [new BetaCompact20260112Edit()]
},
Betas = ["compact-2026-01-12"]
};
var countResponse = await client.Beta.Messages.CountTokens(countParams);
Console.WriteLine($"Current tokens: {countResponse.InputTokens}");
Console.WriteLine($"Original tokens: {countResponse.ContextManagement?.OriginalInputTokens}"); client := juglow.NewClient()
messages := []juglow.BetaMessageParam{juglow.NewBetaUserMessage(juglow.NewBetaTextBlock("Hello, Haijun"))}
countResponse, err := client.Beta.Messages.CountTokens(context.TODO(), juglow.BetaMessageCountTokensParams{
Model: juglow.ModelHaijunOpus5_5,
Messages: messages,
ContextManagement: juglow.BetaContextManagementConfigParam{
Edits: []juglow.BetaContextManagementConfigEditUnionParam{
{OfCompact20260112: &juglow.BetaCompact20260112EditParam{}},
},
},
Betas: []juglow.JuglowBeta{"compact-2026-01-12"},
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("Current tokens: %d\n", countResponse.InputTokens)
fmt.Printf("Original tokens: %d\n", countResponse.ContextManagement.OriginalInputTokens) import com.juglow.models.beta.messages.BetaMessageTokensCount;
import com.juglow.models.beta.messages.MessageCountTokensParams;
import com.juglow.models.beta.messages.BetaContextManagementConfig;
import com.juglow.models.beta.messages.BetaCompact20260112Edit;
// ...
JuglowClient client = JuglowOkHttpClient.fromEnv();
MessageCountTokensParams params = MessageCountTokensParams.builder()
.model("haijun-opus-5-5")
.addUserMessage("Hello, Haijun")
.contextManagement(BetaContextManagementConfig.builder()
.addEdit(BetaCompact20260112Edit.builder().build())
.build())
.addBeta("compact-2026-01-12")
.build();
BetaMessageTokensCount countResponse = client.beta().messages().countTokens(params);
System.out.println("Current tokens: " + countResponse.inputTokens());
System.out.println("Original tokens: " + countResponse.contextManagement().get().originalInputTokens()); $client = new Client();
$messages = [['role' => 'user', 'content' => 'Hello, Haijun']];
$countResponse = $client->beta->messages->countTokens(
messages: $messages,
model: 'haijun-opus-5-5',
betas: ['compact-2026-01-12'],
contextManagement: [
'edits' => [
['type' => 'compact_20260112']
]
]
);
echo "Current tokens: " . $countResponse->inputTokens . "\n";
echo "Original tokens: " . $countResponse->contextManagement->originalInputTokens . "\n"; client = Juglow::Client.new
messages = [{ role: "user", content: "Hello, Haijun" }]
count_response = client.beta.messages.count_tokens(
betas: ["compact-2026-01-12"],
model: "haijun-opus-5-5",
messages: messages,
context_management: {
edits: [{ type: "compact_20260112" }]
}
)
puts "Current tokens: #{count_response.input_tokens}"
puts "Original tokens: #{count_response.context_management.original_input_tokens}"Contoh
Berikut adalah contoh lengkap percakapan yang berjalan lama dengan compaction:
# curl mengirim permintaan satu per satu; kelola array messages di
# skrip pemanggil. Lihat tab SDK untuk loop chat() lengkap. Bentuk permintaan
# satu giliran:
curl https://haijun.my.id/v1/messages \
-H "x-api-key: $JUGLOW_API_KEY" \
-H "juglow-version: 2023-06-01" \
-H "juglow-beta: compact-2026-01-12" \
-H "content-type: application/json" \
-d '{
"model": "haijun-opus-5-5",
"max_tokens": 4096,
"messages": [
{
"role": "user",
"content": "Help me build a Python web scraper"
}
],
"context_management": {
"edits": [
{
"type": "compact_20260112",
"trigger": {
"type": "input_tokens",
"value": 100000
}
}
]
}
}' # CLI menangani giliran individual; kelola array messages di
# skrip pemanggil. Lihat tab SDK untuk loop chat() lengkap. Bentuk
# permintaan satu giliran:
ant beta:messages create \
--beta compact-2026-01-12 \
--transform 'content.#(type=="text").text' \
--raw-output <<'YAML'
model: haijun-opus-5-5
max_tokens: 4096
messages:
- role: user
content: Help me build a Python web scraper
context_management:
edits:
- type: compact_20260112
trigger:
type: input_tokens
value: 100000
YAML client = juglow.Juglow()
messages: list[dict] = []
def chat(user_message: str) -> str:
messages.append({"role": "user", "content": user_message})
response = client.beta.messages.create(
betas=["compact-2026-01-12"],
model="haijun-opus-5-5",
max_tokens=4096,
messages=messages,
context_management={
"edits": [
{
"type": "compact_20260112",
"trigger": {"type": "input_tokens", "value": 100000},
}
]
},
)
# Tambahkan respons (blok compaction otomatis disertakan)
messages.append({"role": "assistant", "content": response.content})
# Kembalikan konten teks
return next(block.text for block in response.content if block.type == "text")
# Jalankan percakapan panjang
print(chat("Help me build a Python web scraper"))
print(chat("Add support for JavaScript-rendered pages"))
print(chat("Now add rate limiting and error handling"))
# Terus panggil chat() selama percakapan masih membutuhkannya const client = new Juglow();
const messages: Juglow.Beta.Messages.BetaMessageParam[] = [];
async function chat(userMessage: string): Promise<string> {
messages.push({ role: "user", content: userMessage });
const response = await client.beta.messages.create({
betas: ["compact-2026-01-12"],
model: "haijun-opus-5-5",
max_tokens: 4096,
messages,
context_management: {
edits: [
{
type: "compact_20260112",
trigger: { type: "input_tokens", value: 100000 }
}
]
}
});
// Tambahkan respons (blok compaction otomatis disertakan)
messages.push({ role: "assistant", content: response.content });
// Kembalikan konten teks
const textBlock = response.content.find((block) => block.type === "text");
return textBlock?.text ?? "";
}
// Jalankan percakapan panjang
console.log(await chat("Help me build a Python web scraper"));
console.log(await chat("Add support for JavaScript-rendered pages"));
console.log(await chat("Now add rate limiting and error handling"));
// Terus panggil chat() selama percakapan masih membutuhkannya JuglowClient client = new();
List<BetaMessageParam> messages = new();
Console.WriteLine(await Chat(client, messages, "Help me build a Python web scraper"));
Console.WriteLine(await Chat(client, messages, "Add support for JavaScript-rendered pages"));
Console.WriteLine(await Chat(client, messages, "Now add rate limiting and error handling"));
static async Task<string> Chat(JuglowClient client, List<BetaMessageParam> messages, string userMessage)
{
messages.Add(new() { Role = Role.User, Content = userMessage });
var parameters = new MessageCreateParams
{
Betas = ["compact-2026-01-12"],
Model = "haijun-opus-5-5",
MaxTokens = 4096,
Messages = messages,
ContextManagement = new BetaContextManagementConfig
{
Edits = [new BetaCompact20260112Edit
{
Trigger = new BetaInputTokensTrigger(100000)
}]
}
};
var response = await client.Beta.Messages.Create(parameters);
messages.Add(new()
{
Role = Role.Assistant,
Content = response.Content.Select(block => new BetaContentBlockParam(block.Json)).ToList()
});
return response.Content
.Select(block => block.Value)
.OfType<BetaTextBlock>()
.Select(tb => tb.Text)
.FirstOrDefault() ?? "";
} package main
import (
"context"
"fmt"
"log"
"github.com/juglows/juglow-sdk-go"
)
var (
client = juglow.NewClient()
messages []juglow.BetaMessageParam
)
func chat(userMessage string) string {
messages = append(messages, juglow.NewBetaUserMessage(juglow.NewBetaTextBlock(userMessage)))
response, err := client.Beta.Messages.New(context.TODO(), juglow.BetaMessageNewParams{
Model: juglow.ModelHaijunOpus5_5,
MaxTokens: 4096,
Messages: messages,
ContextManagement: juglow.BetaContextManagementConfigParam{
Edits: []juglow.BetaContextManagementConfigEditUnionParam{
{OfCompact20260112: &juglow.BetaCompact20260112EditParam{
Trigger: juglow.BetaInputTokensTriggerParam{Value: 100000},
}},
},
},
Betas: []juglow.JuglowBeta{"compact-2026-01-12"},
})
if err != nil {
log.Fatal(err)
}
messages = append(messages, response.ToParam())
for _, block := range response.Content {
if variant, ok := block.AsAny().(juglow.BetaTextBlock); ok {
return variant.Text
}
}
return ""
}
func main() {
fmt.Println(chat("Help me build a Python web scraper"))
fmt.Println(chat("Add support for JavaScript-rendered pages"))
fmt.Println(chat("Now add rate limiting and error handling"))
} import com.juglow.models.beta.messages.BetaContextManagementConfig;
import com.juglow.models.beta.messages.BetaCompact20260112Edit;
import com.juglow.models.beta.messages.BetaInputTokensTrigger;
// ...
private static final JuglowClient client = JuglowOkHttpClient.fromEnv();
private static final List<BetaMessageParam> messages = new ArrayList<>();
public static void main(String[] args) {
System.out.println(chat("Help me build a Python web scraper"));
System.out.println(chat("Add support for JavaScript-rendered pages"));
System.out.println(chat("Now add rate limiting and error handling"));
}
private static String chat(String userMessage) {
messages.add(BetaMessageParam.builder()
.role(BetaMessageParam.Role.USER)
.content(userMessage)
.build());
MessageCreateParams params = MessageCreateParams.builder()
.addBeta("compact-2026-01-12")
.model("haijun-opus-5-5")
.maxTokens(4096L)
.messages(messages)
.contextManagement(BetaContextManagementConfig.builder()
.addEdit(BetaCompact20260112Edit.builder()
.trigger(BetaInputTokensTrigger.builder()
.value(100000L)
.build())
.build())
.build())
.build();
BetaMessage response = client.beta().messages().create(params);
// Tambahkan respons (blok compaction otomatis disertakan)
messages.add(response.toParam());
return response.content().stream()
.filter(block -> block.text().isPresent())
.map(block -> block.text().get().text())
.findFirst()
.orElse("");
} $client = new Client();
$messages = [];
function chat($client, &$messages, $userMessage) {
$messages[] = ['role' => 'user', 'content' => $userMessage];
$response = $client->beta->messages->create(
maxTokens: 4096,
messages: $messages,
model: 'haijun-opus-5-5',
betas: ['compact-2026-01-12'],
contextManagement: [
'edits' => [
[
'type' => 'compact_20260112',
'trigger' => ['type' => 'input_tokens', 'value' => 100000]
]
]
]
);
$messages[] = ['role' => 'assistant', 'content' => $response->content];
foreach ($response->content as $block) {
if ($block->type === 'text') {
return $block->text;
}
}
return '';
}
echo chat($client, $messages, "Help me build a Python web scraper") . "\n";
echo chat($client, $messages, "Add support for JavaScript-rendered pages") . "\n";
echo chat($client, $messages, "Now add rate limiting and error handling") . "\n"; client = Juglow::Client.new
messages = []
def chat(client, messages, user_message)
messages << { role: "user", content: user_message }
response = client.beta.messages.create(
betas: ["compact-2026-01-12"],
model: "haijun-opus-5-5",
max_tokens: 4096,
messages: messages,
context_management: {
edits: [
{
type: "compact_20260112",
trigger: { type: "input_tokens", value: 100000 }
}
]
}
)
messages << { role: "assistant", content: response.content }
response.content.find { |block| block.type == :text }&.text || ""
end
puts chat(client, messages, "Help me build a Python web scraper")
puts chat(client, messages, "Add support for JavaScript-rendered pages")
puts chat(client, messages, "Now add rate limiting and error handling")Pada Haijun Fable 5.1 dan Haijun Opus 5.5, hapus blok thinking dan redacted_thinking dari setiap giliran asisten yang Anda sisipkan kembali setelah blok compaction, atau kirim thinking.block_binding.prefix_mismatch_behavior: "drop_block" dengan header beta thinking-binding-controls-2026-08-01. Blok-blok tersebut dihasilkan ketika riwayat lengkap masih ada, sehingga tidak lagi lolos pemeriksaan percakapan. Di tempat pemeriksaan tersebut diberlakukan, permintaan lanjutan akan ditolak dengan error 400. Blok teks dan blok alat yang dipertahankan dapat dibiarkan apa adanya. Membiarkan API meringkas semuanya, tanpa menyisipkan kembali giliran sebelumnya, akan menghindari masalah ini.
Berikut adalah contoh yang menggunakan pause_after_compaction untuk mempertahankan pertukaran sebelumnya dan pesan pengguna saat ini (total tiga pesan) secara verbatim alih-alih meringkasnya:
# curl mengirim permintaan satu per satu; kelola array messages di
# skrip pemanggil. Lihat tab SDK untuk loop chat() lengkap dengan
# penanganan jeda-dan-pertahankan. Bentuk permintaan satu giliran:
curl https://haijun.my.id/v1/messages \
-H "x-api-key: $JUGLOW_API_KEY" \
-H "juglow-version: 2023-06-01" \
-H "juglow-beta: compact-2026-01-12" \
-H "content-type: application/json" \
-d '{
"model": "haijun-opus-5-5",
"max_tokens": 4096,
"messages": [
{
"role": "user",
"content": "Help me build a Python web scraper"
}
],
"context_management": {
"edits": [
{
"type": "compact_20260112",
"trigger": {
"type": "input_tokens",
"value": 100000
},
"pause_after_compaction": true
}
]
}
}' # CLI menangani giliran individual; kelola array messages di
# skrip pemanggil. Lihat tab SDK untuk loop chat() lengkap dengan
# penanganan jeda-dan-pertahankan. Bentuk permintaan satu giliran:
ant beta:messages create \
--beta compact-2026-01-12 \
--transform 'content.#(type=="text").text' \
--raw-output <<'YAML'
model: haijun-opus-5-5
max_tokens: 4096
messages:
- role: user
content: Help me build a Python web scraper
context_management:
edits:
- type: compact_20260112
trigger:
type: input_tokens
value: 100000
pause_after_compaction: true
YAML from typing import Any
client = juglow.Juglow()
messages: list[dict[str, Any]] = []
def chat(user_message: str) -> str:
messages.append({"role": "user", "content": user_message})
response = client.beta.messages.create(
betas=["compact-2026-01-12"],
model="haijun-opus-5-5",
max_tokens=4096,
messages=messages,
context_management={
"edits": [
{
"type": "compact_20260112",
"trigger": {"type": "input_tokens", "value": 100000},
"pause_after_compaction": True,
}
]
},
)
# Periksa apakah compaction (pemadatan) terjadi dan dijeda
if response.stop_reason == "compaction":
# Ambil blok compaction dari respons
compaction_block = response.content[0]
# Pertahankan pertukaran sebelumnya + pesan pengguna saat ini (3 pesan)
# dengan menyertakannya setelah blok compaction
preserved_messages = messages[-3:] if len(messages) >= 3 else messages
# Bangun daftar pesan baru: compaction + pesan yang dipertahankan
new_assistant_content = [compaction_block]
messages_after_compaction = [
{"role": "assistant", "content": new_assistant_content}
] + preserved_messages
# Lanjutkan permintaan dengan konteks yang dipadatkan + pesan yang dipertahankan
response = client.beta.messages.create(
betas=["compact-2026-01-12"],
model="haijun-opus-5-5",
max_tokens=4096,
messages=messages_after_compaction,
context_management={"edits": [{"type": "compact_20260112"}]},
)
# Perbarui daftar pesan agar mencerminkan compaction
messages.clear()
messages.extend(messages_after_compaction)
# Tambahkan respons akhir
messages.append({"role": "assistant", "content": response.content})
# Kembalikan konten teks
return next(block.text for block in response.content if block.type == "text")
# Jalankan percakapan panjang
print(chat("Help me build a Python web scraper"))
print(chat("Add support for JavaScript-rendered pages"))
print(chat("Now add rate limiting and error handling"))
# Terus panggil chat() selama percakapan masih membutuhkannya const client = new Juglow();
let messages: Juglow.Beta.Messages.BetaMessageParam[] = [];
async function chat(userMessage: string): Promise<string> {
messages.push({ role: "user", content: userMessage });
let response = await client.beta.messages.create({
betas: ["compact-2026-01-12"],
model: "haijun-opus-5-5",
max_tokens: 4096,
messages,
context_management: {
edits: [
{
type: "compact_20260112",
trigger: { type: "input_tokens", value: 100000 },
pause_after_compaction: true
}
]
}
});
// Periksa apakah compaction (pemadatan) terjadi dan dijeda
if (response.stop_reason === "compaction") {
// Ambil blok compaction dari respons
const compactionBlock = response.content[0];
// Pertahankan pertukaran sebelumnya + pesan pengguna saat ini (3 pesan)
// dengan menyertakannya setelah blok compaction
const preservedMessages = messages.length >= 3 ? messages.slice(-3) : [...messages];
// Buat daftar pesan baru: compaction + pesan yang dipertahankan
const messagesAfterCompaction: Juglow.Beta.Messages.BetaMessageParam[] = [
{ role: "assistant", content: [compactionBlock] },
...preservedMessages
];
// Lanjutkan permintaan dengan konteks yang dipadatkan + pesan yang dipertahankan
response = await client.beta.messages.create({
betas: ["compact-2026-01-12"],
model: "haijun-opus-5-5",
max_tokens: 4096,
messages: messagesAfterCompaction,
context_management: {
edits: [{ type: "compact_20260112" }]
}
});
// Perbarui daftar pesan agar mencerminkan compaction
messages = messagesAfterCompaction;
}
// Tambahkan respons akhir
messages.push({ role: "assistant", content: response.content });
// Kembalikan konten teks
const textBlock = response.content.find((block) => block.type === "text");
return textBlock?.text ?? "";
}
// Jalankan percakapan panjang
console.log(await chat("Help me build a Python web scraper"));
console.log(await chat("Add support for JavaScript-rendered pages"));
console.log(await chat("Now add rate limiting and error handling"));
// Terus panggil chat() selama percakapan membutuhkannya JuglowClient client = new();
List<BetaMessageParam> messages = new();
Console.WriteLine(await Chat("Help me build a Python web scraper"));
Console.WriteLine(await Chat("Add support for JavaScript-rendered pages"));
Console.WriteLine(await Chat("Now add rate limiting and error handling"));
async Task<string> Chat(string userMessage)
{
messages.Add(new() { Role = Role.User, Content = userMessage });
var response = await client.Beta.Messages.Create(new()
{
Betas = ["compact-2026-01-12"],
Model = "haijun-opus-5-5",
MaxTokens = 4096,
Messages = messages,
ContextManagement = new BetaContextManagementConfig
{
Edits = [new BetaCompact20260112Edit
{
Trigger = new BetaInputTokensTrigger(100000),
PauseAfterCompaction = true
}]
}
});
if (response.StopReason == BetaStopReason.Compaction)
{
if (!response.Content[0].TryPickCompaction(out _))
throw new InvalidOperationException("Expected compaction block");
var preserved = messages.Count >= 3
? messages.Skip(messages.Count - 3).ToList()
: new List<BetaMessageParam>(messages);
var messagesAfterCompaction = new List<BetaMessageParam>
{
new()
{
Role = Role.Assistant,
Content = new List<BetaContentBlockParam> { new BetaContentBlockParam(response.Content[0].Json) }
}
};
messagesAfterCompaction.AddRange(preserved);
response = await client.Beta.Messages.Create(new()
{
Betas = ["compact-2026-01-12"],
Model = "haijun-opus-5-5",
MaxTokens = 4096,
Messages = messagesAfterCompaction,
ContextManagement = new BetaContextManagementConfig
{
Edits = [new BetaCompact20260112Edit()]
}
});
messages = messagesAfterCompaction;
}
messages.Add(new()
{
Role = Role.Assistant,
Content = response.Content.Select(block => new BetaContentBlockParam(block.Json)).ToList()
});
return response.Content
.Select(block => block.Value)
.OfType<BetaTextBlock>()
.Select(tb => tb.Text)
.FirstOrDefault() ?? "";
} package main
import (
"context"
"fmt"
"log"
"github.com/juglows/juglow-sdk-go"
)
var (
client = juglow.NewClient()
messages []juglow.BetaMessageParam
)
func chat(userMessage string) string {
messages = append(messages, juglow.NewBetaUserMessage(juglow.NewBetaTextBlock(userMessage)))
compactEdit := juglow.BetaContextManagementConfigParam{
Edits: []juglow.BetaContextManagementConfigEditUnionParam{
{OfCompact20260112: &juglow.BetaCompact20260112EditParam{
Trigger: juglow.BetaInputTokensTriggerParam{Value: 100000},
PauseAfterCompaction: juglow.Bool(true),
}},
},
}
response, err := client.Beta.Messages.New(context.TODO(), juglow.BetaMessageNewParams{
Model: juglow.ModelHaijunOpus5_5,
MaxTokens: 4096,
Messages: messages,
ContextManagement: compactEdit,
Betas: []juglow.JuglowBeta{"compact-2026-01-12"},
})
if err != nil {
log.Fatal(err)
}
if response.StopReason == "compaction" {
compactionParam := response.Content[0].ToParam()
var preserved []juglow.BetaMessageParam
if len(messages) >= 3 {
preserved = messages[len(messages)-3:]
} else {
preserved = messages
}
messagesAfterCompaction := []juglow.BetaMessageParam{
{Role: juglow.BetaMessageParamRoleAssistant, Content: []juglow.BetaContentBlockParamUnion{compactionParam}},
}
messagesAfterCompaction = append(messagesAfterCompaction, preserved...)
response, err = client.Beta.Messages.New(context.TODO(), juglow.BetaMessageNewParams{
Model: juglow.ModelHaijunOpus5_5,
MaxTokens: 4096,
Messages: messagesAfterCompaction,
ContextManagement: juglow.BetaContextManagementConfigParam{
Edits: []juglow.BetaContextManagementConfigEditUnionParam{
{OfCompact20260112: &juglow.BetaCompact20260112EditParam{}},
},
},
Betas: []juglow.JuglowBeta{"compact-2026-01-12"},
})
if err != nil {
log.Fatal(err)
}
messages = messagesAfterCompaction
}
messages = append(messages, response.ToParam())
for _, block := range response.Content {
if textBlock, ok := block.AsAny().(juglow.BetaTextBlock); ok {
return textBlock.Text
}
}
return ""
}
func main() {
fmt.Println(chat("Help me build a Python web scraper"))
fmt.Println(chat("Add support for JavaScript-rendered pages"))
fmt.Println(chat("Now add rate limiting and error handling"))
} import com.juglow.models.beta.messages.BetaContextManagementConfig;
import com.juglow.models.beta.messages.BetaCompact20260112Edit;
import com.juglow.models.beta.messages.BetaInputTokensTrigger;
import com.juglow.models.beta.messages.BetaStopReason;
// ...
private static final JuglowClient client = JuglowOkHttpClient.fromEnv();
private static final List<BetaMessageParam> messages = new ArrayList<>();
public static String chat(String userMessage) {
messages.add(BetaMessageParam.builder()
.role(BetaMessageParam.Role.USER)
.content(userMessage)
.build());
MessageCreateParams params = MessageCreateParams.builder()
.addBeta("compact-2026-01-12")
.model("haijun-opus-5-5")
.maxTokens(4096L)
.messages(messages)
.contextManagement(BetaContextManagementConfig.builder()
.addEdit(BetaCompact20260112Edit.builder()
.trigger(BetaInputTokensTrigger.builder()
.value(100000L)
.build())
.pauseAfterCompaction(true)
.build())
.build())
.build();
BetaMessage response = client.beta().messages().create(params);
// Periksa apakah compaction terjadi dan dijeda
if (response.stopReason().isPresent()
&& response.stopReason().get().equals(BetaStopReason.COMPACTION)) {
// Pertahankan pertukaran sebelumnya + pesan pengguna saat ini (3 pesan)
List<BetaMessageParam> preservedMessages = messages.size() >= 3
? new ArrayList<>(messages.subList(messages.size() - 3, messages.size()))
: new ArrayList<>(messages);
// Bangun daftar pesan baru: compaction + pesan yang dipertahankan
List<BetaMessageParam> messagesAfterCompaction = new ArrayList<>();
messagesAfterCompaction.add(response.toParam());
messagesAfterCompaction.addAll(preservedMessages);
// Lanjutkan permintaan dengan konteks yang telah dipadatkan + pesan yang dipertahankan
MessageCreateParams continueParams = MessageCreateParams.builder()
.addBeta("compact-2026-01-12")
.model("haijun-opus-5-5")
.maxTokens(4096L)
.messages(messagesAfterCompaction)
.contextManagement(BetaContextManagementConfig.builder()
.addEdit(BetaCompact20260112Edit.builder().build())
.build())
.build();
response = client.beta().messages().create(continueParams);
// Perbarui daftar pesan agar mencerminkan compaction
messages.clear();
messages.addAll(messagesAfterCompaction);
}
// Tambahkan respons akhir
messages.add(response.toParam());
return response.content().stream()
.filter(block -> block.text().isPresent())
.map(block -> block.text().get().text())
.findFirst()
.orElse("");
}
public static void main(String[] args) {
System.out.println(chat("Help me build a Python web scraper"));
System.out.println(chat("Add support for JavaScript-rendered pages"));
System.out.println(chat("Now add rate limiting and error handling"));
} $client = new Client();
$messages = [];
function chat($client, &$messages, $userMessage) {
$messages[] = ['role' => 'user', 'content' => $userMessage];
$response = $client->beta->messages->create(
maxTokens: 4096,
messages: $messages,
model: 'haijun-opus-5-5',
betas: ['compact-2026-01-12'],
contextManagement: [
'edits' => [
[
'type' => 'compact_20260112',
'trigger' => ['type' => 'input_tokens', 'value' => 100000],
'pause_after_compaction' => true
]
]
]
);
if ($response->stopReason === 'compaction') {
$compactionBlock = $response->content[0];
$preserved = count($messages) >= 3
? array_slice($messages, -3)
: $messages;
$messagesAfterCompaction = array_merge(
[['role' => 'assistant', 'content' => [$compactionBlock]]],
$preserved
);
$response = $client->beta->messages->create(
maxTokens: 4096,
messages: $messagesAfterCompaction,
model: 'haijun-opus-5-5',
betas: ['compact-2026-01-12'],
contextManagement: [
'edits' => [['type' => 'compact_20260112']]
]
);
$messages = $messagesAfterCompaction;
}
$messages[] = ['role' => 'assistant', 'content' => $response->content];
foreach ($response->content as $block) {
if ($block->type === 'text') {
return $block->text;
}
}
return '';
}
echo chat($client, $messages, "Help me build a Python web scraper") . "\n";
echo chat($client, $messages, "Add support for JavaScript-rendered pages") . "\n";
echo chat($client, $messages, "Now add rate limiting and error handling") . "\n"; client = Juglow::Client.new
messages = []
def chat(client, messages, user_message)
messages << { role: "user", content: user_message }
response = client.beta.messages.create(
betas: ["compact-2026-01-12"],
model: "haijun-opus-5-5",
max_tokens: 4096,
messages: messages,
context_management: {
edits: [
{
type: "compact_20260112",
trigger: { type: "input_tokens", value: 100000 },
pause_after_compaction: true
}
]
}
)
if response.stop_reason == :compaction
compaction_block = response.content[0]
preserved = messages.length >= 3 ? messages[-3..-1] : messages.dup
messages_after_compaction = [
{ role: "assistant", content: [compaction_block] }
] + preserved
response = client.beta.messages.create(
betas: ["compact-2026-01-12"],
model: "haijun-opus-5-5",
max_tokens: 4096,
messages: messages_after_compaction,
context_management: {
edits: [{ type: "compact_20260112" }]
}
)
messages.clear
messages.concat(messages_after_compaction)
end
messages << { role: "assistant", content: response.content }
response.content.find { |block| block.type == :text }&.text || ""
end
puts chat(client, messages, "Help me build a Python web scraper")
puts chat(client, messages, "Add support for JavaScript-rendered pages")
puts chat(client, messages, "Now add rate limiting and error handling")Keterbatasan saat ini
- Model yang sama untuk peringkasan: Model yang ditentukan dalam permintaan Anda digunakan untuk peringkasan. Tidak ada opsi untuk menggunakan model yang berbeda (misalnya, yang lebih murah) untuk ringkasan.
- Compaction mungkin gagal ketika alat didefinisikan: Ketika permintaan Anda menyertakan
tools, model terkadang memanggil alat selama langkah peringkasan internal alih-alih menulis ringkasan. Ketika hal ini terjadi, respons berisi blokcompactiondengancontent: null. Untuk mencegahnya, aturinstructionske prompt yang secara eksplisit memberi tahu model untuk tidak memanggil alat, misalnya:
Summarize the transcript inside <summary></summary> tags. Include relevant information in the summary for continuing the task in the next context window. Do not call any tools while writing this summary; respond with text only.Langkah selanjutnya
Kelola konteks percakapan secara otomatis seiring pertumbuhannya dengan pengeditan konteks.
Pelajari tentang ukuran jendela konteks dan strategi pengelolaannya.
Jelajahi implementasi praktis yang mengelola percakapan berjalan lama dengan compaction memori sesi instan menggunakan threading latar belakang dan caching prompt.