Haijun Platform Docs
EN

"Advisor tool" (alat advisor) memungkinkan model executor yang lebih cepat dan lebih murah untuk berkonsultasi dengan model advisor berkecerdasan lebih tinggi di tengah proses generasi guna mendapatkan panduan strategis. Advisor membaca seluruh percakapan, menghasilkan rencana atau koreksi arah, dan executor melanjutkan tugasnya.

Pola ini cocok untuk beban kerja agentic berjangka panjang (agen coding, computer use, pipeline riset multilangkah) di mana sebagian besar giliran bersifat mekanis tetapi memiliki rencana yang sangat baik adalah hal yang krusial. Anda mendapatkan kualitas yang mendekati advisor-saja sementara sebagian besar generasi token terjadi dengan tarif model executor. Untuk hasil terukur, termasuk bagaimana manfaatnya menyusut seiring kemampuan executor sendiri mendekati kemampuan advisor, lihat Mengoptimalkan biaya dan kecerdasan.

mermaid
sequenceDiagram
  participant U as Your application
  participant E as Executor model
  participant A as Advisor model

  U->>E: Request with advisor tool
  note over E: Executor begins the task
  E->>A: server_tool_use (server-side)
  note over A: Reads the full transcript,<br/>returns strategic guidance
  A-->>E: advisor_tool_result
  note over E: Executor continues,<br/>informed by the advice
  E-->>U: Response

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

Kapan menggunakannya

Advisor cocok untuk konfigurasi berikut:

  • Anda saat ini menggunakan Sonnet untuk tugas kompleks: Tambahkan advisor dari tingkat yang lebih tinggi. Opus menjaga total biaya tetap serupa atau lebih rendah; Haijun Fable 5.1 memaksimalkan peningkatan kualitas.
  • Anda saat ini menggunakan Haiku dan menginginkan peningkatan kecerdasan: Tambahkan advisor Opus atau Fable. Perkirakan biaya yang lebih tinggi daripada Haiku saja, tetapi lebih rendah daripada mengganti eksekutor ke model yang lebih besar.

Hasilnya bergantung pada tugas. Evaluasi pada beban kerja Anda sendiri.

Advisor kurang cocok untuk tanya jawab satu giliran (tidak ada yang perlu direncanakan), pemilih model pass-through murni di mana pengguna Anda sudah memilih sendiri tradeoff biaya dan kualitas mereka, atau beban kerja di mana setiap giliran benar-benar memerlukan kemampuan penuh model advisor.

Mulai cepat

Note: Alat advisor masih dalam versi beta. Sertakan header beta advisor-tool-2026-03-01 dalam permintaan Anda.

bash
  curl https://haijun.my.id/v1/messages \
    -H "x-api-key: $JUGLOW_API_KEY" \
    -H "juglow-version: 2023-06-01" \
    -H "juglow-beta: advisor-tool-2026-03-01" \
    -H "content-type: application/json" \
    -d '{
      "model": "haijun-sonnet-5",
      "max_tokens": 4096,
      "tools": [
        {
          "type": "advisor_20260301",
          "name": "advisor",
          "model": "haijun-opus-5"
        }
      ],
      "messages": [{
        "role": "user",
        "content": "Build a concurrent worker pool in Go with graceful shutdown."
      }]
    }'
bash
  ant beta:messages create --beta advisor-tool-2026-03-01 <<'YAML'
  model: haijun-sonnet-5
  max_tokens: 4096
  tools:
    - type: advisor_20260301
      name: advisor
      model: haijun-opus-5
  messages:
    - role: user
      content: Build a concurrent worker pool in Go with graceful shutdown.
  YAML
python
  client = juglow.Juglow()

  response = client.beta.messages.create(
      model="haijun-sonnet-5",
      max_tokens=4096,
      betas=["advisor-tool-2026-03-01"],
      tools=[
          {
              "type": "advisor_20260301",
              "name": "advisor",
              "model": "haijun-opus-5",
          }
      ],
      messages=[
          {
              "role": "user",
              "content": "Build a concurrent worker pool in Go with graceful shutdown.",
          }
      ],
  )

  print(response)
typescript
  const client = new Juglow();

  const response = await client.beta.messages.create({
    model: "haijun-sonnet-5",
    max_tokens: 4096,
    betas: ["advisor-tool-2026-03-01"],
    tools: [
      {
        type: "advisor_20260301",
        name: "advisor",
        model: "haijun-opus-5"
      }
    ],
    messages: [
      {
        role: "user",
        content: "Build a concurrent worker pool in Go with graceful shutdown."
      }
    ]
  });

  console.log(response);
csharp
  using Juglow.Models.Beta.Messages;
  using Messages = Juglow.Models.Messages;

  var client = new JuglowClient();

  var parameters = new MessageCreateParams
  {
      Model = Messages::Model.HaijunSonnet5,
      MaxTokens = 4096,
      Tools = new BetaToolUnion[]
      {
          new BetaAdvisorTool20260301
          {
              Model = Messages::Model.HaijunOpus5
          }
      },
      Messages =
      [
          new BetaMessageParam
          {
              Role = Role.User,
              Content = "Build a concurrent worker pool in Go with graceful shutdown."
          }
      ],
      Betas = ["advisor-tool-2026-03-01"]
  };

  var response = await client.Beta.Messages.Create(parameters);
  Console.WriteLine(response);
go
  client := juglow.NewClient()

  response, err := client.Beta.Messages.New(context.TODO(), juglow.BetaMessageNewParams{
  	Model:     juglow.ModelHaijunSonnet5,
  	MaxTokens: 4096,
  	Tools: []juglow.BetaToolUnionParam{
  		{OfAdvisorTool20260301: &juglow.BetaAdvisorTool20260301Param{
  			Model: juglow.ModelHaijunOpus5,
  		}},
  	},
  	Messages: []juglow.BetaMessageParam{
  		juglow.NewBetaUserMessage(juglow.NewBetaTextBlock("Build a concurrent worker pool in Go with graceful shutdown.")),
  	},
  	Betas: []juglow.JuglowBeta{
  		juglow.JuglowBetaAdvisorTool2026_03_01,
  	},
  })
  if err != nil {
  	log.Fatal(err)
  }
  fmt.Println(response)
java
  import com.juglow.models.beta.messages.BetaAdvisorTool20260301;
  import com.juglow.models.beta.messages.BetaMessage;
  import com.juglow.models.beta.messages.MessageCreateParams;
  import com.juglow.models.messages.Model;

  void main() {
      JuglowClient client = JuglowOkHttpClient.fromEnv();

      MessageCreateParams params = MessageCreateParams.builder()
          .model(Model.HAIJUN_SONNET_5)
          .maxTokens(4096L)
          .addTool(BetaAdvisorTool20260301.builder()
              .model(Model.HAIJUN_OPUS_5)
              .build())
          .addUserMessage("Build a concurrent worker pool in Go with graceful shutdown.")
          .addBeta("advisor-tool-2026-03-01")
          .build();

      BetaMessage response = client.beta().messages().create(params);
      IO.println(response);
  }
php
  $client = new Client();

  $response = $client->beta->messages->create(
      maxTokens: 4096,
      messages: [
          [
              'role' => 'user',
              'content' => 'Build a concurrent worker pool in Go with graceful shutdown.',
          ],
      ],
      model: 'haijun-sonnet-5',
      tools: [
          [
              'type' => 'advisor_20260301',
              'name' => 'advisor',
              'model' => 'haijun-opus-5',
          ],
      ],
      betas: ['advisor-tool-2026-03-01'],
  );

  echo $response;
ruby
  client = Juglow::Client.new

  response = client.beta.messages.create(
    model: "haijun-sonnet-5",
    max_tokens: 4096,
    tools: [
      {
        type: "advisor_20260301",
        name: "advisor",
        model: "haijun-opus-5"
      }
    ],
    messages: [
      {
        role: "user",
        content: "Build a concurrent worker pool in Go with graceful shutdown."
      }
    ],
    betas: ["advisor-tool-2026-03-01"]
  )

  puts response

content respons menyertakan blok advisor_tool_result yang membawa panduan dari advisor. Dengan haijun-opus-5 sebagai advisor, seperti dalam mulai cepat ini, field content pada blok tersebut adalah varian advisor_redacted_result (terenkripsi; executor membacanya di sisi server, tetapi klien Anda tidak). Untuk melihat teks saran secara langsung dalam respons Anda, gunakan haijun-opus-4-8 sebagai model advisor, yang mengembalikan varian advisor_result berupa plaintext. Lihat Varian hasil untuk kedua bentuk secara berdampingan dan model advisor mana yang mengembalikan varian mana, serta Kompatibilitas model untuk daftar lengkap pasangan yang valid.

Cara kerjanya

Saat Anda menambahkan alat advisor ke array tools Anda, model executor menentukan kapan memanggilnya, seperti alat lainnya. Saat executor memanggil advisor:

  1. Executor mengeluarkan blok server_tool_use dengan name: "advisor" dan input kosong. Executor memberi sinyal waktu, dan server menyediakan konteks.
  1. Juglow menjalankan proses inferensi terpisah pada model advisor di sisi server. Advisor berjalan di bawah prompt sistem miliknya sendiri yang disediakan Juglow dan menerima transkrip lengkap executor sebagai konteks kutipan dalam inputnya. Transkrip tersebut mencakup prompt sistem Anda, definisi alat, giliran sebelumnya dan hasil alat, serta teks yang telah dihasilkan executor sejauh ini dalam giliran ini.
  1. Respons advisor dikembalikan ke executor sebagai blok advisor_tool_result.
  1. Executor melanjutkan generasi, dengan informasi dari saran tersebut.

Semua ini terjadi di dalam satu permintaan /v1/messages, tanpa round trip tambahan di sisi Anda. Pengecualiannya adalah giliran yang berhenti sejenak di tengah panggilan, yang Anda lanjutkan dengan permintaan lanjutan (lihat Melanjutkan giliran yang dijeda).

Advisor itu sendiri berjalan tanpa alat dan tanpa manajemen konteks. Blok thinking-nya dibuang sebelum hasil dikembalikan. Hanya teks saran yang sampai ke executor.

Parameter alat

ParameterTipeDefaultDeskripsi
typestringwajibHarus "advisor_20260301".
namestringwajibHarus "advisor".
modelstringwajibID model advisor, seperti haijun-opus-5. Ditagih dengan tarif model ini untuk sub-inferensi.
max_usesintegertak terbatasJumlah maksimum panggilan advisor yang diizinkan dalam satu permintaan. Setelah executor mencapai batas ini, panggilan advisor selanjutnya mengembalikan advisor_tool_result_error dengan error_code: "max_uses_exceeded" dan executor melanjutkan tanpa saran lebih lanjut. Ini adalah batas per permintaan, bukan batas per percakapan. Lihat Kontrol biaya untuk batas tingkat percakapan.
max_tokensintegerbatas output model advisorMembatasi total output advisor (thinking ditambah teks) per panggilan. Minimum 1024. Lihat Membatasi output advisor.
cachingobject \nullnull (nonaktif)Mengaktifkan caching prompt untuk transkrip advisor sendiri di seluruh panggilan dalam satu percakapan. Lihat Caching prompt advisor.

