大模型应用进阶:深度拆解 AI Agent 的 5 种核心演进模式

0 阅读28分钟

一、引言:为什么 2026 年我们仍在讨论 Agent 模式?

2023 年是“Chat”的元年,2024 年是“Copilot”的元年,而 2025–2026 年,则是“Agent 工程化”的元年。

我们正在经历一次重要的范式迁移:从「对话式 AI(Conversational AI)」走向「行为式 AI(Action-oriented AI)」。

过去,我们关注的是模型“说得对不对”;现在,我们更关心它“做得成不成”。

如果把大模型看作一个强大的大脑,那么 Agent 就是:把推理(Reasoning)与行动(Acting)进行工程化封装的系统结构。

Agent 的本质不是“让模型更聪明”,而是通过结构设计,降低对模型原生能力的依赖,提高:

  • 稳定性(Stability)
  • 可控性(Controllability)
  • 可扩展性(Scalability)
  • 成功率(Success Rate)

本文将系统拆解当前主流的 5 种 Agent 架构模式:

  • ReAct
  • CodeAct
  • Plan Mode
  • Reflection Mode
  • Multi-Agent

你将看到它们如何从“单线程思考”逐步演进为“团队级协作系统”。


二、ReAct 模式

核心逻辑

ReAct = Reasoning + Acting

其经典流程:

Thought -> Action -> Observation -> Thought -> ...

也就是:

  1. 思考下一步做什么
  2. 调用工具执行
  3. 观察结果
  4. 再思考下一步

这是第一个真正意义上的 Agent 结构。

ReAct 原理图:

React原理图-草图.png

ReAct 示例代码

import os

from dotenv import load_dotenv
from openai import OpenAI


def get_client_and_model():
    load_dotenv()

    api_key = os.getenv("DEEPSEEK_API_KEY")
    base_url = os.getenv("DEEPSEEK_BASE_URL", "https://api.deepseek.com/v1")
    model = os.getenv("DEEPSEEK_MODEL", "deepseek-chat")

    if not api_key:
        raise RuntimeError("缺少 DEEPSEEK_API_KEY,请先在 .env 中配置。")

    client = OpenAI(api_key=api_key, base_url=base_url)
    return client, model
REACT_PROMPT = """
你是一个严格遵循 ReAct(Reasoning and Acting)模式的智能体。
你必须按以下循环回答问题:

Thought: 你的思考
Action: 要调用的工具名
Action Input: 工具入参(JSON)
PAUSE

当你收到 Observation 后,再继续下一轮 Thought/Action,直到得到最终答案。
结束时输出:
Final Answer: 你的最终答案

可用工具如下:
{tools}

规则:
1. 若是问候/闲聊,不调用工具,直接给出 Final Answer。
2. 若需要外部信息,优先调用工具。
3. 如果问题可直接回答,也可以不调用工具,直接 Final Answer。
4. 每次只调用一个工具;多工具需求分多轮。
5. Action Input 必须是合法 JSON。

示例:
Question: 比较青岛啤酒和贵州茅台的收盘价
Thought: 我需要分别查询两只股票的收盘价
Action: get_closing_price
Action Input: {"name":"青岛啤酒"}
PAUSE

Observation: 67.92

Thought: 还需要贵州茅台的收盘价
Action: get_closing_price
Action Input: {"name":"贵州茅台"}
PAUSE

Observation: 1488.21

Final Answer: 贵州茅台收盘价更高(1488.21 > 67.92)。

现在开始。
Question: {input}
"""
from typing import Any

TOOLS = [
    {
        "name": "get_closing_price",
        "description": "获取指定股票的收盘价",
        "parameters": {
            "type": "object",
            "properties": {
                "name": {
                    "type": "string",
                    "description": "股票名称,例如:青岛啤酒、贵州茅台",
                }
            },
            "required": ["name"],
        },
    }
]


def get_closing_price(name: str) -> str:
    mock_data = {
        "青岛啤酒": "67.92",
        "贵州茅台": "1488.21",
    }
    return mock_data.get(name, "未搜到该股票")


def run_tool(tool_name: str, action_input: dict[str, Any]) -> str:
    if tool_name == "get_closing_price":
        return get_closing_price(action_input["name"])
    return f"未知工具: {tool_name}"
import json
import re
from typing import Any, Optional, Tuple

from llm import get_client_and_model
from prompt import REACT_PROMPT
from tools import TOOLS, run_tool


FINAL_ANSWER_PATTERN = re.compile(r"Final Answer:\s*(.*)", re.DOTALL)
ACTION_PATTERN = re.compile(r"Action:\s*([a-zA-Z_][\w]*)")
ACTION_INPUT_PATTERN = re.compile(r"Action Input:\s*(\{.*\}|\".*\")", re.DOTALL)


class ReActAgent:
    def __init__(self, max_steps: int = 6) -> None:
        self.client, self.model = get_client_and_model()
        self.max_steps = max_steps

    def _send_messages(self, messages: list[dict[str, str]]) -> str:
        response = self.client.chat.completions.create(
            model=self.model,
            messages=messages,
        )
        content = response.choices[0].message.content
        return content or ""

    def _extract_final_answer(self, text: str) -> Optional[str]:
        match = FINAL_ANSWER_PATTERN.search(text)
        if not match:
            return None
        return match.group(1).strip()

    def _extract_action(self, text: str) -> Optional[Tuple[str, dict[str, Any]]]:
        action_match = ACTION_PATTERN.search(text)
        input_match = ACTION_INPUT_PATTERN.search(text)
        if not action_match or not input_match:
            return None

        tool_name = action_match.group(1).strip()
        action_input_text = input_match.group(1).strip()

        try:
            parsed_input = json.loads(action_input_text)
        except json.JSONDecodeError:
            return None

        if isinstance(parsed_input, str):
            parsed_input = {"input": parsed_input}
        if not isinstance(parsed_input, dict):
            return None

        return tool_name, parsed_input

    def run(self, query: str, verbose: bool = True) -> str:
        prompt = REACT_PROMPT.format(
            tools=json.dumps(TOOLS, ensure_ascii=False, indent=2),
            input=query,
        )
        messages: list[dict[str, str]] = [{"role": "user", "content": prompt}]

        for step in range(1, self.max_steps + 1):
            output = self._send_messages(messages)
            if verbose:
                print(f"\n=== Step {step} ===")
                print(output)

            final_answer = self._extract_final_answer(output)
            if final_answer:
                return final_answer

            action = self._extract_action(output)
            if not action:
                return f"模型未按 ReAct 格式输出,原始输出:\n{output}"

            tool_name, action_input = action
            observation = run_tool(tool_name, action_input)
            if verbose:
                print(f"Observation: {observation}")

            messages.append({"role": "assistant", "content": output})
            messages.append({"role": "user", "content": f"Observation: {observation}"})

        return f"超过最大循环次数({self.max_steps})仍未得到 Final Answer。"
