はじめに:
今回「習慣が人間を作る」という仮説のもとアプリケーション「Routune Hub」を作成しました。

(※公開はしておりません)
その過程でMastraというAIエージェントフレームワークに未来を感じましたので記事を書きました。
Routune Hubの概要
Routune Hubは、公開されたRoutine(習慣)をAIによるカスタマイズ(Routune = Routine + tune)をもとにGoogleカレンダーに反映できる習慣設計アプリです。
Routune Hubの主な機能
- Routineの作成 / 公開 / 検索 / Clone
- AIプレビュー(ルーチン解釈・衝突検出・最適化案・将来コメント)
- カレンダー適用(期間指定 → プレビュー → 確認して反映)
- 「Routune」(文献 + ユーザー設定に基づくカスタマイズ)と手動編集の併用
技術スタック
- TypeScript / Next.js 16 / shadcn/ui
- Vitest / Storybook
- Mastra / Langfuse
- AWS Bedrock / DynamoDB / ECS Fargate
- Terraform / GitHub Actions
1. Mastraとは(超ざっくり)
Mastraは AIワークフローの設計・運用をまとめて扱える土台です。
- ワークフロー(複数AIステップの統合)
- エージェント(役割を分離)
- プロンプトや実行の整理がしやすい
例えるなら:
「LLMに名刺と上司と段取り表を渡すフレームワーク」
AIエージェントを扱うフレームワークではPython向けのものが多いですが、MastraはTypeScriptで書くことができます。
そのため、Next.jsのバックエンド(Server Actions / API Routes)にMastraを組み込むことが可能です。
2. MastraのAgentって何?
Mastraの Agent は、AIエージェントを作るための中心クラスです。
大事なのは「行動をどう制御するか」が設定で明確になること。
Agentの特徴(ざっくり)
- エージェントの基本クラスとして機能
- 応答生成・ストリーミングなども扱える
- 代表的な設定例
-
name: エージェントID -
description: 役割 -
instructions: 方針(静的 or 動的) -
model: 使用モデル
-
これにより、
「このAIは何者で、どこまでやるか」
がコード上で明確にできます。
3. ワークフロー設計(全体像)
Routune Hubでは、AIを 分業 させています。
「AIが全部やる」は危険なので、役割分割が基本です。
図で見るワークフロー
4. ここからコード例(概念コード)
注意: 実APIの詳細はMastra公式ドキュメントを参照してください。
ここでは「設計のイメージ」が伝わるように擬似コードで書いています。
4.1 Input / Output を制御する(型で暴走を止める)
const ProfileInput = z.object({
priorities: z.array(z.string()),
constraints: z.array(z.string())
});
const ProfileOutput = z.object({
summary: z.string(),
risks: z.array(z.string())
});
const profileAgent = defineAgent({
name: 'profile-agent',
input: ProfileInput,
output: ProfileOutput,
instructions: ({ input }) =>
`ユーザー制約を要約し、リスクを列挙してください: ${JSON.stringify(input)}`
});
const result = await profileAgent.run({
priorities: ['集中時間を守る'],
constraints: ['夜は作業しない']
});
ポイント
- 入力/出力の形を固定することで
「AIが意味不明な出力を返す」問題を減らせる
4.2 Tool を持たせる(AIに“使える道具”を渡す)
const searchTool = defineTool({
name: 'search-literature',
description: '文献検索を行う',
input: z.object({ query: z.string() }),
execute: async ({ query }) => searchPapers(query)
});
const evidenceAgent = defineAgent({
name: 'evidence-agent',
tools: [searchTool],
instructions: '目的に合う文献を探して要約する'
});
ポイント
- 「検索」「DB参照」などは Tool に分離
- AIが勝手に妄想するより安全
4.3 Agentを繋いでWorkflowにする
const routineWorkflow = defineWorkflow({
steps: [
profileAgent,
routineInterpreter,
conflictAgent,
optimizationAgent,
futureSimulationAgent
]
});
const output = await routineWorkflow.run({
routine,
user,
calendarWindow
});
ポイント
- 分業構成で原因特定が簡単
- 1つ壊れても全体が崩壊しにくい
5. Mastraを使うメリット
5.1 分割しやすい = 壊れた場所が分かる
「AIに全部やらせる」のは一見楽。
でも 故障箇所が特定できない ので、運用不能になります。
「AIが壊れているのか、仕様が曖昧なのか、人生が悪いのか分からない」
Mastraなら、役割ごとに整理できるので安心です。
5.2 入出力が決まっている = 連携が壊れにくい
Agentの入出力が明確なので、
「前の出力が次の入力にならない」問題が起きにくいです。
また、指示や形式を固定化しやすいので、
フォーマット崩壊(ハルシネーション)を抑えやすいのも利点です。
5.3 フローの柔軟性が高い
このアプリでは直列フローだけを使っていますが、
Mastraは以下のような設計も可能です。
- 条件分岐(条件が満たされた場合のみ次へ)
- 同じフローを繰り返す(改善サイクル)
- 人間の承認を待つステップを挟む
「AIの都合」ではなく「運用の都合」に合わせて組めるのが強い。
6. 詳細ドキュメント(公式参照)
Mastra: https://mastra.ai/
Agentリファレンス: https://mastra.ai/en/reference/agents/agent
まとめ:MastraはAI Agent制御の要
- Input / Output 制御で暴走を減らせる
- Tool分離で妄想を減らせる
- Workflow分割で原因特定が速くなる