AI Prompt Engineering · Pelajaran

Penanganan Galat dalam Rantai Perintah

Validasi keluaran perantara dan pulihkan proses dari kegagalan rantai.

Pelajaran 4 dari 413 langkah

Penanganan Galat dalam Rantai Perintah adalah pelajaran AI Prompt Engineering gratis di CoddyKit. Ini adalah pelajaran 4 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar AI Prompt Engineering, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus AI Prompt Engineering mencakup 4 pelajaran total.

Mengapa Rantai Gagal

Rantai perintah menimbulkan mode kegagalan baru yang tidak ada pada sistem dengan satu perintah. Setiap langkah dapat gagal dengan caranya sendiri, dan kegagalan tersebut terakumulasi—output Langkah 2 yang buruk merusak setiap langkah berikutnya.

Mode kegagalan yang umum:

  • Model mengembalikan JSON yang formatnya tidak valid sehingga tidak dapat diurai
  • Model salah memahami tugas dan menghasilkan output yang keliru secara makna
  • Batas laju atau batas waktu API menyebabkan langkah gagal
  • Jendela konteks terlampaui dalam rantai yang panjang
  • Model mengarang data yang kemudian dianggap sebagai fakta oleh langkah-langkah berikutnya

Validasi Output Setelah Setiap Langkah

Garis pertahanan pertama adalah memvalidasi output segera setelah setiap langkah, sebelum meneruskannya ke langkah berikutnya. Jangan pernah berasumsi bahwa model mengembalikan apa yang Anda minta.

import json

def validate_json_output(raw_text, required_fields):
    'Parse and validate that required fields are present in model output.'
    try:
        data = json.loads(raw_text.strip())
    except json.JSONDecodeError as e:
        raise ValueError(f'Invalid JSON: {e}. Raw: {raw_text[:200]}')

    missing = [f for f in required_fields if f not in data]
    if missing:
        raise ValueError(f'Missing required fields: {missing}. Got: {list(data.keys())}')

    return data

# Usage after a chain step
raw = '{"sentiment": "positive", "priority": "high"}'
validated = validate_json_output(raw, required_fields=['sentiment', 'priority'])
print('Valid:', validated)

Logika Percobaan Ulang untuk Kegagalan Sementara

Kegagalan API—batas laju, batas waktu, dan kesalahan server—bersifat sementara. Terapkan logika percobaan ulang dengan jeda eksponensial untuk kegagalan tingkat jaringan:

import anthropic, time

client = anthropic.Anthropic(api_key='YOUR_API_KEY')

def call_with_retry(prompt, max_retries=3, base_delay=1.0):
    last_error = None
    for attempt in range(max_retries):
        try:
            r = client.messages.create(
                model='claude-opus-4-5', max_tokens=500,
                messages=[{'role': 'user', 'content': prompt}]
            )
            return r.content[0].text
        except anthropic.RateLimitError as e:
            wait = base_delay * (2 ** attempt)
            print(f'Rate limited. Waiting {wait}s before retry {attempt+1}/{max_retries}...')
            time.sleep(wait)
            last_error = e
        except anthropic.APIError as e:
            last_error = e
            if attempt < max_retries - 1:
                time.sleep(base_delay)
    raise RuntimeError(f'All retries exhausted: {last_error}')

Validasi Semantik

Beberapa kegagalan memiliki struktur yang valid tetapi maknanya salah—model mengembalikan JSON yang valid, tetapi dengan nilai yang keliru. Gunakan langkah validasi ringan untuk memeriksa ketepatan makna:

def semantic_validate(data, schema_rules):
    'Apply semantic validation rules to parsed output.'
    errors = []

    for field, rules in schema_rules.items():
        value = data.get(field)

        if rules.get('required') and value is None:
            errors.append(f'{field} is required but missing')
            continue

        if 'allowed_values' in rules and value not in rules['allowed_values']:
            errors.append(f'{field} must be one of {rules["allowed_values"]}, got: {value}')

        if 'min_length' in rules and isinstance(value, list) and len(value) < rules['min_length']:
            errors.append(f'{field} must have at least {rules["min_length"]} items, got {len(value)}')

    if errors:
        raise ValueError('Semantic validation failed: ' + '; '.join(errors))

    return data

rules = {'sentiment': {'allowed_values': ['positive', 'negative', 'mixed']}, 'issues': {'min_length': 1}}
data = {'sentiment': 'positive', 'issues': ['login bug']}
print(semantic_validate(data, rules))

Perintah Cadangan

Jika suatu langkah gagal divalidasi setelah beberapa kali percobaan ulang, perintah cadangan dapat menghasilkan output yang lebih sederhana tetapi tetap dapat digunakan, alih-alih menghentikan seluruh rantai:

import json

