AI agent学习2: 智能体经典范式

2026-01-14

1. ReAct

ReAct的巧妙之处是,它认识到思考与行动是相辅相成的。思考指导行动,而行动的结果又反过来修正思考。为此,ReAct范式通过一种特殊的提示工程来引导模型,使其每一步的输出都遵循一个固定的轨迹:

Thought (思考): 这是智能体的“内心独白”。它会分析当前情况、分解任务、制定下一步计划,或者反思上一步的结果。
Action (行动): 这是智能体决定采取的具体动作,通常是调用一个外部工具,例如 Search['华为最新款手机']。
Observation (观察): 这是执行Action后从外部工具返回的结果,例如搜索结果的摘要或API的返回值。

智能体将不断重复这个 Thought -> Action -> Observation 的循环,将新的观察结果追加到历史记录中,形成一个不断增长的上下文,直到它在Thought中认为已经找到了最终答案,然后输出结果。这个过程形成了一个强大的协同效应:推理使得行动更具目的性,而行动则为推理提供了事实依据。

1.1 ReAct demo

demo:

import os
from openai import OpenAI
from dotenv import load_dotenv
from typing import List,Dict

#加载环境变量 .env文件
load_dotenv()

class HelloAgentsLLM:
    """
    为本书 "Hello Agents" 定制的LLM客户端。
    它用于调用任何兼容OpenAI接口的服务,并默认使用流式响应。
    """
    def __init__(self, model: str=None, apiKey: str=None, baseUrl: str=None,timeout: int=None):
        """
        初始化客户端。优先使用传入参数,如果未提供,则从环境变量加载。
        """
        self.model = model or os.getenv("LLM_MODEL_ID")
        apiKey = apiKey or os.getenv("LLM_API_KEY")
        baseUrl = baseUrl or os.getenv("LLM_BASE_URL")
        timeout = timeout or int(os.getenv("LLM_TIMEOUT",60))
        
        if not all([self.model,apiKey,baseUrl,timeout]):
            raise ValueError("模型ID、API密钥和服务地址必须被提供或在.env文件中定义。")

        self.client = OpenAI(api_key=apiKey,base_url=baseUrl,timeout=timeout)

    def think(self,messages: List[Dict[str, str]],temperature: float=0) -> str:
        """
        调用大语言模型进行思考,并返回其响应。
        """
        print(f"🧠 正在调用 {self.model} 模型...")
        try:
            response = self.client.chat.completions.create(model=self.model,messages=messages,temperature=temperature,stream=True)
            # 处理流式响应
            print("✅ 大语言模型响应成功:")
            collect_content=[]
            for chunk in response:
                content = chunk.choices[0].delta.content or ""
                print(content,end='',flush=True)
                collect_content.append(content)
            print() # 在流式输出结束后换行
            return "".join(collect_content)
        
        except Exception as e:
            print(f"❌ 调用LLM API时发生错误: {e}")
            return None
        
from serpapi import SerpApiClient
def search(query: str) -> str:
    """
    一个基于SerpApi的实战网页搜索引擎工具。
    它会智能地解析搜索结果,优先返回直接答案或知识图谱信息。
    """
    print(f"🔍 正在执行 [SerpApi] 网页搜索: {query}")
    try:
        api_key = os.getenv("SERPAPI_API_KEY")
        if not api_key:
            return "错误:SERPAPI_API_KEY 未在 .env 文件中配置。"

        params = {
            "engine": "google",
            "q": query,
            "api_key": api_key,
            "gl": "cn", #国家代码
            "hl": "zh-cn", #语言代码
        }
        client = SerpApiClient(params)
        results = client.get_dict()

        # 智能解析:优先寻找最直接的答案
        if "answer_box_list" in results:    # answer_box(Google的答案摘要框)
            return "\n".join(results["answer_box_list"])
        if "answer_box" in results and "answer" in results["answer_box"]:
            return results["answer_box"]["answer"]
        if "knowledge_graph" in results and "description" in results["knowledge_graph"]:  # knowledge_graph(知识图谱)
            return results["knowledge_graph"]["description"]
        if "organic_results" in results and results["organic_results"]:
            # 如果没有直接答案,则返回前三个有机结果的摘要
            snippets = [
                f"[{i+1}] {res.get('title', '')}\n{res.get('snippet', '')}"
                for i, res in enumerate(results["organic_results"][:3])
            ]
            return "\n\n".join(snippets)
        
        return f"对不起,没有找到关于 '{query}' 的信息。"
    except Exception as e:
        return f"搜索时发生错误: {e}"
    
