품질이 새로운 양이다
요약
AI로 인해 코드 생산량은 급증했으나, 코드 리뷰와 품질 검증이 새로운 병목 현상으로 떠오르고 있습니다. 양적 팽창 속에서 신뢰할 수 있는 소프트웨어를 구축하기 위한 품질 관리의 중요성을 강조합니다.
핵심 포인트
- AI로 인한 코드 생산량 증가가 코드 리뷰 병목 현상을 초래함
- 단순 작동 여부를 넘어 시스템의 신뢰성과 유지보수성이 핵심 과제임
- 코드 churn 및 결함률 상승 등 AI 도입에 따른 부작용 주의 필요
- 숙련된 개발자의 필터링 능력이 AI 시대의 핵심 역량임
AI는 글쓰기 소프트웨어를 저렴하게 만들었습니다. 그것은 명백한 이야기입니다. 더 많은 코드, 더 많은 프로토타입 (prototypes), 더 많은 풀 리퀘스트 (pull requests), 더 많은 “나는 이것을 오후 한나절 만에 만들었다”는 순간들. 매우 인상적입니다. 매우 위험합니다. 매우 LinkedIn스럽습니다.
왜냐하면 흥미로운 이야기는 그보다 한 단계 뒤에서 시작되기 때문입니다. 양(quantity)이 저렴해지면, 품질(quality)이 병목 현상 (bottleneck)이 됩니다.
여기서 품질이란 “컴파일이 되는가?” 또는 “모델이 자신의 가정을 영웅적으로 확인하는 테스트를 함께 생성했는가?”를 의미하는 것이 아닙니다. 물론 그런 것들도 여전히 중요합니다. 하지만 그것들은 더 이상 희소한 것이 아닙니다. 희소한 것은 신뢰 (confidence)입니다. 변경 사항이 올바르다는 신뢰, 팀이 이를 이해하고 있다는 신뢰, 제품이 여전히 타당하다는 신뢰, 그리고 시스템이 미래의 개발자들에게 고고학적 유물로 변하지 않을 것이라는 신뢰 말입니다.
소프트웨어를 구축하는 것이 이보다 쉬웠던 적은 없었습니다. 좋은 소프트웨어를 구축하는 것이 이보다 어려웠던 적은 없었습니다.
코드 리뷰는 청구서가 도착하는 곳입니다
AI는 팀이 이해도를 높이는 속도보다 더 빠르게 출력을 증가시킵니다. 이것이 바로 코드 리뷰 (code review)가 새로운 병목 현상이 되고 있는 이유입니다. 에이전트 기반 코드 리뷰에 관한 O’Reilly의 기사는 몇 가지 놀라운 수치로 이를 가시화합니다: 코드 churn (code churn) 861% 증가, incident-to-PR 비율 242.7% 증가, 결함률 (defect rates) 9%에서 54%로 상승, 중간 리뷰 시간 (median review duration) 441.5% 증가, 그리고 리뷰 없이 병합되는 더 많은 PR들.
그것은 생산성 그래프가 아닙니다. 축 레이블이 붙은 화재 경보기입니다.
전통적인 리뷰는 인간이 인간의 속도로 코드를 생산하는 세상을 위해 설계되었습니다. 한 개발자가 변경 사항을 작성하면, 다른 개발자가 이를 리뷰했고, 시스템은 느렸지만 적어도 어느 정도 균형을 이루었습니다. AI는 그 균형을 깨뜨립니다. 이제 코드는 인간이 깊이 있게 리뷰할 수 있는 속도보다 더 빠르게 도착할 수 있으며, 병목 현상은 “우리가 솔루션을 생산할 수 있는가?”에서 “유능한 누군가가 이 솔루션이 옳다고 확신할 수 있는가?”로 이동합니다.
모든 것을 한 줄씩 검토하는 것이 정답은 아닙니다. 그것은 확장성 (scale)이 없습니다. 하지만 아무것도 변하지 않은 척하며 검토를 덜 하는 것은 더 나쁩니다. 그렇게 하면 기술적으로는 작동하지만, 정신적으로는 비명을 지르며, 리팩터링 (refactor)을 할 때마다 사제가 필요할 것 같은 코드베이스를 얻게 됩니다.
1인 AI 로켓이 팀이라는 벽에 부딪힐 때
현재의 많은 AI 베스트 프랙티스 (best practices)는 경험이 풍부하고 숙련된 1인 개발자에게 매우 효과적으로 작동합니다. 그리고 그것은 타당합니다. 도메인 (domain)을 알고, 아키텍처 (architecture)를 알며, 트레이드오프 (tradeoffs)를 이해하고, 세 겹의 자신만만한 자동 완성 (autocomplete) 너머로 말도 안 되는 소리를 감지할 수 있다면, AI는 놀랍습니다. 그것은 잠도 자지 않고, 불평도 하지 않으며, 가끔은 감정적으로 옳다고 느껴서 데이터베이스 마이그레이션 (database migration)을 스스로 만들어내는 매우 빠른 주니어 개발자를 둔 것과 같습니다.
강력한 개인에게 이것은 진정한 초능력이 될 수 있습니다. 인간은 머릿속에 시스템 모델을 유지합니다. AI는 옵션, 초안, 테스트, 리팩터링 (refactorings), 설명, 그리고 글루 코드 (glue code)를 생성합니다. 전문가는 이를 필터링합니다. 루프 (loop)는 긴밀하며, 컨텍스트 (context)는 국소적입니다. 품질 게이트 (quality gate)는 하나의 두뇌입니다.
팀은 더 어렵습니다.
팀에서는 병목 현상 (bottleneck)이 구현에만 국한되지 않습니다. 그것은 공유된 이해 (shared understanding)입니다. 누가 우리가 왜 이 아키텍처를 선택했는지 알고 있습니까? 누가 3주 전의 제품 제약 사항 (product constraint)을 기억하고 있습니까? 어떤 이해관계자 (stakeholder)의 요청이 의도적으로 구현되지 않았는지 이해하는 사람은 누구입니까? 이 새로운 기능이 도메인 모델 (domain model)에 부합하는지, 아니면 단순히 PR (Pull Request) 설명에서 그럴듯하게 들리는 것뿐인지 구별할 수 있는 사람은 누구입니까?
AI는 개인의 루프를 더 빠르게 만들지만, 팀은 모든 개인을 개별적으로 더 빠르게 만든다고 해서 확장 (scale)되지 않습니다. 팀은 이해를 전달 가능하게 (transferable) 만듦으로써 확장됩니다.
그 지점에서 많은 현재의 관행들이 벽에 부딪힙니다. 프롬프팅 (Prompting)을 더 강하게 한다고 해결되지 않습니다. 더 많은 에이전트 (agents)를 투입한다고 해결되지 않습니다. 더 큰 컨텍스트 윈도우 (context window)가 도움이 되긴 하지만, 그것이 마법처럼 합의를 만들어내지는 않습니다. 팀 수준의 AI에는 공유된 컨텍스트 인프라 (shared context infrastructure)가 필요합니다: 명시적인 결정, 가시적인 가정, 도메인 언어 (domain language), 제품 원칙, 리뷰 기준, 그리고 오해가 아키텍처가 되기 전에 표면화할 수 있는 방법이 필요합니다.
이것이 바로 품질 관행 (quality practices)이 더 이상 관료주의가 아닌 이유입니다. 그것들은 확장 계층 (scaling layer)입니다.
ADR (Architecture Decision Records)과 오픈 지식 형식 (Open Knowledge Format)은 단순히 "보기 좋은 문서"가 아닙니다. 이것들은 AI 사용이 팀과 호환될 수 있게 만드는 방법입니다. 이것들은 개인의 추론 (private reasoning)을 공유된 산출물 (shared artifacts)로 전환합니다. 이것들은 인간과 에이전트 (agents)가 동일한 객체를 두고 논쟁할 수 있게 합니다. 이것들은 코드뿐만 아니라 코드 이면에 담긴 의도 (intent)까지 검토할 수 있게 만듭니다.
1인 AI 로켓은 인상적입니다. 하지만 팀이 비행하기를 원한다면, 로켓 그 이상이 필요합니다. 항공 교통 관제 (air traffic control)가 필요합니다.
리뷰는 한 단계 위로 이동해야 합니다
우리는 여전히 버그, 보안 문제, 테스트 공백, 그리고 아키텍처 드리프트 (architecture drift)를 찾아내야 합니다. 하지만 우리는 제품 품질도 검토해야 합니다: 이것이 직관적인가? 일관성이 있는가? 실제 사용자 문제를 해결하는가? 명확성을 더하는가 아니면 복잡성을 더하는가? 그리고 취향 (taste)을 반영하고 있는가?
이것이 중요한 이유는 AI가 이해관계자 (stakeholder)의 요구사항을 위험할 정도로 저렴하게 만들어 주기 때문입니다. 과거에는 어떤 나쁜 아이디어들은 구현 비용이 너무 많이 들어서 평화롭게 사라졌습니다. 아름다운 자연 선택 기제였죠. 이제 AI는 그 모든 것을 만들어낼 수 있습니다. 백로그 (backlog)에는 더 이상 브레이크가 없습니다. 대신 로켓 엔진과 의심스러운 방향 감각이 달려 있습니다.
따라서 절제 (restraint)는 기술적 숙련도가 됩니다. 취향 (taste)은 엔지니어링의 일부가 됩니다. "아니오"라고 말하는 것이 아키텍처가 됩니다.
사용자와 이해관계자가 원하는 모든 것을 만들 수 있다고 해서, 반드시 그래야 한다는 뜻은 아닙니다. 이 문장은 점심시간 전까지 모든 요청 사항이 작동하는 프로토타입과 함께 전달되기 전까지는 당연하게 들립니다.
팀에게 있어 이것은 훨씬 더 중요합니다. 단 한 명의 전문가는 코딩을 하는 동안 조용히 자신의 취향을 적용할 수 있습니다. 하지만 팀은 조용한 취향에 의존할 수 없습니다. 취향은 논의 가능해져야 합니다. 제품 판단 (product judgment)은 검토 가능해져야 합니다. 아키텍처는 가시화되어야 합니다. 그렇지 않으면 모든 개발자와 모든 에이전트는 로컬 최적화 (optimize locally)를 수행하게 되고, 제품은 개별적으로는 합리적이지만 집합적으로는 사과가 필요한 결정들의 모음으로 서서히 변해갑니다.
AI는 품질에 집중할 때 놀라운 능력을 발휘합니다 — 우리가 그 방향을 겨냥한다면
Clean Code (또는 더 나아가 Vertical Slices), Domain-Driven Design (DDD), Behavior-Driven Development (BDD), 더 나은 테스트, 더 명확한 네이밍, 유용한 문서화, Architecture Decision Records (ADR) (그리고 js/python 개발자들에게는 타입 시스템 (type-systems)조차 당연한 것이 아님) — 팀들이 "하지만 시간이 없어요"라고 말하기 직전에 중요하다고 부르곤 했던 이 모든 것들이 갑자기 훨씬 쉬워집니다. AI는 티켓에서 도메인 언어 (domain language)를 추출하고, BDD 시나리오를 초안 작성하며, 제품 의도와 코드를 비교하고, 불일치를 찾아내며, 리팩터링 (refactorings)을 제안하고, 트레이드오프 (tradeoffs)를 요약하며, 적어도 논쟁을 시작하기에는 충분히 괜찮은 수준의 문서를 생성할 수 있습니다.
올바른 논쟁을 시작하는 것은 과소평가되어 있습니다.
잘못 사용하면 AI는 이해보다 더 많은 코드를 만들어냅니다. 잘 사용하면 AI는 코드보다 더 많은 이해를 만들어냅니다. 이것이 가속과, 벽을 향해 곧장 돌진하는 가속의 차이입니다.
그리고 바로 이 지점에서 팀 규모 확장 (team-scaling)의 이점이 나타납니다. AI는 암묵지 (tacit knowledge)를 공유 지식 (shared knowledge)으로 전환하는 데 도움을 줄 수 있습니다. 모호한 의도를 예시로 바꿀 수 있습니다. 엉망인 토론을 결정 기록 (decision record)으로 바꿀 수 있습니다. PR을 트레이드오프에 대한 검토 가능한 설명으로 바꿀 수 있습니다. "우리가 이렇게 합의한 줄 알았는데"를 "우리가 절대 그렇게 합의하지 않았음을 확인할 수 있는 결과물 (artifact)이 여기 있습니다"로 바꿀 수 있습니다.
이것은 단순한 문서화가 아닙니다. 그것은 조직적 디버깅 (organizational debugging)입니다.
불완전한 ADR의 놀라운 가치
가장 좋은 예 중 하나는 Architecture Decision Records (ADR)입니다. 저는 예전에 ADR을 주로 문서화의 일환으로 생각했습니다. 유용하고, 책임감 있으며, 약간 지루해서, 소프트웨어 세계에서 우주의 열적 죽음(heat death of the universe) 이후에나 일어날 법한 "나중에" 작성될 운명인 것으로 말이죠.
AI는 경제성을 변화시킵니다. 사후에 ADR을 생성할 수 있습니다. 이는 의심스럽게 들릴 수 있으며, 맞습니다. 이상적으로는 결정이 내려질 때 문서화되어야 합니다. 하지만 사후 ADR조차도 시스템이 무엇을 믿고 있는 것처럼 보이는지를 드러내 주기 때문에 믿을 수 없을 정도로 유용할 수 있습니다.
생성된 ADR이 "우리는 ~라는 이유로 이 아키텍처를 선택했습니다..."라고 말하면, 팀원 중 누군가가 즉시 말합니다: "잠깐만요, 우린 그렇게 안 했는데요."
완벽합니다.
그것은 문서화의 실패가 아닙니다. 그것은 가시화된 오해입니다. 약간 잘못된 ADR (Architecture Decision Record, 아키텍처 결정 기록)이라도 ADR이 없는 것보다는 나을 수 있습니다. 왜냐하면 논의를 위한 구체적인 대상을 만들어주기 때문입니다. 그것은 팀에게 수정하고, 도전하고, 개선하며, 정렬할 수 있는 무언가를 제공합니다.
소프트웨어 엔지니어링은 사양(specification)을 수집하는 과정입니다.
이는 Open Knowledge Format (OKF, 개방형 지식 형식)에도 동일하게 적용됩니다: 결정 로그, 도메인 개념, 가정, 리스크, 예시, 공개된 질문, 제품 원칙 등 말입니다. 첫 번째 버전이 완벽할 필요는 없습니다. 사실, 약간 불완전하다면 오히려 더 나을 수도 있습니다. 완벽한 문서는 침묵을 만들 수 있습니다. 불완전한 문서는 유용한 마찰(friction)을 만들어내며, 유용한 마찰이 발생하는 지점에서 공동의 이해(shared understanding)가 구축됩니다.
이것은 팀 내에서 특히 강력한데, 그 산출물(artifact)이 사람, 코드, 그리고 에이전트(agents) 사이의 접점이 되기 때문입니다. 개발자는 그것에 이의를 제기할 수 있습니다. 리뷰어는 그것을 활용할 수 있습니다. 제품 담당자는 의도를 수정할 수 있습니다. 다음 AI 실행 시에는 그것을 컨텍스트(context)로 사용할 수 있습니다. 새로운 팀원은 무엇이 존재하는지뿐만 아니라, 그것이 왜 존재하는지도 이해할 수 있습니다.
그것이 품질이 확장되는 방식입니다. 모든 개인이 더 많은 것을 기억하게 만드는 것이 아니라, 중요한 것들을 잃어버리기 어렵게 만드는 방식으로 말입니다.
함정은 인지적 부채(cognitive debt)입니다
위험은 단순히 AI가 나쁜 코드를 작성한다는 것이 아닙니다. 인간은 훨씬 덜 인상적인 하드웨어를 가지고도 수십 년 동안 나쁜 코드를 작성해 왔습니다. 진짜 위험은 AI가 팀이 이해할 수 있는 속도보다 더 빠르게 그럴듯한 코드를 작성한다는 것입니다.
이것은 인지적 부채(cognitive debt)를 생성합니다: 제품의 일관성보다 더 많은 기능, 신뢰보다 더 많은 테스트, 합의보다 더 많은 문서, 소유권보다 더 많은 코드 말입니다. 그 시점에서 AI는 팀을 더 빠르게 만든 것이 아닙니다. 혼란을 확장 가능한(scalable) 상태로 만든 것입니다.
우리도 이 함정에 빠졌습니다. AI는 진보를 수월하게 느껴지게 만들었고, 그래서 우리는 더 많은 것을 생산했습니다. 그러자 리뷰는 더 무거워졌고, 가정은 추적하기 어려워졌으며, 코드가 완벽해 보이는 곳에서도 오해가 나타나기 시작했습니다. 중요한 부분은 이를 조기에 알아차리는 것이었습니다.
그 대응책은 AI를 덜 사용하는 것이 아니었습니다. AI를 다르게 사용하는 것이었습니다. 구현뿐만 아니라 리뷰 영역(review surfaces)을 위해서도 사용해야 했습니다: ADR(Architecture Decision Records), 설명, 도메인 노트, 제품 관련 질문, 테스트 시나리오, 리스크 요약, 대안적 해석 등입니다. AI는 코드 생성기(code generator)라기보다 **오해 탐지기 (misunderstanding detector)**에 가까워졌습니다.
드러난 오해는 선물입니다. 숨겨진 오해는 가짜 안경과 콧수염을 붙이고 나타난 장애(incident)입니다.
이것이 팀 차원에서의 AI 스윗 스팟 (sweet spot)입니다. AI에게 다음 변경 사항을 만들어 달라고만 하지 마세요. 변경 사항 뒤에 숨겨진 추론을 검사 가능하게(inspectable) 만들어 달라고 요청하세요. 가정을 드러내 달라고 요청하세요. 변경 사항을 ADR, OKF, 제품 원칙, 그리고 도메인 언어(domain language)와 비교해 달라고 요청하세요. 팀이 더 일찍, 그리고 더 정확하게 이견을 제시할 수 있도록 도와달라고 요청하세요.
목표는 대화의 횟수를 줄이는 것이 아닙니다. 목표는 안개를 걷어내고 더 나은 대화를 나누는 것입니다.
품질을 위한 작업은 처음에는 더 느리게 느껴진다
여기 불편한 사실이 있습니다. 품질을 위해 AI를 사용하는 것은 종종 초기에 속도를 늦춥니다 (적어도 결과물을 쏟아내는 속도와 비교했을 때 말입니다). 리뷰 작업이 추가됩니다. 더 많은 토론이 생깁니다. 이견이 드러납니다. 머지(merge)하기 전에 팀이 생각할 것을 요구합니다. 매우 무례하게 느껴질 수 있습니다.
AI가 구현을 순식간에 끝내버리는 경험을 했을 때는 이것이 좌절스럽게 느껴질 수 있습니다. 하지만 더 느리게 느껴지는 것이 반드시 낭비인 것은 아닙니다. 종종 그것은 시스템이 학습하는 과정입니다. 더 나은 결정은 재작업(rework)을 줄입니다. 더 나은 ADR은 혼란을 줄입니다. 더 나은 도메인 언어는 번역 오류를 줄입니다. 더 나은 제품 리뷰는 기능 비대화(feature bloat)를 줄입니다. 더 나은 테스트는 두려움을 줄입니다.
장기적으로 볼 때, 품질은 생산성이 됩니다. 어쩌면 그리 멀지 않은 미래에 말이죠.
비결은 팀이 더 많은 생각을 하고 있지만 아직 복리 효과를 받지는 못한, 그 어색한 중간 단계를 견뎌내는 것입니다. 여기서 문화가 중요해집니다. 만약 문화가 산출물(output)만을 숭배한다면, 품질을 위한 작업은 지연처럼 보일 것입니다. 만약 문화가 이해(understanding)를 가치 있게 여긴다면, 품질을 위한 작업은 투자로 보일 것입니다.
이것이 바로 스케일링 (scaling)이 효과를 발휘하기 시작하는 지점이기도 합니다. 처음에는 ADRs, OKRs, 그리고 더 풍부한 리뷰들이 추가적인 부담처럼 느껴질 것입니다. 하지만 나중에는 이것들이 레일 (rails)이 됩니다. 신규 인원이 더 빠르게 온보딩 (onboarding)됩니다. 에이전트 (Agents)는 더 관련성 높은 초안을 생성합니다. 리뷰는 덜 반복적이게 됩니다. 결정 사항들이 매 스프린트 (sprint)마다 재발견되는 일이 중단됩니다. 제품에 대한 논의는 감정적일 필요가 없어지는데, 이는 가설들이 모두의 머릿속에서 위장한 채 숨어 있는 대신 테이블 위에 명확히 드러나기 때문입니다.
초기 비용은 실재합니다. 하지만 그 대안은 인지 부채 (cognitive debt)에 대한 이자를 영원히 지불하는 것인데, 이는 들리는 것보다 훨씬 덜 즐거운 일이며, 이미 들리는 것만으로도 끔찍합니다.
품질이 새로운 양이다
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기