dev.to

When Code Gets Cheap, Verification Becomes Expensive: How AI changes the economics of software architecture

코드 생성 비용이 낮아질수록 검증 비용은 커집니다 — AI가 소프트웨어 아키텍처의 경제성을 바꾸는 방식

AI 코딩 에이전트가 구현 비용을 낮추면서 반복적으로 발생하는 검증 비용이 더 중요한 설계 요소가 된다고 설명합니다. 타입, 데이터베이스 제약, 상태 머신처럼 잘못된 상태를 구조적으로 막는 설계는 초기 비용이 더 들더라도 시스템 수명 전체의 검증 부담을 줄일 수 있습니다.

AI 요약

AI 코딩 에이전트는 코드 작성과 테스트, 리팩터링을 빠르게 처리하지만, 코드가 요구사항대로 동작하고 기존 불변 조건을 지킨다는 사실까지 빠르게 입증해 주지는 않습니다. 구현 비용은 주로 처음에 발생하지만 검증 비용은 기능 변경, 의존성 업데이트, 버그 수정, 마이그레이션 때마다 되풀이됩니다. 따라서 아키텍처를 비교할 때는 최초 구현 비용뿐 아니라 시스템 수명 동안 정확성을 얼마나 저렴하고 안정적으로 확인할 수 있는지도 따져야 합니다.

검증을 아키텍처의 속성으로 보기

글쓴이는 가상의 두 설계를 비교합니다. A안은 구현에 10만 달러가 들지만 변경 때마다 테스트와 회귀 검증에 많은 비용을 씁니다. B안은 구현에 12만 달러가 들지만 구조가 잘못된 상태를 막고 자동 보장을 제공합니다. A안이 매년 검증에 2만 달러, B안이 5천 달러를 쓴다면 처음 아낀 2만 달러는 오래가지 않습니다. 정확한 숫자보다 중요한 점은 구현비가 일회성인 반면 검증비는 반복해서 발생한다는 점입니다.

여기서 말하는 검증은 테스트를 더 많이 작성하는 일에 그치지 않습니다. 테스트로 잘못된 상태가 생기지 않는지 확인하는 대신, 애초에 그런 상태를 표현할 수 없도록 설계하는 편이 더 강한 보장을 줍니다. 임의의 문자열 대신 UserId 같은 강한 타입을 쓰면 일부 실수를 실행 전에 막습니다. 데이터베이스 제약은 잘못된 관계를 차단하고, 상태 머신은 허용되는 전이를 제한합니다. 스키마는 잘못된 데이터의 유입을 막고, 멱등성(idempotency)은 중복 작업에서 비롯되는 오류를 줄입니다. 명시적인 경계는 컴포넌트 사이의 가능한 상호작용을 줄입니다.

상태 머신을 저장소 구조에 담는 예

글에서는 Created, Validated, Processed, Completed 순서로 진행하는 작업 흐름을 예로 듭니다. 단일 WorkflowEvents 테이블에 이벤트 종류와 페이로드를 저장하면 애플리케이션이 이전 상태를 확인하고, 허용된 전이인지, 페이로드 형식이 맞는지, 불가능한 상태가 생기지 않았는지 판단해야 합니다. 이 규칙은 테스트와 애플리케이션 검증으로 확인할 수 있지만, 변경이 있을 때마다 다시 살펴야 합니다.

대신 단계별 구조를 저장소에 명시하고 각 단계가 바로 앞 단계의 레코드를 참조하게 만들 수 있습니다. Validated에는 해당 Created 레코드가 필요하고, Processed에는 유효한 Validated 레코드가 필요합니다. 단계별 스키마로 필요한 데이터도 표현합니다. 이렇게 하면 데이터베이스가 상태 머신의 일부를 집행해 잘못된 전이를 저장 단계에서 막습니다. 글쓴이는 이 방식이 언제나 낫다고 주장하지 않습니다. 구조가 복잡해지는 대가가 있으므로 문제에 따라 단순한 이벤트 테이블이나 다른 상태 머신 구현이 더 적절할 수 있습니다. 요점은 설계 선택에 따라 검증 비용이 달라진다는 것입니다.

AI보다 사용자, 그리고 시스템 수명 비용

글쓴이는 AI가 이해하기 쉬운 설계를 목표로 삼자는 주장이 아니라고 강조합니다. 더 중요한 변화는 AI가 소프트웨어 변경 속도를 높인다는 점입니다. 변경 횟수가 늘면 매번 복잡한 시스템 모델을 다시 떠올려 불변 조건을 확인하는 비용도 커집니다. 타입, 스키마, 제약 조건, 계약, 자동 검사를 갖춘 구조는 개발자와 리뷰어, 운영 담당자뿐 아니라 에이전트에도 명확한 경계와 피드백을 제공합니다.

따라서 아키텍처를 검토할 때는 구현 비용과 단순성, 성능에 더해 검증 비용, 구조적으로 막는 잘못된 상태의 수, 회귀 감지의 용이성, 자동 보장의 강도, 잘못된 변경의 영향 범위도 살펴야 합니다. 제약을 무조건 늘리라는 뜻은 아닙니다. 지나친 제약은 시스템을 경직시키고 불필요한 복잡성을 낳습니다. 제약이 정확성을 확인하는 반복 비용을 줄일 때 경제적 가치가 생깁니다. 궁극적으로 따질 질문은 AI가 수정하기 편한가가 아니라, 시스템을 만들고 운영하고 바꾸고 검증하는 전체 비용을 고려했을 때 사용자에게 가장 나은 결과를 주는가입니다.

