はじめに
AIエージェントが自律的に動き回るようになると、こんな問題が浮上してきます。
「このリクエストは、本当に人間が意図して動かしているのか?」
スパムBOTと人間が管理しているエージェントをサーバー側はどう区別すればいいのか。
例えば、エージェントに対してAPIのレート制限をかける場合、エージェントの場合はウォレットアドレスで区別するのが自然ですが、そのアドレスが実在する人間に紐づいているのかどうか分かりません。
World Agent Kitは、こんな問題を解決するための仕組みです。
World ID(人間性の証明)とx402を組み合わせることで、「このエージェントには裏に人間がいる」ことをHTTPレベルで検証可能にします。
World Agent Kitとは
World Agent Kitは、x402を拡張してエージェント認証を追加する仕組みです。
以下の2つを組み合わせて実現しています。
- x402: HTTP402を使ったエージェント向け決済プロトコル
- World ID + AgentBook: エージェントのウォレットアドレスを、World Appで検証された人間の署名IDに結びつけるレジストリ
つまりエージェントが「支払える」だけでなく「人間が動かしている」も同時に証明することができます。
World Agent Kitを使うことで例えば以下の課題を解決することができます
| 課題 | 従来 | World Agent Kit |
|---|---|---|
| ボット判定 | IPアドレス・User-Agent等で類推 | World IDによる人間性証明 |
| スパム対策 | レート制限(簡単に突破される) | 人間がバックにいるエージェントを優遇 |
| 支払い | 別途実装が必要 | x402と統合済み |
AgentBookへの登録とリクエスト検証
World Agent KitのコアはAgentBookというレジストリにあり、「事前の登録」と「リクエスト時の検証」の2フェーズで動きます。
3つのアクセスモード
サーバーは用途に応じて3つのアクセスモードを設定することができます。
| モード | 内容 | 典型的な用途 |
|---|---|---|
| Free | 登録済みの人間がバックにいるエージェントは常に無料 | 認証済みユーザーへの特典提供 |
| Free-trial | 最初のN回は無料、以降は通常のx402支払い | お試し無料枠の提供 |
| Discount | 最初のN回は設定した割引率を適用 | 人間がバックにいる場合の割引 |
AgentKitの統合
1. インストール
npm install @worldcoin/agentkit
2. エージェントをAgentBookに登録
npx @worldcoin/agentkit-cli register <agent-address>
CLIを実行すると、以下の3フェーズが自動で進みます。
- nonce取得: AgentBookから対象エージェントアドレスに対する次のnonceを取得
- World App署名フロー: World Appでの検証フローが起動
- 登録トランザクション送信: 署名済みデータをAgentBookに送信して登録
ウォレットが登録されると、AgentKitはリクエスト時に匿名の人間識別子に解決することができます。
3. フックベースのサーバー実装
Honoにx402ミドルウェアとAgentKitフックを追加
import { Hono } from 'hono'
import { serve } from '@hono/node-server'
import { HTTPFacilitatorClient } from '@x402/core/http'
import { ExactEvmScheme } from '@x402/evm/exact/server'
import {
paymentMiddlewareFromHTTPServer,
x402HTTPResourceServer,
x402ResourceServer,
} from '@x402/hono'
import {
agentkitResourceServerExtension,
createAgentBookVerifier,
createAgentkitHooks,
declareAgentkitExtension,
InMemoryAgentKitStorage,
} from '@worldcoin/agentkit'
const WORLD_CHAIN = 'eip155:480'
const BASE = "eip155:8453";
const WORLD_USDC = '0x79A02482A880bCE3F13e09Da970dC34db4CD24d1'
const payTo = '0xYourAddress'
const facilitatorClient = new HTTPFacilitatorClient({
url: 'https://x402-worldchain.vercel.app/facilitator',
})
const evmScheme = new ExactEvmScheme()
// Register a money parser to accept USDC payments on WorldChain.
.registerMoneyParser(async (amount, network) => {
if (network !== WORLD_CHAIN) return null
return {
amount: String(Math.round(amount * 1e6)),
asset: WORLD_USDC,
extra: { name: 'USD Coin', version: '2' },
}
})
const agentBook = createAgentBookVerifier({ network: 'world' })
const storage = new InMemoryAgentKitStorage()
const hooks = createAgentkitHooks({
agentBook,
storage,
mode: { type: 'free-trial', uses: 3 },
})
const resourceServer = new x402ResourceServer(facilitatorClient)
.register(WORLD_CHAIN, evmScheme)
.registerExtension(agentkitResourceServerExtension)
const routes = {
'GET /data': {
// Accept payments on both World Chain and Base
accepts: [
{
scheme: 'exact',
price: '$0.01',
network: WORLD_CHAIN,
payTo,
},
{
scheme: 'exact',
price: '$0.01',
network: BASE,
payTo,
},
],
extensions: declareAgentkitExtension({
statement: 'Verify your agent is backed by a real human',
mode: { type: 'free-trial', uses: 3 },
}),
},
}
const httpServer = new x402HTTPResourceServer(resourceServer, routes)
.onProtectedRequest(hooks.requestHook)
const app = new Hono()
app.use(paymentMiddlewareFromHTTPServer(httpServer))
app.get('/data', c => {
return c.json({ message: 'Protected content' })
})
serve({ fetch: app.fetch, port: 4021 })
4. ストレージ設定
free-trialモードで、人間がバックにいるエージェントがx402支払いフローになる前に3回の無料リクエストを受け取る場合
import type { AgentKitStorage } from '@worldcoin/agentkit'
class DatabaseAgentKitStorage implements AgentKitStorage {
async getUsageCount(endpoint: string, humanId: string) {
return db.getUsageCount(endpoint, humanId)
}
async incrementUsage(endpoint: string, humanId: string) {
await db.incrementUsage(endpoint, humanId)
}
async hasUsedNonce(nonce: string) {
return db.hasUsedNonce(nonce)
}
async recordNonce(nonce: string) {
await db.recordNonce(nonce)
}
}
const hooks = createAgentkitHooks({
agentBook,
storage: new DatabaseAgentKitStorage(),
mode: { type: 'free-trial', uses: 3 },
})
おわりに
AIエージェントが増殖する世界では、「人間が裏にいるのか」の証明がますます重要になってきます。
本格的にそんな世界になると、World IDという人間性の証明基盤を活用できるWorld Agent Kitが活躍するかもしれません。