from agent import ReActAgent


def main() -> None:
    default_query = "请比较青岛啤酒和贵州茅台的股票收盘价谁更高?"
    query = input(f"请输入问题(直接回车使用默认问题):\n[{default_query}]\n> ").strip()
    if not query:
        query = default_query

    agent = ReActAgent(max_steps=6)
    final_answer = agent.run(query=query, verbose=True)

    print("\n=== Final Answer ===")
    print(final_answer)


if __name__ == "__main__":
    main()

技术背景:为什么它重要?

在 ReAct 出现之前,大模型存在两个明显问题:

  • 容易“幻觉”
  • 无法获取实时信息

ReAct 的核心突破是:允许模型边思考边调用工具。

例如:

  • 搜索 API
  • 数据库查询
  • 计算器
  • 外部系统接口

这让模型从“纯语言生成器”变成了“可执行系统”。

适用场景

  • 搜索助手
  • API 编排
  • 简单自动化任务
  • 单轮或短路径工具调用

优点

  • 架构简单
  • 容易实现
  • 逻辑直观

缺点

  • 容易陷入循环
  • 长路径任务容易“走一步忘一步”
  • 对 Prompt 设计依赖极强

ReAct 是 Agent 世界的 “Hello World”,但远不是终点。


三、CodeAct 模式

ReAct 的行动通常是:输出一段 JSON,调用一个 API。

CodeAct 则更进一步:不输出“调用指令”,而是直接生成并执行代码。

例如:

  • Python
  • Bash
  • SQL

核心逻辑

生成代码 -> 执行代码 -> 读取结果 -> 再生成代码

代码成为 Agent 的“中间表示语言(IR)”。

CodeAct 原理图:

CodeAct原理图-草图.png

技术优势

1. 精度更高

自然语言描述计算步骤容易歧义。但:sum(df["revenue"]) 没有歧义。

在:

  • 数学计算
  • 数据分析
  • 复杂逻辑处理

场景中,代码远比文本可靠。

2. 可扩展性更强

代码意味着:

  • 可以调用任何 Python 库
  • 可以访问文件系统
  • 可以控制操作系统
  • 可以构建复杂流程

这让 Agent 成为真正的“自动化执行体”。

CodeAct 示例代码

SYSTEM_PROMPT = """
你是一个严格遵循 CodeAct 模式的智能体。

你的循环流程必须是:
1. 思考任务并规划求解步骤
2. 生成 Python 代码
3. 根据执行反馈观察结果并更新代码
4. 必要时继续修正,直到得到正确答案

输出规则:
1. 当需要执行代码时,只输出一个 Python 代码块(```python ... ```)。
2. 代码必须把关键结果写入变量 result。
3. 你会收到执行反馈(包含 stdout、result、error)。
4. 如果结果已经正确,输出:Final Answer: 你的最终答案
5. 不要输出与上述格式无关的内容。

注意:
- 优先使用 Python 标准库。
- 如果执行报错,先修复报错再继续。
"""
import contextlib
import io


def execute_python(code: str) -> dict[str, str]:
    stdout_buffer = io.StringIO()
    local_vars: dict[str, object] = {}

    try:
        with contextlib.redirect_stdout(stdout_buffer):
            exec(code, {}, local_vars)
        result = local_vars.get("result", "执行成功,但未设置 result 变量")
        stdout_text = stdout_buffer.getvalue().strip()
        return {
            "status": "ok",
            "stdout": stdout_text,
            "result": str(result),
        }
    except Exception as exc:
        stdout_text = stdout_buffer.getvalue().strip()
        return {
            "status": "error",
            "stdout": stdout_text,
            "error": f"{type(exc).__name__}: {exc}",
        }
import json
import re
from typing import Optional

from llm import get_client_and_model
from prompt import SYSTEM_PROMPT
from tools import execute_python


FINAL_ANSWER_PATTERN = re.compile(r"Final Answer:\s*(.*)", re.DOTALL)
PYTHON_BLOCK_PATTERN = re.compile(r"```python\s*(.*?)```", re.DOTALL | re.IGNORECASE)


class CodeActAgent:
    def __init__(self, max_steps: int = 8) -> None:
        self.client, self.model = get_client_and_model()
        self.max_steps = max_steps

    def _send_messages(self, messages: list[dict[str, str]]) -> str:
        response = self.client.chat.completions.create(
            model=self.model,
            messages=messages,
        )
        content = response.choices[0].message.content
        return content or ""

    def _extract_final_answer(self, text: str) -> Optional[str]:
        match = FINAL_ANSWER_PATTERN.search(text)
        if not match:
            return None
        return match.group(1).strip()

    def _extract_python_code(self, text: str) -> Optional[str]:
        match = PYTHON_BLOCK_PATTERN.search(text)
        if not match:
            return None
        return match.group(1).strip()

    def run(self, query: str, verbose: bool = True) -> str:
        messages: list[dict[str, str]] = [
            {"role": "system", "content": SYSTEM_PROMPT},
            {"role": "user", "content": query},
        ]

        for step in range(1, self.max_steps + 1):
            output = self._send_messages(messages)
            if verbose:
                print(f"\n=== Step {step} / LLM Output ===")
                print(output)

            final_answer = self._extract_final_answer(output)
            if final_answer:
                return final_answer

            code = self._extract_python_code(output)
            if not code:
                return f"模型未按 CodeAct 约定输出代码或 Final Answer,原始输出:\n{output}"

            execution_result = execute_python(code)
            observation = json.dumps(execution_result, ensure_ascii=False, indent=2)

            if verbose:
                print("\n=== Execution Observation ===")
                print(observation)

            messages.append({"role": "assistant", "content": output})
            messages.append(
                {
                    "role": "user",
                    "content": (
                        "以下是你刚才代码的执行反馈,请继续下一轮。\n"
                        "如果结果已满足用户问题,请输出:Final Answer: ...\n"
                        "如果报错或结果不满足,请输出修正后的 Python 代码块。\n\n"
                        f"{observation}"
                    ),
                }
            )

        return f"超过最大循环次数({self.max_steps})仍未得到 Final Answer。"
from agent import CodeActAgent


def main() -> None:
    default_query = "请用 Python 计算 1 到 100 的和,并给出计算过程的简要说明。"
    query = input(f"请输入问题(直接回车使用默认问题):\n[{default_query}]\n> ").strip()
    if not query:
        query = default_query

    agent = CodeActAgent(max_steps=8)
    final_answer = agent.run(query=query, verbose=True)

    print("\n=== Final Answer ===")
    print(final_answer)