dev.to 반응

  • @hannune — 데이터 파이프라인에서는 이 문제가 특히 심합니다. 퍼지 매칭 규칙을 작성하는 데는 세 시간쯤 걸렸지만, 한국 회사 이름의 재현율이 조용히 8포인트 떨어진 이유를 알아내는 데 그다음 2주를 썼습니다. 파이프라인에 변경 전 상태를 추적하고 재생할 방법이 없어서, 일부 구간의 이력을 다시 돌리고 결과 차이를 눈으로 확인해야 했습니다. 미뤄 둔 아키텍처 비용은 추적 가능성이었고, 그 뒤로 계속 나눠 갚고 있습니다.
  • @eternaclarity — 테스트는 어떤 상태가 생기지 않아야 한다는 점을 입증하고, 스키마는 그 상태를 불가능하게 만듭니다. 그러면 미래의 개발자가 규칙을 기억할 필요가 없습니다. 이게 ‘잘못된 상태를 표현할 수 없게 만들라’는 요점이고, 제가 특히 강조하고 싶은 부분입니다. 경제성에 관한 설명도 정확합니다. 구현은 한 번이지만 검증은 계속됩니다.
  • @mickyarun — 생성과 검증의 비대칭성은 맞습니다. 다만 그보다 한 단계 아래에 문제가 있다고 봅니다. 검증에는 확인을 실행하는 비용과, 그 결과를 믿을 근거를 마련하는 비용이 있습니다. 에이전트는 첫 번째 비용을 크게 줄입니다. 하지만 같은 에이전트가 테스트와 구현을 함께 작성하게 두면 두 번째 비용은 더 커집니다. 같은 이해에서 나온 두 결과가 서로 일치해도 새로운 정보는 없습니다. 검증처럼 보이지만 맞춤법 검사에 더 가깝습니다. 그래서 잘못된 상태를 표현할 수 없게 만드는 주장은 AI 시대에도 유효하지만, 테스트를 추가하자는 주장은 그렇지 않을 수 있습니다. 타입이나 데이터베이스 제약은 코드를 작성하지 않았고 의도를 추측하지도 않는 도구가 검사합니다. 도구를 선택할 때 한 번 신뢰를 검토하면 변경마다 다시 신뢰를 얻을 필요가 없습니다. 반면 테스트 모음은 작성자가 바뀔 때마다 신뢰성을 다시 입증해야 합니다. 에이전트가 작성자라면 모든 커밋이 그렇습니다. 다만 10만 달러와 12만 달러 예시는 반복 비용을 과소평가합니다. A안에는 연간 회귀 작업 2만 달러뿐 아니라, 빨간 테스트가 실제 오류인지 오래된 단언인지 판단하는 사람의 집중력도 들어갑니다. 이 비용은 저절로 줄어드는 게 아니라 사람들이 확인을 그만두면서 사라집니다. 아무도 읽지 않는 테스트 모음은 테스트가 없는 경우와 같은 방향으로 실패합니다. 그리고 검증 가능성을 아키텍처 속성으로 삼자는 주장은 동의하기 쉽지만 비용을 매기기는 어렵습니다. 가장 필요한 팀의 잘못된 상태는 타입 시스템에 없는 경우가 많습니다. 저희 사례는 실제 결제는 이뤄졌는데 기록에는 이뤄지지 않은 것으로 남는 경우입니다. 어떤 스키마도 그 상태를 표현 불가능하게 만들 수 없습니다. 거래 상대방을 기준으로 검증해야 하므로 느리고 외부 의존적이며, 우리 쪽 아키텍처만으로 비용을 낮출 수 없습니다. 따라서 이 조언은 정확성이 시스템 내부에 있는 경우에 적용된다는 경계를 명시하고 싶습니다.
  • @mateo_ruiz_6992b1fce47843 — 소프트웨어를 AI가 수정하기 쉽게 만드는 것과 시스템이 스스로 정확성을 입증하기 쉽게 만드는 것의 차이가 글의 핵심입니다. 덧붙이자면 검증 가능성은 컴포넌트 내부뿐 아니라 컴포넌트 경계에서도 고려해야 합니다. 강한 타입, 데이터베이스 제약, 상태 머신은 잘못된 내부 상태를 없앨 수 있지만, 실제 장애 중에는 각자 유효한 두 컴포넌트가 상대방이 보장하지 않은 것을 가정해서 생기는 경우가 많습니다. 그래서 계약, 멱등성, 명시적 상태 전이, 좁은 인터페이스가 AI 보조 개발에서 특히 가치 있습니다. 에이전트가 코드베이스를 추론하는 데만 도움이 되는 게 아니라, 사람과 에이전트가 변경 때마다 다시 찾아야 하는 컴포넌트 간 동작을 줄입니다. AI가 변경 속도를 높이면 지속적인 아키텍처 이점은 ‘AI 친화적인 코드’보다 변경당 검증 비용을 낮추는 데 있을 수 있습니다.