빠르게 만들었다. 그다음이 문제다
Next.js App Router 위에서 AI 기능을 붙이는 건 이제 어렵지 않다. API Route 하나 열고, 모델 API 호출 붙이고, 결과를 화면에 뿌리면 그럴듯한 프로토타입이 완성된다. 문제는 그 다음이다. 실제로 사용자가 쓰고, 데이터가 흘러다니고, 권한 경계가 생기는 순간—프로토타입이 감추고 있던 설계 부채가 한꺼번에 드러난다.
최근 dev.to에 올라온 두 편의 실전 사례가 이 흐름을 정확히 보여준다. 하나는 Vision Model을 활용한 이미지→프롬프트 변환 도구, 다른 하나는 Microsoft Loop에 AI 어시스턴트가 읽기 전용으로 접근하는 MCP 서버 구현기다. 스택도 다르고 도메인도 다르지만, 두 사례가 공통으로 가리키는 지점은 같다. 동작하는 것과 제대로 설계된 것 사이의 거리.
사례 1: "describe this image"는 프롬프트가 아니다
ImagePromptNow를 만든 개발자가 처음 맞닥뜨린 문제는 기술이 아니었다. Llama 3.2 Vision 모델에 이미지를 던지고 "이 이미지를 설명해줘"라고 하면 캡션이 나온다. "노란 그네에 앉아 있는 남자." 이건 Stable Diffusion이나 Midjourney에 넣을 수 있는 프롬프트가 아니다.
진짜 설계 문제는 여기서 시작됐다. 모델의 출력을 프롬프트로 쓸 수 있으려면 구조가 있어야 한다. 피사체, 배경, 스타일, 조명, 카메라 앵글, 분위기—이 순서로 뽑아내도록 시스템 프롬프트를 설계하고, 출력을 후처리해 사용 가능한 형태로 가공하는 파이프라인이 필요했다. "Structured Breakdown"을 별도로 노출한 것도 같은 이유다. 사용자가 어떤 요소가 어디서 왔는지 이해해야 직접 수정할 수 있으니까.
여기서 나온 교훈 하나가 인상적이다. 각 모델(Stable Diffusion, DALL-E, Flux)이 선호하는 프롬프트 스타일이 다르다는 걸 알면서도, 이 개발자는 모델별 자동 타겟팅 대신 사용자가 직접 조정할 수 있는 베이스 프롬프트 하나를 선택했다. 복잡한 분기를 제거하고, 사용자의 학습 가능성에 투자한 결정이다. 프로덕트 사고가 기술 선택을 이긴 순간이다.
로컬라이제이션을 초기에 붙인 것도 같은 맥락이다. next-intl로 6개 언어를 지원하자 비영어권 검색 결과에서 빠르게 노출이 시작됐다. 콘텐츠 인접 도구라면 로컬라이제이션은 기능이 아니라 배포 전략이다.
사례 2: 동작하는 것과 안전한 것은 다르다
Microsoft Loop에 AI 어시스턴트를 연결한 MCP 서버 구현기는 권한 설계의 함정을 정면으로 다룬다. 표면적인 문제는 Loop의 콘텐츠 API가 없다는 것이었다. 하지만 SharePoint Embedded 파일 레이어를 통해 우회 접근이 가능하다는 걸 발견하는 데까지는 그리 오래 걸리지 않았다.
진짜 문제는 그다음이었다. SharePoint Embedded는 위임 토큰(delegated token)으로 콘텐츠를 직접 다운로드할 수 없다. 앱 자체 ID(app-only identity)만 허용된다. 이 말은 곧, 앱 ID로 콘텐츠를 가져오는 서비스를 그냥 만들면 권한 평탄화 기계가 된다는 뜻이다. 앱이 볼 수 있으면 서비스에 접근하는 누구든 볼 수 있다. 테넌트 전체가 열리는 데이터 누출이다.
이 문제를 푼 방식이 설계적으로 깔끔하다. 핵심 통찰은 탐색(discovery)과 조회(retrieval)를 분리하는 것이었다.
Graph Search는 위임 호출에서도 보안 트리밍이 작동한다. 즉, 사용자 토큰으로 검색하면 그 사용자가 볼 수 있는 것만 결과로 돌아온다. 그래서 이 MCP 서버는 검색을 사용자 토큰(OAuth OBO 흐름)으로 실행하고, 그 결과로 얻은 (driveId, itemId) 쌍을 사용자별 단기 캐시에 저장한다. 실제 콘텐츠 다운로드는 앱 ID를 쓰지만, 해당 (driveId, itemId)가 이 사용자의 캐시에 있을 때만 허용한다.
권한 판단은 Microsoft가 한다. 앱은 그 판단의 결과물을 가져오는 역할만 한다. 우아한 책임 분리다.
프로토타입이 숨기는 것들
두 사례를 나란히 놓으면 패턴이 보인다.
첫 번째 단계—"동작하게 만들기"—는 빠르다. Next.js와 AI API 조합이라면 하루 안에 뭔가 그럴듯한 게 나온다. 하지만 바로 그 속도가 함정이다. 동작하는 프로토타입은 세 가지를 감춘다. 출력 품질 설계, 권한·보안 경계, 그리고 사용자가 실제로 쓸 수 있는 UX.
이미지→프롬프트 도구는 모델 출력을 그냥 쓰는 대신 시스템 프롬프트와 후처리 파이프라인을 설계했고, 로그인 없음·무제한 사용이라는 UX 원칙을 제품의 핵심으로 삼았다. MCP 서버는 "앱 ID로 다 읽자"는 쉬운 길 대신 탐색-조회 분리라는 구조 설계를 선택했고, OAuth 리소스 서버를 직접 구현해 인증 흐름을 온전히 통제했다.
AI 도구 개발자에게 남는 질문
지금 Next.js로 AI 기능을 붙이고 있다면, 스스로에게 이 질문들을 던져볼 만하다.
모델의 원시 출력을 그대로 쓰고 있는가, 아니면 사용자가 실제로 쓸 수 있는 형태로 구조화하는 파이프라인이 있는가. AI가 접근하는 데이터의 권한 경계를 명시적으로 설계했는가, 아니면 "일단 다 읽을 수 있게" 열어놓았는가. 빠르게 만든 것의 어느 부분이 프로덕션에서 문제가 될지 미리 파악하고 있는가.
프로토타입은 가능성을 보여주기 위한 것이다. 하지만 제품은 그 가능성이 실제로 안전하고 일관되게 작동하는 구조 위에 서야 한다. AI 도구를 만들 때도 이 원칙은 달라지지 않는다. 오히려 모델의 출력이 비결정적이고, 데이터 접근 범위가 넓어질수록 설계의 중요성은 더 커진다.
다음 단계는 어디인가
두 사례 모두 현재진행형이다. 이미지→프롬프트 도구는 특정 시각 요소를 "잠금" 상태로 유지한 채 스타일만 바꿔 재생성하는 기능을 다음으로 계획하고 있다. MCP 서버는 오픈소스(MIT)로 공개되어 있고, 프로덕션 투입 전에 검토해야 할 보안 잔여 위험을 SECURITY.md에 명시적으로 문서화했다.
둘 다 "완성됐다"고 선언하지 않는다. 그게 이 두 사례가 설득력을 갖는 이유다. 프로토타입을 빠르게 만들고, 그 안에서 진짜 설계 문제를 발견하고, 구조를 잡아가는 과정—그것이 AI 도구를 제품으로 만드는 실제 경로다.