AI coding agent yang memodifikasi berkas kode skala besar sering kali mengalami kegagalan akibat hallucinated offsets dan stale edits. Mengirim ulang seluruh isi berkas (full-file rewrite) via HTTP PUT memboroskan token context window, meningkatkan latensi jaringan, serta memicu silent overwrite saat terjadi konkurensi. Solusi yang lebih terukur adalah menerapkan API precision patch berbasis hunk atau line-offset dengan kontrol idempotensi yang ketat.
Struktur Kontrak Payload Precision Patch
Kontrak patch harus bersifat deterministik. API menerima target berkas, hash basis yang diacu model, serta array operasi mutasi yang mereferensikan baris spesifik dan checksum konten sebelum modifikasi.
{
"file_path": "src/services/auth.ts",
"base_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"operations": [
{
"type": "replace",
"start_line": 42,
"end_line": 45,
"expected_context_sha256": "8f434346648f6b96df89dda901c5176b10a6d83961dd3c1ac88b59b2dc327aa4",
"content": " if (!token || isExpired(token)) {\n throw new UnauthorizedException();\n }"
}
]
}Komponen base_sha256 menjamin berkas di disk belum berubah sejak AI membaca snapshot tersebut. Sementara itu, expected_context_sha256 memvalidasi bahwa blok baris target yang akan diganti memiliki konten persis sesuai ekspektasi parser AI agent.
Optimistic Concurrency Control via ETag dan If-Match
Untuk mencegah modifikasi ganda saat model mengeksekusi retry loop atau tool calling secara paralel, server wajib memvalidasi header standar HTTP:
- ETag: Dihasilkan dari SHA-256 seluruh isi berkas saat pembacaan terakhir.
- If-Match: Dikirim oleh AI agent pada header request PATCH. Jika nilai header tidak cocok dengan ETag berkas saat ini, server langsung menolak mutasi.
- Idempotency-Key: UUID unik per tool-call turn untuk memastikan request duplikat akibat network timeout menghasilkan response yang identik tanpa memicu re-patch.
Penanganan Atomic Mutation di Server
Server harus memperlakukan setiap precision patch sebagai transaksi atomik: validasi menyeluruh dilakukan sebelum ada byte yang ditulis ke disk.
import crypto from 'node:crypto';
import fs from 'node:fs/promises';
interface PatchOperation {
start_line: number;
end_line: number;
expected_context_sha256: string;
content: string;
}
export async function applyPrecisionPatch(
filePath: string,
baseSha256: string,
ops: PatchOperation[]
): Promise<string> {
const rawContent = await fs.readFile(filePath, 'utf-8');
const currentSha = crypto.createHash('sha256').update(rawContent).digest('hex');
if (currentSha !== baseSha256) {
throw new Error('STALE_FILE_STATE');
}
const lines = rawContent.split('\n');
// Validasi line range dan chunk integrity
for (const op of ops) {
if (op.start_line < 1 || op.end_line > lines.length || op.start_line > op.end_line) {
throw new Error('OUT_OF_BOUNDS_OFFSET');
}
const targetBlock = lines.slice(op.start_line - 1, op.end_line).join('\n');
const blockSha = crypto.createHash('sha256').update(targetBlock).digest('hex');
if (blockSha !== op.expected_context_sha256) {
throw new Error('CONTEXT_MISMATCH');
}
}
// Eksekusi mutasi baris secara descending agar offset tidak bergeser
const sortedOps = [...ops].sort((a, b) => b.start_line - a.start_line);
for (const op of sortedOps) {
const replacementLines = op.content.split('\n');
lines.splice(op.start_line - 1, (op.end_line - op.start_line) + 1, ...replacementLines);
}
const nextContent = lines.join('\n');
await fs.writeFile(filePath, nextContent, 'utf-8');
return crypto.createHash('sha256').update(nextContent).digest('hex');
}Desain Error Response Saat Terjadi Line Mismatch
Ketika patch gagal diterapkan, server tidak boleh hanya mengembalikan kode 400 Bad Request standar. Response harus memberikan konteks diagnostik struktural agar AI agent dapat melakukan kalkulasi ulang (self-heal) tanpa harus membaca ulang seluruh berkas.
{
"error": "CONTEXT_MISMATCH",
"status": 412,
"file_path": "src/services/auth.ts",
"current_file_sha256": "a1b2c3d4e5f6...",
"failed_operation_index": 0,
"expected_range": { "start_line": 42, "end_line": 45 },
"actual_content_in_range": " if (!token) {\n return null;\n }",
"suggested_rebase_offset": -3
}Dengan informasi actual_content_in_range dan pergeseran baris, AI agent dapat memverifikasi apakah fungsi target sekadar bergeser ke atas/bawah akibat modifikasi sebelumnya, atau logikanya memang telah berubah total secara eksternal.
Trade-off: Line-Offset vs AST Hunk
Pendekatan line-offset sangat cepat dan hemat komputasi, namun rentan bergeser jika ada perubahan format minor seperti penambahan spasi atau import di baris teratas berkas. Sebaliknya, modifikasi berbasis AST (Abstract Syntax Tree) hunk kebal terhadap pergeseran baris, tetapi membutuhkan runtime parser spesifik untuk setiap bahasa pemrograman dan tidak cocok untuk berkas non-kode seperti konfigurasi Markdown atau raw text.
Kombinasi base_sha256 di level berkas, expected_context_sha256 di level hunk, serta evaluasi urutan baris descending menghasilkan patch engine yang aman, deterministik, dan tahan terhadap kegagalan idempotensi AI coding agent.
Komentar
0 komentar
Masuk ke akun kamu untuk ikut berkomentar.
Belum ada komentar
Jadilah yang pertama ikut berdiskusi!