Home Blog AI Systems in Production Episode 04
AI Systems in Production · Episode 04 AI & Agentic Systems 10 Agustus 2025 8 min read

Prompt, Context, Harness & Loop Engineering — Apa Bedanya?

Empat layer engineering LLM yang sering dikacaukan — prompt, context, harness, dan loop — masing-masing punya scope dan pendekatan perbaikan yang berbeda.

RM
Ryan Muliadi
Digital Systems Architect · Ryzen Digital Systems
Empat Layer Engineering LLM — Scope dan Lokasi Problem
04 · LOOP ENGINEERING Bagaimana iterasi agent memperbaiki output secara bertahap 03 · HARNESS ENGINEERING Sistem pengujian — mengukur apakah layer lain berfungsi 02 · CONTEXT ENGINEERING Informasi yang dimasukkan ke context window LLM (RAG, history, tools) 01 · PROMPT ENGINEERING System prompt · few-shot · output format · chain-of-thought Core instruction L L M Diagnosis: mulai dari layer terluar (loop/harness) → dalam (context → prompt)

Ketika output LLM buruk, kebanyakan orang langsung memperbaiki prompt. Tapi sering kali masalahnya bukan di prompt — melainkan di context yang diberikan, atau di cara sistem itu diuji.

Tiga istilah ini punya scope yang berbeda dan solusi yang berbeda. Mencampurnya menyebabkan debugging yang tidak efisien dan perbaikan yang tidak tepat sasaran.

Prompt Engineering

Prompt engineering adalah seni merumuskan instruksi yang diberikan ke LLM untuk mendapatkan output yang diinginkan. Ini mencakup system prompt, few-shot examples, chain-of-thought, dan output format specification.

Scope Prompt Engineering
Mengoptimalkan INSTRUKSI yang diberikan ke LLM. Pertanyaannya: "Bagaimana cara memberitahu LLM apa yang harus dilakukan?"
Python · System Prompt yang Efektif
SYSTEM_PROMPT = """Anda adalah sistem triage keluhan untuk perusahaan properti PT JRP.

TUGAS:
- Analisis keluhan customer berdasarkan foto dan deskripsi
- Kategorikan berdasarkan jenis kerusakan  
- Tentukan prioritas (HIGH/MEDIUM/LOW)

ATURAN:
- Selalu jawab dalam Bahasa Indonesia yang profesional
- Jika foto tidak jelas, MINTA foto ulang sebelum kategorisasi
- Jangan pernah membuat janji waktu perbaikan tanpa cek SLA

OUTPUT FORMAT (wajib JSON):
{
  "category": "atap|dinding|listrik|plumbing|lainnya",
  "priority": "HIGH|MEDIUM|LOW",
  "needs_more_info": true|false,
  "response_to_customer": "..."
}"""

Context Engineering

Context engineering adalah tentang informasi apa yang dimasukkan ke context window LLM, bukan bagaimana instruksinya. Ini mencakup dokumen RAG, conversation history, tool results, dan structured data.

Scope Context Engineering
Mengoptimalkan INFORMASI yang tersedia untuk LLM saat menjawab. Pertanyaannya: "Informasi apa yang dibutuhkan LLM untuk menjawab dengan akurat?"
GejalaRoot CauseSolusi
LLM memberikan info yang salah atau outdatedContext engineeringPerbaiki RAG atau tambahkan data yang relevan
LLM menjawab dalam format yang salahPrompt engineeringPerbaiki output format spec di system prompt
LLM menjawab tidak konsisten antar runBisa keduanyaAudit context quality + tambah few-shot examples
Tidak tahu mana yang bermasalahHarness engineeringBangun test suite untuk mengidentifikasi

Harness Engineering

Harness engineering adalah pembuatan sistem pengujian untuk prompt dan pipeline LLM. Ini bagian yang paling sering dilewati — dan hasilnya, orang tidak punya cara sistematis untuk mengetahui apakah perubahan mereka membuat hal lebih baik atau lebih buruk.

Python · Evaluation Harness
# Test cases: input → expected output
TEST_CASES = [
    {
        "input": "Atap kamar saya bocor saat hujan deras",
        "expected_category": "atap",
        "expected_priority": "HIGH",
        "expected_needs_more_info": False
    },
    {
        "input": "Ada yang rusak di kamar saya",  # vague
        "expected_needs_more_info": True
    },
]

def run_evaluation(prompt, test_cases):
    results = []
    for case in test_cases:
        output = llm.invoke([
            {"role": "system", "content": prompt},
            {"role": "user", "content": case["input"]}
        ])
        parsed = parse_json(output)
        passed = all(
            parsed.get(k) == v
            for k, v in case.items() if k != "input"
        )
        results.append({"input": case["input"], "passed": passed})
    
    accuracy = sum(1 for r in results if r["passed"]) / len(results)
    return accuracy, results

# Sekarang bisa compare: prompt A vs prompt B secara objektif
acc_a, _ = run_evaluation(PROMPT_A, TEST_CASES)
acc_b, _ = run_evaluation(PROMPT_B, TEST_CASES)
print(f"Prompt A: {acc_a:.0%} | Prompt B: {acc_b:.0%}")
💡 Mulai dari Test Cases, Bukan dari Prompt

Bangun test cases dari real user inputs sebelum mulai menulis prompt. Ini memaksa Anda mendefinisikan "output yang benar" secara eksplisit — dan mencegah optimasi terhadap contoh yang tidak representatif.

Loop Engineering

Loop engineering adalah layer keempat yang paling jarang dibahas, tapi semakin penting seiring meningkatnya penggunaan agentic AI. Ini adalah seni merancang bagaimana agent menggunakan hasil iterasi sebelumnya untuk memperbaiki output di iterasi berikutnya.

