课程0基础Agent开发课 / Agent基础 / Agent三大范式-ReAct-Plan-and-Solve-Reflection
— 29 min read

Agent三大范式-ReAct-Plan-and-Solve-Reflection

范式(Paradigm)是一种思维框架,它决定了 Agent 面对任务时的基本行为模式——先做什么、怎么决策、何时停止。

Agent 三大范式:ReAct、Plan-and-Solve、Reflection

为什么需要不同范式:任务结构决定执行策略

范式(Paradigm)是一种思维框架,它决定了 Agent 面对任务时的基本行为模式——先做什么、怎么决策、何时停止。

在理解具体范式之前,先想一个问题:同样是"帮我完成这个任务",为什么不同的任务需要不同的执行策略?

答案在于任务结构的差异。不同类型的任务有不同的结构特征,这些特征决定了什么样的执行策略最有效。

信息获取型任务("查一下 A 公司的最新财报数字")的结构特点是:需要实时数据,不知道需要查几步,每一步的结果决定下一步查什么。这类任务适合边想边做的策略——先试一步,看结果,再决定下一步,不需要提前规划全局。如果强行先做完整规划,会发现根本规划不了,因为第二步的内容取决于第一步查到了什么。

多步骤复杂任务("写一份完整的市场调研报告")的结构特点是:任务边界清晰,可以分解成明确的子任务,各子任务有依赖关系。这类任务适合先规划后执行——一次性想清楚整个任务的结构,按计划推进,方向不会跑偏。如果"边想边做",很可能在某个细节上钻进去,忘了整体目标。

质量敏感型任务("帮我审查这份法律合同")的结构特点是:输出质量至关重要,存在评估标准,但第一次做未必能达到标准。这类任务适合执行后反思——做完检查,不满意就改,直到质量达标。第一稿通常不是最好的,需要迭代。

三种范式——ReAct、Plan-and-Solve、Reflection——分别针对这三种任务结构。理解这一点,范式选择就从"记住规则"变成了"匹配任务结构"。

Agent 三大范式对比

图:ReAct(边想边做)、Plan-and-Solve(先规划再执行)、Reflection(执行后反思迭代)三种范式的执行流程对比。


面对同一个任务——"帮我分析一下这份财报,给出投资建议"——不同的 Agent 范式会走出完全不同的路径:

  • 一个 Agent 可能立刻去搜索公司背景,边搜边想,最后给出结论(ReAct)
  • 另一个 Agent 会先列出分析框架——收入趋势、利润结构、现金流、行业对比——然后逐项执行(Plan-and-Solve)
  • 还有一个 Agent 在给出初稿之后,会自己审查一遍,发现"我忽略了汇率风险",然后补充修改(Reflection)

这三种行为模式,对应了三种不同的范式。理解它们的工作原理和适用边界,是设计 Agent 架构的基础。


ReAct:边想边做

这个范式解决什么问题

在 ReAct 出现之前,让 LLM 使用工具的方式有两种:

  1. 让 LLM 直接生成工具调用,没有思考过程,模型容易在无需工具的情况下乱调工具
  2. 先让模型做完整推理,再执行,但推理脱离了真实数据,质量不高

ReAct 的洞察是:推理和行动应该交织在一起,不是先想好再做,也不是盲目行动。 每次行动之前先显式地思考"为什么要做这一步",每次行动之后观察结果再重新思考。这种思考-行动-观察的循环,比单纯推理或单纯行动都要好。

核心机制

ReAct(Reasoning + Acting 的缩写)来自 Shunyu Yao et al. 2022 年的论文。它的核心思路是:让模型交替输出"思考"和"行动",每次行动后把结果喂回去,继续下一轮思考。

循环是这样的:

用户输入

Thought 思考

Action 行动

Observation 观察

任务完成?

最终答案

一个典型的 ReAct 执行过程长这样:

