프롬프트 연결에서 오류 처리
중간 출력을 검증하고 연결 과정의 실패에서 복구합니다.
프롬프트 연결에서 오류 처리은(는) CoddyKit의 무료 AI Prompt Engineering 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 AI Prompt Engineering 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. AI Prompt Engineering 강의에는 총 4개의 강의가 포함되어 있습니다.
체인이 실패하는 이유
프롬프트 체인에는 단일 프롬프트 시스템에는 없는 새로운 실패 방식이 발생합니다. 각 단계가 저마다의 방식으로 실패할 수 있으며, 실패가 누적됩니다. 잘못된 2단계 출력은 이후의 모든 단계를 손상시킵니다.
일반적인 실패 방식은 다음과 같습니다.
- 모델이 구문 분석할 수 없는 잘못된 형식의 JSON을 반환합니다
- 모델이 작업을 잘못 이해하여 의미상 잘못된 출력을 생성합니다
- 요청 한도 또는 API 시간 초과로 단계가 실패합니다
- 긴 체인에서 문맥 창의 한도를 초과합니다
- 모델이 데이터를 환각하여 이후 단계가 이를 사실로 취급합니다
모든 단계 후 출력 검증
첫 번째 방어선은 각 단계가 끝난 즉시 출력을 검증한 후 다음 단계로 전달하는 것입니다. 모델이 요청한 내용을 반환했다고 절대 가정하지 마십시오.
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)일시적 오류를 위한 재시도 로직
API 오류(요청 한도, 시간 초과, 서버 오류)는 일시적일 수 있습니다. 네트워크 수준의 오류에는 지수적 대기 시간을 적용하는 재시도 로직을 구현하십시오.
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}')의미 검증
일부 오류는 구조적으로는 유효하지만 의미상 잘못되어 있습니다. 모델이 유효한 JSON을 반환했지만 값이 잘못된 경우입니다. 의미가 올바른지 확인하려면 가벼운 검증 단계를 사용하십시오.
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))대체 프롬프트
재시도 후에도 단계의 검증이 실패하면 대체 프롬프트를 사용하여 전체 체인을 중단하는 대신 더 단순하지만 사용할 수 있는 출력을 생성할 수 있습니다.
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)회로 차단기
회로 차단기는 실패하는 체인이 API 호출을 낭비하지 않도록 합니다. 연속해서 N번 실패하면 회로를 열고 추가 API 호출 없이 즉시 오류를 반환합니다.
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.')긴 체인의 중간 결과 저장
단계가 많거나 비용이 많이 드는 체인에서는 중간 결과를 저장하십시오. 나중 단계가 실패하면 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.')점진적 기능 저하
체인의 한 단계가 실패하고 복구할 수 없는 경우, 점진적 기능 저하를 적용하면 전체를 중단하는 대신 부분적인 데이터로 체인을 계속 진행할 수 있습니다.
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.')구조화된 오류 기록
어느 단계가 실패했는지, 입력이 무엇이었는지, 모델이 무엇을 반환했는지 진단할 수 있을 만큼 충분한 문맥과 함께 오류를 기록하십시오.
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.')오류 상황 테스트
오류를 주입하여 오류 처리를 명시적으로 테스트하십시오. 모의 객체를 사용하여 API 오류와 잘못된 형식의 출력을 시뮬레이션하십시오.
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.')운영 환경에서 체인 상태 모니터링
운영 환경에서는 체인 상태 지표를 추적하여 사용자가 성능 저하를 알아차리기 전에 이를 감지하십시오.
- 단계 성공률: 각 단계가 첫 시도에 성공한 실행의 비율
- 대체 처리 활성화율: 대체 프롬프트가 사용되는 빈도
- 기능 저하율: 기능 저하 모드로 완료되는 체인 실행의 비율
- 단계 지연 시간: 단계별 p50/p95 지연 시간을 추적하십시오. 느린 단계는 프롬프트 복잡성에 문제가 있음을 나타냅니다
- 검증 실패율: 높은 실패율은 프롬프트를 개선해야 한다는 신호입니다
빠른 확인
프롬프트 체인에서 회로 차단기의 목적은 무엇입니까?
체인의 오류 처리 — 핵심 요점
견고한 오류 처리가 프로토타입 체인과 운영 환경용 시스템을 구분합니다.
- 각 단계의 출력을 하위 단계로 전달하기 전에 검증하십시오. 모델이 올바른 데이터를 반환했다고 절대 가정하지 마십시오
- 일시적인 API 오류는 지수적 대기를 적용하여 재시도하십시오. 요청 한도와 시간 초과는 복구할 수 있습니다
- 기본 프롬프트의 의미 검증이 실패하면 더 단순한 출력을 생성하도록 대체 프롬프트를 사용하십시오
- 회로 차단기는 반복되는 실패 후 API 호출 낭비를 막습니다
- 비용이 많이 드는 단계를 중간 저장하여 긴 체인이 나중 단계의 실패 후 재개될 수 있도록 하십시오
- 점진적 기능 저하는 중단하는 대신 부분적인 데이터로 파이프라인을 계속 실행합니다
- 운영 환경에서 단계 성공률, 대체 처리율, 기능 저하율을 추적하십시오
AI 튜터와 함께 AI Prompt Engineering을(를) 배우세요 — 무료
브라우저에서 실제 코드를 작성하고 실행하며, 24/7 AI 튜터로부터 즉각적인 도움을 받고, 웹이나 앱에서 중단한 부분부터 계속 학습하세요.
- 코스
- 53
- 레슨
- 199
자주 묻는 질문
“프롬프트 연결에서 오류 처리” 강의는 무료인가요?
네 — “프롬프트 연결에서 오류 처리” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 AI Prompt Engineering 강의 전체를 잠금 해제할 수 있습니다. AI Prompt Engineering 강의에는 총 4개의 강의가 포함되어 있습니다.
“프롬프트 연결에서 오류 처리”에서 뭘 배우나요?
중간 출력을 검증하고 연결 과정의 실패에서 복구합니다. 브라우저에서 직접 실행하는 실습 코드로 AI Prompt Engineering을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
AI Prompt Engineering을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 AI Prompt Engineering은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 4번째 강의입니다.
“프롬프트 연결에서 오류 처리” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 AI Prompt Engineering 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 AI Prompt Engineering 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- 프롬프트 연결이란 무엇인가
- 출력을 입력으로 연결하는 패턴
- 순차 변환 연결
- 프롬프트 연결에서 오류 처리