Skip to content

11-5. 검증·관측·리뷰 루프 ​

한 줄 요약: 에이전트가 만든 변경을 "믿을 만하다"가 아니라 증거 패키지로 판정하고, 실행 기록을 감사 가능한 산출물로 남기며, 실패를 계층별로 귀인할 수 있다.

학습 목표 ​

  • 에이전트 변경의 증거 패키지(diff, 테스트, 정적 검증, 브라우저·성능·접근성 근거)를 구성할 수 있다.
  • 검증 계층을 비용 순서로 배치하고, 작업 유형별로 필요한 계층을 선택할 수 있다.
  • 에이전트 실행 기록에서 관측해야 할 항목(읽은 파일, 실행 명령, 실패한 시도, 포기한 대안, 개입 지점)을 설명할 수 있다.
  • 에이전트 작업의 실패를 모델·컨텍스트·명세·도구·환경·하네스 계층으로 귀인할 수 있다.
  • 반복 작업에 대한 작은 평가 세트를 설계해 워크플로 변경의 효과를 비교할 수 있다.

배경: 왜 이것이 존재하는가 ​

사람이 쓴 코드의 신뢰는 여러 겹의 암묵적 근거 위에 있다. 작성자가 어제도 비슷한 코드를 잘 썼고, 작성하며 스스로 실행해 봤을 것이고, 이상하면 물어봤을 것이고, 문제가 생기면 책임지고 고칠 것이라는 — 조직이 사람에 대해 축적한 신뢰다. 에이전트 변경에는 이 겹들이 없다. 세션마다 이력이 리셋되고, 실행해 봤다는 서술이 사실이 아닐 수 있으며, 책임 소재가 되지 못한다.

그래서 에이전트 시대의 리뷰는 코드 리뷰보다 **감사(audit)**에 가까워진다. 감사의 원칙은 진술이 아니라 증거다. "테스트했다"는 진술 대신 테스트 명령의 실행 기록과 출력, "화면을 확인했다"는 진술 대신 스크린샷과 trace. 10-2에서 PR을 "요구사항, 결정, 검증 결과, 남은 리스크를 담은 변경 패키지"로 정의했는데, 에이전트 작업에서는 이 패키지 규율이 선택이 아니라 신뢰의 유일한 원천이 된다.

역설적으로 이것은 에이전트의 강점이기도 하다. 사람에게 "모든 변경에 스크린샷, Profiler 결과, 접근성 점검을 첨부하라"고 요구하면 규율 비용에 부딪히지만, 에이전트에게 증거 생산은 루프의 몇 스텝일 뿐이다. 검증 증거의 생산 비용이 급락했으므로, 요구 수준을 올리는 것이 합리적이 된다.

핵심 개념 ​

증거 패키지: 변경과 함께 제출되어야 하는 것 ​

에이전트 작업의 완료 산출물은 diff가 아니라 diff를 포함한 증거 패키지다. 표준 구성:

구성 요소내용답하는 질문
diff변경 자체 (작업 명세의 경계와 대조 가능해야 함)무엇이 바뀌었나
정적 검증 로그typecheck, lint, build의 실제 출력기계적 결함이 없나
테스트 결과실행 명령, 통과/실패 수, 새 테스트의 diff동작이 명세대로인가
브라우저 증거스크린샷, Playwright trace, 필요시 영상실제로 렌더링되는가
성능 근거Profiler 비교, Lighthouse, 번들 크기 diff (해당 시)성능 주장이 사실인가
접근성 점검axe 결과, 키보드 절차 기록 (UI 변경 시)접근성이 후퇴하지 않았나
보안 점검새 sink·의존성·secret 스캔 결과 (해당 시)공격면이 늘지 않았나
실행 요약접근 방식, 시도와 실패, 포기한 대안, 가정왜 이렇게 됐나
남은 리스크검증하지 못한 것, 알려진 한계무엇을 더 봐야 하나