if __name__ == "__main__":
    main()

实战案例

  • 数据分析 Agent
  • 自动化运维 Agent
  • 报表生成 Agent
  • AI 自动编程助手

工程风险

  • 代码安全
  • 沙箱隔离
  • 资源控制
  • 无限循环风险

CodeAct 提升了能力上限,同时也提升了系统复杂度。


四、计划模式(Plan Mode):复杂任务的“指挥官”

当任务路径变长时,ReAct 会出现典型问题:每一步都只看当前局部。

Plan Mode 的核心思想是:先规划,再执行。

核心逻辑

任务拆解 -> 生成执行计划 -> 分步执行 -> 汇总结果

类似:

  • 架构师出蓝图
  • 工程师按图施工

Plan Mode 原理图:

PlanMode原理图-草图.png

代表架构

  • Plan-and-Execute
  • LLMCompiler

解决的核心痛点

ReAct 的问题:

  • 容易偏航
  • 中途遗忘目标
  • 长任务成功率下降

Plan Mode 引入:

  • 全局视角
  • 中间检查点
  • 结构化步骤管理

适用场景

  • 研究报告编写
  • 复杂项目规划
  • 多步骤数据处理
  • 长链路业务流程

Plan Mode 示例代码

PLANNER_PROMPT = """
你是 PlanMode 里的“计划器(Planner)”。
给定用户目标后,你需要拆解出一个最小可执行的多步计划。

约束:
1. 步骤必须按执行顺序排列。
2. 每一步都要可执行、可验证。
3. 计划总步数控制在 3-5 步。
4. 输出必须是 JSON,且只能输出 JSON。

输出格式:
{
  "steps": ["步骤1", "步骤2", "步骤3"]
}
"""


EXECUTOR_PROMPT = """
你是 PlanMode 里的“执行器(Executor)”,需要严格执行当前步骤。

你可用的工具定义如下:
{tools_json}

请根据“当前步骤”决定执行动作,并只输出 JSON:

1) 如果需要调用工具:
{
  "action": "tool",
  "tool_name": "工具名",
  "tool_input": { "参数": "值" }
}

2) 如果当前步骤已可直接完成:
{
  "action": "final",
  "content": "本步骤的完成结果"
}
"""


REPLAN_PROMPT = """
你是 PlanMode 里的“计划更新器(Replanner)”。
你需要根据已完成步骤,判断是否可以结束,或返回剩余步骤。

规则:
1. 如果任务已完成,返回 response。
2. 如果任务未完成,返回剩余 steps(不要重复已完成步骤)。
3. 输出必须是 JSON,且只能输出 JSON。

输出格式二选一:
{
  "actions": {
    "response": "最终回答"
  }
}

{
  "actions": {
    "steps": ["剩余步骤1", "剩余步骤2"]
  }
}
"""


FINAL_RESPONSE_PROMPT = """
你是 PlanMode 的总结器。
请根据用户目标和已完成步骤结果,整合出最终回答。
输出必须是 JSON:
{
  "response": "最终回答"
}
"""
from typing import Any


TOOL_SPECS = [
    {
        "name": "search_knowledge",
        "description": "检索主题基础知识,返回适合写作的要点",
        "parameters": {
            "type": "object",
            "properties": {
                "topic": {"type": "string", "description": "检索主题"},
            },
            "required": ["topic"],
        },
    },
    {
        "name": "build_outline",
        "description": "根据主题和要点生成文章提纲",
        "parameters": {
            "type": "object",
            "properties": {
                "topic": {"type": "string", "description": "文章主题"},
                "key_points": {"type": "string", "description": "关键要点"},
            },
            "required": ["topic", "key_points"],
        },
    },
    {
        "name": "write_draft",
        "description": "根据提纲生成内容草稿",
        "parameters": {
            "type": "object",
            "properties": {
                "outline": {"type": "string", "description": "文章提纲"},
                "audience": {"type": "string", "description": "目标读者"},
            },
            "required": ["outline"],
        },
    },
    {
        "name": "polish_article",
        "description": "润色文章,使其更符合技术博客风格",
        "parameters": {
            "type": "object",
            "properties": {
                "draft": {"type": "string", "description": "待润色草稿"},
                "style": {"type": "string", "description": "风格偏好"},
            },
            "required": ["draft"],
        },
    },
]


def search_knowledge(topic: str) -> str:
    return (
        f"主题:{topic}\n"
        "要点:\n"
        "1. 量子比特可同时处于多个状态(叠加)。\n"
        "2. 多个量子比特之间可形成纠缠,产生强关联。\n"
        "3. 量子门操作可构建量子算法,如 Shor、Grover。\n"
        "4. 量子计算适合特定问题,并非替代所有经典计算。"
    )


def build_outline(topic: str, key_points: str) -> str:
    return (
        f"# {topic}\n"
        "## 1. 为什么关注量子计算\n"
        "## 2. 三个核心概念:叠加、纠缠、量子门\n"
        "## 3. 典型应用场景与现实边界\n"
        "## 4. 结语:未来机会与挑战\n"
        f"\n参考要点:\n{key_points}"
    )


def write_draft(outline: str, audience: str = "技术爱好者") -> str:
    return (
        f"面向读者:{audience}\n\n"
        "量子计算并不是“更快的普通计算机”,而是一种新的计算范式。"
        "它利用量子比特的叠加和纠缠,在某些任务上有潜在优势。"
        "例如在组合优化、量子化学模拟等方向,量子方法可能显著缩短求解时间。\n\n"
        "但现实中,量子硬件仍受噪声、纠错成本和规模化难题限制。"
        "因此更准确的判断是:量子计算会与经典计算长期协同,"
        "先在少数高价值场景突破,再逐步扩展。\n\n"
        "以下是本文提纲:\n"
        f"{outline}"
    )


def polish_article(draft: str, style: str = "技术博客") -> str:
    return (
        f"[风格:{style}]\n"
        "量子计算是一种利用量子力学规律进行信息处理的计算方式。"
        "它最值得关注的地方,不是“全面替代经典计算”,而是在特定问题上"
        "提供更优求解路径。\n\n"
        "从原理看,叠加让量子系统具备并行表达能力,纠缠让变量之间形成强耦合,"
        "量子门则像经典逻辑门一样,承担可控计算的职责。"
        "从工程看,噪声与纠错仍是主要瓶颈,短期内更可行的路线是“经典+量子”混合架构。\n\n"
        "如果你把量子计算看作“下一代专用加速器”,而不是“万能机器”,"
        "你会更容易识别它的真实机会。\n\n"
        "---- 原始草稿 ----\n"
        f"{draft}"
    )


