stagehand-automation について
Stagehand v3 を基盤とするブラウザー自動化スキルです。自然言語での操作、構造化データの抽出、ページ状態の確認に対応し、DOM 変更時には要素の指定を調整できます。
主な機能
- 01自然言語によるブラウザー操作
- 02スキーマ検証付きデータ抽出
- 03ページ要素と状態の確認
- 04DOM 変更に応じた要素指定
- 05Playwright との併用
活用シーン
- 01UI 改修に強い E2E テストの作成
- 02ウェブサイトからの構造化情報抽出
- 03複雑なフォーム入力の自動化
- 04複数サイトにまたがるワークフローの実行
MCP 対応
Stagehand は MCP サーバーとして起動でき、Claude Desktop などの MCP 対応クライアントからブラウザーを操作できます。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ adaptationio/ skrillz --skill stagehand-automationインストール後、Claude Code で/stagehand-automationを入力して読み込まれたか確認します。
同梱ファイルreferences/api-reference.mdreferences/troubleshooting.md
詳細
Stagehand の自動化
概要
Stagehand v3 は、脆弱な従来型の自動化と、インテリジェントで自己修復する機能をつなぐ、最先端の AI ブラウザー自動化フレームワークです。Chrome DevTools Protocol(CDP)を基盤としており、v2 より 44% 高速で、Claude とシームレスに連携します。
主な革新点:DOM が変更されても、テストが壊れるのではなく、AI が適応します。
コア API:
act()- 自然言語でアクションを実行しますextract()- ページから構造化データを抽出しますobserve()- 要素とページの状態を特定します
クイックスタート(10 分)
1. Stagehand をインストールする
npm install @browserbase/stagehand zod
2. Claude API を設定する
# Add to .env
ANTHROPIC_API_KEY=your_api_key_here
3. 最初の自動化を作成する
import { Stagehand } from "@browserbase/stagehand";
import { z } from "zod";
async function main() {
const stagehand = new Stagehand({
env: "LOCAL",
modelName: "claude-sonnet-4-20250514",
modelClientOptions: {
apiKey: process.env.ANTHROPIC_API_KEY,
},
});
await stagehand.init();
await stagehand.page.goto("https://news.ycombinator.com");
// AI-powered action - survives UI changes!
await stagehand.act({ action: "click on the first story link" });
// Extract structured data
const data = await stagehand.extract({
instruction: "extract the story title and author",
schema: z.object({
title: z.string(),
author: z.string(),
}),
});
console.log(data);
await stagehand.close();
}
main();
4. 実行する
npx ts-node your-script.ts
コア API
act() - アクションを実行する
自然言語でアクションを実行します:
// Click elements
await stagehand.act({ action: "click the login button" });
// Fill forms
await stagehand.act({ action: "fill in the email field with '[email protected]'" });
await stagehand.act({ action: "enter password 'securepass123'" });
// Navigate
await stagehand.act({ action: "scroll down to the pricing section" });
await stagehand.act({ action: "click the 'Sign Up' button in the header" });
// Complex actions
await stagehand.act({
action: "select 'Premium' from the plan dropdown and click Continue"
});
自己修復:ボタン ID が #login-btn から #auth-signin に変わっても、Stagehand は自動的に適応します。
extract() - 構造化データを取得する
スキーマ検証を行いながらデータを抽出します:
import { z } from "zod";
// Simple extraction
const title = await stagehand.extract({
instruction: "get the main page title",
schema: z.object({
title: z.string(),
}),
});
// Complex extraction
const products = await stagehand.extract({
instruction: "extract all products with name, price, and availability",
schema: z.object({
products: z.array(z.object({
name: z.string(),
price: z.number(),
inStock: z.boolean(),
})),
}),
});
// Extract from specific area
const cartItems = await stagehand.extract({
instruction: "get items in the shopping cart",
schema: z.object({
items: z.array(z.object({
name: z.string(),
quantity: z.number(),
price: z.number(),
})),
total: z.number(),
}),
});
observe() - ページの状態を分析する
ページの要素と状態を把握します:
// Find elements
const elements = await stagehand.observe({
instruction: "find all clickable buttons on this page"
});
// Check state
const loginState = await stagehand.observe({
instruction: "is the user logged in? Look for profile icons or logout buttons"
});
// Identify form fields
const formFields = await stagehand.observe({
instruction: "identify all form input fields and their labels"
});
自己修復パターン
従来型と Stagehand の比較
// TRADITIONAL (Playwright) - Breaks when DOM changes
await page.click('#submit-btn-v2'); // Fails if ID changes
await page.click('.btn-primary:nth-child(2)'); // Fails if order changes
// STAGEHAND - Self-healing
await stagehand.act({ action: "click the submit button" }); // Always works
await stagehand.act({ action: "click the primary action button" }); // Adapts
自己修復が有効になる場合
- ID/クラスの変更:ボタン ID が
#old-idから#new-idに変わる - 構造の変更:要素が DOM ツリー内で移動する
- テキストの変更:ボタンのテキストが「Submit」から「Send」に変わる
- スタイルの変更:CSS クラスが再編成される
キャッシュ(パフォーマンスの最適化)
Stagehand v3 は検出した要素をキャッシュします:
// First call: AI analyzes page, finds element (slow)
await stagehand.act({ action: "click login" });
// Second call: Uses cached selector (fast)
await stagehand.act({ action: "click login" });
// Cache invalidated when page changes significantly
ハイブリッドアプローチ:Playwright + Stagehand
従来の速度と AI の回復力を組み合わせます:
import { Stagehand } from "@browserbase/stagehand";
import { test, expect } from "@playwright/test";
test('hybrid test', async () => {
const stagehand = new Stagehand({ env: "LOCAL" });
await stagehand.init();
// Use Playwright for stable, fast operations
await stagehand.page.goto('https://app.example.com');
await stagehand.page.fill('[data-testid="email"]', '[email protected]');
// Use Stagehand for dynamic/fragile elements
await stagehand.act({ action: "click the login button" });
// Use Playwright for assertions
await expect(stagehand.page).toHaveURL(/dashboard/);
// Use Stagehand for complex extraction
const dashboardData = await stagehand.extract({
instruction: "get user stats from dashboard",
schema: z.object({
totalOrders: z.number(),
accountBalance: z.number(),
}),
});
expect(dashboardData.totalOrders).toBeGreaterThan(0);
});
Claude との連携
モデルの選択
// Claude Sonnet 4 (recommended - balance of speed/quality)
const stagehand = new Stagehand({
modelName: "claude-sonnet-4-20250514",
modelClientOptions: {
apiKey: process.env.ANTHROPIC_API_KEY,
},
});
// Claude Opus (highest quality, slower)
const stagehand = new Stagehand({
modelName: "claude-opus-4-20250514",
});
// Claude Haiku (fastest, simpler tasks)
const stagehand = new Stagehand({
modelName: "claude-3-5-haiku-20241022",
});
コストの最適化
// Use Haiku for simple actions (cheaper)
const simpleStagehand = new Stagehand({
modelName: "claude-3-5-haiku-20241022",
});
await simpleStagehand.act({ action: "click login" });
// Use Sonnet for complex extraction
const complexStagehand = new Stagehand({
modelName: "claude-sonnet-4-20250514",
});
const data = await complexStagehand.extract({
instruction: "extract all product details with nested specifications",
schema: complexSchema,
});
推定コスト
| 操作 | モデル | 推定コスト |
|---|---|---|
| シンプルな act() | Haiku | ~$0.001 |
| 複雑な act() | Sonnet | ~$0.005 |
| シンプルな extract() | Haiku | ~$0.002 |
| 複雑な extract() | Sonnet | ~$0.01 |
MCP との連携
Model Context Protocol 経由で Stagehand を Claude Desktop とともに使用します:
// Stagehand MCP server enables Claude to control browsers
// from Claude Desktop or any MCP-compatible client
import { StagehandMCPServer } from "@browserbase/stagehand/mcp";
const server = new StagehandMCPServer();
server.start();
// Now Claude can call:
// - stagehand.act({ action: "..." })
// - stagehand.extract({ instruction: "..." })
// - stagehand.observe({ instruction: "..." })
エラー処理
try {
await stagehand.act({
action: "click the non-existent button",
timeout: 10000, // 10 second timeout
});
} catch (error) {
if (error.message.includes('timeout')) {
console.log('Element not found within timeout');
} else if (error.message.includes('multiple')) {
console.log('Multiple matching elements found - be more specific');
} else {
throw error;
}
}
// Retry pattern
async function actWithRetry(stagehand, action, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await stagehand.act({ action });
} catch (error) {
if (i === maxRetries - 1) throw error;
await new Promise(r => setTimeout(r, 1000));
}
}
}
ベストプラクティス
1. 指示を具体的にする
// BAD - ambiguous
await stagehand.act({ action: "click button" });
// GOOD - specific
await stagehand.act({ action: "click the blue 'Add to Cart' button below the product image" });
2. コンテキストを使う
// Provide context for better accuracy
await stagehand.act({
action: "in the navigation menu, click on 'Settings'"
});
await stagehand.act({
action: "in the user dropdown in the top right, click 'Logout'"
});
3. Playwright と組み合わせて高速化する
// Fast: Use Playwright for data-testid elements
await stagehand.page.click('[data-testid="submit"]');
// Resilient: Use Stagehand for dynamic elements
await stagehand.act({ action: "dismiss the cookie banner" });
4. スキーマ検証
// Always use Zod schemas for type safety
const schema = z.object({
title: z.string().min(1),
price: z.number().positive(),
inStock: z.boolean(),
});
const data = await stagehand.extract({
instruction: "get product details",
schema,
});
// data is fully typed!
ユースケース
- 自己修復する E2E テスト:UI の再設計後も動作するテスト
- ウェブスクレイピング:あらゆるウェブサイトからデータを抽出
- フォームの自動化:複雑なフォームを自動入力
- AI チャットボットのテスト:会話型 UI と対話
- 複数サイトにまたがるワークフロー:複数サイトのプロセスを自動化
参考資料
references/stagehand-v3-guide.md- API リファレンスの全容references/claude-integration.md- API の設定とモデルの選択references/self-healing-patterns.md- 高度なパターン
Stagehand v3 は、AI を活用した自己修復機能をブラウザー自動化にもたらします。壊れるのではなく、適応するテストを実現します。