def call_with_fallback(primary_prompt, fallback_prompt, required_fields):
    # Try primary prompt
    try:
        raw = call_with_retry(primary_prompt)
        return validate_json_output(raw, required_fields)
    except (ValueError, RuntimeError) as e:
        print(f'Primary prompt failed: {e}. Trying fallback...')

    # Try simpler fallback prompt
    try:
        raw = call_with_retry(fallback_prompt)
        return validate_json_output(raw, required_fields)
    except (ValueError, RuntimeError) as e:
        print(f'Fallback also failed: {e}. Returning safe default.')

    # Return safe default — chain continues with minimal data
    return {field: None for field in required_fields}

# Usage
primary = 'Analyze this review. Return JSON with 10 fields: {...}'
fallback = 'Classify this review. Return JSON: {"sentiment": "positive|negative|neutral"}'
result = call_with_fallback(primary, fallback, ['sentiment'])
print(result)

Pemutus Sirkuit

Pemutus sirkuit mencegah rantai yang gagal membuang panggilan API. Setelah N kegagalan berturut-turut, pemutus ini membuka sirkuit dan segera mengembalikan kesalahan tanpa melakukan panggilan API lebih lanjut:

class CircuitBreaker:
    def __init__(self, failure_threshold=3, recovery_timeout=60):
        self.failure_count = 0
        self.threshold = failure_threshold
        self.state = 'closed'  # closed = normal, open = blocking
        self.opened_at = None

    def call(self, fn, *args, **kwargs):
        import time
        if self.state == 'open':
            elapsed = time.time() - self.opened_at
            if elapsed > 60:  # recovery_timeout
                self.state = 'half-open'
            else:
                raise RuntimeError('Circuit open — skipping API call')
        try:
            result = fn(*args, **kwargs)
            self.failure_count = 0
            self.state = 'closed'
            return result
        except Exception as e:
            self.failure_count += 1
            if self.failure_count >= self.threshold:
                self.state = 'open'
                self.opened_at = time.time()
                print(f'Circuit opened after {self.failure_count} failures.')
            raise e

cb = CircuitBreaker(failure_threshold=3)
print('Circuit breaker initialized.')

Membuat Titik Pemeriksaan pada Rantai Panjang

Untuk rantai dengan banyak langkah atau langkah yang mahal, gunakan titik pemeriksaan untuk menyimpan hasil perantara. Jika langkah yang lebih akhir gagal, lanjutkan dari titik pemeriksaan tersebut, bukan memulai ulang dari Langkah 1:

import json, os

CHECKPOINT_DIR = '/tmp/chain_checkpoints'
os.makedirs(CHECKPOINT_DIR, exist_ok=True)

def save_checkpoint(run_id, step_id, data):
    path = os.path.join(CHECKPOINT_DIR, f'{run_id}_step{step_id}.json')
    with open(path, 'w') as f:
        json.dump(data, f)
    print(f'Checkpoint saved: step {step_id}')

def load_checkpoint(run_id, step_id):
    path = os.path.join(CHECKPOINT_DIR, f'{run_id}_step{step_id}.json')
    if os.path.exists(path):
        with open(path) as f:
            return json.load(f)
    return None

def run_with_checkpoints(run_id, input_data):
    step1 = load_checkpoint(run_id, 1) or json.loads(call(f'Step 1 processing: {input_data}'))
    save_checkpoint(run_id, 1, step1)

    step2 = load_checkpoint(run_id, 2) or json.loads(call(f'Step 2 processing: {step1}'))
    save_checkpoint(run_id, 2, step2)

    return step2

print('Checkpointing system defined.')

Degradasi yang Terkendali

Jika suatu langkah dalam rantai gagal dan tidak dapat dipulihkan, degradasi yang terkendali melanjutkan rantai dengan data sebagian, alih-alih menghentikannya sepenuhnya:

def process_with_degradation(tickets):
    results = []
    for ticket in tickets:
        try:
            # Full chain: extract -> classify -> respond
            extracted = json.loads(call(f'Extract issue from ticket. Return JSON: {{"issue": str}}\n\n{ticket}'))
            classified = json.loads(call(f'Classify priority. Return JSON: {{"priority": str}}\n\n{extracted["issue"]}'))
            response = call(f'Draft response for {classified["priority"]} priority: {extracted["issue"]}')
            results.append({'ticket': ticket, 'response': response, 'degraded': False})
        except Exception as e:
            print(f'Chain failed for ticket, using fallback: {e}')
            # Fallback: simple direct response without classification
            simple_response = call(f'Respond to this support ticket:\n{ticket}')
            results.append({'ticket': ticket, 'response': simple_response, 'degraded': True})
    return results

print('Graceful degradation pipeline defined.')

Pencatatan Kesalahan Terstruktur

Catat kesalahan dengan konteks yang cukup untuk mendiagnosis langkah mana yang gagal, seperti apa inputnya, dan apa yang dikembalikan model:

import logging, traceback
from datetime import datetime

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger('chain')