TOOL_REGISTRY = {
    "search_knowledge": search_knowledge,
    "build_outline": build_outline,
    "write_draft": write_draft,
    "polish_article": polish_article,
}


def run_tool(tool_name: str, tool_input: dict[str, Any]) -> str:
    tool_fn = TOOL_REGISTRY.get(tool_name)
    if not tool_fn:
        return f"工具不存在: {tool_name}"

    try:
        return tool_fn(**tool_input)
    except TypeError as exc:
        return f"工具参数错误: {exc}"
import json
import re
from typing import Any, Optional

from llm import get_client_and_model
from prompt import EXECUTOR_PROMPT, FINAL_RESPONSE_PROMPT, PLANNER_PROMPT, REPLAN_PROMPT
from tools import TOOL_SPECS, run_tool


class PlanModeAgent:
    def __init__(self, max_rounds: int = 8) -> None:
        self.client, self.model = get_client_and_model()
        self.max_rounds = max_rounds

    def _send_messages(self, messages: list[dict[str, str]]) -> str:
        response = self.client.chat.completions.create(
            model=self.model,
            messages=messages,
            temperature=0.2,
        )
        content = response.choices[0].message.content
        return content or ""

    def _extract_json_object(self, text: str) -> Optional[dict[str, Any]]:
        text = text.strip()

        for candidate in (text, self._extract_fenced_json(text), self._extract_brace_json(text)):
            if not candidate:
                continue
            try:
                parsed = json.loads(candidate)
            except json.JSONDecodeError:
                continue
            if isinstance(parsed, dict):
                return parsed
        return None

    def _extract_fenced_json(self, text: str) -> str:
        match = re.search(r"```json\s*(.*?)```", text, re.DOTALL | re.IGNORECASE)
        return match.group(1).strip() if match else ""

    def _extract_brace_json(self, text: str) -> str:
        start = text.find("{")
        end = text.rfind("}")
        if start == -1 or end == -1 or end <= start:
            return ""
        return text[start : end + 1]

    def _default_plan(self, query: str) -> list[str]:
        return [
            f"检索与“{query}”相关的基础知识",
            f"基于知识要点制定“{query}”的文章提纲",
            f"根据提纲撰写“{query}”短文草稿",
            "检查与润色草稿,输出最终文章",
        ]

    def _plan(self, query: str) -> list[str]:
        messages = [
            {"role": "system", "content": PLANNER_PROMPT},
            {"role": "user", "content": f"用户目标:{query}"},
        ]
        output = self._send_messages(messages)
        data = self._extract_json_object(output)

        if not data:
            return self._default_plan(query)

        steps = data.get("steps")
        if not isinstance(steps, list):
            return self._default_plan(query)

        clean_steps = [step.strip() for step in steps if isinstance(step, str) and step.strip()]
        return clean_steps if clean_steps else self._default_plan(query)

    def _build_default_tool_call(
        self,
        query: str,
        step: str,
        past_steps: list[dict[str, str]],
    ) -> tuple[str, dict[str, Any]]:
        if "检索" in step or "知识" in step:
            return "search_knowledge", {"topic": query}

        if "提纲" in step:
            key_points = past_steps[-1]["result"] if past_steps else "无"
            return "build_outline", {"topic": query, "key_points": key_points}

        if "草稿" in step or "撰写" in step:
            outline = past_steps[-1]["result"] if past_steps else f"# {query}\n## 主题内容"
            return "write_draft", {"outline": outline, "audience": "技术博客读者"}

        if "润色" in step or "检查" in step:
            draft = past_steps[-1]["result"] if past_steps else ""
            return "polish_article", {"draft": draft, "style": "技术博客"}

        return "search_knowledge", {"topic": query}

    def _execute_step(
        self,
        query: str,
        full_plan: list[str],
        step: str,
        past_steps: list[dict[str, str]],
    ) -> str:
        tools_json = json.dumps(TOOL_SPECS, ensure_ascii=False, indent=2)
        prompt = EXECUTOR_PROMPT.format(tools_json=tools_json)
        messages = [
            {"role": "system", "content": prompt},
            {
                "role": "user",
                "content": (
                    f"用户目标:{query}\n"
                    f"完整计划:{json.dumps(full_plan, ensure_ascii=False)}\n"
                    f"当前步骤:{step}\n"
                    f"已完成步骤:{json.dumps(past_steps, ensure_ascii=False)}"
                ),
            },
        ]
        output = self._send_messages(messages)
        data = self._extract_json_object(output) or {}

        action = data.get("action")
        if action == "final":
            content = data.get("content", "")
            if isinstance(content, str) and content.strip():
                return content.strip()

        if action == "tool":
            tool_name = data.get("tool_name")
            tool_input = data.get("tool_input", {})
            if isinstance(tool_name, str) and isinstance(tool_input, dict):
                return run_tool(tool_name, tool_input)

        tool_name, tool_input = self._build_default_tool_call(query, step, past_steps)
        return run_tool(tool_name, tool_input)

    def _replan(
        self,
        query: str,
        remaining_plan: list[str],
        past_steps: list[dict[str, str]],
    ) -> tuple[bool, str, list[str]]:
        messages = [
            {"role": "system", "content": REPLAN_PROMPT},
            {
                "role": "user",
                "content": (
                    f"用户目标:{query}\n"
                    f"当前剩余计划:{json.dumps(remaining_plan, ensure_ascii=False)}\n"
                    f"已完成步骤:{json.dumps(past_steps, ensure_ascii=False)}"
                ),
            },
        ]
        output = self._send_messages(messages)
        data = self._extract_json_object(output) or {}
        actions = data.get("actions", {})

        if isinstance(actions, dict):
            response = actions.get("response")
            if isinstance(response, str) and response.strip():
                return True, response.strip(), []

            steps = actions.get("steps")
            if isinstance(steps, list):
                clean_steps = [step.strip() for step in steps if isinstance(step, str) and step.strip()]
                return False, "", clean_steps

        if not remaining_plan:
            return True, "", []
        return False, "", remaining_plan

    def _final_response(self, query: str, past_steps: list[dict[str, str]]) -> str:
        messages = [
            {"role": "system", "content": FINAL_RESPONSE_PROMPT},
            {
                "role": "user",
                "content": (
                    f"用户目标:{query}\n"
                    f"步骤执行结果:{json.dumps(past_steps, ensure_ascii=False)}"
                ),
            },
        ]
        output = self._send_messages(messages)
        data = self._extract_json_object(output) or {}
        response = data.get("response")
        if isinstance(response, str) and response.strip():
            return response.strip()

        if past_steps:
            return past_steps[-1]["result"]
        return "未能生成最终回答。"

    def run(self, query: str, verbose: bool = True) -> str:
        plan = self._plan(query)
        past_steps: list[dict[str, str]] = []

        if verbose:
            print("=== 计划阶段 / Multi-step Plan ===")
            for idx, step in enumerate(plan, start=1):
                print(f"{idx}. {step}")

        for round_id in range(1, self.max_rounds + 1):
            if not plan:
                break

            current_step = plan[0]
            if verbose:
                print(f"\n=== 执行阶段 Round {round_id} ===")
                print(f"执行步骤: {current_step}")

            result = self._execute_step(query, plan, current_step, past_steps)
            past_steps.append({"step": current_step, "result": result})

            if verbose:
                print("步骤结果:")
                print(result)

            done, response, new_plan = self._replan(query, plan[1:], past_steps)
            if done:
                if response:
                    return response
                return self._final_response(query, past_steps)

            plan = new_plan
            if verbose and plan:
                print("更新后剩余计划:")
                for idx, step in enumerate(plan, start=1):
                    print(f"{idx}. {step}")

        return self._final_response(query, past_steps)
