文章目录
React范式
逻辑:ought → Action → Observation循环
python
from langchain_openai import ChatOpenAI
from langgraph.graph import StateGraph, END
from typing import TypedDict, Annotated
import operator
# ----------------------
# 1. 定义状态
# ----------------------
class ReActState(TypedDict):
question: str
thought: str # 思考
action: str # 动作
observation: str # 观察结果
history: list
# ----------------------
# 2. 定义工具(搜索)
# ----------------------
def search_tool(query: str) -> str:
# 模拟搜索
return f"模拟搜索结果:{query} 的结果是北京今天25度"
# ----------------------
# 3. ReAct 核心节点
# ----------------------
llm = ChatOpenAI(model="gpt-3.5-turbo")
def think_node(state: ReActState):
# LLM 思考下一步
prompt = f"问题:{state['question']} 历史:{state['history']} 请思考下一步"
state["thought"] = llm.invoke(prompt).content
return state
def act_node(state: ReActState):
# 执行动作:调用工具
state["action"] = "搜索"
state["observation"] = search_tool(state["question"])
state["history"].append(f"执行:{state['action']} 结果:{state['observation']}")
return state
def should_continue(state):
# 判断是否结束
if "25度" in state["observation"]:
return END
else:
return "think"
# ----------------------
# 4. 构建 ReAct 图
# ----------------------
workflow = StateGraph(ReActState)
workflow.add_node("think", think_node)
workflow.add_node("act", act_node)
workflow.set_entry_point("think")
workflow.add_edge("think", "act")
workflow.add_conditional_edges("act", should_continue)
app = workflow.compile()
# ----------------------
# 运行 ReAct
# ----------------------
if __name__ == "__main__":
result = app.invoke({
"question": "北京今天气温多少",
"history": []
})
print("最终结果:", result["observation"])
底层就是 LangGraph 图结构
但是LangChain / LangGraph 早就内置了标准的 ReAct 循环(Thought → Action → Observation),不需要自己手动定义 think /act/should_continue 节点
python
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent # 🔥 官方内置ReAct循环
from langchain_core.tools import tool
from typing import Annotated, Literal
import os
os.environ["OPENAI_API_KEY"] = "sk-..."
# ----------------------
# 1. 定义工具(你只需要写这个)
# ----------------------
@tool
def search(query: str) -> str:
"""搜索信息"""
return f"【搜索结果】{query}:北京今天气温25℃,晴"
@tool
def calculator(expr: str) -> str:
"""计算表达式"""
return f"【计算结果】{expr} = {eval(expr)}"
tools = [search, calculator]
# ----------------------
# 2. 初始化LLM
# ----------------------
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)
# ----------------------
# 3. 🔥 直接创建ReAct Agent(内置完整Thought/Action/Observation循环)
# ----------------------
agent_executor = create_react_agent(
model=llm,
tools=tools,
# 可选:自定义prompt、记忆、重试、状态
)
# ----------------------
# 4. 运行(自动执行ReAct循环)
# ----------------------
if __name__ == "__main__":
response = agent_executor.invoke({
"messages": [
("user", "北京今天多少度?再算25+17等于多少")
]
})
# 打印最终回答
print("="*50)
print("最终回答:", response["messages"][-1].content)
2.Plan-Execute范式
- Plan-Execute 则是 "先生成计划、再顺序执行" 的两层结构
- Plan--Execute 有很多变种:
要不要 replan(重计划)?
步骤并行还是串行?
执行失败是否重试?
官方不想定死一种结构,所以只给标准模板让你自己搭。
python
from langchain_openai import ChatOpenAI
from langgraph.graph import StateGraph, END
from typing import TypedDict
# ----------------------
# 1. 状态
# ----------------------
class PlanExecuteState(TypedDict):
question: str
plan: list[str] # 完整计划
current_step: int
result: str
# ----------------------
# 2. LLM
# ----------------------
llm = ChatOpenAI(model="gpt-3.5-turbo")
# ----------------------
# 3. Plan 节点(先拆完整计划)
# ----------------------
def plan_node(state: PlanExecuteState):
# 一次性生成完整计划
prompt = f"给任务:{state['question']},生成步骤计划"
plan = llm.invoke(prompt).content.split("\n")
state["plan"] = plan
state["current_step"] = 0
return state
# ----------------------
# 4. Execute 节点(按计划执行)
# ----------------------
def execute_node(state: PlanExecuteState):
step = state["plan"][state["current_step"]]
# 模拟执行
state["result"] = f"执行:{step} → 结果:北京25度"
state["current_step"] += 1
return state
# ----------------------
# 5. 判断:继续 or 结束
# ----------------------
def should_next(state):
if state["current_step"] >= len(state["plan"]):
return END
else:
return "execute"
# ----------------------
# 6. 构建 Plan-Execute 图
# ----------------------
workflow = StateGraph(PlanExecuteState)
workflow.add_node("plan", plan_node)
workflow.add_node("execute", execute_node)
workflow.set_entry_point("plan")
workflow.add_edge("plan", "execute")
workflow.add_conditional_edges("execute", should_next)
app = workflow.compile()
# ----------------------
# 运行
# ----------------------
if __name__ == "__main__":
result = app.invoke({
"question": "查询北京今日气温"
})
print("完整计划:", result["plan"])
print("执行结果:", result["result"])
底层就是 LangGraph 图结构
LangGraph(主框架):没有官方 create_plan_execute_agent() 这种一键封装,但官方有标准模板(你几乎不用改)
python
from langchain_openai import ChatOpenAI
from langgraph.graph import StateGraph, END, START
from langgraph.prebuilt import create_react_agent
from langchain_core.tools import tool
from langchain_core.pydantic_v1 import BaseModel, Field
from typing import List, TypedDict
# ----------------------
# 1. 工具
# ----------------------
@tool
def search(query: str) -> str:
return f"搜索:{query} → 北京25℃"
@tool
def calculator(expr: str) -> str:
return f"计算:{expr} = {eval(expr)}"
tools = [search, calculator]
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)
# ----------------------
# 2. 状态与结构化输出(官方固定写法)
# ----------------------
class Plan(BaseModel):
steps: List[str] = Field(description="计划步骤列表")
class PlanExecuteState(TypedDict):
input: str
plan: List[str]
past_steps: List
response: str
# ----------------------
# 3. Planner(LLM生成结构化计划)
# ----------------------
planner = (
llm.with_structured_output(Plan)
)
def plan_step(state: PlanExecuteState):
plan = planner.invoke(
f"把任务拆成清晰步骤:{state['input']}"
)
return {"plan": plan.steps}
# ----------------------
# 4. Executor(复用内置ReAct执行单步)
# ----------------------
react_agent = create_react_agent(llm, tools)
def execute_step(state: PlanExecuteState):
step = state["plan"][0]
resp = react_agent.invoke({"messages": [("user", step)]})
return {
"plan": state["plan"][1:],
"past_steps": [(step, resp["messages"][-1].content)],
}
# ----------------------
# 5. 路由
# ----------------------
def should_continue(state: PlanExecuteState):
if not state["plan"]:
return END
else:
return "execute"
# ----------------------
# 6. 构建图(官方标准结构)
# ----------------------
workflow = StateGraph(PlanExecuteState)
workflow.add_node("plan", plan_step)
workflow.add_node("execute", execute_step)
workflow.add_edge(START, "plan")
workflow.add_edge("plan", "execute")
workflow.add_conditional_edges("execute", should_continue)
app = workflow.compile()
# ----------------------
# 运行
# ----------------------
if __name__ == "__main__":
res = app.invoke({
"input": "查北京天气,再算25+17,最后总结",
"plan": [],
"past_steps": [],
})
print("计划:", res["plan"])
print("历史:", res["past_steps"])