3.SW개발/AI코딩과실무전략

7편. 설계, 아키텍처, 창의성 - 아직은 인간만이 할 수 있는 일

쿼드큐브 2025. 11. 9. 13:54
반응형
반응형

7편. 설계, 아키텍처, 창의성 - 아직은 인간만이 할 수 있는 일

 

📚 목차
1. AI가 잘하는 것과 못하는 것, 그 경계를 구분하자
2. 전체 시스템 구조를 보지 못하는 AI의 한계
3. 새로운 문제를 푸는 창의력은 아직 인간의 몫
4. 기능 구현보다 더 중요한 것 - 실무에서 반드시 필요한 아키텍처 사고
5. 프롬프트도 설계다 - AI를 위한 구조 중심 질문법
✔ 마무리 - 설계는 아직 인간의 핵심 역량이다

 

AI가 잘 못하는 것을 표현한 삽화 이미지
AI가 잘 못하는 것을 표현한 삽화 이미지

최근 AI는 단순한 코딩 보조 도구를 넘어, 개발 전반에 영향을 미치는 파트너로 자리 잡고 있습니다.

특히 반복적인 기능 구현, 정형화된 로직 처리, 템플릿 기반 코드 생성 같은 작업에서는 AI의 생산성이 많은 개발자에게 실제적인 효율 향상을 가져다주고 있습니다.

 

하지만 이럴수록 우리는 본질적인 질문을 던져야 합니다.

 

“AI는 과연 시스템 전체를 이해하고, 설계하고, 구조화할 수 있을까?”

 

이 글에서는 AI가 잘하지 못하는 영역, 특히 설계(Design), 아키텍처(Architecture), 창의성(Creativity)에 대해 다루려 합니다.

AI 코드의 한계를 정확히 이해하고, 그 경계 바깥에 있는 개발자만의 역할을 분명히 인식하는 것이 이 글의 핵심 목적입니다.

 

1. AI가 잘하는 것과 못하는 것, 그 경계를 구분하자

최근 AI는 단순한 코딩 도구를 넘어, 개발 전반에 영향을 미치는 파트너로 자리 잡고 있습니다.

특히 반복적인 CRUD 처리, 정규표현식 작성, Form 입력 검증과 같은 단일 기능 중심 작업에서는 높은 생산성을 보여주고 있습니다.

 

예를 들어, 다음과 같은 결정은 전적으로 개발자의 설계 사고력에 의존합니다:

🔹어떤 기능을 별도의 모듈로 분리해야 유지보수가 쉬울까?

🔹사용자 수 증가에 따라 동시성을 어떻게 고려해야 할까?

🔹비즈니스 로직을 어느 계층에서 처리하는 것이 아키텍처적으로 바람직할까?

 

이처럼 기능의 맥락과 위치를 판단하는 설계적 사고는 여전히 사람의 역할입니다.

AI는 코드를 생성할 수 있지만, 그 코드가 어떤 구조 안에서 작동해야 하는지는 이해하지 못합니다.

 

이러한 판단은 AI가 데이터로부터 자동 학습할 수 있는 범위를 넘어섭니다. 설계는 코드 이전에 존재하는 의도, 전략, 우선순위의 산물이기 때문입니다.

 

✔️ 실무 예시 - 단순 요청 vs 구조 고려

요청 AI가 생성한 코드 설계자가 고려해야 할 사항
“파일 업로드 기능 만들어줘” POST 요청 처리, 파일 저장, 확장자 검증 상대적으로 단순. 구조 설계 요구 적음
“수십만 명이 동시에 업로드하는 상황의 구조를 설계해줘” ❌ (불가능하거나 부정확) CDN 구성, 비동기 처리, 큐 시스템, 스토리지 분리 등 아키텍처 설계 필요

같은 '파일 업로드'라는 기능이라도, 단순 요청 수준에서는 AI가 훌륭하게 대응할 수 있지만, 시스템 전체 구조나 트래픽 환경을 고려한 설계 수준에서는 한계를 드러냅니다.