from agent import PlanModeAgent


def main() -> None:
    default_query = "写一篇关于量子计算的短文"
    query = input(f"请输入问题(直接回车使用默认问题):\n[{default_query}]\n> ").strip()
    if not query:
        query = default_query

    agent = PlanModeAgent(max_rounds=8)
    final_answer = agent.run(query=query, verbose=True)

    print("\n=== Final Answer ===")
    print(final_answer)


if __name__ == "__main__":
    main()

工程启示

Plan Mode 本质上是:用“结构化控制流”约束模型的自由生成。

这是 Agent 稳定性的关键来源之一。


五、反思模式(Reflection Mode):智能体的“自我进化”

Reflection 是 Agent 体系的质量跃迁。

其核心结构:

执行 -> 评价(Critic) -> 修正(Refine) -> 再执行

Reflection 原理图:

ReflectionMode原理图-草图.png

典型框架

  • Reflexion
  • Self-Refine

Reflection 示例代码

DRAFT_PROMPT = """
你是 ReflectionMode 中的“初稿生成器(Draft Generator)”。
请根据用户目标先给出一个可读的初稿。

要求:
1. 内容紧扣用户目标,不要偏题。
2. 结构清晰,语言自然。
3. 直接输出正文,不要输出解释。
"""


REFLECTION_PROMPT = """
你是 ReflectionMode 中的“反思器(Self-Critique)”。
请对当前草稿做严格评审,并判断是否还需要优化。

评审维度:
1. 是否准确回应用户目标
2. 信息是否完整、有逻辑
3. 表达是否清晰、易读
4. 是否存在明显事实或表述问题

输出要求(必须是 JSON,且只能输出 JSON):
{
  "status": "good_enough 或 needs_improvement",
  "issues": ["问题1", "问题2"],
  "suggestions": ["建议1", "建议2"]
}

当草稿已经足够好时:
1. status 必须为 good_enough
2. issues 与 suggestions 允许为空数组
"""


REFINEMENT_PROMPT = """
你是 ReflectionMode 中的“改写器(Refiner)”。
请根据反思建议改写草稿,输出更好的版本。

要求:
1. 保留原文有效信息,修正问题点。
2. 优先执行 suggestions 中的高价值建议。
3. 若建议与用户目标冲突,以用户目标优先。
4. 直接输出改写后的正文,不要输出解释。
"""
import json
import re
from typing import Any, Optional

from llm import get_client_and_model
from prompt import DRAFT_PROMPT, REFINEMENT_PROMPT, REFLECTION_PROMPT


class ReflectionModeAgent:
    def __init__(self, max_rounds: int = 3) -> None:
        self.client, self.model = get_client_and_model()
        self.max_rounds = max_rounds

    def _send_messages(self, messages: list[dict[str, str]], temperature: float = 0.3) -> str:
        response = self.client.chat.completions.create(
            model=self.model,
            messages=messages,
            temperature=temperature,
        )
        content = response.choices[0].message.content
        return content or ""

    def _extract_json_object(self, text: str) -> Optional[dict[str, Any]]:
        text = text.strip()
        for candidate in (text, self._extract_fenced_json(text), self._extract_brace_json(text)):
            if not candidate:
                continue
            try:
                parsed = json.loads(candidate)
            except json.JSONDecodeError:
                continue
            if isinstance(parsed, dict):
                return parsed
        return None

    def _extract_fenced_json(self, text: str) -> str:
        match = re.search(r"```json\s*(.*?)```", text, re.DOTALL | re.IGNORECASE)
        return match.group(1).strip() if match else ""

    def _extract_brace_json(self, text: str) -> str:
        start = text.find("{")
        end = text.rfind("}")
        if start == -1 or end == -1 or end <= start:
            return ""
        return text[start : end + 1]

    def _build_draft(self, query: str) -> str:
        messages = [
            {"role": "system", "content": DRAFT_PROMPT},
            {"role": "user", "content": f"用户目标:{query}"},
        ]
        draft = self._send_messages(messages, temperature=0.6).strip()
        return draft or f"(未生成内容)用户目标:{query}"

    def _reflect(self, query: str, draft: str) -> tuple[bool, str]:
        messages = [
            {"role": "system", "content": REFLECTION_PROMPT},
            {
                "role": "user",
                "content": f"用户目标:{query}\n\n当前草稿:\n{draft}",
            },
        ]
        output = self._send_messages(messages, temperature=0.1).strip()
        data = self._extract_json_object(output) or {}

        status = data.get("status")
        issues = data.get("issues", [])
        suggestions = data.get("suggestions", [])

        if not isinstance(issues, list):
            issues = []
        if not isinstance(suggestions, list):
            suggestions = []

        if status == "good_enough":
            return True, "草稿质量已达标,无需继续优化。"

        clean_issues = [item.strip() for item in issues if isinstance(item, str) and item.strip()]
        clean_suggestions = [item.strip() for item in suggestions if isinstance(item, str) and item.strip()]

        if not clean_issues and not clean_suggestions:
            if output:
                return False, f"模型反思输出(原文):{output}"
            return False, "反思器未给出有效建议,请增强准确性、结构和可读性。"

        feedback_parts = []
        if clean_issues:
            feedback_parts.append("问题:" + ";".join(clean_issues))
        if clean_suggestions:
            feedback_parts.append("建议:" + ";".join(clean_suggestions))
        return False, "\n".join(feedback_parts)

    def _refine(self, query: str, draft: str, feedback: str) -> str:
        messages = [
            {"role": "system", "content": REFINEMENT_PROMPT},
            {
                "role": "user",
                "content": (
                    f"用户目标:{query}\n\n"
                    f"当前草稿:\n{draft}\n\n"
                    f"反思建议:\n{feedback}"
                ),
            },
        ]
        refined = self._send_messages(messages, temperature=0.4).strip()
        return refined or draft

    def run(self, query: str, verbose: bool = True) -> str:
        draft = self._build_draft(query)
        if verbose:
            print("=== Draft 1 ===")
            print(draft)

        for round_id in range(1, self.max_rounds + 1):
            done, feedback = self._reflect(query, draft)
            if verbose:
                print(f"\n=== Reflection {round_id} ===")
                print(feedback)

            if done:
                return draft

            draft = self._refine(query, draft, feedback)
            if verbose:
                print(f"\n=== Refinement {round_id} ===")
                print(draft)

        return draft