Objek caching memiliki bentuk {"type": "ephemeral", "ttl": "5m" | "1h"}. Tidak seperti cache_control pada blok konten, ini bukan penanda breakpoint. Ini adalah sakelar aktif/nonaktif. Server menentukan di mana batas cache ditempatkan.

Alat advisor juga menerima properti generik yang tersedia pada definisi alat apa pun: cache_control, allowed_callers, defer_loading, dan strict (dibahas dalam structured outputs). Lihat Referensi alat untuk semantiknya.

Struktur respons

Panggilan advisor yang berhasil

Saat advisor dipanggil, blok server_tool_use diikuti oleh blok advisor_tool_result dalam konten asisten. Contoh berikut menunjukkan varian advisor_result plaintext yang dikembalikan oleh advisor Haijun Opus 4.8. Mulai cepat menggunakan Haijun Opus 5, yang mengembalikan varian advisor_redacted_result terenkripsi; lihat Varian hasil untuk kedua bentuk secara berdampingan.

json
{
  "role": "assistant",
  "content": [
    {
      "type": "text",
      "text": "Let me consult the advisor on this."
    },
    {
      "type": "server_tool_use",
      "id": "srvtoolu_abc123",
      "name": "advisor",
      "input": {}
    },
    {
      "type": "advisor_tool_result",
      "tool_use_id": "srvtoolu_abc123",
      "content": {
        "type": "advisor_result",
        "text": "Use a channel-based coordination pattern. The tricky part is draining in-flight work during shutdown: close the input channel first, then wait on a WaitGroup..."
      }
    },
    {
      "type": "text",
      "text": "Here's the implementation. I'm using a channel-based coordination pattern to avoid writer starvation..."
    }
  ]
}

server_tool_use.input selalu kosong. Server menyusun tampilan advisor dari transkrip lengkap secara otomatis. Tidak ada yang dimasukkan executor ke dalam input yang sampai ke advisor.

Varian hasil

Field advisor_tool_result.content adalah discriminated union. Untuk panggilan yang berhasil, variannya bergantung pada model advisor:

VarianFieldDikembalikan ketika
advisor_resulttext, stop_reasonModel advisor mengembalikan plaintext (misalnya, Haijun Opus 4.8).
advisor_redacted_resultencrypted_content, stop_reasonModel advisor mengembalikan output terenkripsi.

Note: Advisor Haijun Fable 5.1, Haijun Mythos 5.1, Haijun Opus 5, Haijun Fable 5, dan Haijun Mythos 5 mengembalikan advisor_redacted_result terenkripsi. Setiap model advisor lain dalam tabel kompatibilitas mengembalikan advisor_result plaintext. Untuk membaca teks saran dalam respons Anda sendiri, gunakan advisor yang mengembalikan plaintext, seperti haijun-opus-4-8, jika baris executor Anda dalam tabel kompatibilitas mencantumkannya. Executor Haijun Fable 5.1, Haijun Mythos 5.1, Haijun Opus 5, Haijun Fable 5, dan Haijun Mythos 5 hanya berpasangan dengan advisor yang mengembalikan bentuk terenkripsi, sehingga pada executor tersebut teks saran tidak dapat dibaca dalam respons.

Berikut adalah permintaan yang sama dikirim dua kali, identik kecuali model advisor dalam definisi alat, yang menunjukkan kedua varian.

Dengan "model": "haijun-opus-4-8", sarannya berupa plaintext:

json
{
  "type": "advisor_tool_result",
  "tool_use_id": "srvtoolu_abc123",
  "content": {
    "type": "advisor_result",
    "text": "Use a channel-based coordination pattern. The tricky part is draining in-flight work during shutdown: close the input channel first, then wait on a WaitGroup..."
  }
}

Dengan "model": "haijun-opus-5", sarannya terenkripsi:

json
{
  "type": "advisor_tool_result",
  "tool_use_id": "srvtoolu_abc123",
  "content": {
    "type": "advisor_redacted_result",
    "encrypted_content": "EqQBCkYIBRgCIiQ5ZjE0N2M2OC0yYWIxLTRkZTktYjA3ZC1hZTUyMzkxYjhkMmU..."
  }
}

Kedua varian hasil membawa field stop_reason saat Anda menetapkan max_tokens pada definisi alat, dan menghilangkannya saat Anda tidak menetapkannya. Field ini berisi stop reason sub-panggilan advisor, biasanya "end_turn", atau "max_tokens" saat batas tercapai. Nilainya sesuai dengan stop_reason tingkat atas Messages API.

Dengan advisor_result, field text berisi saran yang dapat dibaca manusia. Dengan advisor_redacted_result, field encrypted_content berisi blob buram yang tidak dapat Anda baca. Pada giliran berikutnya, server mendekripsinya dan merender plaintext ke dalam prompt executor.

Dalam kedua kasus, kirim kembali konten tersebut apa adanya pada giliran berikutnya. Jika Anda mengganti model advisor di tengah percakapan, lakukan percabangan berdasarkan content.type untuk menangani kedua bentuk.

Hasil error

Jika panggilan advisor gagal, hasilnya membawa error:

json
{
  "type": "advisor_tool_result",
  "tool_use_id": "srvtoolu_abc123",
  "content": {
    "type": "advisor_tool_result_error",
    "error_code": "overloaded"
  }
}

Executor melihat error tersebut dan melanjutkan tanpa saran lebih lanjut. Permintaan itu sendiri tidak gagal.

error_codeArti
max_uses_exceededPermintaan mencapai batas max_uses yang ditetapkan pada definisi alat. Panggilan advisor selanjutnya dalam permintaan yang sama mengembalikan error ini.
too_many_requestsSub-inferensi advisor terkena batas laju.
overloadedSub-inferensi advisor mencapai batas kapasitas.
prompt_too_longTranskrip melebihi jendela konteks model advisor.
execution_time_exceededSub-inferensi advisor kehabisan waktu.
model_not_foundModel advisor yang dikonfigurasi tidak tersedia.
unavailableKegagalan advisor lainnya.

"Rate limit" (batas laju) advisor diambil dari bucket per model yang sama dengan panggilan langsung ke model advisor. Batas laju pada advisor muncul sebagai too_many_requests di dalam hasil alat. Batas laju pada executor menggagalkan seluruh permintaan dengan HTTP 429.

Percakapan multi-giliran

Kirimkan konten asisten lengkap, termasuk blok advisor_tool_result, kembali ke API pada giliran berikutnya. Kirim kembali blok hasil apa adanya: dengan advisor Haijun Opus 5, content blok hasil adalah varian advisor_redacted_result terenkripsi, dan server mendekripsinya serta merender saran ke dalam prompt executor pada giliran berikutnya (lihat Varian hasil). Mekanismenya identik untuk model advisor apa pun.

python
  client = juglow.Juglow()

  tools = [
      {
          "type": "advisor_20260301",
          "name": "advisor",
          "model": "haijun-opus-5",
      }
  ]

  messages = [
      {
          "role": "user",
          "content": "Build a concurrent worker pool in Go with graceful shutdown.",
      }
  ]

  response = client.beta.messages.create(
      model="haijun-sonnet-5",
      max_tokens=1024,
      betas=["advisor-tool-2026-03-01"],
      tools=tools,
      messages=messages,
  )

  # Tambahkan seluruh konten respons, termasuk blok advisor_tool_result apa pun
  messages.append({"role": "assistant", "content": response.content})

  # Lanjutkan percakapan
  messages.append({"role": "user", "content": "Now add a max-in-flight limit of 10."})

  response = client.beta.messages.create(
      model="haijun-sonnet-5",
      max_tokens=1024,
      betas=["advisor-tool-2026-03-01"],
      tools=tools,
      messages=messages,
  )
typescript
  const client = new Juglow();

  const tools: Juglow.Beta.Messages.BetaToolUnion[] = [
    {
      type: "advisor_20260301",
      name: "advisor",
      model: "haijun-opus-5"
    }
  ];

  const messages: Juglow.Beta.Messages.BetaMessageParam[] = [
    {
      role: "user",
      content: "Build a concurrent worker pool in Go with graceful shutdown."
    }
  ];

  const response = await client.beta.messages.create({
    model: "haijun-sonnet-5",
    max_tokens: 1024,
    betas: ["advisor-tool-2026-03-01"],
    tools,
    messages
  });

  // Tambahkan seluruh konten respons, termasuk blok advisor_tool_result apa pun
  messages.push({ role: "assistant", content: response.content });

  // Lanjutkan percakapan
  messages.push({ role: "user", content: "Now add a max-in-flight limit of 10." });

  const followUp = await client.beta.messages.create({
    model: "haijun-sonnet-5",
    max_tokens: 1024,
    betas: ["advisor-tool-2026-03-01"],
    tools,
    messages
  });
csharp
  using Juglow.Models.Beta.Messages;
  using Messages = Juglow.Models.Messages;

  var client = new JuglowClient();

  var tools = new BetaToolUnion[]
  {
      new BetaAdvisorTool20260301 { Model = Messages::Model.HaijunOpus5 }
  };

  var messages = new List<BetaMessageParam>
  {
      new() { Role = Role.User, Content = "Build a concurrent worker pool in Go with graceful shutdown." }
  };

  var response = await client.Beta.Messages.Create(new MessageCreateParams
  {
      Model = Messages::Model.HaijunSonnet5,
      MaxTokens = 1024,
      Tools = tools,
      Messages = messages,
      Betas = ["advisor-tool-2026-03-01"]
  });

  // Tambahkan seluruh konten respons, termasuk blok advisor_tool_result apa pun
  messages.Add(new BetaMessageParam
  {
      Role = Role.Assistant,
      Content = response.Content.Select(block => new BetaContentBlockParam(block.Json)).ToList()
  });

  // Lanjutkan percakapan
  messages.Add(new BetaMessageParam { Role = Role.User, Content = "Now add a max-in-flight limit of 10." });

  var followUp = await client.Beta.Messages.Create(new MessageCreateParams
  {
      Model = Messages::Model.HaijunSonnet5,
      MaxTokens = 1024,
      Tools = tools,
      Messages = messages,
      Betas = ["advisor-tool-2026-03-01"]
  });
