Code as AI Skills (CaaS) 패턴

aiarchitecturetypescriptdeveloper-experience
By sko11/22/20252 min read

CaaS란 무엇인가?

**Code as AI Skills (CaaS)**는 프로덕션 함수가 번역 레이어 없이 AI 기능이 되는 패턴입니다.

핵심 아이디어: 프로덕션 코드가 곧 스킬입니다. 함수를 한 번 작성하고, 가벼운 SKILL.md 파일을 추가하면, 앱과 AI 모두가 사용할 수 있습니다.

┌───────────────────────────────────────────────────────────────────┐
│                       CaaS 플라이휠                               │
├───────────────────────────────────────────────────────────────────┤
│                                                                   │
│    개발자가 코드 작성 ────────► 코드가 AI 스킬이 됨                │
│          ▲                                │                       │
│          │                                │                       │
│          │                                ▼                       │
│    AI가 코드 작성 ◄──────────── AI가 새로운 기능 획득             │
│                                                                   │
│    각 반복: 개발자와 AI 모두 더 유능해짐                          │
│                                                                   │
└───────────────────────────────────────────────────────────────────┘

세 가지 이점:

  1. 한 번 작성, 어디서나 사용 — 동일한 함수가 앱과 AI 컨텍스트에서 작동
  2. AI는 코드베이스와 함께 성장 — 작성한 모든 함수가 AI 스킬이 됨
  3. AI는 스스로 확장 가능 — AI가 작성한 코드가 새로운 스킬이 됨

작동 방식

단일 함수가 애플리케이션과 AI 에이전트 모두에 제공됩니다:

skills/user-management/
├── SKILL.md              ← AI는 이것을 읽고 함수를 발견
└── createUser.ts         ← 실제 함수 (둘 다 사용)

앱은 직접 임포트:

// app/api/register/route.ts 내부
import { createUser } from '@/skills/user-management/createUser';

const result = await createUser({ email: 'user@example.com', name: 'John' });

AI는 SKILL.md를 읽고, 정확히 같은 함수를 임포트:

// AI 생성 코드 (동일)
import { createUser } from '@/skills/user-management/createUser';

const result = await createUser({ email: 'user@example.com', name: 'John' });

포인트: "앱 버전"과 "AI 버전"이 없습니다. 같은 임포트, 같은 함수, 같은 실행. AI는 단지 SKILL.md를 통해 존재를 발견할 필요가 있을 뿐입니다.

┌────────────────────────────────────────────────────────────────────────────┐
│                                                                            │
│   ┌───────────────────────┐                    ┌───────────────────────┐   │
│   │       개발자          │                    │      AI 에이전트      │   │
│   │                       │                    │                       │   │
│   │  함수를 직접 작성하고  │                    │   SKILL.md를 통해     │   │
│   │  임포트               │                    │   발견하고 사용       │   │
│   └───────────┬───────────┘                    └───────────┬───────────┘   │
│               │                                            │               │
│               │  import { createUser }                     │ SKILL.md 읽기 │
│               │  from '@/skills/...'                       │ 그 다음 임포트│
│               │                                            │               │
│               ▼                                            ▼               │
│   ┌────────────────────────────────────────────────────────────────────┐   │
│   │                                                                    │   │
│   │                      /skills 폴더                                  │   │
│   │                    (공유 코드 레이어)                              │   │
│   │                                                                    │   │
│   │     앱이나 AI가 호출하든 동일한 코드가 실행됨                      │   │
│   │                                                                    │   │
│   └────────────────────────────────────────────────────────────────────┘   │
│                                                                            │
└────────────────────────────────────────────────────────────────────────────┘

복리 효과

AI가 새로운 스킬 생성

AI는 기존 스킬을 사용하여 새로운 스킬을 생성할 수 있습니다.

예시: AI에게 "사용자 온보딩 플로우 생성"을 요청

AI가 기존 스킬을 발견하고 조합:

