AI 에이전트 검증 전략, '패턴 감지'에서 '행동 기반'으로 바꿔야 하는 이유

AI 에이전트 검증 전략, '패턴 감지'에서 '행동 기반'으로 바꿔야 하는 이유

정규식으로 6개월을 버텼다가 703줄을 날린 경험이 증명하는 것—에이전트 출력 검증의 진짜 레이어는 diff 형태가 아니라 실제 동작이다.

AI 에이전트 검증 행동 기반 검증 diff 형태 검증 verify_commands 에이전트 품질 관리 Claude Code AI-First 워크플로우 프로덕션 배포 품질
광고

에이전트가 'Exit 0'을 돌려줬는데, 구현 파일이 없었다

테스트 파일은 커밋됐다. CI는 그린이었다. PR도 열려 있었다. 그런데 테스트가 검증해야 할 구현 파일은 diff에 없었다. dev.to에 공개된 Codens 개발기에 따르면, 이 상황을 발견한 건 자동화 시스템이 아니라 PR을 머지 직전에 훑어본 팀원의 눈이었다.

"에이전트가 완료했다고 했으니 됐겠지"—이 가정이 깨지는 순간이다. AI 코딩 에이전트의 실패 모드는 크래시가 아니다. 조용히 성공처럼 보이는 불완전 구현이다.

패턴 감지의 유혹, 그리고 6개월의 함정

당연한 대응처럼 보인다. 티켓 본문에서 파일 경로를 추출하고, 에이전트의 diff가 그 경로를 건드렸는지 정규식으로 확인하는 것. 실제로 초기엔 효과가 있었다. src/notion_sync.py를 언급한 티켓에서 에이전트가 테스트만 올린 케이스를 잡아냈다. 그 한 번의 성공이 6개월간의 패치 작업을 정당화했다.

그런데 균열은 세 방향에서 동시에 왔다.

첫째, 티켓의 절반은 파일 경로를 명시하지 않는다. "모바일에서 반응이 느리다" 같은 결과 중심 티켓에는 정규식이 추출할 경로 자체가 없다. 가드는 조용히 스킵된다. 보호받는 척하지만 실제로는 절반이 열려 있는 안전망이다.

둘째, 구조화된 티켓이 오히려 노이즈를 만든다. "References" 섹션에 참고용으로 적힌 bar.py가 예상 파일 목록에 들어가면, 에이전트가 그 파일을 건드리지 않았다는 이유만으로 정상 구현이 실패로 판정된다. 거짓 양성이다.

셋째, 에이전트의 출력 형식이 바뀌면 파싱 자체가 깨진다. VPS가 diff_files를 공급하지 못하면 stdout에서 경로처럼 보이는 문자열을 스캔하는 폴백 로직이 작동한다. 이 시점에서 검증기는 이미 검증 대상인 에이전트만큼 취약해진다.

결말은 742줄 삭제, 단위 테스트 280개 제거, 순감 -703줄이었다.

형태(Shape)를 보는 것과 동작(Behavior)을 보는 것의 차이

왜 이 구분이 중요한가. AI 에이전트는 컨텍스트 윈도우 안에서 '국소적으로 일관성이 있다'. 함수 시그니처를 변경했는데 호출 사이트 세 곳은 그대로인 경우, 에이전트 입장에서 그건 완료된 작업이다. OpenAPI 스펙을 갱신하지 않은 채 라우트 핸들러만 추가한 경우도 마찬가지다. diff의 형태를 아무리 정교하게 체크해도, 에이전트가 '논리적으로 수행했어야 할 것'이 무엇인지를 코드 외부에서 규칙으로 정의하는 한 이 한계를 넘을 수 없다.

반면 행동 기반 검증(behavior-based verification)은 다르게 묻는다. "이 티켓이 설명한 일이 실제로 일어났는가?" Codens의 verify_commands가 바로 이 접근이다. 티켓마다 "이 명령들이 통과하면 완료"라는 쉘 스니펫을 정의하고, 에이전트 실행 후 그것을 실제로 돌린다. 실패하면 에이전트에게 출력을 피드백으로 넘겨 재시도시킨다. 느리고 비용이 든다. 그러나 거짓 음성이 없다.

아키텍처 관점에서 본 검증 레이어 설계

