에이전트를 '쓴다'는 것과 '통제한다'는 것은 다르다
요즘 팀마다 AI 코딩 에이전트 하나씩은 들여놨다. 문제는 도입 후다. 에이전트가 알아서 코드를 짜고 PR을 올리고 배포까지 건드리는 시대가 됐는데, 정작 그 결과물을 어떻게 검증하고 통제할지는 여전히 손이 가는 곳이 없다. 세 개의 실전 사례가 그 공백을 정확히 짚어준다.
첫 번째 질문: 어떤 에이전트를 골라야 하나
dev.to에 올라온 Claude Code vs. GPT-5.3-Codex 2개월 실사용 비교는 단순한 기능 대결이 아니다. 저자가 꺼낸 핵심 결론은 "두 도구는 경쟁하는 게 아니라 역할이 다르다"는 것이다.
Codex는 전체 코드베이스를 읽고 파일 간 의존성을 추적한다. 에러 핸들링 하나를 고쳐달라고 하면 그 함수를 호출하는 나머지 네 곳까지 함께 수정하고, 쓰지 않는 라이브러리 import까지 잡아낸다. 리팩토링 작업이라면 Codex가 확실히 앞선다.
Claude Code는 다르다. 오케스트레이션이 강점이다. 멀티 에이전트 팀 구성, 장시간 자율 실행, 메모리와 스킬 시스템 연동—이런 건 Codex가 아직 따라오지 못하는 영역이다. 저자는 실제로 밤 10시부터 새벽 5시까지 기능을 개발하고 배포 요약 메일까지 보내는 야간 자동화 시스템을 Claude Code로 운영하고 있다.
실용적인 분배 기준은 명확하다. 코드 개선과 리팩토링은 Codex, 에이전트 운영과 자율 배포는 Claude Code. 팀에 어떤 에이전트를 붙일지 고민하고 있다면, 먼저 그 에이전트에게 무엇을 시킬지부터 정리해야 한다.
두 번째 질문: AI가 짠 코드, 얼마나 믿어도 되나
Cursor, Copilot, ChatGPT를 쓰는 팀의 수백 개 PR을 직접 리뷰한 개발자가 dev.to에 정리한 패턴이 있다. 인간은 거의 만들지 않지만, AI는 반복적으로 생성하는 코드 스멜 5가지다.
첫째, 환각 import. express-validator-utils 같은 이름은 그럴듯하게 들리지만 npm에 존재하지 않는다. LLM은 패키지 레지스트리를 조회하지 않고 다음 토큰을 예측할 뿐이다. AI 헤비 PR의 약 15%에서 발생한다고 한다.
둘째, 복붙 클론. "비슷한 엔드포인트 추가해줘"라고 하면 30줄짜리 코드에서 테이블명 하나만 바꿔 붙여넣는다. 인간 개발자는 고통을 느끼기 때문에 리팩토링하지만, AI는 반복에 고통이 없다.
셋째, 빈 catch 블록. 에러를 삼켜버리는 이 패턴은 새벽 3시에 앱이 조용히 죽는 원인이 된다. AI 학습 데이터에서 에러 핸들링은 종종 생략된 채 등장하기 때문이다.
넷째, deprecated API 사용. new Buffer(), url.parse() 같은 패턴은 AI가 학습 데이터 컷오프 이전 시점을 기준으로 추천하기 때문에 생긴다. 당장 테스트는 통과하지만 시한폭탄이다.
다섯째, 불필요한 과설계. 한 곳에서만 쓰이는 유틸리티 함수에 AbstractSingletonProxyFactoryBean 수준의 패턴을 덧씌운다. AI는 디자인 패턴을 많이 봤을수록 더 자주 꺼내 쓴다.
저자는 이 패턴을 자동으로 탐지하는 CLI 도구 vibe-check를 오픈소스로 공개했다. npx @bzprchny/vibe-check . 한 줄로 22개 룰을 돌리고 Vibe Score를 산출한다. GitHub Action으로 CI에 붙이면 모든 PR에 자동 점수가 붙는다. AI 생성 코드 비중이 높아질수록 이런 전용 린터의 필요성은 커진다.
세 번째 질문: 프로덕션에서 에이전트는 어떻게 실패하나
코드 품질보다 더 위험한 건 에이전트가 조용히 틀리는 경우다. 전통적인 소프트웨어는 시끄럽게 실패한다. 스택 트레이스, 500 에러, 알림. 에이전트는 다르다. 8번째 스텝에서 나온 이상한 결과의 원인이 2번째 스텝의 잘못된 판단인 경우가 많고, 그 사이에 아무 에러도 발생하지 않는다.
dev.to에 정리된 프로덕션 실패 패턴 5개 중 팀에 바로 적용 가능한 핵심 세 가지만 짚는다.
무한 친절 루프. 에이전트가 "한 번 더 확인하자"를 반복하며 툴 호출이 3개에서 47개로 불어난다. 결과 품질은 그대로고 API 비용만 치솟는다. 해결책은 단순하다. MAX_TOOL_CALLS, MAX_RUNTIME_SECONDS 같은 하드 버짓을 코드에 박아야 한다. 초과 시 에러로 죽이는 게 아니라 partial result로 반환하고 에스컬레이션 로그를 남기는 구조가 핵심이다.
툴 스키마 불일치. 캘린더 예약 에이전트가 date: "March 7th"를 넘기면 API는 거부한다. 에이전트는 "March 7, 2026"으로 재시도한다. 또 거부. 세 번째에 "03/07/2026"으로 성공—하지만 3번의 왕복을 낭비했고 다음 번엔 또 반복한다. Pydantic 같은 입력 검증 레이어를 LLM 앞단에 두고, 에러 응답도 {"error": "invalid_date_format", "expected": "YYYY-MM-DD"}처럼 LLM이 이해할 수 있는 구조로 줘야 한다.
과신 오답. 가장 잡기 어렵다. 스텝 카운트 정상, 툴 에러 없음, 실행 시간 정상—모니터링은 모두 녹색인데 출력이 틀렸다. 날짜를 잘못 추출하거나 티켓을 오분류했지만 형식은 완벽하다. 이건 로그만으로는 잡을 수 없다. 워크플로우마다 "정답"의 정의를 명시하고, 경량 검증 스텝을 에이전트 파이프라인 끝에 붙여야 한다.
테크 리드가 지금 당장 해야 할 것
세 사례를 하나의 프레임워크로 엮으면 구조가 보인다.
선택 → 생성 → 실행의 각 단계에 검증 레이어가 필요하다.
- 선택 단계: 에이전트에게 무엇을 시키는지에 따라 도구를 다르게 고른다. 리팩토링과 코드 이해는 Codex 계열, 자율 실행과 오케스트레이션은 Claude Code 계열이 현재 더 낫다.
- 생성 단계: AI가 만든 코드는 vibe-check 같은 전용 린터를 CI에 붙여 자동 검증한다. 특히 환각 import와 deprecated API는 사람 눈으로 잡기 어렵다.
- 실행 단계: 프로덕션 에이전트에는 반드시 하드 버짓과 구조화된 실행 로그를 달아야 한다. 에러 없는 완료가 곧 정답을 의미하지 않는다.
에이전트 신뢰의 조건은 '맹신'이 아니라 '검증 설계'
"AI는 도구일 뿐 아니라 동료다"라고 했을 때 그 의미는 AI를 믿으라는 게 아니다. 동료에게도 코드 리뷰를 하고, 배포 전 체크리스트를 돌리고, 프로덕션 이슈가 생기면 함께 디버깅하듯—에이전트에게도 그 수준의 거버넌스를 적용하라는 뜻이다.
속도는 이미 AI가 준다. 품질과 안정성은 아직 팀이 설계해야 한다. 지금 당장 팀 CI에 AI 코드 스멜 탐지를 붙이고, 에이전트 실행 로그에 버짓 제한을 추가하는 것부터 시작하라. 그게 내일 당장 써먹을 수 있는 AI-First 품질 관리의 첫걸음이다.