Sahaj.blogs
12 Aug 2026 · StudyPhase 15 · Agentic AI

Agentic AI · ReAct

ReAct interleaves reasoning ("Thought") with tool use ("Action") and results ("Observation"); the prompt format, a parser for model output, and a full trace with a scripted model.

ReAct (Yao et al., 2022) combines two earlier ideas: chain-of-thought reasoning, and acting with tools. The model writes text in a fixed pattern:

Thought: what I know and what I need next
Action: tool_name[input]
Observation: (filled in by the application, not the model)
... repeat ...
Final Answer: ...

The paper’s argument is that reasoning helps the model plan and handle surprises, and acting grounds that reasoning in real information, which reduces hallucination.

The important engineering point: the application parses each Action: line, runs the tool, and appends the Observation:. The model only produces text. Here’s that parser and loop, driven by a scripted model so the trace is exact. The tool-calling post uses a real model.

import re

TOOLS = {
    "lookup": lambda k: {"bert": "BERT was published in 2018.", "gpt-2": "GPT-2 was released in 2019."}.get(k.lower(), "unknown"),
    "subtract": lambda s: str(eval(s, {"__builtins__": {}}, {})) if re.fullmatch(r"[\d\s\-]+", s) else "invalid",
}

SCRIPT = iter([
    "Thought: I need the year BERT was published.\nAction: lookup[BERT]",
    "Thought: Now I need GPT-2's release year.\nAction: lookup[GPT-2]",
    "Thought: The gap is 2019 minus 2018.\nAction: subtract[2019 - 2018]",
    "Thought: I have everything.\nFinal Answer: GPT-2 came 1 year after BERT.",
])
fake_llm = lambda prompt: next(SCRIPT)

def react(question, llm, max_steps=6):
    prompt = f"Question: {question}\n"
    for _ in range(max_steps):
        out = llm(prompt)
        prompt += out + "\n"
        if m := re.search(r"Final Answer:\s*(.*)", out):
            return m.group(1), prompt
        if m := re.search(r"Action:\s*(\w+)\[(.*)\]", out):
            tool, arg = m.groups()
            obs = TOOLS[tool](arg) if tool in TOOLS else f"unknown tool {tool}"
            prompt += f"Observation: {obs}\n"
        else:
            prompt += "Observation: could not parse an action\n"
    return "no answer within step limit", prompt

answer, transcript = react("How many years after BERT was GPT-2 released?", fake_llm)
print(transcript)
print("ANSWER:", answer)

Output:

Question: How many years after BERT was GPT-2 released?
Thought: I need the year BERT was published.
Action: lookup[BERT]
Observation: BERT was published in 2018.
Thought: Now I need GPT-2's release year.
Action: lookup[GPT-2]
Observation: GPT-2 was released in 2019.
Thought: The gap is 2019 minus 2018.
Action: subtract[2019 - 2018]
Observation: 1
Thought: I have everything.
Final Answer: GPT-2 came 1 year after BERT.

ANSWER: GPT-2 came 1 year after BERT.

The years come from my own Transformers notes (BERT 2018, GPT-2 2019). The subtract tool only accepts digits, spaces and minus signs before evaluating, which is a small taste of the safety post at the end of this phase.

#agents#react#reasoning

Sources

  1. Yao et al. (2022), ReAct: Synergizing Reasoning and Acting in Language Models — arXiv
  2. ReAct project page — Princeton & Google
  3. Wei et al. (2022), Chain-of-Thought Prompting Elicits Reasoning in Large Language Models — arXiv