AI Agent白手起家68: 智能体优化——计划执行与反思模式实战

纲要

  • 智能体优化的必要性
  • 计划与执行模式
    • 核心原理
    • 流程与节点设计
    • 完整可运行示例
  • 反思模式
    • 核心原理
    • 流程与节点设计
    • 完整可运行示例
  • 两种模式的对比与选型建议
  • 总结与相关度说明

智能体优化的必要性

在之前的实践中,我们构建了单智能体和多智能体应用,但基础的 React 循环在处理复杂、需要多步推理的任务时,往往缺乏全局视角和自我修正能力。为此,业界提出了多种架构优化方案,其中计划与执行反思 是两种最经典且实用的模式。它们同样可以基于 LangGraph 实现,通过引入规划或批判节点,显著提升输出质量。

计划与执行模式

核心原理

计划与执行模式模拟人类解决复杂问题的过程:先整体规划,再逐步执行,并在执行中动态调整计划。其工作流包含三个关键阶段:

  • 规划:根据用户目标生成任务步骤清单。
  • 执行:逐项完成清单中的任务,每个子任务可由独立工具或智能体处理。
  • 重规划:检查已完成的步骤结果,更新计划,可能添加新步骤或调整顺序,直至获得最终答案。

#mermaid-svg-qcCUxj3DonDheeaN{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-qcCUxj3DonDheeaN .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-qcCUxj3DonDheeaN .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-qcCUxj3DonDheeaN .error-icon{fill:#552222;}#mermaid-svg-qcCUxj3DonDheeaN .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-qcCUxj3DonDheeaN .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-qcCUxj3DonDheeaN .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-qcCUxj3DonDheeaN .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-qcCUxj3DonDheeaN .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-qcCUxj3DonDheeaN .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-qcCUxj3DonDheeaN .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-qcCUxj3DonDheeaN .marker{fill:#333333;stroke:#333333;}#mermaid-svg-qcCUxj3DonDheeaN .marker.cross{stroke:#333333;}#mermaid-svg-qcCUxj3DonDheeaN svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-qcCUxj3DonDheeaN p{margin:0;}#mermaid-svg-qcCUxj3DonDheeaN .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-qcCUxj3DonDheeaN .cluster-label text{fill:#333;}#mermaid-svg-qcCUxj3DonDheeaN .cluster-label span{color:#333;}#mermaid-svg-qcCUxj3DonDheeaN .cluster-label span p{background-color:transparent;}#mermaid-svg-qcCUxj3DonDheeaN .label text,#mermaid-svg-qcCUxj3DonDheeaN span{fill:#333;color:#333;}#mermaid-svg-qcCUxj3DonDheeaN .node rect,#mermaid-svg-qcCUxj3DonDheeaN .node circle,#mermaid-svg-qcCUxj3DonDheeaN .node ellipse,#mermaid-svg-qcCUxj3DonDheeaN .node polygon,#mermaid-svg-qcCUxj3DonDheeaN .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-qcCUxj3DonDheeaN .rough-node .label text,#mermaid-svg-qcCUxj3DonDheeaN .node .label text,#mermaid-svg-qcCUxj3DonDheeaN .image-shape .label,#mermaid-svg-qcCUxj3DonDheeaN .icon-shape .label{text-anchor:middle;}#mermaid-svg-qcCUxj3DonDheeaN .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-qcCUxj3DonDheeaN .rough-node .label,#mermaid-svg-qcCUxj3DonDheeaN .node .label,#mermaid-svg-qcCUxj3DonDheeaN .image-shape .label,#mermaid-svg-qcCUxj3DonDheeaN .icon-shape .label{text-align:center;}#mermaid-svg-qcCUxj3DonDheeaN .node.clickable{cursor:pointer;}#mermaid-svg-qcCUxj3DonDheeaN .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-qcCUxj3DonDheeaN .arrowheadPath{fill:#333333;}#mermaid-svg-qcCUxj3DonDheeaN .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-qcCUxj3DonDheeaN .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-qcCUxj3DonDheeaN .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-qcCUxj3DonDheeaN .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-qcCUxj3DonDheeaN .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-qcCUxj3DonDheeaN .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-qcCUxj3DonDheeaN .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-qcCUxj3DonDheeaN .cluster text{fill:#333;}#mermaid-svg-qcCUxj3DonDheeaN .cluster span{color:#333;}#mermaid-svg-qcCUxj3DonDheeaN div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-qcCUxj3DonDheeaN .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-qcCUxj3DonDheeaN rect.text{fill:none;stroke-width:0;}#mermaid-svg-qcCUxj3DonDheeaN .icon-shape,#mermaid-svg-qcCUxj3DonDheeaN .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-qcCUxj3DonDheeaN .icon-shape p,#mermaid-svg-qcCUxj3DonDheeaN .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-qcCUxj3DonDheeaN .icon-shape .label rect,#mermaid-svg-qcCUxj3DonDheeaN .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-qcCUxj3DonDheeaN .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-qcCUxj3DonDheeaN .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-qcCUxj3DonDheeaN :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 还有未完成步骤
全部完成
用户目标
规划节点: 生成步骤列表
执行节点: 完成当前步骤
重规划节点: 评估进度
输出最终答案

