요즘 에이전트 운영에서 가장 과소평가되는 문제 하나를 꼽으라면, 저는 모델 자체보다 도구 계약 드리프트를 들고 싶습니다. 팀들은 종종 실패를 “프롬프트가 약했다"로 해석하지만, 실제 로그를 뜯어 보면 더 자주 보이는 건 다른 종류의 문제입니다. 필수 필드 이름이 바뀌고, enum 값 하나가 늘어나고, 권한 전제조건이 조정되고, 응답 JSON의 중첩이 살짝 바뀌는 순간 잘 돌던 자동화가 갑자기 무너집니다. 에이전트가 똑똑하지 않아서가 아니라, 도구와 런타임 사이 계약이 조용히 변했기 때문입니다.

이 변화는 MCP, WebMCP, 브라우저 액션, 사내 Admin API, 배포 도구가 늘어날수록 더 커집니다. 도구 수가 3개일 때는 사람이 로그를 보며 잡을 수 있지만, 20개를 넘고 모델·프롬프트·도구 버전이 동시에 바뀌기 시작하면 수동 감시는 금방 한계에 닿습니다. 그래서 최근 흐름은 프롬프트 튜닝 경쟁보다, tool contract test와 schema canary를 먼저 깔아 두는 운영 체계 쪽으로 이동하고 있습니다. 이 관점은 Schema-Constrained Output, Tool Permission Manifest, Context Contract Registry, Model Release Canary, MCP 도구 보안·거버넌스와 같은 축 위에 있습니다.

이 글에서 얻는 것

  • 왜 에이전트 도구 품질의 핵심이 프롬프트보다 계약 안정성으로 이동하는지 이해할 수 있습니다.
  • tool contract test를 어디까지 작성해야 하는지, 과설계하지 않고 시작하는 기준을 잡을 수 있습니다.
  • tool_schema_error_rate, invalid_argument_rate, side_effect_rollback_rate 같은 실무 지표를 어떻게 볼지 감을 잡을 수 있습니다.
  • 모델 변경, 프롬프트 변경, 도구 버전 변경을 하나로 뭉개지 않고 분리해서 운영하는 방법을 가져갈 수 있습니다.

핵심 개념/이슈

1) 도구 호출 실패는 이제 모델 품질 문제보다 계약 변화 문제일 때가 많다

에이전트가 답변만 하던 시절에는 품질 이슈의 대부분이 추론이나 사실성 문제였습니다. 하지만 도구 호출이 늘어난 지금은 실패 지형이 달라졌습니다. 대표적인 예는 아래와 같습니다.

  • required 필드가 추가됐는데 프롬프트는 그대로라 호출이 계속 실패
  • enum 값이 soft/hard에서 soft/standard/hard로 바뀌며 잘못된 값 전송
  • 읽기 전용 도구였는데 승인 토큰이 필수로 바뀌어 permission deny 급증
  • 응답 구조가 data.items[]에서 items[]로 바뀌었는데 후속 파서가 그대로라 handoff 실패
  • 도구 설명은 동일하지만 side effect 범위가 달라져 사람이 기대한 안전선이 깨짐

이 문제는 Schema-Constrained Output이 왜 중요한지 보여 줍니다. 에이전트가 자연어로 얼추 맞게 말해도, 도구는 결국 정확한 필드와 정확한 조건을 요구합니다. 도구 수가 늘수록 성패를 가르는 건 언어 감각보다 계약 정합성입니다.

2) MCP나 표준 프로토콜이 있어도 tool contract test는 사라지지 않는다

가끔 “MCP를 쓰면 표준화됐으니 안정성 문제도 줄지 않나"라는 질문을 받습니다. 절반만 맞는 말입니다. 프로토콜이 표준화되면 전송 방식과 discovery는 쉬워집니다. 하지만 실제 장애는 그 위에서 여전히 생깁니다.

  • 도구 설명 텍스트 변경
  • 필수 인자 추가 또는 의미 변경
  • 권한 승격 전제조건 추가
  • 응답 구조 개편
  • timeout, retry, rate limit 정책 조정