Scope Loop Engineering
Mengoptimalkan SIKLUS ITERASI agent. Pertanyaannya: "Bagaimana agent belajar dari langkah sebelumnya dan memperbaiki pendekatannya dalam satu run?"

Berbeda dari tiga layer sebelumnya yang bersifat "set once," loop engineering menangani sistem yang berjalan iteratif — agent yang melakukan Plan → Act → Observe → Plan lagi. Ada tiga pola utama:

Reflection Loop

Agent mengevaluasi output-nya sendiri sebelum memberikan ke user. Setelah menghasilkan jawaban, agent bertanya: "Apakah ini sudah menjawab pertanyaan dengan baik?" Jika tidak, ia revisi sebelum lanjut.

Python · Reflection Pattern
def reflection_loop(llm, task: str, max_reflections: int = 2) -> str:
    response = llm.invoke(f"Selesaikan tugas ini: {task}")

    for _ in range(max_reflections):
        # Agent evaluasi outputnya sendiri
        critique = llm.invoke(f"""
Tugas asli: {task}
Draft jawaban: {response}

Evaluasi draft ini:
1. Apakah sudah menjawab tugas sepenuhnya?
2. Ada informasi penting yang terlewat?
3. Ada yang perlu diperbaiki?

Jika sudah baik, balas "LGTM". Jika tidak, jelaskan apa yang perlu diperbaiki.""")

        if "LGTM" in critique:
            break  # output sudah cukup baik

        # Revisi berdasarkan critique
        response = llm.invoke(
            f"Perbaiki jawaban ini berdasarkan feedback:
{critique}

Jawaban sebelumnya:
{response}"
        )

    return response

Self-Correction Loop

Digunakan ketika output harus memenuhi constraint tertentu — misalnya format JSON yang valid, atau output yang harus bisa diverifikasi secara programatik. Agent mencoba, verifikasi dilakukan, dan jika gagal agent memperbaiki berdasarkan error message.

Python · Self-Correction untuk JSON Output
import json

def self_correct_json(llm, prompt: str, schema: dict, max_retries: int = 3) -> dict:
    last_error = None

    for attempt in range(max_retries):
        # Sertakan error dari percobaan sebelumnya jika ada
        full_prompt = prompt
        if last_error:
            full_prompt += f"

Percobaan sebelumnya gagal dengan error: {last_error}
Perbaiki dan coba lagi."

        raw = llm.invoke(full_prompt)

        try:
            parsed = json.loads(raw)
            # Validasi schema tambahan jika diperlukan
            required = schema.get("required", [])
            missing = [f for f in required if f not in parsed]
            if missing:
                raise ValueError(f"Missing required fields: {missing}")
            return parsed  # sukses
        except (json.JSONDecodeError, ValueError) as e:
            last_error = str(e)
            print(f"Attempt {attempt + 1} failed: {last_error}")

    raise RuntimeError(f"Failed after {max_retries} attempts. Last error: {last_error}")

Critique-Revise Loop (Multi-Agent)

Pola paling powerful tapi juga paling mahal: dua LLM berbeda, satu sebagai "drafter" dan satu sebagai "critic." Ini menghindari blind spot yang terjadi ketika LLM yang sama mengevaluasi outputnya sendiri.

Loop PatternKapan DipakaiCost RelatifKekurangan
Reflection Output perlu quality check sebelum dikirim ke user △ 2× LLM calls LLM bisa bias terhadap outputnya sendiri
Self-Correction Output harus memenuhi constraint terukur (JSON, format) △ 1–3× LLM calls Tidak efektif untuk constraint subjektif
Critique-Revise Kualitas tinggi, output akan dipakai langsung ✗ 3–5× LLM calls Paling mahal, perlu dua LLM berbeda
⚠️ Loop Engineering Bukan untuk Semua Kasus

Setiap iterasi loop berarti tambahan LLM call dan latency. Untuk use case yang latency-sensitive (chatbot real-time, autocomplete), loop engineering bisa membuat UX terasa lambat. Gunakan hanya ketika kualitas output lebih penting dari kecepatan respons.

Kesimpulan

Ketika output LLM buruk, lakukan diagnosis dulu sebelum mulai mengubah sesuatu. Empat layer untuk diperiksa secara berurutan:

01
Harness dulu
Tanpa cara mengukur, Anda tidak tahu layer mana yang bermasalah. Bangun test suite sederhana terlebih dulu.
02
Context engineering
Apakah LLM punya informasi yang cukup dan relevan? RAG, conversation history, atau data injection yang bermasalah sering jadi root cause pertama.
03
Prompt engineering
Apakah instruksinya jelas, format output sudah dispecify, dan few-shot examples representatif?
04
Loop engineering
Jika output masih belum konsisten, pertimbangkan reflection atau self-correction loop — tapi pertimbangkan trade-off cost dan latency.

Bangun harness dulu. Tanpa cara mengukur, Anda tidak pernah tahu apakah perubahan prompt Anda membantu, tidak berpengaruh, atau justru memperburuk kasus lain.

Episode berikutnya: Circuit Breaker untuk AI Agent — sistem pertahanan yang mencegah agent loop selamanya dan menghabiskan token tanpa batas di production.

Series: AI Systems in Production · 6 artikel
01 Apa Itu AI Agent? Bukan Chatbot, Bukan Automation Biasa 02 RAG Pipeline dari Zero — Chunking Strategy yang Benar 03 LangGraph State Machine — Bagian yang Tutorial Skip
04 Prompt, Context, Harness & Loop Engineering — Apa Bedanya? ← You are here
05 Circuit Breaker untuk AI Agent — Mencegah Infinite Loop
06 Evaluasi Output LLM — Beyond Does It Sound Right?