Agent 基础
Agent 的本质
Agent 就是一个能自己干活的 AI。
更工程一点:你给它一个目标、一个工具箱和一套边界(预算 / 权限 / 审批 / 沙箱),它在循环里推进任务,直到完成或停下。
Agent = 大脑 + 手脚 + 记忆 + 主见
(LLM) (Tools) (Memory) (Autonomy)

| 等级 | 名称 | 你说 | 它做 | 典型例子 |
|---|---|---|---|---|
| L0 | Chatbot | 问一句 | 答一句 | ChatGPT 基础对话 |
| L1 | Tool Agent | 要查天气 | 调 API 返回结果 | GPTs 的 Actions |
| L2 | ReAct Agent | 复杂问题 | 思考→行动→观察,循环 | LangChain ReAct |
| L3 | Planning Agent | 大任务 | 先拆解计划,再逐个执行 | 本书重点 |
| L4 | Multi-Agent | 更大任务 | 多个 Agent 分工协作 | Shannon Supervisor |
| L5 | Autonomous | 模糊目标 | 长期自主运行,自我迭代 | Claude Code, Manus |
智能体的构成以及运行原理
PEAS 模型
在人工智能领域,通常使用PEAS 模型来精确描述一个任务环境,即分析其性能度量(Performance)、环境(Environment)、执行器(Actuators)和传感器(Sensors) 。以上文提到的智能旅行助手为例,下表 1.2 展示了如何运用 PEAS 模型对其任务环境进行规约。

在实践中,LLM 智能体所处的数字环境展现出若干复杂特性,这些特性直接影响着智能体的设计。
首先,环境通常是部分可观察的。例如,旅行助手在查询航班时,无法一次性获取所有航空公司的全部实时座位信息。它只能通过调用航班预订 API,看到该 API 返回的部分数据,这就要求智能体必须具备记忆(记住已查询过的航线)和探索(尝试不同的查询日期)的能力。
其次,行动的结果也并非总是确定的。根据结果的可预测性,环境可分为确定性和随机性。旅行助手的任务环境就是典型的随机性环境。当它搜索票价时,两次相邻的调用返回的机票价格和余票数量都可能不同,这就要求智能体必须具备处理不确定性、监控变化并及时决策的能力。
此外,环境中还可能存在其他行动者,从而形成多智能体(Multi-agent) 环境。对于旅行助手而言,其他用户的预订行为、其他自动化脚本,甚至航司的动态调价系统,都是环境中的其他“智能体”。它们的行动(例如,订走最后一张特价票)会直接改变旅行助手所处环境的状态,这对智能体的快速响应和策略选择提出了更高要求。
最后,几乎所有任务都发生在序贯且动态的环境中。“序贯”意味着当前动作会影响未来;而“动态”则意味着环境自身可能在智能体决策时发生变化。这就要求智能体的“感知-思考-行动-观察”循环必须能够快速、灵活地适应持续变化的世界。
智能体并非一次性完成任务,而是通过一个持续的循环与环境进行交互,这个核心机制被称为 智能体循环 (Agent Loop)。如图所示,该循环描述了智能体与环境之间的动态交互过程,构成了其自主行为的基础。
这个循环主要包含以下几个相互关联的阶段:
感知 (Perception):这是循环的起点。智能体通过其传感器(例如,API 的监听端口、用户输入接口)接收来自环境的输入信息。这些信息,即观察 (Observation),既可以是用户的初始指令,也可以是上一步行动所导致的环境状态变化反馈。
思考 (Thought)
:接收到观察信息后,智能体进入其核心决策阶段。对于 LLM 智能体而言,这通常是由大语言模型驱动的内部推理过程。如图所示,“思考”阶段可进一步细分为两个关键环节:
- 规划 (Planning):智能体基于当前的观察和其内部记忆,更新对任务和环境的理解,并制定或调整一个行动计划。这可能涉及将复杂目标分解为一系列更具体的子任务。
- 工具选择 (Tool Selection):根据当前计划,智能体从其可用的工具库中,选择最适合执行下一步骤的工具,并确定调用该工具所需的具体参数。
行动 (Action):决策完成后,智能体通过其执行器(Actuators)执行具体的行动。这通常表现为调用一个选定的工具(如代码解释器、搜索引擎 API),从而对环境施加影响,意图改变环境的状态。
行动并非循环的终点。智能体的行动会引起环境 (Environment) 的状态变化 (State Change),环境随即会产生一个新的观察 (Observation) 作为结果反馈。这个新的观察又会在下一轮循环中被智能体的感知系统捕获,形成一个持续的“感知-思考-行动-观察”的闭环。智能体正是通过不断重复这一循环,逐步推进任务,从初始状态向目标状态演进。
ReAct 循环

