Dilema Arsitektur: Autonomi Penuh vs Intervensi Interaktif

Membangun AI coding agent menuntut keputusan fundamental pada kontrol eksekusi: membiarkan model mengeksekusi instruksi dari awal hingga akhir tanpa interupsi (fully autonomous / batch execution), atau menyisipkan titik validasi manusia di setiap transisi state kritis (conversational human-in-the-loop / interactive checkpoints).

Pendekatan fully autonomous meminimalkan intervensi manual dengan menjalankan loop Plan-Act-Observe hingga tugas selesai. Sebaliknya, arsitektur Human-in-the-Loop (HITL) mewajibkan validasi manusia sebelum mutasi state ireversibel terjadi, seperti modifikasi file sistem, migrasi basis data, atau eksekusi perintah terminal berisiko.

Evaluasi Trade-Off Teknis

1. Context Window Drift dan Konsumsi Token

Pada model fully autonomous, agen berjalan dalam loop otonom panjang. Setiap siklus kegagalan sintaksis, eksekusi test runner, dan perbaikan berulang diakumulasikan ke dalam context window. Hal ini memicu context window drift, di mana instruksi utama tertimbun log error yang panjang. Model kehilangan arah instruksi awal, memicu degradasi logika (hallucination loop), dan meningkatkan konsumsi token input secara eksponensial.

Model conversational HITL memangkas drift ini melalui checkpoint berkala. Manusia memvalidasi intermediate diff atau mengoreksi asumsi model secara dini, memungkinkan agen mereset atau merangkum riwayat context sebelum melanjutkan ke sub-task berikutnya.

2. Broken Build Rollback vs Latensi Eksekusi

Model batch execution memiliki throughput waktu kalkulasi mesin murni yang tinggi karena tidak ada blokir I/O menunggu respon pengguna. Namun, operational cost meningkat saat agen menghasilkan cascade failure di akhir batch: unit test gagal, dependency rusak, atau Git commit history terfragmentasi. Pembersihan broken build ini sering kali membutuhkan intervensi manual yang memakan waktu lebih lama daripada proses generasi kode itu sendiri.

Sebaliknya, HITL menaikkan end-to-end runtime akibat human idle latency. Keuntungannya adalah biaya rollback mendekati nol karena invalid diff atau destructive bash command langsung di-reject sebelum dieksekusi.

State Machine Interaktif untuk Coding Agent

Pola representasi state machine berikut memisahkan aksi baca (read-only discovery) dari aksi tulis (state mutation) menggunakan checkpoint gate:

[State: IDLE]
       |
       v
[State: ANALYZE_WORKSPACE] (Read-only: AST, Grep, LSP)
       |
       v
[State: GENERATE_PATCH]
       |
       v
[State: AWAITING_HUMAN_APPROVAL] <-- Interaktif Checkpoint
       |
       +---> [Action: REJECT / FEEDBACK] ---> Loop back to GENERATE_PATCH
       |
       +---> [Action: APPROVE]
                 |
                 v
         [State: APPLY_DIFF]
                 |
                 v
         [State: RUN_TESTS]
                 |
                 v
         [State: COMMIT_CHANGES]

Implementasi Backend Checkpoint Sederhana (Python)

Kode berikut mengimplementasikan state machine deterministik untuk agen coding. Engine membaca diff yang diajukan model, menahan eksekusi sebelum Git patch diterapkan, dan mewajibkan otorisasi eksplisit:

import sys
import subprocess
from enum import Enum
from dataclasses import dataclass
from typing import Optional

class AgentState(Enum):
    PLANNING = "PLANNING"
    AWAITING_APPROVAL = "AWAITING_APPROVAL"
    APPLIED = "APPLIED"
    FAILED = "FAILED"

@dataclass
class ProposedPatch:
    file_path: str
    diff_content: str

class PatchCheckpointAgent:
    def __init__(self):
        self.state = AgentState.PLANNING

    def stage_patch(self, patch: ProposedPatch) -> None:
        self.current_patch = patch
        self.state = AgentState.AWAITING_APPROVAL

    def review_checkpoint(self) -> bool:
        if self.state != AgentState.AWAITING_APPROVAL:
            raise RuntimeError(f"Invalid state for review: {self.state}")

        print("\n--- PROPOSED DIFF CHECKPOINT ---")
        print(f"Target File: {self.current_patch.file_path}")
        print(self.current_patch.diff_content)
        print("--------------------------------")

        # Input deterministik dari operator manusia
        user_input = input("Approve and apply patch? [y/N]: ").strip().lower()
        return user_input == "y"

    def apply_patch(self) -> None:
        # ponytail: implementasi langsung ke fs; ganti VCS interface jika integrasi ke remote git repo
        if not self.review_checkpoint():
            self.state = AgentState.FAILED
            print("[AGENT] Diff rejected by operator. Aborting.")
            return

        try:
            with open(self.current_patch.file_path, "w", encoding="utf-8") as f:
                f.write(self.current_patch.diff_content)
            
            self.state = AgentState.APPLIED
            print(f"[AGENT] Successfully committed to {self.current_patch.file_path}")
        except OSError as err:
            self.state = AgentState.FAILED
            print(f"[AGENT] I/O Failure applying patch: {err}")

if __name__ == "__main__":
    sample_diff = "def calculate_tax(subtotal: float) -> float:\n    return subtotal * 0.11\n"
    patch = ProposedPatch(file_path="tax_calculator.py", diff_content=sample_diff)

    agent = PatchCheckpointAgent()
    agent.stage_patch(patch)
    agent.apply_patch()
    
    # Runnable assert verification
    assert agent.state in [AgentState.APPLIED, AgentState.FAILED]

Panduan Pemilihan Arsitektur

  • Pilih Fully Autonomous jika: Tasks bersifat isolatif dan idempotent (seperti bulk rename, migrasi modul deklaratif, penulisan unit test untuk pure functions), test suite memiliki coverage tinggi dengan sandbox environment aman, dan biaya rollback murah.
  • Pilih Conversational HITL jika: Agen menangani repository monorepo skala besar, arsitektur menyentuh migrasi schema database, perubahan core contract antarmuka (API breaking changes), atau ketika token context window perlu dikontrol ketat untuk mencegah hallucinations.