0Pricing
AI Prompt Engineering · 강의

모델 업데이트에 따른 회귀 테스트

GPT-4에서 GPT-4o로, 또는 Claude 3에서 3.5로 업그레이드할 때 테스트 모음을 실행합니다.

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

모델 업데이트가 프롬프트를 망가뜨리는 이유

LLM 제공업체는 모델을 정기적으로 업데이트합니다. GPT-4 → GPT-4o → GPT-4o-2024-11-20, Claude 3 → Claude 3.5 → Claude 3.7과 같은 방식입니다. 업데이트할 때마다 모델의 동작이 바뀌며, 대부분의 작업은 개선되지만 특정 프롬프트에서는 간혹 성능이 저하되기도 합니다.

테스트 모음이 없으면 사용자가 문제를 보고하기 전까지 회귀를 알 수 없습니다. 테스트 모음이 있으면 모델 업데이트 후 몇 분 안에 회귀를 감지할 수 있습니다.

모델 업데이트 문제

모델 업데이트로 인해 세 가지 유형의 변경이 발생할 수 있습니다.

  • 개선: 이전에 실패하던 테스트 사례가 이제 통과합니다. 좋은 변화입니다
  • 중립: 동작이 바뀌지 않습니다. 대부분의 테스트가 여기에 해당합니다
  • 회귀: 이전에 통과하던 테스트 사례가 이제 실패합니다. 반드시 조사해야 합니다

회귀율이 1%에 불과해도 중요합니다. 테스트 사례가 200개이고 모델 업데이트 후 2개가 실패하기 시작한다면, 그 2개가 가장 중요한 사용 사례일 수 있습니다.

MODEL_HISTORY = [
    {'model': 'gpt-4', 'deployed': '2023-03-14', 'pass_rate': 0.87},
    {'model': 'gpt-4-turbo', 'deployed': '2023-11-06', 'pass_rate': 0.91},
    {'model': 'gpt-4o', 'deployed': '2024-05-13', 'pass_rate': 0.93},
    {'model': 'gpt-4o-2024-11-20', 'deployed': '2024-11-20', 'pass_rate': None},  # to be measured
]

# Goal: measure pass_rate for the new model before deploying to production

새 모델에서 테스트 모음 실행하기

새 모델 버전이 발표되면 이전 모델과 새 모델 모두에서 전체 테스트 모음을 실행하십시오. 통과율을 비교하고, 동작이 바뀐 구체적인 테스트 사례를 확인하십시오.

import openai
client = openai.OpenAI(api_key='sk-...')

def run_suite_on_model(test_cases, system_prompt, model):
    results = []
    for test in test_cases:
        resp = client.chat.completions.create(
            model=model,
            messages=[
                {'role': 'system', 'content': system_prompt},
                {'role': 'user', 'content': test['input']}
            ],
            temperature=0
        )
        output = resp.choices[0].message.content
        passed = test['evaluator'](output)
        results.append({'id': test['id'], 'passed': passed, 'output': output})
    pass_rate = sum(r['passed'] for r in results) / len(results)
    return results, pass_rate

old_results, old_rate = run_suite_on_model(TEST_CASES, PROMPT, 'gpt-4o')
new_results, new_rate = run_suite_on_model(TEST_CASES, PROMPT, 'gpt-4o-2024-11-20')
print(f'Old: {old_rate:.1%} | New: {new_rate:.1%} | Delta: {(new_rate-old_rate):+.1%}')

모델 버전 간 결과 비교

두 테스트 모음을 모두 실행한 후 상태가 바뀐 사례를 확인하십시오. 통과 → 실패는 회귀이고, 실패 → 통과는 개선입니다.

def diff_results(old_results, new_results):
    old_by_id = {r['id']: r for r in old_results}
    new_by_id = {r['id']: r for r in new_results}

    regressions = []
    improvements = []

    for test_id, new_r in new_by_id.items():
        old_r = old_by_id.get(test_id)
        if old_r is None:
            continue
        if old_r['passed'] and not new_r['passed']:
            regressions.append({'id': test_id, 'old_output': old_r['output'], 'new_output': new_r['output']})
        elif not old_r['passed'] and new_r['passed']:
            improvements.append({'id': test_id})

    print(f'Regressions: {len(regressions)}')
    print(f'Improvements: {len(improvements)}')
    for reg in regressions:
        print(f'  REGRESSED: {reg["id"]}')
        print(f'    Old: {reg["old_output"][:60]}')
        print(f'    New: {reg["new_output"][:60]}')
    return regressions, improvements

regressions, improvements = diff_results(old_results, new_results)

테스트 로그에서 모델 버전 추적하기

