
Improve Nova Act Accuracy - Let Nova Lite Reason, and Nova Act Act
Amazon Nova Act is a breakthrough in browser automation. By pairing it with Amazon Nova Lite in a ReAct architecture, you can unlock a level of reliability and adaptability that neither model achieves alone.
What Nova Act Makes Possible
Browser automation has always been painful. Selenium scripts break the moment a UI changes. CSS selectors rot. XPath expressions are unmaintainable. Every workflow requires constant babysitting.
Amazon Nova Act changes that completely. It lets you describe browser interactions in plain English and executes them with remarkable reliability:
1
2
with NovaAct(starting_page="https://www.google.com") as agent:
agent.act("Search for the latest books on AI Engineering")No selectors. No boilerplate. Just intent, and Nova Act handles the rest. We used it as the browser automation backbone of an AWS Architecture Builder application, and the execution quality was immediately impressive. Nova Act is purpose-built to act: to translate natural language into precise, reliable browser interactions.
But as we pushed it into more complex, multi-step workflows, we discovered something interesting, not a limitation of Nova Act, but an opportunity to make it even more powerful.
The Insight: Separating Reasoning from Acting
Consider a task like:
"Search for the latest books on AI Engineering, navigate through the first 10 results, and collect descriptions from each page."
This is a multi-step workflow with real-world unpredictability. Pages may redirect. Results may vary. A CAPTCHA may appear on a third-party site mid-flow. In our testing, we observed exactly this: Nova Act would reach an unexpected page state and continue executing subsequent steps without the broader context needed to adapt.
This is not a flaw - it's a design boundary. Nova Act is an execution engine. It is phenomenally good at doing what it is told. What it isn't designed to do is step back after each action, assess the current state of the world, compare it against the original goal, and dynamically decide what should happen next.
That higher-order reasoning is a completely different capability; Amazon already has a model built for it.
The Quick Fixes We Deliberately Avoided
At this point, several straightforward patches were on the table:
- Retry limits - stop after N failed attempts on the same action
- Timeout thresholds - abort if a step takes longer than X seconds
- Keyword-based blocking - detect known obstacle patterns like "CAPTCHA" or "verify you are human" in the page title and exit
- Step count ceilings - hard-stop the agent after a fixed number of steps regardless of progress
- Error pattern matching - compare consecutive observations and halt if they look identical
Any of these would have resolved the CAPTCHA loop. We could have shipped one in minutes.
But each of them addresses the symptom, not the cause. The cause is that the agent has no awareness of whether its actions are serving the goal. A retry limit doesn't give it judgment, it just gives it an expiry date. A timeout doesn't teach it to recognise a dead end - it just pulls the plug. The agent remains fundamentally blind to context; it just fails faster.
What we actually wanted was an agent that could see what was happening, understand whether it was making progress, and decide intelligently what to do next - exactly as a human operator would. That is a reasoning problem, not a configuration problem.
And that distinction led us to a much more capable solution.
Enter Amazon Nova Lite
Amazon Nova Lite is a fast, highly capable multimodal model optimised for instruction-following and structured reasoning. It excels at reading context, identifying patterns, and producing precise, structured responses.
The idea is simple: let Nova Lite think, and let Nova Act do.
This is the ReAct pattern - Reason + Act - a well-established agent design architecture now made exceptionally powerful by combining two purpose-built Amazon Nova models:
| Role | Model | Responsibility |
|---|---|---|
| Reason | Amazon Nova Lite | Read observations, assess state, decide next action |
| Act | Amazon Nova Act | Execute browser actions reliably and precisely |
Neither model is doing the other's job. Both are operating in their area of strength. Together, they form an agent that can handle the full complexity of real-world browser workflows.
The Architecture
The loop works like this:

