AI Prompt Engineering · 강의

배포 및 롤백 전략

블루-그린 프롬프트 배포, 기능 플래그, 회귀 발생 시 롤백을 다룹니다.

레슨 3/413개 단계

배포 및 롤백 전략은(는) CoddyKit의 무료 AI Prompt Engineering 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 AI Prompt Engineering 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. AI Prompt Engineering 강의에는 총 4개의 강의가 포함되어 있습니다.

프롬프트 배포의 과제

새 프롬프트 버전을 프로덕션 환경에 배포하는 데에는 실제 위험이 따릅니다. 평균 품질을 높이는 변경이 예외적인 상황에서는 품질을 낮추거나, 지연 시간 급증을 일으키거나, 사용자를 혼란스럽게 만들 수 있습니다. 제어된 배포 전략은 영향 범위를 제한하고 신속한 rollback을 가능하게 하여 이러한 위험을 관리합니다.

블루-그린 프롬프트 배포

블루-그린 배포는 두 환경을 유지합니다. 블루는 현재 프로덕션 환경이고 그린은 새 버전 환경입니다. 검증이 끝나면 트래픽을 블루에서 그린으로 원자적으로 전환합니다. 그린에 문제가 생기면 즉시 이전 상태로 전환할 수 있습니다.

  • 중단 시간 없는 전환
  • 두 버전을 동시에 사용할 수 있는 상태로 유지
  • 재배포가 아니라 구성 변경 한 번으로 rollback 수행
# prompt_router.py — blue/green traffic control
class PromptRouter:
    def __init__(self):
        self.slots = {
            'blue': None,   # {'prompt_id': ..., 'version': ...}
            'green': None,
        }
        self.active_slot = 'blue'

    def load_slot(self, slot, prompt_id, version, template):
        self.slots[slot] = {
            'prompt_id': prompt_id,
            'version': version,
            'template': template
        }
        print(f'Loaded {prompt_id}@{version} into {slot} slot')

    def switch_to(self, slot):
        if not self.slots[slot]:
            raise ValueError(f'Slot {slot} is empty')
        self.active_slot = slot
        info = self.slots[slot]
        print(f'Traffic now routed to {slot}: {info["prompt_id"]}@{info["version"]}')

    def get_active_template(self):
        return self.slots[self.active_slot]['template']

점진적 출시를 위한 트래픽 분할

트래픽의 100%를 한 번에 전환하는 대신 새 버전으로 보내는 비율을 점진적으로 높입니다. 일반적인 증가 단계는 1% → 5% → 10% → 25% → 50% → 100%이며, 각 단계에서 품질을 모니터링합니다.

import random

class TrafficSplitter:
    def __init__(self):
        # version_weights: {version_id: percentage}
        self.version_weights = {
            'v1.1.0': 90,
            'v1.2.0': 10
        }

    def select_version(self):
        versions = list(self.version_weights.keys())
        weights = list(self.version_weights.values())
        return random.choices(versions, weights=weights, k=1)[0]

    def update_split(self, new_weights):
        assert sum(new_weights.values()) == 100, 'Weights must sum to 100'
        self.version_weights = new_weights
        print(f'Traffic split updated: {new_weights}')

# Usage
splitter = TrafficSplitter()
for _ in range(5):
    print(splitter.select_version())

# Ramp to 25%
splitter.update_split({'v1.1.0': 75, 'v1.2.0': 25})

프롬프트 출시를 위한 기능 플래그

기능 플래그를 사용하면 전체 출시 전에 특정 사용자나 세그먼트(베타 사용자, 내부 직원)에 새 프롬프트 버전을 활성화할 수 있습니다. 이를 통해 점진적 출시의 안전성과 실제 사용 사례를 대상으로 한 검증을 결합할 수 있습니다.

# Feature flag-based prompt selection
BETA_USER_IDS = {'user_123', 'user_456', 'user_789'}

def select_prompt_version(user_id, prompt_id, registry):
    # Check if user is in beta cohort
    if user_id in BETA_USER_IDS:
        # Try to get a beta version tagged for this prompt
        beta = registry.get_version_by_tag(prompt_id, tag='beta')
        if beta:
            return beta
    # Default: serve active (stable) version
    return registry.get_active(prompt_id)

# Example: LaunchDarkly-style flag check
def select_prompt_ld(user_id, ld_client, registry):
    use_new = ld_client.variation(
        'use-summarize-v2', {'key': user_id}, default=False
    )
    version = 'v2.0.0' if use_new else 'v1.1.0'
    return registry.get_version(prompt_id='summarize-article', version=version)

새 버전 품질 모니터링