go
  client := juglow.NewClient()

  tools := []juglow.BetaToolUnionParam{
  	{OfAdvisorTool20260301: &juglow.BetaAdvisorTool20260301Param{
  		Model: juglow.ModelHaijunOpus5,
  	}},
  }

  messages := []juglow.BetaMessageParam{
  	juglow.NewBetaUserMessage(juglow.NewBetaTextBlock("Build a concurrent worker pool in Go with graceful shutdown.")),
  }

  response, err := client.Beta.Messages.New(context.TODO(), juglow.BetaMessageNewParams{
  	Model:     juglow.ModelHaijunSonnet5,
  	MaxTokens: 1024,
  	Tools:     tools,
  	Messages:  messages,
  	Betas: []juglow.JuglowBeta{
  		juglow.JuglowBetaAdvisorTool2026_03_01,
  	},
  })
  if err != nil {
  	log.Fatal(err)
  }

  // Tambahkan seluruh konten respons, termasuk blok advisor_tool_result apa pun.
  messages = append(messages, response.ToParam())

  // Lanjutkan percakapan
  messages = append(messages, juglow.NewBetaUserMessage(juglow.NewBetaTextBlock("Now add a max-in-flight limit of 10.")))

  response, err = client.Beta.Messages.New(context.TODO(), juglow.BetaMessageNewParams{
  	Model:     juglow.ModelHaijunSonnet5,
  	MaxTokens: 1024,
  	Tools:     tools,
  	Messages:  messages,
  	Betas: []juglow.JuglowBeta{
  		juglow.JuglowBetaAdvisorTool2026_03_01,
  	},
  })
  if err != nil {
  	log.Fatal(err)
  }
java
  import com.juglow.models.beta.messages.BetaAdvisorTool20260301;
  import com.juglow.models.beta.messages.BetaContentBlock;
  import com.juglow.models.beta.messages.BetaMessage;
  import com.juglow.models.beta.messages.BetaMessageParam;
  import com.juglow.models.beta.messages.BetaToolUnion;
  import com.juglow.models.beta.messages.MessageCreateParams;
  import com.juglow.models.messages.Model;

  void main() {
      JuglowClient client = JuglowOkHttpClient.fromEnv();

      List<BetaToolUnion> tools = List.of(
          BetaToolUnion.ofAdvisorTool20260301(
              BetaAdvisorTool20260301.builder().model(Model.HAIJUN_OPUS_5).build()));

      List<BetaMessageParam> messages = new ArrayList<>();
      messages.add(BetaMessageParam.builder()
          .role(BetaMessageParam.Role.USER)
          .content("Build a concurrent worker pool in Go with graceful shutdown.")
          .build());

      BetaMessage response = client.beta().messages().create(MessageCreateParams.builder()
          .model(Model.HAIJUN_SONNET_5)
          .maxTokens(1024L)
          .tools(tools)
          .messages(messages)
          .addBeta("advisor-tool-2026-03-01")
          .build());

      // Tambahkan seluruh konten respons, termasuk blok advisor_tool_result apa pun
      messages.add(BetaMessageParam.builder()
          .role(BetaMessageParam.Role.ASSISTANT)
          .contentOfBetaContentBlockParams(
              response.content().stream().map(BetaContentBlock::toParam).toList())
          .build());

      // Lanjutkan percakapan
      messages.add(BetaMessageParam.builder()
          .role(BetaMessageParam.Role.USER)
          .content("Now add a max-in-flight limit of 10.")
          .build());

      BetaMessage followUp = client.beta().messages().create(MessageCreateParams.builder()
          .model(Model.HAIJUN_SONNET_5)
          .maxTokens(1024L)
          .tools(tools)
          .messages(messages)
          .addBeta("advisor-tool-2026-03-01")
          .build());
  }
php
  $client = new Client();

  $tools = [
      [
          'type' => 'advisor_20260301',
          'name' => 'advisor',
          'model' => 'haijun-opus-5',
      ],
  ];

  $messages = [
      [
          'role' => 'user',
          'content' => 'Build a concurrent worker pool in Go with graceful shutdown.',
      ],
  ];

  $response = $client->beta->messages->create(
      maxTokens: 1024,
      messages: $messages,
      model: 'haijun-sonnet-5',
      tools: $tools,
      betas: ['advisor-tool-2026-03-01'],
  );

  // Tambahkan seluruh konten respons, termasuk blok advisor_tool_result apa pun
  $messages[] = ['role' => 'assistant', 'content' => $response->content];

  // Lanjutkan percakapan
  $messages[] = ['role' => 'user', 'content' => 'Now add a max-in-flight limit of 10.'];

  $response = $client->beta->messages->create(
      maxTokens: 1024,
      messages: $messages,
      model: 'haijun-sonnet-5',
      tools: $tools,
      betas: ['advisor-tool-2026-03-01'],
  );
ruby
  client = Juglow::Client.new

  tools = [
    {
      type: "advisor_20260301",
      name: "advisor",
      model: "haijun-opus-5"
    }
  ]

  messages = [
    {
      role: "user",
      content: "Build a concurrent worker pool in Go with graceful shutdown."
    }
  ]

  response = client.beta.messages.create(
    model: "haijun-sonnet-5",
    max_tokens: 1024,
    tools: tools,
    messages: messages,
    betas: ["advisor-tool-2026-03-01"]
  )

  # Tambahkan konten respons lengkap, termasuk blok advisor_tool_result apa pun
  messages << { role: "assistant", content: response.content }

  # Lanjutkan percakapan
  messages << { role: "user", content: "Now add a max-in-flight limit of 10." }

  response = client.beta.messages.create(
    model: "haijun-sonnet-5",
    max_tokens: 1024,
    tools: tools,
    messages: messages,
    betas: ["advisor-tool-2026-03-01"]
  )

Anda dapat menghapus alat advisor dari tools pada giliran lanjutan sementara riwayat pesan masih berisi blok advisor_tool_result. Permintaan diterima dan blok historis dipertahankan; model tidak dapat memanggil advisor pada giliran tersebut. Anda tetap harus mengirim header beta advisor-tool-2026-03-01 agar blok riwayat tersebut diterima.

Note: Alat advisor tidak memiliki batas tingkat percakapan bawaan. Untuk membatasi panggilan advisor di seluruh percakapan, hitung di sisi klien. Saat Anda mencapai batas atas Anda, hapus alat advisor dari array tools Anda. Anda tidak perlu menghapus blok advisor_tool_result dari riwayat pesan Anda.

Melanjutkan giliran yang dijeda

Respons dapat berakhir dengan stop_reason: "pause_turn" saat panggilan advisor masih tertunda. Saat itu terjadi, respons berisi blok server_tool_use advisor tanpa advisor_tool_result untuknya. Untuk melanjutkan, tambahkan pesan asisten tersebut ke messages dengan konten yang tidak diubah, pertahankan blok server_tool_use, dan kirim permintaan lagi dengan alat advisor dan header beta yang sama. Anda tidak perlu menambahkan pesan pengguna atau blok tool_result. API menjalankan panggilan advisor yang tertunda dan melanjutkan giliran executor dalam respons baru. Giliran yang dilanjutkan dapat dijeda lagi. Jika demikian, ulangi langkah yang sama. Menghilangkan alat advisor dari permintaan lanjutan mengembalikan 400 invalid_request_error, karena blok server_tool_use yang tertunda tidak memiliki definisi alat untuk dijalankan; sertakan alat tersebut setiap kali ada panggilan yang tertunda. Jika sebaliknya executor memanggil salah satu alat Anda dalam giliran yang sama, respons berakhir dengan stop_reason: "tool_use" saat panggilan advisor masih tertunda. Kirim blok tool_result seperti biasa, dan panggilan advisor yang tertunda berjalan di awal permintaan berikutnya. Lihat Mencampur alat server dan alat klien dalam satu giliran.

Dorongan di tengah percakapan untuk executor yang kurang memanggil

Jika executor Haiku belum memanggil advisor dalam giliran asisten pertamanya, tambahkan pengingat singkat sebagai pesan pengguna tambahan sebelum giliran asisten kedua. Dalam evaluasi perilaku internal Juglow, ini meningkatkan tingkat kelulusan tugas sekitar 7 poin persentase pada executor Haiku. Pada executor Sonnet, dorongan teks biasa tidak memiliki efek terukur dalam pengujian Juglow. Pertimbangan waktu panggilan berikut ini sangat relevan untuk Sonnet. Jangan terapkan dorongan ini pada executor Opus: Pada Opus, ini sedikit menurunkan tingkat kelulusan.

Dengan NUDGE_TURN default sebesar 2, pengingat biasanya tiba setelah model berorientasi pada tugas tetapi sebelum berkomitmen pada suatu pendekatan.

python
  client = juglow.Juglow()

  NUDGE_TURN = 2  # inject before this assistant turn if no advisor call yet
  NUDGE_TEXT = (
      "You have not consulted the advisor yet. If the task has a non-obvious "
      "design decision or a failure mode you haven't ruled out, call advisor "
      "now before committing to an approach."
  )
  MAX_TURNS = 10  # agent loop cap

  def run_your_tools(content):
      # Ganti dengan dispatch alat Anda. Mengembalikan satu blok tool_result per blok tool_use.
      return [
          {
              "type": "tool_result",
              "tool_use_id": block.id,
              "content": "Replace with your tool output.",
          }
          for block in content
          if block.type == "tool_use"
      ]

  tools = [
      {"type": "advisor_20260301", "name": "advisor", "model": "haijun-opus-5"},
      # ... alat Anda yang lain
  ]
  task = "Build a concurrent worker pool in Go with graceful shutdown."
  messages = [{"role": "user", "content": task}]
  advisor_called = False

  for turn in range(1, MAX_TURNS + 1):
      response = client.beta.messages.create(
          model="haijun-haiku-4-5",
          max_tokens=4096,
          betas=["advisor-tool-2026-03-01"],
          tools=tools,
          messages=messages,
      )
      messages.append({"role": "assistant", "content": response.content})
      advisor_called = advisor_called or any(
          block.type == "server_tool_use" and block.name == "advisor"
          for block in response.content
      )
      if response.stop_reason == "end_turn":
          break
      if response.stop_reason == "pause_turn":
          continue  # server tool pending; re-send to let the API complete it

      results = run_your_tools(response.content)  # list of tool_result blocks
      if results:
          messages.append({"role": "user", "content": results})
      # Lewati ini jika prompt sistem Anda sudah menyuruh model memanggil dengan hemat.
      if turn == NUDGE_TURN - 1 and not advisor_called:
          messages.append({"role": "user", "content": NUDGE_TEXT})