두 가지 규율이 패키지의 신뢰를 만든다. 첫째, 증거는 하네스의 기록에서 나와야 한다. 에이전트가 요약문에 "모든 테스트 통과"라고 쓰는 것과, 도구 호출 로그에 pnpm test 실행과 그 출력이 남는 것은 다르다. 전자는 진술, 후자가 증거다. 둘째, "남은 리스크" 항목은 비워지지 않아야 한다. 리스크가 없다는 보고는 대개 리스크를 찾지 않았다는 뜻이다. 작업 명세에 "검증하지 못한 것을 반드시 보고하라"를 넣으면, 에이전트는 이 항목을 의외로 정직하게 채운다.

검증 계층: 싸고 빠른 것부터 ​

검증 수단은 비용(시간·설정 노력)과 잡는 결함의 종류가 다르다. 계층화하면:

text
1. 정적 검증        typecheck / lint / build          초 단위, 전 작업 필수
2. 단위·컴포넌트    vitest, Testing Library           초~분, 로직 변경 필수
3. 사용자 플로우    Playwright e2e                    분 단위, 플로우 영향 시
4. 브라우저 실증    스크린샷, 수동 확인, 콘솔·네트워크    분 단위, UI 변경 시
5. 특화 점검        Lighthouse, axe, bundle, Profiler  해당 속성 변경 시

배치 원칙은 CI 설계(6-5)와 같다 — 싼 검증을 앞에, 비싼 검증을 뒤에. 에이전트 맥락에서 추가되는 고려가 하나 있다. 1~2층은 에이전트의 루프 안에서 돌게 하고(자체 수정의 재료), 3~5층은 완료 조건으로 요구한다(증거의 재료). 매 편집마다 e2e를 돌리는 것은 루프를 느리게 하지만, e2e 없이 완료를 선언하게 두면 증거가 빈다.

계층의 선택은 작업 유형이 정한다. 순수 로직 버그 수정에는 1~2층이면 충분하고, 컴포넌트 구조 변경은 4층(visual)이 필수이며, 성능 작업은 5층 없이는 완료가 아니다. 이 대응을 작업 명세 템플릿에 박아 두는 것이 실무 요령이다.

관측 가능성: 결과가 아니라 과정을 기록한다 ​

증거 패키지가 "결과가 맞는가"를 답한다면, 관측 가능성(observability)은 "과정이 건전했는가"와 "실패했다면 왜인가"를 답한다. 하네스가 남기는 실행 기록에서 확인할 항목:

  • 읽은 파일: 판단의 입력이 무엇이었나. 핵심 문서를 안 읽고 내린 결정은 결과가 맞아도 운이다.
  • 실행한 명령과 출력: 검증 진술의 사실 확인 지점.
  • 실패한 시도와 포기한 대안: 최종 diff에는 없는 정보. "접근 A를 시도했으나 X 때문에 B로 전환"은 리뷰어가 대안을 다시 제안하는 낭비를 막고, 실패 귀인의 재료가 된다.
  • 사람 개입 지점: 어디서 계획을 수정했고 무엇을 승인했나. "에이전트가 한 일"과 "사람이 시킨 일"의 경계는 사후 책임 판단에 필요하다.
  • 최종 판단 근거: 왜 이 파일을 바꿨고 왜 이 접근인가.

운영 요령: 하네스의 원시 로그(세션 전체 transcript)는 보존하되 사람이 읽는 대상은 아니다. 사람이 소비하는 것은 에이전트에게 작성시키는 실행 리포트 — 위 항목의 구조화된 요약 — 이고, 원시 로그는 리포트가 의심스러울 때의 원본 대조용이다. 로그와 메트릭의 관계와 같다.

실패 귀인: "에이전트가 못했다"는 진단이 아니다 ​

에이전트 작업이 실패했을 때 "모델이 멍청해서"로 닫으면 같은 실패가 반복된다. 실패는 계층을 가진 시스템에서 발생하므로 귀인도 계층적이어야 한다.