After every action, Nova Act's observation is passed back to Nova Lite. Nova Lite receives the complete history - every action taken and every outcome observed - and returns a structured decision about what to do next. It can continue, declare the task complete, or recognise that an obstacle requires a change in approach.
The Implementation
Step 1: The Reasoning Layer (Nova Lite)
Nova Lite receives the task and full history, and returns a structured JSON decision:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage, SystemMessage
import json, os
SYSTEM_PROMPT = """You are the reasoning brain of a browser automation agent.
After each browser action you receive an observation describing what happened.
Decide what the agent should do next to complete the original task.
Reply with ONLY a JSON object in this exact shape:
{
"status": "CONTINUE" | "DONE" | "BLOCKED",
"thought": "<one sentence explaining your reasoning>",
"next_action": "<precise instruction for the browser, or empty if DONE/BLOCKED>",
"summary": "<populated only when status is DONE>"
}
Rules:
- CONTINUE while there is still work to do.
- DONE when the task is fully complete.
- BLOCKED when an unrecoverable obstacle is encountered after exhausting alternatives.
- Each next_action must be a single, atomic browser instruction.
- Never attempt to solve CAPTCHAs or enter payment details.
"""
def reason(task: str, history: list[dict]) -> dict:
client = ChatOpenAI(
model="nova-2-lite-v1",
base_url=os.getenv("NOVA_BASE_URL"),
api_key=os.getenv("NOVA_API_KEY"),
)
history_text = "\n".join(
f"Step {i+1}:\n Action: {h['action']}\n Observation: {h['observation']}"
for i, h in enumerate(history)
) or "(none yet - this is the first step)"
response = client.invoke([
SystemMessage(content=SYSTEM_PROMPT),
HumanMessage(content=(
f"Original task: {task}\n\n"
f"History so far:\n{history_text}\n\n"
"What should the agent do next?"
)),
])
return json.loads(response.content.strip())Step 2: The Execution Layer (Nova Act)
Nova Act receives one precise instruction at a time and executes it in the browser:
1
2
3
4
5
6
7
8
from nova_act import NovaAct, ActError
def act(browser: NovaAct, action: str) -> str:
try:
browser.act(action)
return "Action completed."
except ActError as e:
return f"ActError: {e}"Step 3: The ReAct Loop
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
def run(task: str, start_url: str, max_steps: int = 20) -> dict:
with NovaAct(
starting_page=start_url,
nova_act_api_key=os.getenv("NOVA_API_KEY"),
) as browser:
history = []
for step_num in range(1, max_steps + 1):
# 1. REASON - Nova Lite decides what to do next
decision = reason(task, history)
print(f"Step {step_num} | {decision['status']} | {decision['thought']}")
if decision["status"] == "DONE":
return {"success": True, "summary": decision["summary"], "steps": step_num}
if decision["status"] == "BLOCKED":
return {"success": False, "reason": decision["thought"], "steps": step_num}
# 2. ACT - Nova Act executes it
observation = act(browser, decision["next_action"])
# 3. RECORD - observation feeds back into next reasoning cycle
history.append({
"action": decision["next_action"],
"observation": observation,
})
return {"success": False, "reason": "Max steps reached."}Usage
1
2
3
4
5
result = run(
task="Search for the latest books on AI Engineering and navigate to the first result",
start_url="https://www.google.com",
)
print(result["summary"])How Nova Lite Enhances Nova Act's Reach
With Nova Lite reasoning over every observation, the combined agent gains capabilities that neither model has alone:
Adaptive decision-making - Nova Lite reads the current page state after every action and adjusts the plan accordingly. If a page loads differently than expected, the route changes.
Obstacle recognition - When Nova Lite detects that repeated actions are not producing progress, it changes approach rather than repeating the same step.
Goal tracking - Nova Lite holds the original task in context across every step. It knows not just what the current action is, but whether the overall goal is being served.
Clean termination - Nova Lite declares
DONE precisely when the task is complete, not before, not after. This prevents both premature exits and unnecessary extra steps.Cost efficiency - Because Nova Act receives one specific, well-reasoned instruction per step, it wastes no cycles on exploratory or redundant actions.
The Key Principle
Nova Act was designed to be the world's best browser action executor. It delivers on that completely. The ReAct pattern doesn't change what Nova Act is; it gives it a thinking partner that maximises what it can accomplish.
Think of it as the difference between a highly skilled specialist working alone versus working with a sharp strategist guiding each move. The specialist's skills don't change. The outcomes do.
1
2
Without ReAct: Task → Nova Act → Result
With ReAct: Task → Nova Lite → Nova Act → Nova Lite → Nova Act → ... → ResultThe addition is one reasoning loop. The difference in capability for complex, real-world workflows is substantial.
Recommendations for Your Implementation
Keep actions atomic. Every
next_action from Nova Lite should be a single, unambiguous browser instruction. Nova Act performs at its best with specific, focused instructions rather than compound ones.Structure your history well. Nova Lite's decision quality is a direct function of how clearly the history is presented. Pass every action and its observation, formatted consistently.
Set a step ceiling. Cap
max_steps at 15–20 for most workflows. This keeps costs predictable and prevents runaway loops in edge cases.Use Nova Lite's
thought field for debugging. The thought field in every decision is Nova Lite's internal reasoning made visible. It's invaluable for understanding why the agent made a particular choice.Let Nova Act handle the browser entirely. Don't try to extract structured data from
act() - it's not what it's designed for. Use Nova Act to navigate and interact, and let Nova Lite interpret the outcomes through the observation text.Final Thoughts
Amazon Nova Act and Amazon Nova Lite are each exceptional at what they do. Nova Act brings natural-language browser automation to production quality. Nova Lite brings fast, structured reasoning to complex multi-step decisions.
The ReAct pattern is the bridge that connects them; the result is a browser automation agent with the adaptability and reliability that real-world workflows demand.
Use Nova Act as the Act in your ReAct pattern. Pair it with Nova Lite to reason and guide every step. That is where the full power of the Amazon Nova family comes together.
Built using Amazon Nova Act SDK and Amazon Nova Lite via the Amazon Nova API, with LangChain and Python. Part of an ongoing AWS Architecture Builder project leveraging the Amazon Nova model family.
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article