이거 왜 필요했는가?
AI 기능을 사용하기 위해서는 외부sdk를 로드하고, 해당 sdk에서 제공하는 API를 연결하여 크레딧 정보 조회, 생성/취소 기능을 사용할 수 있었다.
2025년 7월 전까지 AI 기능을 쓰는 곳은 아래 사진처럼 3개의 구역에서만 사용하고 있었다.
- 에디터 > 좌측탭 > AI도구
- 에디터 > 좌측탭 > 사진 > 속성창 > 쉬운편집
- 에디터 > 좌측탭 > 사진 > 쉬운편집

그러다가 2025년 7월 미리클(miricle) 프로덕트를 개발하면서,
또 다시 3개의 지점에서 AI 생성 기능을 요구하게 되었다.
- Miricle > AI도구 > 입력화면(생성,크레딧)
- Miricle > AI도구 > 결과화면(재생성)
- Miricle > 메인 > 히어로 영역

당시, 개발 일정이 약 2주 - 2주 반 정도 되는 시간이었기에 미리캔버스에서 사용하고 있는 AI기능을 import해서 쓰는 것보다는 비슷한 코드를 복사/붙여넣기해서 만드는 것이 가장 사이드 이펙트가 적고, 개발공수가 가장 적은 방향이었다.
하지만 정말 많은 코드들이 다른 폴더에 중복해서 생성되는 개발 부채는 늘어남과 동시에 코드량도 많아졌고, 기능 구현을 위해서 AI 기능 사용이라는 큰 덩어리를 옮기기 위해 찍어내는 커밋은 무궁무진하게 늘어났다.

당시, 약 한 달동안 찍어낸 커밋 수는 약 550 - 600개 정도 되었다. 평일 근무로도 충분하지않아서 주말 근무는 당연히 하게 되었고, 코드 찍는 기계가 되었구나~라고 느꼈던 순간이기도 했다.
그치만 개발하면서도 이렇게 비슷하면서도 똑같은 코드를 두벌, 세벌 만들어도 되는건가? 이 상황에서는 그렇지 않았다. 프로덕트 관점에서 요구하는 기능이 같았기에 이 상황에서는 반복작업보다는 생성 기능을 제공하는 무언가. 있는 것이 가장 이상적인 상황이었다.
기능을 구현하면서도 물론 이전에 있던 AI도구의 개선점들을 최대한 반영할 수 있어서 좋았지만, 그럼에도 여전히 비슷한 코드들이 많아서 마음이 참 편하지 않았습니다.
그 마음이 7월로 끝날 수 있었는가…?

다시 미리캔버스로 돌아와서
또 다시 AI 기능 사용을 위한 진입점이 한 군데 더 생성되었다.

이제 AI를 사용하기 위한 진입점이 총 7곳이 되어버린 상황에 직면해버렸다.
앞에서 느꼈던 나의 슬픔 마음이 있었지만, 이번에도 스쿼드 상황을 바라봤을때, 주요 액션이 필요한 시기였기에 이번에도 일단 복사/붙여넣기를 진행하기로 했다.
결과는 어땠을까?
말하지 않아도 다들 예상하실 수 있듯이…

반복되는 또 다른 미니 미리클이었다.
이 와중에 해당 시기에 여러 스쿼드에서 AI 기능에 대한 새로운 피쳐들을 개발하고자하는 시도들이 보였고,
스스로 상상을 해보았는데.
- ‘이 과정이 다른 스쿼드에서 시작된다?’
- ‘갑자기 어디선가 AI 기능 관련 코드가 변경되었는데 우리쪽에서 사이드이펙트가 터진다면..?’
- '진입점 개발을 당장 1주일안에 넣고 싶다고 한다면..?
- …
등등… 정말 아찔한 결과만 떠오르는 생각들 뿐이라고 느꼈다.
그래서 이제는 결심하게 되었다.
🍋 AI-KIT 패키지를 만들자 🍋
우선, 이 패키지 개발을 시작할 수 있었던 배경은 아래와 같다.
- 스쿼드 업무의 효율 향상을 위해 필요한 기술 내용임을 PM님께 알려드렸다.
- 스쿼드의 목표 달성을 위해서 필요한 업무가 있다면 해당 업무를 우선으로 진행하고, 중간중간 틈이 나는 상황에서 AI-KIT 모듈화 이슈를 병렬적으로 진행하는 것으로 정렬하였다.
AI-KIT 의 개요
AI-KIT은 React 애플리케이션에서 AI 생성 기능을 제공하는 라이브러리
외부 AI SDK를 추상화하여 React 환경에서 쉽게 사용할 수 있도록 만든 것이 목적이다.
1. AI 기능 통합
- AI 기능 사용을 위한 사용자 인증
- AI
- text → image
- text → text
- text → video
- text → speech
- image → image
- image → video
- aiLogo , aiPoster, aiRedesign
- 쉬운편집
- 영역 지우개
- 화질개선
- 부분생성
- 이미지 확장
- 배경제거
- 크레딧
- 요청 취소
2. 인증 토큰 자동 관리 및 갱신
- AI SDK를 사용하기 위해 미캔 인증정보와는 별도의 토큰을 발급
- 인증 에러 시 토큰 갱신 후 자동 재시도
- 이중 인증 시스템 (authV1/authV2) 통합 관리
3. 외부 AI SDK의 React 통합
- 동적 스크립트 로딩 (window.__MIRID.aiImage)
- SDK를 React 훅으로 래핑
- AI SDK 사용을 위한 인증정보를 ai-kit에서 관리
- 데이터 형식 자동 변환 (MIME 타입 기반 결과 타입 판별)
- 에러 형식 통일
4. Task 기반 비동기 작업 관리
- 하나의 요청으로 여러 작업 생성
- 각 작업의 상태를 개별 추적
- 작업별 성공/실패 콜백 지원