실패 계층전형적 증상확인 방법처방
작업 명세 모호명세와 다른 방향으로 그럴듯하게 구현명세만 읽고 제3자가 같은 오해를 하는가명세 템플릿 보강 (11-2)
컨텍스트 부족존재하는 규칙·코드를 모른 채 판단읽은 파일 목록에 핵심 문서가 없음지시문·문서·출발점 보강 (11-3)
컨텍스트 오염세션 후반의 퇴행, 폐기한 접근의 반복세션 길이, 압축 발생 여부작업 분할, 새 세션 인계
도구·권한 부족검증을 건너뛰거나 우회 시도"실행할 수 없어서"류 서술, 승인 거부 기록하네스 구성 변경 (11-4)
환경 문제flaky test, 의존성·설정 오류, 외부 API 변화사람이 같은 명령을 실행해도 실패하는가환경 수리 (에이전트와 무관)
하네스 버그도구 호출 자체의 오동작, 잘려 나간 출력원시 로그에서 도구 결과 확인하네스 이슈 보고·우회
모델 추론 실패위 전부 아님: 충분한 정보에서 틀린 추론소거법모델 등급 상향, 작업 분해, 사람 수행

순서에 주목하라. 모델 추론 실패는 소거법의 마지막이다. 실무 경험상 실패의 다수는 위쪽 계층 — 명세, 컨텍스트, 환경 — 에서 나며, 이쪽의 처방은 팀이 통제 가능하다. 흥미로운 확인 방법 하나: 같은 명세를 사람 개발자에게 주었을 때도 헤맬 것 같으면, 그것은 모델 문제가 아니다.

특히 flaky test는 에이전트에게 사람보다 더 유해하다. 사람은 "이 테스트 원래 가끔 죽어"라는 지식으로 무시하지만, 에이전트는 flaky 실패를 진짜 신호로 받아 멀쩡한 코드를 '고치기' 시작한다. 에이전트 도입은 테스트 스위트의 신뢰성 문제를 잠복 상태에서 활성 문제로 바꾼다.

리뷰 루프의 설계 ​

에이전트가 낀 리뷰의 전체 루프를 순서로 설계하면:

text
1. 에이전트 self-review    diff를 명세·지시문과 대조해 스스로 점검, 명세 밖
                           변경과 테스트 약화를 자수하게 한다
2. 자동 게이트             CI: 정적 검증 + 테스트 + (가능하면) e2e smoke
3. 사람 리뷰               증거 패키지 검토 → diff 정독. 관점은 10-2와 동일하되
                           추가 관점: 명세 경계 준수, 테스트 약화, 과잉 변경,
                           증거와 진술의 일치
4. 지적 반영               리뷰 코멘트를 에이전트에게 전달해 수정시킨다.
                           맥락 유지를 위해 가능하면 원래 세션·리포트와 함께
5. 회귀 확인               반영 후 전체 검증 재실행 (부분 수정이 앞 검증을 무효화)
6. 병합                    사람의 결정. 책임 지점.

self-review(1)는 공짜에 가깝고 효과가 좋다 — "제출 전에 diff를 다시 읽고, 작업 명세의 경계를 벗어난 변경과 검증하지 못한 부분을 나열하라"는 지시만으로 상당수의 과잉 변경이 걸러진다. 다만 self-review는 자기 진술이므로 3의 대체가 아니라 3의 입력이다.

사람 리뷰(3)에서 에이전트 diff 특유의 함정은 그럴듯함의 균질성이다. 사람의 나쁜 코드는 대개 티가 나지만(이상한 네이밍, 급한 흔적), 에이전트의 잘못된 코드는 올바른 코드와 표면 품질이 같다. 스타일 신호로 위험을 추정하는 리뷰 습관이 무력화되므로, 리뷰는 표면이 아니라 증거 패키지와 경계 조건(10-2의 상태표) 중심으로 재편되어야 한다.

작은 평가 세트: 워크플로 개선의 계측기 ​

지시문을 고치고, MCP를 붙이고, 모델을 바꿨을 때 — 좋아졌는지 어떻게 아는가? 감으로 답하면 하네스 개선이 미신이 된다. 대안은 작은 평가 세트(eval set)다.

팀에서 반복되는 작업 유형을 5~10개 시나리오로 고정한다. 예: "이 버그 리포트로 원인 파일 찾기", "이 컴포넌트에 loading 상태 추가", "이 훅의 테스트 작성", "이 PR 요약". 각 시나리오는 실제 저장소의 특정 커밋을 기준으로 하고, 성공 판정 기준을 명시한다. 워크플로에 의미 있는 변경이 있을 때 세트를 다시 돌려 비교한다.