즉 표준 프로토콜은 연결 비용을 줄여 주지만 운영 drift를 없애주지는 않습니다. 그래서 MCP 도구 보안·거버넌스에서 말한 권한·감사 원칙과, Tool Permission Manifest에서 다룬 실행 범위 통제가 여전히 중요합니다. 연결이 쉬워질수록 잘못된 호출이 빠르게 늘 수 있기 때문입니다.

3) 좋은 contract test는 모든 JSON 스냅샷을 얼리는 것이 아니라 실패 비싼 경계를 고정한다

contract test를 만들 때 흔히 두 극단으로 갑니다. 하나는 아무것도 안 해서 drift를 전부 런타임에서 맞는 경우, 다른 하나는 응답 전체를 지나치게 고정해 사소한 변경에도 테스트가 깨지는 경우입니다. 실무적으로는 비용이 큰 경계만 고정하는 쪽이 낫습니다.

우선순위를 잡는 기준은 보통 아래 순서면 충분합니다.

  1. 외부 효과가 큰 도구, 예를 들어 배포, 데이터 수정, 외부 전송
  2. 호출 빈도가 높은 핵심 읽기 도구, 예를 들어 검색, 문서 조회, 티켓 조회
  3. 후속 자동화를 여는 허브 도구, 예를 들어 파일 목록, 상태 조회, 티켓 생성

테스트 범위도 모두 같을 필요가 없습니다.

  • 입력 계약 테스트: 필수 필드, enum, 타입, 범위
  • 권한 전제조건 테스트: 승인 필요 여부, role/tenant 제한
  • 출력 계약 테스트: 후속 노드가 의존하는 핵심 필드 존재 여부
  • 실패 매핑 테스트: 4xx/5xx/timeout이 어떤 오류 코드로 올라오는지

이 접근은 Context Contract Registry와 잘 맞습니다. 핵심은 도구 설명을 예쁘게 적는 것이 아니라, 어떤 입력과 출력이 다음 행동을 열어주는지 고정하는 것입니다.

4) 모델 canary와 tool canary를 분리하지 않으면 원인 규명이 꼬인다

모델을 바꾼 날 도구 버전도 올리고 프롬프트도 손보면, 실패가 났을 때 원인을 분리하기 어렵습니다. 이건 운영에서 굉장히 비싼 실수입니다. 그래서 최근 잘하는 팀은 canary 축을 최소 세 개로 나눕니다.

  • model canary: 같은 도구 계약, 다른 모델
  • prompt canary: 같은 모델, 같은 도구 계약, 다른 지시문
  • tool canary: 같은 모델, 같은 프롬프트, 다른 도구 버전 또는 스키마

이렇게 나누면 tool_schema_error_rate가 올랐을 때 모델 회귀인지, 설명 텍스트 변화인지, API 응답 변경인지 훨씬 빨리 좁힐 수 있습니다. 이 점은 Model Release Canary의 핵심과도 닿아 있습니다. 운영에서 중요한 건 최고 점수가 아니라, 회귀 원인을 몇 분 안에 분해할 수 있느냐입니다.

5) 앞으로의 품질 지표는 tool success 하나로는 부족하다

도구 호출이 많은 환경에서 tool_success_rate 하나만 보면 위험합니다. 성공처럼 보이지만 잘못된 파라미터로 side effect가 엇나갈 수도 있고, 응답은 200이어도 후속 노드가 필요한 필드가 없어 실패할 수 있기 때문입니다.

시작 지표는 아래 정도가 현실적입니다.

  • tool_schema_error_rate: 0.5% 이하 목표
  • invalid_argument_rate: 1% 이하 목표
  • permission_deny_unexpected_rate: 0.2% 이하 목표
  • side_effect_rollback_rate: 0.1% 이하 목표
  • contract_test_coverage_on_top_tools: 상위 10개 도구 기준 80% 이상
  • mean_time_to_detect_tool_drift: 15분 이하

