잘못된 지표
AI 생성 코드 품질에 대한 대부분의 논의는 생성 시점의 정확성에 초점을 맞춥니다. 출력이 컴파일되는가? 테스트를 통과하는가? 명세에 맞는가?
이것들은 기본 조건일 뿐입니다. 진짜 비용에 대해서는 아무것도 알려주지 않습니다.
진짜 지표는 대체 가능성입니다. 요구사항이 변할 때 이 module을 삭제하고 동일한 contract 뒤에서 다시 구현하는 비용이 얼마나 싼가?
답이 “거의 공짜”라면, AI의 속도가 복리로 쌓입니다. 답이 “먼저 암묵적 의존성 여섯 개를 추적해야 합니다”라면, 얻었다고 생각한 속도 이점은 이미 사라진 것입니다.
AI 코드가 결합 방향으로 흐르는 이유
대규모 언어 모델은 당장의 요청에 최적화합니다. 미래의 변경에 최적화하지 않습니다.
로그인 흐름을 프롬프트하면 동작하는 로그인 흐름을 얻습니다. Firebase에서 Supabase로, 또는 커스텀 JWT 서비스로 바꿀 때 그것을 소비하는 어떤 화면도 건드리지 않아도 되는 auth interface 뒤의 로그인 흐름은 얻지 못합니다.
이것은 모델의 결함이 아닙니다. 컨텍스트의 결함입니다. 모델은 대체 가능성을 위해 최적화하라는 요청을 받지 않았으므로 그렇게 하지 않은 것입니다.
결과적으로 AI 생성 코드는 기본적으로 강한 결합 방향으로 흐릅니다. 모델이 나빠서가 아니라, 격리는 next-token predictor에게 결코 최소 저항 경로가 아니기 때문입니다.
대체 가능성은 아키텍처 결정이다
대체 가능성은 우연히 생기지 않습니다. 의도적인 구조적 선택입니다:
- 모든 외부 의존성은 애플리케이션이 소유하는 interface 뒤에 놓인다.
- 모든 생성된 module은 구현이 아닌 contract를 노출한다.
- 모든 선택적 기능은 직접 import하지 않고 주입된다.
- 모든 합성 결정은 50개 파일에 흩어지지 않고 하나의 composition root에 존재한다.
새로운 이야기가 아닙니다. 기본적인 dependency inversion입니다. 새로운 것은 AI 생성 코드가 이 원칙들을 위반하는 것을 손쉽고 눈에 보이지 않게 만든다는 점입니다. 무언가를 바꿔야 할 때까지는요.
복리 효과
모든 module이 대체 가능할 때:
- 나쁜 생성 결과의 비용은 며칠이 아니라 몇 분입니다.
- 벤더 변경은 rewrite가 아니라 interface 교체입니다.
- AI 속도가 반복에 걸쳐 로그 함수적이 아니라 선형으로 유지됩니다.
- 팀이 “동일한 contract 뒤에서 이것을 재생성하라”고 말할 수 있고, 실제로 그 말이 통합니다.
module들이 얽혀 있을 때:
- 모든 변경이 전체 의존성 그래프를 이해해야 합니다.
- AI 지원 refactor가 매번 관계없는 시스템을 깨뜨릴 위험이 있습니다.
- blast radius가 예측 불가능하기 때문에 팀이 점차 AI 출력을 신뢰하지 않게 됩니다.
- 속도가 AI 이전 수준으로 되돌아가지만, 유지해야 할 코드는 더 많아집니다.
실용적 테스트
AI 생성 module을 codebase에 수용하기 전에 한 가지 테스트를 적용하십시오:
이 파일을 삭제하고, 이것이 노출하는 interface만 사용하여 처음부터 다시 구현할 때, 소비자를 하나도 수정하지 않아도 되는가?
그렇다면 배포하십시오. 아니라면 배포 전에 경계를 바로잡으십시오.
이것은 enforcement 비용이 낮습니다. composition root와 interface 우선 설계가 이 속성을 구조적으로 제공합니다. 정교한 거버넌스가 필요하지 않습니다. 하나의 아키텍처 규칙을 일관되게 적용하면 됩니다.
AI-Native 아키텍처와의 연결
이 더 넓은 문제에 대해 Stanford CS146S는 AI coding을 제대로 보고 있다 — 빠진 과목은 아키텍처다에서 다룬 바 있습니다. 대체 가능성 원칙은 AI-native codebase가 버전 1을 지나서도 생존할 수 있게 만드는 구체적인 메커니즘입니다.
Stanford는 개발자들에게 AI 도구를 효과적으로 사용하는 법을 가르치고 있습니다. 중요한 일입니다. 하지만 대체 가능성 없는 도구 숙련도는 함정입니다. codebase를 바꾸기 비싸질 때까지 빠르게 배포하다가, 그 이후에는 AI를 전혀 사용하지 않은 팀보다 느려집니다.
규율은 “더 잘 프롬프트하라”가 아닙니다. 규율은 “프롬프트 실수를 되돌리기 싼 구조로 설계하라”입니다.
FAQ
AI 생성 코드에서 “대체 가능한 아키텍처”란 무엇인가요?
대체 가능한 아키텍처란 모든 AI 생성 module이 구현 자체가 아니라 시스템의 나머지가 의존하는 interface 뒤에 놓이는 것을 의미합니다. 요구사항이 변하거나 생성이 잘못되었을 때, 소비자를 건드리지 않고 해당 module을 삭제하고 다시 구현합니다.
AI 생성 codebase에서 대체 가능성을 어떻게 enforcement하나요?
세 가지 메커니즘입니다: 애플리케이션이 소유하는 interface(의존성이 소유하는 것이 아닌), 모든 구현체가 연결되는 단일 composition root, 그리고 어떤 module이든 다른 module의 내부를 직접 import하면 실패하는 CI 검사입니다.
대체 가능성이 초기 개발 속도를 늦추나요?
아닙니다. 구현을 생성하기 전에 interface를 정의하는 데 몇 초가 추가될 뿐입니다. 그렇게 하지 않는 비용은 몇 주 뒤 벤더 교체나 refactor가 전면 rewrite로 변할 때 나타납니다.
이것은 의존성 주입과 같은 것인가요?
의존성 주입은 대체 가능성을 달성하기 위한 하나의 메커니즘이지만 전체 그림은 아닙니다. 대체 가능성은 contract tests, 경계 검증, composition root도 필요로 합니다. 단지 생성자 매개변수만으로는 부족합니다.