모든 AI 코딩 에이전트는 diff를 생성할 수 있습니다. 진짜 문제는 그 diff가 집중적이고 의도적인 과정을 거쳐 나온 것인지, 아니면 저장소를 무작정 훑다가 우연히 정답에 도달한 것인지 아는 것입니다. 현재 대부분의 팀은 이 차이를 구분하지 못합니다.
이것은 기술적인 한계가 아닙니다. 가시성의 문제입니다.
에이전트가 프로덕션 코드 세 줄을 작성할 때, 파일 세 개를 읽고 테스트를 실행했을 수도 있습니다. 아니면 관련 없는 파일 40개를 건드리고, 수십 번의 명령 실패를 겪고, 의존성 설치 오류로 테스트 스위트를 건너뛴 뒤 그 대가로 비용까지 청구했을 수도 있습니다. 어떤 경우든 diff는 똑같아 보입니다. 과정에 대한 기록이 없다면, 결과물의 품질을 추측할 수밖에 없습니다.
채팅 로그가 영수증이 될 수 없는 이유
많은 도구가 작업 증빙으로 채팅 트랜스크립트를 제공합니다. 하지만 트랜스크립트는 영수증이 아닙니다. 그것은 책상 위에 쏟아놓은 부품 상자와 같습니다. 모든 사고 루프, 모든 실패한 시도, 모든 시스템 프롬프트, 그리고 모든 무관한 툴 호출이 들어 있습니다. 단 세 줄의 패치를 검증하기 위해 천 줄의 대화를 읽어야 한다면, 이미 리뷰 워크플로우는 망가진 것입니다.
인간의 주의력은 한정되어 있습니다. 에이전트의 목적은 인지적 노력을 줄이는 것이지, 숙제를 만드는 것이 아닙니다. 트랜스크립트는 리뷰어에게 탐정이 되라고 요구합니다. 영수증은 한눈에 답을 보여줍니다.
유용한 영수증은 실용적인 요약본입니다. 에이전트에게 무엇을 요청했는지, 실제로 무엇을 했는지, 그리고 어떻게 결론에 도달했는지를 알려줍니다. 실패를 숨기지 않고, 오히려 강조합니다.
좋은 영수증이란 무엇인가
검토 가능한 영수증은 일일이 파헤치지 않고도 다음과 같은 구체적인 질문에 답할 수 있어야 합니다:
- 작업은 무엇이었는가? 모호한 프롬프트의 반복이 아닌, 의도된 변경 사항에 대한 명확한 설명.
- 어떤 파일을 읽었는가? 에이전트가 올바른 소스에서 컨텍스트를 구축했는지 판단할 수 있도록.
- 어떤 파일을 수정했는가? 변경 사항의 최종 흔적.
- 어떤 명령어를 실행했는가? 에이전트가 호출한 빌드 단계, 린터, 포맷터 또는 커스텀 스크립트.
- 어떤 명령어가 실패했는가? 성공한 것뿐만 아니라 실패한 것도 포함해야 합니다. 실패는 에이전트가 어디서 임기응변을 해야 했는지, 혹은 어디서 포기했는지를 보여줍니다.
- 어떤 테스트가 통과되었거나 건너뛰어졌는가? 건너뛴 테스트는 위험 신호입니다. 영수증에는 왜 건너뛰었는지 명시되어야 합니다.
- 총비용은 얼마인가? 토큰, API 호출, 컴퓨팅 시간. 여기에는 모델뿐만 아니라 아키텍처 비용도 포함됩니다.
이 형식은 리뷰를 고고학적 발굴 작업에서 빠른 상태 점검(sanity check)으로 바꿔줍니다. 시니어 엔지니어는 영수증을 훑어보고 1분 안에 "이건 말이 되네" 또는 "이건 수상한데"라고 말할 수 있어야 합니다.
이력만이 아닌 흔적(Footprint)을 읽으십시오
에이전트 실행의 흔적은 작업의 형태를 보여줍니다. 에이전트가 티켓의 범위를 준수했나요? 아니면 관련 없는 모듈로 넘어가 아무도 요청하지 않은 것을 변경했나요? "읽은 파일"과 함께 "수정된 파일"을 나열하는 영수증은 이를 명확하게 보여줍니다.
흔적은 반복되는 패턴도 드러냅니다. 같은 설정 파일을 세 번 읽거나 실패하는 테스트를 계속 실행하는 등, 같은 막다른 길에 계속 부딪히는 에이전트는 컴퓨팅 자원과 컨텍스트 윈도우를 낭비하고 있는 것입니다. 이러한 패턴은 눈에 보여야 합니다. 에이전트가 마이그레이션 스크립트를 실행하는 데 아홉 번의 시도가 필요했다면, 영수증에 그 사실이 명시되어야 합니다. 이 정보는 결과물을 평가하는 방식을 바꿉니다. 무차별적인 혼돈을 통해 만들어진 "정확한" diff는 깔끔하게 만들어진 정확한 diff와 같지 않습니다.
잘못된 설계의 숨겨진 비용
비용은 단순히 토큰당 가격만을 의미하지 않습니다. 잘못 설계된 워크플로우는 에이전트가 글자 하나를 생성하기도 전에 비용을 높입니다. 비대해진 툴 스키마, 불필요한 파일 인덱싱, 지나치게 광범위한 시스템 프롬프트는 모두 컨텍스트 윈도우를 팽창시킵니다. 영수증은 이러한 오버헤드를 드러내야 합니다.
생성이 저렴해졌지만 리뷰가 더 어려워졌다면, 얻은 것은 아무것도 없습니다. 병목 현상을 옮겼을 뿐입니다. 엔지니어의 시간은 보통 팀에서 가장 희소한 자원입니다. 풀 리퀘스트(pull request)당 리뷰 시간을 30분 늘리면서 API 비용 5달러를 아끼는 것은 최악의 거래입니다. 영수증은 이러한 거래를 직접 감사할 수 있게 도와줍니다.
정직함은 기능입니다
유용한 영수증은 필요할 때 불편함을 주어야 합니다. 에이전트가 비효율적으로 보이게 만드는 사실을 보고해야 합니다. 그러한 정직함이 다음 인간의 의사결정을 더 빠르고 정확하게 만들기 때문입니다.
예시는 다음과 같습니다:
- "한 줄의 변경을 위해 37개의 파일을 읽었습니다."
- "
npm install이 피어 의존성(peer dependency) 충돌로 실패하여 테스트를 건너뛰었습니다." - "에이전트가 도입한 임포트(import) 오류를 수정하기 위해 요청된 범위를 벗어나
utils.py를 수정했습니다." - "린터(linter)를 4번 실행했습니다. 처음 세 번은 경로 설정 오류로 인해 실패했습니다."
이것들은 기록(receipt)의 버그가 아닙니다. 신호입니다. 리뷰어가 어디에 의구심을 가져야 할지 알려줍니다. 또한 플랫폼 팀에게는 워크플로우 자체를 어디서 강화해야 할지 알려줍니다.
더 작은 단위의 실행, 더 명확한 감독
에이전트가 넓은 범위에서 마음껏 활동하게 두고 싶은 자연스러운 유혹이 있습니다. 전체 서비스를 리팩터링하기 위해 거대한 프롬프트 하나를 던지는 것이 빨라 보일 수 있습니다. 하지만 그렇지 않습니다. 그것은 검토 불가능한 거대한 작업 덩어리를 만들어냅니다. 변경된 80개의 파일 중 어떤 것이 의도된 것인지 추적하다 보면 당신의 오후 시간은 순식간에 사라질 것입니다.
작고 검토 가능한 단위의 실행이 더 낫습니다. 작업에 대한 명확한 경계를 정의하십시오. 에이전트가 읽을 수 있는 파일 목록과 쓸 수 있는 파일 목록을 분리하십시오. 막다른 길을 확인할 수 있도록 실패한 명령의 이력을 기록하십시오. 건너뛴 검증 사항은 명시적으로 표시하십시오. 검색 API부터 테스트 러너까지 모든 외부 도구 사용을 기록하십시오.
목표는 완전한 자율성이 아닙니다. 인간이 검증할 수 없는 완전한 자율성은 책임만 따르는 자동화일 뿐입니다. 진짜 목표는 검토 가능성(reviewability)입니다. 모든 에이전트의 출력물은 승인하거나 거절하기 쉬워야 합니다. 조사하기에 너무 지쳐서 코드를 그냥 수용하게 되는 모호한 중간 지대가 있어서는 안 됩니다.
모든 코딩 에이전트를 위한 테스트
어떤 에이전트나 플랫폼을 도입하기 전에 한 가지 질문을 던지십시오. '이 도구가 인간이 다음 단계를 확신을 가지고 승인할 수 있을 만큼 충분한 증거를 남길 수 있는가?'
대답이 '예'라면, 그 도구는 전문적인 워크플로우에 적합합니다. 대답이 '아니오'라면, 당신은 생산성을 사는 것이 아닙니다. 가끔 컴파일만 되는 미스터리를 사고 있는 것입니다. 주말 사이드 프로젝트라면 괜찮을지 모르지만, 프로덕션 엔지니어링에서는 용납될 수 없습니다.
에이전트의 출력물을 검토 없이 받는 선물처럼 취급하는 팀은 결국 감지되지 않은 범위 확장(scope creep)으로 인해 발생한 미묘한 버그를 배포하게 될 것입니다. 디프(diff)는 아무런 문제가 없어 보일 것입니다. 하지만 기록(receipt)은 진실을 말해주었을 것입니다.
기록(receipt)을 요구하십시오. 검토를 위해 설계하십시오. 신뢰는 전략이 아닙니다. 증거가 전략입니다.
AI 도구 및 개발자 워크플로우에 관한 더 많은 실무적인 논의를 원하신다면, GyaanSetu Telegram 커뮤니티에 참여하실 수 있습니다.
