4.1.2. Reasoning Patterns: ReAct and Chain-of-Thought
💡 First Principle: The ReAct (Reasoning + Acting) pattern transforms an FM from a single-turn responder into a multi-step problem solver by interleaving thought (explicit reasoning about what to do next) with action (calling a tool) and observation (incorporating the tool's result before the next thought). This loop continues until the model determines it has enough information to answer.
The ReAct loop in detail:
Thought: The user wants the Q3 revenue compared to budget. I need to retrieve the actual
revenue figure and the budget figure separately, then compute the variance.
Action: query_financial_db(query="Q3 actual revenue", fiscal_year=2024)
Observation: Q3 actual revenue = $4.2M
Thought: I have the actual. Now I need the budget figure.
Action: query_financial_db(query="Q3 budgeted revenue", fiscal_year=2024)
Observation: Q3 budgeted revenue = $3.8M
Thought: I have both figures. Variance = $4.2M - $3.8M = +$0.4M (+10.5%).
I can now answer.
Final Answer: Q3 actual revenue of $4.2M exceeded the $3.8M budget by $400K (+10.5%).
Implementing ReAct with Step Functions (when you need explicit orchestration control):
{
"Comment": "ReAct reasoning loop",
"StartAt": "Think",
"States": {
"Think": {
"Type": "Task",
"Resource": "arn:aws:lambda:::function:invoke-bedrock-reasoning",
"Next": "Route"
},
"Route": {
"Type": "Choice",
"Choices": [
{"Variable": "$.next_action", "StringEquals": "tool_call", "Next": "Act"},
{"Variable": "$.next_action", "StringEquals": "final_answer", "Next": "Respond"}
]
},
"Act": {
"Type": "Task",
"Resource": "arn:aws:lambda:::function:execute-tool",
"Next": "Think"
},
"Respond": {"Type": "Succeed"}
}
}
Stopping conditions — critical for production agents: Without stopping conditions, a misbehaving agent can loop indefinitely, calling tools repeatedly and accumulating costs. Always implement:
- Maximum iteration limit: Hard cap on reasoning steps (e.g., max 10 iterations)
- Timeout: Lambda timeout propagates through; Step Functions state machine timeout
- IAM boundaries: The Lambda execution role limits what the agent can touch — a tool that can only read DynamoDB cannot accidentally delete records even if the agent tries
- Circuit breaker: Detect repeated identical tool calls (infinite loop pattern) and break
⚠️ Exam Trap: Bedrock Agents automatically limits the number of reasoning steps internally, but exam scenarios about custom agent implementations with Step Functions require explicit stopping conditions in the state machine. Missing stopping conditions = potential runaway agent loop costing hundreds of dollars in FM invocations.
Reflection Question: Your Bedrock Agent-powered travel booking system is observed making 40+ tool calls for a simple "book me a flight to NYC" request before timing out. What are the three most likely causes of excessive reasoning steps, and how would you diagnose each?