MastraとAmazon Bedrock使ってAI エージェントを作る

## 前書き

![E8B7D2CD-DEF0-4F4C-AADE-F34F72EC35DD.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320164/ed732417-c167-4689-9044-1a0975851468.jpeg)

最近、TypeScriptエージェントフレームワークの「Mastra」が話題になっています。どのような特徴があるのか実際に使って検証してみました。

https://mastra.ai/

## 天気情報検索エージェントの実装

### プロジェクト初期化

```bash
> npx create-mastra@latest
```

![03A133A3-67F8-4F3B-AB73-10921881A0A0.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320164/31a9b29c-a229-4e9b-8084-81eda1875627.jpeg)

「Choose Components」でAgentsを選択します。
プロバイダーにAmazon Bedrockの選択肢がありませんが、適当に選んで、後から変更できます。


初期化後のディレクトリ構成:
```
project
    ├── node_modules
    ├── src
    │   ├── mastra
    │   │   ├── agents
    │   │   │   ├── index.ts
    │   │   └── tools
    │   │   │   └── index.ts
    │   └── index.ts
    ├── package.json
    └── tsconfig.json
```

メインのindex.tsファイルはシンプルで、天気エージェントとログ設定を行っています。

```typescript:src/mastra/index.ts
import { Mastra } from '@mastra/core/mastra';
import { createLogger } from '@mastra/core/logger';

import { weatherAgent } from './agents';

export const mastra = new Mastra({
  agents: { weatherAgent },
  logger: createLogger({
    name: 'Mastra',
    level: 'info',
  }),
});

```

天気エージェントの実装

```typescript:src/mastra/agents/index.ts
import { anthropic } from '@ai-sdk/anthropic';
import { Agent } from '@mastra/core/agent';
import { weatherTool } from '../tools';

export const weatherAgent = new Agent({
  name: 'Weather Agent',
  instructions: `
      You are a helpful weather assistant that provides accurate weather information.

      Your primary function is to help users get weather details for specific locations. When responding:
      - Always ask for a location if none is provided
      - If giving a location with multiple parts (e.g. "New York, NY"), use the most relevant part (e.g. "New York")
      - Include relevant details like humidity, wind conditions, and precipitation
      - Keep responses concise but informative

      Use the weatherTool to fetch current weather data.
`,
  model: anthropic('claude-3-5-sonnet-20241022'),
  tools: { weatherTool },
});
```

`@ai-sdk/xxx`からプロバイダーをインポートし、Agentの設定は名前、システムプロンプト、使用モデルとツールを明確に定義します。

### Amazon Bedrockプロバイダーへの変更

VercelのAI SDKからBedrockプロバイダーをインストールして利用できます。

https://sdk.vercel.ai/providers/ai-sdk-providers/amazon-bedrock

```bash
> npm install @ai-sdk/amazon-bedrock
```

```diff_typescript:src/mastra/agents/index.ts
+ import { createAmazonBedrock } from '@ai-sdk/amazon-bedrock';
import { Agent } from '@mastra/core/agent';
import { weatherTool } from '../tools';

+const bedrock = createAmazonBedrock({
+  region: 'us-east-1',
+  accessKeyId: 'xxxxxxxxx',
+  secretAccessKey: 'xxxxxxxxx',
+  sessionToken: 'xxxxxxxxx',
+});

export const weatherAgent = new Agent({
  name: 'Weather Agent',
  instructions: `
      You are a helpful weather assistant that provides accurate weather information.

      Your primary function is to help users get weather details for specific locations. When responding:
      - Always ask for a location if none is provided
      - If giving a location with multiple parts (e.g. "New York, NY"), use the most relevant part (e.g. "New York")
      - Include relevant details like humidity, wind conditions, and precipitation
      - Keep responses concise but informative

      Use the weatherTool to fetch current weather data.
`,
+  model: bedrock('anthropic.claude-3-5-sonnet-20240620-v1:0'),
  tools: { weatherTool },
});

```

mastraの開発サーバーの起動

```bash
> npm run dev

INFO [2025-03-18 23:51:33.248 +0900] (BUNDLER - Dev): Starting watcher...
INFO [2025-03-18 23:51:33.430 +0900] (BUNDLER - Dev): Bundling finished, starting server...
INFO [2025-03-18 23:51:33.433 +0900] (Mastra CLI): [Mastra Dev] - Starting server...
INFO [2025-03-18 23:51:34.177 +0900] (Mastra): 🦄 Mastra API running on port 4111/api
INFO [2025-03-18 23:51:34.178 +0900] (Mastra): 📚 Open API documentation available at http://localhost:4111/openapi.json
INFO [2025-03-18 23:51:34.179 +0900] (Mastra): 🧪 Swagger UI available at http://localhost:4111/swagger-ui
INFO [2025-03-18 23:51:34.179 +0900] (Mastra): 👨‍💻 Playground available at http://localhost:4111/
```

サーバー起動後、`http://localhost:4111/`でチャット画面にアクセスできます。
大阪の天気を尋ねてみると、いい感じの回答してくれました。


![81E99A0B-3B0F-46F2-A072-09D488CDE4D0.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320164/8aa7da3f-2c29-4db3-80fe-0abab6dbd232.jpeg)


バックグラウンドでは`http://localhost:4111/api/agents/weatherAgent/stream`というAPIを呼び出しています。
`http://localhost:4111/swagger-ui`でAPIドキュメントを確認できます。

![2CE34695-7983-467C-8776-EC04A938EC9E.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320164/8f62a02d-01ce-4836-8878-2e9ebb089d03.jpeg)


## Langfuseによるトレース管理

チャット画面でもトレース内容を確認できますが、Langfuseを使うとより効率的に管理できます。

![6D68745F-D06A-4950-A7FD-D3AE6E50A311.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320164/a7c3f194-4e3c-4247-9c84-fad2eed3eb3c.jpeg)

Langfuseの詳細については、以下の記事を参照してください：

https://qiita.com/minorun365/items/9551634a67001cff4073


```bash
> npm install langfuse-vercel
```

```diff_typescript:src/mastra/index.ts
import { Mastra } from "@mastra/core/mastra";
import { createLogger } from "@mastra/core/logger";

import { weatherAgent } from "./agents";
+ import { LangfuseExporter } from "langfuse-vercel";

export const mastra = new Mastra({
  agents: { weatherAgent },
  logger: createLogger({
    name: "Mastra",
    level: "info",
  }),
+  telemetry: {
+    serviceName: "ai",
+    enabled: true,
+    export: {
+      type: "custom",
+      exporter: new LangfuseExporter({
+        publicKey: "pk-lf-xxxxxx",
+        secretKey: "sk-lf-xxxxxx",
+        baseUrl: "https://cloud.langfuse.com",
+      }),
+    },
  },
});
```

再度サーバーを起動して天気を尋ねると、Langfuseダッシュボードでトレース内容を確認できるようになります。

![E70C3581-10AF-49A1-A62C-20587D430375.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320164/17f9854e-983f-4662-9308-33915ae23951.jpeg)

## 最後

TypeScriptで一貫して開発している私にとって、Langfuseへのトレース情報送信がこれほど簡単なのは大変助かります。`@aws-sdk/client-bedrock-runtime`では、多くの手動設定が必要で面倒でした。

Amazon Bedrockユーザーにとって唯一の懸念は認証方法です。AI SDK公式ドキュメントにはIAMユーザー認証情報の使用方法しか記載されていません。もしデプロイ先でリソースロールの権限を使ってAmazon Bedrockの機能を利用できるなら非常に便利です。検証結果は別の記事で報告する予定です。