여기서 중요한 우선순위는 보통 잘못된 성공 방지 > 명시적 실패 탐지 > 비용 최적화 > 호출 속도 순입니다. 배포 도구가 틀린 대상에 성공하는 것보다, 차라리 schema mismatch로 빨리 막히는 편이 낫습니다.

실무 적용

1) 어디서부터 테스트할 것인가

처음부터 모든 도구를 다 잡을 필요는 없습니다. 저는 보통 아래처럼 시작합니다.

  • 상위 10개 핵심 도구 선정
  • 그중 side effect가 있는 도구를 1순위로 승격
  • 읽기 전용이지만 후속 자동화의 허브인 도구를 2순위로 배치
  • 나머지는 runtime validator와 로그 수집만 우선

이때 상위 10개를 고르는 기준은 단순 호출 횟수보다 실패 비용 × 호출 빈도가 낫습니다. 하루 100번 쓰는 배포 도구가 하루 1만 번 쓰는 문서 검색보다 먼저 테스트 대상일 수 있습니다.

2) contract test의 최소 구성

작게 시작해도 아래 네 개는 있으면 좋습니다.

  1. golden request 세트
    • 정상 호출 510개, 실패 호출 23개
  2. schema validator
    • 필수 필드, enum, 타입 체크
  3. permission precondition test
    • 승인 또는 권한 없는 상황에서 기대한 방식으로 거절되는지 확인
  4. downstream compatibility test
    • 응답에서 후속 노드가 쓰는 핵심 필드가 남아 있는지 확인

핵심은 예쁜 테스트 프레임워크보다, drift가 생겼을 때 사용자 영향 전에 막을 수 있느냐입니다. 이건 Test Evidence Pipeline이 강조하는 증거 중심 운영과도 연결됩니다.

3) 운영 기준 숫자

빠른 출발 기준은 이 정도면 충분합니다.

  • 새 도구 추가 시 canary 비율 **5%**로 시작
  • 상위 핵심 도구 10개 중 8개 이상 contract test 확보
  • schema drift 감지 후 rollback 또는 route block까지 15분 이내
  • side effect 도구는 human gate 누락률 0% 목표
  • 동일 주간에 모델·프롬프트·도구 스키마 동시 변경은 금지 또는 강한 승인 게이트 적용

특히 마지막 기준이 중요합니다. 세 축을 동시에 바꾸면 원인 추적 시간이 길어지고, 장애가 났을 때 되돌리는 비용이 커집니다.

4) 2주 도입 플랜

1주차

  • 상위 핵심 도구 10개 선정
  • 각 도구의 필수 입력, 출력 핵심 필드, 권한 전제조건 기록
  • tool_schema_error, invalid_argument, permission_deny 로그를 한 대시보드로 통합

2주차

  • side effect 도구 3~5개에 contract test 추가
  • 읽기 전용 핵심 도구 2~3개에 golden request 세트 추가
  • 모델 canary와 tool canary를 분리해 1회 실행

이렇게만 해도 “프롬프트 문제인 줄 알았는데 사실은 도구 스키마 변경이었다” 같은 사건을 훨씬 빨리 잡을 수 있습니다.

5) 실패 시나리오별 최소 contract test 묶음

실무에서 가장 효과가 큰 방법은 도구마다 거대한 테스트 스위트를 만드는 게 아니라, 운영에서 실제로 많이 터지는 실패 모드 기준으로 최소 세트를 고정하는 것입니다. 예를 들어 배포 도구라면 정상 배포 요청, 필수 필드 누락, 권한 없는 호출, 환경명 enum 오입력, rollback 파라미터 누락 정도만 있어도 초반 회귀를 많이 막을 수 있습니다. 파일 수정 도구라면 대상 경로 없음, 읽기 전용 경로, 예상 diff 과다, dry-run과 실제 실행 결과 차이를 따로 보는 편이 낫고, 브라우저 자동화 도구라면 selector drift, 권한 팝업, 로그인 만료, 응답 지연을 fixture로 남겨 두는 쪽이 유효합니다.

