Misteri Tugas Berdurasi Panjang A2A: Mengapa Pekerjaan Lebih dari Dua Menit Sering Gagal
Hermes platform pesan bagian ke-38: Tiga penyebab dan perbaikan untuk masalah timeout tugas panjang A2A.
Hermes di dua komputer saling “menelepon” untuk memberi tugas, dan setiap kali tugas melebihi dua menit langsung gagal—tidak peduli bagaimana konfigurasi diubah. Ini bukan hal mistis, melainkan tiga masalah kecil yang bertumpuk.
Teka-teki: Kutukan Dua Menit
Bayangkan kamu meminta rekan kerja A untuk membantu memproses sebuah file, dan kalian sepakat dia akan meneleponmu setelah selesai. Tapi setiap kali panggilan berlangsung lebih dari dua menit, kamu tiba-tiba “klik” menutup telepon, lalu muncul “panggilan gagal”. Kamu sudah mencoba ganti telepon, ganti saluran, bahkan pindah kantor—masalahnya tetap saja.
Inilah yang dialami pengguna Hermes. Dua mesin masing-masing menjalankan Hermes, terhubung melalui plugin A2A (protokol komunikasi terbuka antar-agen). Mesin A memberi tugas ke mesin B, dan selama tugas memakan waktu lebih dari sekitar 2 menit, pasti gagal. Komunitas menyebutnya “long reply menyebabkan pelacakan progres rusak”. Yang lebih menyebalkan, pekerjaan di mesin B sebenarnya sudah selesai, tapi mesin A tidak pernah menerima hasilnya.
Penyebab Satu: Si Penelepon Tidak Sabaran
Jebakan pertama murni masalah “sifat keburu-buru”.
Klien Hermes punya pengaturan timeout default—120 detik. Maksudnya apa? Si penelepon memasang alarm untuk dirinya sendiri: kalau lawan bicara tidak merespons dalam 120 detik, aku tutup teleponnya. Tapi di sisi server? Mereka menyediakan jendela respons 300 detik untuk agen bekerja, alias 5 menit.
Lihat kan, si penelepon menutup telepon di menit ke-2, padahal si penerima telepon mengira kamu punya kesabaran 5 menit. Hasilnya: tugas masih berjalan, telepon sudah putus duluan. Dan 120 detik ini di-hardcode di dalam kode, pengguna biasa bahkan tidak bisa menemukan tempat untuk mengubahnya.
Penyebab Dua: Jalur Lama Tidak Punya Tombol “Timeout”
Jebakan kedua adalah masalah warisan sejarah.
Hermes menyediakan dua cara memanggil A2A: yang resmi adalah “transfer via operator” (dipanggil melalui peer yang sudah dikonfigurasi), dan yang lainnya adalah “saluran langsung lama” (dipanggil langsung menggunakan URL asli). Jalur lama ini ditinggalkan dari versi awal, dan di dalamnya juga tertulis hardcode timeout 120 detik, serta tidak membaca file konfigurasi.
Artinya, meskipun kamu sudah belajar cara mengubah waktu timeout, jalur lama tidak akan mendengarkanmu. Seperti kamu memasang baterai baru di telepon jadul, tapi telepon itu memang tidak punya kenop pengatur volume.
Penyebab Tiga: Begitu Waktunya Habis, Hasil Kerja Langsung Dibuang
Jebakan ketiga paling parah: server “membersihkan area” begitu waktunya tiba.
Anggap saja kamu akhirnya berhasil memperbesar timeout klien dan melewati dua jebakan pertama. Eh, di sisi server muncul masalah lagi: begitu jendela respons 300 detik habis, tugas langsung ditandai sebagai “gagal”, meskipun agen masih bekerja keras. Lebih parahnya lagi, status “gagal” ini bersifat lengket—seperti lem yang tidak bisa dilepaskan. Ketika agen akhirnya benar-benar selesai dan kembali membawa hasil, ternyata tidak ada yang menunggunya, dan hasilnya langsung dibuang.
Ini seperti kurir yang pulang tepat waktu—tidak peduli paketmu sudah terkirim atau belum, sistem langsung menampilkan “pengiriman gagal”. Besoknya kamu menerima paketnya, tapi status logistik selamanya tertahan di kolom “gagal”, tidak bisa diubah lagi.
Langkah Pemecahan Satu: Perlambat Alarmnya
Setelah memahami tiga jebakan ini, perbaikannya jadi mudah.
Perbaikan pertama sangat jelas: ubah timeout default klien dari 120 detik menjadi 330 detik. 330 detik > 300 detik milik server, jadi si penelepon lebih sabar daripada si penerima telepon, dan tugas bisa bertahan melewati jendela respons server. Selain itu, a2a_call kini punya parameter override timeout per-panggilan—kamu bisa mengatur timeout untuk satu tugas tertentu tanpa mengubah global. Jalur lama akhirnya “dimodernisasi”, sekarang ia membaca konfigurasi, mewarisi autentikasi dan pengaturan timeout.
Langkah Pemecahan Dua: Tugas “Dipisahkan” Bukan “Dinyatakan Gagal”
Perbaikan kedua lebih cerdas. Server tidak lagi menandai tugas sebagai gagal saat waktunya habis, melainkan “memisahkannya”. Maksudnya apa? Seperti antrian layanan pelanggan—kalau kamu sudah tidak sabar menunggu terlalu lama, kamu boleh menutup telepon, tapi tiketmu tetap ada di sistem, dan kamu akan dapat notifikasi SMS setelah selesai diproses.
Secara spesifik: ketika jendela respons habis, pemanggil menerima status non-terminal “sedang bekerja” beserta petunjuknya. Tugas tetap dalam status WORKING, dan sistem mengatur “pengamat dengan batas waktu” untuk terus memantaunya. Ketika agen benar-benar selesai, hasil asli dicatat. Setelah itu, baik melalui query tasks/get maupun tasks/resubscribe, pengamat bisa melihat hasil akhirnya. Hasil yang datang terlambat tidak lagi dibuang.
Langkah Pemecahan Tiga: Masalah Lain yang Ikut Diperbaiki
Setelah menyelesaikan kasus utama, beberapa masalah tetangga ikut terungkap.
Pemotongan respons streaming: Sebelumnya respons streaming mungkin hanya mengembalikan segmen terakhir ke pemanggil. Contohnya, sebuah rangkaian panjang event_id terpotong dan hanya menyisakan bagian kedua, sehingga pemanggil menerima informasi yang tidak lengkap. Setelah diperbaiki, respons kumulatif dipertahankan secara utuh, dan dalam pengujian, 152 kasus uji semuanya lolos.
Penyelesaian palsu: Ketika budget iterasi agen habis, sebelumnya ia mengembalikan ringkasan “selesai”, tapi pihak lawan tidak bisa membedakan antara “pekerjaan terpotong” dan “pekerjaan yang berhasil diselesaikan”, sehingga hasil parsial bisa saja diterima sebagai hasil lengkap. Sekarang tugas yang terpotong akan melaporkan TASK_STATE_FAILED secara eksplisit, tidak lagi menyamar sebagai sukses.
Peluncur eksternal: Pengguna non-root sekarang bisa mengonfigurasi peluncur agen eksternal, menjalankan subproses atau worker RPC versi tertentu, dengan dukungan output terbatas, pemanenan pohon proses, pembatalan, dan terminasi tepat-satu-kali. Ini menyelesaikan tiga masalah lama: visibilitas penyelesaian, penyelarasan timeout, dan kontinuitas multi-putaran.
Artinya Bagimu
Sekarang, ketika dua Hermes saling memberi tugas, pekerjaan yang melebihi dua menit tidak lagi “pasti gagal”. Waktu timeout bisa diatur, dan jalur lama pun patuh. Yang lebih penting, meskipun server tidak sabar menunggu, tugas tidak akan “divonis mati”—ia tetap dalam status bekerja, dan setelah selesai hasilnya tetap dicatat, kamu bisa cek kapan saja.
Tugas berdurasi panjang akhirnya seperti lari jarak jauh: ada yang menghitung waktu, ada yang menemani berlari, ada yang mencatat hasilnya. Bukan lagi seperti dulu, di tengah jalan wasit meniup peluit dan hasilnya dianulir.
📖 Dokumentasi resmi
この記事は Hermes Agent のDokumentasi resmiに基づいています:Dokumentasi resmi › user-guide/messaging/a2a