Articlemartinfowler.com·2026년 3월 3일·0

Design-First Collaboration

Quick Summary

AI 코딩 협업에서는 곧바로 구현을 받기보다, 인간 페어의 화이트보딩처럼 기능·구성요소·상호작용·계약을 단계적으로 합의한 뒤 코드로 들어가야 한다는 주장이다.

Design-First Collaboration 관련 대표 이미지

🖼️ 인포그래픽

Design-First Collaboration 내용을 설명하는 본문 이미지

🖼️ 4컷 인포그래픽

Design-First Collaboration 내용을 설명하는 본문 이미지

💡 한 줄 요약

AI 코딩 협업에서는 곧바로 구현을 받기보다, 인간 페어의 화이트보딩처럼 기능·구성요소·상호작용·계약을 단계적으로 합의한 뒤 코드로 들어가야 한다는 주장이다.

📌 핵심 요약

  • 글은 인간 페어 프로그래밍이 복잡한 작업에서 먼저 화이트보드로 구성요소, 데이터 흐름, 경계, 요구사항을 맞춘 뒤 코딩하는 것처럼, AI와의 협업도 구현 전에 설계 정렬이 필요하다고 설명한다.
  • AI 코딩 보조자는 요구사항을 받으면 즉시 수백 줄의 코드를 생성하지만, 그 과정에서 범위, 컴포넌트 경계, 데이터 흐름, 인터페이스, 오류 처리 같은 설계 결정을 코드 안에 조용히 묻어 둔다.
  • 저자는 이를 구현 함정이라고 부르며, 사용자가 처음 설계 판단을 확인하는 시점이 코드 리뷰 단계가 되면 범위·아키텍처·통합·계약·품질을 한꺼번에 평가해야 해 인지 부담이 커진다고 지적한다.
  • 해법은 AI에게 바로 구현을 시키지 않고 기능, 구성요소, 상호작용, 계약의 단계로 나누어 대화하는 것이다. 각 단계는 코드가 생기기 전에 동의하거나 반박하거나 방향을 바꿀 수 있는 체크포인트가 된다.
  • 알림 서비스 사례에서 저자는 BullMQ를 감싸는 불필요한 RetryQueue 추상화를 설계 단계에서 제거했고, 합의된 계약을 바탕으로 구현 전에 테스트를 작성할 수 있었다. 이 방식은 작업 복잡도에 맞게 일부 단계만 사용할 수 있으며, 사전 프로젝트 맥락 공유와 결합될 때 더 효과적이다.

🧩 주요 포인트

  1. 글은 인간 페어 프로그래밍이 복잡한 작업에서 먼저 화이트보드로 구성요소, 데이터 흐름, 경계, 요구사항을 맞춘 뒤 코딩하는 것처럼, AI와의 협업도 구현 전에 설계 정렬이 필요하다고 설명한다.
  2. AI 코딩 보조자는 요구사항을 받으면 즉시 수백 줄의 코드를 생성하지만, 그 과정에서 범위, 컴포넌트 경계, 데이터 흐름, 인터페이스, 오류 처리 같은 설계 결정을 코드 안에 조용히 묻어 둔다.
  3. 저자는 이를 구현 함정이라고 부르며, 사용자가 처음 설계 판단을 확인하는 시점이 코드 리뷰 단계가 되면 범위·아키텍처·통합·계약·품질을 한꺼번에 평가해야 해 인지 부담이 커진다고 지적한다.
  4. 해법은 AI에게 바로 구현을 시키지 않고 기능, 구성요소, 상호작용, 계약의 단계로 나누어 대화하는 것이다. 각 단계는 코드가 생기기 전에 동의하거나 반박하거나 방향을 바꿀 수 있는 체크포인트가 된다.
  5. 알림 서비스 사례에서 저자는 BullMQ를 감싸는 불필요한 RetryQueue 추상화를 설계 단계에서 제거했고, 합의된 계약을 바탕으로 구현 전에 테스트를 작성할 수 있었다. 이 방식은 작업 복잡도에 맞게 일부 단계만 사용할 수 있으며, 사전 프로젝트 맥락 공유와 결합될 때 더 효과적이다.

🧠 상세 정리

1. 화이트보드가 먼저라는 출발점

저자는 복잡한 기능을 동료와 페어 프로그래밍할 때 곧바로 키보드 앞에 앉지 않는다고 설명한다. 먼저 화이트보드에서 구성요소를 그리고, 데이터 흐름을 논의하며, 경계가 어디에 있어야 하는지 다툰다. 이 과정은 구현 전에 시스템이 무엇을 해야 하는지 합의하는 단계이며, 때로는 짧고 때로는 길지만 코드의 품질을 결정하는 핵심 작업이다. 따라서 화이트보딩은 부가적인 절차가 아니라 실제 사고가 일어나는 장소이고, 좋은 구현을 가능하게 하는 전제다.