该模式的长处在于清晰的长期计划,且执行子任务时可使用较弱模型以降低成本。缺点是延迟较高,不适合实时对话场景。

完整可运行示例

下面使用 LangGraph 构建一个简化的计划与执行智能体,它会先制定步骤,然后调用模拟搜索工具逐步执行。

首先安装依赖:

bash 复制代码
pip install langgraph langchain-openai python-dotenv
python 复制代码
# plan_execute.py
import os
from typing import TypedDict, List
from dotenv import load_dotenv
from langgraph.graph import StateGraph, END
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from pydantic import BaseModel, Field
from langgraph.checkpoint.memory import MemorySaver

load_dotenv()

# ---------- 结构化输出模型 ----------
class Plan(BaseModel):
    steps: List[str] = Field(description="执行步骤列表")

class Act(BaseModel):
    action: str = Field(description="'plan' 表示继续执行,'response' 表示直接回答")
    updated_plan: List[str] = Field(default=[], description="更新后的剩余步骤")
    response: str = Field(default="", description="如果 action 为 response,则提供答案")

# ---------- 状态定义 ----------
class PlanExecuteState(TypedDict):
    input: str
    plan: List[str]
    executed_steps: List[str]
    final_answer: str

# ---------- LLM 初始化 ----------
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)
planner_llm = llm.with_structured_output(Plan)
replanner_llm = llm.with_structured_output(Act)

# ---------- 模拟搜索工具 ----------
def fake_search(query: str) -> str:
    if "短跑" in query or "女子" in query:
        return "中国女子短跑最快选手是韦永丽,成绩为10.99秒。"
    return "未找到相关信息。"

# ---------- 节点函数 ----------
def planner_node(state: PlanExecuteState) -> PlanExecuteState:
    prompt = ChatPromptTemplate.from_template(
        "针对以下目标,制定一个简单的逐步计划,每步应独立且可执行,最后一步结果应为最终答案。\n"
        "目标:{input}\n计划:"
    )
    chain = prompt | planner_llm
    plan = chain.invoke({"input": state["input"]})
    return {"plan": plan.steps, "executed_steps": []}

def agent_node(state: PlanExecuteState) -> PlanExecuteState:
    if not state["plan"]:
        return state
    step = state["plan"][0]   # 取第一个未执行的步骤
    result = fake_search(step)
    executed = state.get("executed_steps", []) + [f"执行"{step}" → {result}"]
    return {"plan": state["plan"][1:], "executed_steps": executed}

def replanner_node(state: PlanExecuteState) -> PlanExecuteState:
    prompt = ChatPromptTemplate.from_template(
        "原始目标:{input}\n已完成步骤及结果:{executed}\n剩余步骤:{plan}\n"
        "请判断是否可以直接回答。如果可以,用 'response' 动作输出答案;否则用 'plan' 动作提供更新后的剩余步骤。"
    )
    chain = prompt | replanner_llm
    act = chain.invoke({
        "input": state["input"],
        "executed": state["executed_steps"],
        "plan": state["plan"]
    })
    if act.action == "response":
        return {"final_answer": act.response, "plan": []}
    return {"plan": act.updated_plan}

def route(state: PlanExecuteState) -> str:
    if state.get("final_answer"):
        return "end"
    return "continue" if state["plan"] else "end"

# ---------- 构建图 ----------
builder = StateGraph(PlanExecuteState)
builder.add_node("planner", planner_node)
builder.add_node("agent", agent_node)
builder.add_node("replanner", replanner_node)

builder.set_entry_point("planner")
builder.add_edge("planner", "agent")
builder.add_edge("agent", "replanner")
builder.add_conditional_edges("replanner", route, {"continue": "agent", "end": END})

memory = MemorySaver()
app = builder.compile(checkpointer=memory)

