AI 에이전트가 React 서버 컴포넌트(RSC)를 뚝딱 만들어주는 시대가 됐다. Cursor에서 프롬프트 한 줄이면 데이터 페칭 로직이 서버 컴포넌트에 올라가고, 'use client' 지시어가 붙은 인터랙션 레이어가 분리된다. 동작은 한다. 문제는 그다음이다—그 구조가 진짜 올바른가?
RSC가 요구하는 것은 '동작'이 아니라 '경계 설계'
velog에서 공유된 RSC 기술 면접 정리를 보면, 서버 컴포넌트의 핵심은 단순히 '서버에서 실행된다'는 사실이 아니다. 핵심은 어느 경계에서 서버와 클라이언트를 나누느냐다. 뼈대와 데이터 페칭은 서버 컴포넌트에, useState·이벤트 핸들러처럼 브라우저가 필요한 아주 작은 조각만 'use client'로 떼어내는 트리 설계가 요구된다.
이 경계를 잘못 그으면 어떻게 되는가. 클라이언트 번들이 불필요하게 커지고, Zero Bundle이라는 RSC의 가장 큰 이점이 상쇄된다. 더 심각한 경우엔 클라이언트 컴포넌트 안에서 서버 컴포넌트를 직접 import하는 구조가 들어오는데, 이는 런타임 에러로 이어진다. 동작하는 컴포넌트와 올바르게 설계된 컴포넌트 사이의 간극이 바로 여기에 있다.
AI는 구조를 '재발명'하는 경향이 있다
dev.to에 올라온 Renato Marinho의 글은 이 문제를 정확히 건드린다. 그가 명명한 '섀도우 중복(Shadow Duplication)'은 AI 에이전트가 코드를 생성할 때 기존 로직을 인식하지 못한 채 구조적으로 동일한 코드를 다른 이름으로 다시 만들어내는 현상이다. 변수명이 바뀌고 포맷팅이 달라지기 때문에 grep이나 일반적인 diff로는 잡히지 않는다. PR 리뷰에서도 '새 코드처럼' 보인다.
RSC 문맥에서 이 패턴은 더 위험하다. 예를 들어 데이터 페칭 유틸리티를 AI가 새 서버 컴포넌트에 작성했는데, 이미 다른 서버 컴포넌트에 구조적으로 동일한 로직이 존재하는 경우를 생각해보자. 기능은 돌아가지만, 유지보수 시점에서 두 곳을 따로 수정해야 하는 부채가 조용히 쌓인다. RSC 트리가 깊어질수록 이 부채는 더 조용하게, 더 넓은 범위로 번진다.
Tailwind가 주는 또 다른 교훈—도구는 중립적이다
dev.to의 Tailwind 사용 후기 글은 표면적으로는 CSS 프레임워크 이야기처럼 보이지만, 핵심 메시지는 다르다. "Tailwind 자체는 구조적으로 탄탄하지만, 빠르게 던져서 쓰면 유지 불가능한 코드가 된다"는 것이다. 컴포넌트 분해, 클래스 그루핑, 테마 변수화 같은 명시적인 규율 없이는 Tailwind의 장점이 오히려 혼란의 원인이 된다.
AI가 생성하는 RSC 컴포넌트도 정확히 같은 맥락이다. RSC라는 패러다임 자체는 탄탄하다. Zero Bundle, 스트리밍, RSC Payload를 통한 상태 보존—모두 설계된 이점이다. 하지만 AI가 그 패러다임을 '빠르게 적용'할 때, 경계 설계 원칙이 빠진 채 동작하는 구조가 만들어진다. 도구가 좋다고 해서 AI가 그 도구를 올바르게 사용한다는 보장은 없다.
실무에서 지금 당장 적용할 수 있는 체크포인트
AI가 생성한 RSC 컴포넌트를 검토할 때 다음 세 가지를 먼저 보자.
첫째, 'use client' 경계가 최소화되어 있는가. 인터랙션이 필요한 가장 작은 단위에만 붙어 있어야 한다. 페이지 단위 혹은 레이아웃 단위로 'use client'가 붙어 있다면 RSC의 번들 이점을 거의 포기한 셈이다.
둘째, 데이터 페칭 로직이 중복되어 있지 않은가. Marinho가 제안한 것처럼, 구조적 유사도를 기준으로 코드베이스를 스캔하는 도구—그가 만든 Code Clone Detector MCP 서버 같은—를 에이전트 워크플로우에 연결하는 것을 고려해볼 만하다. AI가 코드를 쓰고 난 뒤 스스로 중복을 감지하게 만드는 루프가 이 부채의 발생 시점을 앞당겨 막는다.
셋째, 서버 컴포넌트 안에서 클라이언트 컴포넌트로 전달되는 props가 직렬화 가능한가. RSC Payload는 함수나 클래스 인스턴스를 직렬화할 수 없다. AI가 생성한 코드에서 이 경계를 무심코 넘는 경우가 의외로 잦다.
전망: AI는 코드 생성자가 아니라 코드 청지기가 되어야 한다
AI 에이전트가 RSC 컴포넌트를 생성하는 속도는 앞으로도 빨라질 것이다. 하지만 RSC 아키텍처가 요구하는 경계 설계, 번들 최적화, 중복 없는 데이터 레이어는 '빠름'과 별개의 차원이다. 이 구조적 판단은 여전히 개발자의 몫이며, AI가 그 판단을 보조하도록 워크플로우를 설계하는 것이 다음 단계다.
Marinho의 표현을 빌리자면, AI를 단순한 코드 생성자(code generator)가 아닌 코드 청지기(code steward)로 만드는 것—그것이 RSC 기반 프로젝트에서 AI 워크플로우가 나아가야 할 방향이다. 동작하는 컴포넌트를 빠르게 얻는 것과, 그 컴포넌트가 아키텍처 안에서 올바른 자리를 차지하게 만드는 것은 다른 문제다. 그리고 지금 이 순간, 두 번째 질문에 답하는 것은 여전히 사람이다.