【LLM应用开发原理】Agent经典开发范式

Friday, Mar 6, 2026 | 2 minute read | Updated at Friday, Mar 6, 2026

@

动手学Agent

推荐一个Datawhale开源项目,体系学习,动手实现一个简单Agent架构:HelloAgent

具体的编码实现项目中非常详细,本博文中我只尝试做一个设计思想整理。

Agent经典范式

1.ReAct范式(Reasoning and Acting)

最基础、应用最广的范式,是目前绝大多数 Agent 的基石。

它模仿人类解决问题的直觉:先思考(Thought),再行动(Action),最后观察结果(Observation)。

ReAct结构示意图
ReAct结构示意图

逻辑链路

传统LLM是一问一答。ReAct引入了一个循环(Loop)

用户输入 $\rightarrow$ 思考 (Thought) $\rightarrow$ 行为 (Action/Tool Call) $\rightarrow$ 观察 (Observation/Result) $\rightarrow$ 再次思考…直到得出答案。

适用场景:绝大多数调用工具的短链路任务,如实时搜索、数据库查询、如查天气、订机票等。

缺点Token 消耗大且易迷路

在复杂长任务或者长链路中,模型容易在反复的循环中忘记最初的目标(上下文漂移),或者陷入无限死循环。

流程

  1. 用户输入:“上海明天的天气适合穿短袖吗?”
  2. Thought:我需要先查上海明天的气温,然后再判断是否适合短袖。
  3. Action:调用 weather_api(location="shanghai", date="tomorrow")
  4. Observation:返回 15°C - 22°C,有阵雨。
  5. Thought:气温偏凉且有雨,不适合穿短袖,建议长袖加外套。
  6. Final Answer:不适合,建议穿长袖…

代码逻辑

LLM节点和工具节点之间的无限乒乓球,直到LLM决定停止(或达到最大预设次数)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
def _run_with_tools(self, messages: list, input_text: str, max_tool_iterations: int, **kwargs) -> str:
    current_iteration = 0

    while current_iteration < max_tool_iterations:
        current_iteration += 1
        # 1. 调用 LLM
        response = self.llm.invoke(messages, **kwargs)

        # 2. 检查是否有工具调用
        tool_calls = self._parse_tool_calls(response)

        if not tool_calls:
            # 如果没有工具调用,说明这已经是最终回答了
            self.add_message(Message(input_text, "user"))
            self.add_message(Message(response, "assistant"))
            print(f"✅ {self.name} 最终响应完成")
            return response

        print(f"🔧 检测到 {len(tool_calls)} 个工具调用")

        # 3. 执行工具并收集结果
        tool_results = []
        clean_response = response
        for call in tool_calls:
            result = self._execute_tool_call(call['tool_name'], call['parameters'])
            tool_results.append(f"工具 {call['tool_name']} 返回结果: {result}")

            # 从响应中移除工具调用标记,保持历史记录整洁
            clean_response = clean_response.replace(call['original'], "")

        # 4. 将结果喂回给模型,继续下一轮循环
        # 如果 AI 只输出了标签而没有文字,我们补一个提示词,防止发送空消息
        assistant_display = clean_response.strip() if clean_response.strip() else "正在调用工具处理..."

        # 将清理后的内容存入 assistant 角色
        messages.append({"role": "assistant", "content": assistant_display})

        # 存入工具返回的结果,让 AI 基于这些事实进行下一轮思考
        messages.append({
            "role": "user",
            "content": f"工具执行结果:\n" + "\n".join(tool_results) + "\n请基于这些结果继续回答。"
        })

    return "错误:达到最大工具调用次数限制。"

2.Plan-and-Execute 范式(规划与执行)

针对ReAct容易“走一步看一步”导致跑偏的问题,这种范式把“规划”和“执行”拆分开。

核心逻辑:先做任务规划,再逐个击破。通常由两个逻辑单元(Planner和Executor)组成。

Plan-and-Execute范式示意图
Plan-and-Execute范式示意图

适用场景:撰写研报、多步骤跨平台操作等任务步骤明确、流程较长、逻辑复杂的任务。

