Coding agent berbasis Large Language Model (LLM) sering mengalami halusinasi logika atau silent regression—kondisi ketika agent melaporkan tugas perbaikan selesai karena sintaks valid, namun fungsionalitas sistem rusak akibat hilangnya konteks edge cases. LLM secara inheren bersifat probabilistik dan cenderung mengasumsikan keberhasilan modifikasi tanpa verifikasi runtime mandiri.
Pola Think-Act-Prove memecahkan limitasi ini dengan memisahkan penalaran instruksi, manipulasi file, dan validasi eksekusi secara ketat. Artikel ini menyajikan implementasi verification harness minimalis menggunakan Python untuk mengunci feedback loop agent berbasis exit code deterministik.
Akar Masalah: Bias Konfirmasi pada ReAct Tradisional
Pola tradisional seperti ReAct (Reason-Act) sering kali berhenti segera setelah agent menjalankan aksi penulisan file atau perubahan patch. Agent membaca status penulisan sukses dari tool file system, lalu mengasumsikan kode tersebut dapat dijalankan secara benar.
Kelemahan pendekatan tersebut meliputi:
- Sycophancy dan Konfirmasi Palsu: Model cenderung memvalidasi penalarannya sendiri tanpa umpan balik nyata dari interpreter atau compiler.
- Breakage pada Dependensi Tersembunyi: Refaktor lokal merusak kontrak API di modul lain tanpa disadari oleh model yang bekerja pada window konteks terbatas.
- State Hallucination: Agent berasumsi runtime dependencies, environment variables, atau database migrations sudah sinkron secara otomatis.
Solusinya adalah menerapkan prinsip zero-trust: perubahan kode tidak pernah dianggap selesai sampai test runner lokal mengeluarkan return code 0.
Anatomi Siklus Think-Act-Prove
Pola Think-Act-Prove membagi eksekusi tugas ke dalam tiga fase eksplisit yang berjalan di dalam bounded retry loop:
- Think: Agent menganalisis failure trace atau instruksi user, membaca file target, dan merumuskan rencana modifikasi spesifik.
- Act: Agent menerapkan patch atau mutasi file menggunakan diff patch engine atau overwrite aman.
- Prove: Harness mengeksekusi test runner deterministik (misalnya
pytest), menangkapexit_code, dan merangkumstdout/stderr. Jika verifikasi gagal, payload log diteruskan kembali ke fase Think sebagai umpan balik objektif.
Implementasi Verification Harness dengan Python
Harness evaluasi bertindak sebagai supervisor eksternal di luar kontrol agent. Harness mengeksekusi testing suite lokal, membatasi timeout eksekusi, serta memformat output failure agar hemat token.
import subprocess
import json
from dataclasses import dataclass
from typing import Optional, List, Dict, Any
@dataclass
class ExecutionResult:
passed: bool
exit_code: int
stdout: str
stderr: str
class TestRunnerHarness:
def __init__(self, test_cmd: List[str], timeout_seconds: int = 30):
self.test_cmd = test_cmd
self.timeout_seconds = timeout_seconds
def prove(self) -> ExecutionResult:
"""Menjalankan test suite deterministik dan menangkap exit code."""
try:
process = subprocess.run(
self.test_cmd,
capture_output=True,
text=True,
timeout=self.timeout_seconds
)
return ExecutionResult(
passed=(process.returncode == 0),
exit_code=process.returncode,
stdout=process.stdout,
stderr=process.stderr
)
except subprocess.TimeoutExpired:
return ExecutionResult(
passed=False,
exit_code=-1,
stdout="",
stderr=f"Test execution timed out after {self.timeout_seconds}s"
)
@staticmethod
def format_feedback(result: ExecutionResult, max_chars: int = 1500) -> Dict[str, Any]:
"""Memangkas log error panjang untuk menghemat budget token prompt."""
raw_output = result.stderr if result.stderr.strip() else result.stdout
truncated_output = raw_output[-max_chars:] if len(raw_output) > max_chars else raw_output
return {
"status": "PASSED" if result.passed else "FAILED",
"exit_code": result.exit_code,
"error_context": truncated_output.strip()
}
Orchestrator Loop dengan Budget Limit
Jika agent melakukan perbaikan yang memicu error baru, loop perbaikan berulang tanpa batasan (infinite repair loop) akan menguras budget API tokens. Tambahkan loop guard menggunakan threshold batas iterasi (max_attempts).
class ThinkActProveAgent:
def __init__(self, harness: TestRunnerHarness, max_attempts: int = 3):
self.harness = harness
self.max_attempts = max_attempts
def think(self, feedback: Optional[Dict[str, Any]]) -> str:
# ponytail: integrasi call LLM (OpenAI/Anthropic SDK) di sini.
# Placeholder representasi rencana perubahan oleh LLM
return "Plan: Fix edge case in auth token expiry validation."
def act(self, plan: str) -> None:
# ponytail: terapkan patch git/unified diff ke file target.
# Simulasi mutasi file lokal
pass
def run(self) -> bool:
feedback = None
for attempt in range(1, self.max_attempts + 1):
# 1. THINK
plan = self.think(feedback)
# 2. ACT
self.act(plan)
# 3. PROVE
eval_result = self.harness.prove()
if eval_result.passed:
return True
feedback = self.harness.format_feedback(eval_result)
# Rollback perubahan lokal jika limit tercapai dan kode masih gagal
return False
# Runner eksekusi
if __name__ == "__main__":
harness = TestRunnerHarness(test_cmd=["pytest", "tests/test_auth.py", "-q"])
agent = ThinkActProveAgent(harness=harness, max_attempts=3)
success = agent.run()
assert success or not success # Deterministic check exit
Alternatif Ringkas (The Lazier Path)
Gunakan git hook lokal (pre-commit) atau bash-level loop until pytest; do agent-fix; done jika kompleksitas arsitektur Python runner tidak diperlukan untuk use case lokal personal.
Praktik Terbaik dan Trade-Offs
- Test Suite Dependency: Pola Prove hanya seandal cakupan unit test yang tersedia. Jika unit test tidak mencakup regression case, harness tetap menghasilkan false positive. Terapkan mutation testing secara berkala untuk mengevaluasi kualitas suite.
- Sandbox Isolation: Menjalankan
subprocess.run()langsung pada mesin host memicu risiko keamanan saat agent menghasilkan destructive commands. Eksekusi tahap Prove di dalam container Docker atau ephemeral environment terisolasi. - Token Overhead: Menyisipkan raw stack trace ke LLM context window memakan kuota token. Pangkas output hanya pada assertion failure dan traceback esensial menggunakan regex sebelum menyuntikkannya ke prompt berikutnya.
Komentar
0 komentar
Masuk ke akun kamu untuk ikut berkomentar.
Belum ada komentar
Jadilah yang pertama ikut berdiskusi!