#31The ReAct loop with a max_steps guardMedium

The ReAct loop with a max_steps guard

Background

The ReAct agent loops: ask the LLM, and if it says SEARCH:, run the search, append the observation, and go again; if it says ANSWER:, return. A max_steps guard prevents an infinite loop.

Problem statement

Implement react_loop(query, llm, search, system_prompt, max_steps=6).

Input

  • query — the user question.
  • llm — callable messages -> str (returns a SEARCH:/ANSWER: line).
  • search — callable query -> list[str].
  • system_prompt — the ReAct system prompt string.
  • max_steps — loop cap.

Output

Returns the final answer string. Per step:

  1. response = llm(messages).
  2. If it starts with "SEARCH:": search the query, append {"role":"assistant","content":response} then {"role":"user","content":"OBSERVATION:\n" + "\n".join(f"- {r}" for r in results)}, and loop.
  3. If it starts with "ANSWER:": return the stripped text.
  4. Otherwise: return the response unchanged.
  5. If max_steps is exhausted: return "Reached maximum steps without a final answer."

Examples

Example 1 — one search, then answer

llm:    step 0 -> "SEARCH: find it"; step 1 -> "ANSWER: final result"
search: q -> ["doc"]
react_loop("question", llm, search, "P")  ->  "final result"

Constraints

  • Seed messages with the system prompt + the user query.
  • Append assistant + observation messages on each SEARCH:.
  • Return on ANSWER: (stripped) or any non-protocol response (verbatim).
  • Stop after max_steps with the fixed message.

Notes

  • The growing messages list is the only memory: each LLM call re-reads the whole transcript.
Python
Loading...

▶ Run executes the 3 visible sample tests below in your browser. Submit runs the full suite — including hidden tests — on the server for an official verdict.

  • Reference example: one search then a final answer
  • Sample: an immediate answer
  • Example: max_steps guard fires on a search loop