결국 AI가 잘하는 일은 “코드 단위 기능 생성”이고, AI가 하지 못하는 일은 “기능 간 관계와 구조를 판단하는 설계”입니다.
이 경계를 분명히 이해하는 것이 개발자가 AI를 효과적으로 활용하는 첫걸음입니다.

 

2. 전체 시스템 구조를 보지 못하는 AI의 한계

GPT와 같은 대규모 언어 모델은 프롬프트로 주어진 코드 조각이나 문맥 범위 내에서만 판단하고 응답을 생성합니다.

즉, 수천 줄에 걸친 프로젝트 전체 구조나 모듈 간의 책임 분리 같은 계층적 설계 맥락을 완전히 이해하진 못합니다.

 

AI는 특정 함수나 클래스 수준에서는 정확한 코드 출력을 보여줄 수 있지만, 그 코드가 시스템 내에서 어떤 계층에 속해야 하고, 어디서 호출되어야 하며, 다른 모듈과 어떻게 연결되어야 하는지는 제대로 파악하지 못합니다.

 

✔️ 실무 예시 – 레이어드 아키텍처에서의 AI 오작동 사례

/myapp/
├── controllers/
├── services/
├── repositories/
└── domain/

예를 들어 회원가입 기능을 구현할 때, 일반적으로는 다음과 같은 계층 분리가 이루어집니다:
🔹 controller: HTTP 요청/응답 처리
🔹 service: 비즈니스 로직 수행
🔹 repository: DB 접근 및 영속성 처리

 

하지만 AI에게 단순히 “회원가입 기능 만들어줘”라고 요청하면 다음과 같은 코드를 반환할 수 있습니다:

# AI가 생성한 예시
class UserService:
    def register_user(self, user_data):
        user = UserModel(**user_data)
        db.session.add(user)  # DB 직접 접근
        db.session.commit()

→ 겉보기에는 멀쩡해 보이지만, 이는 서비스 레이어에서 직접 DB를 조작하고 있어 계층 간 책임 구분이 무너진 예입니다.

 

이러한 코드가 실제 프로젝트에 들어가면 다음과 같은 문제가 발생할 수 있습니다

🔹계층 혼동: DB 접근 로직이 service에 들어감 → 재사용·테스트 어려움
🔹중복 로직 증가: 동일한 비즈니스 규칙이 여러 레이어에 흩어짐
🔹의존성 역전 위반: 상위 계층이 하위 구현 세부사항에 직접 접근함

 

결과적으로, 시스템 전체의 유지보수성이 떨어지고 조금만 구조가 커져도 코드 복잡도와 오류 확률이 급격히 증가하게 됩니다.

 

AI는 “이 기능을 어떻게 구현할까?”에 답하는 데는 능숙하지만, “이 기능을 시스템 어디에, 어떤 역할로 배치할까?”에는 답하지 못합니다.

기능 중심 코드 생성은 AI의 강점이지만, 계층 간 역할 정의, 의존성 설계, 도메인 모델링은 지금도 인간 개발자의 경험과 판단이 필요한 영역입니다.

 

3. 새로운 문제를 푸는 창의력은 아직 인간의 몫

AI는 이미 존재하는 알고리즘을 조합하거나, 범용 문제에 대해 학습된 패턴을 적용하는 데 매우 능숙합니다.

예를 들어, 정렬, 분류, 추천, 회귀와 같은 정형화된 문제에 대해서는 빠르게 코드와 예제를 만들어낼 수 있습니다.

 

하지만 완전히 새로운 맥락에서, 문제를 정의하고 구조화하며 창의적인 방식으로 해결 전략을 설계하는 작업은 여전히 인간 개발자의 역할입니다.

 

✔️ 실무 시나리오 – 이탈 고객 리텐션 전략 설계

다음은 실제 서비스에서 발생할 수 있는 문제입니다.