from agent import ReflectionModeAgent


def main() -> None:
    default_query = "写一段关于“ReflectionMode 反思模式”的技术博客内容,包含概念、流程和一个应用场景。"
    query = input(f"请输入问题(直接回车使用默认问题):\n[{default_query}]\n> ").strip()
    if not query:
        query = default_query

    agent = ReflectionModeAgent(max_rounds=3)
    final_answer = agent.run(query=query, verbose=True)

    print("\n=== Final Answer ===")
    print(final_answer)


if __name__ == "__main__":
    main()

为什么它有效?

大模型第一次输出往往:

  • 方向对
  • 但细节有问题

加入 Critic 角色后:

  • 能指出错误
  • 给出改进建议
  • 再次生成更优版本

这在:

  • 代码生成
  • 文案创作
  • 数学推理

场景中效果显著。

工程代价

  • Token 成本增加
  • 推理时间增加
  • 系统复杂度增加

但换来的收益是:成功率的显著提升。

Reflection 本质是:用“多次思考”换“单次成功”


六、多智能体模式(Multi-Agent):从个人英雄主义到团队协作

当单 Agent 复杂度达到上限时,多 Agent 架构出现了。

核心思想:

让不同角色各司其职。


两种常见组织形式

1.层级架构

Boss Agent
   ↓
Worker Agent
   ↓
Executor

类似公司组织。


2.协作架构

  • 程序员 Agent 写代码
  • 测试员 Agent 找 Bug
  • 架构师 Agent 设计系统

Multi-Agent 原理图:

MultiAgent原理图-草图.png

代表框架:

  • MetaGPT
  • AutoGen

优势

  • 模块化
  • 可替换
  • 易扩展
  • 适合企业级系统

Multi-Agent 示例代码

RESEARCHER_PROMPT = """
你是 Multi-Agent 系统中的研究员(Researcher)。
你的任务是把工具提供的原始资料整理成可执行情报。

要求:
1. 聚焦用户目标,提炼关键信息,不写空话。
2. 给出 5-8 条高密度研究要点。
3. 输出必须是 JSON,且只能输出 JSON。

输出格式:
{
  "research_notes": "结构化研究结论,建议用 1. 2. 3. 编号",
  "risks": ["潜在风险1", "潜在风险2"]
}
"""


PLANNER_PROMPT = """
你是 Multi-Agent 系统中的规划师(Planner)。
你要基于研究结论设计最小可执行计划。

要求:
1. 步骤按执行顺序排列。
2. 每一步可执行、可验证。
3. 总步数控制在 4-6 步。
4. 输出必须是 JSON,且只能输出 JSON。

输出格式:
{
  "plan_steps": ["步骤1", "步骤2", "步骤3"],
  "acceptance_criteria": ["验收标准1", "验收标准2"]
}
"""


EXECUTOR_PROMPT = """
你是 Multi-Agent 系统中的执行员(Executor)。
你要根据计划产出可直接用于技术博客的正文内容。

要求:
1. 内容聚焦“Agent 的 5 种模式”中的 Multi-Agent 模式。
2. 结构清晰,优先给出架构、流程、价值和适用场景。
3. 使用中文,避免营销化语气。
4. 输出必须是 JSON,且只能输出 JSON。

输出格式:
{
  "draft": "可直接发布的博客正文"
}
"""


EVALUATOR_PROMPT = """
你是 Multi-Agent 系统中的评估员(Evaluator)。
你要判断执行结果是否达到可发布标准。

要求:
1. 仅基于用户目标与验收标准进行评估。
2. 给出明确通过/不通过结论。
3. 若不通过,反馈必须是可执行修改建议。
4. 输出必须是 JSON,且只能输出 JSON。

输出格式:
{
  "pass": true,
  "score": 90,
  "feedback": "评估结论与修改建议"
}
"""


FINAL_RESPONSE_PROMPT = """
你是 Multi-Agent 系统的最终汇总器。
请输出最终给用户的回答。

要求:
1. 如果草稿已通过评估,直接给出最终版本。
2. 如果未通过但达到返工上限,给出当前最佳版本并明确剩余风险。
3. 输出必须是 JSON,且只能输出 JSON。

输出格式:
{
  "final_answer": "最终回答"
}
"""
from typing import Any


TOOL_SPECS = [
    {
        "name": "search_knowledge",
        "description": "检索 Multi-Agent 相关基础知识",
        "parameters": {
            "type": "object",
            "properties": {
                "topic": {"type": "string", "description": "检索主题"},
            },
            "required": ["topic"],
        },
    },
    {
        "name": "fetch_case_snippets",
        "description": "返回博客可复用的案例片段",
        "parameters": {
            "type": "object",
            "properties": {
                "topic": {"type": "string", "description": "案例主题"},
            },
            "required": ["topic"],
        },
    },
    {
        "name": "quality_rubric",
        "description": "返回技术博客验收标准",
        "parameters": {
            "type": "object",
            "properties": {},
        },
    },
]


def search_knowledge(topic: str) -> str:
    return (
        f"主题:{topic}\n"
        "多智能体模式核心:\n"
        "1. 系统管理器负责任务拆分、角色路由、状态跟踪。\n"
        "2. 研究员负责信息收集与证据整理,降低后续幻觉风险。\n"
        "3. 规划师将目标转成步骤和验收标准,提升执行可控性。\n"
        "4. 执行员按计划产出结果,不直接跳步。\n"
        "5. 评估员做独立质量门禁,触发返工闭环。\n"
        "6. 多智能体优势在于角色分工、并行扩展、质量可追踪。"
    )


def fetch_case_snippets(topic: str) -> str:
    return (
        f"案例主题:{topic}\n"
        "可复用片段:\n"
        "- 场景A:复杂研究任务(资料检索、事实交叉验证、结构化输出)。\n"
        "- 场景B:工程交付任务(计划生成、代码执行、质量评审)。\n"
        "- 场景C:内容生产任务(选题研究、提纲规划、正文写作、终审把关)。"
    )