- Reason(思考)
分析现在的情况,决定下一步干什么。
输入:用户目标 + 历史观察结果
输出:下一步要做什么,为什么
关键原则:只想一步。 不要让 LLM 想太远,它会发散。告诉它:“基于当前信息,你下一个动作是什么?”
- Act(行动)
调用工具,执行动作。
输入:思考阶段决定的动作
输出:执行结果
提示:一轮只推进一个关键动作。前期调试时尤其重要:动作越小,越容易定位问题。等你把流程跑顺了,再考虑并行调用工具提速。
常见的行动类型:
- 追问/确认(Clarify)
- 搜索(Web Search)
- 读文件(Read File)
- 写文件(Write File)
- 调用 API(HTTP Request)
- 执行代码(Code Execution)
- Observe(观察)
记录执行结果,喂给下一轮的 Reason 阶段。
输入:行动的执行结果
输出:结构化的观察记录
下面是一个简单示例
"""智能旅行助手 Agent — 基于 ReAct 模式调用工具和 LLM。"""
import re
import requests
from openai import OpenAI
from tavily import TavilyClient
# ---------------------------------------------------------------------------
# 配置
# ---------------------------------------------------------------------------
API_KEY = "sk-**************************"
BASE_URL = "https://api.deepseek.com"
MODEL_ID = "deepseek-v4-pro"
TAVILY_API_KEY = "tvly-dev-2************"
MAX_ITERATIONS = 5
REQUIRED_TOOLS = ("get_weather", "get_attraction")
DEFAULT_USER_PROMPT = (
"你好,请帮我查询一下今天北京的天气,然后根据天气推荐一个合适的旅游景点。"
)
AGENT_SYSTEM_PROMPT = """
你是一个智能旅行助手。你的任务是分析用户的请求,并使用可用工具一步步地解决问题。
# 工作流程(必须按顺序执行,不可跳过):
1. 调用 get_weather 获取天气
2. 调用 get_attraction 获取景点推荐(必须使用,禁止自行编造景点)
3. 整合两次工具结果后,再使用 Finish 回答用户
# 可用工具:
- `get_weather(city: str)`: 查询指定城市的实时天气。
- `get_attraction(city: str, weather: str)`: 根据城市和天气搜索推荐的旅游景点。
# 输出格式要求:
你的每次回复必须严格遵循以下格式,包含一对Thought和Action:
Thought: [你的思考过程和下一步计划]
Action: [你要执行的具体行动]
Action的格式必须是以下之一:
1. 调用工具:function_name(arg_name="arg_value")
2. 结束任务:Finish[最终答案]
# 重要提示:
- 每次只输出一对Thought-Action
- Action必须在同一行,不要换行
- 在未调用 get_attraction 之前,禁止使用 Finish
- Finish 必须严格基于 Observation 中的工具返回结果,不得修改或编造数据
- 天气信息必须原样引用 get_weather 的 Observation(如气温数值)
- 景点推荐必须来自 get_attraction 的 Observation,优先引用其中的中文搜索结果
- 当两次工具都调用完毕、信息足够时,使用 Action: Finish[最终答案] 结束
请开始吧!
"""
# ---------------------------------------------------------------------------
# 工具
# ---------------------------------------------------------------------------
def get_weather(city: str) -> str:
"""通过 wttr.in API 查询指定城市的实时天气。"""
try:
data = requests.get(f"https://wttr.in/{city}?format=j1", timeout=10).json()
current = data["current_condition"][0]
desc = current["weatherDesc"][0]["value"]
return f"{city}当前天气:{desc},气温{current['temp_C']}摄氏度"
except requests.RequestException as e:
return f"错误:查询天气时遇到网络问题 - {e}"
except (KeyError, IndexError, ValueError) as e:
return f"错误:解析天气数据失败,可能是城市名称无效 - {e}"
def get_attraction(city: str, weather: str) -> str:
"""根据城市和天气,使用 Tavily Search API 搜索并返回景点推荐。"""
try:
response = TavilyClient(api_key=TAVILY_API_KEY).search(
query=f"{city}在{weather}天气下最值得去的旅游景点推荐及理由",
search_depth="basic",
include_answer=True,
)
results = sorted(
response.get("results", []),
key=lambda r: sum(
1 for c in r.get("title", "") + r.get("content", "") if "\u4e00" <= c <= "\u9fff"
),
reverse=True,
)
parts = []
for item in results[:3]:
title = item.get("title", "").strip()
content = " ".join(item.get("content", "").split())
if len(content) > 200:
content = content[:200] + "..."
if title:
parts.append(f"- {title}: {content}")
if answer := response.get("answer"):
parts.append(f"- 综合摘要: {answer}")
return "景点搜索结果:\n" + "\n".join(parts) if parts else "抱歉,没有找到相关的旅游景点推荐。"
except Exception as e:
return f"错误:执行Tavily搜索时出现问题 - {e}"
TOOLS = {
"get_weather": get_weather,
"get_attraction": get_attraction,
}
# ---------------------------------------------------------------------------
# Agent 主循环
# ---------------------------------------------------------------------------
def run_agent(
user_prompt: str = DEFAULT_USER_PROMPT,
max_iterations: int = MAX_ITERATIONS,
) -> None:
"""运行 ReAct Agent:LLM 调用、输出解析、工具执行。"""
llm = OpenAI(api_key=API_KEY, base_url=BASE_URL)
history = [f"用户请求: {user_prompt}"]
called_tools: set[str] = set()
print(f"用户输入: {user_prompt}\n" + "=" * 40)
for i in range(max_iterations):
print(f"--- 循环 {i + 1} ---\n")
# 1. 调用 LLM
print("正在调用大语言模型...")
try:
resp = llm.chat.completions.create(
model=MODEL_ID,
messages=[
{"role": "system", "content": AGENT_SYSTEM_PROMPT},
{"role": "user", "content": "\n".join(history)},
],
)
llm_output = resp.choices[0].message.content or ""
print("大语言模型响应成功。")
except Exception as e:
print(f"调用LLM API时发生错误: {e}")
llm_output = "错误:调用语言模型服务时出错。"
# 2. 截断多余的 Thought-Action,提取 Action
if match := re.search(
r"(Thought:.*?Action:.*?)(?=\n\s*(?:Thought:|Action:|Observation:)|\Z)",
llm_output,
re.DOTALL,
):
llm_output = match.group(1).strip()
print(f"模型输出:\n{llm_output}\n")
history.append(llm_output)
action_match = re.search(r"Action: (.*)", llm_output, re.DOTALL)
if not action_match:
observation = "错误: 未能解析到 Action 字段。请严格遵循 'Thought: ... Action: ...' 格式。"
print(f"Observation: {observation}\n" + "=" * 40)
history.append(f"Observation: {observation}")
continue
action_str = action_match.group(1).strip()
# 3. Finish:检查必需工具是否都已调用
if action_str.startswith("Finish"):
missing = [t for t in REQUIRED_TOOLS if t not in called_tools]
if missing:
observation = f"错误: 尚未调用必需工具 {', '.join(missing)},禁止 Finish。"
print(f"Observation: {observation}\n" + "=" * 40)
history.append(f"Observation: {observation}")
continue
answer = re.match(r"Finish\[(.*)\]", action_str, re.DOTALL)
print(f"任务完成,最终答案: {answer.group(1) if answer else action_str}")
break
# 4. 工具调用
tool_match = re.search(r"(\w+)\(", action_str)
args_match = re.search(r"\((.*)\)", action_str)
if not tool_match or not args_match:
observation = f"错误:无法解析 Action '{action_str}'"
else:
tool_name = tool_match.group(1)
kwargs = dict(re.findall(r'(\w+)="([^"]*)"', args_match.group(1)))
if tool_name not in TOOLS:
observation = f"错误:未定义的工具 '{tool_name}'"
else:
print(f"调用工具: {tool_name}({kwargs})")
called_tools.add(tool_name)
observation = TOOLS[tool_name](**kwargs)
print(f"Observation: {observation}\n" + "=" * 40)
history.append(f"Observation: {observation}")
if __name__ == "__main__":
run_agent()