from typing import Dict, Any
class ToolExecutor:
    """
    一个工具执行器,负责管理和执行工具。
    """
    def __init__(self):
        self.tools: Dict[str, Dict[str, Any]] = {}
    def registerTools(self,name: str,description: str,func: callable):
        """
        向工具箱中注册一个新工具。
        """
        if name in self.tools:
            print(f"警告:工具 '{name}' 已存在,将被覆盖。")
        self.tools[name] = {"description":description,"func":func}
        print(f"工具 '{name}' 已注册。")
    
    def getTools(self,name: str)-> callable:
        """
        根据名称获取一个工具的执行函数。
        """
        return self.tools.get(name,{}).get("func")
    
    def getAvailableTools(self)->str:
        """
        获取所有可用工具的格式化描述字符串。
        """
        return "\n".join([
            f"- {name} : {info["description"]}"
            for name, info in self.tools.items()
        ])

# ReAct提示词模板
# 角色定义,工具清单,格式规约,动态上下文
REACT_PROMPT_TEMPLATE = """
请注意,你是一个有能力调用外部工具的智能助手。

可用工具如下:
{tools}

请严格按照以下格式进行回应:

Thought: 你的思考过程,用于分析问题、拆解任务和规划下一步
Action: 你决定采取的行动,必须是以下格式之一:
- `[]`:调用一个可用工具
- `Finish[最终答案]`:当你认为已经获得最终答案时。
- 当你收集到足够的信息,能够回答用户的最终问题时,你必须在Action:字段后使用 finish(answer="...")来输出最终答案。

现在,请开始解决以下问题:
Question: {question}
History: {history}
"""
import re
class ReActAgent:
    def __init__(self,llm_client: HelloAgentsLLM,tool_executor: ToolExecutor,max_steps: int=5):
        self.llm_client = llm_client
        self.tool_executor = tool_executor
        self.max_steps = max_steps
        self.history = []

    #(这些方法 是 ReActAgent类的一部分)
    def _parse_output(self,text: str):
        """解析LLM的输出,提取Thought和Action"""
        thought_match = re.search(r"Thought: (.*)",text) # .默认不匹配换行符
        action_match = re.search(r"Action: (.*)",text)
        thought = thought_match.group(1).strip() if thought_match else None # 0表示整个字串(包括Thought),1表示获取(.*)匹配到的内容
        action = action_match.group(1).strip() if action_match else None
        return thought, action

    def _parse_action(self,action_text: str):
        """解析Action字符串,提取工具名称和输入。"""
        match = re.match(r"(\w+)\[(.*)\]",action_text)
        if match:
            return match.group(1), match.group(2) # 1表示工具名(\w+), 2表示输入(.*)
        return None, None
    
    def run(self,question:str):
        """
        运行ReAct智能体来回答一个问题。
        """
        self.history = [] #每次运行时重置历史记录
        current_step= 0

        while current_step < self.max_steps:
            current_step += 1
            print(f"--- 第{current_step}步 ---")

            # 1. 格式化提示词
            tools_desc = self.tool_executor.getAvailableTools()
            history_str = "\n".join(self.history)
            prompt = REACT_PROMPT_TEMPLATE.format(
                tools=tools_desc,
                question=question,
                history=history_str
            )

            # 2. 调用LLM进行思考
            messages = [{"role":"user","content":prompt}]
            response_text = self.llm_client.think(messages=messages)

            if not response_text :
                print("错误:LLM未能返回有效响应")
                break
            # ...(后续的解析、执行、整合步骤)
            # 3. 解析LLM的输出
            thought,action = self._parse_output(response_text)

            if thought:
                print(f"思考: {thought}")
            
            if not action:
                print("警告,未能解析出有效的Action,流程中止。")
                break

            # 4. 执行action
            if action.startswith("Finish"):
                # 如果是Finish指令,提取最终答案并结束
                final_answer = re.match(r"Finish\[(.*)\]",action).group(1)
                print(f"最终答案: {final_answer}")
                return final_answer
            
            tool_name, tool_input = self._parse_action(action)
            if not tool_name or not tool_input:
                # ....处理无效Action格式 ....
                continue
            print(f"🎬 行动: {tool_name}[{tool_input}]")
            tool_function = self.tool_executor.getTools(tool_name)
            if not tool_function:
                observation = f"错误:未找到名为 '{tool_name}'的工具。"
            else:
                observation = tool_function(tool_input) # 调用真实工具。

            # 5. 将action本身和工具执行后的observation添加到历史记录中。
            # (这段逻辑紧随工具调用之后,在 while 循环的末尾)
            print(f"👀 观察: {observation}")
            # 将本轮的Action和observation添加到历史记录中
            self.history.append(f"Action: {action}")
            self.history.append(f"Observation: {observation}")

        # 循环结束
        print("已达到最大步数,流程中止。")
        return None


