Documentation Index
Fetch the complete documentation index at: https://mintlify.com/browserbase/stagehand/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The quality of your prompts directly impacts Stagehand’s reliability and performance. This guide covers proven patterns for writing effective instructions.
General Principles
Be Specific and Clear
// ❌ Vague
await stagehand.act("do something");
// ✅ Specific
await stagehand.act("click the blue 'Add to Cart' button");
Use Imperative Language
// ❌ Passive/Unclear
await stagehand.act("the login button should be clicked");
// ✅ Direct command
await stagehand.act("click the login button");
Include Visual Descriptors
// ❌ Ambiguous
await stagehand.act("click the button");
// ✅ Descriptive
await stagehand.act("click the red 'Submit' button at the bottom of the form");
Act() Prompts
Clicking Elements
// Good examples
await stagehand.act("click the 'Sign In' button");
await stagehand.act("click the menu icon in the top right");
await stagehand.act("click the third product card");
await stagehand.act("click the checkbox next to 'I agree to terms'");
Filling Forms
// ❌ Missing context
await stagehand.act("type 'john@example.com'");
// ✅ Specifies target
await stagehand.act("type 'john@example.com' in the email field");
await stagehand.act("type 'password123' in the password input");
await stagehand.act("type 'John Doe' in the full name field");
Selecting from Dropdowns
await stagehand.act("select 'United States' from the country dropdown");
await stagehand.act("select 'Medium' from the size selector");
await stagehand.act("choose 'Blue' from the color options");
Navigation
await stagehand.act("scroll down to the footer");
await stagehand.act("scroll to the reviews section");
await stagehand.act("hover over the 'Products' menu item");
// ❌ Too broad
const result = await stagehand.extract("get data");
// ✅ Specific fields
const result = await stagehand.extract(
"get the product title, price, and availability status"
);
Use Structured Schemas
import { z } from "zod";
const productSchema = z.object({
title: z.string().describe("The product name"),
price: z.number().describe("Price in USD"),
inStock: z.boolean().describe("Whether the product is available"),
rating: z.number().optional().describe("Star rating out of 5"),
});
const result = await stagehand.extract(
"extract the product details",
{ schema: productSchema }
);
// result.extraction is fully typed
console.log(result.extraction.title);
console.log(result.extraction.price);
const searchResultsSchema = z.object({
results: z.array(z.object({
title: z.string(),
url: z.string(),
description: z.string(),
})),
});
const results = await stagehand.extract(
"extract all search results including title, URL, and description",
{ schema: searchResultsSchema }
);
Observe() Prompts
Observe returns a list of actions to perform:
// Get multiple related actions
const actions = await stagehand.observe(
"return actions to fill the login form with username 'john@example.com' and password 'test123'"
);
for (const action of actions) {
await stagehand.act(action);
}
Good Observe Patterns
// Form filling
const formActions = await stagehand.observe(
"return actions to complete the signup form with name 'John', email 'john@example.com', and phone '555-1234'"
);
// Multi-step workflows
const checkoutActions = await stagehand.observe(
"return actions to proceed through checkout: select shipping, enter payment details, and confirm order"
);
Agent Instructions
Clear Goals
const agent = stagehand.agent();
// ❌ Too vague
await agent.execute({
instruction: "do some stuff on Amazon",
maxSteps: 10,
});
// ✅ Clear objective
await agent.execute({
instruction: "search for 'wireless mouse' on Amazon and add the first result to cart",
maxSteps: 10,
});
Break Down Complex Tasks
// ❌ Too complex for one agent call
await agent.execute({
instruction: "research competitors, analyze pricing, create spreadsheet, and send email",
maxSteps: 50,
});
// ✅ Break into smaller tasks
await agent.execute({
instruction: "navigate to competitor website and extract product prices",
maxSteps: 15,
});
// Then handle analysis and email separately
Include Stop Conditions
await agent.execute({
instruction: "search for 'laptop' and add first result to cart, then stop",
maxSteps: 10,
});
await agent.execute({
instruction: "scroll through products until you find one under $50, then click it",
maxSteps: 20,
});
Using System Prompts
Stagehand-Level System Prompts
const stagehand = new Stagehand({
env: "LOCAL",
systemPrompt: `You are automating an e-commerce website.
- Always verify prices before adding to cart
- If an item is out of stock, skip it
- Prefer items with 4+ star ratings`,
});
Agent-Level System Prompts
const agent = stagehand.agent({
systemPrompt: `You are a research assistant.
- Extract data accurately
- When information is missing, note it as 'N/A'
- Today's date is ${new Date().toLocaleDateString()}`,
});
await agent.execute({
instruction: "gather company information from the about page",
maxSteps: 5,
});
Common Mistakes to Avoid
Overly Complex Instructions
// ❌ Too many steps in one instruction
await stagehand.act(
"click the menu, then click products, then select laptops category, then filter by price under $1000, then sort by rating"
);
// ✅ Break into individual actions
await stagehand.act("click the menu button");
await stagehand.act("click the 'Products' link");
await stagehand.act("select 'Laptops' from the category filter");
await stagehand.act("select 'Under $1000' from the price filter");
await stagehand.act("sort by rating");
Ambiguous References
// ❌ Which button?
await stagehand.act("click the button");
// ✅ Specific reference
await stagehand.act("click the 'Add to Cart' button");
Missing Context
// ❌ What form?
await stagehand.act("submit the form");
// ✅ Identifies the form
await stagehand.act("submit the login form");
await stagehand.act("click the submit button in the contact form");
Using Variables
Dynamically insert values into prompts:
const userEmail = "john@example.com";
const password = "secure123";
await stagehand.act(
"type '{{email}}' in the email field",
{ variables: { email: userEmail } }
);
await stagehand.act(
"type '{{password}}' in the password field",
{ variables: { password } }
);
Variables with Agent
const searchTerm = "wireless keyboard";
const maxPrice = 50;
const agent = stagehand.agent();
await agent.execute({
instruction: "search for '{{product}}' and find options under ${{price}}",
maxSteps: 15,
variables: {
product: searchTerm,
price: maxPrice.toString(),
},
});
Testing Your Prompts
Iterate and Refine
// Start simple
await stagehand.act("click login");
// If it fails, add more detail
await stagehand.act("click the login button");
// If still failing, be very specific
await stagehand.act("click the blue 'Log In' button in the top right corner");
Use Verbose Mode During Development
const stagehand = new Stagehand({
env: "LOCAL",
verbose: 2, // See detailed logs
});
await stagehand.act("click submit");
// Logs will show what Stagehand "sees" and how it interprets your instruction
Prompt Engineering for Reliability
Handle Dynamic Content
// ❌ Brittle: relies on exact text
await stagehand.act("click the button that says 'Add to Cart'");
// ✅ Flexible: works with variations
await stagehand.act("click the button to add the item to the cart");
Account for Loading States
// Wait for content before acting
const page = stagehand.context.pages()[0];
await page.waitForLoadState("domcontentloaded");
await stagehand.act("click the first product");
Use Conditional Logic
try {
await stagehand.act("click the cookie consent banner's accept button", {
timeout: 5000,
});
} catch (error) {
// No banner appeared, continue
}
await stagehand.act("search for products");
Example: Complete Workflow
import { Stagehand } from "@browserbasehq/stagehand";
import { z } from "zod";
const stagehand = new Stagehand({
env: "LOCAL",
cacheDir: "./cache",
});
await stagehand.init();
const page = stagehand.context.pages()[0];
await page.goto("https://example-store.com");
// Clear, specific instructions
await stagehand.act("type 'laptop' in the search bar");
await stagehand.act("click the search button");
// Structured extraction
const productSchema = z.object({
products: z.array(z.object({
name: z.string(),
price: z.number(),
rating: z.number(),
})),
});
const results = await stagehand.extract(
"extract the name, price, and rating for all products shown",
{ schema: productSchema }
);
// Act on extracted data
if (results.extraction.products.length > 0) {
await stagehand.act("click the first product in the search results");
}
await stagehand.close();
Related