typescript
  const client = new Juglow();

  const NUDGE_TURN = 2; // inject before this assistant turn if no advisor call yet
  const NUDGE_TEXT =
    "You have not consulted the advisor yet. If the task has a non-obvious " +
    "design decision or a failure mode you haven't ruled out, call advisor " +
    "now before committing to an approach.";
  const MAX_TURNS = 10; // agent loop cap

  function runYourTools(
    content: Juglow.Beta.Messages.BetaContentBlock[]
  ): Juglow.Beta.Messages.BetaToolResultBlockParam[] {
    // Ganti dengan dispatch alat Anda. Mengembalikan satu blok tool_result per blok tool_use.
    return content
      .filter((block) => block.type === "tool_use")
      .map((block) => ({
        type: "tool_result" as const,
        tool_use_id: block.id,
        content: "Replace with your tool output."
      }));
  }

  const tools: Juglow.Beta.Messages.BetaToolUnion[] = [
    { type: "advisor_20260301", name: "advisor", model: "haijun-opus-5" }
    // ... alat Anda yang lain
  ];
  const task = "Build a concurrent worker pool in Go with graceful shutdown.";
  const messages: Juglow.Beta.Messages.BetaMessageParam[] = [{ role: "user", content: task }];
  let advisorCalled = false;

  for (let turn = 1; turn <= MAX_TURNS; turn++) {
    const response = await client.beta.messages.create({
      model: "haijun-haiku-4-5",
      max_tokens: 4096,
      betas: ["advisor-tool-2026-03-01"],
      tools,
      messages
    });
    messages.push({ role: "assistant", content: response.content });
    advisorCalled =
      advisorCalled ||
      response.content.some(
        (block) => block.type === "server_tool_use" && block.name === "advisor"
      );
    if (response.stop_reason === "end_turn") {
      break;
    }
    if (response.stop_reason === "pause_turn") {
      continue; // server tool pending; re-send to let the API complete it
    }

    const results = runYourTools(response.content); // list of tool_result blocks
    if (results.length > 0) {
      messages.push({ role: "user", content: results });
    }
    // Lewati ini jika prompt sistem Anda sudah menginstruksikan model untuk memanggil secara hemat.
    if (turn === NUDGE_TURN - 1 && !advisorCalled) {
      messages.push({ role: "user", content: NUDGE_TEXT });
    }
  }
csharp
  using Juglow.Models.Beta.Messages;
  using Messages = Juglow.Models.Messages;

  var client = new JuglowClient();

  const int NudgeTurn = 2; // inject before this assistant turn if no advisor call yet
  const string NudgeText =
      "You have not consulted the advisor yet. If the task has a non-obvious "
      + "design decision or a failure mode you haven't ruled out, call advisor "
      + "now before committing to an approach.";
  const int MaxTurns = 10; // agent loop cap

  // Ganti dengan dispatch alat Anda. Mengembalikan satu blok tool_result per blok tool_use.
  List<BetaContentBlockParam> RunYourTools(IReadOnlyList<BetaContentBlock> content)
  {
      List<BetaContentBlockParam> results = [];
      foreach (var block in content)
      {
          if (block.TryPickToolUse(out var toolUse))
          {
              results.Add(new BetaToolResultBlockParam
              {
                  ToolUseID = toolUse.ID,
                  Content = "Replace with your tool output."
              });
          }
      }
      return results;
  }

  var tools = new BetaToolUnion[]
  {
      new BetaAdvisorTool20260301 { Model = Messages::Model.HaijunOpus5 }
      // ... alat Anda yang lain
  };
  var task = "Build a concurrent worker pool in Go with graceful shutdown.";
  var messages = new List<BetaMessageParam> { new() { Role = Role.User, Content = task } };
  var advisorCalled = false;

  for (var turn = 1; turn <= MaxTurns; turn++)
  {
      var response = await client.Beta.Messages.Create(new MessageCreateParams
      {
          Model = Messages::Model.HaijunHaiku4_5,
          MaxTokens = 4096,
          Tools = tools,
          Messages = messages,
          Betas = ["advisor-tool-2026-03-01"]
      });
      messages.Add(new BetaMessageParam
      {
          Role = Role.Assistant,
          Content = response.Content.Select(block => new BetaContentBlockParam(block.Json)).ToList()
      });
      advisorCalled =
          advisorCalled
          || response.Content.Any(block =>
              block.TryPickServerToolUse(out var serverToolUse)
              && serverToolUse.Name.Value() == Name.Advisor
          );
      if (response.StopReason == BetaStopReason.EndTurn)
      {
          break;
      }
      if (response.StopReason == BetaStopReason.PauseTurn)
      {
          continue; // server tool pending; re-send to let the API complete it
      }

      var results = RunYourTools(response.Content); // list of tool_result blocks
      if (results.Count > 0)
      {
          messages.Add(new BetaMessageParam { Role = Role.User, Content = results });
      }
      // Lewati ini jika prompt sistem Anda sudah menginstruksikan model untuk memanggil dengan hemat.
      if (turn == NudgeTurn - 1 && !advisorCalled)
      {
          messages.Add(new BetaMessageParam { Role = Role.User, Content = NudgeText });
      }
  }
go
  const (
  	nudgeTurn = 2 // inject before this assistant turn if no advisor call yet
  	nudgeText = "You have not consulted the advisor yet. If the task has a non-obvious " +
  		"design decision or a failure mode you haven't ruled out, call advisor " +
  		"now before committing to an approach."
  	maxTurns = 10 // agent loop cap
  )

  // Ganti dengan dispatch alat Anda. Mengembalikan satu blok tool_result per blok tool_use.
  func runYourTools(content []juglow.BetaContentBlockUnion) []juglow.BetaContentBlockParamUnion {
  	var results []juglow.BetaContentBlockParamUnion
  	for _, block := range content {
  		if block.Type == "tool_use" {
  			results = append(results, juglow.NewBetaToolResultBlock(block.ID, "Replace with your tool output.", false))
  		}
  	}
  	return results
  }

  func main() {
  	client := juglow.NewClient()

  	tools := []juglow.BetaToolUnionParam{
  		{OfAdvisorTool20260301: &juglow.BetaAdvisorTool20260301Param{
  			Model: juglow.ModelHaijunOpus5,
  		}},
  		// ... alat Anda yang lain
  	}
  	task := "Build a concurrent worker pool in Go with graceful shutdown."
  	messages := []juglow.BetaMessageParam{
  		juglow.NewBetaUserMessage(juglow.NewBetaTextBlock(task)),
  	}
  	advisorCalled := false

  	for turn := 1; turn <= maxTurns; turn++ {
  		response, err := client.Beta.Messages.New(context.TODO(), juglow.BetaMessageNewParams{
  			Model:     juglow.ModelHaijunHaiku4_5,
  			MaxTokens: 4096,
  			Tools:     tools,
  			Messages:  messages,
  			Betas: []juglow.JuglowBeta{
  				juglow.JuglowBetaAdvisorTool2026_03_01,
  			},
  		})
  		if err != nil {
  			log.Fatal(err)
  		}

  		messages = append(messages, response.ToParam())

  		for _, block := range response.Content {
  			if block.Type == "server_tool_use" && block.Name == "advisor" {
  				advisorCalled = true
  			}
  		}
  		if response.StopReason == juglow.BetaStopReasonEndTurn {
  			break
  		}
  		if response.StopReason == juglow.BetaStopReasonPauseTurn {
  			continue // server tool pending; re-send to let the API complete it
  		}

  		results := runYourTools(response.Content) // list of tool_result blocks
  		if len(results) > 0 {
  			messages = append(messages, juglow.BetaMessageParam{
  				Role:    juglow.BetaMessageParamRoleUser,
  				Content: results,
  			})
  		}
  		// Lewati ini jika prompt sistem Anda sudah meminta model untuk jarang memanggil alat.
  		if turn == nudgeTurn-1 && !advisorCalled {
  			messages = append(messages, juglow.NewBetaUserMessage(juglow.NewBetaTextBlock(nudgeText)))
  		}
  	}
  }
java
  import com.juglow.models.beta.messages.BetaAdvisorTool20260301;
  import com.juglow.models.beta.messages.BetaContentBlock;
  import com.juglow.models.beta.messages.BetaContentBlockParam;
  import com.juglow.models.beta.messages.BetaMessage;
  import com.juglow.models.beta.messages.BetaMessageParam;
  import com.juglow.models.beta.messages.BetaServerToolUseBlock;
  import com.juglow.models.beta.messages.BetaStopReason;
  import com.juglow.models.beta.messages.BetaToolResultBlockParam;
  import com.juglow.models.beta.messages.BetaToolUnion;
  import com.juglow.models.beta.messages.MessageCreateParams;
  import com.juglow.models.messages.Model;

  static final int NUDGE_TURN = 2; // inject before this assistant turn if no advisor call yet
  static final String NUDGE_TEXT =
      "You have not consulted the advisor yet. If the task has a non-obvious "
          + "design decision or a failure mode you haven't ruled out, call advisor "
          + "now before committing to an approach.";
  static final int MAX_TURNS = 10; // agent loop cap

  // Ganti dengan dispatch alat Anda. Mengembalikan satu blok tool_result per blok tool_use.
  List<BetaContentBlockParam> runYourTools(List<BetaContentBlock> content) {
      List<BetaContentBlockParam> results = new ArrayList<>();
      for (BetaContentBlock block : content) {
          if (block.isToolUse()) {
              results.add(BetaContentBlockParam.ofToolResult(
                  BetaToolResultBlockParam.builder()
                      .toolUseId(block.asToolUse().id())
                      .content("Replace with your tool output.")
                      .build()));
          }
      }
      return results;
  }

  void main() {
      JuglowClient client = JuglowOkHttpClient.fromEnv();

      List<BetaToolUnion> tools = List.of(
          BetaToolUnion.ofAdvisorTool20260301(
              BetaAdvisorTool20260301.builder().model(Model.HAIJUN_OPUS_5).build())
          // ... alat Anda yang lain
      );
      String task = "Build a concurrent worker pool in Go with graceful shutdown.";
      List<BetaMessageParam> messages = new ArrayList<>();
      messages.add(BetaMessageParam.builder()
          .role(BetaMessageParam.Role.USER)
          .content(task)
          .build());
      boolean advisorCalled = false;

      for (int turn = 1; turn <= MAX_TURNS; turn++) {
          BetaMessage response = client.beta().messages().create(MessageCreateParams.builder()
              .model(Model.HAIJUN_HAIKU_4_5)
              .maxTokens(4096L)
              .tools(tools)
              .messages(messages)
              .addBeta("advisor-tool-2026-03-01")
              .build());
          messages.add(BetaMessageParam.builder()
              .role(BetaMessageParam.Role.ASSISTANT)
              .contentOfBetaContentBlockParams(
                  response.content().stream().map(BetaContentBlock::toParam).toList())
              .build());
          advisorCalled = advisorCalled
              || response.content().stream().anyMatch(block ->
                  block.isServerToolUse()
                      && block.asServerToolUse().name().equals(BetaServerToolUseBlock.Name.ADVISOR));
          BetaStopReason stopReason = response.stopReason().orElse(null);
          if (BetaStopReason.END_TURN.equals(stopReason)) {
              break;
          }
          if (BetaStopReason.PAUSE_TURN.equals(stopReason)) {
              continue; // server tool pending; re-send to let the API complete it
          }

          List<BetaContentBlockParam> results = runYourTools(response.content()); // list of tool_result blocks
          if (!results.isEmpty()) {
              messages.add(BetaMessageParam.builder()
                  .role(BetaMessageParam.Role.USER)
                  .contentOfBetaContentBlockParams(results)
                  .build());
          }
          // Lewati ini jika prompt sistem Anda sudah menginstruksikan model untuk memanggil secara hemat.
          if (turn == NUDGE_TURN - 1 && !advisorCalled) {
              messages.add(BetaMessageParam.builder()
                  .role(BetaMessageParam.Role.USER)
                  .content(NUDGE_TEXT)
                  .build());
          }
      }
  }