if __name__ == "__main__":
    llm = HelloAgentsLLM()
    tool_executor = ToolExecutor()
    search_desc = "一个搜索网页的引擎,当你需要回答关于时事、事实以及在你的知识库中找不到的信息时,应使用此工具"
    tool_executor.registerTools("Search",search_desc,search)
    agent = ReActAgent(llm_client=llm,tool_executor=tool_executor)
    question = "华为最新的手机是哪一款?它的主要卖点是什么?"
    agent.run(question)

1.2 ReAct 优点与局限性

(1)ReAct 的主要特点
1.1 高可解释性:ReAct 最大的优点之一就是透明。
通过 Thought 链,我们可以清晰地看到智能体每一步的“心路历程”——它为什么会选择这个工具,下一步又打算做什么。
这对于理解、信任和调试智能体的行为至关重要。

1.2 动态规划与纠错能力:与一次性生成完整计划的范式不同,ReAct 是“走一步,看一步”。
它根据每一步从外部世界获得的 Observation 来动态调整后续的 Thought 和 Action。
如果上一步的搜索结果不理想,它可以在下一步中修正搜索词,重新尝试。

1.3 工具协同能力:ReAct 范式天然地将大语言模型的推理能力与外部工具的执行能力结合起来。
LLM 负责运筹帷幄(规划和推理),工具负责解决具体问题(搜索、计算),二者协同工作,突破了单一 LLM 在知识时效性、计算准确性等方面的固有局限。


(2)ReAct 的固有局限性
2.1 对LLM自身能力的强依赖:ReAct 流程的成功与否,高度依赖于底层 LLM 的综合能力。
如果 LLM 的逻辑推理能力、指令遵循能力或格式化输出能力不足,就很容易在 Thought 环节产生错误的规划,或者在 Action 环节生成不符合格式的指令,导致整个流程中断。

2.2 执行效率问题:由于其循序渐进的特性,完成一个任务通常需要多次调用 LLM。
每一次调用都伴随着网络延迟和计算成本。
对于需要很多步骤的复杂任务,这种串行的“思考-行动”循环可能会导致较高的总耗时和费用。

2.3 提示词的脆弱性:整个机制的稳定运行建立在一个精心设计的提示词模板之上。
模板中的任何微小变动,甚至是用词的差异,都可能影响 LLM 的行为。
此外,并非所有模型都能持续稳定地遵循预设的格式,这增加了在实际应用中的不确定性。

2.4 可能陷入局部最优:步进式的决策模式意味着智能体缺乏一个全局的、长远的规划。
它可能会因为眼前的 Observation 而选择一个看似正确但长远来看并非最优的路径,甚至在某些情况下陷入“原地打转”的循环中。

当遇到ReAct的问题时,调试可以从以下几点入手:

1. 检查完整的提示词:
在每次调用 LLM 之前,将最终格式化好的、包含所有历史记录的完整提示词打印出来。这是追溯 LLM 决策源头的最直接方式。

2. 分析原始输出:
当输出解析失败时(例如,正则表达式没有匹配到 Action),务必将 LLM 返回的原始、未经处理的文本打印出来。这能帮助你判断是 LLM 没有遵循格式,还是你的解析逻辑有误。

3. 验证工具的输入与输出:
检查智能体生成的 tool_input 是否是工具函数所期望的格式,同时也要确保工具返回的 observation 格式是智能体可以理解和处理的。

