Tips & Tricks

Panduan Lengkap Harness Engineering: Membangun Agen AI ala Claude Code

Prompt saja tidak cukup untuk menjinakkan LLM. Pelajari cara merangkai tool, konteks, dan control loop menjadi harness, lengkap dengan kode yang bisa dijalankan dan arsitektur Claude Code sebagai panduan.

Era “lempar prompt ke ChatGPT, selesai” sudah berakhir. Sejak 2025, pusat gravitasi rekayasa AI bergeser cepat ke harness engineering. Kata kunci ini muncul berulang di blog internal Anthropic maupun riset agen OpenAI.

Namun jika ditanya “apa itu harness?”, masih sedikit yang bisa menjawab lugas. Artikel ini membedah harness engineering lewat kode yang dapat dijalankan dan arsitektur Claude Code sendiri sebagai studi kasus. Setelah membacanya, Anda siap membangun agen sendiri dari nol.

Harness adalah “perancah” yang mengelilingi AI

“Harness” secara harfiah berarti tali pengikat kuda atau sabuk pengaman. Di dunia perangkat lunak, kita mengenal “test harness”: struktur luar yang membuat sesuatu benar-benar berjalan.

Dalam konteks AI, harness adalah lapisan pembungkus di sekitar LLM. Lebih konkret, ia menyatukan semua yang dibutuhkan model untuk mengerjakan tugas dunia nyata:

  • Tool: baca file, jalankan perintah, panggil API, dan seterusnya
  • Manajemen konteks: apa yang diingat, dilupakan, dikompresi
  • Control loop: kapan memanggil, berhenti, mencoba ulang
  • Izin dan pengaman: mencegah operasi destruktif dijalankan tanpa izin
  • Memori: pengetahuan yang bertahan lintas sesi

Prompt hanyalah satu input ke harness ini. Harness yang lemah membuat prompt paling cerdas pun mentok pada langit-langit performa. Itulah mengapa orang mulai bilang: “prompt engineering saja tidak cukup.”

Kenapa harness penting: pikirkan dalam bentuk OODA loop

LLM sendiri hanya bisa “menghasilkan token berikutnya.” Untuk menyelesaikan tugas nyata, Anda perlu memutar OODA loop (Observe → Orient → Decide → Act) dari strategi militer.

FaseIsiPenanggung jawab
Observe (amati)Membaca lingkungan (file, kueri DB)Harness
Orient (olah)Menyusun informasi untuk LLMHarness
Decide (putuskan)Memilih tindakan berikutnyaLLM
Act (eksekusi)Menjalankan (perintah, panggilan API)Harness

Jelas bahwa tiga dari empat fase milik harness. LLM hanya unggul di Decide. Kualitas perancah di sekelilingnya menentukan kualitas seluruh agen.

Tiga tingkat harness lewat contoh

Mari selesaikan tugas yang sama, “buat artikel blog”, pada tiga tingkat harness.

Tingkat 1: panggilan API mentah (nyaris tanpa harness)

import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();

const res = await client.messages.create({
  model: "claude-opus-4-6",
  max_tokens: 4096,
  messages: [{ role: "user", content: "Tulis artikel blog" }],
});
console.log(res.content[0].text);

Hasil: teks generik dan dangkal. Tema dan struktur berubah setiap kali.

Tingkat 2: berikan tool (harness menengah)

const tools = [
  {
    name: "read_existing_posts",
    description: "Mengambil daftar artikel blog yang ada beserta judulnya",
    input_schema: { type: "object", properties: {} },
  },
  {
    name: "write_post",
    description: "Menulis file MDX",
    input_schema: {
      type: "object",
      properties: {
        slug: { type: "string" },
        frontmatter: { type: "object" },
        body: { type: "string" },
      },
      required: ["slug", "frontmatter", "body"],
    },
  },
];

async function runAgent(userGoal: string) {
  let messages = [{ role: "user", content: userGoal }];
  while (true) {
    const res = await client.messages.create({
      model: "claude-opus-4-6",
      max_tokens: 4096,
      tools,
      messages,
    });
    if (res.stop_reason === "end_turn") break;

    // Harness yang mengeksekusi panggilan tool
    const toolUse = res.content.find((c) => c.type === "tool_use");
    const result = await executeTool(toolUse.name, toolUse.input);
    messages.push({ role: "assistant", content: res.content });
    messages.push({
      role: "user",
      content: [{ type: "tool_result", tool_use_id: toolUse.id, content: result }],
    });
  }
}

