<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Schema Regression on jyukki's Blog</title><link>https://jyukki.com/tags/schema-regression/</link><description>Recent content in Schema Regression on jyukki's Blog</description><generator>Hugo -- 0.147.0</generator><language>ko-kr</language><lastBuildDate>Thu, 30 Apr 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://jyukki.com/tags/schema-regression/index.xml" rel="self" type="application/rss+xml"/><item><title>2026 개발 트렌드: Tool Contract Test, 에이전트 도구 연동은 프롬프트보다 스키마 회귀 테스트가 먼저다</title><link>https://jyukki.com/posts/2026-04-30-tool-contract-test-agent-runtime-trend/</link><pubDate>Thu, 30 Apr 2026 00:00:00 +0000</pubDate><guid>https://jyukki.com/posts/2026-04-30-tool-contract-test-agent-runtime-trend/</guid><description>도구 호출이 늘어난 지금, 에이전트 품질은 프롬프트보다 도구 계약의 안정성에서 더 자주 무너집니다. 요즘 팀들이 tool contract test와 schema canary를 먼저 붙이는 이유를 정리합니다.</description><content:encoded><![CDATA[<p>요즘 에이전트 운영에서 가장 과소평가되는 문제 하나를 꼽으라면, 저는 모델 자체보다 <strong>도구 계약 드리프트</strong>를 들고 싶습니다. 팀들은 종종 실패를 &ldquo;프롬프트가 약했다&quot;로 해석하지만, 실제 로그를 뜯어 보면 더 자주 보이는 건 다른 종류의 문제입니다. 필수 필드 이름이 바뀌고, enum 값 하나가 늘어나고, 권한 전제조건이 조정되고, 응답 JSON의 중첩이 살짝 바뀌는 순간 잘 돌던 자동화가 갑자기 무너집니다. 에이전트가 똑똑하지 않아서가 아니라, <strong>도구와 런타임 사이 계약이 조용히 변했기 때문</strong>입니다.</p>
<p>이 변화는 MCP, WebMCP, 브라우저 액션, 사내 Admin API, 배포 도구가 늘어날수록 더 커집니다. 도구 수가 3개일 때는 사람이 로그를 보며 잡을 수 있지만, 20개를 넘고 모델·프롬프트·도구 버전이 동시에 바뀌기 시작하면 수동 감시는 금방 한계에 닿습니다. 그래서 최근 흐름은 프롬프트 튜닝 경쟁보다, <strong>tool contract test와 schema canary를 먼저 깔아 두는 운영 체계</strong> 쪽으로 이동하고 있습니다. 이 관점은 <a href="/posts/2026-04-04-schema-constrained-output-runtime-validator-trend/">Schema-Constrained Output</a>, <a href="/posts/2026-04-05-tool-permission-manifest-runtime-attestation-trend/">Tool Permission Manifest</a>, <a href="/posts/2026-04-16-context-contract-registry-agent-input-governance-trend/">Context Contract Registry</a>, <a href="/posts/2026-04-25-model-release-canary-regression-budget-trend/">Model Release Canary</a>, <a href="/posts/2026-03-02-mcp-tooling-security-governance-trend/">MCP 도구 보안·거버넌스</a>와 같은 축 위에 있습니다.</p>
<h2 id="이-글에서-얻는-것">이 글에서 얻는 것</h2>
<ul>
<li>왜 에이전트 도구 품질의 핵심이 프롬프트보다 <strong>계약 안정성</strong>으로 이동하는지 이해할 수 있습니다.</li>
<li>tool contract test를 어디까지 작성해야 하는지, 과설계하지 않고 시작하는 기준을 잡을 수 있습니다.</li>
<li><code>tool_schema_error_rate</code>, <code>invalid_argument_rate</code>, <code>side_effect_rollback_rate</code> 같은 <strong>실무 지표</strong>를 어떻게 볼지 감을 잡을 수 있습니다.</li>
<li>모델 변경, 프롬프트 변경, 도구 버전 변경을 하나로 뭉개지 않고 분리해서 운영하는 방법을 가져갈 수 있습니다.</li>
</ul>
<h2 id="핵심-개념이슈">핵심 개념/이슈</h2>
<h3 id="1-도구-호출-실패는-이제-모델-품질-문제보다-계약-변화-문제일-때가-많다">1) 도구 호출 실패는 이제 모델 품질 문제보다 계약 변화 문제일 때가 많다</h3>
<p>에이전트가 답변만 하던 시절에는 품질 이슈의 대부분이 추론이나 사실성 문제였습니다. 하지만 도구 호출이 늘어난 지금은 실패 지형이 달라졌습니다. 대표적인 예는 아래와 같습니다.</p>
<ul>
<li><code>required</code> 필드가 추가됐는데 프롬프트는 그대로라 호출이 계속 실패</li>
<li>enum 값이 <code>soft</code>/<code>hard</code>에서 <code>soft</code>/<code>standard</code>/<code>hard</code>로 바뀌며 잘못된 값 전송</li>
<li>읽기 전용 도구였는데 승인 토큰이 필수로 바뀌어 permission deny 급증</li>
<li>응답 구조가 <code>data.items[]</code>에서 <code>items[]</code>로 바뀌었는데 후속 파서가 그대로라 handoff 실패</li>
<li>도구 설명은 동일하지만 side effect 범위가 달라져 사람이 기대한 안전선이 깨짐</li>
</ul>
<p>이 문제는 <a href="/posts/2026-04-04-schema-constrained-output-runtime-validator-trend/">Schema-Constrained Output</a>이 왜 중요한지 보여 줍니다. 에이전트가 자연어로 얼추 맞게 말해도, 도구는 결국 <strong>정확한 필드와 정확한 조건</strong>을 요구합니다. 도구 수가 늘수록 성패를 가르는 건 언어 감각보다 계약 정합성입니다.</p>
<h3 id="2-mcp나-표준-프로토콜이-있어도-tool-contract-test는-사라지지-않는다">2) MCP나 표준 프로토콜이 있어도 tool contract test는 사라지지 않는다</h3>
<p>가끔 &ldquo;MCP를 쓰면 표준화됐으니 안정성 문제도 줄지 않나&quot;라는 질문을 받습니다. 절반만 맞는 말입니다. 프로토콜이 표준화되면 전송 방식과 discovery는 쉬워집니다. 하지만 실제 장애는 그 위에서 여전히 생깁니다.</p>
<ul>
<li>도구 설명 텍스트 변경</li>
<li>필수 인자 추가 또는 의미 변경</li>
<li>권한 승격 전제조건 추가</li>
<li>응답 구조 개편</li>
<li>timeout, retry, rate limit 정책 조정</li>
</ul>
<p>즉 표준 프로토콜은 <strong>연결 비용을 줄여 주지만 운영 drift를 없애주지는 않습니다</strong>. 그래서 <a href="/posts/2026-03-02-mcp-tooling-security-governance-trend/">MCP 도구 보안·거버넌스</a>에서 말한 권한·감사 원칙과, <a href="/posts/2026-04-05-tool-permission-manifest-runtime-attestation-trend/">Tool Permission Manifest</a>에서 다룬 실행 범위 통제가 여전히 중요합니다. 연결이 쉬워질수록 잘못된 호출이 빠르게 늘 수 있기 때문입니다.</p>
<h3 id="3-좋은-contract-test는-모든-json-스냅샷을-얼리는-것이-아니라-실패-비싼-경계를-고정한다">3) 좋은 contract test는 모든 JSON 스냅샷을 얼리는 것이 아니라 실패 비싼 경계를 고정한다</h3>
<p>contract test를 만들 때 흔히 두 극단으로 갑니다. 하나는 아무것도 안 해서 drift를 전부 런타임에서 맞는 경우, 다른 하나는 응답 전체를 지나치게 고정해 사소한 변경에도 테스트가 깨지는 경우입니다. 실무적으로는 <strong>비용이 큰 경계만 고정</strong>하는 쪽이 낫습니다.</p>
<p>우선순위를 잡는 기준은 보통 아래 순서면 충분합니다.</p>
<ol>
<li>외부 효과가 큰 도구, 예를 들어 배포, 데이터 수정, 외부 전송</li>
<li>호출 빈도가 높은 핵심 읽기 도구, 예를 들어 검색, 문서 조회, 티켓 조회</li>
<li>후속 자동화를 여는 허브 도구, 예를 들어 파일 목록, 상태 조회, 티켓 생성</li>
</ol>
<p>테스트 범위도 모두 같을 필요가 없습니다.</p>
<ul>
<li><strong>입력 계약 테스트</strong>: 필수 필드, enum, 타입, 범위</li>
<li><strong>권한 전제조건 테스트</strong>: 승인 필요 여부, role/tenant 제한</li>
<li><strong>출력 계약 테스트</strong>: 후속 노드가 의존하는 핵심 필드 존재 여부</li>
<li><strong>실패 매핑 테스트</strong>: 4xx/5xx/timeout이 어떤 오류 코드로 올라오는지</li>
</ul>
<p>이 접근은 <a href="/posts/2026-04-16-context-contract-registry-agent-input-governance-trend/">Context Contract Registry</a>와 잘 맞습니다. 핵심은 도구 설명을 예쁘게 적는 것이 아니라, <strong>어떤 입력과 출력이 다음 행동을 열어주는지 고정하는 것</strong>입니다.</p>
<h3 id="4-모델-canary와-tool-canary를-분리하지-않으면-원인-규명이-꼬인다">4) 모델 canary와 tool canary를 분리하지 않으면 원인 규명이 꼬인다</h3>
<p>모델을 바꾼 날 도구 버전도 올리고 프롬프트도 손보면, 실패가 났을 때 원인을 분리하기 어렵습니다. 이건 운영에서 굉장히 비싼 실수입니다. 그래서 최근 잘하는 팀은 canary 축을 최소 세 개로 나눕니다.</p>
<ul>
<li><strong>model canary</strong>: 같은 도구 계약, 다른 모델</li>
<li><strong>prompt canary</strong>: 같은 모델, 같은 도구 계약, 다른 지시문</li>
<li><strong>tool canary</strong>: 같은 모델, 같은 프롬프트, 다른 도구 버전 또는 스키마</li>
</ul>
<p>이렇게 나누면 <code>tool_schema_error_rate</code>가 올랐을 때 모델 회귀인지, 설명 텍스트 변화인지, API 응답 변경인지 훨씬 빨리 좁힐 수 있습니다. 이 점은 <a href="/posts/2026-04-25-model-release-canary-regression-budget-trend/">Model Release Canary</a>의 핵심과도 닿아 있습니다. 운영에서 중요한 건 최고 점수가 아니라, <strong>회귀 원인을 몇 분 안에 분해할 수 있느냐</strong>입니다.</p>
<h3 id="5-앞으로의-품질-지표는-tool-success-하나로는-부족하다">5) 앞으로의 품질 지표는 tool success 하나로는 부족하다</h3>
<p>도구 호출이 많은 환경에서 <code>tool_success_rate</code> 하나만 보면 위험합니다. 성공처럼 보이지만 잘못된 파라미터로 side effect가 엇나갈 수도 있고, 응답은 200이어도 후속 노드가 필요한 필드가 없어 실패할 수 있기 때문입니다.</p>
<p>시작 지표는 아래 정도가 현실적입니다.</p>
<ul>
<li><code>tool_schema_error_rate</code>: <strong>0.5% 이하</strong> 목표</li>
<li><code>invalid_argument_rate</code>: <strong>1% 이하</strong> 목표</li>
<li><code>permission_deny_unexpected_rate</code>: <strong>0.2% 이하</strong> 목표</li>
<li><code>side_effect_rollback_rate</code>: <strong>0.1% 이하</strong> 목표</li>
<li><code>contract_test_coverage_on_top_tools</code>: 상위 10개 도구 기준 <strong>80% 이상</strong></li>
<li><code>mean_time_to_detect_tool_drift</code>: <strong>15분 이하</strong></li>
</ul>
<p>여기서 중요한 우선순위는 보통 <strong>잘못된 성공 방지 &gt; 명시적 실패 탐지 &gt; 비용 최적화 &gt; 호출 속도</strong> 순입니다. 배포 도구가 틀린 대상에 성공하는 것보다, 차라리 schema mismatch로 빨리 막히는 편이 낫습니다.</p>
<h2 id="실무-적용">실무 적용</h2>
<h3 id="1-어디서부터-테스트할-것인가">1) 어디서부터 테스트할 것인가</h3>
<p>처음부터 모든 도구를 다 잡을 필요는 없습니다. 저는 보통 아래처럼 시작합니다.</p>
<ul>
<li>상위 10개 핵심 도구 선정</li>
<li>그중 side effect가 있는 도구를 1순위로 승격</li>
<li>읽기 전용이지만 후속 자동화의 허브인 도구를 2순위로 배치</li>
<li>나머지는 runtime validator와 로그 수집만 우선</li>
</ul>
<p>이때 상위 10개를 고르는 기준은 단순 호출 횟수보다 <strong>실패 비용 × 호출 빈도</strong>가 낫습니다. 하루 100번 쓰는 배포 도구가 하루 1만 번 쓰는 문서 검색보다 먼저 테스트 대상일 수 있습니다.</p>
<h3 id="2-contract-test의-최소-구성">2) contract test의 최소 구성</h3>
<p>작게 시작해도 아래 네 개는 있으면 좋습니다.</p>
<ol>
<li><strong>golden request 세트</strong>
<ul>
<li>정상 호출 5<del>10개, 실패 호출 2</del>3개</li>
</ul>
</li>
<li><strong>schema validator</strong>
<ul>
<li>필수 필드, enum, 타입 체크</li>
</ul>
</li>
<li><strong>permission precondition test</strong>
<ul>
<li>승인 또는 권한 없는 상황에서 기대한 방식으로 거절되는지 확인</li>
</ul>
</li>
<li><strong>downstream compatibility test</strong>
<ul>
<li>응답에서 후속 노드가 쓰는 핵심 필드가 남아 있는지 확인</li>
</ul>
</li>
</ol>
<p>핵심은 예쁜 테스트 프레임워크보다, drift가 생겼을 때 <strong>사용자 영향 전에 막을 수 있느냐</strong>입니다. 이건 <a href="/posts/2026-04-10-test-evidence-pipeline-ai-change-review-trend/">Test Evidence Pipeline</a>이 강조하는 증거 중심 운영과도 연결됩니다.</p>
<h3 id="3-운영-기준-숫자">3) 운영 기준 숫자</h3>
<p>빠른 출발 기준은 이 정도면 충분합니다.</p>
<ul>
<li>새 도구 추가 시 canary 비율 **5%**로 시작</li>
<li>상위 핵심 도구 10개 중 <strong>8개 이상</strong> contract test 확보</li>
<li>schema drift 감지 후 rollback 또는 route block까지 <strong>15분 이내</strong></li>
<li>side effect 도구는 human gate 누락률 <strong>0% 목표</strong></li>
<li>동일 주간에 모델·프롬프트·도구 스키마 동시 변경은 <strong>금지</strong> 또는 강한 승인 게이트 적용</li>
</ul>
<p>특히 마지막 기준이 중요합니다. 세 축을 동시에 바꾸면 원인 추적 시간이 길어지고, 장애가 났을 때 되돌리는 비용이 커집니다.</p>
<h3 id="4-2주-도입-플랜">4) 2주 도입 플랜</h3>
<p><strong>1주차</strong></p>
<ul>
<li>상위 핵심 도구 10개 선정</li>
<li>각 도구의 필수 입력, 출력 핵심 필드, 권한 전제조건 기록</li>
<li><code>tool_schema_error</code>, <code>invalid_argument</code>, <code>permission_deny</code> 로그를 한 대시보드로 통합</li>
</ul>
<p><strong>2주차</strong></p>
<ul>
<li>side effect 도구 3~5개에 contract test 추가</li>
<li>읽기 전용 핵심 도구 2~3개에 golden request 세트 추가</li>
<li>모델 canary와 tool canary를 분리해 1회 실행</li>
</ul>
<p>이렇게만 해도 &ldquo;프롬프트 문제인 줄 알았는데 사실은 도구 스키마 변경이었다&rdquo; 같은 사건을 훨씬 빨리 잡을 수 있습니다.</p>
<h3 id="5-실패-시나리오별-최소-contract-test-묶음">5) 실패 시나리오별 최소 contract test 묶음</h3>
<p>실무에서 가장 효과가 큰 방법은 도구마다 거대한 테스트 스위트를 만드는 게 아니라, <strong>운영에서 실제로 많이 터지는 실패 모드 기준으로 최소 세트</strong>를 고정하는 것입니다. 예를 들어 배포 도구라면 <code>정상 배포 요청</code>, <code>필수 필드 누락</code>, <code>권한 없는 호출</code>, <code>환경명 enum 오입력</code>, <code>rollback 파라미터 누락</code> 정도만 있어도 초반 회귀를 많이 막을 수 있습니다. 파일 수정 도구라면 <code>대상 경로 없음</code>, <code>읽기 전용 경로</code>, <code>예상 diff 과다</code>, <code>dry-run과 실제 실행 결과 차이</code>를 따로 보는 편이 낫고, 브라우저 자동화 도구라면 <code>selector drift</code>, <code>권한 팝업</code>, <code>로그인 만료</code>, <code>응답 지연</code>을 fixture로 남겨 두는 쪽이 유효합니다.</p>
<p>중요한 점은 모든 테스트를 성공 케이스로만 채우지 않는 것입니다. 운영 장애는 보통 &ldquo;될 때는 된다&quot;보다 &ldquo;실패했을 때 어떤 코드와 어떤 메시지로 막히는가&quot;에서 갈립니다. 그래서 최소 세트도 <code>성공 2~3개 + 실패 2~3개 + 권한/정책 1~2개</code> 정도로 섞는 편이 좋습니다. 이때 실패 응답을 단순 문자열 비교로 얼리기보다, <code>error_code</code>, <code>retryable</code>, <code>approval_required</code>, <code>side_effect_started</code> 같은 핵심 필드만 고정하면 유지비도 과하게 커지지 않습니다.</p>
<p>추가로 팀이 자주 놓치는 부분이 <strong>사람 승인 전제조건</strong>입니다. 승인 기반 도구는 schema만 맞아도 실제 실행 가능성이 보장되지 않습니다. 그래서 golden contract에 &ldquo;승인 없음&rdquo;, &ldquo;승인 있음&rdquo;, &ldquo;승인 만료&rdquo; 세 상태를 최소한 한 번씩 넣어 두면 운영 사고를 훨씬 빨리 줄일 수 있습니다. 특히 <a href="/posts/2026-04-14-execution-receipt-agent-operations-trend/">Execution Receipt</a>나 <a href="/posts/2026-04-23-review-ops-unified-human-gate-trend/">Review Ops Unified Human Gate</a> 같은 흐름과 같이 보면, contract test는 단순 파서 점검이 아니라 <strong>실행 경계와 승인 경계를 함께 검증하는 장치</strong>라는 점이 더 또렷해집니다.</p>
<h2 id="트레이드오프주의점">트레이드오프/주의점</h2>
<ol>
<li>
<p><strong>과도한 스냅샷 고정은 유지비를 키운다</strong><br>
전체 응답을 전부 고정하면 사소한 텍스트 변경에도 테스트가 깨져 피로도가 커집니다. 핵심 필드와 위험한 경계 위주로 고정해야 합니다.</p>
</li>
<li>
<p><strong>테스트가 있다고 안전한 것은 아니다</strong><br>
도구 설명은 통과해도 권한 정책이나 rate limit이 바뀌면 운영 사고는 여전히 납니다. 계약 테스트와 운영 로그를 같이 봐야 합니다.</p>
</li>
<li>
<p><strong>읽기 전용 도구만 보고 안심하면 안 된다</strong><br>
읽기 도구 응답 구조가 바뀌면 후속 생성·수정 노드가 잘못된 결정을 내릴 수 있습니다. side effect 도구가 아니어도 허브 도구는 중요합니다.</p>
</li>
<li>
<p><strong>사람 승인과 contract test는 대체 관계가 아니다</strong><br>
배포, 데이터 수정, 외부 전송은 테스트가 있어도 마지막 human gate가 필요합니다. 테스트는 승인을 없애는 장치가 아니라, 승인 전에 이상을 더 빨리 찾는 장치입니다.</p>
</li>
</ol>
<h2 id="체크리스트-또는-연습">체크리스트 또는 연습</h2>
<h3 id="체크리스트">체크리스트</h3>
<ul>
<li><input disabled="" type="checkbox"> 상위 핵심 도구 10개와 실패 비용이 정리돼 있다.</li>
<li><input disabled="" type="checkbox"> 필수 입력 필드, enum, 권한 전제조건이 문서화돼 있다.</li>
<li><input disabled="" type="checkbox"> <code>tool_schema_error</code>, <code>invalid_argument</code>, <code>permission_deny</code>를 분리해 본다.</li>
<li><input disabled="" type="checkbox"> 모델 변경, 프롬프트 변경, 도구 스키마 변경을 같은 배포로 묶지 않는다.</li>
<li><input disabled="" type="checkbox"> side effect 도구에는 contract test와 human gate가 함께 있다.</li>
<li><input disabled="" type="checkbox"> drift 감지 후 차단 또는 rollback까지 목표 시간이 정해져 있다.</li>
</ul>
<h3 id="연습-과제">연습 과제</h3>
<ol>
<li>현재 팀의 핵심 도구 10개를 적고, 실패 비용이 높은 순서대로 다시 정렬해 보세요.</li>
<li>그중 1개를 골라 필수 필드, 허용 enum, 권한 전제조건, 실패 코드 매핑 표를 만들어 보세요.</li>
<li>최근 2주간 tool failure 로그를 분류해 보고, 프롬프트 문제와 계약 문제의 비율을 따져 보세요.</li>
<li>같은 모델과 프롬프트를 유지한 채 도구 스키마만 바뀌는 canary 시나리오를 1개 설계해 보세요.</li>
</ol>
<h2 id="관련-글">관련 글</h2>
<ul>
<li><a href="/posts/2026-04-04-schema-constrained-output-runtime-validator-trend/">Schema-Constrained Output Runtime Validator</a></li>
<li><a href="/posts/2026-04-05-tool-permission-manifest-runtime-attestation-trend/">Tool Permission Manifest와 Runtime Attestation</a></li>
<li><a href="/posts/2026-04-10-test-evidence-pipeline-ai-change-review-trend/">Test Evidence Pipeline</a></li>
<li><a href="/posts/2026-04-16-context-contract-registry-agent-input-governance-trend/">Context Contract Registry</a></li>
<li><a href="/posts/2026-04-25-model-release-canary-regression-budget-trend/">Model Release Canary</a></li>
<li><a href="/posts/2026-03-02-mcp-tooling-security-governance-trend/">MCP 도구 보안·거버넌스</a></li>
</ul>
]]></content:encoded></item></channel></rss>