4. 调整提示词中的示例 (Few-shot Prompting):
如果模型频繁出错,可以在提示词中加入一两个完整的“Thought-Action-Observation”成功案例,通过示例来引导模型更好地遵循你的指令。

5. 尝试不同的模型或参数:
更换一个能力更强的模型,或者调整 temperature 参数(通常设为0以保证输出的确定性),有时能直接解决问题。

2. Plan-and-Solve

Plan-and-Solve Prompting 由 Lei Wang 在2023年提出。其核心动机是为了解决思维链在处理多步骤、复杂问题时容易“偏离轨道”的问题。
与 ReAct 将思考和行动融合在每一步不同,Plan-and-Solve 将整个流程解耦为两个核心阶段,如下所示:

1. 规划阶段 (Planning Phase): 首先,智能体会接收用户的完整问题。
它的第一个任务不是直接去解决问题或调用工具,而是将问题分解,并制定出一个清晰、分步骤的行动计划。这个计划本身就是一次大语言模型的调用产物。

2. 执行阶段 (Solving Phase): 在获得完整的计划后,智能体进入执行阶段。
它会严格按照计划中的步骤,逐一执行。
每一步的执行都可能是一次独立的 LLM 调用,或者是对上一步结果的加工处理,直到计划中的所有步骤都完成,最终得出答案。

这种“先谋后动”的策略,使得智能体在处理需要长远规划的复杂任务时,能够保持更高的目标一致性,避免在中间步骤中迷失方向。

2.1 Plan-and-Solve demo

demo:

PLANNER_PROMPT_TEMPLATE = """
你是一个顶级的AI规划专家,你的任务是讲用户提出的复杂问题分解成一个由多个简单步骤组成的行动计划。
请确保计划中的每个步骤都是一个独立的、可执行的子任务,并且严格按照逻辑顺序排列。
你的输出必须是Python列表,其中每个元素都是一个描述子任务的字符串。

问题: {question}

请严格按照以下格式输出你的计划,```python与```作为前后缀是必要的:
```python
["步骤1","步骤2","步骤3", ...]
```
"""

from llm_client import HelloAgentsLLM
import ast
class Planner:
    def __init__(self,llm_client:HelloAgentsLLM):
        self.llm_client = llm_client

    def plan(self,question: str)-> list[str]:
        """
        根据用户问题生成一个行动计划
        """
        prompt = PLANNER_PROMPT_TEMPLATE.format(question=question)

        # 为了生成计划,构造一个简单的消息列表
        messages=[{"role":"user","content": prompt}]
        
        print("--- 正在生成计划 ---")
        # 使用流失输出来获取完整的计划
        response_text = self.llm_client.think(messages=messages) or ""

        print(f"✅ 计划已生成:\n{response_text}")

        # 解析LLM输出的列表字符串
        try:
            # 找到```python和```之间的内容
            plan_str = response_text.split("```python")[1].split("```")[0].strip()
            # 使用ast.literal_eval来安全地执行字符串,将其转化为python列表
            plan = ast.literal_eval(plan_str)
            return plan if isinstance(plan,list) else []
        except (ValueError,SyntaxError,IndexError) as e:
            print(f"❌ 解析计划时出错: {e}")
            print(f"原始响应: {response_text}")
            return []
        except Exception as e:
            print(f"❌ 解析计划时出错: {e}")

EXECUTOR_PROMPT_TEMPLATE = """
你是一位顶级的AI执行专家,你的任务是严格按照给定的计划,一步步地解决问题。
你将收到原始的问题、完整的计划、以及到目前为止已经完成的步骤和结果。
请你专注于解决"当前步骤",并仅输出该步骤的最终答案,不要输出任何额外的解释或对话。

# 原始问题:
{question}

# 完整计划:
{plan}

# 历史步骤与结果:
{history}

# 当前步骤:
{current_step}

请仅输出针对"当前步骤"的回答:
"""