모든 테스트 실행 로그에는 정확한 모델 식별자가 포함되어야 합니다. 단순히 'gpt-4o'가 아니라 전체 버전 문자열인 'gpt-4o-2024-11-20'을 기록해야 합니다. OpenAI와 Anthropic은 별칭(예: 'gpt-4o')이 가리키는 모델을 별칭 이름을 바꾸지 않고 자주 업데이트하므로, 로그가 과거 동작을 디버깅하는 데 필수적입니다.

import openai, json
from datetime import datetime, timezone

client = openai.OpenAI(api_key='sk-...')

def run_test_with_version_tracking(test, system_prompt, model_alias):
    resp = client.chat.completions.create(
        model=model_alias,
        messages=[
            {'role': 'system', 'content': system_prompt},
            {'role': 'user', 'content': test['input']}
        ],
        temperature=0
    )
    output = resp.choices[0].message.content
    return {
        'test_id': test['id'],
        'model_alias': model_alias,
        'model_actual': resp.model,  # The exact versioned model ID returned by the API
        'timestamp': datetime.now(timezone.utc).isoformat(),
        'output': output,
        'passed': test['evaluator'](output)
    }

회귀 조사하기

회귀가 발견되면 프롬프트를 업데이트하기 전에 조사하십시오. 프롬프트가 더 나빠진 것인지, 아니면 모델이 동작을 바꿀 만큼 더 나아진 것인지 확인해야 합니다.

예를 들어 GPT-4o의 후속 모델이 형식 지침을 더 엄격하게 따르면서 테스트가 실패할 수 있습니다. 이전 테스트가 약간 규정을 따르지 않는 출력을 기대했기 때문입니다. 이 경우에는 모델이 개선된 것이며 프롬프트가 아니라 테스트를 업데이트해야 합니다.

def investigate_regression(test_id, old_output, new_output, prompt, user_input):
    # Step 1: check if old behavior was actually wrong
    judge_prompt = (
        f'Given this task prompt: {prompt}\n'
        f'And this user input: {user_input}\n\n'
        f'Which output is better?\n'
        f'A) {old_output}\n'
        f'B) {new_output}\n\n'
        'Reply with A or B and one sentence explanation.'
    )
    resp = client.chat.completions.create(
        model='gpt-4o',
        messages=[{'role': 'user', 'content': judge_prompt}],
        temperature=0
    )
    verdict = resp.choices[0].message.content
    print(f'Judge verdict for {test_id}: {verdict}')
    # If judge says B (new output) is better: update the test, not the prompt

프롬프트와 테스트 중 무엇을 업데이트할지 결정하기

회귀를 조사한 후 다음 세 가지 조치 중 하나를 선택하십시오.

  • 프롬프트 업데이트: 같은 동작을 얻으려면 새 모델에 다른 지침 표현이 필요합니다
  • 테스트 업데이트: 이전에 기대한 출력이 잘못되었거나 최적이 아니었습니다. 새 출력이 실제로 더 좋습니다
  • 회귀 수용: 새 모델이 이 작업을 안정적으로 수행하지 못합니다. 이 사용 사례에는 이전 모델 별칭을 사용하십시오
REGRESSION_ACTIONS = {
    'prompt_updated': {
        'when': 'New model ignores instruction the old model followed. Same behavior needed.',
        'action': 'Add stronger/rephrased instruction. Re-run tests on new model.'
    },
    'test_updated': {
        'when': 'New model output is objectively better but fails old test criteria.',
        'action': 'Update expected output in test. Document the improvement.'
    },
    'model_pinned': {
        'when': 'New model cannot perform this task reliably despite prompt changes.',
        'action': 'Pin the model alias to the old versioned ID for this endpoint.'
    }
}

모델 버전 고정하기

모델 업데이트로 인해 수용할 수 없는 회귀가 발생하면 조사하는 동안 모델을 이전 버전 ID로 고정하십시오. 운영 환경에서는 별칭(예: 'gpt-4o')을 사용하지 마십시오. 항상 특정 버전을 사용하십시오.

# Bad practice: alias can point to different model versions over time
client.chat.completions.create(
    model='gpt-4o',  # could be any version at any time
    messages=[...]
)

# Good practice: pin to a specific version for production
client.chat.completions.create(
    model='gpt-4o-2024-11-20',  # guaranteed behavior
    messages=[...]
)

# Track in config
MODEL_CONFIG = {
    'sentiment_classifier': 'gpt-4o-2024-11-20',
    'code_generator': 'gpt-4o-2024-11-20',
    'summarizer': 'gpt-4o-mini-2024-07-18',
}

CI에서 자동화된 회귀 테스트

구성 파일의 모델 버전이 변경되면 회귀 테스트 모음이 자동으로 실행되도록 하십시오. GitHub Actions 또는 유사한 CI를 사용하여 배포 전에 회귀를 감지하십시오.

