
Pengalaman membangun sistem tool output spilling di Nouride agar agent tetap stabil dan tidak mengalami amnesia saat output perintah terminal berukuran besar.
Kalau lu sering ngoprek atau pakai coding agent yang punya akses terminal (misal: tool exec), lu mungkin pernah ngalamin momen di mana si agent awalnya nurut dan enak diajak mikir, tapi pas masuk turn ke-20 atau ke-30 mendadak halu, ngulang-ngulang jawaban, atau langsung error context length exceeded.
Penyebab utamanya hampir selalu ada di manajemen I/O tool yang berantakan, bukan model LLM-nya.
Cukup satu perintah terminal yang output-nya gak terkontrol—misalnya docker logs, git diff monorepo, atau build script yang nge-dump stack trace ribuan baris—ribuan baris teks mentah itu langsung membanjiri context window. Sekali log berukuran 4 MB sampai 6 MB masuk mentah-mentah ke payload prompt, efek buruknya langsung beruntun:
Waktu gw bangun Nouride (daemon multi-agent ringan buat kebutuhan homelab), masalah ini jadi prioritas awal yang harus beres. Gw butuh agent kayak Nouva bisa nemenin ngoding nembus puluhan sampai ratusan turn tanpa mogok di tengah jalan.
Ini beberapa pendekatan yang sempat gw coba dan solusi yang akhirnya gw pakai lewat konsep Tool Output Spilling.
Sebelum nemu pola yang enak, gw sempat nyoba beberapa pendekatan umum yang ternyata nyusahin waktu dipakai kerja:
Gw sempat mikir solusinya cukup dikasih instruksi di prompt: "Kalau output terminal kira-kira bakal panjang, redirect ke file ya, terus kasih tahu path-nya aja."
Cara ini gak jalan konsisten. Model LLM gak bisa tahu seberapa panjang output dari sebuah program sebelum program itu dieksekusi. Pas manggil journalctl atau npm test, model gak bisa nebak apakah hasilnya 5 baris atau 10.000 baris. Menyerahkan kontrol alokasi memori ke intuisi model sebelum perintah berjalan itu rapuh banget.
Solusi berikutnya gw coba pasang limit karakter di backend. Kalau output melebihi batas tertentu, potong dan ambil 2.000 karakter pertama.
Cara ini justru bikin masalah baru. Di log eksekusi software, sinyal paling krusial hampir selalu ada di ujung akhir (tail): baris error terakhir, summary compiler, atau exit code failure. Pas yang diambil cuma bagian depan (head), agent cuma melihat log inisialisasi awal yang sukses, lalu menyimpulkan prosesnya lancar padahal aslinya crash di baris ke-5.000.
Ada juga pola agent yang cuma ngasih teks pendek: [output 5MB dipotong, jalankan lagi perintahnya kalau mau lihat detail].
Pola ini gak efisien kalau perintah yang dijalankan itu proses compile atau test suite yang makan waktu 2 menit. Masa agent harus nungguin 2 menit lagi cuma buat ngintip baris tengah yang tadi gak kebaca?
Akhirnya gw adaptasi konsep klasik dari sistem operasi: memory spilling / paging to disk. Kalau kapasitas memori cepat (RAM) terbatas, OS nge-swap halaman memori yang belum dipakai ke disk daripada langsung mematikan prosesnya.
Di Nouride, harness daemon duduk di tengah antara hasil eksekusi tool dan payload prompt yang dikirim ke LLM. Alurnya bekerja secara deterministik:
Satu hasil tool call gak boleh menghabiskan context window. Di Nouride, satu tool result dijatah maksimal 25% dari total conversation budget (dengan floor 2.000 token). Tujuannya supaya kalau agent manggil 3 atau 4 tool sekaligus dalam satu turn, masih ada sisa ruang 50% untuk prompt persona, memory, dan chat history.
Kalau panjang karakter dari tool result melebihi batas budget:
$DATA_DIR/tool-output/<session_id>/<call_id>.txt.0600 (mencegah leak jika ada log environment variable atau secret).LLM hanya menerima excerpt ringkas dengan pembagian terukur:
read and an offset, or narrow it with grep."Format yang diterima agent seperti ini:
[output too large for the context — 14,200 lines, ~2,840KB.
The first 65 and last 35 lines are below; 14,100 in the middle are not.]
Full output: /srv/nouride/.nouride/data/tool-output/s_019/call_exec_42.txt
Open it with `read` and an offset, or narrow it with `grep` — it is a normal file and it is readable.
... (baris awal perintah) ...
... (baris akhir / exit error) ...
Pola spilling ini langsung menyelesaikan beberapa masalah teknis:
grep atau read dengan offset langsung ke path file spill.Agent AI yang reliable di sesi panjang membutuhkan disiplin kontrol I/O di level runtime harness. Dengan mengalirkan log bervolume besar ke filesystem dan hanya menyuapkan ringkasan terstruktur plus file pointer ke LLM, model tetap fokus pada task utama tanpa membebani context window.