LangChain ReAct Prompt Templates
Source: LangChain ReAct Prompt Templates
Raw file:
raw/docs/langchain-react-prompts.md
Origin:langchain-ai/langchain(master)
libs/langchain/langchain_classic/agents/react/wiki_prompt.pylibs/langchain/langchain_classic/agents/react/textworld_prompt.py
What these files are
The actual prompt templates used by ReActDocstoreAgent and ReActTextWorldAgent. Both are deprecated alongside their agents (0.1.0 / removed 1.0). They make concrete what the code in base.py only implies: that the loop's control protocol is entirely a text convention.
Template variables
Both prompts share the same two input variables:
| Variable | Role |
|---|---|
{input} |
Task or question — filled once at invocation |
{agent_scratchpad} |
Growing string of Thought:/Action:/Observation: turns — appended to each iteration |
# wiki_prompt.py
SUFFIX = """\nQuestion: {input}
{agent_scratchpad}"""
WIKI_PROMPT = PromptTemplate.from_examples(EXAMPLES, SUFFIX, ["input", "agent_scratchpad"])
# textworld_prompt.py
SUFFIX = """\n\nSetup: {input}
{agent_scratchpad}"""
TEXTWORLD_PROMPT = PromptTemplate.from_examples(EXAMPLES, SUFFIX, ["input", "agent_scratchpad"])
PromptTemplate.from_examples() concatenates static few-shot demonstrations (showing the full Thought/Action/Observation/Finish cycle) followed by the dynamic SUFFIX. The few-shot examples teach the LLM the text protocol.
Control signals — all plain text
| Signal | Text form | Who produces it |
|---|---|---|
| Tool call | Action: ToolName[argument] |
LLM (plain text) |
| Exit | Action: Finish[answer] |
LLM (plain text) |
| Stop generation | stop token "\nObservation:" |
Framework (injected) |
| LLM turn prefix | "Thought:" |
Framework (llm_prefix property) |
| Result injection | "Observation: <result>" |
Framework (appended to scratchpad) |
Tool names appear literally in text:
- Wiki:
Search[query],Lookup[term],Finish[answer] - TextWorld:
Play[command],Finish[yes/no]
ReActOutputParser reads Action: / Action Input: lines from the LLM's output via string matching to determine what to execute next.
The prompt-as-protocol insight
The entire agent loop control protocol is a shared text contract between:
- The prompt template (
{agent_scratchpad}slot) - The few-shot examples (demonstrate the format)
- The output parser (
ReActOutputParserreadsAction:lines) - The framework loop (injects stop tokens, appends observations)
There is no structured object. The LLM doesn't "call" a tool — it writes text that looks like a tool call, and the parser interprets it. This means:
- Tool name validity is enforced only at construction (not at parse time)
- Parallel execution is impossible (the text is sequential by nature)
- Any deviation in format (wrong casing, extra whitespace) can silently fail
Contrast with modern tool-call loops
Modern loops (LangGraph, pi-mono, Hermes) replace this entirely: the LLM emits a structured tool_calls array in its JSON response. The framework reads AIMessage.tool_calls directly — no text parsing, no stop tokens, no scratchpad string management. Tool invocation becomes a typed object; routing becomes a function on that object. The text convention is gone.
Related wiki pages
- LangChain ReAct Agent Loop (Legacy) — updated with prompt template detail
- Source - LangChain Agent Loop — broader source including LangGraph
- LangChain LangGraph Agent Loop (Modern) — the replacement
- Agent Loop Evolution — full cross-framework analysis