AI 코딩 시대에도 도메인 이해, 팀 설계, 보편 언어가 복잡한 소프트웨어를 만드는 핵심인 이유를 살펴봅니다.
AI 코딩을 어떻게 생각하든, 소프트웨어를 만드는 방식은 바뀌고 있습니다. 모두가 “무엇이 계속 중요할까?”라고 궁금해합니다. 우리에게 있는 것은 의견뿐이니, 제 의견을 말씀드리겠습니다. 도메인 주도 설계 뒤에 있는 대부분의 아이디어는 그 어느 때보다 중요해졌습니다. DDD는 애초부터 코드에만 관한 것이 아니었기 때문입니다. 에이전트로 코딩을 더 많이 하게 되어도, 우리는 여전히 도메인을 이해하고, 잘 모델링하고, 팀으로 일해야 합니다. DDD가 여전히 무엇을 가르쳐 줄 수 있는지, 그리고 AI가 무엇을 대체할 수 없는지 살펴보겠습니다.
늘 하던 단서부터 덧붙이겠습니다. 저는 팀이 어려움을 겪기 쉽고 DDD가 빛을 발하는, 수개월 또는 수년에 걸쳐 유지되는 복잡한 프로젝트에 관해 씁니다. 개인 프로젝트나 CRUD에 고급 패턴을 사용할 이유는 없습니다.
Eric Evans는 20년도 더 전에 _Domain-Driven Design_을 출간했지만, 여전히 놀랄 만큼 생생합니다. 이 책은 많은 주제를 다루지만, 핵심 메시지는 소프트웨어 공학에서 어려운 부분은 문제 도메인을 이해하고 이를 코드로 잘 모델링하는 일이라는 것입니다. 이 부분을 제대로 하는 것이 더 어렵기 때문에, 엔지니어에게 기술적 세부 사항에 매몰되지 말고 무엇을 해결하는지에 집중하라고 말합니다.
대신 기술적 재능은 정교한 프레임워크를 만드는 데 투입되어, 기술로 도메인 문제를 해결하려 합니다. 도메인을 학습하고 모델링하는 일은 다른 이들에게 맡겨집니다. 소프트웨어의 핵심에 있는 복잡성은 정면으로 다뤄야 합니다. 그렇지 않으면 무의미해질 위험이 있습니다.
이제 AI 도구 덕분에 구현 세부 사항의 중요성이 낮아지는 모습을 볼 수 있습니다. 어느 정도는 프로그래밍 언어나 프레임워크에 대한 깊은 지식 없이도 생산적으로 일할 수 있고, 다른 기술 스택으로 옮기기도 쉬워졌습니다. 최고 수준의 코딩 에이전트를 사용해 보았다면, 이들이 꽤 괜찮은 코드를 빠르게 생성하는 모습을 봤을 것입니다.
하지만 에이전트를 이끌고 그 결과물이 타당한지 판단하려면 여전히 고수준 소프트웨어 개념을 알아야 합니다. 무엇보다도 도메인 복잡성, 즉 해결하려는 비즈니스 문제는 여전히 어려운 부분입니다. 좋은 소식은 코딩이 그 어느 때보다 쉬워졌다는 것입니다. 따라서 구현 세부 사항에 빠져들기보다 이런 복잡한 문제에 집중할 수 있습니다.
다만 프레임워크를 만드는 데 집착하는 대신, 또는 마이크로서비스를 더 추가하거나 유행하는 다른 것을 좇는 대신, 이제는 모델 벤치마크를 따르고 에이전트 환경을 최적화해 더 적은 노력으로 _더 나은 코드_를 생성하려 합니다. Evans가 2003년에 지적했듯이, 우리는 여전히 기술로 도메인 문제를 해결하려 합니다. 재미있게도 이번에는 CEO들도 이를 믿고 우리를 그 방향으로 밀어붙입니다.
이제 알아내야 할 작은 한 가지가 남았습니다. 바로 _그것이 어떻게 작동해야 하는가_입니다. 누군가가 알려 주면 구현에 토큰을 쏟아붓고 일을 끝냈다고 할 수 있습니다. 아무도 모른다면, 에이전트가 우리를 위해 계획을 작성할 수 있을지도 모릅니다.
DDD의 토대는 모델 주도 설계입니다. 도메인이 작동하는 방식을 코드로 표현되는 모델로 정제하는 일입니다. 도메인 모델은 추상적 개념이며, 이를 표현하는 단 하나의 방식은 없습니다. 문서, 다이어그램, 코드를 사용할 수 있지만, 이들은 모두 도메인이 작동하는 방식의 단순화입니다. 정확한 모델은 설계와 구현 사이를 오가며 배운 것을 반복해서 적용하는 과정에서 나옵니다.
DDD는 이를 _지식 정제_라고 부릅니다. 도메인 전문가, 즉 비즈니스가 어떻게 작동하는지 아는 사람과 소프트웨어 구축 전문가인 엔지니어가 필요합니다. 이들은 소프트웨어가 무엇을 해야 하는지와 이를 어떻게 구현할지 이해하기 위해 함께 일합니다. 예를 들어 Event Storming 세션에서는 개발자와 이해관계자가 포스트잇으로 비즈니스가 작동하는 방식을 함께 그려 보는 워크숍을 진행합니다.
도메인을 파악하는 일은 팀의 노력과 힘든 작업을 요구하므로, 다른 누군가에게 맡기고 싶어집니다. 예를 들어 AI 에이전트는 조사와 분석에 탁월하며 문서, 채팅, 코드에 접근할 수 있습니다. 이들이 도메인 모델을 만들어 주고 구현까지 할 수 있을 것처럼 보입니다.
하지만 이 순진한 접근은 핵심을 놓칩니다. 모델을 함께 다루는 가치는 여러분과 팀이 도메인이 어떻게 작동하는지 _이해_하게 되는 데 있습니다. AI가 생성한 텍스트 벽은 비즈니스 문제를 파악하는 데 도움이 되지 않습니다. 에이전트는 아무도 읽지 않는 인상적인 산출물만 만들 것입니다.
도메인 모델은 산출물이 아닙니다.
문제는 어떤 것이 어떻게 작동할 수 있는지에 대한 긴 문서를 작성하는 데 있던 적이 없습니다. 소프트웨어 프로젝트는 더 흔히 다른 문제로 실패합니다.
제가 여러 번 빠진 함정이 하나 있습니다. 엔지니어링 팀에서는 우리가 모든 것을 파악했다고 느끼기 쉽습니다. 우리는 프로그래밍 전문가이고, 패턴을 알고, 모범 사례를 따릅니다. 누군가, 즉 비즈니스 이해관계자나 제품 관리자만 우리에게 무엇을 해야 할지 알려 주면 됩니다.
하지만 도메인 전문가도 명확한 계획이 없는 경우가 많습니다. 이들은 자신이 가진 문제는 알지만, 해결책은 아직 모릅니다. 모든 요구 사항이 담긴 완전한 문서도 없습니다. 개발자의 첫 반응은 “뭔가 생각나면 알려 주세요. 저는 여기 있을게요.”일 수 있습니다. 다시 말해 우리는 코딩이라는 재미있는 부분을 위해 여기 있는 것입니다. 이 부분이 바로 AI 에이전트가 자동화하는 부분이라는 점에 주목하세요.
반대 극단에서는 비기술 관리자가 전체 해결책을 생각해 내고 팀에 구현하라고 넘깁니다. 또는 가장 최근의 흐름으로, 누군가 AI를 이용해 완전한 기능 또는 제품 명세를 생성하고 읽어 보지도 않은 채 전달합니다. 그러면 계획 비슷한 것은 존재하지만, 프로덕션에 투입할 준비가 된 것과는 거리가 멉니다. 누군가 그렇지 않다고 주장한다면, 그들이 실제로 출시하는 것이 얼마나 복잡한지 확인해 보세요.
이 모든 시나리오에서 누구도 자신이 무엇을 하는지 명확히 모릅니다. 누가 코드를 작성하든 얼마나 빠르든, 이 시점에서 그 코드는 가치가 거의 없습니다.
반대로 모델을 함께 다루면 팀은 문제 도메인을 이해하고 해결책에 합의합니다. 개발자는 이를 구현하고, 예상치 못한 일이 생기거나 다음 반복이 시작되면 도메인 전문가가 참여할 수 있습니다.
AI로 대부분의 코딩을 하더라도, 동료를 이끄는 것처럼 에이전트를 이끌기 위해 도메인에 깊이 익숙해져야 합니다. 에이전트를 어떻게 구성하는지나 어떤 LLM을 사용하는지는 해결책에 대한 명확한 정신 모델만큼 중요하지 않습니다. 하나를 골라야 한다면, 저는 해야 할 일을 생각하는 과정을 건너뛰느니 직접 코드를 전혀 작성하지 않는 쪽을 택하겠습니다.
코드를 읽는 것보다 작성하는 일은 언제나 쉬웠습니다. 이제는 에이전트가 큰 기능 하나를 단 한 번의 요청으로 만들어 줄 수 있으니 그 차이가 더 극단적입니다. 작동하더라도 내부에서 무슨 일이 벌어지는지 전혀 모를 수 있습니다.
이제 우리는 코드 리뷰에서 더 자주 막힙니다. 하지만 이 역시 새로운 문제는 아닙니다. 완성된 기능을 준비해 거대한 PR을 던져 주는 독불장군 개발자와 일하는 것처럼 익숙하게 느껴지기까지 합니다. 설계에 대해 아는 것이 없고, 아무도 고려하지 않은 빈틈이 흔히 있습니다. PR 검토는 고통스럽습니다.
이런 상황을 피하는 방법이 있으며, 저는 많은 프로젝트에서 이것이 작동하는 것을 보았습니다. 코드 작성에 앉기 전에 팀으로 해결책을 설계하고 논의하는 것입니다. 먼저 도메인 부분, 즉 무엇을 해결하는지와 어떻게 작동해야 하는지를 다룹니다. 위의 지식 정제를 참고하세요. 그다음 기술적 측면을 다룹니다. 구현을 시작한 뒤에는 예상 밖의 일이 생길 가능성이 거의 없습니다.
아주 작은 세부 사항마다 합의할 필요는 없고, 완전한 서면 명세도 필요 없습니다. 모두가 알고 있는 고수준 계획을 간단히 그리는 것으로 충분합니다. 포스트잇 몇 장과 화이트보드면 충분합니다.
설계를 바꾸기에 가장 좋은 순간은 누구도 코드를 작성하기 전입니다.
이런 세션 뒤에는 PR 검토가 매끄럽습니다. PR 댓글에서 전체 설계를 논의하지 않아도 되므로 작업을 작은 단위로 나누기 쉽습니다. 기능이 프로덕션에 반영된 후의 빈틈도 줄어듭니다. 이미 세부 사항에 합의했고 모두가 무엇을 만드는지 이해하기 때문입니다.
설계를 건너뛰는 것은 시간을 절약하는 것처럼 보일 수 있습니다. 누구도 회의가 더 많아지는 것을 좋아하지 않습니다. 하지만 팀이 PR을 통해 처음 기능을 알게 된다면, 모든 문제를 검토하고 논의하고 수정하는 데 훨씬 더 오래 걸립니다. 리뷰는 보통 비동기로 진행되므로 댓글이 여러 차례 오가게 됩니다. 코드 리뷰는 구현이 올바른지 재확인하는 과정이어야지, 접근 방식 자체가 타당한지 논의를 시작하는 자리가 되어서는 안 됩니다.
짧은 계획으로 시작하면 나중의 리뷰 시간을 절약할 수 있습니다.
코드 전에 설계하는 일은 AI 에이전트와 더 잘 일하는 데도 도움이 됩니다. 에이전트에 더 많은 고품질 맥락을 제공하면 결과물은 더 정확해지고 코딩 단계는 짧아집니다. 그리고 팀이 해결책을 더 잘 알수록, 모든 코드를 생성하더라도 리뷰는 더 쉬워집니다.
최근 저는 클라우드 비용을 줄이려 하고 있습니다. 명확한 측정 지표가 있으므로 AI에 딱 맞는 작업입니다. 저는 에이전트에게 우리 Go 서비스가 가장 많은 메모리를 사용하는 위치를 찾아 줄이라고 하고, 그 사용량을 줄이라고 했습니다.
몇 번 실행한 뒤 RAM을 수많은 메가바이트 절약했습니다. 하지만 메모리는 꽤 저렴하고, 이 변경으로 줄어든 비용은 월 $1이라는 사실을 깨달았습니다. 놀랍지 않죠? 저는 비용을 줄이려 한다고 에이전트에 설명하지 않았습니다. 그저 메모리 사용량을 목표로 제시했을 뿐입니다.
이는 팀에서 사람들 사이에 일어나는 일과 정확히 같으므로 익숙하게 들릴 것입니다. 팀 내 의사소통에 도움이 되는 좋은 관행은 AI와 일할 때도 관련이 있습니다. 소프트 스킬이 컴퓨터를 다루는 데 도움이 될 줄 누가 알았겠습니까?
DDD는 우리가 사용하는 언어에 관한 몇 가지 아이디어로 이 문제를 다룹니다.
첫 번째는 보편 언어입니다. 팀과 코드 전반에서 같은 언어를 사용해, 모두가 무엇을 말하는지 알 수 있게 하는 것입니다.
많은 팀에서 뒤죽박죽인 이름은 기본값입니다. 코드에서 엔지니어는 회사의 다른 사람들이 쓰는 명칭과 점점 멀어지는 기술 용어를 사용합니다. AI에 문서와 의사결정 기록을 제공하더라도, 에이전트는 그 안에서 사용하는 언어를 이해해야 합니다.
지식 정제 중에는 도메인의 개념을 무엇이라 부르는지 생각해 보세요. 처음에는 개념 하나당 이름이 둘 이상인 일이 흔합니다. 이미 쓰고 있는 이름을 선택하거나 더 정확한 이름을 만드세요. 그런 다음 문서, 구어, 코드에서 그 이름을 사용하세요.
Event Storming 세션은 이름을 선택하기에 좋은 장소입니다.
언어는 프로젝트와 함께 계속 발전하므로 이름을 단 한 번만 선택할 수는 없습니다. 설계 세션과 논의 중에 계속 신경 써야 하는 일입니다.
보편 언어와 직접 연결된 또 다른 아이디어는 큰 시스템에서 선택한 이름이 모든 영역에 보편적이지는 않다는 것입니다. DDD는 각 영역을 경계 컨텍스트라고 부릅니다. 지원 컨텍스트에서는 고객을 _프로필_로, 전자상거래 컨텍스트에서는 _사용자_로 생각할 수 있습니다. 전체 프로젝트에 이름을 강요하는 것이 아니라 각 컨텍스트 안에서 일관된 이름을 사용해야 합니다.
이는 소프트웨어를 팀 사이에 나눠야 하는 큰 제품에서 특히 중요합니다. 온갖 종류의 작업을 위한 하나의 모델을 만드는 데 지나치게 집중하면 경계를 긋기 어려워집니다. 경계 컨텍스트를 염두에 두면 결합도가 낮은 시스템에 도달하기가 쉬워집니다.
에이전트는 전체 저장소에 접근할 수 있고 여러분이 부여한 이름을 찾을 것입니다. 비슷한 엔터티를 순진하게 하나로 통합하려 할 수 있으므로, 이유가 있어 분리되어 있음을 분명히 하세요.
같은 도메인 개념도 컨텍스트에 따라 다른 이름을 가질 수 있습니다.
널리 알려져 있고 정확한 개념을 사용하면 의미를 표현하기가 쉽습니다. 팀원과 일할 때도, 프롬프트에서 쓸 때도 효과가 있습니다.
모호한 프롬프트는 에이전트가 잘못된 해결책에 많은 노력을 쓰게 할 수 있습니다.
사용자가 생성되면 CRM과 지원 시스템에 추가
정확한 이름을 고수하면 목표가 더 명확해집니다.
사용자가 웹사이트에서 가입하면 비동기로 다음을 생성: 1) CRM의 고객 항목, 2) 지원 시스템의 프로필
도메인 언어에 관한 세부 사항을 에이전트의 맥락에 넣어야 합니다. 문서를 최신 상태로 유지해야 하는 또 하나의 이유입니다. 코드 가까이에 있는 Markdown 파일은 문서를 가져오기 위한 맞춤 통합이 필요 없으므로 좋은 출발점입니다.
모델과 에이전트는 계속 발전하지만, 이들을 완전히 신뢰할 수는 없습니다. 여전히 실수를 하고, 결국 책임질 사람이 필요합니다. 결과가 올바른지 어떻게 알 수 있을까요?
도메인에서 일하는 과정이 자신이 무엇을 하는지 안다는 신뢰를 쌓는 방법입니다. 시스템을 설계하고 작동 방식을 이해하는 사람은 무엇인가 잘못될 가능성이 있는지 말할 수 있습니다.
개발자는 자신이 다루는 주제의 전문가가 됩니다. 코드 작성 너머의 역량을 배우며, 호기심 있는 엔지니어에게는 복잡한 비즈니스 도메인도 시간이 지나면 직관적으로 느껴집니다. 그 영역에서 도움이 필요하다면 누구에게 물어야 할지 압니다. 매우 상세한 지시 없이도 일을 해낼 수 있다고 믿을 만한 사람과 일하면 엄청난 골칫거리를 피할 수 있습니다.
최근 AI에 관한 서사는 두 가지가 있습니다. 하나는 이제 누구나 잘 알려진 앱의 복제본을 생성할 수 있다는 것입니다. 처음에는 충격적이었지만, 장기적으로 그다지 흥미로운 일은 아닙니다. AI가 없어도 이미 덜 다듬어진 앱은 너무 많습니다.
더 흥미로운 이야기는 경험 많은 엔지니어가 이제 더 복잡한 애플리케이션을 만들 수 있다는 점입니다. 예를 들어 팀은 비싼 서드파티 소프트웨어를 사내 솔루션으로 대체할 수 있습니다. 하지만 자기들 버전이 잘 작동한다고 어떻게 신뢰할 수 있을까요?
바로 그 특정 도메인에서 일하며 이미 쌓은 지식 덕분입니다. 자신이 아는 것을 AI와 결합해 자체 버전을 아주 빠르게 구축하므로, 라이선스 비용을 내는 것보다 저렴해집니다. 게다가 필요한 맞춤 기능도 무엇이든 추가할 수 있습니다.
고용주에게 제품 관점을 갖고 도메인을 잘 아는 엔지니어가 곁에 있다는 것은 매우 큰 자산입니다. 이들은 모호한 세부 사항을 파악하고 논의를 이끌 수 있습니다. 개발자를 시키는 대로 코드를 작성하는 사람으로 여기는 것은 언제나 순진한 생각이었고, 이제는 더더욱 그렇습니다.
엔지니어에게는 기술 역량에만 집중하기보다 알지 못하는 도메인에서 일하는 법을 배우는 일이 더 큰 보상을 줍니다. 하나의 프레임워크 전문가가 되기보다 비즈니스 문제를 잘 해결한다면 수익 중심 영역에서 일하기가 더 쉽습니다.
DDD는 소프트웨어에 코드 작성보다 훨씬 많은 것이 있음을 보여 줍니다. 복잡한 시스템을 다뤄 봤다면 분명 여러 번 보았을 것입니다.
이 주제는 제 첫 소프트웨어 직장에서의 기억을 떠올리게 합니다. 한때 어려운 문제를 다루며 펜과 종이로 몇 시간 동안 끄적였습니다. 키보드는 거의 건드리지 않았지만 마침내 해결책을 찾아냈습니다. 막 일을 시작한 때라 말문이 막혔습니다. “와, 오늘 나는 생각하는 데 돈을 받았네.”
당시에는 이 느낌이 낯설었지만, 오늘날에는 더 낯설게 느껴집니다. 당시에는 문제를 생각하는 데 하루를 썼다고 말해도 관리자는 눈 하나 깜빡하지 않았을 것입니다. 오늘날 우리는 결과물에 더 집중합니다. 생각도 AI가 하게 하면 안 될까요?
위임된 사고.
한 가지 이유는, 에이전트의 결과물이 타당한지 판단할 수 있는 유일한 까닭이 과거에 그런 문제를 오래 생각해 본 적이 있기 때문입니다.
어차피 AI가 모든 것을 처리할 테니 더는 이런 경험이 필요 없다는 주장도 있습니다. AI에 의존하는 것이 결국 새로운 표준이 될 수는 있지만, 제가 무시할 수 없는 문제가 하나 있습니다. 복잡한 문제를 다루려면 뇌를 훈련해야 하며, 생각하지 않고는 새로운 정신 모델을 만들 수 없습니다.
제가 떠올릴 수 있는 가장 좋은 비유는 책을 읽는 것과 그 요약을 읽는 것의 차이입니다. 독서는 몇 시간 동안 주제에 관해 생각하도록 강제합니다. 마음속에 복잡한 모델을 천천히 구축하고, 이미 알고 있는 다른 것들과 연결합니다. 브라우저 탭을 닫고 10초 뒤에 잊어버릴 몇 문장을 읽는 대신, 주제를 이해하게 됩니다.
아직 누구도 모범 사례를 알지 못하므로, 지금은 실험하고 무엇이 효과적인지 살펴볼 좋은 시기입니다. 당분간 저는 전통적인 문제 해결과 코드로 일하는 새로운 방식을 시도하는 일을 섞어 갈 것입니다.
이 글에서는 개별 패턴보다 DDD 뒤에 있는 철학에 더 집중했습니다. 코드에 더 가까운 전술적 패턴을 포함해 더 많은 글을 쓸 계획입니다. 직접 타이핑하지 않더라도, 저는 여전히 그것들이 유용하다고 생각합니다. 다음 글을 놓치지 않도록 아래에서 구독하세요.