AI 코딩 에이전트 평가 하네스: 행동 평가로 회귀를 잡는 법
AI 코딩 에이전트를 팀에 붙이면 처음에는 데모가 잘 됩니다. 작은 버그를 고치고, 테스트를 추가하고, README를 수정합니다. 문제는 그다음입니다. 프롬프트를 조금 바꿨더니 테스트를 안 돌리고 완료했다고 말하거나, 모델을 교체했더니 애매한 요구사항에서 마음대로 추측하기 시작합니다. 이때 필요한 것이 평가 하네스입니다.
Google Developers Blog의 “The Anatomy of Harness Engineering”은 이 문제를 잘 짚습니다. 큰 end-to-end 벤치마크 점수만 보면 “몇 점 올랐다”는 건 알 수 있지만, 왜 좋아졌는지, 무엇이 깨졌는지는 알기 어렵습니다. 실무에서는 행동 평가가 필요합니다.
행동 평가는 무엇을 보는가
행동 평가는 최종 답변 문구가 아니라 중간 행동을 봅니다. 예를 들어 “Mountain View 날씨가 어때?”라는 질문에 모델이 그럴듯한 문장을 만들었는지가 아니라, 실제로 live search 도구를 호출했는지를 확인합니다.
코딩 에이전트라면 다음 행동을 볼 수 있습니다.
- 애매한 요구사항에서 질문을 했는가.
- build file을 바꾼 뒤 validator를 실행했는가.
- 테스트 실패 로그를 읽고 원인을 좁혔는가.
- 문서 생성 시 공식 링크를 포함했는가.
- PR 작성 전 변경 파일 목록을 요약했는가.
이런 행동은 정답 문자열보다 안정적입니다. 모델이 자연어를 조금 다르게 써도 핵심 행동이 맞으면 통과시킬 수 있습니다. 반대로 답변 문장이 훌륭해도 테스트를 실행하지 않았다면 실패로 볼 수 있습니다.
왜 E2E 벤치마크만으로 부족한가
Terminal-Bench나 DeepSWE 같은 큰 벤치마크는 모델 비교에는 유용합니다. 하지만 팀의 내부 agent harness를 개선할 때는 너무 느리고 비쌉니다. 더 큰 문제는 원인 분석입니다. 점수가 3% 떨어졌을 때 이유가 무엇인지 바로 알기 어렵습니다.
프롬프트가 문제인지, 도구 스키마가 문제인지, 파일 접근 권한이 문제인지, 모델이 CLI 플래그를 hallucination했는지, 테스트 실행 시간이 길어져 timeout이 난 것인지 구분해야 합니다. 행동 평가는 이런 원인을 좁히는 데 좋습니다.
좋은 비유는 단위 테스트와 통합 테스트입니다. E2E 벤치마크는 전체 제품 시나리오를 봅니다. 행동 평가는 “이 함수가 이 조건에서 이 API를 호출해야 한다”는 식의 작은 안전망입니다. 둘 다 필요하지만, 매일 돌릴 수 있는 것은 작은 테스트입니다.
첫 평가 케이스는 최근 실패에서 뽑아야 합니다
평가 하네스를 만들 때 가장 흔한 실수는 처음부터 거대한 평가 세트를 만들려는 것입니다. 그러면 유지보수 비용이 올라가고, 무엇이 중요한지 흐려집니다. 시작점은 최근 실패 하나면 충분합니다.
예를 들어 에이전트가 “간단한 버그 수정”을 하고 테스트를 실행하지 않은 채 완료했다고 합시다. 첫 eval은 이것만 봅니다.
- 입력: 작은 버그 수정 요청
- 기대 행동: 변경 후 test runner 호출
- 실패 조건: test runner 호출 없이 완료 선언
이 테스트가 생기면 프롬프트를 바꾸거나 모델을 교체할 때 같은 실수가 반복되는지 확인할 수 있습니다. 하네스의 목적은 “우리 agent가 똑똑하다”를 증명하는 게 아닙니다. 이미 겪은 사고가 다시 나지 않게 하는 것입니다.
엄격한 assertion과 느슨한 assertion을 나누세요
모든 행동을 딱딱하게 고정하면 오히려 좋은 해결책을 막을 수 있습니다. 단순 작업은 엄격하게 봐도 됩니다. 예를 들어 “package.json을 바꾼 뒤 npm test를 실행했는가”는 명확합니다.
하지만 복잡한 리팩터링은 경로가 여러 개일 수 있습니다. 이때 “반드시 A 도구 다음 B 도구를 호출하라”고 고정하면 정상적인 대안을 실패로 처리합니다. 이런 경우는 결과 기반 또는 LLM-as-judge를 섞을 수 있습니다. 다만 judge도 기준표가 필요합니다.
추천 구조는 세 가지입니다.
- 필수 안전 행동: 테스트 실행, diff 확인, 민감 파일 수정 금지처럼 엄격하게 본다.
- 권장 행동: 로그 확인, 관련 문서 링크 첨부처럼 점수화한다.
- 결과 품질: 변경이 요구사항을 만족하는지 judge나 기존 테스트로 본다.
이렇게 나누면 에이전트가 유연하게 일하면서도 위험한 행동은 막을 수 있습니다.
CI에 넣을 때는 단일 실행보다 배치 추세를 봅니다
AI 모델은 비결정성이 있습니다. 같은 입력도 조금 다르게 처리할 수 있습니다. 그래서 eval 하나가 한 번 실패했다고 바로 배포를 막으면 개발 속도가 느려질 수 있습니다. Google 글에서도 batch evaluation과 aggregate pass rate를 강조합니다.
실무에서는 다음 방식이 적당합니다.
- PR마다 빠른 smoke eval 5~10개를 실행한다.
- nightly로 더 큰 eval 세트를 실행한다.
- 모델 변경, 프롬프트 변경, 도구 스키마 변경 시 full eval을 실행한다.
- 개별 실패보다 카테고리별 통과율 추세를 본다.
예를 들어 “테스트 실행 행동” 통과율이 95%에서 70%로 떨어졌다면 바로 원인을 봐야 합니다. 반면 복잡한 문서 작성 품질이 2~3% 흔들리는 것은 샘플을 보고 판단할 수 있습니다.
평가 로그는 제품 로그처럼 남겨야 합니다
하네스가 쓸모 있으려면 로그가 남아야 합니다. 입력 프롬프트, 시스템 프롬프트 버전, 모델, 도구 스키마 버전, 호출된 도구, 파일 diff, 테스트 결과, 최종 응답을 묶어서 저장하세요. 그래야 실패가 났을 때 원인을 찾습니다.
특히 도구 스키마 버전은 중요합니다. 모델이 잘못된 게 아니라 도구 설명이 바뀌어 실패하는 경우가 많습니다. 예를 들어 'run_tests' 도구의 인자가 'target'에서 'command'로 바뀌었는데 프롬프트 예시는 그대로라면 실패합니다.
실행 체크리스트
- 최근 발생한 agent 실패 3개를 수집했다.
- 각 실패를 “관찰 가능한 행동”으로 바꿨다.
- 필수 안전 행동과 권장 행동을 분리했다.
- 최종 문구 equality 대신 도구 호출, 파일 diff, 테스트 결과를 검증한다.
- PR용 smoke eval과 nightly full eval을 나눴다.
- 프롬프트, 모델, 도구 스키마 버전을 로그에 남긴다.
- 단일 실패보다 카테고리별 통과율 추세를 본다.
- eval 실패는 프롬프트 수정뿐 아니라 도구 설계 문제로도 분류한다.
출처: Google Developers Blog, “The Anatomy of Harness Engineering”