code
Thought: 用户要分析财报,我需要先找到这份财报的具体数据。
Action: search("阿里巴巴 2024年Q3财报")
Observation: 营收为2365亿,同比增长5%,净利润436亿...

Thought: 有了基础数据,现在需要和上个季度对比。
Action: search("阿里巴巴 2024年Q2财报")
Observation: 营收为2432亿,净利润344亿...

Thought: Q3 营收环比下降,但利润增长明显。需要了解利润率变化原因。
Action: search("阿里巴巴 2024Q3 利润率改善原因")
Observation: 主要来自云计算业务盈利提升和降本增效...

Thought: 现在有足够信息了,可以给出分析。
Final Answer: 阿里巴巴Q3营收小幅下降但利润改善明显,核心原因是...

关键点:每次行动之前都有思考过程,模型不是盲目调用工具,而是先推理"现在应该做什么、为什么"。每次观察结果都会被追加进对话历史,模型的下一步决策基于完整的上下文。

代码实现

验证目的:通过一个包含搜索和计算工具的 ReAct Agent,观察"Thought-Action-Observation"循环的实际运行过程,理解 LLM 如何在每一步根据上一步的观察结果决定下一步行动。

python
from openai import OpenAI
import json

client = OpenAI()

def search(query: str) -> str:
    """模拟搜索工具"""
    # 实际场景接入 Tavily / SerpAPI 等真实搜索 API
    mock_results = {
        "阿里巴巴 2024Q3": "营收2365亿元,同比增长5%,净利润436亿元,云计算收入增长7%",
        "阿里巴巴 2024Q2": "营收2432亿元,净利润344亿元",
    }
    for key, value in mock_results.items():
        if key in query:
            return value
    return f"搜索结果:{query} 的相关信息..."

def calculate(expression: str) -> str:
    """模拟计算工具"""
    try:
        result = eval(expression)  # 实际场景应使用安全的表达式解析
        return str(result)
    except Exception as e:
        return f"计算错误: {e}"

