LangGraph agents akhirnya mendapat cara yang boleh dipercayai untuk mengekalkan keadaan (state) mereka selepas berminggu-minggu kehilangan data secara senyap. Selepas tiga percubaan teknik checkpointing yang gagal—SQLite, storan objek mentah, dan versi yang rosak bagi setiap satunya—penulis akhirnya menemui corak kemas kini atomik (atomic-update pattern) yang menghalang ejen daripada bermula semula dari awal setiap kali permintaan tiba.

Mengapa checkpointing penting untuk LangGraph

LangGraph membolehkan pembangun menyatukan panggilan LLM menjadi "ejen" yang boleh digunakan semula dan mampu mengingati apa yang berlaku sebelum ini dalam sesuatu perbualan. Ejen-ejen tersebut memecahkan permintaan pengguna kepada sub-tugasan, menyimpan hasil perantara, dan menyambung semula dari tempat terakhir mereka berhenti pada panggilan seterusnya. Jika keadaan (state) yang disimpan hilang, ejen akan mengira semula segalanya, membazirkan kuasa pengkomputeran, meningkatkan kependaman (latency), dan memberikan pengalaman pengguna yang buruk. Dalam bot pengeluaran yang mengendalikan mesej Telegram, kehilangan tersebut telah memadamkan sejarah perbualan selama berminggu-minggu.

Penyelesaian pertama: SQLite saver

SqliteSaver terbina dalam berfungsi dengan baik apabila hanya satu instans yang menjalankan ejen tersebut. Ia menulis setiap checkpoint sebagai blob JSON dalam fail SQLite tempatan. Masalah bermula apabila pembangun menambah medan (field) baharu kepada jenis AgentState dan melakukan redeploy. Checkpoint sedia ada, yang dicipta sebelum perubahan skema, tidak mempunyai medan baharu tersebut. Oleh kerana SqliteSaver tidak pernah menjalankan migrasi, LangGraph memuatkan JSON yang tidak lengkap, membuang data yang hilang, dan ejen bermula semula dari awal.

Poin utama: Storan SQLite adalah alat demonstrasi, bukan penyelesaian sedia-pengeluaran (production-ready) apabila evolusi skema diperlukan.

Penyelesaian kedua: Object storage

Untuk mendapatkan kawalan ke atas format penserialan (serialization), penulis menulis penyimpan (saver) tersuai yang memuat naik checkpoint JSON ke Oracle Cloud Object Storage. Langkah ini memberikan fleksibiliti untuk menguruskan versi skema secara manual, tetapi ia memperkenalkan mod kegagalan baharu. Apabila dua permintaan mengenai bebenang (thread) perbualan yang sama secara serentak, kedua-duanya cuba menulis semula (overwrite) objek yang sama. Perkhidmatan storan objek dioptimumkan untuk corak tulis-sekali, baca-banyak kali; ia tidak menyediakan semantik penulisan semula atomik. Keadaan perlumbaan (race condition) tersebut menghasilkan fail JSON yang rosak atau terpotong, dan ejen sekali lagi kehilangan konteksnya.

Poin utama: Penulisan semula (overwrite) biasa dalam storan objek tidak selamat apabila pelbagai pekerja (workers) boleh mengakses kunci (key) yang sama pada masa yang sama.

Penyelesaian ketiga: Kemas kini atomik dengan penomboran versi

Reka bentuk akhir yang stabil menggabungkan dua idea: nombor versi eksplisit dan penulisan bersyarat (conditional writes) berdasarkan ETag objek (pengenal pasti checksum perkhidmatan storan).

  1. Baca checkpoint semasa dan tangkap ETag-nya.
  2. Tambah (increment) medan versi di dalam sampul (envelope) checkpoint.
  3. Tulis checkpoint yang dikemas kini menggunakan permintaan bersyarat yang hanya berjaya jika ETag sepadan dengan yang dibaca sebelum ini.
  4. Cuba semula keseluruhan gelung baca-tambah-tulis jika penulisan bersyarat gagal kerana proses lain telah mengubah objek tersebut.

Oleh kerana penulisan hanya berjaya apabila tiada proses lain yang mengubah fail tersebut, hanya satu pekerja yang boleh melakukan komit (commit) keadaan baharu pada satu-satu masa. Medan versi juga memudahkan pengesanan checkpoint usang dan membolehkan migrasi ke hadapan apabila skema berubah.

Corak ini berfungsi dengan storan objek yang menyokong penulisan bersyarat berasaskan ETag.

Pengajaran untuk jurutera AI

  • Gunakan SQLite hanya untuk prototaip. Ejen pengeluaran memerlukan storan yang boleh mengendalikan perubahan skema dan penulisan serentak.
  • Rancang migrasi skema anda sendiri. Kamus bertipe (typed dictionaries) menerangkan bentuk untuk analisis statik tetapi tidak menguatkuasakan struktur semasa masa larian (runtime).
  • Anggap keadaan (state) sebagai sumber kongsi. Pepijat konkurensi muncul sebagai kehilangan data secara senyap; ia lebih sukar untuk dinyahpepijat (debug) berbanding pengecualian (exception) yang nyata.
  • Gunakan primitif awan. Penulisan bersyarat berasaskan ETag memberikan penguncian optimistik (optimistic locking) yang murah tanpa memerlukan perkhidmatan penguncian berasingan.
  • Log setiap langkah. Kegagalan senyap—seperti medan yang hilang yang diabaikan oleh LangGraph—adalah yang paling sukar untuk dikesan.

Apa seterusnya untuk checkpointing LangGraph?

Bagi pasukan yang telah menghadapi jalan buntu yang sama, resipi kemas kini atomik ini menawarkan penyelesaian pantas dan kos rendah. Ia menunjukkan bahawa saluran paip (pipeline) pengeluaran yang boleh dipercayai tidak memerlukan storan keadaan yang berat—hanya pengendalian konkurensi dan penomboran versi yang teliti.

Rumusan: Sampul versi yang ringkas ditambah dengan penulisan bersyarat menukarkan sistem yang tidak stabil kepada sistem yang boleh dipercayai, membolehkan jurutera AI memberi tumpuan kepada logik ejen berbanding penyahpepijatan kehilangan data yang tidak berkesudahan.