Mendesain Tool Schema yang Robust untuk AI Coding Agent
KR
Kevin Ray

Dipublikasikan 5 Juli 2026

Mendesain Tool Schema yang Robust untuk AI Coding Agent

Baru-baru ini Armin Ronacher, creator Flask dan Jinja, mengungkapkan bug menarik di Pi editor: model Claude Opus 4.8 menghasilkan tool call dengan field yang sama sekali tidak ada di schema, seperti requireUnique, oldText2, atau bahkan event.0.additionalProperties. Yang lebih mengejutkan: model SOTA justru lebih sering salah dibanding model lama dalam hal schema adherence. Fenomena ini mengajarkan kita bahwa mendesain tool schema untuk AI coding agent tidak bisa asal-asalan. Artikel ini adalah panduan praktis untuk membuat schema yang robust berdasarkan analisis Ronacher dan best practice dari komunitas.

Mengapa Model Baru Justru Lebih Buruk di Tool Tertentu

Tool call pada dasarnya adalah text generation dengan in-band signalling. Model menerima transcript percakapan, system prompt, dan daftar tool yang tersedia, lalu menghasilkan teks yang diinterpretasikan oleh API atau client sebagai function call. Anthropic menggunakan format internal bernama ANTML yang menyerupai XML, di mana parameter array di-serialize sebagai JSON string di dalam tag.

Masalahnya: model-model terbaru kemungkinan besar di-post-train pada harness yang mirip Claude Code, yaitu tool-coding agent milik Anthropic sendiri. Harness tersebut sangat forgiving atau toleran terhadap kesalahan: menerima alias parameter, memperbaiki Unicode escape yang rusak, dan secara silent memfilter unknown keys. Akibatnya, model belajar bahwa sedikit malformed call masih bisa sukses. Ketika dihadapkan pada schema pihak ketiga yang strict dan tidak forgiving, model justru gagal karena prior-nya terlalu kuat terhadap schema internal Anthropic.

Langkah 1: Gunakan Schema yang Flat

Claude Code menggunakan tool edit yang flat: file_path, old_string, new_string, dan flag opsional replace_all. Schema flat lebih mudah di-sample oleh model daripada nested array of objects, karena setiap parameter berada di top level dan tidak memerlukan serialisasi JSON bersarang.

Jika memungkinkan, hindari struktur seperti ini yang terlalu kompleks:

// Hindari
{
  "path": "file.py",
  "edits": [
    { "oldText": "...", "newText": "..." }
  ]
}

Preferensikan struktur flat dengan parameter top-level. Jika kamu membutuhkan multiple edits, pertimbangkan untuk membuat tool call terpisah untuk setiap edit daripada menggabungkannya dalam satu array. Atau, gunakan flat fields seperti old_string_1, new_string_1 jika memang harus dalam satu call.

Langkah 2: Aktifkan Constrained Decoding

Anthropic menyediakan mode strict untuk tool use. Mode ini menggunakan grammar-aware decoding yang mencegah model menghasilkan key yang tidak ada di schema. Ronacher menemukan bahwa mengaktifkan strict mode hampir sepenuhnya menghilangkan masalah invented keys di Opus 4.8 dalam pengujiannya.

OpenAI punya pendekatan serupa melalui format Harmony, di mana model menandai bagian message dengan <|constrain|>json. Marker ini membantu sampler beralih ke JSON-constrained sampling untuk body tool call. Jika platform LLM-mu mendukung constrained decoding atau structured outputs, aktifkan selalu untuk tool schema kritis.

Langkah 3: Hindari JSON Bersarang di Dalam String

Parameter array yang di-serialize sebagai JSON string di dalam XML tag (seperti di format ANTML) adalah titik rawan paling rentan terhadap hallucination. Setelah model menghasilkan multi-line string yang panjang di dalam newText, ia harus memutuskan apakah menutup object dengan } atau menambahkan field tambahan. Ini adalah highest-entropy point dalam generation, dan di sinilah hallucination field paling sering terjadi.

Solusi: jika platform-mu memungkinkan, gunakan top-level attribute untuk parameter string, dan pisahkan array ke tool call tersendiri. Atau gunakan format yang native mendukung schema constraint, seperti OpenAI function calling dengan JSON schema validation yang strict.

Langkah 4: Desain Harness yang Strict, Bukan Forgiving

Claude Code memiliki retry path, parameter aliases, type coercion, dan Unicode repair. Ini terdengar bagus untuk user experience, tapi berbahaya untuk reinforcement learning. Jika model melihat bahwa panggilan malformed tetap sukses karena harness memperbaikinya secara otomatis, ia tidak mendapat sinyal negatif untuk berhenti melakukan kesalahan.

Rekomendasi untuk harness internal yang kamu bangun:

  • Jangan tambahkan alias parameter. Gunakan satu nama yang konsisten di seluruh schema.

  • Jangan lakukan silent filtering untuk unknown keys. Return error eksplisit agar model belajar dari kegagalan.

  • Jangan repair Unicode atau escaped string secara otomatis. Biarkan model belajar menghasilkan output yang valid sejak awal.

Langkah 5: Uji Schema dengan Model Terbaru

Behavior tool calling bisa berubah signifikan antar versi model. Schema yang berhasil dengan Opus 4.5 mungkin gagal dengan Opus 4.8 karena perubahan post-training data. Buatlah test suite yang menjalankan schema-mu terhadap berbagai model (Claude, GPT, Codex) dengan berbagai macam prompt context:

  1. Single-turn prompt langsung seperti edit file ini saja.

  2. Multi-turn agentic history dengan file reading, diagnosis, dan planning.

  3. Prompt dengan thinking blocks yang panjang dan kompleks.

  4. Prompt dengan konten non-ASCII atau multi-line string kompleks yang membutuhkan escaping.

Ukur failure rate untuk setiap skenario. Jika failure rate meningkat pada model terbaru, itu tanda bahwa schema-mu off-distribution terhadap post-training data model tersebut dan perlu disederhanakan.

Langkah 6: Pertimbangkan Grammar-Aware Decoding

Constrained decoding atau grammar-aware decoding memang punya tradeoff quality dalam beberapa kasus, tapi jika model semakin kuat dalam solving task sambil semakin lemah dalam faithfully emitting tool schema, harness perlu guarantee yang lebih kuat. LARK grammar untuk custom tools, JSON schema constraint, atau sampler masking adalah investasi yang worth it untuk production system.

Format Harmony dari OpenAI adalah contoh bagus di mana model secara eksplisit menandai region yang perlu di-constrain dengan <|constrain|>json. Ini memungkinkan inference engine untuk switch ke mode constrained decoding hanya pada bagian yang relevan, tanpa mengorbankan kreativitas model di bagian lain dari respons.

Kesimpulan

Tool schema bukan kontrak abstrak yang netral. Schema yang terlalu nested, terlalu forgiving, atau tidak menggunakan constrained decoding akan meningkatkan kemungkinan hallucination pada model SOTA. Desain schema yang flat, strict, dan well-tested adalah kunci untuk membangun AI coding agent yang reliable dan tidak mengecewakan user di tengah session produktif.

Sumber referensi: Better Models: Worse Tools oleh Armin Ronacher dan Pi Issue #6278.