Paper·arxiv.org
agentsreasoningtool-usellm-agentsreact-frameworkprompt-engineeringagentic-ai
ReAct: Reasoning and Acting in LLMs
Implement the ReAct framework to enable large language models (LLMs) to reason and act by interleaving thought generation with tool execution. This approach enhances LLM capabilities for complex tasks, improving performance and interpretability.
intermediate1 hour6 steps
The play
- Understand the ReAct LoopGrasp the core principle: LLMs generate 'Thought' (reasoning), then 'Action' (tool use), followed by 'Observation' (tool output), which feeds back into the next 'Thought'.
- Select Your LLM and ToolsChoose an LLM (e.g., OpenAI GPT-4, Llama 3) and identify external tools it will interact with (e.g., search API, calculator, code interpreter). Define clear function signatures for your tools.
- Craft the ReAct PromptDesign a system prompt that guides the LLM to output its reasoning (Thought), the tool to use (Action), and expects the tool's output (Observation). Clearly define the output format for Thought, Action (tool_name[args]), and subsequent Observation.
- Implement the Agent LoopWrite a loop that takes an LLM's response, parses it for 'Thought' and 'Action', executes the specified tool with its arguments, captures the 'Observation', and appends it to the conversation history before calling the LLM again. Include a stop condition.
- Integrate Tool ExecutionCreate a dispatcher function that maps tool names from the LLM's 'Action' output to actual Python functions that execute those tools and return their results as 'Observation' strings.
- Test and IterateRun your ReAct agent with a complex query requiring both reasoning and tool use. Analyze the LLM's 'Thought' process and refine your prompt or tool definitions based on its performance.
Starter code
import json
def mock_llm_response(prompt_history):
# Simplified mock LLM. In reality, this calls an actual LLM API.
last_user_query = prompt_history[-1]
if 'current date' in last_user_query:
return 'Thought: I need to use a tool to find the current date. Action: get_current_date[]'
elif 'Observation:' in last_user_query and '2023-10-27' in last_user_query:
return 'Thought: I have the current date. I can now answer the question. The current date is 2023-10-27.'
elif 'hello' in last_user_query:
return 'Thought: This is a simple greeting. I can respond directly. Hello there!'
else:
return 'Thought: I am not sure how to respond to this. Action: search_web[how to respond to "' + last_user_query + '"]'
def get_current_date():
# Mock tool for getting current date
return '2023-10-27'
def search_web(query):
# Mock tool for web search
return f"Search results for '{query}': Example result 1, Example result 2"
def tool_dispatcher(action_string):
tool_name = action_string.split('[')[0]
args_str = action_string.split('[')[1].strip(']')
args = [arg.strip().strip("'\") for arg in args_str.split(',') if arg.strip()]
if tool_name == 'get_current_date':
return get_current_date()
elif tool_name == 'search_web':
return search_web(*args)
else:
return f"Error: Unknown tool '{tool_name}'"
def run_react_agent(initial_query, max_iterations=5):
prompt_history = [f"User: {initial_query}"]
for i in range(max_iterations):
llm_output = mock_llm_response(prompt_history)
print(f"LLM Output: {llm_output}")
prompt_history.append(f"Agent: {llm_output}")
if 'Thought:' in llm_output and 'Action:' in llm_output:
thought, action = llm_output.split('Action:', 1)
action = action.strip()
print(f"Executing Action: {action}")
observation = tool_dispatcher(action)
print(f"Observation: {observation}")
prompt_history.append(f"Observation: {observation}")
elif 'Thought:' in llm_output and 'Action:' not in llm_output:
print(f"Final Answer: {llm_output.split('Thought:', 1)[1].strip()}")
break
else:
print("Unexpected LLM output format. Exiting.")
break
else:
print("Max iterations reached.")
# --- Run the ReAct Agent ---
print("\n--- Running ReAct Agent for 'What is the current date?' ---")
run_react_agent("What is the current date?")
print("\n--- Running ReAct Agent for 'Hello' ---")
run_react_agent("Hello")Source