class Executor:
    def __init__(self,llm_client:HelloAgentsLLM):
        self.llm_client = llm_client

    def execute(self,question: str,plan: list[str])-> str:
        """
        根据计划,逐步执行并解决问题。
        """
        history = "" #用于存储历史步骤和结果的字符串
        
        print("\n--- 正在执行计划 ---")

        for i, step in enumerate(plan):
            print(f"\n-> 正在执行步骤 {i+1}/{len(plan)}: {step}")

            prompt = EXECUTOR_PROMPT_TEMPLATE.format(
                question=question,
                plan=plan,
                history=history,
                current_step=step
            )
            messages = [{"role":"user","content":prompt}]

            response_text = self.llm_client.think(messages=messages) or ""

            #更新历史记录,为下一步做准备
            history += f"步骤 {i+1}: {step}\n结果: {response_text}\n\n"

            print(f"✅ 步骤 {i+1} 已完成,结果: {response_text}")

        # 循环结束后,最后一步的响应就是最终答案
        final_answer = response_text
        return final_answer
    
class PlanAndSolveAgent:
    def __init__(self,llm_client:HelloAgentsLLM):
        """
        初始化智能体,同时创建规划器和执行器实例。
        """
        self.llm_client = llm_client
        self.planner = Planner(self.llm_client)
        self.executor = Executor(self.llm_client)

    def run(self,question: str):
        """
        运行智能体的完整流程:先规划,后执行。
        """
        print(f"\n--- 开始处理问题 ---\n 问题: {question}")

        # 1. 调用规划器生成计划
        plan = self.planner.plan(question)

        # 检查计划是否成功生成
        if not plan:
            print("\n--- 任务终止 --- \n无法生成有效的行动计划")
            return
        
        # 2. 调用执行器执行计划
        final_answer = self.executor.execute(question,plan)

        print(f"\n--- 任务完成 ---\n最终答案: {final_answer}")

if __name__ == "__main__":
    question = "一个水果店一周卖出了15个苹果。周二卖出的苹果数量是周一的两倍。周三卖出的数量比周二少了5个。请问这三天总共卖出了多少个苹果?"
    llm = HelloAgentsLLM()
    plan_and_solve_agent = PlanAndSolveAgent(llm)
    plan_and_solve_agent.run(question)

3. Reflection

在已经实现的ReActPlan-and-Solve范式中,智能体一旦完成了任务,其工作流程便告结束。
然而,它们生成的初始答案,无论是行动轨迹还是最终结果,都可能存在谬误或有待改进之处
Reflection 机制的核心思想,正是为智能体引入一种事后(post-hoc)的自我校正循环,使其能够像人类一样,审视自己的工作,发现不足,并进行迭代优化。
Reflection核心工作流程可以概括为一个简洁的三步循环:执行 -> 反思 -> 优化。

1. 执行 (Execution):
首先,智能体使用我们熟悉的方法(如 ReAct 或 Plan-and-Solve)尝试完成任务,生成一个初步的解决方案或行动轨迹。这可以看作是“初稿”。

2. 反思 (Reflection):
接着,智能体进入反思阶段。它会调用一个独立的、或者带有特殊提示词的大语言模型实例,来扮演一个“评审员”的角色。
这个“评审员”会审视第一步生成的“初稿”,并从多个维度进行评估,例如:
事实性错误:是否存在与常识或已知事实相悖的内容?
逻辑漏洞:推理过程是否存在不连贯或矛盾之处?
效率问题:是否有更直接、更简洁的路径来完成任务?
遗漏信息:是否忽略了问题的某些关键约束或方面? 根据评估,它会生成一段结构化的反馈 (Feedback),指出具体的问题所在和改进建议。

3. 优化 (Refinement):
最后,智能体将“初稿”和“反馈”作为新的上下文,再次调用大语言模型,
要求它根据反馈内容对初稿进行修正,生成一个更完善的“修订稿”。

Reflection的价值在于,为智能体提供了一个内部的纠错回路,使其运行不完全依赖于外部反馈。并为大模型构建了一个临时的短期记忆
个人感觉,reflection可以说是reactplan and solve的进阶版。

