AI는 코드를 생성할 수 있습니다. 더 어려운 문제는 무엇을 만들지 결정하는 것입니다.
요약
AI가 코드 구현 속도를 획기적으로 높였지만, 프로젝트의 방향성을 결정하는 의사결정 문제는 여전히 인간의 영역으로 남아 있습니다. 무엇을 만들지 결정하는 맥락과 트레이드오프 판단은 AI가 대신할 수 없는 핵심적인 소프트웨어 개발 과정입니다.
핵심 포인트
- AI는 구현 속도를 높여주지만, 프로젝트의 우선순위와 목적을 결정하지는 못함
- 코드 생성 비용의 하락이 오히려 잘못된 방향으로의 빠른 구현을 유도할 위험이 있음
- 기술적 개선, 기능 구현, 사용자 검증 사이의 전략적 선택이 개발의 핵심 과제임
- AI는 선택지를 제공할 뿐, 프로젝트의 맥락에 따른 최종 판단은 개발자의 몫임
프로젝트가 정말로 정체되는 순간
프로젝트는 놀랍게도 앞으로 나아가고 있는 것 같으면서도 동시에 완전히 막혀 있는 것처럼 느껴질 수 있습니다. 추구할 가치가 있는 아이디어가 있고, 그럴듯한 작업들로 가득 찬 백로그 (backlog)가 있으며, 그중 어떤 것이든 구현할 수 있는 충분한 도구들이 있습니다. 문제는 다음 코드 조각을 작성할 능력이 없는 것이 아니라, 어떤 코드 조각이 향후 며칠간의 작업 시간을 할애할 가치가 있는지 모른다는 것입니다.
이 지점이 바로 많은 프로젝트가 표류하기 시작하는 지점입니다. 다음 단계가 아이디어를 검증할 수 있는 작은 기능이어야 할까요, 아니면 나중에 작업을 더 쉽게 만들어 줄 기술적 개선이어야 할까요, 아니면 더 이상의 구현을 하기 전에 사용자들과 대화를 나누는 것이어야 할까요? 이 세 가지 모두 개별적으로는 합리적으로 들릴 수 있지만, 하나를 선택한다는 것은 다른 것들을 미룬다는 것을 의미합니다.
AI는 이 작업의 구현 (implementation) 측면을 훨씬 더 빠르게 만들었습니다. AI는 컴포넌트 (component)를 생성하고, 스키마 (schema)를 제안하며, 익숙하지 않은 API를 설명하거나, 실패하는 테스트를 추적하는 데 도움을 줄 수 있습니다. 하지만 의미 있는 맥락 (context) 없이는 해당 컴포넌트, 스키마, 통합 (integration) 또는 테스트가 현재 프로젝트에 가장 유용한 것인지 여부를 AI가 결정할 수는 없습니다.
소프트웨어를 구축하는 데 있어 어려운 부분은 종종 코드를 생산하는 것이 아닙니다. 코드에 목적을 부여하는 결정을 내리는 것입니다.
코드 생성은 실제 문제를 해결했습니다 - 하지만 이 문제는 아닙니다
코딩 어시스턴트 (coding assistants)가 변화시킨 것들을 무시하는 것은 실수일 것입니다. 어시스턴트들은 종종 반복적이거나 느린 소프트웨어 개발 단계에서 유용합니다. 익숙하지 않은 라이브러리 (library)를 탐색하거나, 컴포넌트의 첫 버전을 생성하거나, 테스트를 작성하거나, 언어 간 번역을 하거나, 버그를 좁혀가는 과정 등이 그러합니다. 잘 활용한다면, 이들은 아이디어와 작동하는 실험 사이의 시간을 단축해 줍니다.
그 속도는 가치 있지만, 해결되지 않은 결정을 더 쉽게 미루게 만들 수도 있습니다. 코드를 생산하는 비용이 저렴해지면, 어떤 것이 프로젝트에 가장 잘 부합하는지 결정하기보다는 여러 가능성을 구현하고 싶은 유혹에 빠지게 됩니다. 잘못된 기능을 빠르게 구현하는 것도 결국 잘못된 방향으로 움직이는 데 시간을 쓰는 것일 뿐입니다.
가장 중요한 질문들은 보통 코딩 과제보다 덜 명확합니다. 이 기능이 첫 번째 출시(first release)에 필수적인 것인가요, 아니면 그저 상상하기 쉬워서 추가하는 건가요? 이 서비스 경계(service boundary)가 우리가 오늘날 가진 문제를 해결해 주나요, 아니면 우리가 결코 갖지 않을지도 모르는 문제를 해결해 주나요? 올바른 다음 단계가 기술적 변경(technical change)일까요, 아니면 우리가 만들고자 하는 결과물에 과연 누군가가 필요로 하는지 먼저 배워야 할까요?
이 질문들은 보편적인 답을 가지고 있지 않습니다. 프로젝트의 사용자, 제약 조건(constraints), 현재 단계, 그리고 잘못했을 때의 결과에 따라 달라집니다. 언어 모델(language model)은 유용한 선택지를 제공하고 가정을 검토하는 데 도움을 줄 수 있지만, 개발자를 대신하여 맥락(context)을 공급하거나 트레이드오프(trade-off)를 결정할 수는 없습니다.
이러한 구별이 중요한 이유는 구현과 판단에 서로 다른 종류의 지원이 필요하기 때문입니다. 하나는 우리가 답을 빠르게 산출하도록 돕고, 다른 하나는 우리가 올바른 질문을 하고 있는지 결정하는 데 도움을 줍니다.
이러한 결정들이 비싼 이유
멘토링 대화에서 반복적으로 어려움을 겪었던 부분은 거의
또한 모멘텀 비용 (momentum cost)도 존재합니다. 다음 단계가 불분명할 때, 개발자들은 종종 구체적으로 느껴지는 작업, 즉 리팩터링 (refactoring), 백로그 (backlog) 재정리, 유연성 추가, 또는 나중에 유용할지도 모르는 기능을 구축하는 것과 같은 작업들을 선택함으로써 대응하곤 합니다. 이러한 행동들 중 그 어느 것도 본질적으로 틀린 것은 아니지만, 프로젝트에 지금 당장 무엇이 필요한지에 대한 더 어려운 결정을 피하는 수단이 될 수 있습니다.
가장 비용이 많이 드는 실수는 종종 극적인 실패가 아닙니다. 그것은 결과와의 명확한 연결 고리 없이 몇 주 동안 반복되는, 합리적으로 보이는 선택들입니다. 불일치가 눈에 보일 때쯤이면, 더 많은 코드가 쌓여 있고, 되돌려야 할 컨텍스트 (context)는 더 많아지며, 원래의 가정을 재검토하려는 의지는 더 낮아집니다.
이것이 결정을 명시적으로 만드는 것이 중요한 이유입니다. 그것이 결정이 옳을 것이라고 보장하지는 않지만, 새로운 증거가 나타났을 때 그 근거를 검토하고, 테스트하고, 변경할 수 있을 만큼 충분히 가시화해 줍니다.
에디터를 열기 전의 가벼운 의사결정 프레임워크 (decision framework)
목표는 모든 제품 선택을 워크숍으로 만드는 것이 아닙니다. 대부분의 결정에는 긴 문서가 필요하지 않으며, 프레임워크가 업무를 지연시키는 또 다른 수단이 되어서는 안 됩니다. 유용한 버전은 몇 분 안에 작성할 수 있을 만큼 작으면서도, 다른 사람이 당신이 왜 그 방향을 선택했는지 이해할 수 있을 만큼 구체적이어야 합니다.
의미 있는 작업을 시작하기 전에, 저는 다섯 가지 사항을 명시하는 것이 유용하다고 생각합니다.
1. 결과 (Outcome)
만들고 싶은 기능 (feature)이 아니라, 만들고자 하는 변화로부터 시작하세요. "팀 역할 추가"는 구현 (implementation)을 설명하지만, "계정 소유자가 민감한 프로젝트 데이터에 접근할 수 있는 사람을 제어할 수 있도록 허용"하는 것은 결과 (outcome)를 설명합니다. 이 차이는 중요합니다. 결과는 더 단순한 해결책을 위한 여지를 남겨두기 때문입니다.
명확한 결과는 나중에 작업을 평가할 수 있는 방법도 제공합니다. 기능은 출시되었지만 사용자의 상황이 개선되지 않았다면, 구현은 맞았을지 몰라도 결정은 틀렸을 수 있다는 점을 더 쉽게 파악할 수 있습니다.
2. 제약 사항 (Constraints)
2. 제약 사항 (Constraints)
문서화되지 않은 경우에도 모든 프로젝트에는 제약 사항이 있습니다. 아이디어를 검증하는 시간, 시스템을 유지 관리할 인원 수, 기존 기술 선택, 신뢰성 요구사항, 그리고 실수했을 때의 비용 등 모든 것이 적절한 해결책이 무엇인지에 영향을 미칩니다.
이러한 제약 사항들을 가시화하면 '최고의' 접근 방식에 대한 추상적인 논의를 막을 수 있습니다. 그런 것은 거의 없습니다. 오직 이 프로젝트, 이러한 한계, 그리고 현재 시점에서 합리적인 접근 방식만이 존재할 뿐입니다.
3. 대안 (Options)
확신하기 전에 두세 가지 신뢰할 만한 대안을 문서로 작성하세요. 이것은 가능한 모든 아키텍처를 목록화한다는 의미가 아닙니다. 첫 번째 작동 가능한 접근 방식이 자동으로 올바르다는 가정을 피하는 것을 의미합니다.
예를 들어, 기본적인 접근 제어(access control)가 필요한 MVP는 단일 소유자/멤버 구분, 작은 고정 역할 세트, 또는 완전히 구성 가능한 권한 시스템을 고려할 수 있습니다. 각 옵션은 다른 비용, 유연성 수준, 그리고 나중에 변경하기 어려워질 위험성을 가집니다.
4. 충분히 좋음 (Good enough)
이것이 보통 가장 어려운 질문입니다. 현재 단계에 안전하고 유용한 최소한의 결정은 무엇인가요? 복잡한 엔터프라이즈 요구사항을 가진 성숙한 제품은 유연한 권한 모델(permission model)이 필요할 수 있습니다. 팀들이 협업하는지 여부를 배우려는 초기 제품은 소유자와 다른 모든 사람을 구분하는 것만으로도 충분할 수 있습니다.
'충분히 좋음(Good enough)'은 부주의한 작업에 대한 변명이 아닙니다. 완전성에는 비용이 따른다는 것을 인정하고, 결정은 오늘 사용 가능한 증거에 비례해야 한다는 것입니다. 중요한 부분은 해결책이 의도적으로 다루지 않는 것이 무엇인지, 그리고 그것을 재검토할 정당성을 부여하는 증거가 무엇인지를 명시하는 것입니다.
5. 가역성 (Reversibility)
마지막으로, 그 선택을 되돌리는 것이 얼마나 어려울지 물어보세요. 어떤 결정은 저렴한 실험입니다: 복사본 변경, 임시 워크플로우(workflow), 또는 제한된 기능 플래그(feature flag). 다른 것들은 데이터 모델, 공개 API(public APIs), 운영 의존성(operational dependencies), 또는 사용자 기대치를 생성하며, 이는 되돌리기가 비용이 많이 듭니다.
되돌리기 쉬운 결정은 1년 동안 프로젝트의 형태를 결정지을 결정만큼 높은 수준의 확실성을 필요로 하지 않습니다. 이는 모든 선택을 영구적인 것으로 취급하거나, 중대한 선택을 마치 해롭지 않은 실험인 것처럼 취급하는 두 가지 극단적인 상황을 모두 피할 수 있는 유용한 방법입니다.
권한(permissions) 예시에 적용해 보면, 그 논리는 간단할 수 있습니다. 즉각적인 결과는 계정 소유자가 한 명의 협업자(collaborator)를 초대하도록 허용하는 것이고, 제약 조건은 짧은 검증 기간(validation window)이며, 대안은 소유자/멤버(owner/member) 역할 또는 구성 가능한 권한 시스템(configurable permission system)입니다. '충분히 괜찮은(good enough)' 수준은 소유자/멤버 모델이며, 데이터 모델이 오직 두 개의 역할만 존재할 것이라고 가정하지 않는다면 이 결정은 되돌릴 수 있습니다. 이것이 완벽한 정답은 아닐지라도, 가시적인 근거(rationale)를 가진 결정입니다.
이를 기록한다고 해서 불확실성이 사라지는 것은 아닙니다. 다만 불확실성을 논의하고, 이의를 제기하며, 재검토할 수 있을 만큼 구체적인 것으로 만들어 줄 뿐입니다. 이는 막연한 우려에서 곧바로 자신감 있어 보이는 구현(implementation)으로 바로 넘어가는 것보다 종종 더 가치 있는 일입니다.
결정이 프레임화된 후에 AI를 사용하세요
이것은 AI를 덜 사용하라는 주장이 아닙니다. AI가 더 유용하게 쓰일 가능성이 높은 시점에 사용하라는 주장입니다. 결과, 제약 조건, 옵션, 그리고 되돌릴 수 있는 수준(level of reversibility)이 명확해지면, AI 어시스턴트는 그저 공백을 그럴싸해 보이는 답변으로 채우는 대신 결정을 검토하는 데 도움을 줄 수 있습니다.
다음의 차이를 생각해 보십시오:
"내 SaaS를 위한 아키텍처(architecture)를 설계해 줘."
이 요청에는 아키텍처 결정을 의미 있게 만드는 정보가 거의 포함되어 있지 않습니다. 어시스턴트는 제품의 요구사항, 규모(scale), 제약 조건, 팀, 그리고 운영 복잡성(operational complexity)에 대한 허용치를 스스로 만들어내야 합니다. 상세한 답변을 내놓을 수는 있겠지만, 상세함이 곧 그 권장 사항이 프로젝트에 적합하다는 증거는 아닙.
더 유용한 요청은 결정에 맥락(context)을 제공하는 것입니다:
"저는 클라이언트와 프로젝트 업데이트를 공유해야 하는 독립 컨설턴트들을 위한 MVP (Minimum Viable Product)를 구축하고 있습니다. 이들이 4주 이내에 이를 사용할지 검증해야 합니다. 저는 혼자 작업하고 있으며 운영 복잡성 (operational complexity)을 낮게 유지하고 싶습니다. 현재 관계형 데이터베이스 (relational database)를 사용하는 단일 애플리케이션과 알림을 위한 별도의 이벤트 기반 서비스 (event-driven service) 사이에서 고민 중입니다. 이 단계에서 어떤 옵션이 적절할까요? 제가 놓치고 있는 리스크는 무엇이며, 나중에 이 결정을 재검토해야 할 정당한 이유는 무엇일까요?"
두 번째 프롬프트가 더 나은 이유는 단어를 더 많이 사용했기 때문이 아닙니다. 무엇을 최적화(optimising)하려 하는지, 그리고 실제로 어떤 트레이드오프 (trade-off)를 고려하고 있는지를 명시했기 때문에 더 나은 것입니다. 이는 모델이 가정을 식별하고, 대안을 비교하며, 개발자가 놓쳤을 수 있는 리스크를 지적할 수 있도록 충분한 재료를 제공합니다.
이 단계에서 AI는 여러 가지 유용한 역할을 수행할 수 있습니다. 명시된 결과가 충분히 구체적인지 이의를 제기하거나, 고려할 가치가 있는 대안을 생성하고, 각 옵션의 결과를 설명하며, 선택 사항을 짧은 결정 기록 (decision record)으로 전환하는 것을 도울 수 있습니다. 또한 기술적 추론만으로 해결하기보다는 사용자, 측정 또는 작은 실험을 통해 답을 얻어야 하는 질문들을 식별할 수도 있습니다.
이 중 그 어떤 것도 LLM (Large Language Model)을 권위 있는 정보원으로 만들어주지는 않습니다. 개발자는 여전히 맥락 (context)이 정확한지, 조언이 적용 가능한지, 그리고 결과적으로 발생하는 변경 사항이 안전한지를 판단해야 합니다. 가치는 의사결정에 대한 책임을 위임하는 데 있는 것이 아니라, 추론 과정을 더 명시적으로 만들고 검토하기 쉽게 만드는 데 있습니다.
내가 Hakkle을 만드는 이유
이러한 간극이 저로 하여금 Hakkle을 만들게 했습니다. 저는 계속해서 같은 질문으로 돌아왔습니다: 구현 도구들이 더 빠르고 유능해지고 있다면, 개발자가 그 구현에 관한 결정을 더 명확하게 내릴 수 있도록 돕는 것은 무엇일까?
Hakkle의 이면에 있는 가설은 AI가 누군가를 대신해 그러한 결정을 내려야 한다는 것이 아닙니다. 대신, 프로젝트를 인지하는 기술 코치 (technical coach)가 개발자가 목표, 제약 조건, 이전의 선택, 그리고 미결 질문들을 추적할 수 있도록 돕고, 그 맥락 (context)을 사용하여 다음 결정을 검토할 수 있도록 도울 수 있다는 것입니다. 목표는 계획 (planning), 우선순위 지정 (prioritisation), 아키텍처 논의 (architecture discussions), 그리고 트레이드오프 (trade-offs)를 단순히 고립된 프롬프트 (prompts)의 흐름으로 축소하지 않고 지원하는 것입니다.
이는 여전히 초기 단계의 아이디어이며, 그 차이점은 중요합니다. 범용 LLM (Large Language Model)과 좋은 메모만으로도 이미 많은 사람과 많은 프로젝트에 충분할 수 있습니다. 저는 지속적인 프로젝트 맥락 (project context)과 더 의도적인 결정 과정이 실제로 가치를 제공하는 지점이 어디인지, 그리고 단순히 관리해야 할 또 다른 도구를 추가하는 것에 불과한 지점이 어디인지를 배우려고 노력하고 있습니다.
현재로서는 Hakkle을 제품이라기보다 검증 작업 (validation exercise)으로 취급하고 있습니다. 유용한 결과는 모든 개발자에게 기술 코치가 필요하다는 것을 증명하는 것이 아닙니다. 개발자들이 어떤 결정을 가장 어렵게 느끼는지, 현재 그것들을 어떻게 해결해 나가고 있는지, 그리고 도구가 잘못된 자신감 (false confidence)이나 추가적인 마찰 (friction)을 만들지 않으면서 도움을 줄 수 있는지를 이해하는 것입니다.
맺음말
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기