에이전트가 주장한 대로 수행했음을 증명하기: 영수증 기반 접근 방식
요약
AI 에이전트가 수행한 작업의 신뢰성을 검증하기 위해 실제 도구 호출과 결과를 기록하는 '영수증(receipt)' 기반 접근 방식을 소개합니다. LLM 비용 없이 기존의 검증된 실행 기록을 기준점(baseline)으로 삼아, 업데이트 후의 동작을 재현하고 차이점을 비교(diffing)함으로써 에이전트의 동작 변화를 정확히 포착할 수 있습니다.
핵심 포인트
- 에이전트의 요약된 트랜스크립트는 실제 동작을 증명하는 데 한계가 있음
- 도구 호출, 인자, 출력값을 포함한 실제 실행 기록(영수증)이 필요함
- 검증된 실행을 기준점으로 삼아 업데이트 후의 동작과 비교 분석 가능
- reelier를 활용하면 LLM 비용 없이 도구 동작을 재현하고 diff 확인 가능
TL;DR: 에이전트가 "완료되었습니다"라고 말했습니다. 지난주에 의존성(dependency)이 업데이트되었습니다. 에이전트가 이전에 했던 일을 여전히 수행하고 있는지 실제로 증명할 수 없습니다. 왜냐하면 이전에 무엇을 했는지에 대한 기록이 없기 때문입니다. 여기에서 저는 LLM 비용 없이 실제 실행을 기록하고, 향후 모든 실행을 이 기록과 비교(diffing)하기 시작한 방법을 소개합니다.
이것이 나의 문제가 된 순간
나는 성공적인(green) Dependabot PR을 병합했습니다. MCP 도구 서버의 작은 패치 업데이트였고, SemVer(유의적 버전) 상 안전했으며, CI(지속적 통합)도 통과했기에 버튼을 클릭했습니다.
3일 후, 한 사용자가 에이전트가 이전에 실행하던 단계를 건너뛰고 있다고 보고했습니다. 나의 테스트 스위트(test suite) 중 아무것도 이를 잡아내지 못했습니다. 왜냐하면 나의 "테스트"는 내가 직접 에이전트를 실행하고, 트랜스크립트(transcript)를 읽고, 괜찮아 보인다고 판단하는 것이었기 때문입니다. 에이전트는 매번 저에게 "완료되었습니다"라고 말했습니다. 에이전트가 의도적으로 거짓말을 한 것은 아닙니다. 단지 알 방법이 없었을 뿐이고, 저에게도 확인할 방법이 없었습니다.
"에이전트가 주장한 대로 수행했음을 어떻게 증명할 것인가"라는 질문의 밑바탕에 깔린 진짜 질문은 이것입니다: 무엇과 비교할 것인가? 올바르게 수행되었던 실행에 대한 정직한 기록이 없다면, 특정 실행이 올바르다는 것을 증명할 수 없습니다.
트랜스크립트가 증거가 될 수 없는 이유
본능적인 반응은 트랜스크립트를 다시 읽는 것입니다. 하지만 이는 몇 번의 실행을 넘어 확장(scale)될 수 없으며, 더 나쁜 것은 트랜스크립트가 에이전트 자신의 요약본이라는 점입니다. 만약 에이전트가 파일을 작성했다고 말했지만 실제로 작성하지 않았다면, 트랜스크립트에는 여전히 파일을 작성했다고 기록되어 있을 것입니다.
당신이 실제로 원하는 것은 그라운드 트루스(ground truth, 실측값)입니다: 에이전트가 수행한 정확한 도구 호출(tool calls), 전달한 인자(arguments), 그리고 돌려받은 출력값(outputs) 말입니다. 서술(narration)이 아니라, 영수증(receipt)이 필요합니다.
성공했던 실행을 기록하라
결국 나에게 효과가 있었던 해결책은 가장 좋은 의미에서 지루한 것이었습니다. 에이전트가 제대로 작동할 때 실제 실행을 하나 기록하는 것입니다. 그 캡처본이 다른 모든 것을 측정하는 기준점(baseline)이 됩니다.
에이전트의 실제, 검증된 실행을 캡처하세요 reelier record -- node agent.js "onboard a new client" 기록을 작성합니다: 모든 도구 호출, 인자, 그리고 결과
이 기록은 모의(mock)도 아니고 수기로 작성된 픽스처(fixture)도 아닙니다. 그것은 에이전트가 도구 호출 하나하나를 통해 실제로 수행한 것입니다. 그것이 바로 당신에게 부족했던 영수증입니다.
재현하고 기준선과 비교하기
이제 유용한 부분입니다. 무언가 변경될 때(의존성 업데이트, MCP 도구 서버 패치, 리팩토링 등) 기록된 실행을 재현하고 그 결과를 원래 결과와 차이점 분석(diff)합니다.
기록된 도구 동작을 모델 호출 없이 재현하기 reelier run --max-level 0
이 실행을 기록된 기준선과 비교하기 reelier diff
--max-level 0은 LLM을 전혀 호출하지 않고 기록된 도구 동작을 재현합니다. 이는 재현 비용이 0 LLM 토큰이라는 것을 의미합니다. reelier의 자체 테스트에서 1,000번 중 1,000번의 재현 결과가 바이트 단위로 동일하게 나왔는데, 이것이 diff를 신뢰할 수 있게 만드는 요소입니다. 즉, 무언가가 변경되었다면 모델이 오늘 다르게 느껴서가 아니라 사용자의 업데이트 때문에 변경된 것입니다.
만약 업데이트가 아무것도 변경하지 않았다면, reelier diff는 비어 있고 안심하고 병합(merge)할 수 있습니다. 만약 도구 호출, 인자 또는 결과가 변경되었다면, diff는 사용자에게 전달되기 전에 무엇이 어디에서 정확히 변경되었는지 보여줍니다.
중요한 단계에 대한 단언(Assert)
전체적인 diff는 사람에게는 훌륭합니다. 하지만 CI 환경에서는 보통 특정 사항에 실패하도록 설정하는 것이 일반적입니다. 즉, 이 도구는 호출되어야 하고, 이 인자는 존재해야 하며, 이 단계는 사라지면 안 됩니다. 단계별 단언(Per-step asserts)을 사용하면 실제로 신경 쓰는 실행 부분을 지정할 수 있어, 의미 있는 편차(drift)가 어깨를 으쓱하는 것 대신 빨간색 체크 표시로 나타나게 합니다.
PR에 연결하기 (Dependabot이 부족한 부분)
이것은 Dependabot이 제공할 수 없는 부분입니다. Dependabot은 버전이 변경되었고 SemVer(Semantic Versioning)가 안전하다고 알려줄 뿐입니다. 하지만 에이전트의 동작이 여전히 동일한지는 알려주지 않습니다. SemVer-safe가 곧 behavior-safe를 의미하지는 않습니다.
따라서 재현을 풀 리퀘스트(pull request, PR)에 배치하세요. GitHub Action은 업데이트된 의존성을 대상으로 기록된 워크플로우를 다시 실행하고 diff하며, 동작이 편차를 보이면 해당 체크가 PR에서 빨간색으로 표시됩니다. 이제
리플레이(replay)가 0 토큰이기 때문에, 모든 Dependabot PR에서 무료로 실행됩니다. bump-check 레시피의 전체 설정 과정은 여기에서 확인할 수 있습니다: https://www.reelier.com/docs/dependabot-bump-check
모델 업그레이드에 관한 솔직한 주의사항
솔직하게 짚고 넘어가야 할 점이 하나 있습니다. 0-토큰 이야기는 의존성(dependency)이나 MCP-tool 업데이트와 같이 기록된 도구의 동작을 리플레이(replay)하는 경우에 해당합니다. 만약 모델 업그레이드를 테스트하는 것이라면, 실제로 새로운 모델을 대상으로 다시 실행해야 하며, 이 과정에서는 토큰 비용이 발생합니다. 왜냐하면 모델 자체가 검증 대상이기 때문입니다. 이 경우에도 '기록 후 diff(record then diff)' 패턴은 여전히 적용되지만, 무료로 수행할 수는 없습니다. 문제는 다르지만, 동일한 원칙이 적용됩니다.
머릿속에 각인된 멘탈 모델 (Mental Model)
에이전트의 "완료(done)"를 사실이 아닌 하나의 주장(claim)으로 취급하세요. 기록된 실행(recorded run)은 그 주장을 뒷받침하거나 혹은 폭로하는 영수증(receipt)입니다. 모든 실행에 영수증이 따라붙게 되면, "증명해 봐"라는 말은 코드 리뷰에서의 논쟁이 아니라 하나의 diff가 됩니다.
reelier는 MIT 라이선스 기반의 오픈 소스이므로, 블랙박스를 신뢰하는 대신 기록(record), 리플레이(replay), 그리고 diff가 정확히 어떻게 작동하는지 직접 읽어볼 수 있습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기