3.1 Reflection demo

    from typing import List,Dict,Any,Optional

    class Memory:
        """
        一个简单的短期记忆模块,用于存储智能体的行动与反思轨迹。
        """
        def __init__(self):
            """
            初始化一个空列表来存储所有记录。
            """
            self.records: List[Dict[str,Any]] = []

        def add_record(self, record_type:str,content: str):
            """
            向记忆中添加一条新纪录。

            参数:
            - record_type (str): 记录的类型('execution'或'reflection').
            - content (str): 记录的具体内容(例如,生成的代码或反思的反馈)。
            """
            record = {"type": record_type,"content":content}
            self.records.append(record)
            print(f"📝 记忆已更新,新增一条 '{record_type}' 记录。")

        def get_trajectory(self)->str:
            """
            将所有记录格式化为一个连贯的字符串文本,用于构建提示词
            """
            trajectory_parts = []
            for record in self.records:
                if record['type'] == 'execution':
                    trajectory_parts.append(f"--- 上一轮尝试(代码)---\n{record['content']}")
                elif record['type'] == 'reflection':
                    trajectory_parts.append(f"--- 评审员反馈 ---\n{record['content']}")

            return "\n\n".join(trajectory_parts)
        
        def get_last_execution(self)-> Optional[str]:
            """
            获取最近一次的执行结果(例如,最新生成的代码)。
            如果不存在,则返回None
            """
            for record in reversed(self.records):
                if record['type'] == 'execution':
                    return record['content']
            return None

    INITIAL_PROPMPT_TEMPLATE = """
    你是一位资深的Python程序员。请根据以下要求,编写一个Python函数。
    你的代码必须包含完整的函数签名、文档字符串,并遵循PEP 8编码规范。

    要求: {task}

    请直接输出代码,不要包含任何额外的解释
    """

    REFLECT_PROMPT_TEMPLATE = """
    你是一位极其严格的代码评审专家和资深算法工程师,对代码的性能有极致的要求。
    你的任务是审查以下Python代码,并专注于找出其在<strong>算法效率</strong>上的主要瓶颈。

    # 原始任务:
    {task}

    # 待审查的代码:
    ```pythobn
    {code}
    ```

    请分析该代码的时间复杂度,并思考是否存在一种<strong>算法上更有</strong>的解决方案来显著提升性能。
    如果存在,请清晰地指出当前算法的不足,并提出具体的、可行的改进算法建议(例如,使用筛法替代试除法)。
    如果代码在算法层面已经达到最优,才能回答"无需改进"。

    请直接输出你的反馈,不要包含任何额外的解释。
    """

    REFINE_PROMPT_TEMPLATE = """
    你是一位资深的Python程序员。你正在根据一位代码评审专家的反馈来优化你的代码。

    # 原始任务:
    {task}

    # 你上一轮尝试的代码:
    {last_code_attempt}
    # 评审员反馈:
    {feedback}

    请根据评审员的反馈,生成一个优化后的新版本代码。
    你的代码必须包含完整的函数签名、文档字符串,并遵循PEP 8编码规范。
    请直接输出优化后的代码,不要包含任何额外的解释。
    """

    from llm_client import HelloAgentsLLM

    class ReflectionAgent:
        def __init__(self,llm_client:HelloAgentsLLM,max_iterations=3):
            self.llm_client = llm_client
            self.memory = Memory()
            self.max_iterations = max_iterations

        def _get_llm_response(self,prompt:str)-> str:
            """一个辅助方法,用于调用LLM并获取完整的流失响应。"""
            messages = [{"role":"user","content": prompt}]
            response_text = self.llm_client.think(messages=messages) or ""
            return response_text

        def run(self,task: str):
            print(f"\n--- 开始处理任务 ---\n任务:{task}")

            # --- 1. 初始执行 ---
            print("\n--- 正在进行初始尝试 ---")
            initial_prompt = INITIAL_PROPMPT_TEMPLATE.format(task=task)
            initial_code = self._get_llm_response(initial_prompt)
            self.memory.add_record("execution",initial_code)

            # --- 2. 迭代循环:反思与优化 ---
            for i in range(self.max_iterations):
                print(f"\n--- 第 {i+1}/{self.max_iterations} 轮迭代 ---")

                # a. 反思
                print("\n-> 正在进行反思...")
                last_code = self.memory.get_last_execution()
                reflect_prompt = REFLECT_PROMPT_TEMPLATE.format(task=task,code=last_code)
                feedback = self._get_llm_response(reflect_prompt)
                self.memory.add_record("reflection",feedback)

                # b. 检查是否需要停止:
                if "无需改进" in feedback:
                    print("\n✅ 反思认为代码已无需改进,任务完成。")
                    break

                # c. 优化
                print("\n-> 正在进行优化...")
                refine_prompt = REFINE_PROMPT_TEMPLATE.format(
                    task=task,
                    last_code_attempt = last_code,
                    feedback = feedback
                )
                refine_code = self._get_llm_response(refine_prompt)
                self.memory.add_record("execution",refine_code)

            final_code = self.memory.get_last_execution()
            print(f"\n--- 任务完成 ---\n最终生成的代码:\n```python\n{final_code}\n```")
            return final_code

    if __name__ == '__main__':
        # 1. 初始化LLM客户端 (请确保你的 .env 和 llm_client.py 文件配置正确)
        try:
            llm_client = HelloAgentsLLM()
        except Exception as e:
            print(f"初始化LLM客户端时出错: {e}")
            exit()

        # 2. 初始化 Reflection 智能体,设置最多迭代2轮
        agent = ReflectionAgent(llm_client, max_iterations=2)

        # 3. 定义任务并运行智能体
        task = "编写一个Python函数,找出1到n之间所有的素数 (prime numbers)。"
        agent.run(task)