“1회 구매 후 재방문하지 않는 고객이 많습니다.
이탈 가능성이 높은 고객에게 맞춤형 리텐션 전략을 적용하고 싶습니다.”

 

이 문제는 단순히 분류 모델을 만드는 수준을 넘어섭니다.
먼저, ‘이탈’이 무엇을 의미하는지부터 정의해야 합니다
🔹 며칠 내 미접속을 이탈로 볼 것인가?
🔹 장기 고객과 단기 고객은 어떻게 구분할 것인가?
🔹 행동 로그(클릭, 찜, 스크롤 등)는 어떤 방식으로 수집하고 분석할 것인가?

 

그리고 나서야 아래와 같은 설계 흐름이 가능합니다:
🔹 사용자 세그먼트 기준 정의 (예: 첫 방문 후 7일 이내 미재방문 사용자)
🔹 비정형 로그 데이터 처리 방식 결정 (클릭 횟수, 시간 간격, 페이지 뎁스 등)
🔹 의미 있는 feature 추출 및 모델링 (이탈 위험도 score화 등)
🔹 실시간 적용을 위한 인프라 구성 고려 (stream-based vs batch scoring)

 

✔️ AI에게 요청하면 나오는 코드 예시

from xgboost import XGBClassifier

model = XGBClassifier()
model.fit(X_train, y_train)

이처럼 GPT는 대부분 일반적인 머신러닝 모델 학습 코드를 제시합니다.

하지만 앞서 설명한 비즈니스 목표에 맞는 세부 정의, 전처리, 구조 설계는 빠져 있습니다.
→ 문제 정의가 없으면 설계도 없고, 설계가 없으면 코드도 무의미해집니다.

 

AI는 수많은 데이터로부터 패턴을 추출하고, 그에 기반해 출력을 생성하는 구조입니다.
하지만 문제 자체가 기존에 존재하지 않는 경우엔, 데이터를 기반으로 판단할 근거가 없습니다.

즉, "과거에 없던 문제"에 대해
🔹 어떤 기준으로 문제를 정의할지
🔹 어떤 변수에 주목해야 할지
🔹 어떤 방식으로 해결 접근을 구성할지


이런 창의적 판단은 경험과 맥락을 이해하는 인간 개발자의 직관과 사고력에 의존할 수밖에 없습니다.

반응형

 

4. 기능 구현보다 더 중요한 것 – 실무에서 반드시 필요한 아키텍처 사고

코드는 기능을 구현하기 위한 수단일 뿐입니다.

반면 아키텍처는 그 기능들이 어떻게 구성되고 연결되며 확장될 수 있는지를 결정짓는 시스템의 설계도입니다.


AI가 생성한 코드는 기능 단위로는 훌륭해 보일 수 있습니다.

그러나 그 기능들이 서로 어떻게 연결되는지, 장기적으로 어떻게 유지·확장되어야 하는지에 대한 고려는 부족합니다.

 

✔️ 예시 시나리오 : 마이크로서비스 전환 실패

한 스타트업은 MVP를 빠르게 개발하기 위해 GPT와 Copilot을 적극 활용했습니다.

초기에는 단일 서비스 구조로도 문제없이 운영됐지만, 사용자가 늘고 서비스가 복잡해지자 마이크로서비스로의 전환을 시도하게 됩니다.

하지만 전환 과정에서 다음과 같은 구조적 문제가 터져 나왔습니다

문제 유형 현상
순환 참조 마이크로서비스 간 직접 호출이 반복되며 의존성 꼬임 발생
인증 로직 중복 공통 인증 처리 없이 각 서비스에 중복된 인증 로직이 존재
유틸리티 파편화 공통 코드가 서비스별로 흩어져 유지보수와 재사용 불가
모니터링 부재 서비스 단위 모니터링/배포 체계가 없어 운영 혼란 발생

이 사례의 핵심은 AI가 생성한 코드의 품질 문제가 아니라, 초기에 아키텍처를 정의하지 않은 것에 있습니다

 