2. AI 코딩 보조자가 만드는 구현 함정

AI 코딩 보조자와 작업할 때는 이 원칙이 쉽게 사라진다. 사용자가 기능을 설명하면 AI는 몇 초 만에 수백 줄의 구현을 내놓고, 그 속도는 매우 매력적으로 보인다. 그러나 무엇을 만들어야 하는지 이해하는 일과 어떻게 만들어야 하는지를 함께 결정하는 일은 다르다. AI는 어떤 컴포넌트를 만들지, 기존 인프라를 쓸지 새 추상화를 둘지, 인터페이스가 어떤 모양이어야 하는지 묻지 않고 곧바로 구현으로 뛰어든다.

3. 설계 결정이 코드 안에 숨을 때 생기는 문제

저자가 말하는 구현 함정은 단순히 AI가 설계를 건너뛴다는 뜻이 아니다. AI는 코드를 생성하면서 실제로 범위, 컴포넌트 경계, 데이터 흐름, 인터페이스, 오류 처리에 관한 설계 결정을 내린다. 문제는 그 결정들이 별도의 대화로 드러나지 않고 구현 안에 묻혀 도착한다는 점이다. 사용자는 이미 존재하는 큐 시스템을 써야 한다거나 기존 서비스와 맞지 않는 인터페이스라는 점을 코드가 나온 뒤에야 발견하게 된다.

4. AI 코드 리뷰가 더 피곤한 이유

인간 동료가 화이트보딩 뒤에 코드를 제출하면 리뷰어는 이미 이해하고 동의한 설계에 비추어 구현을 검토한다. 반면 AI가 단일 프롬프트에서 코드를 생성하면 사용자는 범위가 맞는지, 아키텍처 경계가 적절한지, 기존 인프라와 통합되는지, 계약이 올바른지, 코드 품질이 괜찮은지를 동시에 판단해야 한다. 이 모든 판단이 한꺼번에 얽혀 있기 때문에 리뷰는 훨씬 피곤해진다. 저자는 이것이 부주의의 문제가 아니라 인간의 작업 기억이 감당하기 어려운 판단 차원의 과부하라고 본다.

5. 변경 비용과 기술 부채 주입

저자는 소프트웨어 공학에서 오래전부터 알려진 변경 비용의 원리를 AI 협업에도 적용한다. 요구사항 오해를 설계 단계에서 잡는 비용은 구현 단계에서 고치는 것보다 훨씬 작고, 운영 환경에서 발견하는 것과는 비교하기 어려울 만큼 낮다. AI가 만든 400줄 코드에 범위 오류가 섞여 들어간 뒤 발견하는 것보다, 2분짜리 설계 대화에서 범위 불일치를 잡는 편이 훨씬 싸다. 또한 AI는 요청하지 않은 rate limiting, analytics hooks, webhook system 같은 기능을 덧붙일 수 있으며, 저자는 이를 단순한 범위 확장이 아니라 검토·테스트·유지보수 부담을 늘리는 기술 부채 주입으로 본다.

6. Design-First의 단계적 대화 구조

저자가 제안하는 해법은 인간 페어가 자연스럽게 하는 화이트보딩 대화를 AI 협업 안에 다시 세우는 것이다. 구현을 바로 요청하는 대신 기능, 구성요소, 상호작용, 계약이라는 점진적 설계 수준을 통과한다. 기능 단계에서는 핵심 요구사항과 범위를 확인하고, 구성요소 단계에서는 서비스·모듈·주요 추상화를 논의한다. 상호작용 단계에서는 데이터 흐름, API 호출, 이벤트를 다루며, 계약 단계에서는 함수 시그니처, 타입, 스키마 같은 인터페이스를 명확히 한다.

7. 체크포인트가 인지 부담을 줄이는 방식

이 구조의 핵심은 각 단계가 코드가 존재하기 전의 체크포인트가 된다는 점이다. 사용자는 단계마다 동의하거나 반대하거나 방향을 바꿀 수 있으며, 모든 판단을 한 번에 떠안지 않아도 된다. 기능 단계는 AI와 사용자가 같은 기능과 같은 범위를 말하고 있는지 확인하는 공유 어휘 점검 역할을 한다. 구성요소, 상호작용, 계약으로 내려갈수록 실제 기술 설계가 구체화되고, 다음 단계의 의사결정 공간은 이전 합의에 의해 좁아진다.