def quality_rubric() -> str:
    return (
        "验收标准:\n"
        "1. 是否准确说明多智能体角色分工与信息流。\n"
        "2. 是否体现‘管理器-执行-评估-返工’闭环。\n"
        "3. 是否给出至少 2 个适用场景与边界。\n"
        "4. 是否可直接用于技术博客发布(结构完整、语言清晰)。"
    )


TOOL_REGISTRY = {
    "search_knowledge": search_knowledge,
    "fetch_case_snippets": fetch_case_snippets,
    "quality_rubric": quality_rubric,
}


def run_tool(tool_name: str, tool_input: dict[str, Any]) -> str:
    tool_fn = TOOL_REGISTRY.get(tool_name)
    if not tool_fn:
        return f"工具不存在: {tool_name}"

    try:
        return tool_fn(**tool_input)
    except TypeError as exc:
        return f"工具参数错误: {exc}"
import json
import re
from dataclasses import dataclass, field
from typing import Any, Optional

from llm import get_client_and_model
from prompt import (
    EVALUATOR_PROMPT,
    EXECUTOR_PROMPT,
    FINAL_RESPONSE_PROMPT,
    PLANNER_PROMPT,
    RESEARCHER_PROMPT,
)
from tools import TOOL_SPECS, run_tool


@dataclass
class MultiAgentState:
    query: str
    research_notes: str = ""
    risks: list[str] = field(default_factory=list)
    plan_steps: list[str] = field(default_factory=list)
    acceptance_criteria: list[str] = field(default_factory=list)
    draft: str = ""
    passed: bool = False
    score: int = 0
    feedback: str = ""
    rework_count: int = 0
    phase: str = "research"
    trace: list[str] = field(default_factory=list)


class MultiAgentBlogAgent:
    def __init__(self, max_rounds: int = 10, max_reworks: int = 2) -> None:
        self.client, self.model = get_client_and_model()
        self.max_rounds = max_rounds
        self.max_reworks = max_reworks

    def _send_messages(self, messages: list[dict[str, str]]) -> str:
        response = self.client.chat.completions.create(
            model=self.model,
            messages=messages,
            temperature=0.2,
        )
        content = response.choices[0].message.content
        return content or ""

    def _extract_json_object(self, text: str) -> Optional[dict[str, Any]]:
        text = text.strip()

        for candidate in (text, self._extract_fenced_json(text), self._extract_brace_json(text)):
            if not candidate:
                continue
            try:
                parsed = json.loads(candidate)
            except json.JSONDecodeError:
                continue
            if isinstance(parsed, dict):
                return parsed
        return None

    def _extract_fenced_json(self, text: str) -> str:
        match = re.search(r"```json\s*(.*?)```", text, re.DOTALL | re.IGNORECASE)
        return match.group(1).strip() if match else ""

    def _extract_brace_json(self, text: str) -> str:
        start = text.find("{")
        end = text.rfind("}")
        if start == -1 or end == -1 or end <= start:
            return ""
        return text[start : end + 1]

    def _manager_route(self, state: MultiAgentState) -> tuple[str, str]:
        if state.phase == "research":
            return "researcher", "先收集事实和样例,降低后续输出偏差。"

        if state.phase == "plan":
            if state.rework_count > 0:
                return "planner", "评估未通过,规划师根据反馈重排步骤。"
            return "planner", "将研究结论转成可执行计划。"

        if state.phase == "execute":
            return "executor", "按计划产出博客正文。"

        if state.phase == "evaluate":
            return "evaluator", "独立评估质量并决定是否返工。"

        return "done", "流程完成。"

    def _run_researcher(self, state: MultiAgentState) -> None:
        tool_outputs = {
            "tool_specs": TOOL_SPECS,
            "search_knowledge": run_tool("search_knowledge", {"topic": state.query}),
            "fetch_case_snippets": run_tool("fetch_case_snippets", {"topic": "Multi-Agent 多智能体模式"}),
            "quality_rubric": run_tool("quality_rubric", {}),
        }

        messages = [
            {"role": "system", "content": RESEARCHER_PROMPT},
            {
                "role": "user",
                "content": (
                    f"用户目标:{state.query}\n\n"
                    f"工具返回资料:\n{json.dumps(tool_outputs, ensure_ascii=False, indent=2)}"
                ),
            },
        ]

        output = self._send_messages(messages)
        data = self._extract_json_object(output) or {}

        notes = data.get("research_notes")
        risks = data.get("risks")

        if not isinstance(notes, str) or not notes.strip():
            notes = (
                f"1. {tool_outputs['search_knowledge']}\n"
                f"2. {tool_outputs['fetch_case_snippets']}\n"
                f"3. {tool_outputs['quality_rubric']}"
            )

        if not isinstance(risks, list):
            risks = ["缺少真实工具/数据源时,研究结论会偏向示例化。"]

        state.research_notes = notes.strip()
        state.risks = [item.strip() for item in risks if isinstance(item, str) and item.strip()]
        state.trace.append("researcher")

    def _default_plan(self, query: str) -> list[str]:
        return [
            f"明确 {query} 的目标读者与输出范围",
            "定义系统管理器与四个角色的职责边界",
            "按信息流描述任务拆分、执行与评估闭环",
            "补充适用场景、边界与落地建议",
            "整理为可直接发布的博客正文",
        ]

    def _run_planner(self, state: MultiAgentState) -> None:
        messages = [
            {"role": "system", "content": PLANNER_PROMPT},
            {
                "role": "user",
                "content": (
                    f"用户目标:{state.query}\n\n"
                    f"研究结论:{state.research_notes}\n\n"
                    f"风险点:{json.dumps(state.risks, ensure_ascii=False)}\n\n"
                    f"评估反馈(若为空表示首轮):{state.feedback}"
                ),
            },
        ]

        output = self._send_messages(messages)
        data = self._extract_json_object(output) or {}

        plan_steps = data.get("plan_steps")
        criteria = data.get("acceptance_criteria")

        if not isinstance(plan_steps, list):
            plan_steps = self._default_plan(state.query)

        clean_steps = [step.strip() for step in plan_steps if isinstance(step, str) and step.strip()]
        if not clean_steps:
            clean_steps = self._default_plan(state.query)

        if not isinstance(criteria, list):
            criteria = [
                "角色分工与任务边界清晰",
                "包含管理器路由与返工闭环",
                "包含至少 2 个适用场景",
                "内容可直接用于技术博客",
            ]

        clean_criteria = [item.strip() for item in criteria if isinstance(item, str) and item.strip()]

        state.plan_steps = clean_steps
        state.acceptance_criteria = clean_criteria
        state.trace.append("planner")

    def _run_executor(self, state: MultiAgentState) -> None:
        messages = [
            {"role": "system", "content": EXECUTOR_PROMPT},
            {
                "role": "user",
                "content": (
                    f"用户目标:{state.query}\n\n"
                    f"执行计划:{json.dumps(state.plan_steps, ensure_ascii=False)}\n\n"
                    f"验收标准:{json.dumps(state.acceptance_criteria, ensure_ascii=False)}\n\n"
                    f"研究结论:{state.research_notes}\n\n"
                    f"上轮评估反馈(若为空表示首轮):{state.feedback}"
                ),
            },
        ]

        output = self._send_messages(messages)
        data = self._extract_json_object(output) or {}
        draft = data.get("draft")

        if not isinstance(draft, str) or not draft.strip():
            draft = output

        state.draft = draft.strip()
        state.trace.append("executor")

    def _run_evaluator(self, state: MultiAgentState) -> None:
        messages = [
            {"role": "system", "content": EVALUATOR_PROMPT},
            {
                "role": "user",
                "content": (
                    f"用户目标:{state.query}\n\n"
                    f"验收标准:{json.dumps(state.acceptance_criteria, ensure_ascii=False)}\n\n"
                    f"当前草稿:\n{state.draft}"
                ),
            },
        ]

        output = self._send_messages(messages)
        data = self._extract_json_object(output) or {}

        passed = data.get("pass")
        score = data.get("score")
        feedback = data.get("feedback")

        if not isinstance(passed, bool):
            passed = False

        if not isinstance(score, int):
            score = 60 if passed else 45

        if not isinstance(feedback, str) or not feedback.strip():
            feedback = "评估输出缺失,建议补充更明确的架构流程、场景和边界。"

        state.passed = passed
        state.score = max(0, min(100, score))
        state.feedback = feedback.strip()
        state.trace.append("evaluator")

    def _finalize(self, state: MultiAgentState) -> str:
        messages = [
            {"role": "system", "content": FINAL_RESPONSE_PROMPT},
            {
                "role": "user",
                "content": (
                    f"用户目标:{state.query}\n\n"
                    f"是否通过评估:{state.passed}\n"
                    f"评估分数:{state.score}\n"
                    f"评估反馈:{state.feedback}\n\n"
                    f"当前草稿:\n{state.draft}"
                ),
            },
        ]

        output = self._send_messages(messages)
        data = self._extract_json_object(output) or {}
        final_answer = data.get("final_answer")

        if isinstance(final_answer, str) and final_answer.strip():
            return final_answer.strip()

        if state.passed:
            return state.draft

        return (
            "[未达到通过标准,返回当前最佳版本]\n"
            f"评估反馈:{state.feedback}\n\n"
            f"{state.draft}"
        )

    def run(self, query: str, verbose: bool = True) -> dict[str, Any]:
        state = MultiAgentState(query=query)

        for round_id in range(1, self.max_rounds + 1):
            role, reason = self._manager_route(state)

            if verbose:
                print(f"\n=== Round {round_id} ===")
                print(f"[Manager] 路由到: {role}")
                print(f"[Manager] 决策原因: {reason}")

            if role == "done":
                break

            if role == "researcher":
                self._run_researcher(state)
                state.phase = "plan"
                if verbose:
                    print("[Researcher] 研究结论已产出。")
                continue

            if role == "planner":
                self._run_planner(state)
                state.phase = "execute"
                if verbose:
                    print("[Planner] 执行计划已生成。")
                    for idx, step in enumerate(state.plan_steps, start=1):
                        print(f"  {idx}. {step}")
                continue

            if role == "executor":
                self._run_executor(state)
                state.phase = "evaluate"
                if verbose:
                    print("[Executor] 草稿已生成。")
                continue

            if role == "evaluator":
                self._run_evaluator(state)
                if verbose:
                    print(f"[Evaluator] pass={state.passed}, score={state.score}")
                    print(f"[Evaluator] feedback={state.feedback}")

                if state.passed:
                    state.phase = "done"
                elif state.rework_count >= self.max_reworks:
                    state.phase = "done"
                else:
                    state.rework_count += 1
                    state.phase = "plan"
                    if verbose:
                        print(f"[Manager] 进入返工流程,第 {state.rework_count} 次返工。")
                continue

        final_answer = self._finalize(state)
        return {
            "final_answer": final_answer,
            "passed": state.passed,
            "score": state.score,
            "rework_count": state.rework_count,
            "trace": state.trace,
        }