# ---------- 测试 ----------
if __name__ == "__main__":
    config = {"configurable": {"thread_id": "plan-demo"}}
    result = app.invoke({"input": "中国女子短跑最快的选手是谁?"}, config)
    if result.get("final_answer"):
        print("最终答案:", result["final_answer"])
    else:
        print("执行记录:", result["executed_steps"])

运行示例将看到智能体先规划步骤,再逐步执行并最终给出答案。

反思模式

核心原理

反思模式在生成器之后增加一个批判者角色,形成"写作→评审→改进"的循环。生成节点创建内容,反思节点给出详细反馈,生成节点据此修改,如此反复,直至满足质量要求。
#mermaid-svg-8CVJU0n2wHfJVKlQ{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-8CVJU0n2wHfJVKlQ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-8CVJU0n2wHfJVKlQ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-8CVJU0n2wHfJVKlQ .error-icon{fill:#552222;}#mermaid-svg-8CVJU0n2wHfJVKlQ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-8CVJU0n2wHfJVKlQ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-8CVJU0n2wHfJVKlQ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-8CVJU0n2wHfJVKlQ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-8CVJU0n2wHfJVKlQ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-8CVJU0n2wHfJVKlQ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-8CVJU0n2wHfJVKlQ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-8CVJU0n2wHfJVKlQ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-8CVJU0n2wHfJVKlQ .marker.cross{stroke:#333333;}#mermaid-svg-8CVJU0n2wHfJVKlQ svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-8CVJU0n2wHfJVKlQ p{margin:0;}#mermaid-svg-8CVJU0n2wHfJVKlQ .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-8CVJU0n2wHfJVKlQ .cluster-label text{fill:#333;}#mermaid-svg-8CVJU0n2wHfJVKlQ .cluster-label span{color:#333;}#mermaid-svg-8CVJU0n2wHfJVKlQ .cluster-label span p{background-color:transparent;}#mermaid-svg-8CVJU0n2wHfJVKlQ .label text,#mermaid-svg-8CVJU0n2wHfJVKlQ span{fill:#333;color:#333;}#mermaid-svg-8CVJU0n2wHfJVKlQ .node rect,#mermaid-svg-8CVJU0n2wHfJVKlQ .node circle,#mermaid-svg-8CVJU0n2wHfJVKlQ .node ellipse,#mermaid-svg-8CVJU0n2wHfJVKlQ .node polygon,#mermaid-svg-8CVJU0n2wHfJVKlQ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-8CVJU0n2wHfJVKlQ .rough-node .label text,#mermaid-svg-8CVJU0n2wHfJVKlQ .node .label text,#mermaid-svg-8CVJU0n2wHfJVKlQ .image-shape .label,#mermaid-svg-8CVJU0n2wHfJVKlQ .icon-shape .label{text-anchor:middle;}#mermaid-svg-8CVJU0n2wHfJVKlQ .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-8CVJU0n2wHfJVKlQ .rough-node .label,#mermaid-svg-8CVJU0n2wHfJVKlQ .node .label,#mermaid-svg-8CVJU0n2wHfJVKlQ .image-shape .label,#mermaid-svg-8CVJU0n2wHfJVKlQ .icon-shape .label{text-align:center;}#mermaid-svg-8CVJU0n2wHfJVKlQ .node.clickable{cursor:pointer;}#mermaid-svg-8CVJU0n2wHfJVKlQ .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-8CVJU0n2wHfJVKlQ .arrowheadPath{fill:#333333;}#mermaid-svg-8CVJU0n2wHfJVKlQ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-8CVJU0n2wHfJVKlQ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-8CVJU0n2wHfJVKlQ .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8CVJU0n2wHfJVKlQ .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-8CVJU0n2wHfJVKlQ .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8CVJU0n2wHfJVKlQ .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-8CVJU0n2wHfJVKlQ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-8CVJU0n2wHfJVKlQ .cluster text{fill:#333;}#mermaid-svg-8CVJU0n2wHfJVKlQ .cluster span{color:#333;}#mermaid-svg-8CVJU0n2wHfJVKlQ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-8CVJU0n2wHfJVKlQ .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-8CVJU0n2wHfJVKlQ rect.text{fill:none;stroke-width:0;}#mermaid-svg-8CVJU0n2wHfJVKlQ .icon-shape,#mermaid-svg-8CVJU0n2wHfJVKlQ .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8CVJU0n2wHfJVKlQ .icon-shape p,#mermaid-svg-8CVJU0n2wHfJVKlQ .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-8CVJU0n2wHfJVKlQ .icon-shape .label rect,#mermaid-svg-8CVJU0n2wHfJVKlQ .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8CVJU0n2wHfJVKlQ .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-8CVJU0n2wHfJVKlQ .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-8CVJU0n2wHfJVKlQ :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 需改进
已满意
用户请求
生成节点: 创建初稿
反思节点: 评审并给出建议
输出最终内容