Hasil: tema non-duplikat terpilih dan MDX dengan format benar terbentuk. Hanya dengan menambahkan tool, kualitas melonjak drastis.

Tingkat 3: harness lengkap setara Claude Code

  • Loop otonom (persetujuan pengguna, percobaan ulang saat error)
  • Kompresi konteks (meringkas percakapan panjang untuk menghemat token)
  • Delegasi subagen (menerjemahkan dalam konteks terpisah)
  • Prompt caching (bagian statis tidak dikirim ulang)
  • Hooks (lint otomatis sebelum commit)

Merangkai semuanya sendiri adalah proyek besar. Karena itulah mempelajari Claude Code sebagai implementasi referensi amat berharga.

Membongkar harness Claude Code

Claude Code adalah harness agen paling matang di Anthropic. Ia dapat dipahami dalam lima lapisan berikut.

Lapisan 1: desain tool

Read, Edit, Write, Bash, Glob, Grep, Agent, dan sebagainya tersedia sejak awal. Perhatikan granularitasnya:

  • Grep bukan sekadar grep, melainkan pembungkus ripgrep yang cepat dan akurat
  • Edit bukan menulis ulang seluruh berkas, melainkan mengganti string tertentu dengan diff minimal
  • Agent memunculkan subagen dengan konteks terisolasi

Kualitas tool langsung memengaruhi kualitas agen. “Asal jalan” tidak cukup. Rancang tool dengan memperhatikan idempotensi, pesan error yang jelas, dan tanggung jawab tunggal.

Lapisan 2: konteks berlapis

~/.claude/CLAUDE.md         ← aturan global
./CLAUDE.md                 ← aturan proyek (dimuat otomatis)
~/.claude/memory/           ← memori jangka panjang (lintas sesi)
  ├── user_profile.md
  ├── feedback_xxx.md
  └── project_xxx.md
riwayat percakapan           ← giliran terbaru
tugas/rencana                ← kemajuan sesi saat ini

Setiap lapisan punya usia dan peran berbeda. Salah menulis, informasi cepat hilang atau justru data usang tetap tinggal. “Hanya untuk sesi ini” → tugas; “sering dipakai” → memori.

Lapisan 3: delegasi subagen

Dengan tool Agent, Anda bisa memunculkan agen lain di konteks tersendiri.

# Agen utama hanya memberi instruksi, kerja berat diserahkan ke subagen
Agent(
  subagent_type: "general-purpose",
  prompt: "Terjemahkan blog/harness.mdx ke bahasa Inggris dan 8 bahasa lain,
           simpan masing-masing di blog-{lang}/ lalu laporkan"
)

Dengan begitu, konteks utama tidak tercemar log yang ramai. Log build panjang, hasil terjemahan antara, dump pencarian — apa pun yang Anda hanya butuh hasil akhirnya, bisa dioper sepenuhnya.

Lapisan 4: hooks (pemrosesan deterministik)

Lewat .claude/settings.json, Anda bisa menyisipkan perintah shell sebelum dan sesudah pemanggilan tool.

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          { "type": "command", "command": "npx tsc --noEmit" }
        ]
      }
    ]
  }
}

Setelah tiap penyuntingan, pemeriksaan tipe dijalankan otomatis. Segala sesuatu yang “lebih baik diselesaikan secara deterministik alih-alih dimintakan ke LLM berulang-ulang” layak jadi hook.

Lapisan 5: mode izin

{
  "permissions": {
    "allow": ["Read", "Grep", "Glob"],
    "deny": ["Bash(rm -rf*)", "Bash(git push --force*)"],
    "ask": ["Write", "Edit", "Bash"]
  }
}

Tolak perintah destruktif secara eksplisit, minta persetujuan untuk operasi tulis. Insiden terjadi ketika sesuatu dijalankan tanpa pengawasan, jadi lapisan ini menentukan keamanan operasional.

Lima jebakan klasik

1. Terlalu banyak tool Beri model 30 tool, ia akan bingung memilih dan akurasinya turun. Rumus praktis: 5-15. Kelebihannya serahkan ke subagen.

2. Prompt caching tidak dimanfaatkan Tanpa cache_control API Claude, system prompt panjang dikirim ulang penuh setiap giliran — biaya membengkak. Ingat TTL 5 menit dan cache bagian statisnya.

