🔄 ReAct Pattern: Reasoning + Acting
ReAct (Reasoning and Acting) là pattern quan trọng nhất trong AI Agents. Bài này sẽ giúp bạn hiểu và implement ReAct pattern.
ReAct là gì?
ReAct Definition
ReAct kết hợp:
- Reasoning: LLM suy nghĩ và phân tích
- Acting: Thực hiện actions dựa trên suy nghĩ
- Observing: Quan sát kết quả từ actions
Vòng lặp ReAct:
Diagram
graph LR
T[Thought] --> A[Action]
A --> O[Observation]
O --> T
O -->|Done| F[Final Answer]Cấu trúc ReAct Loop
Mỗi bước trong ReAct loop gồm 3 phần:
Text
1Thought: [LLM suy nghĩ về vấn đề]2Action: [Tool/function cần gọi]3Observation: [Kết quả từ action]Ví dụ cụ thể
Question: "Thời tiết hôm nay ở Hà Nội thế nào?"
Text
1Thought: Tôi cần tìm thông tin thời tiết ở Hà Nội. 2 Tôi sẽ sử dụng tool get_weather.3 4Action: get_weather(city="Hanoi")5 6Observation: {"temp": 25, "condition": "sunny", "humidity": 65}7 8Thought: Đã có thông tin thời tiết. Tôi sẽ tổng hợp 9 và trả lời người dùng.10 11Action: final_answer("Hà Nội hôm nay trời nắng, 12 nhiệt độ 25°C, độ ẩm 65%.")Implement ReAct với LangChain
Step 1: Define Tools
Python
1from langchain.tools import tool2from langchain_community.tools import DuckDuckGoSearchRun34@tool5def get_weather(city: str) -> str:6 """7 Lấy thông tin thời tiết hiện tại của một thành phố.8 9 Args:10 city: Tên thành phố (tiếng Anh)11 12 Returns:13 Thông tin thời tiết dạng JSON14 """15 # Giả lập API call16 import json17 weather_data = {18 "city": city,19 "temperature": 25,20 "condition": "Sunny",21 "humidity": 6522 }23 return json.dumps(weather_data)2425@tool26def calculate(expression: str) -> str:27 """28 Tính toán biểu thức toán học.29 30 Args:31 expression: Biểu thức cần tính (ví dụ: "2 + 2 * 3")32 33 Returns:34 Kết quả tính toán35 """36 try:37 result = eval(expression)38 return str(result)39 except Exception as e:40 return f"Error: {str(e)}"4142# Search tool43search = DuckDuckGoSearchRun()4445tools = [get_weather, calculate, search]Step 2: Create ReAct Prompt
Python
1from langchain.prompts import PromptTemplate23react_prompt = PromptTemplate.from_template("""4Bạn là một AI assistant hữu ích. Trả lời câu hỏi bằng cách 5suy nghĩ từng bước và sử dụng tools khi cần.67Bạn có access đến các tools sau:8{tools}910Format response của bạn:1112Question: câu hỏi cần trả lời13Thought: suy nghĩ về cách giải quyết14Action: tên_tool[input]15Observation: kết quả từ tool16... (lặp lại Thought/Action/Observation nếu cần)17Thought: Tôi đã có đủ thông tin18Final Answer: câu trả lời cuối cùng1920Bắt đầu!2122Question: {input}23Thought: {agent_scratchpad}24""")Step 3: Create Agent
Python
1from langchain.agents import create_react_agent, AgentExecutor2from langchain_openai import ChatOpenAI34# Initialize LLM5llm = ChatOpenAI(model="gpt-4o", temperature=0)67# Create ReAct agent8agent = create_react_agent(9 llm=llm,10 tools=tools,11 prompt=react_prompt12)1314# Create executor15agent_executor = AgentExecutor(16 agent=agent,17 tools=tools,18 verbose=True, # Xem chi tiết reasoning19 max_iterations=5, # Giới hạn số bước20 handle_parsing_errors=True21)Step 4: Run Agent
Python
1# Test agent2response = agent_executor.invoke({3 "input": "Thời tiết Hà Nội hôm nay thế nào? Nếu nhiệt độ > 30 thì tính 30 * 1.5"4})56print(response["output"])Output (verbose=True):
Text
1> Entering new AgentExecutor chain...2 3Thought: Tôi cần kiểm tra thời tiết Hà Nội trước, 4sau đó quyết định có cần tính toán không.5 6Action: get_weather[Hanoi]7Observation: {"city": "Hanoi", "temperature": 25, "condition": "Sunny", "humidity": 65}8 9Thought: Nhiệt độ là 25°C, không lớn hơn 30, 10nên không cần tính toán. Tôi có thể trả lời.11 12Final Answer: Thời tiết Hà Nội hôm nay nắng đẹp, 13nhiệt độ 25°C, độ ẩm 65%. Vì nhiệt độ không vượt quá 1430°C nên không cần thực hiện phép tính.15 16> Finished chain.ReAct với LangGraph
LangGraph cung cấp cách build ReAct agents linh hoạt hơn:
Python
1from langgraph.prebuilt import create_react_agent2from langchain_openai import ChatOpenAI34# Cách đơn giản với LangGraph5llm = ChatOpenAI(model="gpt-4o")67graph = create_react_agent(8 model=llm,9 tools=tools,10 state_modifier="Bạn là AI assistant thông minh."11)1213# Invoke14result = graph.invoke({15 "messages": [("user", "Tìm thông tin về Python 3.12")]16})Advanced: Custom ReAct Logic
Khi cần control flow phức tạp hơn:
Python
1from langgraph.graph import StateGraph, END2from typing import TypedDict, Annotated3import operator45class AgentState(TypedDict):6 messages: Annotated[list, operator.add]7 next_step: str89def reasoning_node(state: AgentState):10 """LLM reasoning step"""11 messages = state["messages"]12 response = llm.invoke(messages)13 14 if "FINAL ANSWER" in response.content:15 return {"messages": [response], "next_step": "end"}16 else:17 return {"messages": [response], "next_step": "action"}1819def action_node(state: AgentState):20 """Execute tool based on LLM decision"""21 last_message = state["messages"][-1]22 tool_call = parse_tool_call(last_message)23 24 result = execute_tool(tool_call)25 26 return {27 "messages": [f"Observation: {result}"],28 "next_step": "reasoning"29 }3031def route(state: AgentState):32 return state["next_step"]3334# Build graph35workflow = StateGraph(AgentState)36workflow.add_node("reasoning", reasoning_node)37workflow.add_node("action", action_node)3839workflow.add_conditional_edges(40 "reasoning",41 route,42 {43 "action": "action",44 "end": END45 }46)47workflow.add_edge("action", "reasoning")4849workflow.set_entry_point("reasoning")50graph = workflow.compile()Best Practices cho ReAct
1. Tool Descriptions rõ ràng
Python
1@tool2def search_products(query: str, category: str = None, max_price: float = None) -> str:3 """4 Tìm kiếm sản phẩm trong database.5 6 QUAN TRỌNG: Chỉ sử dụng tool này khi user hỏi về sản phẩm.7 8 Args:9 query: Từ khóa tìm kiếm (bắt buộc)10 category: Danh mục sản phẩm (optional): electronics, clothing, books11 max_price: Giá tối đa (optional)12 13 Returns:14 Danh sách sản phẩm phù hợp dạng JSON15 16 Examples:17 - search_products("laptop gaming")18 - search_products("áo", category="clothing", max_price=500000)19 """20 # Implementation2. Handle Errors gracefully
Python
1agent_executor = AgentExecutor(2 agent=agent,3 tools=tools,4 handle_parsing_errors=True, # Tự động retry khi parse error5 max_iterations=5, # Tránh infinite loops6 early_stopping_method="generate" # Tạo response khi max iterations7)3. Add Fallbacks
Python
1from langchain_core.runnables import RunnableWithFallbacks23# Fallback khi GPT-4 fail4agent_with_fallback = agent_executor.with_fallbacks([5 fallback_agent_executor # Dùng GPT-3.5 như backup6])Bài tập thực hành
Hands-on Exercise
Build một ReAct Agent đơn giản:
-
Tạo 3 tools:
get_current_time(): Trả về thời gian hiện tạisearch_wikipedia(query): Tìm trên Wikipediacalculate(expression): Tính toán
-
Create ReAct agent với LangChain
-
Test với các câu hỏi:
- "Mấy giờ rồi?"
- "Albert Einstein sinh năm nào?"
- "Tính 15% của 2000"
- "Einstein sống được bao nhiêu tuổi?" (cần combine tools)
Python
1# Starter code2from langchain.tools import tool3from langchain_openai import ChatOpenAI4from langchain.agents import create_react_agent, AgentExecutor56# TODO: Define your tools7@tool8def get_current_time() -> str:9 """Lấy thời gian hiện tại"""10 from datetime import datetime11 return datetime.now().strftime("%Y-%m-%d %H:%M:%S")1213# TODO: Add more tools1415# TODO: Create agent1617# TODO: Test agentTiếp theo
Trong bài tiếp theo, chúng ta sẽ học về LangGraph Basics - framework mạnh mẽ để build complex agent workflows.