from agent import MultiAgentBlogAgent


def main() -> None:
    default_query = "写一段技术博客内容,解释 Agent 的 5 种模式里 Multi-Agent 多智能体模式的工作机制与价值。"
    query = input(f"请输入问题(直接回车使用默认问题):\n[{default_query}]\n> ").strip()
    if not query:
        query = default_query

    agent = MultiAgentBlogAgent(max_rounds=10, max_reworks=2)
    result = agent.run(query=query, verbose=True)

    print("\n=== Final Answer ===")
    print(result["final_answer"])

    print("\n=== Meta ===")
    print(
        f"passed={result['passed']} | score={result['score']} | "
        f"rework_count={result['rework_count']}"
    )
    print("trace=", " -> ".join(result["trace"]))


if __name__ == "__main__":
    main()

挑战

  • 通信协议设计
  • 角色边界定义
  • 状态同步问题
  • Token 成本爆炸

Multi-Agent 更像一个“AI 组织系统”,而不是单个模型。


七、总结对比:如何选择?

模式核心特点复杂度推荐场景
ReAct实时推理、单次任务简单 API 调用、搜索助手
CodeAct编程驱动、高精度数据处理、环境控制
Plan Mode结构化拆解、长路径项目规划、报告生成
Reflection自我迭代、高质量代码优化、内容精修
Multi-Agent分工协作、高吞吐企业级复杂工作流

选型建议

  • 如果你刚入门:从 ReAct 开始。
  • 如果涉及计算或环境操作:用 CodeAct。
  • 如果任务路径长:加入 Plan。
  • 如果质量要求高:加入 Reflection。
  • 如果系统极其复杂:考虑 Multi-Agent。

现实工程中,往往是多种模式混合使用。

例如:

Plan + CodeAct + Reflection

这已经成为主流工程实践。


八、结语:迈向 AGI 的工程阶梯

一个重要认知:Agent 模式不是在提升模型智力,而是在提升系统可靠性。

我们正在通过“工程结构”弥补模型的:

  • 不稳定性
  • 非确定性
  • 幻觉问题

Agent 是从“模型驱动”走向“系统驱动”的关键一步。

真正的 AGI,也许不只是一个超级模型,而是:一个由多个智能模块构成的协作系统。

如果你已经在实践 Agent 架构,欢迎在掘金分享你的工程心得。

未来 3 年,将是 Agent 架构快速进化的时代。

而现在,正是入场的最好时机。