İstem Zincirlerinde Hata Yönetimi
Ara çıktıları doğrulayın ve zincir başarısızlıklarından kurtulun.
İstem Zincirlerinde Hata Yönetimi, CoddyKit'te ücretsiz bir AI Prompt Engineering dersidir. Bu, 4 dersinin 4. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, AI Prompt Engineering öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. AI Prompt Engineering kursu toplamda 4 dersten oluşur.
Zincirler Neden Başarısız Olur
İstem zincirleri, tek istemli sistemlerde bulunmayan yeni başarısızlık biçimleri ortaya çıkarır. Her adım kendine özgü bir şekilde başarısız olabilir ve hatalar birbirini büyütür — 2. Adımın hatalı çıktısı, sonraki tüm adımları bozar.
Yaygın başarısızlık biçimleri:
- Model, ayrıştırılamayan bozuk JSON döndürür
- Model görevi yanlış anlar ve anlamsal olarak hatalı çıktı üretir
- İstek hız sınırları veya API zaman aşımları adımların başarısız olmasına neden olur
- Uzun bir zincirde bağlam penceresi aşılır
- Model, sonraki adımların gerçek kabul ettiği verileri uydurur
Her Adımdan Sonra Çıktı Doğrulama
İlk savunma hattı, çıktıyı bir sonraki adıma aktarmadan önce her adımın hemen ardından doğrulamaktır. Modelin istediğiniz şeyi döndürdüğünü asla varsaymayın.
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)Geçici Hatalar İçin Yeniden Deneme Mantığı
API hataları (istek hız sınırları, zaman aşımları, sunucu hataları) geçicidir. Ağ düzeyindeki hatalar için üstel beklemeli yeniden deneme mantığı uygulayın:
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}')Anlamsal Doğrulama
Bazı hatalar yapısal olarak geçerli, ancak anlamsal olarak yanlıştır — model geçerli JSON döndürür, fakat değerler hatalıdır. Anlamsal doğruluğu denetlemek için hafif bir doğrulama adımı kullanın:
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))Yedek İstemler
Bir adım yeniden denemelerden sonra doğrulamayı geçemezse, yedek bir istem tüm zincirin çökmesi yerine daha basit ama kullanılabilir bir çıktı üretebilir:
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)Devre Kesiciler
Bir devre kesici, başarısız olan bir zincirin API çağrılarını boşa harcamasını önler. N ardışık başarısızlıktan sonra devreyi açar ve başka API çağrıları yapmadan hemen hata döndürür:
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.')Uzun Zincirlerde Denetim Noktası Kullanımı
Çok sayıda adım veya maliyeti yüksek adımlar içeren zincirlerde, ara sonuçları kaydetmek için denetim noktası kullanımından yararlanın. Geç bir adım başarısız olursa, 1. Adımdan yeniden başlatmak yerine denetim noktasından devam edin:
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.')Kademeli Bozulma
Zincirdeki bir adım başarısız olduğunda ve kurtarılamadığında, kademeli bozulma zincirin tamamen çökmesi yerine kısmi verilerle devam etmesini sağlar:
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.')Yapılandırılmış Hata Günlükleme
Hataları, hangi adımın başarısız olduğunu, girdinin ne olduğunu ve modelin ne döndürdüğünü teşhis etmeye yetecek bağlamla günlüğe kaydedin:
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.')Hata Senaryolarını Sınama
Hataları enjekte ederek hata yönetiminizi açıkça sınayın. API hatalarını ve bozuk çıktıları benzetmek için sahte nesneler kullanın:
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.')Üretimde Zincir Sağlığını İzleme
Kullanıcılar bozulmayı fark etmeden önce tespit etmek için üretimde zincir sağlığı ölçümlerini izleyin:
- Adım başarı oranı: Her adımın ilk denemede başarılı olduğu çalıştırmaların yüzdesi
- Yedek etkinleştirme oranı: Yedek istem ne sıklıkla kullanılıyor?
- Bozulma oranı: Zincir çalıştırmalarının ne kadarı bozulmuş kipte tamamlanıyor?
- Adım gecikmesi: Her adım için p50/p95 gecikmesini izleyin — yavaş bir adım, istem karmaşıklığı sorunlarına işaret eder
- Doğrulama başarısızlık oranı: Yüksek oran, istemin iyileştirilmesi gerektiğini gösterir
Hızlı Kontrol
İstem zincirindeki bir devre kesicinin amacı nedir?
Zincirlerde Hata Yönetimi — Temel Çıkarımlar
Sağlam hata yönetimi, prototip zincirlerini üretim sistemlerinden ayıran unsurdur:
- Modelin doğru verileri döndürdüğünü asla varsaymayın; aşağı akışa aktarmadan önce her adımın çıktısını doğrulayın
- Geçici API hatalarını üstel beklemeyle yeniden deneyin — istek hız sınırları ve zaman aşımları kurtarılabilir
- Birincil istem anlamsal doğrulamayı geçemezse daha basit bir çıktı için yedek istemler kullanın
- Devre kesiciler, tekrarlanan başarısızlıklardan sonra API çağrılarının boşa harcanmasını durdurur
- Uzun zincirlerin geç bir adımın başarısızlığından sonra devam edebilmesi için maliyeti yüksek adımlarda denetim noktaları kullanın
- Zincirin çökmesi yerine kısmi verilerle çalışmasını sürdürmek için kademeli bozulmadan yararlanın
- Üretimde adım başarı oranını, yedek kullanım oranını ve bozulma oranını izleyin
Yapay zeka eğitmeniyle AI Prompt Engineering öğren — ücretsiz
Tarayıcında gerçek kod yaz ve çalıştır, 7/24 yapay zeka eğitmeninden anında yardım al; web'de ya da uygulamada kaldığın yerden devam et.
- Kurslar
- 53
- Dersler
- 199
Sıkça Sorulan Sorular
“İstem Zincirlerinde Hata Yönetimi” dersi ücretsiz mi?
Evet — “İstem Zincirlerinde Hata Yönetimi” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve AI Prompt Engineering kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. AI Prompt Engineering kursu toplamda 4 dersten oluşur.
“İstem Zincirlerinde Hata Yönetimi” dersinde ne öğreneceğim?
Ara çıktıları doğrulayın ve zincir başarısızlıklarından kurtulun. AI Prompt Engineering ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.
AI Prompt Engineering öğrenmeye başlamak için deneyim gerekli mi?
Önceden deneyim gerekmez. CoddyKit'te AI Prompt Engineering, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 4. dersidir.
“İstem Zincirlerinde Hata Yönetimi” dersi ne kadar sürer?
Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.
Bu AI Prompt Engineering dersinde kod yazıp çalıştırabilir miyim?
Evet. Her AI Prompt Engineering dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.
Bu kursun tüm dersleri
- İstem Zincirleme Nedir?
- Çıktıdan Girdiye Kalıplar
- Sıralı Dönüşüm Zincirleri
- İstem Zincirlerinde Hata Yönetimi