// skills/onboarding/onboardUser.ts (AI 생성)
import { sendWelcomeEmail } from '@/skills/email/sendWelcomeEmail';
import { createUser } from '@/skills/user-management/createUser';

export async function onboardUser(email: string, name: string) {
  const user = await createUser({ email, name });
  if (user.success) {
    await sendWelcomeEmail(email, name);
  }
  return user;
}

AI는 SKILL.md도 생성하여, 이제 onboardUser가 앱, AI, 그리고 미래의 구성에서 사용 가능합니다.

당신이 새로운 스킬 생성 (같은 패턴)

당신도 동일한 작업을 수행합니다 — 기존 스킬(AI 생성 포함)을 조합:

// skills/admin/bulkOnboard.ts (당신이 작성)
import { onboardUser } from '@/skills/onboarding/onboardUser';
// AI 생성
import { assignRole } from '@/skills/permissions/assignRole';

export async function bulkOnboardAdmins(
  users: Array<{ email: string; name: string }>,
) {
  const results = [];
  for (const user of users) {
    const result = await onboardUser(user.email, user.name);
    if (result.success) {
      await assignRole(result.userId, 'admin');
    }
    results.push(result);
  }
  return results;
}

SKILL.md를 추가(또는 AI에게 생성 요청)하면, AI도 당신의 코드를 사용할 수 있습니다.

성장 루프

┌────────────────────────────────────────────────────────────────────┐
│                                                                    │
│   개발자 기여                         결과                         │
│   ──────────────────                 ──────                        │
│                                                                    │
│   • 새로운 유틸리티 함수 작성   →    AI가 이제 사용 가능           │
│   • 기존 코드 리팩토링         →    AI가 개선된 버전 획득         │
│   • 새로운 도메인 폴더 추가     →    AI가 새로운 기능 발견         │
│                                                                    │
│   AI 기여                            결과                         │
│   ──────────────                     ──────                        │
│                                                                    │
│   • AI가 새로운 함수 작성       →    개발자가 임포트 가능          │
│   • AI가 SKILL.md 생성         →    자신의 작업을 문서화          │
│   • AI가 기존 스킬 확장         →    둘 다 즉시 이익              │
│                                                                    │
└────────────────────────────────────────────────────────────────────┘

                           /skills 폴더
                      ┌───────────────────────┐
          1주차:      │  5개 함수             │
                      └───────────────────────┘

                      ┌───────────────────────┐
          2주차:      │  12개 함수            │  ← 개발자 4개, AI 3개 추가
                      └───────────────────────┘

                      ┌───────────────────────┐
          4주차:      │  28개 함수            │  ← 복리 성장
                      └───────────────────────┘

수학: 10개의 함수를 작성하면, 10개의 AI 스킬을 생성한 것입니다. AI가 5개를 더 작성하면, 이제 15개의 함수와 15개의 AI 스킬이 있습니다. "앱이 할 수 있는 것"과 "AI가 할 수 있는 것" 사이의 격차가 0이 됩니다.


스킬 설정

폴더 구조

/skills 폴더는 앱 폴더 외부에 위치합니다:

project-root/
├── app/                    # 애플리케이션 라우트
├── skills/                 # ← 스킬은 여기 (app의 형제)
│   ├── user-management/
│   │   ├── SKILL.md        # ← 필수: AI 발견용
│   │   └── createUser.ts
│   ├── email/
│   │   ├── SKILL.md
│   │   └── sendWelcome.ts
│   └── {subdomain}/        # 중첩된 스킬 허용
│       └── SKILL.md
└── package.json

필수 vs 유연한 것:

| 필수 | 유연한 것 | | ---------------------- | ------------------------ | | 각 도메인의 SKILL.md | .ts 파일 구성 방법 | | 도메인 폴더 이름 | _models/, _utils/ 등 | | | 추가 .md 문서 (선택) | | | 파일 명명 규칙 |

SKILL.md 형식

간결하게 유지 (30-50줄). AI는 이것을 자주 읽습니다.

---
name: email
description: Resend API를 통해 이메일 전송. 환영 이메일, 알림에 사용.
---

