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
  1. マシンは、エージェントが何をできるかを定義します。
  2. runAgentはマシンを呼び出し、制御をエグゼキューターに委ねます。
  3. エグゼキューターは選択したLLM(AI SDK、OpenAI SDKなど)を呼び出します。
  4. LLMはイベントを返します。マシンはガードに対して検証します。
  5. 有効な場合、マシンは遷移します。そうでなければモデルに再試行を求めます。

主な機能(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
  • プロジェクト
  • プロジェクト
  • プロジェクト