def logged_step(step_name, prompt, validator=None):
    start = datetime.utcnow()
    try:
        raw = call_with_retry(prompt)
        result = validator(raw) if validator else raw
        logger.info(f'[{step_name}] SUCCESS in {(datetime.utcnow()-start).total_seconds():.2f}s')
        return result
    except Exception as e:
        logger.error(f'[{step_name}] FAILED after {(datetime.utcnow()-start).total_seconds():.2f}s')
        logger.error(f'[{step_name}] PROMPT: {prompt[:200]}')
        logger.error(f'[{step_name}] ERROR: {traceback.format_exc()}')
        raise

print('Structured error logging defined.')

Menguji Skenario Kesalahan

Uji penanganan kesalahan Anda secara khusus dengan menyuntikkan kegagalan. Gunakan objek tiruan untuk menyimulasikan kesalahan API dan output yang formatnya tidak valid:

from unittest.mock import patch, MagicMock

def test_fallback_on_json_error():
    with patch('__main__.call') as mock_call:
        # First call returns malformed JSON, fallback returns valid JSON
        mock_call.side_effect = [
            'This is not JSON at all',
            '{"sentiment": "positive"}'
        ]

        result = call_with_fallback(
            primary_prompt='Analyze review with 10 fields',
            fallback_prompt='Just classify sentiment as JSON',
            required_fields=['sentiment']
        )

        assert result['sentiment'] == 'positive'
        print('PASS: fallback activated correctly on JSON parse error')

def test_circuit_breaker_opens():
    cb = CircuitBreaker(failure_threshold=2)
    for i in range(2):
        try:
            cb.call(lambda: (_ for _ in ()).throw(RuntimeError('API fail')))
        except RuntimeError:
            pass
    assert cb.state == 'open'
    print('PASS: circuit breaker opened after 2 failures')

print('Error handling tests defined.')

Memantau Kesehatan Rantai dalam Produksi

Dalam lingkungan produksi, lacak metrik kesehatan rantai untuk mendeteksi penurunan kinerja sebelum disadari pengguna:

  • Tingkat keberhasilan langkah: Persentase proses ketika setiap langkah berhasil pada percobaan pertama
  • Tingkat aktivasi perintah cadangan: Seberapa sering perintah cadangan digunakan?
  • Tingkat degradasi: Berapa bagian proses rantai yang selesai dalam mode terdegradasi?
  • Latensi langkah: Lacak latensi p50/p95 per langkah—langkah yang lambat menunjukkan masalah kompleksitas perintah
  • Tingkat kegagalan validasi: Tingkat yang tinggi menandakan bahwa perintah perlu disempurnakan

Pemeriksaan Cepat

Apa tujuan pemutus sirkuit dalam rantai perintah?

Penanganan Kesalahan dalam Rantai—Inti Pembelajaran

Penanganan kesalahan yang tangguh membedakan rantai purwarupa dari sistem produksi:

  • Validasi output setiap langkah sebelum meneruskannya—jangan pernah berasumsi bahwa model mengembalikan data yang benar
  • Lakukan percobaan ulang terhadap kegagalan API sementara dengan jeda eksponensial—batas laju dan batas waktu dapat dipulihkan
  • Gunakan perintah cadangan untuk menghasilkan output yang lebih sederhana ketika perintah utama gagal dalam validasi semantik
  • Pemutus sirkuit menghentikan pemborosan panggilan API setelah terjadi kegagalan berulang
  • Buat titik pemeriksaan untuk langkah yang mahal agar rantai panjang dapat dilanjutkan setelah kegagalan pada langkah akhir
  • Degradasi yang terkendali menjaga alur kerja tetap berjalan dengan data sebagian, alih-alih menghentikannya
  • Lacak tingkat keberhasilan langkah, tingkat penggunaan perintah cadangan, dan tingkat degradasi dalam produksi
Gratis untuk memulai

Belajar AI Prompt Engineering dengan tutor AI — gratis

Tulis dan jalankan kode asli di browser kamu, dapatkan bantuan instan dari tutor AI 24/7, dan lanjutkan di mana kamu tinggalkan di web atau aplikasi.

Kursus
53
Pelajaran
199

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Penanganan Galat dalam Rantai Perintah” gratis?

Ya — teks lengkap “Penanganan Galat dalam Rantai Perintah” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus AI Prompt Engineering, upgrade ke CoddyKit PRO. Kursus AI Prompt Engineering mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Penanganan Galat dalam Rantai Perintah”?

Validasi keluaran perantara dan pulihkan proses dari kegagalan rantai. Kamu berlatih AI Prompt Engineering dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai AI Prompt Engineering?

Tidak diperlukan pengalaman sebelumnya. AI Prompt Engineering di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 4 dari 4.

Berapa lama pelajaran “Penanganan Galat dalam Rantai Perintah” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran AI Prompt Engineering ini?

Ya. Setiap pelajaran AI Prompt Engineering menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Apa Itu Rantai Perintah?
  2. Pola Keluaran-ke-Masukan
  3. Rantai Transformasi Berurutan
  4. Penanganan Galat dalam Rantai Perintah
← Kembali ke AI Prompt Engineering