/ 2menit

Failover tanpa merusak stream

Memindahkan request ke provider yang sehat itu mudah. Melakukannya setelah token pertama sampai ke klien: itu bagian yang sulit.

Router yang berdiri di depan beberapa provider model punya satu tugas yang terlihat sepele tapi tidak: saat satu provider mulai gagal, kirim request berikutnya ke jalur yang sehat. Kalau klien menunggu respons utuh, itu namanya retry. Kalau klien sedang membaca stream, Anda sudah terikat pada satu provider begitu byte pertama keluar.

Masalah retry pada stream

Sebagian besar implementasi failover memeriksa status code sebelum streaming dimulai. 429 atau 503 mudah: pilih rute berikutnya, kirim payload yang sama, klien tidak pernah tahu. Kegagalan yang menyakitkan justru yang datang setelah koneksi terbuka dan respons sudah berjalan: provider yang mengembalikan header seketika lalu macet, atau yang mengirim dua token lalu mati.

Saat itu klien sudah menerima jawaban sebagian. Memulai ulang request di provider lain berarti klien melihat teks ganda, atau respons yang bertentangan dengan dirinya sendiri di tengah jalan. Menempelkan jawaban provider kedua secara diam-diam ke jawaban pertama lebih buruk daripada gagal terang-terangan.

Mengintip chunk pertama

Pendekatan yang berhasil adalah memperlakukan chunk pertama sebagai titik komitmen sesungguhnya, bukan header respons. Executor membuka stream upstream, mengambil tepat satu chunk, dan baru setelah itu menyerahkan stream ke klien.

Satu chunk itulah keputusannya. Kalau datang dalam batas waktu, rute sehat dan sisa stream diteruskan apa adanya. Kalau koneksi error, atau tidak ada apa pun yang datang dalam anggaran waktu, executor membuang stream parsial itu, menandai rute sebagai degradasi, dan pindah ke tier berikutnya, dengan payload yang belum pernah dilihat klien satu byte pun.

let mut upstream = provider.stream(&payload).await?;
let first = timeout(budget, upstream.next()).await??;
// Hanya sekarang respons ini terikat pada rute tersebut.

Biayanya satu chunk latensi pada setiap request, dan manfaatnya failover berhenti terlihat. Urutan juga penting: tier ditelusuri sesuai urutan yang didefinisikan key, jadi provider murah-tapi-rewel tidak pernah terpilih mendahului primary hanya karena menjawab lebih cepat.

Penghematan yang diukur, bukan diklaim

Prinsip yang sama berlaku pada langkah penghemat token. Komponen penghemat yang melaporkan penghematannya sendiri sedang menilai pekerjaannya sendiri: ia menghitung apa yang ia buang, bukan apa yang benar-benar ditagih model.

Menjalankan penghemat sebagai pipeline deterministik lalu mengukur ulang pesan hasil penulisan ulang memberi angka yang bisa dipercaya, karena diturunkan dari payload yang benar-benar dikirim. Kalau satu penghemat gagal, pipeline fail open: request tetap keluar tanpa modifikasi, bukan tidak keluar sama sekali.

Pelajaran umumnya layak diulang. Angka apa pun yang dilaporkan sebuah sistem tentang dirinya sendiri sebaiknya dihitung ulang dari artefak yang dihasilkannya, bukan diakumulasi dari niat kode yang menghasilkannya.

Tulisan lain

2 menit

Satu route, lima jendela

Bagaimana satu route SvelteKit menjadi workspace, dock, papan yang terkunci ke desktop, dan dua jendela on-demand, semuanya membaca database lokal yang sama.

  • Tauri
  • Svelte
  • Desktop
Baca artikel

2 menit

Memberi LLM akses data ERP tanpa memberi SQL

Cara server MCP berbasis Rust membuka analitik ke klien LLM lewat tool yang sudah diizinkan, dan kenapa parameter binding lebih baik daripada model yang menulis query.

  • Rust
  • MCP
  • AI
Baca artikel