Workflow / Agent 差异
智能体分类如下:
- 单智能体自主循环:这是早期的典型范式,如 AgentGPT 所代表的模式。其核心是一个通用智能体通过“思考-规划-执行-反思”的闭环,不断进行自我提示和迭代,以完成一个开放式的高层级目标。
- 多智能体协作:这是当前最主流的探索方向,旨在通过模拟人类团队的协作模式来解决复杂问题。它又可细分为不同模式: 角色扮演式对话:如 CAMEL 框架,通过为两个智能体(例如,“程序员”和“产品经理”)设定明确的角色和沟通协议,让它们在一个结构化的对话中协同完成任务。 组织化工作流:如 MetaGPT 和 CrewAI,它们模拟一个分工明确的“虚拟团队”(如软件公司或咨询小组)。每个智能体都有预设的职责和工作流程(SOP),通过层级化或顺序化的方式协作,产出高质量的复杂成果(如完整的代码库或研究报告)。AutoGen 和 AgentScope 则提供了更灵活的对话模式,允许开发者自定义智能体间的复杂交互网络。
- 高级控制流架构:诸如 LangGraph 等框架,则更侧重于为智能体提供更强大的底层工程基础。它将智能体的执行过程建模为状态图(State Graph),从而能更灵活、更可靠地实现循环、分支、回溯以及人工介入等复杂流程
Workflow 是让 AI 按部就班地执行指令,而 Agent 则是赋予 AI 自由度去自主达成目标。

智能体经典构建

在构建前, 提前准备部分工具函数
LLM_MODEL_ID="YOUR-MODEL"
LLM_API_KEY="YOUR-API-KEY"
LLM_BASE_URL="YOUR-URL"
SERPAPI_API_KEY="YOUR_SERPAPI_API_KEY"
# llm_client
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]):
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("✅ 大语言模型响应成功:")
collected_content = []
for chunk in response:
if not chunk.choices:
continue
content = chunk.choices[0].delta.content or ""
print(content, end="", flush=True)
collected_content.append(content)
print() # 在流式输出结束后换行
return "".join(collected_content)
except Exception as e:
print(f"❌ 调用LLM API时发生错误: {e}")
return None
# --- 客户端使用示例 ---
if __name__ == '__main__':
try:
llmClient = HelloAgentsLLM()
exampleMessages = [
{"role": "system", "content": "You are a helpful assistant that writes Python code."},
{"role": "user", "content": "写一个快速排序算法"}
]
print("--- 调用LLM ---")
responseText = llmClient.think(exampleMessages)
if responseText:
print("\n\n--- 完整模型响应 ---")
print(responseText)
except ValueError as e:
print(e)
# tools.py
from dotenv import load_dotenv
# 加载 .env 文件中的环境变量
load_dotenv()
import os
from serpapi import SerpApiClient
from typing import Dict, Any
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:
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"]:
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 registerTool(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 getTool(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()
])
# --- 工具初始化与使用示例 ---
if __name__ == '__main__':
# 1. 初始化工具执行器
toolExecutor = ToolExecutor()
# 2. 注册我们的实战搜索工具
search_description = "一个网页搜索引擎。当你需要回答关于时事、事实以及在你的知识库中找不到的信息时,应使用此工具。"
toolExecutor.registerTool("Search", search_description, search)
# 3. 打印可用的工具
print("\n--- 可用的工具 ---")
print(toolExecutor.getAvailableTools())
# 4. 智能体的Action调用,这次我们问一个实时性的问题
print("\n--- 执行 Action: Search['英伟达最新的GPU型号是什么'] ---")
tool_name = "Search"
tool_input = "英伟达最新的GPU型号是什么"
tool_function = toolExecutor.getTool(tool_name)
if tool_function:
observation = tool_function(tool_input)
print("--- 观察 (Observation) ---")
print(observation)
else:
print(f"错误:未找到名为 '{tool_name}' 的工具。")
ReAct
- Thought (思考): 这是智能体的“内心独白”。它会分析当前情况、分解任务、制定下一步计划,或者反思上一步的结果。
- Action (行动): 这是智能体决定采取的具体动作,通常是调用一个外部工具,例如
Search['华为最新款手机']。 - Observation (观察): 这是执行
Action后从外部工具返回的结果,例如搜索结果的摘要或API的返回值。