새 버전으로 트래픽을 라우팅한 후에는 다음 신호를 실시간으로 모니터링하십시오.

  • 오류율: API 오류, 형식이 잘못된 출력, 구문 분석 실패
  • 지연 시간: P95 응답 시간(새 프롬프트는 더 길고 느릴 수 있음)
  • 품질 점수: LLM 평가자 또는 지표에서 산출한 자동 평가 점수
  • 사용자 신호: 부정 평가 비율, 재시도율, 세션 이탈률
from collections import defaultdict
import time

class VersionMonitor:
    def __init__(self):
        self.metrics = defaultdict(lambda: {
            'calls': 0, 'errors': 0,
            'latency_sum': 0, 'quality_sum': 0
        })

    def record(self, version, latency_ms, quality_score, error=False):
        m = self.metrics[version]
        m['calls'] += 1
        m['latency_sum'] += latency_ms
        m['quality_sum'] += quality_score
        if error:
            m['errors'] += 1

    def report(self, version):
        m = self.metrics[version]
        n = m['calls'] or 1
        return {
            'version': version,
            'calls': m['calls'],
            'error_rate': round(m['errors'] / n, 3),
            'avg_latency_ms': round(m['latency_sum'] / n),
            'avg_quality': round(m['quality_sum'] / n, 2)
        }

품질 저하 시 자동 rollback

수동 rollback은 프로덕션 장애에 대응하기에 너무 느립니다. 위반되면 이전 버전으로 자동 전환되는 임계값인 rollback 트리거를 정의하십시오.

ROLLBACK_THRESHOLDS = {
    'error_rate': 0.05,      # > 5% errors trigger rollback
    'avg_latency_ms': 10000, # > 10s avg latency triggers rollback
    'avg_quality': 3.5       # < 3.5 quality score triggers rollback
}

def check_and_rollback(monitor, registry, version, previous_version):
    report = monitor.report(version)
    triggers = []

    if report['error_rate'] > ROLLBACK_THRESHOLDS['error_rate']:
        triggers.append(f'error_rate={report["error_rate"]}')
    if report['avg_latency_ms'] > ROLLBACK_THRESHOLDS['avg_latency_ms']:
        triggers.append(f'latency={report["avg_latency_ms"]}ms')
    if report['avg_quality'] < ROLLBACK_THRESHOLDS['avg_quality']:
        triggers.append(f'quality={report["avg_quality"]}')

    if triggers:
        print(f'ROLLBACK TRIGGERED: {triggers}')
        registry.activate_version('summarize-article', previous_version)
        alert_oncall(f'Prompt auto-rolled back to {previous_version}: {triggers}')
        return True
    return False

카나리 배포 패턴

카나리는 새 프롬프트 버전을 먼저 받는 소규모 트래픽 구간(1~5%)입니다. 관찰 기간이 지난 후 카나리가 정상적이면 트래픽을 점진적으로 전환합니다. 그렇지 않으면 카나리 사용자에게만 영향을 줍니다.

import time

def canary_deploy(registry, splitter, monitor, new_version, prev_version,
                  soak_minutes=30, stages=[1, 5, 25, 50, 100]):
    for pct in stages:
        splitter.update_split({
            prev_version: 100 - pct,
            new_version: pct
        })
        print(f'Stage: {pct}% canary. Soaking for {soak_minutes} min...')
        time.sleep(soak_minutes * 60)  # wait soak period

        should_rollback = check_and_rollback(
            monitor, registry, new_version, prev_version
        )
        if should_rollback:
            splitter.update_split({prev_version: 100})
            print('Canary aborted. Fully reverted to', prev_version)
            return False
        print(f'Stage {pct}% passed quality check.')

    print(f'Canary complete. {new_version} now at 100%.')
    return True

배포 흐름 조율

완전한 프롬프트 배포 흐름은 검증, 카나리 시작, 모니터링 반복, 최종 전환 또는 rollback을 통합합니다. 이 모든 과정은 자동화하고, 주요 단계에는 사람의 승인 절차를 둡니다.

# deploy_prompt.py — full pipeline
import argparse

def deploy(prompt_id, new_version, prev_version, dry_run=False):
    print(f'=== Deploying {prompt_id}: {prev_version} -> {new_version} ===')

    # 1. Validate new version exists in registry
    artifact = registry.get_version(prompt_id, new_version)
    print(f'Found artifact: {artifact["version"]}')

    # 2. Run offline eval suite
    score = run_eval_suite(artifact['template'])
    if score < 0.90:
        raise RuntimeError(f'Eval score {score} below threshold 0.90')
    print(f'Eval passed: {score}')

    if dry_run:
        print('Dry run complete. Not deploying.')
        return

    # 3. Canary deploy with automatic rollback
    success = canary_deploy(
        registry, splitter, monitor,
        new_version, prev_version,
        soak_minutes=15, stages=[1, 5, 25, 100]
    )

    print('Deployment', 'SUCCEEDED' if success else 'FAILED')

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--new', required=True)
    parser.add_argument('--prev', required=True)
    parser.add_argument('--dry-run', action='store_true')
    args = parser.parse_args()
    deploy('summarize-article', args.new, args.prev, args.dry_run)