// Task 상태
type Task =
| { state: 'PENDING', key: string }
| { state: 'SUCCESS', key: string, data: {...} }
| { state: 'ERROR', key: string };
// 콜백 시스템
onTaskSuccess: (task: Task.Success) => void;
onTaskError: (task: Task.Error) => void;
onTaskComplete: (task: Task) => void;
AI-KIT 데이터 흐름도
1. 컴포넌트에서의 데이터 흐름

useAIKitLoaderQuery

useAIKitAuthQuery

2. 요청 단계

3. 에러 처리 단계

그래서 AI-KIT 어떻게 사용하는 건가요?
패키지 구조도의 핵심만 보여드리면 아래와 같다.
├── src/
│ ├── hooks/ # AI Kit 기능을 사용하기 위한 React hooks
│ │
│ ├── providers/ # Provider 및 관련 hooks
│ │ # - AIKitQueryProvider: AIKitClient를 제공하는 Provider
│ │ # - useAIKitQuery: Provider에서 AIKitClient를 가져오는 hook
│ │
│ ├── types/ # 타입 정의
│ │ ├── client/ # 클라이언트에서 사용하는 타입 (AIKitTask, AIKitClient, UserStorage 등)
│ │ ├── sdk/ # SDK 레벨의 타입 정의 (외부 SDK와의 인터페이스)
│ │ └── shared/ # SDK와 client의 공유 타입 정의
│ │
│ ├── converter/ # 데이터 변환 함수
│ │
│ ├── queries/ # 내부적으로만 사용되는 React Query 쿼리 (모듈 외부로 export되지 않음)
│ │ # - useAIKitLoaderQuery: AI Kit SDK 로더 쿼리
│ │
│ ├── constants/ # 상수 정의
│ │
│ └── __test__/ # 테스트 파일
│
├── dist/ # 빌드 결과물
├── node_modules/ # 의존성 패키지
├── package.json
├── README.md
├── tsconfig.json
└── vite.config.ts
- types 하위에 있는 파일들
- converter
- queries
- constants
위 4가지 함수가 기능별로 중복해서 이름만 다르게 작성되어있는 상태였다.
약… 48개정도 * 3 = 97개 사라졌다.ex) ai-drawing~ , ai-core~ , ai-workflow ~
🚨 AI-KIT을 개발하면서 겪었던 트러블 슈팅
문제 상황
- AIKitQueryProvider에서 sdk 스크립트 로드 & auth 발급하여 aiKitQueryClient 생성하는 로직 구현 되어있었다.
- app에서 감싸는 경우 sdk 스크립트 로드를 위해 csr 렌더링을 해야 하는 상황이 발생했다.
- ssr : false 로 렌더링을 해야 하는 상황

해결 방안
- 설명했던 방식대로 useAIKitCreditQuery, useAIKitGenerateMutation … 기능 사용을 위한 훅을 호출할 때, sdk로드 & auth 발급해서 사용하도록 구조 개편을 진행했다.
- sdk 로드 ,auth 발급은 쿼리 캐시 보고 데이터 가져오도록 작성
남은 작업들
- ai-kit 1차 모듈화한 것 내부 미리클, 외부 미리클에 100% 적용하기
- AI-KIT 내부 폴더 구조 개편하기
- 사실 지금까지는 이 필요성을 느끼지 못했는데, 미리클 스쿼드의 내년 OKR의 주요 내용 중에서 '30초만에 사용성을 느낄 수 있는 UI/UX를 기능에 따라 동일하게 제공한다' 라는 맥락이 있었고, 이에 따르면 layered architecture 로 가볼만한 이유가 된다고 생각했다.
그리고 모두가 생각했으면 하는 앞으로의 개발 자세
스쿼드 업무를 하면서 느꼈지만, 프로덕트 관점에서는 제품 성장과 매출이 우선시 되어야 하기에 최대한 빠르게 검증하는 과정이 특정 시기마다 반복된다고 느꼈다.
하지만, 그 과정에서 개발적으로 불필요한 내용, 아니면 이런 부분이 개선되면 프로덕트 관점에서 새로운 시도를 하기까지 오히려 더 시간이 단축될 수 있는 부분들을 개발자 스스로 발견하고, 피쳐 개발 이외의 시간을 투자하여 개선하는 것이 나뿐만 아니라 다른 개발자, 그리고 스쿼드 더 크게보면 미리디까지에도 영향을 줄 수 있는 부분이라고 생각했고 그래서 개발자는 ‘코드 찍어내는 기계’가 맞지만 그 코드를 얼마나 효율적으로 찍어내는 기계인지 스스로 점검하면서 임할 필요성을 크게 느꼈다.
앞으로 여러분들도 개발을 하다가 이러한 비슷한 경험을 하고 있다면, 피쳐 개발이 몰려있다하더라도 틈틈히 내부 개발 부채들을 해결하는 노력을 시도해보았으면 좋을 것 같다.
왜냐하면 나뿐만 아니라 다른 모든 이들에게 좋은 영향을 주기 위해서는 위와 같은 노력이 필요하다고 생각하기 때문이다.