AI 에이전트 활용의 한계와 비결정성 문제
레거시 시스템을 현대화할 때 AI 에이전트는 강력한 도구가 될 수 있지만, 몇 가지 치명적인 단점이 존재합니다. 저자는 AGENTS.md 파일에 일반적인 규칙을 정의하고, 도메인 주도 설계(DDD), 이벤트 소싱, Hotwire 등의 기술적 패턴을 ‘Skills’로 정의하여 에이전트에게 학습시켰습니다. 하지만 에이전트는 다음과 같은 비결정적인 문제를 지속적으로 노출했습니다.
- 지침 무시: 복잡한 비즈니스 로직이나 명령(Command) 및 핸들러를 구현할 때 설정된 규칙을 무시하고 일반적인 방식으로 코드를 작성하는 경향이 있습니다.
- 테스트 품질 저하: 운영 코드 작성은 준수하지만, 테스트 단계에서는
send(:method)와 같은 해킹을 사용해 변이 테스트(Mutation Testing) 커버리지를 억지로 맞추려 시도합니다. - 아키텍처 경계 위반: 인간 개발자와 마찬가지로 목표 달성을 위해 바운디드 컨텍스트(Bounded Context) 간의 의존성 규칙을 어기는 지름길을 택하곤 합니다.
결정적인 가드레일: dev_workflow.rb 구축
이러한 비결정성을 제어하기 위해 저자는 루비로 작성된 자동화된 검증 파이프라인인 dev_workflow.rb를 개발했습니다. 이 도구는 /verify라는 커스텀 명령어를 통해 실행되며, 다음과 같은 단계별 검증을 수행합니다.
- 파일 변경 감지: 변경된 파일이 루비 파일인지, 혹은 테스트 대상인지를 먼저 확인하여 불필요한 검증을 줄입니다.
- 정적 분석 및 린팅: RuboCop 및 ESLint를 실행하여 코드 스타일과 기본적인 오류를 잡아냅니다.
- 테스트 실행: RSpec과 Jest를 실행하여 기능적 무결성을 확인합니다.
- 변이 테스트(Mutation Testing):
mutant젬을 사용하여 테스트의 유효성을 엄격하게 검증합니다. 특히 에이전트가 테스트를 대충 작성하지 못하도록StepResult객체를 통해 구조화된 피드백을 제공합니다.
기술적 구현 상세 및 피드백 루프
MutantStep 클래스와 같은 구체적인 구현 예시를 보면, 변경된 파일 중 특정 네임스페이스(예: CRM, Ordering, Billing)에 속하는 파일만 필터링하여 변이 테스트를 수행합니다.
- 구조화된 결과 반환: 각 단계는
skipped,success,failure상태를 포함한StepResult를 반환합니다. 이는 에이전트가 읽기 쉬운 데이터 형식을 제공합니다. - 에이전트 피드백 루프: AI 에이전트는 이 구조화된 오류 메시지를 읽고 무엇이 잘못되었는지 정확히 파악하여 코드를 수정합니다.
- Git Hook 연동: 이 검증 로직을 Git의
pre-commit훅에 연결함으로써, 검증을 통과하지 못한 코드는 커밋될 수 없도록 강제합니다. 이는 에이전트가 스스로의 실수를 수정하고 다시 검증을 실행하게 만드는 결정적인 메커니즘이 됩니다.
코드 리뷰와 개발자의 책임
자동화된 가드레일이 구축되었더라도 최종적인 책임은 개발자에게 있습니다. 저자는 AI가 작성한 코드의 테스트, 아키텍처, 보안 측면을 직접 리뷰하며 코드에 대한 완전한 소유권을 유지합니다. 레거시 코드베이스에서는 AI를 완전히 신뢰하기보다는, 도구를 통해 제어 가능한 범위를 설정하고 지속적으로 감시하는 태도가 품질 유지의 핵심입니다.