모델 업그레이드는 브레이킹 체인지입니다: TypeScript로 LLM 제공업체용 계약 테스트 구축하기
요약
주요 LLM 제공업체들(Google, Anthropic, OpenAI)이 모델을 지속적으로 업그레이드하면서 API 계약에 빈번하고 예측 불가능한 변경 사항들이 발생하고 있습니다. 이러한 변화는 개발자들에게 의존성 업그레이드와 같은 테스트 스위트 구축의 필요성을 제기합니다. 본 글은 LLM 제공업체용 계약 테스트를 TypeScript로 구축하는 방법을 다룹니다.
핵심 포인트
- LLM 모델 업데이트는 API 계약 변경과 같습니다.
- Google, Anthropic, OpenAI 등 주요 업체에서 빈번한 API 변경이 발생함.
- 모델 문자열 변경은 개발자에게 의존성 업그레이드와 같은 테스트가 필요함을 의미합니다.
- TypeScript를 사용하여 LLM 제공업체별 계약 테스트 스위트를 구축하는 방법을 제시합니다.
모델을 호출하는 대부분의 코드는 무해해 보이는 한 줄을 가지고 있습니다.
model: "claude-sonnet-5"
이것은 설정 변경처럼 느껴집니다.
하지만 이 문자열은 API 계약의 일부입니다.
그리고 이번 달, 그 계약들이 바뀌었습니다.
- 9월 17일, Google은 Antigravity Agent 09-2026을 출시했습니다. 로컬에서 도구를 실행하거나
function_call단계를 파싱하는 경우, "내장된 도구가 변경되었습니다": PascalCase 매개변수와write_file(path, content)가write_to_file또는replace_file_content로 바뀌었습니다. 이전의antigravity-preview-05-2026은 "2026년 10월 5일에 중단됩니다." - 9월 22일, Anthropic은 Claude Opus 5.5를 출시했습니다. 릴리스 노트에 따르면,
thinking: {"type": "disabled"}와{"type": "enabled", ...}는 "400 오류를 반환합니다." 따라서tool_choice타입인any와tool도 마찬가지입니다. - 9월 28일, Anthropic은 Claude Sonnet 5.5를 출시했습니다. 릴리스 노트에는 "Claude Sonnet 5용으로 작성된 코드는 다섯 가지 방식으로 Claude Sonnet 5.5에서 작동하지 않을 수 있다."고 명시되어 있습니다.
- 9월 29일, DevDay에서 OpenAI는 GPT-6.1 Sol을 출시했습니다. 해당 모델 페이지에는 "
none및minimal추론 노력은 지원되지 않습니다."라고 되어 있습니다.
Sonnet 5.5의 다섯 가지 변경 사항은 릴리스 노트에 따르면 다음과 같습니다:
- "사전 사고(up-front thinking)를 비활성화하려면,
disabled대신thinking: {"type": "between_tools"}를 높은(high) 노력 또는 그 이하에서 전송해야 합니다." - "강제 도구 사용(
tool_choice타입any및tool)은 400 오류를 반환합니다." - "사고 블록(Thinking blocks)은 모델과 대화에 연결됩니다."
- "Claude API와 Google Cloud에서 이전에 사용되던
computer_20251124컴퓨터 사용 도구는 더 이상 허용되지 않습니다." - "어드바이저 도구(advisor tool)는 Claude Opus 4.8, Claude Opus 4.7, 그리고 Claude Sonnet 5를 어드바이저로 거부합니다."
What's new page에 "요청을 실패시키지 않으면서 응답 형태를 변경하는" 기능이 추가되었습니다: 툴 호출(tool calls) 사이의 텍스트가 thinking 블록으로 반환됩니다.
400은 크고 명확합니다.
빈 진행 메시지는 조용합니다.
서로 다른 회사들.
같은 패턴입니다.
모델 문자열을 변경하는 것은 의존성 업그레이드(dependency upgrade)입니다. 테스트 스위트가 필요합니다.
그래서 하나를 만들어 봅시다.
API 키는 없습니다. 두 제공업체 모두 모의(mock)입니다: 요청 규칙은 위의 문서를 따르고, 응답은 임의로 생성되었습니다.
목차 (Table of Contents)
- 우리가 만들 것
- 프로젝트 설정
- 1단계: 중립적인 요청 및 응답
- 2단계: 두 모델 버전 모킹하기
- 3단계: 계약(Contract) 작성하기
- 4단계: 두 실행 결과 비교 (Diff) 하기
- 5단계: 문서에서 알려진 오류 확인하기
- 6단계: 게이트를 구축하고 실행하기
- 문제가 발생하는 지점
- 더 큰 아이디어
우리가 만들 것 (What We Are Building)
하나의 체크는 릴리스 노트를 읽습니다. 다른 하나는 두 모델 버전을 비교합니다(diff).
프로젝트 설정 (Project Setup)
Node.js 18 이상이 필요합니다.
mkdir model-upgrade-gate
cd model-upgrade-gate
...
다음 블록들을 순서대로 upgrade-gate.ts로 저장하세요.
1단계: 중립적인 요청 및 응답 (A Neutral Request and Response)
type Req = {
prompt: string;
maxTokens: number;
...
앱의 형태가 아니라, 공급업체 SDK(vendor SDK)를 사용합니다.
계약은 제공업체가 아닌, 여러분의 앱을 설명해야 합니다.
2단계: 두 모델 버전 모킹하기 (Mock Two Model Versions)
// MOCK PROVIDER. 네트워크 연결 없음, API 키 없음. 두 Sonnet 5.5 거절 메시지는
// Anthropic의 문서(9월 28일자)를 따르며, tool_choice 오류는 그곳에서 인용했습니다.
// 다른 오류 텍스트와 모든 응답은 임의로 생성되었습니다.
...
Sonnet 5.5는 disabled 상태의 사고 과정(thinking)과 강제된 도구 사용을 거부합니다.
진행 상황 노트는 또한 thinking 블록으로 이동합니다. 기본값인 display: "omitted" 상태에서는 문서에 텍스트가 비어 있다고 나와 있습니다. 하지만 between_tools를 사용하면 다시 나타납니다.
모든 것에 동의하는 목업은 그저 매우 공손한 거짓말쟁이일 뿐입니다.
Step 3: 계약 작성하기
type Contract = { name: string; req: Req; check: (res: Ok) => string | null };
const weather: Req = { prompt: "Weather in Paris?", maxTokens: 500, tools: ["get_weather"] };
...
일곱 가지 약속. 각 체크는 null 또는 이유를 반환합니다.
거절 계약은 문서를 따릅니다. 거부된 요청은 HTTP 200과 stop_reason: "refusal"을 반환합니다.
Step 4: 두 실행 비교하기
type Result = { name: string; pass: boolean; detail: string };
function runSuite(provider: Provider): Result[] {
...
중요한 전환은 단 하나입니다: 이전에는 통과했지만, 지금은 실패하는 경우.
Step 5: 문서에서 알려진 문제 확인하기
type KnownBreak = { model: string; param: string; bad: string[]; docs: string; source: string };
// 공급업체 문서에서 가져옴, 2026년 10월 3일 확인됨.
...
이것은 사용 중단된 파라미터(deprecated-params) 체크입니다. 각 행은 날짜와 함께 공급업체의 문서에서 가져옵니다.
DEADLINE 라인은 실패가 아닙니다. 서두를 이유입니다.

Step 6: 게이트 구축 및 실행하기
// 임의로 만든 앱의 예시 호출 지점들.
const S5 = "claude-sonnet-5", S55 = "claude-sonnet-5-5";
const callSites: CallSite[] = [
...
실행하기:
npx tsx upgrade-gate.ts
실제 출력:
Upgrade gate, 2026-10-03
Known breaks (from release notes)
...
종료 코드 1. CI가 중단됩니다.
progress text between tools를 보세요. 400 에러는 없습니다. 사용자가 단순히 진행 상황을 보기만 안 되는 것입니다.
조용한 장애(The quiet break)란 상태 코드가 절대 잡아낼 수 없는 문제입니다.
문서에는 수정 사항이 명시되어 있습니다: between_tools, auto에 엄격한 도구 사용 추가, none 대신 low, 그리고 새로운 Antigravity 도구 이름들.
작동 방식의 문제점 (Where It Breaks Down)

목(Mocks)의 표류 (Mocks Drift)
저는 규칙들을 수동으로 복사했습니다. 이 규칙들은 플랫폼별로도 다릅니다: computer_20251124는 Claude API와 Google Cloud에서는 거부되지만, Sonnet 5.5는 Amazon Bedrock에서도 여전히 허용합니다.
녹색 게이트(green gate)를 신뢰하기 전에 실제 API에 대해 계약을 실행해 보세요.
동작이 곧 계약은 아니다 (Behavior Isn't a Contract)
Anthropic은 Sonnet 5.5의
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기