Code as AI Skills (CaaS)パターン
CaaSとは?
Code as AI Skills (CaaS) は、あなたの本番環境の関数が翻訳レイヤーなしにAIの能力になるパターンです。
コアアイデア:本番環境のコードがスキルそのものです。一度関数を書いて、軽量な SKILL.md ファイルを追加すれば、アプリとAIの両方がそれを使用できます。
┌────────────────────────────────────────────────────────────────────┐
│ CaaSフライホイール │
├────────────────────────────────────────────────────────────────────┤
│ │
│ 開発者がコードを書く ────────► コードがAIスキルになる │
│ ▲ │ │
│ │ │ │
│ │ ▼ │
│ AIがコードを書く ◄────────── AIが新しい能力を獲得する │
│ │
│ 各イテレーション:開発者とAIの両方がより有能になる │
│ │
└────────────────────────────────────────────────────────────────────┘
3つの利点:
- 一度書いて、どこでも使用 — 同じ関数がアプリとAIコンテキストで動作
- AIはコードベースとともに成長 — 書いたすべての関数がAIスキルになる
- 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ができること」のギャップがゼロになります。
スキルのセットアップ
フォルダー構造
/skills フォルダーはアプリフォルダーの外側にあります:
project-root/
├── app/ # アプリケーションルート
├── skills/ # ← スキルはここ(appの兄弟)
│ ├── user-management/
│ │ ├── SKILL.md # ← 必須:AI発見用
│ │ └── createUser.ts
│ ├── email/
│ │ ├── SKILL.md
│ │ └── sendWelcome.ts
│ └── {subdomain}/ # ネストされたスキルも可能
│ └── SKILL.md
└── package.json
必須と柔軟なもの:
| 必須 | 柔軟 |
| ----------------------- | --------------------------------- |
| 各ドメインの 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ファイル内 | | ------------------------ | --------------------- | | 関数シグネチャ | 段階的なワークフロー | | 1行の説明 | 詳細なコード例 | | ファイルの場所 | エッジケースと注意点 | | 他のドキュメントへの参照 | 完全なAPIドキュメント |
経験則: AIが関数を使用するかどうかを決定するのに役立つなら → SKILL.md。複雑なシナリオで正しく使用するのに役立つなら → 参照ファイル。
なぜ従来のツールではなくCaaSなのか?
従来のAIツールでは、2つの別々のものを維持する必要があります:
┌───────────────────────────────────────────────────────────────────────┐
│ 従来型:維持すべき2つのもの │
├───────────────────────────────────────────────────────────────────────┤
│ │
│ 1. JSONスキーマ(AI用) 2. 実際の関数(アプリ用) │
│ ┌─────────────────────────┐ ┌─────────────────────────┐ │
│ │ { │ │ function createUser() { │ │
│ │ "name": "create_user",│ ←→ │ // 実装 │ │
│ │ "inputSchema": {...} │ │ } │ │
│ │ } │ └─────────────────────────┘ │
│ └─────────────────────────┘ │
│ │
│ 問題:これらは同期を保つ必要があります。常にズレます。 │
│ │
└───────────────────────────────────────────────────────────────────────┘
┌───────────────────────────────────────────────────────────────────────┐
│ CaaS:維持すべき1つのもの │
├───────────────────────────────────────────────────────────────────────┤
│ │
│ あなたの関数 + SKILL.md(それを指す) │
│ ┌─────────────────────────┐ ┌─────────────────────────┐ │
│ │ function createUser() { │ ←── │ SKILL.mdの内容: │ │
│ │ // 実装 │ │ "createUserはここ" │ │
│ │ } │ └─────────────────────────┘ │
│ └─────────────────────────┘ │
│ │
│ SKILL.mdは単なるポインタ。関数が信頼できる唯一の情報源です。 │
│ │
└───────────────────────────────────────────────────────────────────────┘
| 従来型 | CaaS | | --------------------------------- | ---------------------------- | | スキーマがAIが見るものを定義 | コードがAIが見るものを定義 | | スキーマは実装について嘘をつける | SKILL.mdは実際のコードを指す | | 関数を更新 → スキーマも更新が必要 | 関数を更新 → 完了 | | スキーマのテスト + 関数のテスト | 関数を一度テスト |
結論
重要なポイント:
- 一度書いて、どこでも使用 — 本番環境の関数がアプリとAIの両方に提供
- 翻訳不要 — AIは同じコードをインポートして実行
- 簡潔に保つ — SKILL.mdは発見を提供、実装ではない
- 複利成長 — あなたとAIの両方がスキルフォルダーに貢献
はじめ方:
/skillsフォルダーを作成(/appの兄弟)- 関数を含むドメインフォルダーを追加
- 最小限の SKILL.md を書く
- アプリで関数をインポート — AIも今それを使用できる
CaaSの哲学: あなたのコードベースはすでに能力で満ちています。それらを発見可能にすれば、スキルになります。