중요한 점은 모든 테스트를 성공 케이스로만 채우지 않는 것입니다. 운영 장애는 보통 “될 때는 된다"보다 “실패했을 때 어떤 코드와 어떤 메시지로 막히는가"에서 갈립니다. 그래서 최소 세트도 성공 2~3개 + 실패 2~3개 + 권한/정책 1~2개 정도로 섞는 편이 좋습니다. 이때 실패 응답을 단순 문자열 비교로 얼리기보다, error_code, retryable, approval_required, side_effect_started 같은 핵심 필드만 고정하면 유지비도 과하게 커지지 않습니다.

추가로 팀이 자주 놓치는 부분이 사람 승인 전제조건입니다. 승인 기반 도구는 schema만 맞아도 실제 실행 가능성이 보장되지 않습니다. 그래서 golden contract에 “승인 없음”, “승인 있음”, “승인 만료” 세 상태를 최소한 한 번씩 넣어 두면 운영 사고를 훨씬 빨리 줄일 수 있습니다. 특히 Execution ReceiptReview Ops Unified Human Gate 같은 흐름과 같이 보면, contract test는 단순 파서 점검이 아니라 실행 경계와 승인 경계를 함께 검증하는 장치라는 점이 더 또렷해집니다.

트레이드오프/주의점

  1. 과도한 스냅샷 고정은 유지비를 키운다
    전체 응답을 전부 고정하면 사소한 텍스트 변경에도 테스트가 깨져 피로도가 커집니다. 핵심 필드와 위험한 경계 위주로 고정해야 합니다.

  2. 테스트가 있다고 안전한 것은 아니다
    도구 설명은 통과해도 권한 정책이나 rate limit이 바뀌면 운영 사고는 여전히 납니다. 계약 테스트와 운영 로그를 같이 봐야 합니다.

  3. 읽기 전용 도구만 보고 안심하면 안 된다
    읽기 도구 응답 구조가 바뀌면 후속 생성·수정 노드가 잘못된 결정을 내릴 수 있습니다. side effect 도구가 아니어도 허브 도구는 중요합니다.

  4. 사람 승인과 contract test는 대체 관계가 아니다
    배포, 데이터 수정, 외부 전송은 테스트가 있어도 마지막 human gate가 필요합니다. 테스트는 승인을 없애는 장치가 아니라, 승인 전에 이상을 더 빨리 찾는 장치입니다.

체크리스트 또는 연습

체크리스트

  • 상위 핵심 도구 10개와 실패 비용이 정리돼 있다.
  • 필수 입력 필드, enum, 권한 전제조건이 문서화돼 있다.
  • tool_schema_error, invalid_argument, permission_deny를 분리해 본다.
  • 모델 변경, 프롬프트 변경, 도구 스키마 변경을 같은 배포로 묶지 않는다.
  • side effect 도구에는 contract test와 human gate가 함께 있다.
  • drift 감지 후 차단 또는 rollback까지 목표 시간이 정해져 있다.

연습 과제

  1. 현재 팀의 핵심 도구 10개를 적고, 실패 비용이 높은 순서대로 다시 정렬해 보세요.
  2. 그중 1개를 골라 필수 필드, 허용 enum, 권한 전제조건, 실패 코드 매핑 표를 만들어 보세요.
  3. 최근 2주간 tool failure 로그를 분류해 보고, 프롬프트 문제와 계약 문제의 비율을 따져 보세요.
  4. 같은 모델과 프롬프트를 유지한 채 도구 스키마만 바뀌는 canary 시나리오를 1개 설계해 보세요.

관련 글