# .github/workflows/prompt_regression.yml (YAML, shown as comment)
# name: Prompt Regression Tests
# on:
#   push:
#     paths:
#       - 'config/models.json'  # triggers when model version changes
#       - 'prompts/*.txt'       # triggers when prompts change
# jobs:
#   test:
#     runs-on: ubuntu-latest
#     steps:
#       - uses: actions/checkout@v4
#       - name: Install dependencies
#         run: pip install pytest openai jsonschema
#       - name: Run prompt test suite
#         run: pytest tests/prompts/ -v --junitxml=results.xml
#         env:
#           OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}

# In Python: read model version from config
import json
with open('config/models.json') as f:
    MODEL_CONFIG = json.load(f)
MODEL = MODEL_CONFIG['sentiment_classifier']

제공업체 간 회귀 처리하기

회귀 테스트는 제공업체를 전환할 때도 적용됩니다. GPT-4o → Claude, Claude → Gemini와 같은 경우입니다. 같은 테스트 모음을 사용하면 새 제공업체의 동작 차이에 맞게 어떤 프롬프트를 변경해야 하는지 알 수 있습니다.

def cross_provider_test(test_cases, system_prompt, providers):
    all_results = {}
    for provider, config in providers.items():
        results, rate = run_suite_on_model(
            test_cases, system_prompt, model=config['model']
        )
        all_results[provider] = {'rate': rate, 'results': results}
        print(f'{provider}: {rate:.1%}')

    # Find cases that fail on one provider but not another
    for test in test_cases:
        outcomes = {
            p: next(r for r in all_results[p]['results'] if r['id'] == test['id'])['passed']
            for p in providers
        }
        if not all(outcomes.values()):
            failing = [p for p, passed in outcomes.items() if not passed]
            print(f'  {test["id"]}: FAILS on {failing}')

    return all_results

통과율 추세 모니터링하기

테스트 이력 로그를 읽어 시간에 따른 통과율을 그래프로 표시하십시오. 하락 추세는 프롬프트 성능 저하나 모델 드리프트를 나타냅니다. 갑작스러운 하락은 회귀 사건(모델 업데이트 또는 프롬프트 변경)을 나타냅니다.

import json

def plot_pass_rate_trend(history_file='test_history.jsonl'):
    runs = []
    with open(history_file) as f:
        for line in f:
            runs.append(json.loads(line))

    runs.sort(key=lambda r: r['run_id'])

    print('Pass rate trend:')
    for run in runs[-10:]:  # last 10 runs
        bar = '#' * int(run['pass_rate'] * 40)
        print(f"{run['run_id'][:10]} {run['model']:30} {run['pass_rate']:.0%} |{bar}|")

    # Detect regression
    if len(runs) >= 2:
        delta = runs[-1]['pass_rate'] - runs[-2]['pass_rate']
        if delta < -0.05:
            print(f'ALERT: pass rate dropped {delta:.0%} since last run!')

plot_pass_rate_trend()

지식 확인

새 모델 버전으로 인해 테스트가 실패했지만, 조사 결과 새 모델의 출력이 이전 출력보다 실제로 더 나은 것으로 밝혀졌다면 올바른 조치는 무엇입니까?

요약: 모델 업데이트 전반의 회귀 테스트

모델이 업데이트될 때 회귀 테스트에 사용하는 주요 방법은 다음과 같습니다.

  • 이전 모델과 새 모델 모두에서 전체 테스트 모음 실행 — 통과율을 비교하고 구체적인 실패 항목을 비교합니다
  • 정확한 모델 버전 추적 — 별칭만 기록하지 말고 모든 테스트 로그에 기록합니다
  • 각 회귀 조사: 프롬프트 문제인지, 테스트 문제인지, 모델 능력 문제인지 확인합니다
  • 운영 환경에서 모델 고정 — 별칭이 아니라 특정 버전 ID를 사용합니다
  • CI에서 자동화 — 모델 구성이나 프롬프트 파일 변경을 트리거로 사용합니다

다음 강의에서는 도구를 활용하여 완전한 프롬프트 테스트 모음을 구축하는 방법을 다룹니다.

자주 묻는 질문

“모델 업데이트에 따른 회귀 테스트” 강의는 무료인가요?

네 — “모델 업데이트에 따른 회귀 테스트” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 AI Prompt Engineering 강의 전체를 잠금 해제할 수 있습니다. AI Prompt Engineering 강의에는 총 4개의 강의가 포함되어 있습니다.

“모델 업데이트에 따른 회귀 테스트”에서 뭘 배우나요?

GPT-4에서 GPT-4o로, 또는 Claude 3에서 3.5로 업그레이드할 때 테스트 모음을 실행합니다. 브라우저에서 직접 실행하는 실습 코드로 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(으)로 돌아가기