php
  $client = new Client();

  const NUDGE_TURN = 2; // inject before this assistant turn if no advisor call yet
  const NUDGE_TEXT = "You have not consulted the advisor yet. If the task has a non-obvious "
      . "design decision or a failure mode you haven't ruled out, call advisor "
      . "now before committing to an approach.";
  const MAX_TURNS = 10; // agent loop cap

  // Ganti dengan dispatch alat Anda. Mengembalikan satu blok tool_result per blok tool_use.
  function runYourTools(array $content): array
  {
      $results = [];
      foreach ($content as $block) {
          if ($block->type === 'tool_use') {
              $results[] = [
                  'type' => 'tool_result',
                  'tool_use_id' => $block->id,
                  'content' => 'Replace with your tool output.',
              ];
          }
      }
      return $results;
  }

  $tools = [
      ['type' => 'advisor_20260301', 'name' => 'advisor', 'model' => 'haijun-opus-5'],
      // ... alat Anda yang lain
  ];
  $task = 'Build a concurrent worker pool in Go with graceful shutdown.';
  $messages = [['role' => 'user', 'content' => $task]];
  $advisorCalled = false;

  for ($turn = 1; $turn <= MAX_TURNS; $turn++) {
      $response = $client->beta->messages->create(
          maxTokens: 4096,
          messages: $messages,
          model: 'haijun-haiku-4-5',
          tools: $tools,
          betas: ['advisor-tool-2026-03-01'],
      );
      $messages[] = ['role' => 'assistant', 'content' => $response->content];
      foreach ($response->content as $block) {
          if ($block->type === 'server_tool_use' && $block->name === 'advisor') {
              $advisorCalled = true;
          }
      }
      if ($response->stopReason === 'end_turn') {
          break;
      }
      if ($response->stopReason === 'pause_turn') {
          continue; // server tool pending; re-send to let the API complete it
      }

      $results = runYourTools($response->content); // list of tool_result blocks
      if ($results !== []) {
          $messages[] = ['role' => 'user', 'content' => $results];
      }
      // Lewati ini jika prompt sistem Anda sudah menginstruksikan model untuk memanggil secara hemat.
      if ($turn === NUDGE_TURN - 1 && !$advisorCalled) {
          $messages[] = ['role' => 'user', 'content' => NUDGE_TEXT];
      }
  }
ruby
  client = Juglow::Client.new

  NUDGE_TURN = 2 # inject before this assistant turn if no advisor call yet
  NUDGE_TEXT =
    "You have not consulted the advisor yet. If the task has a non-obvious " \
    "design decision or a failure mode you haven't ruled out, call advisor " \
    "now before committing to an approach."
  MAX_TURNS = 10 # agent loop cap

  # Ganti dengan dispatch alat Anda. Mengembalikan satu blok tool_result per blok tool_use.
  def run_your_tools(content)
    content.filter_map do |block|
      next unless block.type == :tool_use
      { type: "tool_result", tool_use_id: block.id, content: "Replace with your tool output." }
    end
  end

  tools = [
    { type: "advisor_20260301", name: "advisor", model: "haijun-opus-5" }
    # ... alat Anda yang lain
  ]
  task = "Build a concurrent worker pool in Go with graceful shutdown."
  messages = [{ role: "user", content: task }]
  advisor_called = false

  (1..MAX_TURNS).each do |turn|
    response = client.beta.messages.create(
      model: "haijun-haiku-4-5",
      max_tokens: 4096,
      tools: tools,
      messages: messages,
      betas: ["advisor-tool-2026-03-01"]
    )
    messages << { role: "assistant", content: response.content }
    advisor_called ||= response.content.any? do |block|
      block.type == :server_tool_use && block.name == :advisor
    end
    break if response.stop_reason == :end_turn
    next if response.stop_reason == :pause_turn # server tool pending; re-send to let the API complete it

    results = run_your_tools(response.content) # list of tool_result blocks
    messages << { role: "user", content: results } unless results.empty?
    # Lewati ini jika prompt sistem Anda sudah menginstruksikan model untuk memanggil dengan hemat.
    messages << { role: "user", content: NUDGE_TEXT } if turn == NUDGE_TURN - 1 && !advisor_called
  end

Tambahkan dorongan sebagai pesan pengguna tersendiri setelah hasil alat, bukan sebagai blok saudara dalam pesan yang sama. Pesan pengguna berturut-turut adalah valid. Dalam pengujian Juglow pada executor Haiku dan Sonnet, keduanya berperilaku setara dengan blok saudara. Bentuk pesan terpisah juga menjaga pengingat tetap jelas terpisah dari output alat.

Trade-off: Dorongan meningkatkan tingkat panggilan, yang dapat mendorong tugas yang sangat sederhana ke konsultasi yang tidak perlu. Jika beban kerja Anda mencampur tugas sederhana dan kompleks, pertimbangkan untuk menaikkan NUDGE_TURN ke 3 agar tugas dua giliran selesai sebelum dorongan dipicu, atau kondisikan dorongan pada sinyal kompleksitas tugas yang sudah Anda hitung. Jika prompt sistem Anda sudah berisi bahasa pengekangan ("simpan advisor untuk ketidakpastian yang sesungguhnya"), lewati dorongan sepenuhnya, karena kedua instruksi tersebut bertentangan.

Dorongan teks biasa sangat menonjol pada executor Haiku dan Sonnet: 74 persen (Sonnet) hingga 98 persen (Haiku) dari percobaan yang diberi dorongan dalam pengujian Juglow langsung memanggil advisor pada giliran 2. Jika itu terjadi sebelum executor Anda membaca masalah atau mengumpulkan konteks, panggilan advisor yang dihasilkan minim konteks dan dapat menggeser panggilan berikutnya yang waktunya lebih tepat. Ukur giliran panggilan pertama baseline executor Anda sebelum menambahkan dorongan. Jika executor sudah memanggil advisor secara andal dan panggilan pertamanya biasanya terjadi pada giliran N, tetapkan NUDGE_TURN lebih besar dari N. Dalam pengujian Juglow, dorongan giliran 2 pada beban kerja di mana panggilan pertama baseline adalah giliran 7 atau lebih berkorelasi dengan penurunan kinerja tugas 3 hingga 4 poin persentase. Pada beban kerja browse di mana tingkat panggilan baseline adalah 86 persen, dorongan yang sama meningkatkan keterlibatan tanpa biaya kinerja tugas.

Untuk memaksa konsultasi pada permintaan tertentu alih-alih memberi dorongan, tetapkan tool_choice ke {"type": "tool", "name": "advisor"}, dengan tunduk pada batasan dalam Memaksa penggunaan alat. Memaksa penggunaan alat tidak dapat digabungkan dengan pemikiran diperpanjang manual (thinking: {type: "enabled"}): API mengembalikan 400 invalid_request_error jika Anda mengaktifkan keduanya. Adaptive thinking mendukung penggunaan alat yang dipaksa. Executor Haijun Fable 5.1 dan Haijun Mythos 5.1 menolak tipe tool_choice tool dan any, jadi gunakan dorongan prompt pada model tersebut.

Streaming

Sub-inferensi advisor tidak melakukan streaming. Stream executor berhenti sejenak saat advisor berjalan; kemudian hasil lengkap tiba dalam satu event.

Blok server_tool_use dengan name: "advisor" menandakan bahwa panggilan advisor dimulai. Jeda dimulai saat blok tersebut ditutup (content_block_stop). Selama jeda, stream senyap kecuali keepalive ping SSE standar yang dikeluarkan kira-kira setiap 30 detik. Panggilan advisor singkat mungkin tidak menampilkan ping.

Saat advisor selesai, advisor_tool_result tiba dalam bentuk lengkap dalam satu event content_block_start (tanpa delta). Output executor kemudian melanjutkan streaming.

Event message_delta menyusul dengan array usage.iterations yang diperbarui yang mencerminkan jumlah token advisor.

Penggunaan dan penagihan

Panggilan advisor berjalan sebagai sub-inferensi terpisah yang ditagih dengan tarif model advisor. Penggunaan dilaporkan dalam array usage.iterations[]:

json
{
  "usage": {
    "input_tokens": 1760,
    "cache_read_input_tokens": 412,
    "cache_creation_input_tokens": 0,
    "output_tokens": 531,
    "iterations": [
      {
        "type": "message",
        "input_tokens": 412,
        "cache_read_input_tokens": 0,
        "cache_creation_input_tokens": 0,
        "output_tokens": 89
      },
      {
        "type": "advisor_message",
        "model": "haijun-opus-5",
        "input_tokens": 823,
        "cache_read_input_tokens": 0,
        "cache_creation_input_tokens": 0,
        "output_tokens": 1612
      },
      {
        "type": "message",
        "input_tokens": 1348,
        "cache_read_input_tokens": 412,
        "cache_creation_input_tokens": 0,
        "output_tokens": 442
      }
    ]
  }
}

Field usage tingkat atas hanya mencerminkan token executor. Token advisor tidak digabungkan ke dalam total tingkat atas karena ditagih dengan tarif berbeda. Iterasi dengan type: "advisor_message" ditagih dengan tarif model advisor, dan iterasi dengan type: "message" ditagih dengan tarif model executor.

Setiap field usage tingkat atas adalah jumlah field tersebut di seluruh iterasi executor, termasuk input_tokens, output_tokens, dan cache_read_input_tokens. Karena setiap iterasi executor mengirim ulang percakapan yang terus bertambah, input iterasi berikutnya mencakup output iterasi sebelumnya, sehingga jumlah input_tokens melebihi ukuran prompt tunggal mana pun. Gunakan usage.iterations untuk rincian lengkap per iterasi saat membangun logika pelacakan biaya.

Output advisor biasanya 400 hingga 700 token teks, atau 1.400 hingga 1.800 token total termasuk thinking. Penghematan biaya berasal dari advisor yang tidak menghasilkan output akhir lengkap Anda. Executor melakukannya dengan tarifnya yang lebih rendah.

max_tokens tingkat atas hanya berlaku untuk output executor. Ini tidak membatasi token sub-inferensi advisor. Untuk membatasi output advisor secara langsung, tetapkan max_tokens pada definisi alat. Token advisor juga tidak diambil dari task budget apa pun yang diterapkan pada executor.

Priority Tier berlaku untuk setiap model secara independen. Komitmen Priority Tier pada model executor tidak meluas ke advisor. Panggilan advisor berjalan pada Priority Tier hanya jika organisasi Anda juga memiliki komitmen pada model advisor.

Caching prompt advisor

Ada dua lapisan caching yang independen.

Caching sisi executor

