Parse ReAct Logs into Thought Action Observation Steps in Python

Parse a ReAct agent's textual log into structured steps with thought, action, and observation using regex and named tuples.

Medium Python 3.9+ Aug 9, 2026 AI & LLM integration patterns 13 views 0 copies

Python code

34 lines
Python 3.9+
import re
from collections import namedtuple


ReActStep = namedtuple("ReActStep", ["thought", "action", "observation"])


def parse_react_log(log: str) -> list[ReActStep]:
    """Parse a ReAct log into structured thought/action/observation steps."""
    pattern = re.compile(
        r"Thought:\s*(?P<thought>.+?)\s*"
        r"Action:\s*(?P<action>\w+\[.*?\])\s*"
        r"Observation:\s*(?P<observation>.+?)(?=\s*Thought:|\s*$)",
        re.DOTALL
    )
    return [
        ReActStep(m.group("thought"), m.group("action"), m.group("observation").strip())
        for m in pattern.finditer(log)
    ]


if __name__ == "__main__":
    sample_log = """
Thought: I need to check the weather.
Action: search[weather in London]
Observation: It's raining in London.

Thought: I should suggest an umbrella.
Action: reply[Bring an umbrella]
Observation: User thanks me.
"""
    steps = parse_react_log(sample_log)
    for i, step in enumerate(steps, 1):
        print(f"Step {i}: thought={step.thought!r}, action={step.action!r}, observation={step.observation!r}")

Output

stdout
Step 1: thought='I need to check the weather.', action='search[weather in London]', observation="It's raining in London."
Step 2: thought='I should suggest an umbrella.', action='reply[Bring an umbrella]', observation='User thanks me.'

How it works

The code uses a compiled regex with named groups to capture each 'Thought:', 'Action:', and 'Observation:' segment. The re.DOTALL flag allows matching across newlines, and the lookahead (?=\s*Thought:|\s*$) stops each observation at the next thought or end of string. A namedtuple stores each step for structured access. The parse_react_log function returns a list of these tuples, making it easy to iterate and inspect agent reasoning traces.

Common mistakes

  • Forgetting `re.DOTALL` causes the pattern to stop at newlines, breaking multi-line thoughts/observations.
  • Using a plain tuple instead of namedtuple makes field access less readable.
  • Assuming action quotes are always single quotes while logs may use double quotes.

Variations

  1. Use a dataclass with `@dataclass` instead of namedtuple for mutable or annotated steps.
  2. Add a `final` field or action output parser to extract arguments from the action string.

Real-world use cases

  • Debugging LLM agents by logging and analyzing each reasoning step after a run.
  • Building a replay or evaluation tool that reads saved ReAct transcripts to measure step quality.
  • Converting agent logs into structured data for a vector store or monitoring dashboard.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from AI & LLM integration patterns

Related tutorials and quizzes for this topic.