結論:本記事では「Stagehand完全ガイド2026」の定義・主要機能・実際の活用方法を、初心者でも理解できる形で体系的に解説します。
対象読者:本テーマに興味がある実務担当者・意思決定者。
読了後にできること:本記事の要点を踏まえて、自社や自分の状況に合わせた次のアクションを判断できます。
TypeScriptでブラウザ操作をAI化するなら、2026年現在の最有力候補がStagehandだ。GitHub Stars 22.5k、MIT ライセンスのOSSで、Browserbase社が開発する「TypeScript製ブラウザAIエージェントFW」として急速に普及している。
PythonのBrowser-useが「フルエージェント自律実行」を目指すのに対し、Stagehandは「PlaywrightにAIを後付けする」ハイブリッド設計。TypeScript開発者が既存コードを壊さずAI化できる点が最大の差別化ポイントだ。
本記事ではインストールから実践コードまで、Stagehandを今日から使い始めるために必要な情報を全部まとめた。
Stagehandとは何か?Browser-useとの本質的な違い
StagehandはPlaywrightのラッパーとして動作する。既存のPlaywrightコードにAI命令を数行追加するだけで、セレクタ指定なしのブラウザ操作が可能になる。
Browser-useとの根本的な違いを整理すると次のとおりだ。
| 項目 | Stagehand | Browser-use |
|---|---|---|
| 言語 | TypeScript(主) | Python |
| 設計思想 | PlaywrightにAIを後付け | フルエージェント自律実行 |
| AI呼び出しタイミング | 必要な時だけ | 常時LLM推論 |
| 制御粒度 | ステップごとに制御可能 | ゴール指定で全自動 |
| GitHub Stars | 22.5k | 50k+ |
| ライセンス | MIT | MIT |
「ブラウザ操作の途中でデータを検証したい」「特定のステップだけ人間が確認したい」といったケースではStagehandが圧倒的に扱いやすい。一方、ゴールだけ渡して全部任せたいならBrowser-useが向く。
インストールとセットアップ(5分)
npmパッケージ名は @browserbasehq/stagehand だ。
npm install @browserbasehq/stagehand zod
npx playwright install chromium
最小構成の初期化コードは次のとおり。ローカルで動かす場合はBrowserbase APIキーは不要だ。
import { Stagehand } from "@browserbasehq/stagehand";
const stagehand = new Stagehand({
env: "LOCAL", // BrowserbaseはBROWSERBASEに変更
verbose: 1,
debugDom: true,
});
await stagehand.init();
const page = stagehand.page;
await page.goto("https://example.com");
await stagehand.close();
環境変数 OPENAI_API_KEY(または ANTHROPIC_API_KEY)を設定しておく必要がある。
export OPENAI_API_KEY="sk-..."
# または
export ANTHROPIC_API_KEY="sk-ant-..."
3つのコアAPI:act / extract / observe
Stagehandの操作はほぼこの3メソッドで完結する。
act() — 自然言語でブラウザ操作
CSSセレクタなしでクリック・入力・スクロールが実行できる。ページのデザイン変更にも自動対応する。
// ログインフォームの操作
await stagehand.act({ action: "click the login button" });
await stagehand.act({ action: "type 'user@example.com' into the email field" });
await stagehand.act({ action: "fill in the password field with 'mypassword'" });
await stagehand.act({ action: "submit the form" });
// 変数を使った動的な操作
const searchTerm = "Stagehand browser automation";
await stagehand.act({
action: `search for "${searchTerm}" in the search box`
});
extract() — Zodスキーマで型安全なデータ抽出
ページからデータを取り出すと同時にZodで型検証をかけられる。スクレイピングの型安全化に強力だ。
import { z } from "zod";
// 商品情報の構造化抽出
const product = await stagehand.extract({
instruction: "extract the product name, price, and availability",
schema: z.object({
name: z.string().describe("product name"),
price: z.number().describe("price in USD"),
inStock: z.boolean().describe("whether the item is in stock"),
variants: z.array(z.string()).describe("available size or color options"),
}),
});
console.log(product.name); // string が保証される
console.log(product.price); // number が保証される
配列抽出も直感的だ。
// 検索結果一覧を全件取得
const results = await stagehand.extract({
instruction: "extract ALL search results with their titles and URLs",
schema: z.array(
z.object({
title: z.string(),
url: z.string().url(),
snippet: z.string().optional(),
})
),
});
observe() — アクション候補の先読み
observe()はページ上で実行可能なアクションを事前に列挙する。UIの状態確認やテスト自動化に有用だ。
// フォーム送信前にアクション候補を確認
const actions = await stagehand.observe({
instruction: "what actions can I take on this page?"
});
console.log(actions);
// [
// { description: "click submit button", selector: "..." },
// { description: "click cancel link", selector: "..." },
// ]
// observe結果をactに直接渡せる
await stagehand.act(actions[0]);
Zodスキーマによる型安全抽出のベストプラクティス
extractをフル活用するには、スキーマのdescribeフィールドが重要だ。LLMへのヒントになるため、フィールド名だけでなく意味を添えると精度が上がる。
// 精度の低い例(describeなし)
const badSchema = z.object({
price: z.number(),
date: z.string(),
});
// 精度の高い例(describeあり)
const goodSchema = z.object({
price: z.number().describe("listing price in USD, excluding tax"),
date: z.string().describe("listing date in ISO 8601 format"),
isNegotiable: z.boolean().describe("true if price is marked as negotiable"),
});
ページによってフィールドが欠損する場合は z.optional() を使う。
const productSchema = z.object({
title: z.string(),
price: z.number(),
rating: z.number().optional().describe("star rating 1-5, may not exist"),
reviewCount: z.number().optional(),
});
Visionモード(スクリーンショット連携)
StagehandはDOMベースの解析とVision(スクリーンショット)モードを使い分けられる。JavaScriptで描画されたキャンバスやSVGベースのUIにはVisionモードが有効だ。
const stagehand = new Stagehand({
env: "LOCAL",
modelName: "claude-3-7-sonnet-20250219", // Vision対応モデルを指定
modelClientOptions: {
apiKey: process.env.ANTHROPIC_API_KEY,
},
enableCaching: false,
});
await stagehand.init();
// Vision経由でキャンバスUI上のボタンをクリック
await stagehand.act({
action: "click the blue 'Export' button in the chart toolbar",
useVision: true, // スクリーンショット解析を強制
});
Browserbaseクラウド統合(並列実行・セッション管理)
Stagehandをローカルで動かす場合はPlaywrightのみ依存するが、本番スケールにはBrowserbaseのマネージドブラウザとの統合が推奨される。
Browserbaseへの接続
const stagehand = new Stagehand({
env: "BROWSERBASE",
apiKey: process.env.BROWSERBASE_API_KEY,
projectId: process.env.BROWSERBASE_PROJECT_ID,
browserbaseSessionCreateParams: {
proxies: true, // 自動プロキシローテーション
stealth: true, // ステルスモード(bot検知回避)
},
});
await stagehand.init();
並列セッションの起動
Browserbaseでは複数セッションを並列で動かせる。プランごとの上限は次のとおりだ。
| プラン | 月額 | 同時セッション数 | ブラウザ時間 |
|---|---|---|---|
| Free | $0 | 3 | 1時間 |
| Developer | $20 | 25 | 100時間 |
| Startup | $99 | 100 | 500時間 |
| Scale | 要相談 | 250+ | カスタム |
// 並列で複数URLをスクレイピング
const urls = ["https://example.com/1", "https://example.com/2", "https://example.com/3"];
const results = await Promise.all(
urls.map(async (url) => {
const s = new Stagehand({ env: "BROWSERBASE", /* ... */ });
await s.init();
await s.page.goto(url);
const data = await s.extract({
instruction: "extract the main article title and author",
schema: z.object({
title: z.string(),
author: z.string().optional(),
}),
});
await s.close();
return data;
})
);
E2Eテスト統合パターン
StagehandはPlaywrightのテスト基盤の上に乗るため、既存のPlaywright Testに追加できる。セレクタに依存しないため、UI変更耐性が高いテストが書ける。
import { test, expect } from "@playwright/test";
import { Stagehand } from "@browserbasehq/stagehand";
test("ログインフローのE2Eテスト", async () => {
const stagehand = new Stagehand({ env: "LOCAL" });
await stagehand.init();
await stagehand.page.goto("https://myapp.example.com/login");
// セレクタ不要でフォーム入力
await stagehand.act({ action: "enter 'testuser@example.com' in the email field" });
await stagehand.act({ action: "enter 'password123' in the password field" });
await stagehand.act({ action: "click the sign in button" });
// ログイン成功を検証
const status = await stagehand.extract({
instruction: "check if the user is logged in successfully",
schema: z.object({
isLoggedIn: z.boolean(),
username: z.string().optional(),
}),
});
expect(status.isLoggedIn).toBe(true);
await stagehand.close();
});
スクレイピング・フォーム自動化の実例
ECサイトの価格監視スクリプトを例に、Stagehandの実用パターンを示す。
import { Stagehand } from "@browserbasehq/stagehand";
import { z } from "zod";
async function monitorProductPrice(productUrl: string) {
const stagehand = new Stagehand({ env: "LOCAL" });
await stagehand.init();
await stagehand.page.goto(productUrl);
// 価格・在庫・評価を一括抽出
const info = await stagehand.extract({
instruction: "extract current price, stock status, and review score",
schema: z.object({
price: z.number().describe("current selling price in JPY"),
originalPrice: z.number().optional().describe("original price before discount"),
inStock: z.boolean(),
reviewScore: z.number().min(0).max(5).optional(),
reviewCount: z.number().optional(),
}),
});
await stagehand.close();
return info;
}
// 複数商品を並列監視
const products = [
"https://shop.example.com/item/1001",
"https://shop.example.com/item/1002",
];
const prices = await Promise.all(products.map(monitorProductPrice));
console.log(prices);
Vercel AI SDK・LangChainとの連携
StagehandはVercel AI SDKの AISdkClient を通じて複数プロバイダーを切り替えられる。また、LangChainのツールとして組み込むことでエージェントワークフローに統合できる。
import { Stagehand } from "@browserbasehq/stagehand";
import { openai } from "@ai-sdk/openai";
// Vercel AI SDK経由でモデルを指定
const stagehand = new Stagehand({
env: "LOCAL",
modelName: "gpt-4o",
modelClientOptions: {
// AISdkClient設定
provider: openai("gpt-4o"),
},
});
await stagehand.init();
// LangChainのtool定義としてact()を包む
import { tool } from "langchain/tools";
const browserActTool = tool(
async ({ instruction }: { instruction: string }) => {
await stagehand.act({ action: instruction });
return `Executed: ${instruction}`;
},
{
name: "browser_action",
description: "Perform an action in the browser using natural language",
schema: z.object({ instruction: z.string() }),
}
);
失敗パターン4選と対処法
実際にStagehandを使う中でハマりやすい4つのパターンをまとめた。
1. act()が誤ったボタンをクリックする
「submit」「send」等の一般的な表現は複数要素にマッチすることがある。observe()で先にアクション候補を確認してから、より具体的な表現でact()を呼ぶとよい。
// 曖昧な指定(失敗しやすい)
await stagehand.act({ action: "click submit" });
// 具体的な指定(安定)
await stagehand.act({ action: "click the blue 'Submit Order' button at the bottom of the checkout form" });
2. extract()でundefinedが返る
対象要素がページにない場合、スキーマが required だと例外が出る。extractの前にobserve()でページ状態を確認するか、スキーマを optional() にする。
3. SPAのナビゲーション後に古いDOMを解析する
Reactなどのルーティング後は waitForLoadState で待機が必要だ。
await stagehand.act({ action: "click the 'Products' navigation item" });
await stagehand.page.waitForLoadState("networkidle");
// ここでextract()を実行
4. Browserbase接続時にセッションが残る
try-finallyで必ず stagehand.close() を呼ぶこと。残留セッションは課金対象になる。
const stagehand = new Stagehand({ env: "BROWSERBASE", /* ... */ });
try {
await stagehand.init();
// ... 処理 ...
} finally {
await stagehand.close(); // 必須
}
Stagehandが向くケース・向かないケース早見表
Stagehandは「自然言語+コードのハイブリッド」という設計上、すべてのブラウザ自動化に万能なわけではありません。導入を判断する前に、自分のユースケースがStagehandの強みと噛み合うかを確認しておくと、運用後の手戻りを大きく減らせます。以下は代表的なタスク別の適性と、その理由をまとめた早見表です。
| ユースケース | 適性 | 理由 |
|---|---|---|
| 動的サイト・SPAの操作(ログイン後画面、無限スクロール、モーダル) | ◎ 向く | act()が画面状態をLLMで解釈するため、DOM構造が変わってもセレクタ書き換えが起きにくい。手書きセレクタが崩れやすい領域ほど効果が出る。 |
| 構造化データの抽出(商品情報・表・レビューを型付きで取得) | ◎ 向く | extract()とZodスキーマの組み合わせで、欲しい形に整えた状態で取り出せる。後処理パースが不要になりやすい。 |
| レイアウトが頻繁に変わるサイトの継続監視 | ○ 条件付きで向く | セレクタ変化への耐性は高い一方、ページごとにLLM呼び出しが発生する。実行頻度とコストのバランス設計が前提になる。 |
| 単純で構造が安定した静的ページのスクレイピング | △ 向きにくい | セレクタが安定しているならLLMを介する必要が薄く、Playwright単体やHTTP取得+パースの方が速く安価になりやすい。 |
| 数万〜数十万ページ規模の大規模クロール | △ 向きにくい | ページあたりのLLM呼び出しが積み上がり、コストとレイテンシが支配的になりやすい。一覧抽出はStagehand、明細取得は軽量手段、といった分業が現実的。 |
| ミリ秒単位の応答速度が要件のリアルタイム処理 | × 向かない | LLM推論を挟む分、純粋なAPIアクセスやセレクタ直叩きより1ステップの遅延が大きくなる。 |
判断の軸はシンプルです。「対象ページの構造が安定しているか」「実行回数がどれくらいか」の2点を最初に見積もってください。構造が不安定で実行回数が中規模までなら、保守コストを下げる方向でStagehandが効きます。逆に構造が安定していて大量実行するなら、従来型ツールやAPI直取得の方がトータルで有利になることが多い、という整理になります。なお具体的な料金・レート上限・推論速度は変動するため、本番見積もりの前にStagehand公式ドキュメントで最新値を確認することをおすすめします。
他のブラウザ自動化手段との使い分け
Stagehandは既存のブラウザ自動化ツールを置き換えるものというより、「どこにLLMを挟むか」を選べるレイヤーとして理解すると使い分けがクリアになります。下表は代表的な手段との特性比較です。数値ベンチマークは環境差が大きいため、ここではあくまで設計思想と適した役割の一般論として整理します。
| 手段 | 操作の指定方法 | LLMの関与 | 得意な領域 | 主な留意点 |
|---|---|---|---|---|
| Stagehand | 自然言語+コードの併用 | あり(act/extract/observe単位) | 変化に強い操作・型付き抽出・AIエージェント組み込み | 1操作ごとに推論コストとレイテンシが乗る |
| Playwright単体 | セレクタ・コードで明示指定 | なし | 挙動が確定的なE2Eテスト・安定サイトの自動化 | UI変更時にセレクタ保守が継続的に発生する |
| Puppeteer | セレクタ・コードで明示指定 | なし | Chrome系に絞った軽量スクレイピング・PDF/スクショ生成 | クロスブラウザ対応はPlaywrightより限定的 |
| browser-use | 自然言語ゴールをエージェントに委任 | 強い(自律的に判断) | 手順未定義の探索的タスク・人間の操作代行 | 挙動の再現性・制御性をコードで縛りにくい |
| Selenium | セレクタ・コードで明示指定 | なし | 多言語・多ブラウザ・既存資産が大きい組織での標準化 | セットアップが重く、近年のモダン用途では冗長になりやすい |
選び方の目安
- テストの安定性が最優先なら、確定的に動くPlaywright単体やSeleniumを基盤に。崩れやすい一部の操作だけStagehandの
act()で補強する、という併用が現実的です。 - UI変更に強い実装が欲しいなら、操作部分をStagehandに寄せると保守工数を圧縮できます。Stagehand自体がPlaywrightベースのため、既存のPlaywright資産と同居させやすいのも利点です。
- 手順を細かく決めたくない探索的タスクなら、自律性の高いbrowser-useが適します。逆に「毎回同じ手順を正確に」回したいならStagehandやPlaywrightのように手続きを明示できる側を選びます。
- 既存資産がSelenium/Puppeteer中心の場合は、全面移行よりも崩れやすい工程だけStagehandへ切り出す段階的な置き換えが、リスクが小さく検証もしやすい進め方です。
つまり「Stagehand vs 他ツール」は二者択一ではなく、確定的に書ける部分は従来ツール、変化に弱い部分にだけLLMを挟むという棲み分けが、コストと安定性の両面で扱いやすい結論になります。各ツールの最新仕様や対応範囲は更新されるため、採用前にBrowserbase公式や各ツールのドキュメントで現状を確認してください。
まとめ:Stagehandを選ぶべき場面
Stagehandが最適な場面をまとめると次のとおりだ。
- 既存のPlaywright / Next.jsプロジェクトにAIブラウザ操作を追加したい
- TypeScriptのエコシステムで完結させたい
- Zodによる型安全なWebスクレイピングを実装したい
- E2Eテストの保守コストを下げたい(セレクタ不要)
- Browserbaseのマネージドクラウドで並列・スケールさせたい
一方、Pythonベースのコードベースや「ゴールだけ渡して全自動」が必要な場面ではBrowser-useやAIブラウザ比較記事も参照してほしい。
Stagehandは v3.6.4(2026年5月時点)でAPIが安定しており、GitHubのissueレスポンスも活発だ。TypeScript開発者がブラウザAIエージェントに入門するなら、現時点での最短ルートといえる。
この記事を読んで導入イメージが固まってきた方へ
UravationではAIエージェント導入の研修・コンサルを行っています。