이 경험은 AI 에이전트 아키텍처의 더 큰 논의와 맞닿아 있다. dev.to의 'Deterministic vs Agentic' 분석이 지적하듯, 에이전트 시스템의 신뢰성 문제는 결국 어디에 판단을 위임하고 어디를 코드로 고정할 것인가의 문제다. SWE-bench Pro에서 최상위 모델조차 Pass@1이 23%에 그친다는 수치는, 에이전트 루프 자체를 믿는 것이 얼마나 위험한 베팅인지를 보여준다.

검증 레이어 설계에서 이 구분은 실질적이다:

  • 형태 검증(Shape Guard): diff가 특정 파일을 포함하는가, 스키마가 유효한가. 빠르고 저렴하다. 그러나 '올바른 동작'을 보장하지 않는다.
  • 행동 검증(Behavior Verification): 실제 테스트를 돌려 기능이 작동하는가. 느리고 비싸다. 그러나 거짓 통과를 허용하지 않는다.
  • 관찰성(Observability): 어느 단계에서 무엇이 실패했는가를 추적한다. Braintrust·Trainline 사례(dev.to)가 강조하듯, 에이전트 실행의 전체 트레이스—LLM 호출, 툴 콜, 출력, 지연—를 계측하지 않으면 디버깅은 추측이다.

세 레이어는 대체 관계가 아니다. 형태 검증은 명백한 오류를 빠르게 걸러내는 첫 번째 필터가 될 수 있다. 다만, 그것만으로 '에이전트가 실제로 일을 했다'고 판단하는 순간 함정에 빠진다.

팀 리빌딩 관점: 검증 설계는 개발자의 책임이다

AI-First 팀을 리빌딩하면서 내가 가장 자주 보는 패턴이 있다. 에이전트 도입 초기엔 도구가 뱉는 '그린 사인'을 지나치게 신뢰한다. Exit 0, CI 통과, 에이전트 완료 메시지—이 세 가지가 동시에 뜨면 머지 버튼을 누르게 된다.

그런데 에이전트가 생성한 코드의 품질 게이트는 결국 팀이 설계해야 한다. 도구가 제공하는 기본 피드백 루프를 그대로 믿는 것은, 에이전트에게 완료 판정권을 넘기는 것과 같다. Codens 개발자가 6개월 만에 내린 결론처럼, 'diff가 어떻게 생겼는가'보다 '실제로 동작하는가'를 묻는 검증 구조를 먼저 설계해야 한다.

실용적 체크리스트로 정리하면:

  1. 티켓마다 verify_commands를 작성하라. '완료 조건'을 자연어가 아닌 실행 가능한 명령으로 명세하는 습관이 검증 자동화의 출발점이다.
  2. 형태 검증을 첫 번째 필터로, 행동 검증을 최종 게이트로. 비용 구조를 고려하되, 행동 검증을 생략하는 지름길은 없다.
  3. 에이전트 실행 전 구간을 트레이스하라. 어떤 툴이 호출됐고 무엇을 반환했는지 계측하지 않으면, 실패 원인을 찾는 데 에이전트가 구현하는 시간보다 더 오래 걸린다.
  4. 검증기도 테스트하라. 정규식 기반 가드가 무너진 근본 이유 중 하나는, 검증 로직 자체의 엣지 케이스를 충분히 테스트하지 않았기 때문이다.

전망: 에이전트가 많아질수록 검증 설계가 경쟁력이 된다

에이전트 도입 속도는 계속 빨라진다. Claude Code, Cursor, Copilot—선택지가 늘어날수록 '어떤 에이전트를 쓰는가'보다 '에이전트 출력을 어떻게 검증하는가'가 팀의 실질적 품질을 결정하게 된다.

703줄짜리 정규식 가드를 삭제하는 커밋 하나가 던지는 메시지는 단순하다. 에이전트의 출력이 '그럴듯해 보이는가'를 묻는 검증은 오래 버티지 못한다. 실제로 동작하는가를 확인하는 구조만이 프로덕션에서 살아남는다. AI-First 팀의 검증 전략은 지금 이 질문에서 다시 시작해야 한다.

출처

더 많은 AI 트렌드를 Seedora 앱에서 확인하세요