GPT는 “사용자 인증 기능 만들어줘” 같은 요청에는 훌륭히 반응합니다.
그러나 아래와 같은 질문에는 답하지 못합니다:

🔹 이 인증 기능은 별도의 서비스로 분리해야 할까?

🔹 토큰 발급과 갱신은 어떤 레이어에서 관리하는 게 좋은가?

🔹 인증 정보는 어떻게 중앙 관리해야 할까?

즉, AI는 로직을 구현할 수는 있어도,역할 분리, 책임 할당, 서비스 간 계약, 배포 전략까지 고려하는 구조 중심 설계는 제시하지 못합니다.

 

5. 프롬프트도 설계다 – AI를 위한 구조 중심 질문법

AI에게 "이 기능 만들어줘"라고 단순히 요청하는 시대는 지났습니다.

이제는 AI를 제대로 활용하려면, 무엇을 만들고자 하는지, 어떤 맥락에서 쓰일 코드인지, 어떤 구조와 제약 조건이 필요한지를 프롬프트에서부터 명확히 전달해야 합니다.

 

프롬프트는 단순한 지시가 아니라, 설계 의도를 담은 설명서입니다.

AI가 좋은 코드를 출력하도록 만들고 싶다면, 먼저 좋은 입력을 설계해야 합니다.

 

🔷 전략 1: 컨텍스트를 명확하게 전달하라

기능 중심 요청만 하면, AI는 계층을 무시한 '즉흥 코드'를 생성하기 쉽습니다.

“회원가입 기능 만들어줘”

→ controller, service, repository를 뒤섞은 코드가 나올 수 있습니다.

반면, 아래처럼 아키텍처 맥락과 역할을 명확히 전달하면, 더 정돈된 코드를 얻을 수 있습니다.

“MVC 구조를 따릅니다.  
DB 접근은 repository 레이어에서만 처리하고,  
서비스 레이어에서는 비즈니스 로직만 수행해 주세요.  
비밀번호는 bcrypt로 암호화하고, 이메일 중복 여부도 검사해 주세요.”

이처럼 역할 분리, 구조 제약, 비즈니스 요구 조건을 명시하면 AI도 기능을 계층에 맞게 나누어 출력하려고 시도합니다.

 

🔷 전략 2: 문제를 설명형으로 요청하라

프롬프트를 질문 대신 상황 설명으로 바꾸는 것만으로도, AI가 더 논리적이고 구조적인 결과를 생성할 수 있습니다.

“이탈 사용자 분류 모델 만들어줘”

→ 단순한 ML 예제 코드, XGBoost나 RandomForest 같은 기본 모델이 나올 가능성이 높습니다.

“우리 서비스는 한 달에 한 번 이상 접속한 고객과 그렇지 않은 고객을 구분해  
리텐션 전략을 다르게 적용하고자 합니다.  
이 기준에 따라 사용자 유형을 분류하고,  
계층별 책임을 나눠서 구현할 수 있는 방법을 알려주세요.”

→ 이렇게 상황과 목적을 함께 설명하면, AI가 왜 그 기능이 필요한지를 유추하고 코드 외에도 구조나 데이터 흐름 설계를 함께 제안하는 경향이 나타납니다.

 

🔷 전략 3: 코드보다 구조를 먼저 요청하라

프롬프트를 통해 설계 구조부터 먼저 요청하는 것도 좋은 전략입니다.
기능을 곧바로 요청하기보다, 계층 분리와 역할 정의를 먼저 제시하면 AI를 단순한 코드 생성 도우미가 아니라 설계 파트너로 활용할 수 있습니다.

“RBAC 구현 코드 보여줘”

→ 사용자-역할-권한 관계가 어떻게 연결되는지 불분명합니다.

“RBAC(Role-Based Access Control) 기반 권한 관리를 구현하려고 합니다.  
User, Role, Permission 세 가지 개체로 구성하고,  
각각의 관계와 역할을 설명해 주세요.  
이 구조를 기반으로 계층별 책임을 나누는 방법도 알려주세요.”

