AI Sparkup

최신 AI 쉽게 깊게 따라잡기⚡

AI에게 “아키텍처 좀 지켜줘”를 백 번 말해도 안 되는 이유

AI 코딩 도구에게 “우리 구조를 따라줘”라고 매번 다시 타이핑하고 있다면, 그건 작업 흐름이 아니라 베이비시팅에 가깝습니다. 한 팀 리드가 월 2천만 달러를 처리하는 실제 금융 코드베이스에서 350번의 AI 세션을 돌리며 찾아낸 결론은, 더 똑똑하게 부탁하는 게 아니라 모델이 부딪힐 수밖에 없는 벽을 코드 안에 세우는 것이었습니다.

AI 생성 이미지

대형 사설 클라이언트 코드베이스를 다루는 팀 리드 Scott Spence가 자신의 실전 경험을 정리한 글입니다. 핵심은 ‘drift(드리프트)’라는 문제입니다. AI가 만든 그럴듯한 편법 하나가 복사되고, 다음 세션이 그걸 ‘원래 이 앱이 작동하는 방식’으로 취급하기 시작하면서 잘못된 패턴이 코드베이스 전체로 번지는 현상이죠. 그는 이걸 막는 방법이 프롬프트 강화가 아니라 리포지토리 자체에 심은 ‘가드레일’이라고 말합니다.

출처: How I Stop LLMs Drifting In Production Codebases – Scott Spence

편법 하나가 내일의 아키텍처가 되는 과정

드리프트는 작게 시작합니다. 게으른 동기화 코드 하나가 세 개로 늘어나고, 어떤 라우트가 다른 라우트를 흉내 내며 데이터베이스를 직접 불러오고, 의존성 그래프를 이해하기 귀찮아서 캐시를 통째로 무효화하는 코드가 등장합니다. 데모용 가짜 데이터와 임시 코드가 슬그머니 프로덕션 형태로 굳어집니다. 그리고 다음 세션은 이 모든 걸 ‘선례’로 받아들입니다.

문제의 뿌리는 LLM의 본성에 있습니다. 저자의 표현을 빌리면, LLM은 엔지니어이기 이전에 패턴 추종자입니다. 가장 가까이 있는, 작동하는 것처럼 보이는 예시를 찾아 거기서부터 이어 나가죠. 리포지토리가 깔끔한 경계와 검증된 패턴으로 차 있으면 모델은 그걸 복사합니다. 편법으로 차 있으면 그 편법을 더 빠르게 복사합니다. AI가 코드를 더 빨리 만들수록, 잘못된 패턴도 더 빨리 번지는 셈입니다.

조언(advice)이 아니라 압력(pressure)으로

이 글에서 가장 날카로운 구분이 여기입니다. 저자는 팀이 쓰지 말자고 정한 어떤 코드 패턴(원문에서는 AI가 유독 자주 오용하는 Svelte의 $effect를 예로 듭니다)을 막는 두 가지 방식을 비교합니다. 하나는 스타일 가이드나 프롬프트에 “그 패턴 쓰지 마세요”라고 적어두는 조언입니다. AI는 이걸 무시하고 코드를 만들 수 있고, 그러면 사람이 매번 리뷰에서 잡아내야 하죠. 다른 하나는 AI가 그 코드를 저장하려는 순간 도구가 “저장되지 않았습니다, 다른 방식으로 다시 쓰세요”라고 거부하는 압력입니다. 부탁이 아니라 막힌 길이라 AI는 다시 쓰는 수밖에 없습니다. 조언은 사람이 끝없이 단속해야 해서 리뷰 부채로 쌓이지만, 압력은 한 번 세워두면 알아서 막아주니 확장됩니다.

그래서 가드레일은 모델이 정중하게 잊을 수 없는 자리에 놓여야 합니다. 저자가 제시하는 층은 대략 코드가 쓰이기 전 도구 경계, 변경이 아직 작을 때의 린트 규칙, 잘못된 임포트가 일반화되기 전의 아키텍처 검사, 모델이 비즈니스 규칙을 지어내기 전의 문서 인용, 그리고 작업이 “완료됐다”고 선언되기 전의 핸드오프 검증으로 이어집니다. 핵심 발상은 단순합니다. 잘못된 코드가 파일로 저장되기 직전에, 도구가 “안 됩니다”라고 말하게 만드는 것이죠.

흥미로운 디테일 하나. 거부 메시지에는 “실제로 교체본을 쓰기 전까지 성공했다고 보고하지 말 것”이라는 문장이 들어갑니다. 에이전트는 도구 호출이 실패해도 “완료했습니다”라고 말하는 데 능하기 때문에, 실패를 명시적으로 만들어 모델이 상상 속 진척이 아니라 실제 작업을 이어 가게 만드는 장치입니다.

warn에서 block으로 가는 ‘래칫’

개인 실무자가 가장 가져갈 만한 통찰은 가드레일을 한 번에 강제하지 않는다는 점입니다. 저자는 세 가지 모드를 둡니다. 패턴을 관찰만 하고 싶을 때는 경고(warn), 리포지토리가 준비되면 차단(block), 의도적으로 허용하는 패턴은 끄기(off)입니다.

규칙이 너무 시끄러우면 우선 ‘권고(advisory)’로 둡니다. 가령 라우트 컴포넌트가 너무 커지면 검사는 통과시키되 “350줄, 상태 선언 7개, 추출을 고려하세요” 같은 냄새만 드러냅니다. 그러다 팀이 준비되면 권고를 강제 실패로 승격시키죠. 리뷰 코멘트가 세 번 반복되면 규칙으로, 규칙이 시끄러우면 권고로, 권고가 계속 진짜 문제를 잡으면 다시 규칙으로. 이 한 방향 톱니바퀴가 가드레일을 관료주의가 아니라 ‘길의 유지보수’로 만듭니다.

실수 없는 AI가 아니라, 실수가 싸고 시끄러운 시스템

저자가 공개한 350세션의 숫자는 벤치마크가 아니라 ‘영수증’에 가깝습니다. 경계 검사는 199개 세션에 등장했고 그중 39개에서 실패했으며, 라우트가 데이터베이스에 직접 접근하거나 데모 데이터가 프로덕션 경로로 새어 드는 실제 문제들을 잡아냈습니다. 중요한 건 그 규칙들이 아무도 안 보는 문서가 아니라 평소 작업 경로 안에 있었다는 점입니다.

이 글이 겨냥하는 목표는 “실수하지 않는 AI”가 아닙니다. 그런 건 존재하지 않으니까요. 대신 흔한 실수가 싸고, 시끄럽고, 고치기 지루한 시스템을 만드는 것입니다. 가드레일에는 분명한 대가가 따릅니다. 기술적으로는 멀쩡한 코드를 막기도 하고, 허용 목록을 계속 관리해야 하며, 가끔은 일부러 단순하게 만든 규칙이 영리한 해법을 가로막습니다. 그럼에도 저자는 매 세션마다 AI가 아키텍처를 새로 발명하는 코드베이스보다, 지루한 오탐 몇 개를 택하겠다고 말합니다.

원문에는 Svelte의 $effect 차단, 경계 검사 스크립트, 문서 인용 규칙, 스킬 파일, 핸드오프 검증까지 여섯 개 층의 구체적인 구현 예시와 설정이 담겨 있습니다. 자신의 스택에 맞춰 직접 벽을 세워 보고 싶다면 원문을 참고하시길 권합니다.


AI Sparkup 구독하기

최신 게시물 요약과 더 심층적인 정보를 이메일로 받아 보세요! (무료)

Comments

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다