messages: [{
  role: "system",
  content: [
    { type: "text", text: longStaticInstructions,
      cache_control: { type: "ephemeral" } },   // ← ini
    { type: "text", text: dynamicContext },
  ],
}]

3. Pesan error yang tidak bisa dibaca LLM Tool yang hanya membalas Error: undefined membuat model tidak bisa memulihkan diri. Tuliskan apa salahnya dan cara memperbaikinya.

throw new Error(
  `File '${path}' tidak ada. ` +
  `File yang ada di scripts/: ${list.join(", ")}`
);

4. Melewati persetujuan manusia Otomatis menyetujui aksi destruktif (delete, force push, update DB) suatu hari pasti berujung kecelakaan. Default: minta konfirmasi untuk tulis, tolak untuk hapus.

5. Memori tidak pernah dibersihkan Informasi usang menarik agen ke asumsi keliru. Memori juga butuh pembersihan berkala (di Claude Code lewat /compact atau penyuntingan manual).

Jalankan mini harness Anda sendiri

Terakhir, harness minimal dengan Node.js + TypeScript yang bisa langsung dijalankan.

// mini-harness.ts
import Anthropic from "@anthropic-ai/sdk";
import { readFileSync, writeFileSync } from "fs";

const client = new Anthropic();

const tools = [
  { name: "read_file",
    description: "Membaca file teks",
    input_schema: { type: "object", properties: { path: { type: "string" } }, required: ["path"] } },
  { name: "write_file",
    description: "Menulis file teks",
    input_schema: { type: "object", properties: { path: { type: "string" }, content: { type: "string" } }, required: ["path", "content"] } },
];

const executors = {
  read_file: ({ path }) => readFileSync(path, "utf-8"),
  write_file: ({ path, content }) => { writeFileSync(path, content); return `written ${path}`; },
};

async function loop(goal: string, maxSteps = 10) {
  const messages: any[] = [{ role: "user", content: goal }];
  for (let i = 0; i < maxSteps; i++) {
    const res = await client.messages.create({
      model: "claude-opus-4-6", max_tokens: 4096, tools, messages,
    });
    messages.push({ role: "assistant", content: res.content });
    if (res.stop_reason === "end_turn") return res.content;

    const toolUse = res.content.find((c: any) => c.type === "tool_use") as any;
    if (!toolUse) return res.content;
    const result = executors[toolUse.name](toolUse.input);
    messages.push({
      role: "user",
      content: [{ type: "tool_result", tool_use_id: toolUse.id, content: String(result) }],
    });
  }
}

await loop("Baca README.md dan simpan ringkasan 3 baris sebagai TL;DR.md");

Dengan ini Anda sudah punya mini-agen yang dapat membaca file yang ada dan menulis file baru. Tambahkan tool Grep, Bash, dan Agent, maka jadilah Claude Code versi mini.

Kesimpulan: dari penulis prompt menjadi arsitek harness

Sudut pandang lamaSudut pandang baru
Prompt bagus → hasil bagusHarness bagus → hasil bagus
Memilih modelMerancang model + tool + konteks + izin
Pertanyaan satu kaliOperasi loop berkelanjutan

Claude Code adalah materi ajar terbaik untuk merasakan pergeseran perspektif ini. Jangan sekadar memakai — bongkar mekanismenya dan adopsi idenya ke agen Anda sendiri. Itulah sikap yang dituntut bagi insinyur AI sejak 2026.

Mulailah dengan menyalin mini harness di atas dan menjalankannya. Sepuluh menit kemudian Anda sudah membuat langkah pertama menuju agen pribadi.

Artikel terkait

Referensi

#claude-code #agent-sdk #harness #prompt-engineering #llm #anthropic

Tingkatkan alur kerja Claude Code kamu

50 template prompt yang sudah teruji, siap copy-paste ke Claude Code sekarang juga.

Gratis

PDF Gratis: Cheatsheet Claude Code dalam 5 Menit

Cukup masukkan emailmu dan kami akan langsung mengirim cheatsheet PDF A4 satu halaman.

Kami menjaga data pribadimu dengan aman dan tidak pernah mengirim spam.

Masa

Tentang Penulis

Masa

Engineer yang aktif menggunakan Claude Code. Mengelola claudecode-lab.com, media teknologi 10 bahasa dengan lebih dari 2.000 halaman.