使用 LangChain 构建 ReAct Agent
使用 LangChain 的 AgentExecutor 组装完整的 ReAct Agent,配备网页搜索工具、计算器工具和文档查询工具,然后追踪其推理步骤。
使用 LangChain 构建 ReAct Agent 是 CoddyKit 上的免费 AI Engineering Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 AI Engineering Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 AI Engineering Academy 课程共包含 4 节课。
本课时的部分内容尚未翻译,以英文显示。
LangChain's Agent Ecosystem
LangChain provides a complete stack for building agents: tools define what the agent can do, prompts give it its instructions and reasoning format, the LLM does the thinking, and the AgentExecutor runs the loop that dispatches tool calls and feeds observations back. You configure each piece separately so you can swap components without rewriting everything.
Assembling a ReAct Agent
The quickest way to build a ReAct agent in LangChain is with create_react_agent. You pass it an LLM, a list of tools, and a prompt template. It returns a runnable that generates Thought/Action/Observation steps automatically. Wrap it in an AgentExecutor to manage the loop.
from langchain import hub
from langchain.agents import create_react_agent, AgentExecutor
from langchain_openai import ChatOpenAI
from langchain_core.tools import tool
# 1. Define tools
@tool
def search(query: str) -> str:
'''Search the web for current information. Input: a search query string.'''
return f'Search results for "{query}": [mock result]'
@tool
def calculator(expression: str) -> str:
'''Evaluate a math expression. Input: a valid Python math expression.'''
try:
return str(eval(expression))
except Exception as e:
return str(e)
tools = [search, calculator]
# 2. Load a ReAct prompt template
prompt = hub.pull('hwchase17/react')
# 3. Create the agent
llm = ChatOpenAI(model='gpt-4o', temperature=0)
agent = create_react_agent(llm, tools, prompt)Running with AgentExecutor
AgentExecutor manages the Thought/Action/Observation loop. Pass verbose=True during development to print every step to the console — this trace is invaluable for debugging. The max_iterations parameter is your safety valve against infinite loops.
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
verbose=True, # Print each step
max_iterations=10, # Safety limit
handle_parsing_errors=True # Don't crash on format errors
)
# Invoke with a user question
result = agent_executor.invoke({
'input': 'What is the square root of 144 multiplied by the number of days in a leap year?'
})
print('Final answer:', result['output'])Reading the Verbose Trace
The verbose trace shows exactly how the agent reasons. Each iteration prints the model's Thought, the Action it chose, and the Observation from the tool. This lets you spot exactly where the agent goes wrong — whether it chose the wrong tool, passed the wrong argument, or misread the observation.
# Example verbose output from AgentExecutor:
#
# > Entering new AgentExecutor chain...
# Thought: I need to find the square root of 144 first, then multiply by days in a leap year.
# Action: calculator
# Action Input: 144 ** 0.5
# Observation: 12.0
# Thought: 12.0 times 366 days in a leap year.
# Action: calculator
# Action Input: 12.0 * 366
# Observation: 4392.0
# Thought: I have the final answer.
# Final Answer: 4392.0
# > Finished chain.Using Built-In LangChain Tools
LangChain ships with many ready-made tools for common tasks. You can add a web search tool from langchain_community.tools without writing any code. These tools handle API authentication and response parsing for you.
from langchain_community.tools import DuckDuckGoSearchRun
from langchain_community.tools import WikipediaQueryRun
from langchain_community.utilities import WikipediaAPIWrapper
# Web search tool
search_tool = DuckDuckGoSearchRun()
# Wikipedia lookup tool
wiki_tool = WikipediaQueryRun(
api_wrapper=WikipediaAPIWrapper(top_k_results=2)
)
# Add to your agent
tools_with_search = [search_tool, wiki_tool, calculator]
agent_executor.tools = tools_with_searchDocument Lookup as a RAG Tool
One of the most powerful patterns is exposing your RAG pipeline as an agent tool. The agent decides when to retrieve from your knowledge base versus when to use other tools or rely on its training. This makes your RAG system dynamic — the agent calls it only when relevant.
from langchain_core.tools import tool
@tool
def lookup_knowledge_base(query: str) -> str:
'''Search the company knowledge base for internal policies, procedures, and documentation.
Use when the user asks about company-specific information not available publicly.
Input: a natural language question or keyword query.
'''
# Your RAG pipeline here
retrieved_chunks = vector_store.similarity_search(query, k=3)
context = '\n'.join([doc.page_content for doc in retrieved_chunks])
return context if context else 'No relevant documents found.'Streaming Agent Output
For a better user experience, stream the agent's final answer token by token rather than waiting for the full response. Use agent_executor.astream_events to receive events as they occur, including intermediate steps and the final output stream.
import asyncio
async def stream_agent(user_input: str):
async for event in agent_executor.astream_events(
{'input': user_input},
version='v1'
):
kind = event['event']
if kind == 'on_chat_model_stream':
chunk = event['data']['chunk']
if chunk.content:
print(chunk.content, end='', flush=True)
elif kind == 'on_tool_start':
print(f'\n[Calling tool: {event["name"]}]')
elif kind == 'on_tool_end':
print(f'[Tool result: {str(event["data"]["output"])[:100]}]')
asyncio.run(stream_agent('What is the latest news about AI?'))Passing Agent Memory
Combine agent reasoning with conversation memory so the agent remembers previous interactions. Use RunnableWithMessageHistory to wrap the agent executor and provide a chat history store. The agent then has both memory of past turns and the ability to call tools.
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain_community.chat_message_histories import ChatMessageHistory
session_store = {}
def get_session_history(session_id: str):
if session_id not in session_store:
session_store[session_id] = ChatMessageHistory()
return session_store[session_id]
agent_with_memory = RunnableWithMessageHistory(
agent_executor,
get_session_history,
input_messages_key='input',
history_messages_key='chat_history'
)Customizing the ReAct Prompt
The default hub prompt works well, but you often need a custom system prompt for your specific domain. A custom prompt lets you add persona instructions, output formatting rules, and domain-specific guidance before the tool descriptions. Use ChatPromptTemplate with the required ReAct placeholders.
from langchain_core.prompts import ChatPromptTemplate
custom_prompt = ChatPromptTemplate.from_messages([
('system', '''You are a helpful customer support agent for TechCorp.
Always be polite and professional. When you do not know something, use your tools.
You have access to these tools:
{tools}
Tool names: {tool_names}
Use this format:
Thought: ...
Action: tool_name
Action Input: input_value
Observation: result
Final Answer: your response to the customer
'''),
('human', '{input}'),
('assistant', '{agent_scratchpad}')
])
agent = create_react_agent(llm, tools, custom_prompt)Observing Agent Reasoning Steps
The AgentExecutor returns intermediate steps alongside the final output when you set return_intermediate_steps=True. Each step is a tuple of the agent's action and the tool's observation. This is useful for building UIs that show the agent's reasoning process to users.
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
return_intermediate_steps=True
)
result = agent_executor.invoke({'input': 'What is 2 to the power of 10?'})
print('Final answer:', result['output'])
print('Reasoning steps:')
for step in result['intermediate_steps']:
action, observation = step
print(f' Tool: {action.tool}, Input: {action.tool_input}')
print(f' Observation: {observation}')Testing Your Agent Thoroughly
Test your agent against a suite of representative questions covering: single-tool tasks, multi-hop tasks requiring several tool calls, tasks where no tool is needed (model answers from training data), and adversarial inputs like questions designed to confuse tool selection. Track pass rates and failure patterns to improve your tool descriptions and prompt.
Quick Check
Test your understanding of building a ReAct agent with LangChain.
Lesson Recap
In this lesson you learned: create_react_agent assembles an LLM, tools, and a prompt into a ReAct agent, AgentExecutor manages the Thought/Action/Observation loop with configurable safety limits, and verbose=True and return_intermediate_steps=True give you full visibility into agent reasoning. Next up we learn how to handle agent failures and prevent infinite loops.
常见问题解答
「使用 LangChain 构建 ReAct Agent」课时是免费的吗?
是的 — 「使用 LangChain 构建 ReAct Agent」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 AI Engineering Academy 课程的其余内容,请升级到 CoddyKit PRO。 AI Engineering Academy 课程共包含 4 节课。
「使用 LangChain 构建 ReAct Agent」这节课中我会学到什么?
使用 LangChain 的 AgentExecutor 组装完整的 ReAct Agent,配备网页搜索工具、计算器工具和文档查询工具,然后追踪其推理步骤。 你通过在浏览器中直接运行的动手代码来练习 AI Engineering Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 AI Engineering Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 AI Engineering Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。
「使用 LangChain 构建 ReAct Agent」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 AI Engineering Academy 课中编写并运行代码吗?
能。每节 AI Engineering Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- ReAct 框架:思考、行动、观察
- 为您的 Agent 定义工具
- 使用 LangChain 构建 ReAct Agent
- 处理智能体故障与循环