---
title: "オンチェーンAIエージェントのアーキテクチャ:5つの構築パターン"
description: "オンチェーンAIエージェントの5つの構築パターンを、それぞれの実装例とともに紹介:ウォレット監視、イベント駆動リアクター、ポートフォリオリバランサー、検知と実行を分離したマルチエージェント構成、そして安全なメインネット前テスト。"
---

# オンチェーンAIエージェントのアーキテクチャ:5つの構築パターン

<ImageBlock
  src="https://media.alchemy.com/blog/onchain-ai-agent-architectures-hero.png"
  alt="オンチェーンAIエージェントアーキテクチャガイドのカバーイラスト"
  width={1920}
  height={900}
  priority
/>

オンチェーンの状態を読み書きするAIエージェントは、デモから本番運用へと移行した。モデルは推論でき、エージェントウォレットはスコープ付き権限のもとで署名でき、インフラはイベントがオンチェーンに反映されてから数秒でエージェントにプッシュできる。それでも構築がうまくいかないのはアーキテクチャの部分だ。エージェントが本来購読できるイベントをポーリングしていたり、信頼できない入力を読み取るのと同じプロセスで署名権限を保持していたり、実資金を使ってメインネットで学習していたりする。

オンチェーンエージェントとは、観察し、判断し、行動するループである。本番のエージェントはこのループを5つの反復パターンに配置しており、それぞれについて以下に実例を示す。[オンチェーンエージェント構築ガイド](https://www.alchemy.com/blog/how-to-build-onchain-agents)では、これらすべての基盤となるプリミティブ（ウォレット、決済レール、データフィード）を扱っている。このページのテーマは、それらのプリミティブをどう組み合わせるかである。

<EmbeddedTable
  table={{
    columns: [
      { key: "pattern", width: 170, title: "Pattern", dataType: "object" },
      { key: "trigger", width: 200, title: "Trigger", dataType: "object" },
      {
        key: "reads",
        width: 180,
        title: "The agent reads",
        dataType: "object",
      },
      { key: "does", width: 180, title: "The agent does", dataType: "object" },
      {
        key: "when",
        width: 230,
        title: "Reach for it when",
        dataType: "object",
      },
    ],
    data: [
      {
        pattern: { title: "Wallet watcher", tooltip: "", icon: "" },
        trigger: {
          title: "A transfer hits a watched address",
          tooltip: "",
          icon: "",
        },
        reads: { title: "Webhook or WebSocket events", tooltip: "", icon: "" },
        does: { title: "Wakes and evaluates", tooltip: "", icon: "" },
        when: {
          title: "You track deposits, whales, or counterparties",
          tooltip: "",
          icon: "",
        },
        id: 0,
      },
      {
        pattern: { title: "Event-driven reactor", tooltip: "", icon: "" },
        trigger: { title: "A contract emits an event", tooltip: "", icon: "" },
        reads: { title: "Filtered logs", tooltip: "", icon: "" },
        does: { title: "Responds with a transaction", tooltip: "", icon: "" },
        when: {
          title: "Protocol state changes drive your strategy",
          tooltip: "",
          icon: "",
        },
        id: 1,
      },
      {
        pattern: { title: "Portfolio rebalancer", tooltip: "", icon: "" },
        trigger: {
          title: "Allocation drifts past a band",
          tooltip: "",
          icon: "",
        },
        reads: { title: "Balances and prices", tooltip: "", icon: "" },
        does: { title: "Proposes a swap", tooltip: "", icon: "" },
        when: {
          title: "You hold target weights and want them enforced",
          tooltip: "",
          icon: "",
        },
        id: 2,
      },
      {
        pattern: { title: "Detect-then-execute split", tooltip: "", icon: "" },
        trigger: {
          title: "The detector emits a signal",
          tooltip: "",
          icon: "",
        },
        reads: {
          title: "Everything, while signing nothing",
          tooltip: "",
          icon: "",
        },
        does: {
          title: "The executor verifies, then signs",
          tooltip: "",
          icon: "",
        },
        when: {
          title: "Untrusted input meets real money",
          tooltip: "",
          icon: "",
        },
        id: 3,
      },
      {
        pattern: { title: "Pre-mainnet testing", tooltip: "", icon: "" },
        trigger: { title: "Every new capability", tooltip: "", icon: "" },
        reads: { title: "Testnets and dry-runs", tooltip: "", icon: "" },
        does: { title: "Promotes the agent in stages", tooltip: "", icon: "" },
        when: {
          title: "Always, before the other four go live",
          tooltip: "",
          icon: "",
        },
        id: 4,
      },
    ],
  }}
/>

## リアルタイムのウォレット監視エージェントはどう構築するか

監視したいアドレスをwebhookに登録し、チェーン側からデータが届く形にする。ループでバランスをポーリングするのは計算資源を消費するうえ、それでも瞬間を捉え損ねる。プッシュ型のパイプラインなら転送がオンチェーンに反映されてから数秒で届き、それこそがウォッチャーの仕事の全てである。

例えば、あるファンドの取引相手のウォレットを追跡し、USDCの大口移動があればフラグを立てるエージェントを考える。Alchemyでは、単一の[Address Activity webhook](https://www.alchemy.com/webhooks)でネイティブ転送、ERC-20、ERC-721、ERC-1155の転送を[最大100,000アドレス](https://www.alchemy.com/docs/reference/webhook-types)分カバーできるため、1つのwebhookで取引相手リスト全体を監視できる。エージェントを常駐プロセスとして動かしており、パブリックURLを公開したくない場合は、[WebSocket subscriptions](https://www.alchemy.com/docs/reference/subscription-api)がインプロセスで同じ役割を果たす。`alchemy_minedTransactions`でsubscribeすれば、対象アドレスに絞られた確認済みトランザクションがそのまま得られ、ログのパースは不要である。Solanaでは、[Yellowstone gRPC streaming](https://www.alchemy.com/solana-grpc)が同じ役割をTBあたり75ドルで、切れ目のない再接続とともに果たす。どのトランスポートが適しているか迷う場合は、[webhooks vs WebSockets vs gRPCの比較](https://www.alchemy.com/overviews/webhooks-vs-websockets-vs-grpc)で詳しく線引きしている。

ハンドラ自体はほぼ何もしないようにする。配信がAlchemyから来たことを検証し、重複を排除し、イベントをエージェントの判断ステップに渡し、それから初めて確認応答を返す。

<CodeSnippet
  language="typescript"
  code={`import express from "express";
import { createHmac, timingSafeEqual } from "node:crypto";
const SIGNING_KEY = process.env.ALCHEMY_WEBHOOK_SIGNING_KEY!; // from the webhook's dashboard settings
const USDC = "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"; // canonical USDC contract on Ethereum mainnet
const seen = new Set<string>();
function remember(key: string) {
  seen.add(key);
  if (seen.size > 10_000) seen.delete(seen.values().next().value!); // bound the set; only recent deliveries repeat
}
function wake(signal: unknown) {
  // The agent's decide step starts here. Queue the signal;
  // don't run model reasoning inside the request handler.
}
const app = express();
app.use(
  express.json({
    verify: (req, _res, buf) => {
      (req as { rawBody?: Buffer }).rawBody = buf; // keep the raw bytes for the HMAC check
    },
  })
);
app.post("/hooks/address-activity", (req, res) => {
  const sig = Buffer.from(String(req.headers["x-alchemy-signature"] ?? ""), "hex");
  const expected = createHmac("sha256", SIGNING_KEY)
    .update((req as { rawBody?: Buffer }).rawBody ?? Buffer.alloc(0))
    .digest();
  if (sig.length !== expected.length || !timingSafeEqual(sig, expected)) {
    return res.sendStatus(401); // not signed with our key; never process it
  }
  for (const transfer of req.body.event.activity) {
    const key = \`\${transfer.hash}:\${transfer.log?.logIndex ?? "native"}\`; // one tx can carry several transfers
    if (seen.has(key)) continue; // repeat delivery, already handled
    if (transfer.rawContract?.address?.toLowerCase() === USDC && transfer.value > 50_000) {
      wake({ kind: "large-transfer", ...transfer }); // if this throws, the key stays unmarked and the retry redelivers
    }
    remember(key); // mark handled only after the handoff succeeded
  }
  res.sendStatus(200); // ack only after queueing: a crash above gets retried, not lost
});
app.listen(8080);`}
/>

このパターンを本番で信頼できるものにする習慣は3つある。配信を信頼する前にHMAC署名を検証すること。これがないと、エンドポイントURLを知った者が誰でも偽の転送をPOSTしてエージェントを操作できてしまう。トークンはシンボルではなく必ずコントラクトアドレスで照合すること。誰でもUSDCを名乗るトークンをデプロイし、監視対象アドレスに送りつけられるからである。そして配信は少なくとも1回（at-least-once）であるため、重複排除の記録は省略できない。インメモリのセットは単一の常駐プロセスでは機能するが、再起動やレプリカを伴うサービスでは、Redisのキーやデータベースの行のように共有され永続的な場所にその記録を置く必要がある。トレーディングエージェントにとって、重複した起動は重複したトランザクションを意味するからだ。機械的なフィルタリングはハンドラの役割であり、モデルはそこに関与させない。転送ごとにLLM呼び出しを行えば、その転送を配信したインフラよりもコストがかさむことになる。

## AIエージェントにスマートコントラクトのイベントを監視させ、自動的に反応させるにはどうすればよいか

コントラクトのログをsubscribeし、重要な1つか2つのイベントに絞り込み、ハンドラを冪等にする。コントラクトイベントはエージェントが得られる最もクリーンなトリガーである。コントラクトが何が起きたか、どの順序で起きたかを正確に述べてくれるからだ。

Alchemyではこれを2つの手段でカバーしている。[Custom webhooks](https://www.alchemy.com/docs/reference/custom-webhooks-quickstart)はGraphQLフィルタを受け取るため、コントラクトアドレスとイベントトピックで照合し、要求したログだけを受け取ることができる。これはサーバーレスなリアクターに適している。長時間稼働するエージェントには、WebSocketのログsubscriptionがすべてを1つのプロセス内に保つ。以下は、Uniswap v3プールを監視するリアクターの例で、単一のスワップが価格を動かした瞬間を検知するためにトレーディングエージェントが使う類のフィードである。

<CodeSnippet
  language="typescript"
  code={`import { createPublicClient, webSocket, parseAbiItem } from "viem";
import { mainnet } from "viem/chains";
function react(args: unknown) {
  // Decide step: is this swap big enough to act on?
}
const client = createPublicClient({
  chain: mainnet,
  transport: webSocket("wss://eth-mainnet.g.alchemy.com/v2/YOUR_API_KEY"),
});
client.watchEvent({
  address: "0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640", // USDC/WETH 0.05% pool
  event: parseAbiItem(
    "event Swap(address indexed sender, address indexed recipient, int256 amount0, int256 amount1, uint160 sqrtPriceX96, uint128 liquidity, int24 tick)"
  ),
  onLogs: (logs) => {
    for (const log of logs) {
      if (log.removed) continue; // reorg removal notice; irreversible actions also need the confirmation-depth rule below
      react(log.args);
    }
  },
});`}
/>

`log.removed`のチェックは見た目以上に重要である。チェーンは再編成（reorg）することがあり、エージェントがすでに対応したログが数ブロック後に正規チェーンから消えることがある。冪等なハンドラと、確認深度のルール（不可逆な行動の前に数ブロック待つ）の組み合わせが標準的な防御策である。リアクターのそれ以外の規律はウォッチャーと同じである。subscriptionのフィルタが安価な除外処理を担い、モデルはそれを通過したイベントだけを目にする。

## DeFiのポートフォリオリバランシングエージェントを構築するには何が必要か

必要なのは4つ、現在の残高、現在の価格、乖離ルール、スワップ経路である。エージェントは最初の2つを読み取り、3つ目を確認し、ルールに触れた時だけ4つ目に手を付ける。

WETH、USDC、WBTCを50/30/20の比率で保有するトレジャリーエージェントを例にとる。残高は[Portfolio API](https://www.alchemy.com/docs/reference/portfolio-apis)から取得する。これは複数ネットワークにまたがるウォレットのトークンを1回のリクエストで返してくれるため、チェーンごとの呼び出しをファンアウトさせる必要がない。価格は[Prices API](https://www.alchemy.com/docs/reference/prices-api-quickstart)から取得する。乖離ルールは単純な算術である。よくある出発点は、各目標比率の周囲に5パーセントポイントのバンドを設けることである。これはタイマーで確認する。乖離のほとんどはトークンの移動ではなく価格の変動によって生じ、価格変動はそれに反応すべきオンチェーンイベントを何も生まないからである。ウォッチャー（パターン1）が報告する転送は、入出金が発生した瞬間を捉える補助的なトリガーとなる。

<CodeSnippet
  language="typescript"
  code={`const TARGET = { WETH: 0.5, USDC: 0.3, WBTC: 0.2 } as const;
const BAND = 0.05; // rebalance when a weight drifts 5 points from target
const WALLET = "0xYourTreasuryWallet"; // the wallet the agent manages
const res = await fetch(
  \`https://api.g.alchemy.com/data/v1/\${process.env.ALCHEMY_API_KEY}/assets/tokens/by-address\`,
  {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      addresses: [{ address: WALLET, networks: ["eth-mainnet"] }],
    }),
  }
);
const { data } = await res.json();
// Price each balance with the Prices API, sum to a total, then:
for (const [symbol, target] of Object.entries(TARGET)) {
  const drift = weightOf(symbol, data) - target; // weightOf: your portfolio math
  if (Math.abs(drift) > BAND) {
    propose({ symbol, drift }); // propose: log it and request approval; never swap directly
  }
}`}
/>

実行側は生の秘密鍵を保持すべきではない。[スコープ付きエージェントウォレット](https://www.alchemy.com/blog/agent-wallets-alchemy-cli)を使えば、鍵はカストディ内に留まり、セッションには付与した権限のみが伴う。ERC-20を使うには、スワップの前にルーターに対するallowanceが必要になる。毎回正確な量だけをapproveすれば、トランザクションが1回余分にかかる代わりに、攻撃者が引き出せる恒常的なallowanceを残さずに済む。

<CodeSnippet
  language="bash"
  code={`# before each swap: let the router from your quote spend exactly this swap's WETH
alchemy evm approve 0xRouterFromQuote --token-address 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 --amount 0.4 -n eth-mainnet
# swap WETH into USDC (Ethereum mainnet contract addresses)
alchemy evm swap execute \\
  --from 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 \\
  --to 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 \\
  --amount 0.4 --slippage 0.5 -n eth-mainnet \\
  --signer session --json --no-interactive`}
/>

このループの形に注目してほしい。エージェントが提案し、別の何かが承認する。初期の段階ではその「何か」はあなた自身である。後には、サイズ、スリッページ、資産の許可リストに関するポリシーチェックがそれを担うことができる。[DeFi AIエージェント概要](https://www.alchemy.com/overviews/defi-ai-agents)では、この分離が本番のDeFiエージェント全体で標準になっている理由を扱っている。また、[gas sponsorship](https://www.alchemy.com/gasless-transactions)は、あなたが管理するポリシーのもとで手数料を支払うことで最後の運用上の手間を取り除き、エージェントはガス残高を管理する必要がなくなる。

## 検知と実行を分離したマルチエージェントシステムに最適なアーキテクチャとは

エージェントを作業量ではなく権限で分割する。検知役はすべてを読み取れるが何も署名できない。実行役はトランザクションに署名するが、自ら再検証していないものは何も信じない。

これはアナリストとトレーダーの関係と考えるとよい。アナリストは一日中市場を監視し、誰とでも話すことができる。トレーダーはアナリストの推奨を受け取り、それを検証し、口座にアクセスできるのはトレーダーだけである。

このパターンの一般的な捉え方は、汎用エージェントツール群に由来する。そこではプランナーモデルがステップを生成し、executorエージェントがツールを実行する。それは主にオーケストレーションの話である。オンチェーンでは、この分離が複雑さに見合う理由はもっと厳しい――カストディの問題である。検知役は一日中、信頼できない入力を消費する。メンプールのノイズ、サードパーティのAPI、イベントストリーム、時にはソーシャルフィードもある。そのどれもがプロンプトインジェクションを運んでくる可能性がある。もし敵対的な入力を読み取るプロセスが、署名権限を持つプロセスと同一であれば、1つの汚染されたメッセージが署名済みトランザクションになりかねない。両者を分離すれば、乗っ取られた検知役ができる最悪のことは、実行役に捨てられる悪い提案をすることだけになる。

検知役はパターン1と2から構築され、ポーリングループではなくプッシュ型インフラに接続される。シグナルをキュー経由で発行し、そのキューは監査ログを兼ねる。シグナルの契約は小さく検証可能に保つ。

<CodeSnippet
  language="json"
  code={`{
  "kind": "arb-opportunity",
  "pair": "WETH/USDC",
  "evidence": { "txHash": "0x…", "block": 23411005 },
  "proposal": { "action": "swap", "from": "WETH", "to": "USDC", "amount": "0.4" },
  "observedAt": "2026-09-05T09:14:03Z",
  "expiresAt": "2026-09-05T09:14:33Z"
}`}
/>

実行役は、シグナルに基づいて行動する前に3つのルールを適用する。

- **証拠をオンチェーンで再検証する。** 検知役の要約を信じるのではなく、参照されたトランザクション自体を自分で読む。検知役の仕事は気づくことであり、証明することは実行役の仕事である。
- **有効期限を強制する。** 攻撃者がループにいなくても、検知・実行システムが古くなった機会に基づいて行動すれば損失につながる。
- **ウォレット層で支出上限を設ける。** シグナルごと、日ごとの予算は[スコープ付きセッション](https://www.alchemy.com/blog/agent-wallets-alchemy-cli)に置き、動作がおかしいと感じた瞬間にダッシュボードから取り消すことができる。

ツール側では、実行役に必要なのは、検証用のRPC接続と署名を行う手段の2つだけである。より多くを消費するのは検知役の側であり、これをインデックス済みのデータ（履歴には[Transfers API](https://www.alchemy.com/docs/reference/transfers-api-quickstart)、状態にはPortfolio API）と組み合わせることで、トークン消費を推論に振り向け、生のチェーンデータのデコードに費やさずに済む。[自律エージェント向けブロックチェーンAPI比較](https://www.alchemy.com/overviews/best-blockchain-apis-for-autonomous-onchain-agents)では、この選択のインフラ面を扱っている。

## メインネット移行前にAIエージェントのトランザクションを安全にテストするにはどうすればよいか

エージェントと実資金の間に4つのゲートを設ける。すべてのトランザクションをドライランする、鍵が使える金額に上限を設ける、テストネットでループ全体をリハーサルする、資金を動かす操作には人間の承認を残す、である。

- **まずドライランする。** Alchemy CLIは署名やブロードキャストを行わずに任意のsendをプレビューできる（`alchemy evm send 0xRecipient 0.4 --dry-run`）。コード上では、viemの`simulateContract`が、実際のメインネット状態に対してコントラクト呼び出しを検証でき、送信は行わない。これにより、古びたフィクスチャではなく実際の価格と実際のプールの深さを使ったリハーサルになる。
- **鍵に上限を設ける。** スコープ付きセッションウォレットは設定したスケジュールで失効し、承認された範囲内のことしか実行できない。[gas sponsorship policies](https://www.alchemy.com/gasless-transactions)は、手数料層に許可リストと支出上限を追加する。上限付きの鍵は、最悪の場合のバグをアカウント全損から有限の損失に変える。
- **テストネットでリハーサルする。** 同じコードをSepoliaやBase Sepoliaのエンドポイントに向け、[testnet faucets](https://www.alchemy.com/faucets)からエージェントに資金を供給する。リハーサルと本番でコードが変わってしまえば、そのリハーサルには意味がない。ネットワーク名は設定に置き、それ以外は何も変えない。
- **資金を動かす操作にはゲートをかける。** エージェントが未成熟なうちは、すべてのsend、swap、approveが明示的な承認を待つ。ほとんどのチームは、監査ログがエージェントの挙動について実績を積むにつれて、一度に1つの操作タイプずつ、意図的にゲートを緩めていく。

これをうまく運用しているチームは、昇格をスイッチではなく段階的な連続として扱う。まずメインネットに対する読み取り専用、次にテストネットでの書き込み、次に上限付きのメインネット書き込み、そして最後にフル予算という順序である。各段階が、次の段階を正当化するログを生み出す。

## すでに存在する部品から始める

このページで扱ったパターンはすべて、今日利用できるインフラの上で動く。[Alchemy CLI](https://www.alchemy.com/agents)はウォレット、send、swap、webhook管理を1つのバイナリで扱い、エージェントは`--json --no-interactive`でそれを操作できる。ホスト型の[MCP server](https://www.alchemy.com/docs/alchemy-mcp-server)は、RPC、シミュレーション、データにまたがる168個のツールを公開しており、[Alchemy plugin for Claude Code](https://www.alchemy.com/blog/alchemy-claude-plugin-now-live)を使えばこの一式を1つのコマンドでインストールできる。契約も最低利用料もない無料枠から始めることができ、エージェントは自分自身のウォレットを使って[自らサインアップし](https://www.alchemy.com/blog/ai-agents-can-now-sign-up-for-alchemy)、USDCで支払うことすらできる。どのパターンから始めるにせよ、ループは変わらない。観察し、判断し、行動する。

## よくある質問

### 検知役が機会を見つけ、実行役がそれを実行するマルチエージェントシステムに最適なアーキテクチャは何か

権限で分割する。イベントストリームを読み取るが鍵を一切持たない検知役、小さく署名済みのシグナルを運ぶキュー、そしてシグナルごとにオンチェーンで再検証してから行動する実行役である。Alchemy上では、検知役はwebhookまたはWebSocket subscriptionで動作し、実行役は支出上限と即時取り消しを備えたスコープ付きエージェントウォレットで署名する。

### リアルタイムのウォレット監視エージェントに最適なインフラは何か

ポーリングではなくプッシュ型のイベント配信である。AlchemyのAddress Activity webhooksは1つのwebhookあたり最大100,000アドレスの転送を追跡し、WebSocket subscriptionsは対象アドレスに絞ったマイニング済みトランザクションをストリームし、Yellowstone gRPCはSolanaをカバーする。プッシュ型のパイプラインは、ポーリングループの遅延と計算コストなしに、転送がオンチェーンに反映されてから数秒でエージェントを起動させる。

### AIコーディングエージェントはウォレットの活動を監視するためにどのようなツールを使うべきか

Alchemy MCP serverは、RPC、トランザクション履歴、ポートフォリオデータをカバーする168個のツールをコーディングエージェントに提供し、Alchemy CLIはコマンドラインからwebhookを作成・管理する。ランタイム自体には、Address Activity webhookまたは`alchemy_minedTransactions` subscriptionがウォレットイベントを配信し、Transfers APIが履歴を補完する。

### DeFiのポートフォリオリバランシングエージェントを構築するには何が必要か

残高、価格、乖離ルール、スワップ経路である。Alchemy Portfolio APIは複数ネットワークの残高を1回の呼び出しで返し、Prices APIがそれを評価し、乖離チェック（一般には目標比率の周囲に5ポイントのバンド）が行動すべきタイミングを決める。実行はスコープ付きエージェントウォレットを通して行い、エージェントが提案しポリシーまたは人間が承認する形にする。

### AIエージェントにスマートコントラクトのイベントを監視させ、自動的に反応させるにはどうすればよいか

コントラクトのログをsubscribeし、一致したイベントをエージェントに渡す。Alchemyのcustom webhooksは配信前にGraphQLでコントラクトアドレスとイベントトピックによりフィルタリングでき、WebSocketのログsubscriptionはインプロセスで同じことを行う。ハンドラは冪等にし、reorgされたログはスキップし、モデルには機械的なフィルタを通過したイベントについてのみ推論させる。

### メインネット移行前にAIエージェントのトランザクションを安全にテストするにはどうすればよいか

ゲートを重ねる。Alchemy CLIのドライランフラグでトランザクションをプレビューし、`eth_call`ベースのシミュレーションで実際の状態に対してコントラクト呼び出しを検証し、スコープ付きセッションとgasポリシーの支出上限でエージェントのウォレットに上限を設け、Alchemyのfaucetsから資金を得てSepoliaやBase Sepoliaでリハーサルし、監査ログがより緩いゲートに値すると証明するまでは、資金を動かすすべての操作に人間の承認を残す。