tools = [
    {
        "type": "function",
        "function": {
            "name": "search",
            "description": "搜索互联网获取最新信息",
            "parameters": {
                "type": "object",
                "properties": {
                    "query": {"type": "string", "description": "搜索关键词"}
                },
                "required": ["query"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "calculate",
            "description": "执行数学计算",
            "parameters": {
                "type": "object",
                "properties": {
                    "expression": {"type": "string", "description": "数学表达式"}
                },
                "required": ["expression"]
            }
        }
    }
]

def react_agent(user_input: str) -> str:
    messages = [
        {
            "role": "system",
            "content": "你是一个分析助手。遇到需要数据支撑的问题,先搜索再分析,每步都先想清楚再行动。"
        },
        {"role": "user", "content": user_input}
    ]

    tool_map = {"search": search, "calculate": calculate}

    max_iterations = 10  # 防止无限循环的安全上限
    for iteration in range(max_iterations):
        response = client.chat.completions.create(
            model="gpt-4o",
            messages=messages,
            tools=tools,
        )

        message = response.choices[0].message

        # LLM 决定直接回答,ReAct 循环结束
        if message.tool_calls is None:
            return message.content

        # LLM 决定调用工具(ReAct 的 Action 阶段)
        messages.append(message)

        for tool_call in message.tool_calls:
            func_name = tool_call.function.name
            func_args = json.loads(tool_call.function.arguments)

            print(f"[Action] {func_name}({func_args})")
            result = tool_map[func_name](**func_args)
            print(f"[Observation] {result[:100]}...")

            # 把观察结果追加进对话(ReAct 的 Observation 阶段)
            messages.append({
                "role": "tool",
                "tool_call_id": tool_call.id,
                "content": result
            })

        # 循环继续,LLM 基于 Observation 进入下一轮 Thought

    return "达到最大迭代次数,任务未完成"

# 运行示例
result = react_agent("分析一下阿里巴巴最近两个季度的财务表现,计算利润同比增长率")
print(result)

预期输出示例

code
[Action] search({'query': '阿里巴巴 2024Q3'})
[Observation] 营收2365亿元,同比增长5%,净利润436亿元,云计算收入增长7%...
[Action] search({'query': '阿里巴巴 2024Q2'})
[Observation] 营收2432亿元,净利润344亿元...
[Action] calculate({'expression': '(436-344)/344*100'})
[Observation] 26.744...

分析:阿里巴巴2024年Q3净利润436亿元,环比增长约26.7%,主要受益于云计算业务盈利能力提升...

ReAct 的适用场景与局限

适用场景

  • 信息检索类任务,不知道要查几步才能得到答案
  • 需要根据中间结果动态调整查询策略
  • 任务路径高度不确定,需要灵活应对

局限

  • 面对复杂多步骤任务容易"迷失"。它没有全局规划,每一步都是局部决策,可能在某个分支上越走越偏,忘记了最初的目标
  • 没有质量保证机制,给出答案就结束,无法自动识别"这个答案质量不够好"
  • token 消耗相对分散,每步都要输出 Thought 文字

Plan-and-Solve:先谋后动

这个范式解决什么问题

ReAct 的核心问题是:每一步只看当前局势,没有全局视野。这对简单的信息检索任务没有问题,但对结构复杂的任务就会出现问题。

想象一下:你要写一份包含市场分析、竞争对手分析、财务预测、风险评估四个部分的商业报告。如果用 ReAct,Agent 可能在市场分析部分搜索了太多数据,花了大量 token,结果到了财务预测部分发现已经接近上下文窗口限制,只能草草了事。

Plan-and-Solve 解决的就是这个问题。先把任务完整拆解成步骤列表,给整个执行过程一张"地图",再按计划逐步执行。 有了地图,就不会在某个局部迷路。

核心机制

Plan-and-Solve 来自 Lei Wang et al. 2023 年的论文《Plan-and-Solve Prompting》。核心思想是:先完整地把任务拆解成子任务列表,然后按计划逐步执行。

用户输入

Planning 制定计划

子任务 1

子任务 2

子任务 3

执行子任务 1

执行子任务 2

执行子任务 3

汇总结果

最终答案

Planner 负责全局视角:读入问题,输出一个完整的步骤列表。这一步要求 LLM 在动手之前想清楚全程,类似于项目启动前先写工作计划。

Executor 负责单步执行:每次只处理一个步骤,但能看到之前所有步骤的执行结果。上下文不断积累,最后一步拿到完整的历史,输出最终答案。

代码实现

用一道多步数学应用题来演示两阶段架构:

小明周一买了 15 个苹果,周二又买了周一数量的 2 倍,周三吃掉了 5 个。请问小明现在一共有多少个苹果?并计算平均每天新增(不含周三)多少个苹果?

python
import ast
import re
from openai import OpenAI

client = OpenAI()


class Planner:
    """
    规划阶段:把问题拆解成清晰的步骤列表。
    输出格式:Python list,每个元素是一个步骤描述字符串。
    """
    def __init__(self):
        self.system_prompt = """你是一个任务规划专家。
将用户的问题拆解成清晰的执行步骤,以 Python list 格式输出。

要求:
1. 每个步骤是一个字符串,描述具体要做什么
2. 步骤要足够细,每步只做一件事
3. 最后一步必须是"汇总前面所有结果,给出最终答案"
4. 只输出 Python list,不要有任何其他文字

输出示例:
["步骤1:计算...", "步骤2:根据步骤1的结果计算...", "步骤3:汇总前面所有结果,给出最终答案"]"""

    def plan(self, question: str) -> list[str]:
        response = client.chat.completions.create(
            model="gpt-4o",
            messages=[
                {"role": "system", "content": self.system_prompt},
                {"role": "user", "content": question},
            ],
            temperature=0,
        )
        raw_output = response.choices[0].message.content.strip()

        # 安全解析:只接受字面量,不执行任意代码
        try:
            steps = ast.literal_eval(raw_output)
            if isinstance(steps, list) and all(isinstance(s, str) for s in steps):
                return steps
        except (ValueError, SyntaxError):
            pass

        # 容错:尝试用正则提取列表内容
        items = re.findall(r'"([^"]+)"', raw_output)
        if items:
            return items

        # 兜底:把原始输出作为单步计划
        return [raw_output, "汇总前面所有结果,给出最终答案"]


class Executor:
    """
    执行阶段:逐步执行计划,维护 history 字符串积累上下文。
    每步执行都能看到所有历史结果,确保上下文完整。
    """
    def __init__(self):
        self.system_prompt = """你是一个严谨的执行者。
你会收到:原始问题、完整计划、当前要执行的步骤、以及之前步骤的执行结果。
只执行当前步骤,给出该步骤的结果,不要超前执行其他步骤。
输出要简洁,只写计算过程和结果,不要废话。"""

    def execute_step(
        self,
        question: str,
        full_plan: list[str],
        current_step: str,
        step_index: int,
        history: str,
    ) -> str:
        plan_text = "\n".join(f"{i+1}. {s}" for i, s in enumerate(full_plan))

        user_content = f"""原始问题:{question}

完整计划:
{plan_text}

之前步骤的执行结果:
{history if history else "(这是第一步,暂无历史结果)"}

当前执行步骤(第 {step_index + 1} 步):{current_step}

请执行当前步骤,给出结果:"""

        response = client.chat.completions.create(
            model="gpt-4o",
            messages=[
                {"role": "system", "content": self.system_prompt},
                {"role": "user", "content": user_content},
            ],
            temperature=0,
        )
        return response.choices[0].message.content.strip()


class PlanAndSolveAgent:
    """
    组合 Planner 和 Executor 的完整 Agent。
    """
    def __init__(self):
        self.planner = Planner()
        self.executor = Executor()

    def run(self, question: str) -> str:
        print(f"\n问题:{question}")
        print("=" * 60)

        # 阶段一:规划
        print("\n[规划阶段]")
        steps = self.planner.plan(question)
        for i, step in enumerate(steps):
            print(f"  {i + 1}. {step}")

        # 阶段二:执行
        print("\n[执行阶段]")
        history = ""

        for i, step in enumerate(steps):
            print(f"\n步骤 {i + 1}{step}")
            result = self.executor.execute_step(
                question=question,
                full_plan=steps,
                current_step=step,
                step_index=i,
                history=history,
            )
            print(f"结果:{result}")
            history += f"\n步骤 {i + 1}{step})的结果:\n{result}\n"

        return result  # 最后一步的结果就是最终答案


if __name__ == "__main__":
    agent = PlanAndSolveAgent()
    question = (
        "小明周一买了 15 个苹果,周二又买了周一数量的 2 倍,"
        "周三吃掉了 5 个。请问小明现在一共有多少个苹果?"
        "并计算周一和周二平均每天新增多少个苹果?"
    )
    answer = agent.run(question)
    print(f"\n最终答案:{answer}")

预期输出

code
问题:小明周一买了 15 个苹果...
============================================================

[规划阶段]
  1. 计算周一购买的苹果数量
  2. 计算周二购买的苹果数量(周一的2倍)
  3. 计算周三之后剩余的苹果数量(扣除吃掉的5个)
  4. 计算周一和周二平均每天新增苹果数
  5. 汇总前面所有结果,给出最终答案

[执行阶段]
步骤 1:计算周一购买的苹果数量
结果:周一购买 15 个苹果。
...
最终答案:小明现在共有 40 个苹果。周一和周二平均每天新增 22.5 个苹果。

Plan-and-Solve 的局限与改进方向

最大局限:计划是静态的。Planner 基于有限的初始信息制定计划,执行中遇到意外很难灵活调整。如果 Planner 本身规划有误,整个任务都会跑偏。

改进方向:动态重规划。在执行每个步骤之后,检查"计划还需要调整吗"。如果需要,重新调用 Planner 更新剩余步骤。这本质上是把 Plan-and-Solve 和 ReAct 融合——宏观上有计划,微观上可以灵活调整。LangGraph 的一些高级用法就走这个路子。

Plan-and-Solve 的适用场景

适用场景

  • 任务结构清晰,步骤可以提前确定
  • 主要靠推理而非工具调用的场景(如数学题、结构化分析)
  • 任务步骤之间有明确的依赖关系

不适用场景

  • 需要实时获取外部信息,查询结果高度不确定
  • 任务路径依赖中间结果,无法提前规划

Reflection:做完再审

这个范式解决什么问题

ReAct 和 Plan-and-Solve 都在解决"怎么把任务执行完"的问题。但还有另一类问题:怎么把任务执行好

第一稿往往不是最好的。法律文件需要多轮审查,代码需要测试和优化,分析报告需要逻辑自洽。人类的创作过程就是这样:写初稿、反思、修改、再反思。

Reflection 背后有一个实践观察:当你用不同的 Prompt 引导同一个 LLM,它能以不同的方式处理同一个内容。用"请生成一份报告"引导时,LLM 倾向于流畅地输出;用"请找出这份报告的问题"引导时,LLM 倾向于批评性地审查。

更准确的理解:这不是说 LLM 有两种独立的"能力模式"——LLM 本质上始终在做条件概率预测。不同的是 Prompt 上下文:生成 Prompt 引导模型续写内容,评估 Prompt 引导模型寻找问题。改变 Prompt,就改变了模型输出的方向。

把这两种 Prompt 策略拆分成 Actor(执行者)和 Critic(评审者)两个角色,交替工作,就能利用 LLM 的自我改进能力。

核心机制

Reflection 范式来自 Shinn et al. 2023 年的《Reflexion》论文。核心思想是:让 Agent 在执行之后,增加一个自我评估和反思的环节,根据反思结果决定是否重试、如何改进。

用户输入

Actor 执行任务

生成初始输出

Critic 评估质量

质量达标?

输出最终结果

生成改进建议

Actor 根据建议修改

Actor(执行者):负责执行任务,生成输出。关注"做出来",不关注"是否最优"。

Critic(评审者):负责评估 Actor 的输出,指出问题和改进方向。关注"质量是否足够好",用明确的评估标准衡量。

关键设计原则:Critic 提示词的质量决定了整个 Reflection 机制是否有效。如果 Critic 提示词太宽泛,LLM 会给出"还不错,继续吧"这类无意义的反馈,Reflection 就变成了无效的循环调用。Critic 必须有明确的评估维度清单。

代码实现

以代码优化为例,演示从"能用"到"高效"的迭代过程:

python
from openai import OpenAI
from dataclasses import dataclass, field

client = OpenAI()

# ============================================================
# 三个核心提示词:Actor、Critic、Refine
# ============================================================

ACTOR_PROMPT = """你是一个 Python 专家。
请根据用户需求,直接给出可运行的 Python 函数,包含函数定义、必要注释和时间复杂度说明。"""

CRITIC_PROMPT = """你是一个严苛的代码审查员,专门挑算法效率问题。

审查标准(必须逐项检查):
1. 时间复杂度:是否存在更优的算法?O(n²) 能否优化到 O(n log n)?O(n√n) 能否优化到 O(n log log n)?
2. 空间复杂度:内存使用是否可以优化?
3. 边界处理:是否处理了 n=0、n=1、负数等边界情况?
4. 代码质量:变量命名是否清晰?是否有重复逻辑可以抽取?

重要规则:你的职责是找问题,不是表扬。
如果确实无法继续优化(已经是理论最优),在最后一行单独写:NO_IMPROVEMENT_NEEDED"""

REFINE_PROMPT_TEMPLATE = """你是一个 Python 专家。
根据代码审查意见,改进原有代码。

原始代码:
{original_code}

审查意见:
{feedback}

请根据审查意见,给出改进后的完整代码。改动的部分需要在注释里说明改进原因。"""


# ============================================================
# 记忆:追踪每次迭代的输出和反馈
# ============================================================

@dataclass
class IterationRecord:
    version: int
    code: str
    feedback: str = ""


@dataclass
class ReflectionMemory:
    records: list[IterationRecord] = field(default_factory=list)

    def add(self, version: int, code: str, feedback: str = ""):
        self.records.append(IterationRecord(version=version, code=code, feedback=feedback))

    def get_trajectory(self) -> str:
        """把完整迭代历史格式化成文字"""
        lines = []
        for record in self.records:
            lines.append(f"=== 版本 {record.version} ===")
            lines.append(record.code)
            if record.feedback:
                lines.append(f"--- 审查意见 ---")
                lines.append(record.feedback)
            lines.append("")
        return "\n".join(lines)


# ============================================================
# ReflectionAgent:初始执行 → 循环(Critic 评估 → Actor 改进)
# ============================================================

class ReflectionAgent:
    def __init__(self, max_iterations: int = 3):
        self.max_iterations = max_iterations

    def _execute(self, task: str) -> str:
        """Actor:初次执行任务"""
        response = client.chat.completions.create(
            model="gpt-4o",
            messages=[
                {"role": "system", "content": ACTOR_PROMPT},
                {"role": "user", "content": task},
            ],
            temperature=0,
        )
        return response.choices[0].message.content.strip()

    def _critique(self, code: str) -> tuple[bool, str]:
        """Critic:评估代码质量,返回(是否需要继续改进, 反馈内容)"""
        response = client.chat.completions.create(
            model="gpt-4o",
            messages=[
                {"role": "system", "content": CRITIC_PROMPT},
                {"role": "user", "content": f"请审查以下代码:\n\n{code}"},
            ],
            temperature=0,
        )
        feedback = response.choices[0].message.content.strip()
        need_improvement = "NO_IMPROVEMENT_NEEDED" not in feedback
        return need_improvement, feedback

    def _refine(self, original_code: str, feedback: str) -> str:
        """Actor:根据 Critic 的审查意见改进代码"""
        prompt = REFINE_PROMPT_TEMPLATE.format(
            original_code=original_code,
            feedback=feedback,
        )
        response = client.chat.completions.create(
            model="gpt-4o",
            messages=[{"role": "user", "content": prompt}],
            temperature=0,
        )
        return response.choices[0].message.content.strip()

    def run(self, task: str) -> tuple[str, ReflectionMemory]:
        memory = ReflectionMemory()

        print("\n[初次执行]")
        current_code = self._execute(task)
        print(current_code[:200] + "...")
        memory.add(version=0, code=current_code)

        for i in range(self.max_iterations):
            print(f"\n[第 {i + 1} 轮 Critic 评审]")
            need_improvement, feedback = self._critique(current_code)
            print(f"审查意见:{feedback[:200]}...")

            if not need_improvement:
                print(f"审查员认为已无需改进,提前终止迭代。")
                break

            print(f"\n[第 {i + 1} 轮 Actor 改进]")
            refined_code = self._refine(current_code, feedback)
            print(refined_code[:200] + "...")

            memory.records[-1].feedback = feedback
            memory.add(version=i + 1, code=refined_code)
            current_code = refined_code

        return current_code, memory


if __name__ == "__main__":
    agent = ReflectionAgent(max_iterations=3)
    task = "写一个函数 find_primes(n),返回所有小于等于 n 的素数列表"
    final_code, memory = agent.run(task)
    print("\n" + "=" * 60)
    print("最终代码:")
    print(final_code)

实际效果

  • 版本 0(初始执行):通常是试除法,时间复杂度 O(n√n)
  • Critic 反馈:指出效率不足,建议使用埃拉托斯特尼筛法,时间复杂度可优化到 O(n log log n)
  • 版本 1(第一轮改进):筛法实现,带完整边界处理
  • 第二轮 Critic 审查:如果边界处理和代码质量都通过,输出 NO_IMPROVEMENT_NEEDED,循环提前终止

从 O(n√n) 到 O(n log log n),在 n=100000 的场景下,实际运行时间差了 10 倍以上。

Reflection 的成本收益

成本:每多一轮迭代,就多 2 次 LLM 调用(Critic + Refine)。如果迭代 3 轮,总共需要 7 次调用(1 次初始执行 + 3 次 Critic + 3 次 Refine)。延迟从几秒变成几十秒,token 消耗增加 7 倍。

收益:输出质量显著提升。对于代码生成、技术文档、分析报告类任务,Critic 往往能发现人工 review 才能发现的问题。

适合使用的场景

  • 代码生成:专门针对时间复杂度、空间复杂度、边界情况
  • 技术文档:检查逻辑完整性、技术准确性
  • 分析报告:检查论据是否充分、结论是否有数据支撑
  • 任务不紧急、对质量要求高

不适合的场景

  • 实时对话:响应时间从 2 秒变成 20 秒,体验直接崩了
  • 简单查询:天气查询、数学计算不需要 Reflection
  • 有确定性答案的任务:查数据库查到了就是查到了,Reflection 没有意义

三种范式的核心区别

维度 ReAct Plan-and-Solve Reflection
核心思路 边想边做 先规划后执行 执行后反思改进
解决的问题 如何灵活应对意外 如何保持全局视野 如何保证输出质量
适合任务 信息检索类,路径不确定 复杂多步骤类,结构清晰 高质量输出类,有评估标准
对意外的适应 弱(计划静态) 中(可迭代改进)
全局视野
输出质量保证 有(多轮迭代)
延迟 低(一次规划) 高(多次迭代)
Token 消耗 高(成倍增加)

组合使用:三种范式的最佳实践

实际项目里,三种范式通常组合使用。一个典型的高质量 Agent 架构是:

用户输入

Plan-and-Solve: 制定整体计划

子任务 1: ReAct 执行

子任务 2: ReAct 执行

子任务 3: ReAct 执行

汇总子任务结果

Reflection: 评估整体输出

质量达标?

针对性补充执行

最终输出

  • Plan-and-Solve 负责宏观规划,保证方向正确
  • ReAct 负责执行每个子任务,灵活应对信息检索中的意外
  • Reflection 负责最后把关,保证整体输出质量

这个组合在代码生成、深度研究、复杂报告撰写这类任务上效果很好。


范式选择指南

不确定, 需要实时探索

确定, 可以提前规划

没有

没有

选哪种范式?

任务路径是否确定?

ReAct

对输出质量有高要求?

Plan-and-Solve + Reflection

Plan-and-Solve

对输出质量有高要求?

ReAct + Reflection

ReAct

高质量复杂任务

高质量探索任务

效率优先的结构化任务

快速信息检索

选择要点

  • 任务路径是否确定? 确定就用 Plan-and-Solve,不确定就用 ReAct。
  • 对输出质量要求高不高? 高就加 Reflection。
  • 延迟和成本能接受多高? Reflection 会显著增加两者,不能无限堆叠。

把所有任务都套上 Reflection 是常见的过度设计——简单查询也迭代三轮,用户等了十几秒。同样,在简单问答任务上用 Plan-and-Solve,花大量时间规划,然后发现执行只需要一步,规划完全是浪费。理解每种范式的边界,才能在正确的场景用正确的范式。

本页目录