기록할 지표는 성공률만이 아니다.

  • 성공률: 판정 기준 충족 여부
  • 수정량: 사람이 결과를 고친 정도 (diff 라인)
  • 검증 누락: 요구된 증거 중 빠진 것
  • 개입 횟수: 사람이 끼어든 횟수
  • 재작업 비용: 재시도·재명세에 든 시간
  • 토큰·시간 비용: 회당 소모

비결정성 때문에 시나리오당 1회 실행으로는 노이즈가 크다. 같은 시나리오를 2~3회 돌려 편차 자체를 기록하는 것이 현실적 타협이다. 목적은 통계적 엄밀성이 아니라 "바꿨더니 나빠졌다"를 감이 아니라 기록으로 잡는 것이다. 대규모 평가 플랫폼은 이 과정의 산업화 버전이며, 팀 수준에서는 마크다운 표와 스크립트로 충분하다.

실무 관점 ​

검증 비용의 재배분 ​

에이전트 도입 전, 개발 시간의 대부분은 작성에 들고 검증은 상대적으로 쌌다. 도입 후 작성 비용이 급락하면서 병목은 검증과 리뷰로 이동한다. 이 재배분을 인정하지 않는 팀 — 에이전트로 PR 생산량을 3배로 늘리면서 리뷰 관행은 그대로 두는 팀 — 은 두 결말 중 하나로 간다: 리뷰가 병목이 되어 이득이 사라지거나, 리뷰가 형식화되어 결함이 병합된다.

건강한 재배분의 방향은 이 문서가 다룬 순서대로다. 증거 생산을 에이전트에게 의무화해 리뷰어의 확인 비용을 낮추고, 자동 게이트를 강화해 사람 리뷰가 판단이 필요한 곳에만 쓰이게 하고, 리뷰 자체의 일부(self-review, 에이전트 교차 리뷰)를 자동화한다. 에이전트에게 리뷰를 시키는 것은 유효하지만, 에이전트 리뷰어도 같은 injection·hallucination 위험을 가지므로 "사람 리뷰의 입력"이지 대체가 아니다.

안티패턴 ​

  • 녹색 체크 신앙: CI 통과 = 병합 가능으로 취급. 에이전트는 CI를 통과하는 잘못된 코드(테스트가 안 보는 곳의 결함, 테스트 약화)를 만들 수 있다. CI는 필요 조건이다.
  • 증거 요구 없는 완료 수용: "됐습니다"를 받고 종료. 증거 패키지가 없는 완료는 미완료로 취급하는 규칙이 필요하다.
  • 실패 기록의 폐기: 실패한 세션을 그냥 버림. 실패 기록은 하네스 개선 루프(11-4)의 원료다. 최소한 귀인 한 줄은 남긴다.
  • 리뷰 코멘트의 무맥락 전달: 리뷰 지적을 새 세션에 코멘트만 던지면, 에이전트는 원래 작업의 맥락 없이 지적을 문자적으로 반영한다(지적된 줄만 고치고 같은 패턴의 다른 줄은 방치). 원래 명세·리포트와 함께 전달한다.
  • 평가 없는 워크플로 변경: 지시문·도구·모델을 동시에 여럿 바꾸면 무엇이 효과였는지 영원히 모른다.

어디까지 요구할 것인가 ​

증거 패키지의 수준은 작업 위험도에 비례시킨다. 문서 오타 수정에 Lighthouse를 요구하는 것은 관료제다. 실용적 3단계:

  • 경량 (문서, 주석, 설정 사소 변경): diff + 정적 검증.
  • 표준 (일반 코드 변경): + 테스트 결과 + 관련 UI 스크린샷 + 실행 요약 + 남은 리스크.
  • 강화 (결제·인증·공유 컴포넌트·성능 민감 경로): + e2e + 특화 점검(성능/접근성/보안) + 사람 브라우저 확인.

이 분류를 PR 템플릿과 팀 정책(11-6)에 연결하면 운영이 된다.

더 깊이 ​

검증의 비대칭성이라는 근본 문제 ​