import re
from llm_client import HelloAgentsLLM
from tools import ToolExecutor, search
# (此处省略 REACT_PROMPT_TEMPLATE 的定义)
REACT_PROMPT_TEMPLATE = """
请注意,你是一个有能力调用外部工具的智能助手。
可用工具如下:
{tools}
请严格按照以下格式进行回应:
Thought: 你的思考过程,用于分析问题、拆解任务和规划下一步行动。
Action: 你决定采取的行动,必须是以下格式之一:
- `{{tool_name}}[{{tool_input}}]`:调用一个可用工具。
- `Finish[最终答案]`:当你认为已经获得最终答案时。
- 当你收集到足够的信息,能够回答用户的最终问题时,你必须在`Action:`字段后使用 `Finish[最终答案]` 来输出最终答案。
现在,请开始解决以下问题:
Question: {question}
History: {history}
"""
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 = []
def run(self, question: str):
self.history = []
current_step = 0
while current_step < self.max_steps:
current_step += 1
print(f"\n--- 第 {current_step} 步 ---")
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)
messages = [{"role": "user", "content": prompt}]
response_text = self.llm_client.think(messages=messages)
if not response_text:
print("错误:LLM未能返回有效响应。"); break
thought, action = self._parse_output(response_text)
if thought: print(f"🤔 思考: {thought}")
if not action: print("警告:未能解析出有效的Action,流程终止。"); break
if action.startswith("Finish"):
# 如果是Finish指令,提取最终答案并结束
final_answer = self._parse_action_input(action)
print(f"🎉 最终答案: {final_answer}")
return final_answer
tool_name, tool_input = self._parse_action(action)
if not tool_name or not tool_input:
self.history.append("Observation: 无效的Action格式,请检查。"); continue
print(f"🎬 行动: {tool_name}[{tool_input}]")
tool_function = self.tool_executor.getTool(tool_name)
observation = tool_function(tool_input) if tool_function else f"错误:未找到名为 '{tool_name}' 的工具。"
print(f"👀 观察: {observation}")
self.history.append(f"Action: {action}")
self.history.append(f"Observation: {observation}")
print("已达到最大步数,流程终止。")
return None
def _parse_output(self, text: str):
# Thought: 匹配到 Action: 或文本末尾
thought_match = re.search(r"Thought:\s*(.*?)(?=\nAction:|$)", text, re.DOTALL)
# Action: 匹配到文本末尾
action_match = re.search(r"Action:\s*(.*?)$", text, re.DOTALL)
thought = thought_match.group(1).strip() if thought_match else None
action = action_match.group(1).strip() if action_match else None
return thought, action
def _parse_action(self, action_text: str):
match = re.match(r"(\w+)\[(.*)\]", action_text, re.DOTALL)
return (match.group(1), match.group(2)) if match else (None, None)
def _parse_action_input(self, action_text: str):
match = re.match(r"\w+\[(.*)\]", action_text, re.DOTALL)
return match.group(1) if match else ""
if __name__ == '__main__':
llm = HelloAgentsLLM()
tool_executor = ToolExecutor()
search_desc = "一个网页搜索引擎。当你需要回答关于时事、事实以及在你的知识库中找不到的信息时,应使用此工具。"
tool_executor.registerTool("Search", search_desc, search)
agent = ReActAgent(llm_client=llm, tool_executor=tool_executor)
question = "小米手机最新款是什么?, 当前时间为2026年6月2日 10:00:00"
agent.run(question)
运行结果如下
工具 'Search' 已注册。
--- 第 1 步 ---
🧠 正在调用 deepseek-v4-pro 模型...
✅ 大语言模型响应成功:
Thought: 用户想知道截至2026年6月2日小米手机的最新款。我需要搜索最新的信息。
Action: Search[小米手机 最新款 2026]
Thought: 用户想知道截至2026年6月2日小米手机的最新款。我需要搜索最新的信息。
Action: Search[小米手机 最新款 2026]
调用工具: Search(小米手机 最新款 2026)
🔍 正在执行 [SerpApi] 网页搜索: 小米手机 最新款 2026
--- 观察 (Observation) ---
[1] Xiaomi 17
Xiaomi 17,6.3″质感小尺寸,观感手感皆焕新;搭载第五代骁龙8 至尊版移动平台和7000mAh小米金沙江电池,性能电量双跃升;更有徕卡光学Summilux 高速镜头,纯净光影, ...
[2] 2026年618小米红米手机各系列介绍及选购指南( ...
红米Turbo5 Max相比标准版和上一代Pro主要升级了处理器、超声波指纹和电池容量。价格差不多。因此目前更推荐Max款。Max的机身尺寸较大,喜欢大屏可以考虑,建议线下试试手感 ...
[3] 小米智慧手機、旗艦機、最新型號推薦
POCO X8 Pro · Xiaomi 17T · Xiaomi 17T Pro · POCO M8s 5G · REDMI 15C · Xiaomi 14T Pro · REDMI Note 15 5G · REDMI Note 14 Pro+ 5G.
--- 第 2 步 ---
🧠 正在调用 deepseek-v4-pro 模型...
✅ 大语言模型响应成功:
Thought: 用户询问当前时间(2026年6月2日)小米手机的最新款。提供的搜索结果中,第一条就是“Xiaomi 17”,并介绍了其特性,这明显是2026年的最新旗舰。因此,小米手机最新款是小米17系列,可能包括小米17、小米17 Pro等,但最直接的答案是“小米17”。我将以此作为最终答案。
Action: Finish[截至2026年6月2日,小米手机最新款是 **Xiaomi 17(小米17)**。该机型搭载第五代骁龙8至尊版移动平台和7000mAh电池,配备徕卡光学Summilux高速镜头等。]
Thought: 用户询问当前时间(2026年6月2日)小米手机的最新款。提供的搜索结果中,第一条就是“Xiaomi 17”,并介绍了其特性,这明显是2026年的最新旗舰。因此,小米手机最新款是小米17系列,可能包括小米17、小米17 Pro等,但最直接的答案是“小米17”。我将以此作为最终答案。
Action: Finish[截至2026年6月2日,小米手机最新款是 **Xiaomi 17(小米17)**。该机型搭载第五代骁龙8至尊版移动平台和7000mAh电池,配备徕卡光学Summilux高速镜头等。]
最终答案: 截至2026年6月2日,小米手机最新款是 **Xiaomi 17(小米17)**。该机型搭载第五代骁龙8至尊版移动平台和7000mAh电池,配备徕卡光学Summilux高速镜头等。
(1)ReAct 的主要特点
- 高可解释性:ReAct 最大的优点之一就是透明。通过
Thought链,我们可以清晰地看到智能体每一步的“心路历程”——它为什么会选择这个工具,下一步又打算做什么。这对于理解、信任和调试智能体的行为至关重要。 - 动态规划与纠错能力:与一次性生成完整计划的范式不同,ReAct 是“走一步,看一步”。它根据每一步从外部世界获得的
Observation来动态调整后续的Thought和Action。如果上一步的搜索结果不理想,它可以在下一步中修正搜索词,重新尝试。 - 工具协同能力:ReAct 范式天然地将大语言模型的推理能力与外部工具的执行能力结合起来。LLM 负责运筹帷幄(规划和推理),工具负责解决具体问题(搜索、计算),二者协同工作,突破了单一 LLM 在知识时效性、计算准确性等方面的固有局限。
(2)ReAct 的固有局限性
- 对LLM自身能力的强依赖:ReAct 流程的成功与否,高度依赖于底层 LLM 的综合能力。如果 LLM 的逻辑推理能力、指令遵循能力或格式化输出能力不足,就很容易在
Thought环节产生错误的规划,或者在Action环节生成不符合格式的指令,导致整个流程中断。 - 执行效率问题:由于其循序渐进的特性,完成一个任务通常需要多次调用 LLM。每一次调用都伴随着网络延迟和计算成本。对于需要很多步骤的复杂任务,这种串行的“思考-行动”循环可能会导致较高的总耗时和费用。
- 提示词的脆弱性:整个机制的稳定运行建立在一个精心设计的提示词模板之上。模板中的任何微小变动,甚至是用词的差异,都可能影响 LLM 的行为。此外,并非所有模型都能持续稳定地遵循预设的格式,这增加了在实际应用中的不确定性。
- 可能陷入局部最优:步进式的决策模式意味着智能体缺乏一个全局的、长远的规划。它可能会因为眼前的
Observation而选择一个看似正确但长远来看并非最优的路径,甚至在某些情况下陷入“原地打转”的循环中。
(3)调试技巧
当你构建的 ReAct 智能体行为不符合预期时,可以从以下几个方面入手进行调试:
- 检查完整的提示词:在每次调用 LLM 之前,将最终格式化好的、包含所有历史记录的完整提示词打印出来。这是追溯 LLM 决策源头的最直接方式。
- 分析原始输出:当输出解析失败时(例如,正则表达式没有匹配到
Action),务必将 LLM 返回的原始、未经处理的文本打印出来。这能帮助你判断是 LLM 没有遵循格式,还是你的解析逻辑有误。 - 验证工具的输入与输出:检查智能体生成的
tool_input是否是工具函数所期望的格式,同时也要确保工具返回的observation格式是智能体可以理解和处理的。 - 调整提示词中的示例 (Few-shot Prompting):如果模型频繁出错,可以在提示词中加入一两个完整的“Thought-Action-Observation”成功案例,通过示例来引导模型更好地遵循你的指令。
- 尝试不同的模型或参数:更换一个能力更强的模型,或者调整
temperature参数(通常设为0以保证输出的确定性),有时能直接解决问题。
Plan-and-Solve
Plan-and-Solve 将整个流程解耦为两个核心阶段
- 规划阶段 (Planning Phase): 首先,智能体会接收用户的完整问题。它的第一个任务不是直接去解决问题或调用工具,而是将问题分解,并制定出一个清晰、分步骤的行动计划。这个计划本身就是一次大语言模型的调用产物。
- 执行阶段 (Solving Phase): 在获得完整的计划后,智能体进入执行阶段。它会严格按照计划中的步骤,逐一执行。每一步的执行都可能是一次独立的 LLM 调用,或者是对上一步结果的加工处理,直到计划中的所有步骤都完成,最终得出答案。

an-and-Solve 尤其适用于那些结构性强、可以被清晰分解的复杂任务,例如:
- 多步数学应用题:需要先列出计算步骤,再逐一求解。
- 需要整合多个信息源的报告撰写:需要先规划好报告结构(引言、数据来源A、数据来源B、总结),再逐一填充内容。
- 代码生成任务:需要先构思好函数、类和模块的结构,再逐一实现。
import os
import ast
from llm_client import HelloAgentsLLM
from dotenv import load_dotenv
from typing import List, Dict
# 加载 .env 文件中的环境变量,处理文件不存在异常
try:
load_dotenv()
except FileNotFoundError:
print("警告:未找到 .env 文件,将使用系统环境变量。")
except Exception as e:
print(f"警告:加载 .env 文件时出错: {e}")
# --- 1. LLM客户端定义 ---
# 假设你已经有llm_client.py文件,里面定义了HelloAgentsLLM类
# --- 2. 规划器 (Planner) 定义 ---
PLANNER_PROMPT_TEMPLATE = """
你是一个顶级的AI规划专家。你的任务是将用户提出的复杂问题分解成一个由多个简单步骤组成的行动计划。
请确保计划中的每个步骤都是一个独立的、可执行的子任务,并且严格按照逻辑顺序排列。
你的输出必须是一个Python列表,其中每个元素都是一个描述子任务的字符串。
问题: {question}
请严格按照以下格式输出你的计划,```python与```作为前后缀是必要的:
```python
["步骤1", "步骤2", "步骤3", ...]
"""
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}")
try:
plan_str = response_text.split("```python")[1].split("```")[0].strip()
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}")
return []
# --- 3. 执行器 (Executor) 定义 ---
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 = ""
final_answer = ""
print("\n--- 正在执行计划 ---")
for i, step in enumerate(plan, 1):
print(f"\n-> 正在执行步骤 {i}/{len(plan)}: {step}")
prompt = EXECUTOR_PROMPT_TEMPLATE.format(
question=question, plan=plan, history=history if history else "无", current_step=step
)
messages = [{"role": "user", "content": prompt}]
response_text = self.llm_client.think(messages=messages) or ""
history += f"步骤 {i}: {step}\n结果: {response_text}\n\n"
final_answer = response_text
print(f"✅ 步骤 {i} 已完成,结果: {final_answer}")
return final_answer
# --- 4. 智能体 (Agent) 整合 ---
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}")
plan = self.planner.plan(question)
if not plan:
print("\n--- 任务终止 --- \n无法生成有效的行动计划。")
return
final_answer = self.executor.execute(question, plan)
print(f"\n--- 任务完成 ---\n最终答案: {final_answer}")
# --- 5. 主函数入口 ---
if __name__ == '__main__':
try:
llm_client = HelloAgentsLLM()
agent = PlanAndSolveAgent(llm_client)
question = "一个水果店周一卖出了15个苹果。周二卖出的苹果数量是周一的两倍。周三卖出的数量比周二少了5个。请问这三天总共卖出了多少个苹果?"
agent.run(question)
except ValueError as e:
print(e)
--- 开始处理问题 ---
问题: 一个水果店周一卖出了15个苹果。周二卖出的苹果数量是周一的两倍。周三卖出的数量比周二少了5个。请问这三天总共卖出了多少个苹果?
--- 正在生成计划 ---
🧠 正在调用 deepseek-v4-pro 模型...
✅ 大语言模型响应成功:
```python
["确定周一卖出的苹果数量:15个",
"计算周二卖出的数量:周一数量乘以2",
"计算周三卖出的数量:周二数量减去5",
"将三天卖出的数量相加得到总和"]
✅ 计划已生成:
["确定周一卖出的苹果数量:15个",
"计算周二卖出的数量:周一数量乘以2",
"计算周三卖出的数量:周二数量减去5",
"将三天卖出的数量相加得到总和"]
--- 正在执行计划 ---
-> 正在执行步骤 1/4: 确定周一卖出的苹果数量:15个
🧠 正在调用 deepseek-v4-pro 模型...
✅ 大语言模型响应成功:
15个
✅ 步骤 1 已完成,结果: 15个
-> 正在执行步骤 2/4: 计算周二卖出的数量:周一数量乘以2
🧠 正在调用 deepseek-v4-pro 模型...
✅ 大语言模型响应成功:
30个
✅ 步骤 2 已完成,结果: 30个
-> 正在执行步骤 3/4: 计算周三卖出的数量:周二数量减去5
🧠 正在调用 deepseek-v4-pro 模型...
✅ 大语言模型响应成功:
25个
✅ 步骤 3 已完成,结果: 25个
-> 正在执行步骤 4/4: 将三天卖出的数量相加得到总和
🧠 正在调用 deepseek-v4-pro 模型...
✅ 大语言模型响应成功:
70
✅ 步骤 4 已完成,结果: 70
--- 任务完成 ---
最终答案: 70
[Reflection]( https://hello-agents.datawhale.cc/#/./chapter4/第四章 智能体经典范式构建?id=_44-reflection)
在我们已经实现的 ReAct 和 Plan-and-Solve 范式中,智能体一旦完成了任务,其工作流程便告结束。然而,它们生成的初始答案,无论是行动轨迹还是最终结果,都可能存在谬误或有待改进之处。Reflection 机制的核心思想,正是为智能体引入一种事后(post-hoc)的自我校正循环,使其能够像人类一样,审视自己的工作,发现不足,并进行迭代优化。
其核心工作流程可以概括为一个简洁的三步循环:执行 -> 反思 -> 优化。
- 执行 (Execution):首先,智能体使用我们熟悉的方法(如 ReAct 或 Plan-and-Solve)尝试完成任务,生成一个初步的解决方案或行动轨迹。这可以看作是“初稿”。
- 反思 (Reflection):接着,智能体进入反思阶段。它会调用一个独立的、或者带有特殊提示词的大语言模型实例,来扮演一个“评审员”的角色。这个“评审员”会审视第一步生成的“初稿”,并从多个维度进行评估,例如:
- 事实性错误:是否存在与常识或已知事实相悖的内容?
- 逻辑漏洞:推理过程是否存在不连贯或矛盾之处?
- 效率问题:是否有更直接、更简洁的路径来完成任务?
- 遗漏信息:是否忽略了问题的某些关键约束或方面? 根据评估,它会生成一段结构化的反馈 (Feedback),指出具体的问题所在和改进建议。
- 优化 (Refinement):最后,智能体将“初稿”和“反馈”作为新的上下文,再次调用大语言模型,要求它根据反馈内容对初稿进行修正,生成一个更完善的“修订稿”。

from typing import List, Dict, Any
from HelloAgentsLLM import HelloAgentsLLM
# --- 模块 1: 记忆模块 ---
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): 记录的具体内容 (例如,生成的代码或反思的反馈)。
"""
self.records.append({"type": record_type, "content": content})
print(f"📝 记忆已更新,新增一条 '{record_type}' 记录。")
def get_trajectory(self) -> str:
"""
将所有记忆记录格式化为一个连贯的字符串文本,用于构建提示词。
"""
trajectory = ""
for record in self.records:
if record['type'] == 'execution':
trajectory += f"--- 上一轮尝试 (代码) ---\n{record['content']}\n\n"
elif record['type'] == 'reflection':
trajectory += f"--- 评审员反馈 ---\n{record['content']}\n\n"
return trajectory.strip()
def get_last_execution(self) -> str|None:
"""
获取最近一次的执行结果 (例如,最新生成的代码)。
"""
for record in reversed(self.records):
if record['type'] == 'execution':
return record['content']
return None
# --- 模块 2: Reflection 智能体 ---
# 1. 初始执行提示词
INITIAL_PROMPT_TEMPLATE = """
你是一位资深的Python程序员。请根据以下要求,编写一个Python函数。
你的代码必须包含完整的函数签名、文档字符串,并遵循PEP 8编码规范。
要求: {task}
请直接输出代码,不要包含任何额外的解释。
"""
# 2. 反思提示词
REFLECT_PROMPT_TEMPLATE = """
你是一位极其严格的代码评审专家和资深算法工程师,对代码的性能有极致的要求。
你的任务是审查以下Python代码,并专注于找出其在**算法效率**上的主要瓶颈。
# 原始任务:
{task}
# 待审查的代码:
```python
{code}
```
请分析该代码的时间复杂度,并思考是否存在一种**算法上更优**的解决方案来显著提升性能。
如果存在,请清晰地指出当前算法的不足,并提出具体的、可行的改进算法建议(例如,使用筛法替代试除法)。
如果代码在算法层面已经达到最优,才能回答“无需改进”。
请直接输出你的反馈,不要包含任何额外的解释。
"""
# 3. 优化提示词
REFINE_PROMPT_TEMPLATE = """
你是一位资深的Python程序员。你正在根据一位代码评审专家的反馈来优化你的代码。
# 原始任务:
{task}
# 你上一轮尝试的代码:
{last_code_attempt}
# 评审员的反馈:
{feedback}
请根据评审员的反馈,生成一个优化后的新版本代码。
你的代码必须包含完整的函数签名、文档字符串,并遵循PEP 8编码规范。
请直接输出优化后的代码,不要包含任何额外的解释。
"""
class ReflectionAgent:
def __init__(self, llm_client, max_iterations=3):
self.llm_client = llm_client
self.memory = Memory()
self.max_iterations = max_iterations
def run(self, task: str):
print(f"\n--- 开始处理任务 ---\n任务: {task}")
# --- 1. 初始执行 ---
print("\n--- 正在进行初始尝试 ---")
initial_prompt = INITIAL_PROMPT_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 or "no need for improvement" in feedback.lower():
print("\n✅ 反思认为代码已无需改进,任务完成。")
break
# c. 优化
print("\n-> 正在进行优化...")
refine_prompt = REFINE_PROMPT_TEMPLATE.format(
task=task,
last_code_attempt=last_code,
feedback=feedback
)
refined_code = self._get_llm_response(refine_prompt)
self.memory.add_record("execution", refined_code)
final_code = self.memory.get_last_execution()
print(f"\n--- 任务完成 ---\n最终生成的代码:\n{final_code}")
return final_code
def _get_llm_response(self, prompt: str) -> str:
"""一个辅助方法,用于调用LLM并获取完整的流式响应。"""
messages = [{"role": "user", "content": prompt}]
# 确保能处理生成器可能返回None的情况
response_text = self.llm_client.think(messages=messages) or ""
return response_text
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)
--- 开始处理任务 ---
任务: 编写一个Python函数,找出1到n之间所有的素数 (prime numbers)。
--- 正在进行初始尝试 ---
🧠 正在调用 xxxxxx 模型...
✅ 大语言模型响应成功:
```python
def find_primes(n):
...
return primes
```
📝 记忆已更新,新增一条 'execution' 记录。
--- 第 1/2 轮迭代 ---
-> 正在进行反思...
🧠 正在调用 xxxxxx 模型...
✅ 大语言模型响应成功:
当前代码的时间复杂度为O(n * sqrt(n))。虽然对于较小的n值,这种实现是可以接受的,但当n非常大时,性能会显著下降。主要瓶颈在于每个数都需要进行试除法检查,这导致了较高的时间开销。
建议使用埃拉托斯特尼筛法(Sieve of Eratosthenes),该算法的时间复杂度为O(n log(log n)),能够显著提高查找素数的效率。
改进后的代码如下:
```python
def find_primes(n):
...
return primes
```
📝 记忆已更新,新增一条 'reflection' 记录。
-> 正在进行优化...
🧠 正在调用 xxxxxx 模型...
✅ 大语言模型响应成功:
```python
def find_primes(n):
...
return primes
```
📝 记忆已更新,新增一条 'execution' 记录。
--- 第 2/2 轮迭代 ---
-> 正在进行反思...
🧠 正在调用 xxxxxx 模型...
✅ 大语言模型响应成功:
当前代码使用了Eratosthenes筛法,时间复杂度为O(n log log n),空间复杂度为O(n)。此算法在寻找1到n之间的所有素数时已经非常高效,通常情况下无需进一步优化。但在某些特定场景下,可以考虑以下改进:
1. <strong>分段筛法(Segmented Sieve)</strong>:适用于n非常大但内存有限的情况。将区间分成多个小段,每段分别用筛法处理,减少内存使用。
2. <strong>奇数筛法(Odd Number Sieve)</strong>:除了2以外,所有素数都是奇数。可以在初始化`is_prime`数组时只标记奇数,这样可以将空间复杂度降低一半,同时减少一些不必要的计算。
然而,这些改进对于大多数应用场景来说并不是必需的,因为标准的Eratosthenes筛法已经足够高效。因此,在一般情况下,<strong>无需改进</strong>。
📝 记忆已更新,新增一条 'reflection' 记录。
✅ 反思认为代码已无需改进,任务完成。
--- 任务完成 ---
最终生成的代码:
```python
def find_primes(n):
"""
Finds all prime numbers between 1 and n using the Sieve of Eratosthenes algorithm.
:param n: The upper limit of the range to find prime numbers.
:return: A list of all prime numbers between 1 and n.
"""
if n < 2:
return []
is_prime = [True] * (n + 1)
is_prime[0] = is_prime[1] = False
p = 2
while p * p <= n:
if is_prime[p]:
for i in range(p * p, n + 1, p):
is_prime[i] = False
p += 1
primes = [num for num in range(2, n + 1) if is_prime[num]]
return primes
```
- 有效的“批判”是优化的前提:在第一轮反思中,由于我们使用了“极其严格”且“专注于算法效率”的提示词,智能体没有满足于功能正确的初版代码,而是精准地指出了其
O(n * sqrt(n))的时间复杂度瓶颈,并提出了算法层面的改进建议——埃拉托斯特尼筛法。 - 迭代式改进: 智能体在接收到明确的反馈后,于优化阶段成功地实现了更高效的筛法,将算法复杂度降至
O(n log log n),完成了第一次有意义的自我迭代。 - 收敛与终止: 在第二轮反思中,智能体面对已经高效的筛法,展现出了更深层次的知识。它不仅肯定了当前算法的效率,甚至还提及了分段筛法等更高级的优化方向,但最终做出了“在一般情况下无需改进”的正确判断。这个判断触发了我们的终止条件,使优化过程得以收敛。
尽管 Reflection 机制在提升任务解决质量上表现出色,但这种能力的获得并非没有代价。在实际应用中,我们需要权衡其带来的收益与相应的成本。
(1)主要成本
- 模型调用开销增加:这是最直接的成本。每进行一轮迭代,至少需要额外调用两次大语言模型(一次用于反思,一次用于优化)。如果迭代多轮,API 调用成本和计算资源消耗将成倍增加。
- 任务延迟显著提高:Reflection 是一个串行过程,每一轮的优化都必须等待上一轮的反思完成。这使得任务的总耗时显著延长,不适合对实时性要求高的场景。
- 提示工程复杂度上升:如我们的案例所示,Reflection 的成功在很大程度上依赖于高质量、有针对性的提示词。为“执行”、“反思”、“优化”等不同阶段设计和调试有效的提示词,需要投入更多的开发精力。
(2)核心收益
- 解决方案质量的跃迁:最大的收益在于,它能将一个“合格”的初始方案,迭代优化成一个“优秀”的最终方案。这种从功能正确到性能高效、从逻辑粗糙到逻辑严谨的提升,在很多关键任务中是至关重要的。
- 鲁棒性与可靠性增强:通过内部的自我纠错循环,智能体能够发现并修复初始方案中可能存在的逻辑漏洞、事实性错误或边界情况处理不当等问题,从而大大提高了最终结果的可靠性。
综上所述,Reflection 机制是一种典型的“以成本换质量”的策略。它非常适合那些对最终结果的质量、准确性和可靠性有极高要求,且对任务完成的实时性要求相对宽松的场景。例如:
- 生成关键的业务代码或技术报告。
- 在科学研究中进行复杂的逻辑推演。
- 需要深度分析和规划的决策支持系统。
反之,如果应用场景需要快速响应,或者一个“大致正确”的答案就已经足够,那么使用更轻量的 ReAct 或 Plan-and-Solve 范式可能会是更具性价比的选择。