## 사용 가능한 함수

### sendWelcomeEmail

**시그니처:** `sendWelcomeEmail(to: string, name: string): Promise<{ success }>`
**설명:** 새 사용자에게 환영 이메일 전송
**위치:** `sendWelcome.ts`

## 하위 도메인

- **Templates:** `templates/SKILL.md` - 이메일 템플릿 관리

어디에 무엇을 넣을지:

| SKILL.md 내 | 별도 .md 파일 내 | | ----------------------- | ---------------------- | | 함수 시그니처 | 단계별 워크플로우 | | 한 줄 설명 | 상세한 코드 예제 | | 파일 위치 | 엣지 케이스와 주의사항 | | 다른 문서에 대한 포인터 | 전체 API 문서 |

경험 법칙: AI가 함수 사용 여부를 결정하는 데 도움이 되면 → SKILL.md. 복잡한 시나리오에서 올바르게 사용하는 데 도움이 되면 → 참조 파일.


왜 전통적인 도구보다 CaaS인가?

전통적인 AI 도구는 두 개의 별도 항목을 유지 관리해야 합니다:

┌───────────────────────────────────────────────────────────────────────┐
│  전통적: 유지해야 할 두 가지                                          │
├───────────────────────────────────────────────────────────────────────┤
│                                                                       │
│  1. JSON 스키마 (AI용)              2. 실제 함수 (앱용)                │
│  ┌─────────────────────────┐      ┌─────────────────────────┐         │
│  │ {                       │      │ function createUser() { │         │
│  │   "name": "create_user",│  ←→  │   // 구현               │         │
│  │   "inputSchema": {...}  │      │ }                       │         │
│  │ }                       │      └─────────────────────────┘         │
│  └─────────────────────────┘                                          │
│                                                                       │
│  문제: 이들은 반드시 동기화되어야 함. 항상 어긋남.                     │
│                                                                       │
└───────────────────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────────────────┐
│  CaaS: 유지해야 할 한 가지                                            │
├───────────────────────────────────────────────────────────────────────┤
│                                                                       │
│  당신의 함수 + SKILL.md (그것을 가리킴)                               │
│  ┌─────────────────────────┐      ┌─────────────────────────┐         │
│  │ function createUser() { │  ←── │ SKILL.md 내용:          │         │
│  │   // 구현               │      │ "createUser는 여기"     │         │
│  │ }                       │      └─────────────────────────┘         │
│  └─────────────────────────┘                                          │
│                                                                       │
│  SKILL.md는 단지 포인터. 함수가 진실의 원천.                          │
│                                                                       │
└───────────────────────────────────────────────────────────────────────┘

| 전통적 | CaaS | | -------------------------------------- | ----------------------------- | | 스키마가 AI가 보는 것을 정의 | 코드가 AI가 보는 것을 정의 | | 스키마가 구현에 대해 거짓말할 수 있음 | SKILL.md는 실제 코드를 가리킴 | | 함수 업데이트 → 스키마도 업데이트 필요 | 함수 업데이트 → 완료 | | 스키마 테스트 + 함수 테스트 | 함수를 한 번만 테스트 |


결론

핵심 요점:

  1. 한 번 작성, 어디서나 사용 — 프로덕션 함수가 앱과 AI 모두에 제공
  2. 번역 불필요 — AI가 동일한 코드를 임포트하고 실행
  3. 간결하게 유지 — SKILL.md는 발견을 제공, 구현이 아님
  4. 복리 성장 — 당신과 AI 모두 스킬 폴더에 기여

시작하기:

  1. /skills 폴더 생성 (/app의 형제)
  2. 함수가 있는 도메인 폴더 추가
  3. 최소한의 SKILL.md 작성
  4. 앱에서 함수 임포트 — AI도 이제 사용 가능

CaaS 철학: 당신의 코드베이스는 이미 기능으로 가득 차 있습니다. 발견 가능하게 만들면, 그것들이 스킬이 됩니다.


추가 리소스