에이전트 검증의 이론적 바탕에는 생성-검증 비대칭이 있다. 어떤 속성은 검증이 생성보다 쉽다(테스트 통과 여부, 타입 정합성 — NP류의 검증 용이성). 어떤 속성은 검증이 생성만큼 어렵다(이 추상화가 적절한가, 이 코드가 6개월 뒤 유지보수 가능한가). 에이전트 위임이 잘 작동하는 영역은 정확히 첫 번째 부류이고, 11-1의 위임 적합도 표는 이 비대칭의 응용이었다. 두 번째 부류에서 우리가 쓰는 도구는 기계 검증이 아니라 판단의 위임 없는 유지 — 사람 리뷰, 설계 논의 — 다. 검증 계층을 아무리 쌓아도 두 번째 부류가 사라지지 않는다는 것이, 검증 자동화의 한계선이자 11-7에서 다룰 사람 역할의 근거다.

에이전트 PR에 대한 관찰 데이터 ​

Security in the Age of AI Teammates 연구(참고 자료)는 에이전트가 만든 PR의 보안 관련 기여를 실제 데이터에서 분석하며, 에이전트 PR이 사람 PR과 리뷰 지연·병합률에서 체계적으로 다르게 다뤄짐을 관찰한다. 신뢰 격차는 심리 문제가 아니라 이 문서의 언어로 설명된다: 에이전트 PR에는 암묵적 신뢰 근거가 없으므로, 명시적 증거가 그 자리를 채워야 병합률 격차가 줄어든다. 실무 시사점은 역방향으로도 있다 — 에이전트 PR임을 숨겨 병합률을 올리는 것은 신뢰 문제를 해결한 것이 아니라 이연시킨 것이다. 사용 도구의 투명한 표기와 증거 패키지가 정공법이다.

trace 표준화의 방향 ​

에이전트 실행 기록은 현재 하네스마다 형식이 다르다. 관측 인프라 관점에서는 OpenTelemetry가 LLM·에이전트 span 규약(GenAI semantic conventions)을 확장해 온 흐름이 주목할 만하다. 도구 호출을 span으로, 세션을 trace로 모델링하면 기존 분산 추적 인프라(수집, 보존, 검색, 대시보드)를 에이전트 관측에 재사용할 수 있다. 팀이 자체 하네스나 게이트웨이를 운영한다면, 독자 로그 형식보다 이 규약에 올라타는 것이 도구 교체 내성이 있는 선택이다. 백엔드에서 구조화 로깅과 분산 추적이 걸어온 길을 에이전트 관측이 압축적으로 다시 걷고 있다.

정리 ​

  • 에이전트 변경의 신뢰는 진술이 아니라 증거에서 온다: diff + 정적 검증 + 테스트 + 브라우저·성능·접근성 근거 + 실행 요약 + 남은 리스크가 증거 패키지의 표준 구성이다.
  • 검증은 계층화한다: 싼 정적 검증·단위 테스트는 에이전트 루프 안에서, e2e·브라우저·특화 점검은 완료 조건으로. 요구 수준은 작업 위험도에 비례시킨다.
  • 관측은 결과가 아니라 과정의 기록이다: 읽은 파일, 실행 명령, 실패한 시도, 포기한 대안, 개입 지점이 남아야 리뷰가 감사가 되고 귀인이 가능해진다.
  • 실패 귀인은 명세→컨텍스트→도구·권한→환경→하네스→모델의 소거 순서로 하며, 모델 탓은 마지막이다. 다수의 실패는 팀이 통제 가능한 계층에서 난다.
  • 워크플로 변경의 효과는 감이 아니라 5~10개 시나리오의 작은 평가 세트로 계측하고, 성공률 외에 수정량·검증 누락·개입 횟수·재작업 비용을 함께 기록한다.

확인 문제 ​

  1. 다음 에이전트 실행 리포트에서 검증 증거가 부족한 지점을 모두 찾아라: "장바구니 합계 버그를 수정했다. 원인은 수량 변경 시 memoization 키가 갱신되지 않는 것이었다. 수정 후 테스트를 실행해 통과를 확인했고, 브라우저에서도 정상 동작을 확인했다. 추가로 눈에 띈 비슷한 패턴 2곳도 함께 수정했다. 리스크는 없다."