3.2 Reflection优缺点

一个设计良好的Reflection机制,其价值不仅在于修复错误,更在于驱动解决方案在质量和效率上实现阶梯式的提升。

缺点:
1. 开销大,每轮迭代调用2次大模型
2. 延迟大,反思和优化必须串行
3. 提示词工程复杂度大,要写多个提示词,且提示词质量很重要。


优点:
1. 解决方案质量跃迁
2. 鲁棒性和可靠性增强。

4. 常见的AI agent低代码平台

1. coze
2. dify
3. n8n

5. AI agent开发框架

1、AutoGen:AutoGen 的核心思想是通过对话实现协作。
它将多智能体系统抽象为一个由多个“可对话”智能体组成的群聊。
开发者可以定义不同角色(如 Coder, ProductManager, Tester),并设定它们之间的交互规则(例如,Coder 写完代码后由 Tester 自动接管)。
任务的解决过程,就是这些智能体在群聊中通过自动化消息传递,不断对话、协作、迭代直至最终目标达成的过程。

2、AgentScope:AgentScope 是一个专为多智能体应用设计的、功能全面的开发平台。
它的核心特点是易用性和工程化。它提供了一套非常友好的编程接口,让开发者可以轻松定义智能体、构建通信网络,并管理整个应用的生命周期。
其内置的消息传递机制和对分布式部署的支持,使其非常适合构建和运维复杂、大规模的多智能体系统。

3、CAMEL:CAMEL 提供了一种新颖的、名为角色扮演 (Role-Playing) 的协作方法。
其核心理念是,我们只需要为两个智能体(例如,AI研究员 和 Python程序员)设定好各自的角色和共同的任务目标,它们就能在“初始提示 (Inception Prompting)”的引导下,自主地进行多轮对话,相互启发、相互配合,共同完成任务。它极大地降低了设计多智能体对话流程的复杂度。

4、LangGraph:作为 LangChain 生态的扩展,LangGraph 另辟蹊径,将智能体的执行流程建模为图 (Graph)。
在传统的链式结构中,信息只能单向流动。
而 LangGraph 将每一步操作(如调用LLM、执行工具)定义为图中的一个节点 (Node),并用边 (Edge) 来定义节点之间的跳转逻辑。
这种设计天然支持循环 (Cycles),使得实现如 Reflection 这样的迭代、修正、自我反思的复杂工作流变得异常简单和直观。

5.1 AutoGen

AutoGen 的设计哲学根植于”以对话驱动协作”。它巧妙地将复杂的任务解决流程,映射为不同角色的智能体之间的一系列自动化对话。

5.2 AgentScope

5.3 CAMEL

5.4 LangGraph

references

https://datawhalechina.github.io/hello-agents/#/./chapter4/%E7%AC%AC%E5%9B%9B%E7%AB%A0%20%E6%99%BA%E8%83%BD%E4%BD%93%E7%BB%8F%E5%85%B8%E8%8C%83%E5%BC%8F%E6%9E%84%E5%BB%BA?id=_421-react-%e7%9a%84%e5%b7%a5%e4%bd%9c%e6%b5%81%e7%a8%8b