|
| 1 | +# Agent AI SDK |
| 2 | + |
| 3 | +AWS Lambda上でVercel AI SDKを使用し、Amazon BedrockやAzure OpenAIとの対話を行うエージェントアプリケーションです。 |
| 4 | + |
| 5 | +## アーキテクチャ |
| 6 | + |
| 7 | +- **AWS Lambda (Node.js 24.x)**: サーバーレスコンピューティング |
| 8 | +- **Lambda Function URL**: エンドポイント公開 |
| 9 | +- **Amazon Bedrock / Azure OpenAI**: LLMバックエンド |
| 10 | +- **Vercel AI SDK**: AI/LLM連携ライブラリ |
| 11 | +- **AWS CDK**: インフラストラクチャ管理 |
| 12 | + |
| 13 | +## 機能 |
| 14 | + |
| 15 | +- ストリーミングレスポンス対応 |
| 16 | +- ToolLoopAgentによるツール呼び出し |
| 17 | +- マルチプロバイダー対応(AWS Bedrock、Azure OpenAI) |
| 18 | +- セッション管理 |
| 19 | +- トークン使用量のログ記録 |
| 20 | + |
| 21 | +## 必要条件 |
| 22 | + |
| 23 | +- Node.js 24.x |
| 24 | +- AWS CLI(設定済み) |
| 25 | +- AWS CDK |
| 26 | +- pnpm |
| 27 | + |
| 28 | +## セットアップ |
| 29 | + |
| 30 | +```bash |
| 31 | +# 依存関係のインストール |
| 32 | +pnpm install |
| 33 | + |
| 34 | +# ビルド |
| 35 | +pnpm run build |
| 36 | + |
| 37 | +# テスト |
| 38 | +pnpm run test |
| 39 | +``` |
| 40 | + |
| 41 | +## デプロイ |
| 42 | + |
| 43 | +```bash |
| 44 | +# CDK bootstrap(初回のみ) |
| 45 | +npx cdk bootstrap |
| 46 | + |
| 47 | +# デプロイ |
| 48 | +npx cdk deploy |
| 49 | +``` |
| 50 | + |
| 51 | +デプロイ後、Lambda Function URLが出力されます。 |
| 52 | + |
| 53 | +## API使用方法 |
| 54 | + |
| 55 | +```bash |
| 56 | +curl -X POST <Function URL> \ |
| 57 | + -H "Content-Type: application/json" \ |
| 58 | + -d '{ |
| 59 | + "prompt": "こんにちは", |
| 60 | + "modelId": "claude-3-sonnet", |
| 61 | + "session": "session-id", |
| 62 | + "id": "query-id" |
| 63 | + }' |
| 64 | +``` |
| 65 | + |
| 66 | +### リクエストパラメータ |
| 67 | + |
| 68 | +| パラメータ | 型 | 必須 | 説明 | |
| 69 | +| --------- | ---- | ---- | ---- | |
| 70 | +| `prompt` | string | 是 | ユーザーの入力プロンプト | |
| 71 | +| `modelId` | string | 是 | 使用するモデルID | |
| 72 | +| `session` | string | 任意 | セッション識別子 | |
| 73 | +| `id` | string | 任意 | クエリ識別子 | |
| 74 | + |
| 75 | +## プロジェクト構造 |
| 76 | + |
| 77 | +```text |
| 78 | +. |
| 79 | +├── bin/ |
| 80 | +│ └── agent-ai-sdk.ts # CDKエントリポイント |
| 81 | +├── lib/ |
| 82 | +│ └── agent-ai-sdk-stack.ts # CDKスタック定義 |
| 83 | +├── lambda/ |
| 84 | +│ ├── index.ts # Lambdaハンドラー |
| 85 | +│ └── handler.ts # ビジネスロジック |
| 86 | +├── test/ |
| 87 | +│ └── agent-ai-sdk.test.ts # テスト |
| 88 | +└── cdk.json # CDK設定 |
| 89 | +``` |
| 90 | + |
| 91 | +## 開発コマンド |
| 92 | + |
| 93 | +| コマンド | 説明 | |
| 94 | +| ------- | ---- | |
| 95 | +| `pnpm run build` | TypeScriptコンパイル | |
| 96 | +| `pnpm run watch` | 変更監視モード | |
| 97 | +| `pnpm run test` | テスト実行 | |
| 98 | +| `npx cdk deploy` | スタックデプロイ | |
| 99 | +| `npx cdk diff` | 差分確認 | |
| 100 | +| `npx cdk synth` | CloudFormationテンプレート生成 | |
| 101 | + |
| 102 | +## Agents |
| 103 | + |
| 104 | +本プロジェクトは Vercel AI SDK の `ToolLoopAgent` を使用して、LLMとの対話を行います。 |
| 105 | + |
| 106 | +### ToolLoopAgent の構成 |
| 107 | + |
| 108 | +```typescript |
| 109 | +const agent = new ToolLoopAgent({ |
| 110 | + model, // LLMモデルインスタンス |
| 111 | + instructions: 'You are a helpful assistant.', // システムプロンプト |
| 112 | + tools: { // ツール定義(オプション) |
| 113 | + // カスタムツールをここに追加 |
| 114 | + }, |
| 115 | + experimental_telemetry: { // テレメトリ設定(オプション) |
| 116 | + isEnabled: true, |
| 117 | + metadata: { |
| 118 | + model: modelId, |
| 119 | + thread_id: session, |
| 120 | + query_id: id, |
| 121 | + } |
| 122 | + }, |
| 123 | +}); |
| 124 | +``` |
| 125 | + |
| 126 | +### ツールの追加方法 |
| 127 | + |
| 128 | +ToolLoopAgent はツール呼び出しを自動的にループ処理します。カスタムツールを追加する場合: |
| 129 | + |
| 130 | +```typescript |
| 131 | +import { tool } from 'ai'; |
| 132 | +import { z } from 'zod'; |
| 133 | + |
| 134 | +const agent = new ToolLoopAgent({ |
| 135 | + model, |
| 136 | + instructions: 'You are a helpful assistant.', |
| 137 | + tools: { |
| 138 | + getWeather: tool({ |
| 139 | + description: '指定された都市の天気を取得します', |
| 140 | + parameters: z.object({ |
| 141 | + city: z.string().describe('都市名'), |
| 142 | + }), |
| 143 | + execute: async ({ city }) => { |
| 144 | + // 天気APIを呼び出す処理 |
| 145 | + return { temperature: 25, condition: 'sunny' }; |
| 146 | + }, |
| 147 | + }), |
| 148 | + // 他のツールを追加... |
| 149 | + }, |
| 150 | +}); |
| 151 | +``` |
| 152 | + |
| 153 | +### ストリーミング設定 |
| 154 | + |
| 155 | +スムーズなストリーミングレスポンスを実現するため、`smoothStream` を使用: |
| 156 | + |
| 157 | +```typescript |
| 158 | +const stream = await agent.stream({ |
| 159 | + messages, |
| 160 | + experimental_transform: smoothStream({ |
| 161 | + delayInMs: 20, // チャンク間の遅延(デフォルト: 10ms) |
| 162 | + chunking: 'line', // チャンク分割方法: 'word' | 'line'(デフォルト: 'word') |
| 163 | + }), |
| 164 | +}); |
| 165 | +``` |
| 166 | + |
| 167 | +### ステップ完了コールバック |
| 168 | + |
| 169 | +各ステップ(ツール呼び出しや応答生成)完了時の処理: |
| 170 | + |
| 171 | +```typescript |
| 172 | +const stream = await agent.stream({ |
| 173 | + messages, |
| 174 | + onStepFinish: async ({ usage, finishReason, toolCalls }) => { |
| 175 | + // トークン使用量の記録 |
| 176 | + logger.info('Step completed:', { |
| 177 | + inputTokens: usage.inputTokens, |
| 178 | + outputTokens: usage.outputTokens, |
| 179 | + finishReason, // 'stop' | 'length' | 'content-filter' | 'tool-calls' | 'error' | 'other' |
| 180 | + toolsUsed: toolCalls?.map(tc => tc.toolName), |
| 181 | + }); |
| 182 | + }, |
| 183 | +}); |
| 184 | +``` |
| 185 | + |
| 186 | +### セッション管理 |
| 187 | + |
| 188 | +会話履歴はメモリ内に保持され、複数ターンの対話が可能: |
| 189 | + |
| 190 | +```typescript |
| 191 | +const messages: ModelMessage[] = []; |
| 192 | + |
| 193 | +// ユーザー入力を追加 |
| 194 | +messages.push({ role: 'user', content: prompt }); |
| 195 | + |
| 196 | +// エージェント実行 |
| 197 | +const stream = await agent.stream({ messages }); |
| 198 | + |
| 199 | +// アシスタント応答を履歴に追加 |
| 200 | +messages.push({ role: 'assistant', content: response }); |
| 201 | +``` |
| 202 | + |
| 203 | +**注意**: Lambdaのステートレス性により、セッションは同じLambdaインスタンス内でのみ保持されます。 |
| 204 | + |
| 205 | +## モデル設定 |
| 206 | + |
| 207 | +使用可能なモデルは `common-core` パッケージの `models` で定義されています。対応プラットフォーム: |
| 208 | + |
| 209 | +- **AWS**: Amazon Bedrock |
| 210 | +- **Azure**: Azure OpenAI |
| 211 | + |
| 212 | +## IAMポリシー |
| 213 | + |
| 214 | +Lambda実行ロールには以下の権限が付与されています: |
| 215 | + |
| 216 | +- `AWSLambdaExecute` |
| 217 | +- `CloudFrontReadOnlyAccess` |
| 218 | +- `bedrock:InvokeModel*` |
| 219 | +- `logs:PutLogEvents` |
| 220 | + |
| 221 | +## ライセンス |
| 222 | + |
| 223 | +MIT |
0 commit comments