Blok advisor_tool_result dapat di-cache seperti blok konten lainnya. Breakpoint cache_control yang ditempatkan setelahnya pada giliran berikutnya akan hit. Prompt executor selalu berisi saran plaintext terlepas dari apakah klien Anda menerima text atau encrypted_content, sehingga perilaku caching identik untuk kedua varian hasil.

Caching sisi advisor

Tetapkan caching pada definisi alat untuk mengaktifkan "prompt caching" (caching prompt) untuk transkrip advisor sendiri di seluruh panggilan dalam percakapan yang sama:

python
  tools = [
      {
          "type": "advisor_20260301",
          "name": "advisor",
          "model": "haijun-opus-5",
          "caching": {"type": "ephemeral", "ttl": "5m"},
      }
  ]
typescript
  const tools: Juglow.Beta.Messages.BetaToolUnion[] = [
    {
      type: "advisor_20260301",
      name: "advisor",
      model: "haijun-opus-5",
      caching: { type: "ephemeral", ttl: "5m" }
    }
  ];
csharp
  using Juglow.Models.Beta.Messages;
  using Messages = Juglow.Models.Messages;

  var tools = new BetaToolUnion[]
  {
      new BetaAdvisorTool20260301
      {
          Model = Messages::Model.HaijunOpus5,
          Caching = new BetaCacheControlEphemeral { Ttl = Ttl.Ttl5m }
      }
  };
go
  tools := []juglow.BetaToolUnionParam{
  	{OfAdvisorTool20260301: &juglow.BetaAdvisorTool20260301Param{
  		Model:   juglow.ModelHaijunOpus5,
  		Caching: juglow.BetaCacheControlEphemeralParam{TTL: juglow.BetaCacheControlEphemeralTTLTTL5m},
  	}},
  }
java
  import com.juglow.models.beta.messages.BetaAdvisorTool20260301;
  import com.juglow.models.beta.messages.BetaCacheControlEphemeral;
  import com.juglow.models.beta.messages.BetaToolUnion;
  import com.juglow.models.messages.Model;

  List<BetaToolUnion> tools = List.of(
      BetaToolUnion.ofAdvisorTool20260301(BetaAdvisorTool20260301.builder()
          .model(Model.HAIJUN_OPUS_5)
          .caching(BetaCacheControlEphemeral.builder()
              .ttl(BetaCacheControlEphemeral.Ttl.TTL_5M)
              .build())
          .build()));
php
  $tools = [
      [
          'type' => 'advisor_20260301',
          'name' => 'advisor',
          'model' => 'haijun-opus-5',
          'caching' => ['type' => 'ephemeral', 'ttl' => '5m'],
      ],
  ];
ruby
  tools = [
    {
      type: "advisor_20260301",
      name: "advisor",
      model: "haijun-opus-5",
      caching: { type: "ephemeral", ttl: "5m" }
    }
  ]

Prompt advisor pada panggilan ke-N adalah prompt panggilan ke-(N-1) dengan satu segmen tambahan, sehingga prefiksnya stabil di seluruh panggilan. Dengan caching diaktifkan, setiap panggilan advisor menulis entri cache, dan panggilan berikutnya membaca hingga titik tersebut dan hanya membayar deltanya. Anda akan melihat cache_read_input_tokens menjadi bukan nol pada iterasi advisor_message kedua dan selanjutnya.

Kapan mengaktifkannya: Penulisan cache lebih mahal daripada penghematan dari pembacaan ketika advisor dipanggil dua kali atau kurang per percakapan. Caching mencapai titik impas pada kira-kira tiga panggilan advisor dan membaik dari sana. Aktifkan untuk loop agen yang panjang, dan biarkan nonaktif untuk tugas singkat.

Jaga konsistensinya: Tetapkan caching sekali dan biarkan untuk seluruh percakapan. Mengaktifkan dan menonaktifkannya di tengah percakapan menyebabkan cache miss.

Warning: clear_thinking dengan nilai keep selain "all" menggeser transkrip kutipan advisor setiap giliran, menyebabkan cache miss di sisi advisor. Ini hanya degradasi biaya. Kualitas saran tidak terpengaruh. Saat pemikiran diperpanjang diaktifkan tanpa konfigurasi clear_thinking eksplisit, API secara default menggunakan keep: {type: "thinking_turns", value: 1}, yang memicu perilaku ini (default pada model Opus/Sonnet sebelumnya dan semua model Haiku, sedangkan pada Opus 4.5+ dan Sonnet 4.6+ defaultnya adalah mempertahankan semua giliran). Tetapkan keep: "all" untuk menjaga stabilitas cache advisor.

Menggabungkan dengan alat lain

Alat advisor dapat dikombinasikan dengan alat sisi server dan sisi klien lainnya. Tambahkan semuanya ke array tools yang sama:

python
  tools = [
      {
          "type": "web_search_20250305",
          "name": "web_search",
          "max_uses": 5,
      },
      {
          "type": "advisor_20260301",
          "name": "advisor",
          "model": "haijun-opus-5",
      },
      {
          "name": "run_bash",
          "description": "Run a bash command",
          "input_schema": {
              "type": "object",
              "properties": {"command": {"type": "string"}},
          },
      },
  ]
typescript
  const tools: Juglow.Beta.Messages.BetaToolUnion[] = [
    {
      type: "web_search_20250305",
      name: "web_search",
      max_uses: 5
    },
    {
      type: "advisor_20260301",
      name: "advisor",
      model: "haijun-opus-5"
    },
    {
      name: "run_bash",
      description: "Run a bash command",
      input_schema: {
        type: "object",
        properties: { command: { type: "string" } }
      }
    }
  ];
csharp
  using System.Text.Json;
  using Juglow.Models.Beta.Messages;
  using Messages = Juglow.Models.Messages;

  var tools = new BetaToolUnion[]
  {
      new BetaWebSearchTool20250305 { MaxUses = 5 },
      new BetaAdvisorTool20260301 { Model = Messages::Model.HaijunOpus5 },
      new BetaTool
      {
          Name = "run_bash",
          Description = "Run a bash command",
          InputSchema = new()
          {
              Properties = new Dictionary<string, JsonElement>
              {
                  ["command"] = JsonSerializer.SerializeToElement(new { type = "string" })
              }
          }
      }
  };
go
  tools := []juglow.BetaToolUnionParam{
  	{OfWebSearchTool20250305: &juglow.BetaWebSearchTool20250305Param{
  		MaxUses: juglow.Int(5),
  	}},
  	{OfAdvisorTool20260301: &juglow.BetaAdvisorTool20260301Param{
  		Model: juglow.ModelHaijunOpus5,
  	}},
  	{OfTool: &juglow.BetaToolParam{
  		Name:        "run_bash",
  		Description: juglow.String("Run a bash command"),
  		InputSchema: juglow.BetaToolInputSchemaParam{
  			Properties: map[string]any{
  				"command": map[string]any{"type": "string"},
  			},
  		},
  	}},
  }
java
  import com.juglow.core.JsonValue;
  import com.juglow.models.beta.messages.BetaAdvisorTool20260301;
  import com.juglow.models.beta.messages.BetaTool;
  import com.juglow.models.beta.messages.BetaToolUnion;
  import com.juglow.models.beta.messages.BetaWebSearchTool20250305;
  import com.juglow.models.messages.Model;

  List<BetaToolUnion> tools = List.of(
      BetaToolUnion.ofWebSearchTool20250305(BetaWebSearchTool20250305.builder()
          .maxUses(5L)
          .build()),
      BetaToolUnion.ofAdvisorTool20260301(BetaAdvisorTool20260301.builder()
          .model(Model.HAIJUN_OPUS_5)
          .build()),
      BetaToolUnion.ofBetaTool(BetaTool.builder()
          .name("run_bash")
          .description("Run a bash command")
          .inputSchema(BetaTool.InputSchema.builder()
              .properties(JsonValue.from(Map.of(
                  "command", Map.of("type", "string"))))
              .build())
          .build()));
php
  $tools = [
      [
          'type' => 'web_search_20250305',
          'name' => 'web_search',
          'max_uses' => 5,
      ],
      [
          'type' => 'advisor_20260301',
          'name' => 'advisor',
          'model' => 'haijun-opus-5',
      ],
      [
          'name' => 'run_bash',
          'description' => 'Run a bash command',
          'input_schema' => [
              'type' => 'object',
              'properties' => ['command' => ['type' => 'string']],
          ],
      ],
  ];
ruby
  tools = [
    {
      type: "web_search_20250305",
      name: "web_search",
      max_uses: 5
    },
    {
      type: "advisor_20260301",
      name: "advisor",
      model: "haijun-opus-5"
    },
    {
      name: "run_bash",
      description: "Run a bash command",
      input_schema: {
        type: "object",
        properties: { command: { type: "string" } }
      }
    }
  ]

Executor dapat mencari di web, memanggil advisor, dan menggunakan alat kustom Anda dalam giliran yang sama. Rencana advisor dapat menginformasikan alat mana yang akan digunakan executor selanjutnya.

FiturInteraksi
Pemrosesan batchDidukung. usage.iterations dilaporkan per item.
Penghitungan tokenHanya mengembalikan token input iterasi pertama executor. Untuk perkiraan kasar advisor, panggil count_tokens dengan model ditetapkan ke model advisor dan pesan yang sama.
Pengeditan konteksclear_tool_uses tidak sepenuhnya kompatibel dengan blok alat advisor. Dengan clear_thinking, lihat peringatan caching sebelumnya.
pause_turnPanggilan advisor yang menggantung mengakhiri respons dengan stop_reason: "pause_turn" dan blok server_tool_use tanpa hasil ketika tidak ada blok tool_use klien yang menunggu hasil Anda dalam giliran yang sama. Advisor berjalan saat dilanjutkan. Jika executor juga memanggil salah satu alat Anda dalam giliran tersebut, respons berakhir dengan stop_reason: "tool_use", dan panggilan advisor yang tertunda berjalan di awal permintaan berikutnya, setelah Anda mengirim blok tool_result. Lihat Melanjutkan giliran yang dijeda, Mencampur alat server dan alat klien dalam satu giliran, dan Alat server.

Praktik terbaik

Prompting untuk tugas coding dan agen

Alat advisor dilengkapi dengan deskripsi bawaan yang mendorong executor untuk memanggilnya di dekat awal tugas kompleks dan saat menemui kesulitan. Untuk tugas riset, biasanya tidak diperlukan prompting tambahan.

Pada tugas coding dan agen, advisor menghasilkan kecerdasan lebih tinggi dengan biaya serupa ketika mengurangi total panggilan alat dan panjang percakapan. Dua waktu pemanggilan mendorong peningkatan ini:

  1. Panggilan advisor pertama yang lebih awal, setelah beberapa pembacaan eksploratif ada dalam transkrip.
  1. Untuk tugas sulit, panggilan advisor terakhir setelah penulisan file dan output pengujian ada dalam transkrip.