缺点响应延迟(Latency)高。由于需要先做完整的规划,用户的第一反馈会很慢;且如果初始规划失误,后续步骤可能全是无效功。

流程

  1. 用户输入:“分析特斯拉和比亚迪的财报并对比写一份 PPT 提纲。”
  2. Planner (规划阶段):生成步骤列表:① 搜索特斯拉财报;② 搜索比亚迪财报;③ 提取关键数据;④ 生成对比表格;⑤ 撰写提纲。
  3. Executor (执行阶段):依次调用 ReAct 模式完成 ① 至 ⑤。
  4. Re-planner (重评阶段):检查结果,如果发现步骤 ② 没搜到数据,则修改计划重新搜索。

代码逻辑

for循环+队列,生成清单->消费清单,清单可以线性执行,部分不依赖前面内容的也可以并行执行。

Tip

每一个清单(执行器)单元也可以是一个单个的拥有独立调用工具能力的Agent。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
def run(self,task:str):
    # 1. Planner 阶段:生成静态计划
    plan=self._generate_plan(task)
    print(f"📋 生成的计划:\n{plan}")

    #2. Solver阶段: 循环执行每一个步骤
    results=[]
    steps=self._parse_steps(plan)
    for i,step in enumerate(steps):
        print(f"🚀 正在执行第 {i+1} 步: {step}")
        #调用之前写好的SimpleAgent.run
        result=self.executor.run(step)
        results.append(f"步骤{i+1}结果:{result}")
    return self._summarize(task,results)

3.Reflection/Self-Correction范式(反思与修正)

为了让Agent不仅“做完”,还能“做好”,引入了类似人类的“自我审查”机制。

全称:Reasoning with Reflection (反思增强)

应用场景:长文本生成、代码生成、翻译优化。

缺点成本极高。为了得到一个正确答案,可能需要消耗 3-5 倍的 Token 和计算时间。

核心逻辑:引入一个批判者(Critic)角色,对输出结果进行打分和错误分析,并将失败经验作为新的上下文。

Reflection范式原理示意
Reflection范式原理示意

流程

  1. 执行:模型生成一段处理数据的 Python 代码。
  2. 测试:代理层在沙箱运行代码,报错 IndexError
  3. Reflection:模型分析报错原因:“我在处理空列表时没有判断长度。”
  4. Refine:模型参考失败经验,生成修正后的代码并再次测试。

代码逻辑

Tip

这里的批判者(Critic)往往可能会使用不同的模型或者不同的Agent来做交叉验证。

1
2
3
4
5
6
candidate = agent.initial_guess(task)
for i in range(max_retries):
    feedback = critic.evaluate(candidate) # 检查错误或逻辑漏洞
    if feedback.is_perfect: break
    # 将失败尝试和反馈重新喂给模型
    candidate = agent.refine(candidate, feedback, memory=past_attempts)

© 2021 - 2026 古月月仔的博客

🌱 Powered by Hugo with theme Dream.

关于我
  • 我是古月月仔
  • Shimizu Tou
  • 分享技术学习笔记与生活点滴
  • 现居: 上海 中国
  • 家乡: 平遥 山西
在用的学习工具
  • 📝 Typora — 极致简洁的 Markdown 编辑器,助力沉浸式文档撰写与知识记录。
  • 📓 Notion — 一站式工作空间,用于搭建个人知识库、项目管理与深度协作。
  • 🔗 N8N — 强大的基于节点的自动化工作流工具,轻松实现不同应用间的逻辑联动。
  • 🤖 Gemini — 智能 AI 助手,在代码辅助、创意激发与信息检索中提供强力支撑。
我的爱好
  • 🚀 喜欢折腾各种好玩的技术
  • 📸 业余摄影爱好者
  • 🎮 各类游戏玩家
  • 💻 数码产品折腾爱好者
  • 📚 阅读:赫尔曼·黑塞 & 阿尔贝·加缪
  • 🎞️ 追番中:《电锯人:蕾塞篇》
  • 🎬 经典重温:《命运石之门》
最近正在学