8. 알림 서비스 사례에서 드러난 효과

저자는 이메일 전용 전달, 재시도 로직, 기본 상태 추적이 필요한 알림 서비스를 만들면서 이 방식을 적용했다. 프로젝트에는 작업 처리를 위한 BullMQ가 있었고, 기능 단계에서 범위와 제외 대상을 먼저 확인했다. 구성요소 단계에서 AI는 BullMQ를 감싸는 RetryQueue 추상화를 제안했지만, 저자는 BullMQ의 내장 재시도와 지수 백오프가 이미 충분하므로 별도 래퍼는 불필요하다고 반박했다. 코드가 아직 없었기 때문에 이 설계 이견은 몇 초 만에 해결되었고, 이후 상호작용은 핸들러가 BullMQ 작업을 큐에 넣고 워커가 처리하며 재시도는 네이티브 기능으로 맡기는 더 단순한 흐름이 되었다.

9. 계약, 테스트, 구현으로 이어지는 흐름

계약 단계에서 저자는 NotificationPayload, NotificationResult, EmailProvider, DeliveryTracker 같은 함수 시그니처와 타입, 인터페이스를 합의했다. 이 합의는 구현 코드가 나오기 전 테스트를 작성할 수 있는 조건을 만들었다. 계약을 승인하고 테스트를 생성한 다음 그 테스트에 맞춰 구현하는 흐름은 테스트 주도 개발을 실천하는 팀에 자연스럽게 연결된다. TDD를 하지 않는 팀이라도 계약은 검토 가능한 명세가 되어 오해가 버그가 되기 전에 드러나도록 돕는다.

10. 규율, 복잡도 조절, 지식 프라이밍

Design-First는 AI 보조자를 흔히 쓰는 방식과 반대되는 규율을 요구한다. AI는 도움이 되기 위해 빨리 눈에 보이는 결과물을 만들려 하고, 가만히 두면 설계 단계와 구현 단계를 섞어 버린다. 그래서 사용자는 아직 구성요소 단계라면 구성요소 구조만 보이라고 멈춰 세워야 하며, 이는 조기 세부사항으로부터 작업 기억을 보호하는 행위다. 모든 작업이 전체 단계를 필요로 하지는 않으므로 간단한 유틸리티는 계약 단계에서 시작하고, 단일 컴포넌트는 구성요소 단계에서 시작할 수 있다. 여기에 기술 스택, 관례, 아키텍처 결정 같은 프로젝트 맥락을 미리 공유하는 Knowledge Priming이 결합되면, 각 설계 단계가 실제 코드베이스에 더 잘 고정된다.

🧾 핵심 주장 / 시사점

  • AI 협업의 핵심 위험은 코드 생성 속도 자체가 아니라, 설계 합의가 사라진 채 결정들이 구현 안에 숨어 들어가는 구조에 있다.
  • Design-First는 AI를 더 느리게 쓰자는 제안이 아니라, 가장 싼 시점에 오해를 발견해 전체 검토 비용과 유지보수 부담을 낮추는 방법이다.
  • 좋은 AI 프롬프트는 더 많은 구현 지시를 담는 것이 아니라, 코드가 나오기 전에 어떤 수준의 설계 결정을 먼저 합의할지 분리하는 데서 시작된다.

✅ 액션 아이템

  • 요구사항 수령 즉시 구현을 시작하지 않고 기능, 구성요소, 상호작용, 계약의 4단계를 순차 합의한 뒤 코드 작성으로 전환한다.
  • 범위·컴포넌트 경계·데이터 흐름·인터페이스·오류 처리 판단을 코드에 묻히지 않게 설계 단계에서 분리해 합의한다.
  • 합의된 계약을 바탕으로 구현 전 테스트를 먼저 작성하고, 과도한 레이어(예: 불필요한 RetryQueue 감싸기)의 제거 가능성을 기준에 따라 평가한다.

❓ 열린 질문

  • 복잡도에 따라 일부 단계만 쓸 경우, 어느 조건에서 기능/구성요소/상호작용/계약 단계를 생략할 수 있는가?
  • AI가 생성 직후 코드에 섞어 넣는 범위·경계·통합 판단을 어떤 질문으로 먼저 노출해 즉시 수정할 것인가?
  • 현재 작업에서 계약 정렬로 제거 가능한 추상 레이어가 있다면 무엇을 어디서부터 판단해 없앨 수 있는가?

관련 문서

공통 태그와 주제 흐름을 기준으로 같이 보면 좋은 문서를 이어서 제안합니다.