Jika agen Anda mengekspos alat lain yang mirip perencana (misalnya, alat daftar todo), arahkan model untuk memanggil advisor sebelum alat-alat tersebut sehingga rencana advisor mengalir ke dalamnya. Prompt sistem yang disarankan memperkuat pola panggilan awal. Tambahkan kalimat pengarah Anda sendiri yang menunjuk ke alat perencana mana pun yang diekspos agen Anda.

Prompt sistem yang disarankan untuk tugas coding

Tanpa pengarahan prompt sistem, executor cenderung kurang memanggil advisor di beberapa domain, khususnya tugas coding. Untuk tugas coding di mana Anda menginginkan waktu advisor yang konsisten dan sekitar dua hingga tiga panggilan untuk setiap tugas, tambahkan blok berikut di awal prompt sistem executor Anda sebelum kalimat lain yang menyebutkan advisor.

Panduan waktu:

text
You have access to an `advisor` tool backed by a stronger reviewer model. It takes NO parameters — when you call advisor(), your entire conversation history is automatically forwarded. They see the task, every tool call you've made, every result you've seen.

Call advisor BEFORE substantive work — before writing, before committing to an interpretation, before building on an assumption. If the task requires orientation first (finding files, fetching a source, seeing what's there), do that, then call advisor. Orientation is not substantive work. Writing, editing, and declaring an answer are.

Also call advisor:
- When you believe the task is complete. BEFORE this call, make your deliverable durable: write the file, save the result, commit the change. The advisor call takes time; if the session ends during it, a durable result persists and an unwritten one doesn't.
- When stuck — errors recurring, approach not converging, results that don't fit.
- When considering a change of approach.

On tasks longer than a few steps, call advisor at least once before committing to an approach and once before declaring done. On short reactive tasks where the next action is dictated by tool output you just read, you don't need to keep calling — the advisor adds most of its value on the first call, before the approach crystallizes.

Bagaimana executor harus memperlakukan saran (tempatkan langsung setelah blok waktu):

text
Give the advice serious weight. If you follow a step and it fails empirically, or you have primary-source evidence that contradicts a specific claim (the file says X, the paper states Y), adapt. A passing self-test is not evidence the advice is wrong — it's evidence your test doesn't check what the advice is checking.

If you've already retrieved data pointing one way and the advisor points another: don't silently switch. Surface the conflict in one more advisor call — "I found X, you suggest Y, which constraint breaks the tie?" The advisor saw your evidence but may have underweighted it; a reconcile call is cheaper than committing to the wrong branch.

Prompt sistem alternatif untuk Haiku pada beban kerja coding

Haijun Haiku 4.5 menerapkan panduan advisor default secara konservatif. Itu menjaga tingkat panggilannya tetap rendah secara tepat pada beban kerja riset dan pencarian tetapi mengorbankan kualitas pada beban kerja coding, di mana konsultasi advisor awal secara andal sepadan dengan biayanya. Pada benchmark coding internal, varian dekat dari blok berikut (pengecualian read-only dalam Hard rule ditambahkan setelah pengukuran) meningkatkan tingkat kelulusan Haiku sekitar 7,5 poin persentase di atas default bawaan.

Gunakan blok ini sebagai pengganti blok waktu dan saran sebelumnya ketika executor Haiku Anda menjalankan beban kerja yang didominasi coding atau tugas penulisan:

text
Consult a stronger reviewer who sees your full conversation transcript.

No parameters. When you call advisor(), your entire history -- task, every tool call and result, your reasoning -- is automatically forwarded. The advisor sees exactly what you've done.

Call advisor BEFORE substantive work -- before writing, before committing to an interpretation, before building on an assumption. If the task requires orientation first (finding files, fetching a source, seeing what's there), do that, then call advisor. Orientation is not substantive work. Writing, editing, and declaring an answer are.

Also call advisor:
- When you believe the task is complete. BEFORE this call, make your deliverable durable: write the file, save the result, commit the change. The advisor call takes time; if the session ends during it, a durable result persists and an unwritten one doesn't.
- When stuck -- errors recurring, approach not converging, results that don't fit.
- When considering a change of approach.

On tasks longer than a few steps, call advisor at least once before committing to an approach and once before declaring done. On short reactive tasks where the next action is dictated by tool output you just read, you don't need to keep calling -- the advisor adds most of its value on the first call, before the approach crystallizes.

Give the advice serious weight. If you follow a step and it fails empirically, or you have primary-source evidence that contradicts a specific claim (the file says X, the paper states Y), adapt. A passing self-test is not evidence the advice is wrong -- it's evidence your test doesn't check what the advice is checking.

If you've already retrieved data pointing one way and the advisor points another: don't silently switch. Surface the conflict in one more advisor call -- "I found X, you suggest Y, which constraint breaks the tie?" The advisor saw your evidence but may have underweighted it; a reconcile call is cheaper than committing to the wrong branch.

Call advisor for design, architecture, and risk questions where you won't touch a file. If your response would be analysis or a recommendation with no other tool calls, call advisor first -- that judgment call is exactly where a second opinion is highest-value.

Hard rule: your first write_file, edit_file, or state-changing bash call on a task must be preceded by an advisor call in the same or an earlier turn. Read-only orientation commands (ls, cat, grep, find) are not state-changing. This is a checkpoint, not a difficulty judgment. It applies to one-line edits too.

Catatan: Pada benchmark pemahaman browse internal (n = 1.266), varian dekat dari blok ini mengorbankan sekitar 4 poin persentase akurasi relatif terhadap default bawaan. Jika beban kerja Anda mencampur coding dengan pencarian atau pengambilan yang substansial, tetap gunakan blok yang disarankan, atau kondisikan penggantian pada sinyal jenis beban kerja yang sudah Anda hitung.

Meningkatkan panggilan advisor pada executor Opus

Executor Opus biasanya memanggil advisor dengan tingkat yang tepat tanpa prompting tambahan. Jika executor Opus Anda kurang memanggil pada beban kerja Anda, tambahkan checkpoint berikut ke prompt sistem Anda:

text
Call advisor for design, architecture, and risk questions where you won't touch a file. If your response would be analysis or a recommendation with no other tool calls, call advisor first. That judgment call is exactly where a second opinion is highest-value. (This does not apply to simple factual lookups or arithmetic; those you answer directly.)

Hard rule: your first write_file, edit_file, or state-changing bash call on a task must be preceded by an advisor call in the same or an earlier turn. Read-only orientation commands (ls, cat, grep, find) are not state-changing. This is a checkpoint, not a difficulty judgment. It applies to one-line edits too.

Catatan: Dalam pengujian Juglow, varian dekat dari blok ini (pengecualian read-only dalam Hard rule ditambahkan setelah pengukuran) meningkatkan tingkat kelulusan pada tugas yang kurang memanggil sekitar 7 hingga 10 poin persentase tetapi menyebabkan Opus terlalu sering memanggil pada tugas yang tindakan pertamanya tidak memerlukan perencanaan. Efek bersihnya kira-kira datar pada beban kerja campuran. Hanya tambahkan jika Anda telah mengamati Opus melewatkan advisor pada tugas di mana konsultasi akan membantu. Jangan tambahkan sebagai default.

Memangkas panjang output advisor

Output advisor adalah pendorong biaya terbesar advisor, dan max_tokens tingkat atas tidak membatasinya. Advisor melihat prompt sistem Anda dan pesan pengguna Anda sebagai konteks kutipan tentang tugas executor, sehingga instruksi yang ditujukan langsung kepada advisor diikuti jauh lebih andal daripada deskripsi orang ketiga. Penempatan paling efektif yang diuji Juglow adalah sebuah baris dalam pesan pengguna:

text
(Advisor: please keep your guidance under 80 words — I need a focused starting point, not a comprehensive plan.)

Baris ini dapat ditambahkan di awal secara programatis oleh framework agen Anda sebelum mengirim permintaan. Batas ini adalah batasan lunak. Advisor sesekali melebihinya, jadi mintalah sekitar 80 persen dari batas atas Anda yang sebenarnya.

Note: Dalam pengujian Juglow, baris ini juga meningkatkan seberapa sering executor berkonsultasi dengan advisor, tetapi efek bersihnya tetap total biaya yang lebih rendah (lebih banyak konsultasi, masing-masing lebih singkat).

Pasangkan pendekatan ini dengan panduan waktu dalam Prompt sistem yang disarankan untuk tugas coding (atau blok Haiku alternatif jika Anda menggantinya) untuk tradeoff biaya-versus-kualitas yang paling kuat. Untuk batas atas keras alih-alih permintaan lunak, lihat Membatasi output advisor.

Membatasi output advisor

Tetapkan max_tokens pada definisi alat untuk membatasi total output advisor (thinking ditambah teks) per panggilan:

python
  tools = [
      {
          "type": "advisor_20260301",
          "name": "advisor",
          "model": "haijun-opus-5",
          "max_tokens": 2048,
      }
  ]
typescript
  const tools: Juglow.Beta.Messages.BetaToolUnion[] = [
    {
      type: "advisor_20260301",
      name: "advisor",
      model: "haijun-opus-5",
      max_tokens: 2048
    }
  ];
csharp
  using Juglow.Models.Beta.Messages;
  using Messages = Juglow.Models.Messages;

  var tools = new BetaToolUnion[]
  {
      new BetaAdvisorTool20260301
      {
          Model = Messages::Model.HaijunOpus5,
          MaxTokens = 2048
      }
  };
go
  tools := []juglow.BetaToolUnionParam{
  	{OfAdvisorTool20260301: &juglow.BetaAdvisorTool20260301Param{
  		Model:     juglow.ModelHaijunOpus5,
  		MaxTokens: juglow.Int(2048),
  	}},
  }
java
  import com.juglow.models.beta.messages.BetaAdvisorTool20260301;
  import com.juglow.models.beta.messages.BetaToolUnion;
  import com.juglow.models.messages.Model;

  List<BetaToolUnion> tools = List.of(
      BetaToolUnion.ofAdvisorTool20260301(BetaAdvisorTool20260301.builder()
          .model(Model.HAIJUN_OPUS_5)
          .maxTokens(2048L)
          .build()));
php
  $tools = [
      [
          'type' => 'advisor_20260301',
          'name' => 'advisor',
          'model' => 'haijun-opus-5',
          'max_tokens' => 2048,
      ],
  ];
ruby
  tools = [
    {
      type: "advisor_20260301",
      name: "advisor",
      model: "haijun-opus-5",
      max_tokens: 2048
    }
  ]

Nilai minimumnya adalah 1024. Menetapkan max_tokens di atas batas output model advisor sendiri mengembalikan error 400. Batas ini berlaku untuk setiap panggilan advisor secara independen dan tidak dibagi di seluruh panggilan dalam permintaan yang sama.

Ini bukan sekadar pemotongan keras. Server juga memberikan kepada advisor anggaran token yang tersisa, sehingga advisor membentuk responsnya agar sesuai.

Titik awal yang direkomendasikan: max_tokens: 2048. Dalam pengujian Juglow pada benchmark penalaran sulit (n = 40 per konfigurasi), ini mengurangi rata-rata output advisor sekitar 7x dibandingkan dengan membiarkan batas tidak ditetapkan, dengan pemotongan hampir nol dan tanpa degradasi kualitas yang terdeteksi. Nilai minimum 1024 mengurangi output sekitar 10x tetapi memotong sekitar 10 persen panggilan. Perbedaan akurasi di seluruh konfigurasi berada dalam rentang noise pada ukuran sampel ini. Validasi pada beban kerja Anda sendiri.

max_tokensRata-rata token output advisorPanggilan terpotong
tidak ditetapkan\~4.200 hingga 5.900n/a
2048\~630 hingga 840\~0%
1024\~370 hingga 480\~10%

Tugas penalaran sulit memunculkan output advisor yang jauh lebih panjang daripada 1.400 hingga 1.800 token tipikal yang dikutip sebelumnya untuk beban kerja yang lebih ringan. Gunakan tabel ini untuk mengukur rasio penghematan, bukan sebagai baseline universal untuk output advisor.

Saat advisor mencapai batas, blok hasil membawa stop_reason: "max_tokens" pada kedua varian hasil, model advisor mana pun yang Anda gunakan. Gunakan stop_reason untuk mendeteksi saran yang terpotong dan memutuskan apakah akan menaikkan batas atau membiarkan executor melanjutkan dengan panduan parsial. API juga menambahkan [Advisor output truncated at max_tokens=2048.] (menyebutkan batas Anda) ke teks saran, sehingga executor melihat pemotongan dalam konteksnya sendiri; dengan advisor advisor_result plaintext, penanda tersebut juga terlihat oleh klien Anda. Kedua sinyal hanya muncul saat Anda menetapkan max_tokens pada definisi alat.

json
{
  "type": "advisor_tool_result",
  "tool_use_id": "srvtoolu_abc123",
  "content": {
    "type": "advisor_redacted_result",
    "encrypted_content": "EqQBCkYIBRgCIiQ3YTAwMjY1Mi1mZjM5LTQ1NGUtODgxNC1kNjNjNTk1ZWI3Y...",
    "stop_reason": "max_tokens"
  }
}

Periksa output_tokens pada entri advisor_message yang sesuai dalam usage.iterations untuk melihat seberapa dekat setiap panggilan dengan batasnya.

Dibandingkan dengan pendekatan berbasis prompt, max_tokens adalah batas atas keras alih-alih permintaan lunak. Gunakan max_tokens saat Anda memerlukan batas terjamin untuk biaya atau latensi. Gunakan pendekatan berbasis prompt (atau keduanya bersama-sama) saat Anda ingin condong ke arah keringkasan tanpa risiko terpotong di tengah pemikiran.

Memadukan dengan pengaturan effort

Untuk tugas pengodean, memadukan eksekutor Sonnet pada effort (upaya) tingkat medium dengan advisor Opus menghasilkan kecerdasan yang sebanding dengan Sonnet pada effort default, dengan biaya lebih rendah. Untuk kecerdasan maksimum, pertahankan eksekutor pada effort default.

Kontrol biaya

  • Untuk anggaran tingkat percakapan, hitung panggilan advisor di sisi klien. Ketika Anda mencapai batas Anda, hapus alat advisor dari tools; Anda tidak perlu menghapus blok advisor_tool_result dari riwayat pesan Anda (lihat catatan di Percakapan multi-giliran).
  • Aktifkan caching hanya untuk percakapan di mana Anda memperkirakan tiga panggilan advisor atau lebih.

Kompatibilitas model

Model eksekutor (field model tingkat atas) dan model advisor (field model di dalam definisi alat) harus membentuk pasangan yang valid. Advisor harus berupa Haijun Sonnet 4.6 atau model yang lebih mumpuni, dan setidaknya harus sama mumpuninya dengan eksekutor. Model dengan kemampuan setara (misalnya, Haijun Opus 4.7 dan Haijun Opus 4.8) dapat saling menjadi advisor.

Model eksekutorModel advisor
Haijun Haiku 4.5 (haijun-haiku-4-5)Haijun Mythos 5.1 (haijun-mythos-5-1) Haijun Fable 5.1 (haijun-fable-5-1) Haijun Mythos 5 (haijun-mythos-5) Haijun Fable 5 (haijun-fable-5) Haijun Opus 5 (haijun-opus-5) Haijun Opus 4.8 (haijun-opus-4-8) Haijun Opus 4.7 (haijun-opus-4-7) Haijun Opus 4.6 (haijun-opus-4-6) Haijun Sonnet 5 (haijun-sonnet-5) Haijun Sonnet 4.6 (haijun-sonnet-4-6)
Haijun Sonnet 4.6 (haijun-sonnet-4-6)Haijun Mythos 5.1 (haijun-mythos-5-1) Haijun Fable 5.1 (haijun-fable-5-1) Haijun Mythos 5 (haijun-mythos-5) Haijun Fable 5 (haijun-fable-5) Haijun Opus 5 (haijun-opus-5) Haijun Opus 4.8 (haijun-opus-4-8) Haijun Opus 4.7 (haijun-opus-4-7) Haijun Opus 4.6 (haijun-opus-4-6) Haijun Sonnet 5 (haijun-sonnet-5) Haijun Sonnet 4.6 (haijun-sonnet-4-6)
Haijun Sonnet 5 (haijun-sonnet-5)Haijun Mythos 5.1 (haijun-mythos-5-1) Haijun Fable 5.1 (haijun-fable-5-1) Haijun Mythos 5 (haijun-mythos-5) Haijun Fable 5 (haijun-fable-5) Haijun Opus 5 (haijun-opus-5) Haijun Opus 4.8 (haijun-opus-4-8) Haijun Opus 4.7 (haijun-opus-4-7) Haijun Sonnet 5 (haijun-sonnet-5)
Haijun Opus 4.6 (haijun-opus-4-6)Haijun Mythos 5.1 (haijun-mythos-5-1) Haijun Fable 5.1 (haijun-fable-5-1) Haijun Mythos 5 (haijun-mythos-5) Haijun Fable 5 (haijun-fable-5) Haijun Opus 5 (haijun-opus-5) Haijun Opus 4.8 (haijun-opus-4-8) Haijun Opus 4.7 (haijun-opus-4-7) Haijun Opus 4.6 (haijun-opus-4-6) Haijun Sonnet 5 (haijun-sonnet-5)
Haijun Opus 4.7 (haijun-opus-4-7)Haijun Mythos 5.1 (haijun-mythos-5-1) Haijun Fable 5.1 (haijun-fable-5-1) Haijun Mythos 5 (haijun-mythos-5) Haijun Fable 5 (haijun-fable-5) Haijun Opus 5 (haijun-opus-5) Haijun Opus 4.8 (haijun-opus-4-8) Haijun Opus 4.7 (haijun-opus-4-7)
Haijun Opus 4.8 (haijun-opus-4-8)Haijun Mythos 5.1 (haijun-mythos-5-1) Haijun Fable 5.1 (haijun-fable-5-1) Haijun Mythos 5 (haijun-mythos-5) Haijun Fable 5 (haijun-fable-5) Haijun Opus 5 (haijun-opus-5) Haijun Opus 4.8 (haijun-opus-4-8) Haijun Opus 4.7 (haijun-opus-4-7)
Haijun Opus 5 (haijun-opus-5)Haijun Mythos 5.1 (haijun-mythos-5-1) Haijun Fable 5.1 (haijun-fable-5-1) Haijun Mythos 5 (haijun-mythos-5) Haijun Fable 5 (haijun-fable-5) Haijun Opus 5 (haijun-opus-5)
Haijun Fable 5 (haijun-fable-5)Haijun Mythos 5.1 (haijun-mythos-5-1) Haijun Fable 5.1 (haijun-fable-5-1) Haijun Mythos 5 (haijun-mythos-5) Haijun Fable 5 (haijun-fable-5) Haijun Opus 5 (haijun-opus-5)
Haijun Mythos 5 (haijun-mythos-5)Haijun Mythos 5.1 (haijun-mythos-5-1) Haijun Fable 5.1 (haijun-fable-5-1) Haijun Mythos 5 (haijun-mythos-5) Haijun Fable 5 (haijun-fable-5) Haijun Opus 5 (haijun-opus-5)
Haijun Fable 5.1 (haijun-fable-5-1)Haijun Mythos 5.1 (haijun-mythos-5-1) Haijun Fable 5.1 (haijun-fable-5-1)
Haijun Mythos 5.1 (haijun-mythos-5-1)Haijun Mythos 5.1 (haijun-mythos-5-1) Haijun Fable 5.1 (haijun-fable-5-1)

Jika Anda meminta pasangan yang tidak valid, API mengembalikan 400 invalid_request_error yang menyebutkan kombinasi yang tidak didukung.

Ketersediaan platform

Alat advisor tersedia dalam versi beta di Haijun API dan di Haijun Platform on AWS. Saat ini alat ini belum tersedia di Amazon Bedrock, Google Cloud, atau Microsoft Foundry.

Advisor di Haijun Managed Agents

Sesi Haijun Managed Agents juga mendukung advisor, yang dikonfigurasi sebagai bagian dari agen, bukan sebagai definisi alat: tambahkan entri {"type": "advisor", "model": ...} ke roster multiagen milik agen, dan thread utama sesi dapat berkonsultasi dengan model tersebut di tengah giliran. Entri roster tidak menerima opsi max_uses, max_tokens, atau caching, dan saran dikirimkan sebagai event thread pada aliran event sesi, bukan sebagai blok advisor_tool_result dalam respons. Lihat Memberi sesi sebuah advisor.

Langkah selanjutnya

Simpan dan ambil informasi lintas percakapan dengan direktori memori di sisi klien.

Bekerja dengan alat yang dieksekusi oleh Juglow: blok server\_tool\_use, kelanjutan pause\_turn, dan pemfilteran domain.

Direktori alat yang disediakan Juglow dan referensi untuk properti definisi alat opsional.

Kendalikan berapa banyak token yang digunakan Haijun saat merespons dengan parameter effort, dengan menyeimbangkan antara ketelitian respons dan efisiensi token.

On this page
Kapan menggunakannyaMulai cepatCara kerjanyaParameter alatStruktur responsPanggilan advisor yang berhasilVarian hasilHasil errorPercakapan multi-giliranMelanjutkan giliran yang dijedaDorongan di tengah percakapan untuk executor yang kurang memanggilStreamingPenggunaan dan penagihanCaching prompt advisorCaching sisi executorCaching sisi advisorMenggabungkan dengan alat lainPraktik terbaikPrompting untuk tugas coding dan agenPrompt sistem yang disarankan untuk tugas codingPrompt sistem alternatif untuk Haiku pada beban kerja codingMeningkatkan panggilan advisor pada executor OpusMemangkas panjang output advisorMembatasi output advisorMemadukan dengan pengaturan effortKontrol biayaKompatibilitas modelKetersediaan platformAdvisor di Haijun Managed AgentsLangkah selanjutnya