该模式尤其适合需要反复打磨的创作任务,如文章撰写、代码优化等。缺点同样是多轮调用带来更高的延迟和成本。

完整可运行示例

构建一个文章撰写智能体,通过反思迭代提升文章质量。

python 复制代码
# reflection_writer.py
import os
from typing import TypedDict
from dotenv import load_dotenv
from langgraph.graph import StateGraph, END
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage
from langgraph.checkpoint.memory import MemorySaver

load_dotenv()

class WriterState(TypedDict):
    task: str
    draft: str
    feedback: str
    iteration: int

llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0.7)

def generate_draft(state: WriterState) -> WriterState:
    prompt = f"你是一名文章助手。任务:{state['task']}\n"
    if state.get("feedback"):
        prompt += f"上一次的反馈意见:{state['feedback']}\n请根据反馈修改文章。"
    response = llm.invoke([HumanMessage(content=prompt)])
    return {"draft": response.content, "iteration": state.get("iteration", 0) + 1}

def reflect_on_draft(state: WriterState) -> WriterState:
    prompt = f"你是一名严格编辑。请评审以下文章,指出不足并给出改进建议。\n文章:{state['draft']}\n建议:"
    response = llm.invoke([HumanMessage(content=prompt)])
    return {"feedback": response.content}

def should_continue(state: WriterState) -> str:
    return "end" if state.get("iteration", 0) >= 3 else "continue"

builder = StateGraph(WriterState)
builder.add_node("generator", generate_draft)
builder.add_node("reflector", reflect_on_draft)
builder.set_entry_point("generator")
builder.add_edge("generator", "reflector")
builder.add_conditional_edges("reflector", should_continue, {"continue": "generator", "end": END})

memory = MemorySaver()
app = builder.compile(checkpointer=memory)

if __name__ == "__main__":
    config = {"configurable": {"thread_id": "reflect-demo"}}
    final = app.invoke({"task": "写一篇关于科学用脑的短文,约300字,通俗易懂。"}, config)
    print("最终文章:\n", final["draft"])
    print("\n迭代次数:", final["iteration"])

运行后会看到文章在多轮反思后质量明显提升。

两种模式的对比与选型建议

维度 计划与执行 反思
核心思想 全局规划→逐步执行→动态调整 生成→评审→改进循环
典型应用 复杂多步任务、信息检索类 文案写作、代码优化等创造性任务
延迟 较高 较高
模型成本 规划节点可用强模型,执行节点可用弱模型 生成和反思节点均需一定能力
实现复杂度 较复杂,需要三个主要节点 相对简单,两个主要节点

两种模式可以组合使用,例如在计划执行的每个步骤中嵌入反思,以获得更好的效果。

总结

本博客详细讲解了智能体架构优化的两种经典模式:计划与执行、反思,并给出了基于 LangGraph 的完整可运行代码。掌握这些模式后,你可以根据任务需求选择合适的优化策略,或进行创新组合,从而构建更强大、更可靠的 AI 应用。

本文覆盖了计划与执行、反思的原理、流程和代码实现,并补充了示例代码。

相关推荐
刘海东刘海东1 小时前
类数据的结构型的赋予生命的加权逻辑方程结构图(简称结构图)
人工智能
a1122998211 小时前
AI搜索布局怎么选?GEO工具与SEO工具对比评测
人工智能
用户337922545681 小时前
Event-Sourced Session:AI Agent 的“会话即事件流“设计
人工智能
用户337922545681 小时前
DeepSeek Harness 架构解析:MCP 和 Skill 如何被统一为 Cordis 插件
人工智能
liuxiaocheng1 小时前
快速上手:5 分钟跑通第一个 AI SDK 例子
前端·人工智能·后端
cxr8281 小时前
上下文工程框架之11 模块与优先级链和冲突消解、淘汰与版本
人工智能·架构
代码方舟1 小时前
Java数据工程:利用天远车辆vin码查车辆信息详版优化抵押贷款合规体验
java·人工智能
Cosolar2 小时前
DeepSeek Harness 理解 Harness 的设计哲学 - 可组合的插件运行时
人工智能·设计模式·架构
DFT计算杂谈2 小时前
Janus单层Cr2SSe中的应变可调多压电效应与谷电子学
人工智能·算法·机器学习