A from-scratch Python implementation of "ReAct: Synergizing Reasoning and Acting in Language Models" (Yao et al., 2022).
Standard CoT prompts the model to reason in its head — but it can hallucinate facts.
ReAct interleaves Thought (reasoning) with Action (tool calls) and Observation (real results), grounding the reasoning in retrieved facts.
Standard CoT: Think ────────────────────────────► Answer (can hallucinate)
ReAct: Think → Act → Observe → Think → Act → Observe → ... → Answer
↑ ↑
Wikipedia Calculator
(real facts) (exact math)
Each step:
- Thought N — the model reasons about what to do next
- Action N — calls a tool:
Search[query],Lookup[term],Calculate[expr], orFinish[answer] - Observation N — the real tool result, injected back into context
The LLM never generates the Observation — that always comes from the real tool. This prevents hallucination of facts.
- Zero external dependencies — pure Python 3.11 stdlib
- OpenRouter back-end — any model via
OPENROUTER_API_KEY - 4 built-in tools — Wikipedia Search, Lookup, Calculator, Finish
- Safe calculator — AST-based, blocks
__import__,open, etc. - Wikipedia via free MediaWiki API — no API key required for search
- 30 offline unit tests — LLM and network fully mocked
git clone https://github.com/MONISMALIK1/react_agent
cd react_agent
pip install -e .
export OPENROUTER_API_KEY="sk-or-..." # https://openrouter.ai/keys# Ask a factual question
python -m react_agent "Who was the first person to walk on the moon, and in what year?"
# Show every Thought / Action / Observation as it runs
python -m react_agent "What is the capital of Australia?" --verbose
# A question requiring calculation
python -m react_agent "How many days are in 17 weeks?"
# Increase max reasoning steps (default: 7)
python -m react_agent "..." --steps 12Example output:
Question: Who was the first person to walk on the moon?
Step 1
Thought: I should search for the first moon landing.
Action: Search[Apollo 11]
Observation: Apollo 11 was the first crewed mission to land on the Moon...
Step 2
Thought: Neil Armstrong was the first to walk on the Moon in 1969.
Action: Finish[Neil Armstrong, 1969]
============================================================
Answer: Neil Armstrong, 1969
Steps taken: 2
from react_agent import run
result = run("What is the population of Tokyo?", max_steps=7)
print(result.answer) # "approximately 14 million (city), 37 million (metro)"
print(result.finished) # True
for step in result.steps:
print(step.thought)
print(step.action_name, step.action_input)
print(step.observation)| Tool | Usage | Description |
|---|---|---|
Search[entity] |
Search[Eiffel Tower] |
Fetches Wikipedia intro paragraph |
Lookup[keyword] |
Lookup[height] |
Finds next sentence in current article containing keyword |
Calculate[expr] |
Calculate[3 * (14 + 2)] |
Safe AST-evaluated arithmetic |
Finish[answer] |
Finish[Paris] |
Returns the answer and ends the loop |
react_agent/
├── llm.py OpenRouter HTTP wrapper
├── prompts.py 4-shot ReAct few-shot prompt (from paper)
├── tools.py Search, Lookup, Calculate, Finish implementations
├── agent.py ReAct loop — parse Thought/Action, execute, append Observation
├── __init__.py Public API
├── __main__.py CLI
└── tests/
├── test_tools.py Calculator, dispatch, Wikipedia (mocked)
└── test_agent.py Parser unit tests + full loop integration tests
No API key or network needed:
python -m unittest discover -s react_agent/tests -t . -v@inproceedings{yao2023react,
title = {ReAct: Synergizing Reasoning and Acting in Language Models},
author = {Shunyu Yao and Jeffrey Zhao and Dian Yu and Nan Du and
Izhak Shafran and Karthik Narasimhan and Yuan Cao},
booktitle = {ICLR},
year = {2023},
url = {https://arxiv.org/abs/2210.03629}
}