statelyai/agent
Create state-machine-powered LLM agents using XState
Stately Agent – 安全なステートマシン駆動型AIエージェント
これは何か
- XStateステートマシンとしてLLM搭載エージェントを構築できるTypeScript/JavaScriptライブラリです。マシンが制御フローを所有し、言語モデルはマシンが検証するイベントを提案するだけです。
なぜ重要なのか
- すべての可能な遷移がコードで定義されガードされているため、エージェントが無効なアクションを実行できないことを保証します。
- ライブAPIキーがなくても、エージェントを決定的で、検査可能で、再開可能で、テスト可能にします。
- あらゆるJavaScriptランタイム(Node、Vercel、ブラウザ)で動作し、Vercel AI SDK、OpenAI SDK、またはTanStack AIと組み合わせて使用できます。
コアコンセプト
| コンセプト | 機能 |
|---|---|
| マシン定義 | XStateを使用して、エージェントの状態、ガード、型付きリクエストを記述します。 |
| モデル提案 | LLMはイベント(例:AUTO_REFUND)を生成するように求められます。 |
| ガード検証 | ステートマシンはイベントをガードに対してチェックします。不正なイベントは拒否され、モデルに再試行を求めます。 |
| エグゼキューター | 選択したAIプロバイダーを呼び出すプレーンな関数(decide、generateTextなど)。これらはライブラリに組み込まれておらず、ホストが提供します。 |
| 環境とポリシー | ビジネスルールはTypeScriptコード(environment)として存在します。JSONエンコードされたポリシーはモデルが編集できますが、プロモーション前にverifyAgentConfigでゲートされます。 |
| 永続性と耐久性 | XStateのスナップショットAPIを使用します。スナップショットはどこにでも保存できます(ファイル、データベース、デュラブルオブジェクト)。 |
クイックスタート(返金リクエストの例)
import { runAgent, setupAgent } from "@statelyai/agent";
import { z } from "zod";
const agentSetup = setupAgent({
context: z.object({ request: z.string(), amount: z.number() }),
input: z.object({ request: z.string(), amount: z.number() }),
output: z.object({ outcome: z.enum(["refunded", "review"]) }),
events: {
AUTO_REFUND: {},
REVIEW: z.object({ reason: z.string() })
}
});
const refundMachine = agentSetup.createMachine({
context: ({ input }) => input,
initial: "deciding",
states: {
deciding: {
invoke: { src: "agent.decide", input: ({ context }) => ({
model: "fast",
system: "Choose AUTO_REFUND for eligible requests. Otherwise choose REVIEW.",
prompt: `${context.request}\nAmount: $${context.amount}`,
allowedEvents: ["AUTO_REFUND", "REVIEW"]
}) },
on: {
AUTO_REFUND: ({ context }) =>
context.amount <= 100 ? { target: "refunded" } : undefined,
REVIEW: { target: "review" }
}
},
refunded: { type: "final", output: () => ({ outcome: "refunded" }) },
review: { type: "final", output: () => ({ outcome: "review" }) }
}
});
// モックエグゼキューター – APIキー不要
const result = await runAgent(refundMachine, {
input: { request: "I was charged twice", amount: 75 },
executors: { decide: async () => ({ event: { type: "AUTO_REFUND" } }) }
});
if (result.status === "done") console.log(result.output); // → { outcome: 'refunded' }
モデルはAUTO_REFUNDまたはREVIEWのみを発行できます。AUTO_REFUNDのガードが100ドルの制限を強制するため、不正な選択は自動的に拒否されます。
インストール
# コアライブラリ + XState (alpha) + Zod スキーマ検証用
pnpm add @statelyai/agent@alpha xstate@6.0.0-alpha.64 zod
# オプションのAI‑SDKエグゼキューター (Vercel AI SDK)
pnpm add ai@^7 @ai-sdk/openai@^4
# または生のOpenAI SDKエグゼキューター
pnpm add openai
# またはTanStack AIエグゼキューター
pnpm add @tanstack/ai @tanstack/ai-openai
Node 22.18+が必要です。
動作の仕組み(アーキテクチャ)
flowchart LR
M[エージェントマシン<br/>状態・ガード・リクエスト] -->|リクエスト| R[runAgent]
R -->|エグゼキューター呼び出し| E[ホストエグゼキューター<br/>generateText・streamText・decide]
E -->|API呼び出し| L[LLMプロバイダー]
L -->|結果| E
E -->|結果| R
R -->|イベント/出力| M
- マシンは、エージェントが何をできるかを定義します。
runAgentはマシンを呼び出し、制御をエグゼキューターに委ねます。- エグゼキューターは選択したLLM(AI SDK、OpenAI SDKなど)を呼び出します。
- LLMはイベントを返します。マシンはガードに対して検証します。
- 有効な場合、マシンは遷移します。そうでなければモデルに再試行を求めます。
主な機能(READMEに記載)
- 型付き契約 –
zodスキーマでコンテキスト、入力、出力、イベントを定義し、コンパイル時の安全性を確保。 - モデル非依存 – エグゼキューターを介して任意のプロバイダーをプラグイン可能。コアはAI SDKをインポートしません。
- JSONポリシー – モデルがJSONポリシーを書き換えられますが、
verifyAgentConfigがホールドアウトテストのゲインに基づいてプロモーションをゲートします。 - デュラブルスナップショット – XStateのネイティブスナップショット形式を使用して、エージェントをどこにでも永続化・復元できます。
- 組み込みパターン – ReAct、プラン・アンド・エグゼキュート、RAG、スーパーバイザーなど、単一ファイルのテンプレートとしてすぐに使用可能。
- プロバイダーなしでのテスト –
MockLanguageModelV3を使用すると、オフラインでエージェントを単体テストできます。 - 可観測性と予算 – ドキュメントにはログ、使用状況追跡、予算強制のフックが含まれています。
典型的なユースケース
- カスタマーサービスボット – 規制上の制限(返金上限、データプライバシールールなど)を遵守する必要があるもの。
- ワークフロー自動化 – 各ステップが検証された状態遷移であるもの(承認フロー、チケットトリアージ)。
- ツール呼び出しエージェント – 実行前にツール引数の厳格な検証が必要なもの。
- 自己改善エージェント – ポリシー更新を提案でき、デプロイ前に自動的に審査されるもの。
- あらゆるスタックへの埋め込み – サーバーレス関数から長時間実行されるデュラブルオブジェクトまで、制御フローはすべてステートマシン内にあるため。
詳細情報
- ドキュメント: https://stately.ai/docs/packages/agent
- 例:
examples/フォルダ(二十の質問、カメレオン、チケットトリアージなど) - LangGraphとの比較:
docs/langgraph-comparison.md - パターンライブラリ:
docs/patterns.md
TL;DR
Stately Agentを使用すると、LLM駆動エージェントを正式なステートマシンとして記述できます。モデルはイベントを提案するだけで、マシンがビジネスルールを強制するため、エージェントは安全でテスト可能で、あらゆるJavaScript環境に移植可能です。
関連
- プロジェクト
- Dispatch
- プロジェクト
- プロジェクト
- プロジェクト