→ 이렇게 구조와 설계 흐름을 먼저 요청하면, AI는 코드뿐만 아니라 데이터 모델링, 계층 설계, 연동 방식까지 포함된 답변을 시도합니다.

 

✔️ 실무에서 자주 접하는 AI 프롬프트의 문제점과 그 개선 예시

🔹 목적 불명확

1. 잘못된 프롬프트
“대시보드 만들고 싶어”

2. 개설된 프롬프트
“로그인한 사용자의 KPI 지표를 시각화하는 관리자용 대시보드를 만들고 싶습니다. 
데이터는 외부 API에서 받아오며, 역할별로 접근 권한이 다릅니다.”

단순히 "대시보드"라고만 하면 어떤 데이터를 보여줘야 하는지, 누가 사용할 것인지가 불분명합니다.

사용자 유형, 데이터 출처, 권한 구조 등 설계에 필요한 조건을 명확히 전달해야 AI가 의미 있는 결과를 생성할 수 있습니다.

 

🔹계층 미정

1. 잘못된 프롬프트
“댓글 기능 구현해줘”

2. 개선된 프롬프트
“Spring Boot 기반 REST API 구조에서 댓글 작성 기능을 구현하고 싶습니다. 
controller는 요청을 받고, service에서는 작성 제한 로직을 검증하고, 
repository에서 DB 저장을 처리하게 해 주세요.”

계층을 지정하지 않으면 AI는 controller와 service, repository 로직을 구분하지 못하고 하나의 클래스에 몰아넣을 가능성이 높습니다. 계층별 역할을 명확히 지정하면 의도에 맞는 계층 구조의 코드를 얻을 수 있습니다.

 

🔹데이터 구조 없음

1. 잘못된 프롬프트
“사용자 리스트 보여줘”

2. 개선된 프롬프트
“MongoDB에 저장된 사용자 목록을 페이징 방식으로 불러오고, 
관리자와 일반 사용자 권한에 따라 다른 필드를 노출하고 싶습니다.”

단순히 "리스트 보여줘"만 전달하면 AI는 기본적인 리스트 출력 코드만 제공할 수 있습니다.

데이터 소스(MongoDB), 출력 방식(페이징), 역할별 출력 조건 같은 요구 조건을 명시하면 실무에 바로 사용할 수 있는 형태로 AI가 응답할 수 있습니다.

 

AI는 사용자의 요청을 액면 그대로 해석합니다.

따라서 실제 서비스 맥락에서 필요한 조건들을 프롬프트에 포함하지 않으면, 기능은 동작하더라도 구조나 책임 분리가 맞지 않는 코드가 생성될 수 있습니다.

잘 설계된 프롬프트는 단순히 코드의 품질만이 아니라, 생성된 코드의 위치, 책임, 사용 맥락까지 명확히 반영하게 만들어 줍니다. 프롬프트 작성도 설계의 일부이며, 이는 결국 실무 설계 능력과 연결됩니다.

 

✔ 마무리 - 설계는 아직 인간의 핵심 역량이다

AI는 반복 작업을 빠르게 처리하고, 정형화된 기능 구현에는 매우 유용한 도구입니다.

하지만 설계 없이 생성된 코드는 시스템 전체의 구조나 흐름을 담보하지 못하는 단편적 결과물에 불과합니다.

 

아키텍처 설계, 비즈니스 해석, 창의적 문제 해결은 여전히 개발자만이 할 수 있는 일입니다.

GPT는 코드의 형태는 제시할 수 있어도, 어떤 구조 속에서 동작해야 하는지까지 설계하지는 못합니다.

속도보다 중요한 건 방향이고, 코드보다 앞서는 건 설계입니다.
AI의 출력을 진짜 시스템으로 만들기 위해선, 그 위에 개발자의 구조적 사고와 판단이 더해져야 합니다.

 

※ 게시된 글 및 이미지 중 일부는 AI 도구의 도움을 받아 생성되거나 다듬어졌습니다.
반응형

 

 

반응형