Jawaban singkat untuk pertanyaan yang paling sering diajukan pembaca tentang topik ini.
01Apa yang dibutuhkan agen coding tanpa pengawasan yang tidak dibutuhkan agen interaktif?
Empat hal: identitas untuk melakukan commit dengan token bercakupan sempit, ruang kerja miliknya sendiri yang direset sebelum setiap run, jadwal tetap yang dipilih mengikuti reset kuota penyedia model, dan cara berhenti — batas giliran, batas jam dinding, dan watchdog. Mode kegagalan agen tanpa pengawasan bukan crash, melainkan berjalan selamanya.
02Kenapa Docker socket host tidak boleh dipasang ke container agen?
Karena itu mengubah isolasi container menjadi akses root di host. Agen yang menjalankan perintah shell dari keluaran model adalah beban kerja tidak tepercaya yang punya akses sah, jadi ia sebaiknya mendapat sistem berkas, jaringan, dan batas memori — dan tidak mendapat apa pun yang memungkinkannya menjangkau host. Kalau ia harus membangun image, beri builder rootless di dalam container-nya sendiri.
03Kenapa agen tidak bisa push ke git padahal tokennya valid?
Banyak runtime agen menyanitasi environment yang diserahkan ke subproses shell, membuang variabel yang namanya tampak seperti rahasia. Itu perilaku yang benar untuk perkakas yang menjalankan perintah karangan model, tetapi membuat autentikasi lewat variabel lingkungan tidak terlihat oleh agen. Persistensikan kredensial ke disk saat boot dengan izin ketat, lalu verifikasi dengan variabelnya dihapus secara eksplisit.
04Bagaimana sebaiknya run terjadwal diatur waktunya di tier model gratis?
Tepat setelah reset kuota harian penyedia, yang biasanya berupa waktu UTC tetap. Run yang mulai saat itu mendapat jatah penuh; run yang sama pada malam hari mendapat sisanya. Beri jarak antar pekerjaan berat juga, karena dua pekerjaan berat di jendela yang sama akan saling men-rate-limit lebih efektif daripada beban eksternal mana pun.
05Resiliensi apa yang dibutuhkan agen tanpa pengawasan?
Batas keras jam dinding per run agar pekerjaan yang menggantung tidak memblokir penjadwal, langkah clean-start yang mereset ruang kerja dan menghapus berkas tak terlacak, watchdog tanpa akses model yang menuai proses macet serta memangkas disk, dan peringatan yang terpisah agar laporan rutin dan kegagalan nyata tidak tiba di kanal yang sama.
Menjalankan Hermes Agent sebagai Coder Otonom di VPS
Container yang dikeraskan, workstream cron, kredensial yang tahan environment tersanitasi, dan lapisan resiliensi yang menjaga agen tanpa pengawasan tetap hidup.
Menjalankan agen coding tanpa pengawasan di VPS kecil membutuhkan empat hal: container terkunci tanpa Docker socket, kredensial yang dipersistensikan ke disk alih-alih variabel lingkungan, cron yang dijadwalkan mengikuti reset kuota penyedia model, dan watchdog yang menuai run macet sebelum disk penuh.
Pada Juli saya menaruh sebuah agen coding open-source di VPS dua gigabyte dan memberinya tugas: setiap pagi, perbaiki salah satu pustaka saya, buka pull request, dan merge kalau tesnya lolos. Ia berjalan sejak saat itu, dan bagian yang menarik sama sekali bukan modelnya. Yang menarik adalah semua yang mengelilinginya — container, kredensial, jadwal, dan penanganan kegagalan.
Ini separuh infrastruktur dari proyek itu, ditulis sebagai catatan yang saya harap saya punya di hari pertama. Nama-namanya generik karena bentuk yang sama berlaku untuk runtime agen mana pun yang mungkin Anda jalankan seperti ini.
Apa yang sebenarnya dibutuhkan agar bisa tanpa pengawasan
Agen yang Anda awasi butuh terminal. Agen yang tidak Anda awasi butuh empat hal yang akan Anda berikan kepada rekan kerja junior, dan semuanya urusan infrastruktur, bukan prompt.
Sebuah identitas. Ia melakukan commit, push, dan membuka pull request sebagai seseorang, dengan token yang cakupannya persis sebatas kebutuhan itu dan tidak lebih.
Sebuah ruang kerja. Clone yang ia miliki sendiri, direset ke keadaan yang diketahui sebelum setiap run, agar kegagalan kemarin tidak mengotori hari ini.
Sebuah jadwal. Waktu tetap yang dipilih secara sengaja, karena kuota model gratis adalah sumber daya yang punya jam.
Sebuah cara berhenti. Batas giliran, timeout jam dinding, dan watchdog, karena mode kegagalan agen tanpa pengawasan bukan crash — melainkan berjalan selamanya.
Tiga dari empat hal itu adalah yang mula-mula saya salah lakukan lalu perbaiki belakangan, dan karena itulah mereka mendapat porsi terbesar di bawah ini.
Isolasi yang menjadi tumpuan seluruh setup ini. Agen mendapat sistem berkas, jaringan, dan batas memori, dan secara khusus tidak mendapat Docker socket milik host — satu-satunya pemberian yang mengubah agen terkurung menjadi tak terkurung.
Container-nya, dan apa yang sengaja tidak ada di dalamnya
Pengerasannya biasa saja dan tetap layak dilakukan, karena agen yang menjalankan perintah shell dari keluaran model adalah definisi beban kerja tidak tepercaya yang punya akses sah.
# docker-compose.yml — the hardening that costs nothing and matters
services:
agent:
image: agent:local
container_name: agent
env_file: .env # chmod 600, never committed
cap_drop: [ALL] # no capabilities at all
security_opt: [no-new-privileges:true]
mem_limit: 1g # a 2 GB box cannot afford a runaway
read_only: false # the workspace needs writes; the host does not
user: "1000:1000" # never root
volumes:
- agent-state:/home/agent/state # one volume, all persistence
networks: [agent-net] # its own network
# deliberately absent: /var/run/docker.sock
volumes: { agent-state: }
networks: { agent-net: }
Dua pilihan layak disebut. Batas memori bukan opsional di mesin kecil: tanpanya, satu build yang lepas kendali menjatuhkan seluruh mesin, termasuk apa pun yang Anda inangi di sana. Dan semua persistensinya masuk ke satu volume bernama, artinya rebuild menjadi aman dan pemulihan cukup satu penyalinan volume alih-alih penggalian arkeologis.
Jangan pernah memasang Docker socket host ke dalam container agen. Itu satu-satunya pemberian yang mengubah isolasi container menjadi akses root di host, dan instruksi tingkat prompt sebanyak apa pun tidak menggantikannya. Kalau agen memang perlu membangun image, beri ia builder rootless di dalam container-nya sendiri.
Jebakan kredensial yang memakan dua hari saya
Kegagalan paling membingungkan sepanjang proyek: agen tidak bisa push ke GitHub, sementara perintah yang persis sama dijalankan tangan di dalam container yang sama berjalan mulus. Bukan masalah token, bukan masalah jaringan — tokennya valid dan jaringannya baik-baik saja.
# The failure that cost me two days: the agent could not push, while an
# identical command run by hand worked perfectly.
#
# Cause: the runtime sanitises its subprocess environment and strips
# variables matching *_TOKEN and *_API_KEY before handing the shell to
# the agent. Environment-variable auth is therefore invisible to it.
# Fix: persist credentials to DISK at boot, not to the environment.
git config --global credential.helper store
printf 'https://%s:x-oauth-basic@github.com\n' "$GITHUB_TOKEN" \
> ~/.git-credentials && chmod 600 ~/.git-credentials
mkdir -p ~/.config/gh && cat > ~/.config/gh/hosts.yml <<YAML
github.com:
oauth_token: $GITHUB_TOKEN
git_protocol: https
YAML
chmod 600 ~/.config/gh/hosts.yml
# Verified the right way: unset the variable, then try.
env -u GITHUB_TOKEN gh auth status && env -u GITHUB_TOKEN git push
Penyebabnya adalah sebuah fitur keamanan. Runtime menyanitasi environment yang ia serahkan ke subproses shell, membuang variabel yang namanya tampak seperti rahasia, dan itu justru tepat untuk perkakas yang menjalankan perintah karangan model. Konsekuensinya, autentikasi lewat variabel lingkungan tidak terlihat oleh agen meski terlihat oleh Anda. Perbaikannya adalah mempersistensikan kredensial ke disk saat boot, dengan izin ketat, agar perkakasnya menemukannya tanpa perlu environment. Jebakan yang sama menggigit saya kedua kalinya lewat kunci penyedia model, dan perbaikan yang sama berlaku.
Uji perbaikan kredensial dengan menghapus variabelnya secara eksplisit lebih dulu. Menjalankan perintah dengan variabel lingkungan masih ada tidak membuktikan apa pun, karena itulah jalur yang memang sudah bekerja; menghapusnyalah yang membuktikan kredensial di disk benar-benar bekerja.
Menjadwal mengikuti kuota, bukan jam kantor
Dengan tingkatan model gratis atau murah, jadwal adalah keputusan anggaran. Kuota harian biasanya direset pada waktu UTC tetap, dan pekerjaan yang berjalan tepat setelah reset itu mendapat jatah penuh, sementara pekerjaan yang sama pada malam hari mendapat sisanya.
Pekerjaan
Irama
Kenapa slot itu
Run perbaikan utama
Harian, sesaat setelah reset kuota
Pekerjaan termahal mendapat anggaran paling segar dan persaingan paling sedikit
Run perbaikan kedua
Harian, awal sore
Berangkat dari branch main yang sudah dimajukan run pagi, jadi tidak menduplikasi pekerjaan
Watchdog
Tiap beberapa jam, tanpa melibatkan model
Menuai proses macet dan memangkas disk sebelum keduanya menjadi gangguan
Laporan harian
Malam hari
Merangkum commit dan merge hari itu, dan hanya inilah yang rutin saya baca
Laporannya lebih penting daripada kedengarannya. Agen tanpa pengawasan yang tidak punya ringkasan harian adalah sistem yang akan berhenti Anda percayai dalam seminggu, karena Anda tidak punya bukti ia mengerjakan apa pun. Satu surel per malam berisi jumlah commit dan pull request yang ter-merge adalah pembeda antara eksperimen dan rekan kerja.
Kebenaran tak glamor tentang agen otonom: sebagian besar rekayasanya adalah pekerjaan operasi biasa — disk, memori, jadwal, dan restart — di mesin yang tidak ditonton siapa pun pada pukul tiga pagi. Foto: Carl Lender from Sunrise, USA / Wikimedia Commons, CC BY 2.0
Lapisan resiliensi
Agen tanpa pengawasan gagal dengan cara yang tak pernah dialami agen interaktif, karena tak seorang pun menekan escape. Empat mekanisme menutup hampir semuanya.
Batas keras jam dinding di sekeliling setiap run terjadwal, agar pekerjaan yang menggantung tidak memblokir penjadwal di belakangnya. Batas giliran saja tidak cukup, karena satu panggilan tool yang macet tidak memakan giliran.
Langkah clean-start saat boot: reset ruang kerja ke branch remote dan hapus berkas tak terlacak. Run yang gagal meninggalkan puing, dan puing membuat suite tes run berikutnya gagal karena alasan yang tidak ada hubungannya dengan kode.
Watchdog yang sama sekali tidak punya akses model, menuai proses build yang berjalan lama, memangkas log dan sesi lama, serta memberi peringatan ketika disk melewati ambang batas.
Peringatan yang terpisah: laporan rutin ke surel, dan hanya kegagalan sungguhan yang masuk ke kanal chat. Mencampurnya melatih Anda mengabaikan keduanya.
Langkah clean-start adalah yang pertama akan saya tambahkan di pembangunan ulang mana pun. Satu berkas tes tak terlacak yang ditinggalkan run yang crash membuat hasil tiga hari berturut-turut terlihat seperti regresi, padahal kodenya baik-baik saja sepanjang waktu.
Urutan yang akan saya pakai lagi
Lima langkah, dan dua yang pertama justru paling sering dilewati.
Masukkan seluruh deployment ke version control — Dockerfile, berkas compose, konfigurasi, skrip — dengan rahasia dikecualikan dan berkas contoh yang di-commit sebagai penggantinya.
Buat satu run manual berjalan dari ujung ke ujung, termasuk push dan pull request-nya, sebelum menambahkan jadwal apa pun.
Tambahkan kredensial dengan cara yang benar-benar akan dikonsumsi agen, lalu verifikasi dengan variabel lingkungannya dihapus.
Tambahkan satu pekerjaan cron, amati selama tiga hari, dan baru setelah itu tambahkan yang kedua.
Tambahkan watchdog dan laporan harian sebelum Anda berhenti memperhatikan, bukan sesudahnya.
Kalau installer Anda menarik versi terbaru agen saat build alih-alih versi yang dipatok, tambahkan argumen build pemecah cache yang Anda naikkan secara sengaja. Kalau tidak, versi Anda adalah apa pun yang kebetulan terbaru saat perubahan tak berhubungan memaksa rebuild terakhir — dan itu bukan sifat yang Anda inginkan pada sesuatu yang me-merge kodenya sendiri.
Agen coding otonom di VPS kecil adalah sembilan puluh persen rekayasa operasi biasa dan sepuluh persen konfigurasi model. Kurung dengan benar, beri kredensial yang benar-benar bisa ia pakai, jadwalkan mengikuti kuota yang ia andalkan, dan awasi dengan sesuatu yang lebih bodoh darinya — maka ia menjadi kontributor harian yang sungguh berguna, bukan demo yang sekali berhasil.