정답과 해설

① "테스트를 실행해 통과" — 명령·출력 로그가 없다. 어떤 테스트가 몇 개 돌았는지, 이 버그를 재현하는 테스트가 존재하는지(수정 전 실패 → 수정 후 통과의 기록) 불명. ② "브라우저에서 정상 동작 확인" — 스크린샷·trace 없음. 에이전트의 진술뿐이며 hallucination일 수 있다. ③ "비슷한 패턴 2곳도 함께 수정" — 명세 경계 밖 과잉 변경. 별도 작업으로 분리하거나 최소한 그 2곳 각각의 검증 증거가 필요하고, diff 리뷰 범위가 조용히 넓어졌음을 리뷰어가 인지해야 한다. ④ "리스크는 없다" — 비어 있는 리스크 항목은 리스크를 찾지 않았다는 신호. 검증하지 못한 것(예: 수량 외 다른 갱신 경로, 동시 변경 시나리오)이 나열되어야 한다. 추가로 memoization 원인 진단 자체의 근거(Profiler 또는 재현 로그)도 없다.

  1. 에이전트가 같은 유형의 폼 컴포넌트 작업에서 3번 연속 실패했다. 세션 기록을 보니 매번 팀의 폼 검증 라이브러리 대신 직접 검증 로직을 작성했고, 지적하면 고치지만 다음 세션에서 반복된다. 실패 귀인 표를 적용해 원인 계층을 진단하고 처방을 제시하라.
정답과 해설

증상 분석: 에이전트는 일관되게 그럴듯한 코드를 작성하고 지적하면 고친다 — 추론 능력의 문제가 아니다. "다음 세션에서 반복"이 결정적 단서다: 세션 간 기억이 없으므로, 매 세션 공급되는 컨텍스트에 팀의 폼 규칙이 없는 것이다. 귀인: 컨텍스트 부족 계층. 확인 방법: 세션 로그의 읽은 파일 목록에 폼 규칙 문서나 기존 폼 구현이 있는지 본다(없을 것이다). 처방: ① 저장소 지시문에 규칙 추가 — "폼 검증은 반드시 X 라이브러리 사용, 참조 구현은 src/features/auth/LoginForm.tsx". ② 폼 작업 명세 템플릿에 참조 구현 경로를 출발점으로 포함. ③ 가능하면 기계 검증으로 봉인 — 직접 검증 패턴을 잡는 lint 규칙. 모델 등급 상향은 이 경우 처방이 아니다 — 어떤 모델도 공급되지 않은 팀 규칙은 모른다.

  1. 팀이 에이전트 지시문을 크게 개편하고 MCP 도구 2개를 추가하면서 모델도 최신으로 올렸다. 2주 뒤 "체감상 좋아졌다"는 의견과 "더 산만해졌다"는 의견이 갈린다. 이 상황을 예방했어야 할 방법과, 지금이라도 할 수 있는 것을 제시하라.
정답과 해설

예방했어야 할 것: ① 변경 전 평가 세트 구축 — 반복 작업 5~10개 시나리오, 판정 기준, 지표(성공률·수정량·검증 누락·개입 횟수·비용)를 고정하고 변경 전 기준선을 기록. ② 변경의 분리 — 지시문·MCP·모델을 동시에 바꾸면 효과 귀인이 불가능하다. 한 번에 하나씩, 각 변경 후 세트 재실행. 지금이라도 할 것: ① 늦었지만 세트를 지금 구축하고 현 구성의 기준선을 잡는다. ② 논쟁 중인 변경을 하나씩 되돌려 비교한다 — 예: MCP 2개를 끄고 세트 실행("산만해졌다"가 도구 과잉의 컨텍스트 오염이라는 가설 검증), 지시문 개편 전 버전은 Git에 있으므로 그 버전으로도 실행. ③ 비결정성 대비 시나리오당 2~3회 실행해 편차를 함께 기록. 핵심 원리: 하네스 구성 변경도 코드 변경처럼 계측과 롤백 가능성을 갖춰야 한다.

참고 자료 ​