수동 rollback 절차

자동 rollback이 실행되지 않았지만 사람이 품질 문제를 발견한 경우, 수동 rollback 대응 지침서가 신속하고 일관된 조치를 보장합니다.

# RUNBOOK: Manual Prompt Rollback
# Estimated time to execute: 2-3 minutes

# Step 1: Identify current and target versions
python manage.py prompt list-versions --prompt-id summarize-article
# Output:
#   v1.2.0  [ACTIVE]  2024-08-15  alice
#   v1.1.0  [stable]  2024-07-01  alice

# Step 2: Activate previous stable version
python manage.py prompt activate --prompt-id summarize-article --version v1.1.0
# Output: Activated summarize-article@v1.1.0

# Step 3: Verify traffic is serving old version
python manage.py prompt verify --prompt-id summarize-article
# Output: Active version: v1.1.0  Serving: 100%

# Step 4: Log the incident
python manage.py incident create \
  --title 'Prompt rollback: summarize-article v1.2.0 -> v1.1.0' \
  --severity P2 \
  --reason 'Quality score dropped from 4.1 to 3.2 after v1.2.0 deploy'

코드로 관리하는 배포 구성

배포 구성을 버전 관리되는 파일에 정의하여 모든 배포 결정을 감사할 수 있고 재현 가능하게 만드십시오.

# deployments/summarize-article.yaml
prompt_id: summarize-article
current_stable: '1.1.0'
canary_config:
  stages: [1, 5, 25, 50, 100]
  soak_minutes_per_stage: 15
rollback_thresholds:
  error_rate_max: 0.05
  latency_p95_max_ms: 8000
  quality_score_min: 3.5
feature_flags:
  beta_group: [user_123, user_456]
alerts:
  pagerduty_key: 'PD_KEY_PLACEHOLDER'
  slack_channel: '#prompt-alerts'

# Load and apply with a deploy script
import yaml

with open('deployments/summarize-article.yaml') as f:
    config = yaml.safe_load(f)

print('Deploying with config:', config['canary_config'])

당직 대응 지침서 및 사후 분석

모든 되돌리기나 사고가 발생한 후에는 사후 분석을 작성하여 발생한 일, 근본 원인, 시간 순서 및 후속 조치 항목을 기록합니다. 운영 절차서에서는 사후 분석을 참조하고, 여기서 얻은 교훈을 반영하여 업데이트해야 합니다.

# Post-mortem template (stored in docs/post-mortems/)

## Incident: summarize-article v1.2.0 quality regression
## Date: 2024-08-15
## Severity: P2
## Duration: 47 minutes (09:15 - 10:02 UTC)

### What happened
Deployed v1.2.0 of summarize-article. At 5% canary, quality score dropped
from 4.1 to 3.0 for articles over 2000 words.

### Root cause
New prompt template removed the explicit length constraint instruction.
Long articles caused the model to generate overly verbose summaries.

### Timeline
09:15  v1.2.0 deployed to 5% canary
09:28  Quality monitor detected avg_quality < 3.5
09:29  Auto-rollback triggered to v1.1.0
09:32  Incident acknowledged by on-call
10:02  Post-mortem drafted

### Action items
- [ ] Add length regression test to eval suite
- [ ] Update canary monitoring to separate metrics by article length
- [ ] Add changelog requirement: 'length behavior' field

빠른 확인

블루-그린 프롬프트 배포에서 그린 슬롯이 품질 검사를 통과하지 못하면 어떻게 됩니까?

배포 전략 요약

운영 환경의 프롬프트 배포에는 위험을 관리하기 위한 체계적인 전략이 필요합니다:

  • 블루-그린: 두 개의 실행 중인 환경을 유지하고 즉시 원자적으로 전환
  • 카나리: 각 단계에서 품질 검사를 수행하며 트래픽을 1% → 5% → 25% → 100%로 점진적으로 확대
  • 기능 플래그: 광범위한 출시 전에 베타 사용자를 대상으로 지정
  • 자동 되돌리기: 임계값(오류율, 지연 시간, 품질)에 따른 복귀
  • 운영 절차서: 당직 엔지니어를 위한 수동 되돌리기 절차를 문서화
  • 사후 분석: 모든 사고 이후 지속적인 개선 수행
무료로 시작

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개 중 3번째 강의입니다.

“배포 및 롤백 전략” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 AI Prompt Engineering 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 AI Prompt Engineering 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. 프롬프트 레지스트리 아키텍처
  2. 프롬프트 버전 관리
  3. 배포 및 롤백 전략
  4. 운영 환경에서 프롬프트 성능 모니터링
← AI Prompt Engineering(으)로 돌아가기