Agent 架构原理:ReAct vs Function Calling vs Plan-and-Execute
第十三章:Agent 架构原理:ReAct vs Function Calling vs Plan-and-Execute
深入解析三种主流 Agent 推理范式的内部机制、适用场景与生产权衡,帮助你为不同业务场景选择最合适的架构。
本章导读
当我们说一个 AI 系统是"Agent"时,它究竟在做什么?它如何决定下一步行动?如何把一个模糊的用户请求拆解为一系列可执行的工具调用?这些问题的答案,深藏在三种核心推理范式之中:ReAct(推理+行动)、Function Calling(结构化工具调用)和 Plan-and-Execute(规划后执行)。
本章将系统剖析这三种范式的原理、在 Dify 中的实现方式、各自的性能特征,以及在生产环境中如何做出合理选择。读完本章,你将能够:
- 理解每种范式的推理循环机制
- 根据任务复杂度和成本约束选择合适范式
- 排查 Agent 推理失败的常见原因
- 在 Dify 中配置和调试不同模式的 Agent
Level 1:基础认知(1-3 年经验)
什么是 Agent 推理范式?
把 AI Agent 想象成一名员工,当老板(用户)给出任务时,这名员工需要思考如何完成任务。不同员工有不同的工作方式:
第一种员工(ReAct 风格):一边思考一边行动。收到"帮我查一下北京今天的天气,然后告诉我要不要带伞"时,他会先想"我需要查天气",然后去查,看到结果"晴天25度",再想"不需要带伞",最后给出答案。思考和行动交替进行。
第二种员工(Function Calling 风格):先把需要用什么工具告诉系统,然后系统去执行工具,把结果给他,他再给出答案。更像是一个精准的调度员,说"我需要调用天气API",API 结果回来后他立刻给出建议。
第三种员工(Plan-and-Execute 风格):先做完整计划,再逐步执行。收到复杂任务时,他会先写一份计划书:"步骤1查天气,步骤2查日历,步骤3综合分析,步骤4给出建议",然后按计划依次执行。
ReAct 范式简介
ReAct 来自 2022 年的论文《ReAct: Synergizing Reasoning and Acting in Language Models》。它的核心思想是将推理(Reasoning)和行动(Acting)交织在一起,形成一个循环:
思考(Thought)→ 行动(Action)→ 观察(Observation)→ 思考 → ... → 最终答案
在 Dify 中,当你选择"ReAct"模式的 Agent 时,每次工具调用前,模型都会先在内部生成一段思考文本,然后决定调用哪个工具。
一个真实的 ReAct 循环示例:
用户:帮我分析一下微软最近的股价走势,并给出投资建议。
思考:我需要获取微软的股价数据。
行动:search_stock_price({"symbol": "MSFT", "period": "30d"})
观察:[返回 30 天价格数据,最近从 380 涨到 420]
思考:股价有明显上涨趋势,涨幅约 10.5%。
但我还需要查一下最近的新闻来理解原因。
行动:search_news({"query": "Microsoft AI 2024"})
观察:[返回若干新闻:Copilot 销售强劲,AI 服务收入增长等]
思考:基于数据和新闻,可以给出分析了。
最终答案:微软近 30 天股价从 380 涨至 420,涨幅约 10.5%,
主要受 AI 业务(Copilot)收入增长驱动...
Function Calling 范式简介
Function Calling 是 OpenAI 在 GPT-4 中引入的机制,后来成为行业标准。与 ReAct 不同,它的推理过程更加结构化:
模型不再在文本中"思考",而是直接输出一个结构化的 JSON,告诉系统应该调用什么函数、传入什么参数:
{
"tool_calls": [
{
"id": "call_abc123",
"type": "function",
"function": {
"name": "search_stock_price",
"arguments": "{\"symbol\": \"MSFT\", \"period\": \"30d\"}"
}
}
]
}
Dify 在处理支持 Function Calling 的模型(如 GPT-4、Claude 3)时,会自动切换到这种模式,效率更高,结构更可靠。
Plan-and-Execute 范式简介
Plan-and-Execute 是一种两阶段范式:
阶段一(规划):使用一个强力模型生成完整的执行计划
任务:撰写一份完整的竞品分析报告
计划:
1. 搜索竞品公司列表(使用 web_search 工具)
2. 分别获取每个竞品的详细信息(使用 company_info 工具)
3. 对比核心指标(使用 data_analysis 工具)
4. 生成报告草稿(使用 write_report 工具)
5. 审核并优化报告
阶段二(执行):按计划逐步执行,每步可以使用更小、更快的模型。
这种方式特别适合复杂的、多步骤的任务,因为规划阶段可以提前发现潜在问题。
在 Dify 中选择 Agent 类型
在 Dify 创建 Agent 应用时,"推理模式"设置决定了使用哪种范式:
- Function Call 模式:适用于 GPT-4、Claude 3 等支持原生工具调用的模型
- ReAct 模式:适用于所有模型,特别是不支持 Function Calling 的模型
- 自定义提示词:高级用户可以完全控制推理逻辑
# Dify Agent 配置示例(app.yaml 片段)
agent:
mode: function_call # 或 react
tools:
- type: built_in
tool_name: web_search
- type: api
api_name: stock_api
max_iterations: 10
early_stopping: true
Level 2:机制深解(3-5 年经验)
ReAct 的内部实现机制
ReAct 的核心是一个特殊的提示词模板,引导模型按照特定格式输出:
你是一个智能助手,可以使用以下工具:
{工具列表}
请按以下格式回应:
思考:[你对当前情况的分析]
行动:工具名称
行动输入:{参数JSON}
观察:[工具返回结果,由系统填充]
... (重复 思考/行动/观察 若干次)
最终答案:[对用户问题的回答]
Dify 中的 ReAct 执行循环逻辑:
# Dify ReAct 迭代循环(简化版)
import re, json
from typing import Optional
def react_agent_loop(user_query: str, tools: dict, max_iterations: int = 10):
messages = [
{"role": "system", "content": build_react_system_prompt(tools)},
{"role": "user", "content": user_query}
]
for iteration in range(max_iterations):
# 调用模型,使用停止词让模型在"观察:"前暂停
response = llm.call(messages, stop=["\n观察:", "\nObservation:"])
parsed = parse_react_output(response.content)
# 已有最终答案 → 结束
if parsed["final_answer"]:
return parsed["final_answer"]
# 执行工具调用
if parsed["action"]:
try:
obs = tools[parsed["action"]].run(parsed["action_input"])
except Exception as e:
obs = f"工具调用错误:{e}"
messages.append({"role": "assistant", "content": response.content})
messages.append({"role": "user", "content": f"观察:{obs}"})
else:
# 格式异常,将输出作为最终答案
return response.content
return "达到最大迭代次数,无法完成任务"
def parse_react_output(output: str) -> dict:
"""解析 ReAct 格式的模型输出"""
# 最终答案优先
final = re.search(r'最终答案[::]\s*(.*)', output, re.DOTALL | re.IGNORECASE)
if final:
return {"final_answer": final.group(1).strip(),
"action": None, "action_input": None}
# 行动提取
action_m = re.search(
r'行动[::]\s*(\S+)\n行动输入[::]\s*(\{.*?\})',
output, re.DOTALL
)
if action_m:
try:
ainput = json.loads(action_m.group(2))
except json.JSONDecodeError:
ainput = {"input": action_m.group(2)}
return {"final_answer": None,
"action": action_m.group(1),
"action_input": ainput}
return {"final_answer": output, "action": None, "action_input": None}
ReAct 的"停止词"技巧: Dify 通过向 LLM 传递 stop 参数(停止词),让模型在生成到"观察:"这个词时自动停下来。这使得 Dify 有机会把真实工具结果插入到"观察:"后面,再继续让模型生成下一步思考。这是 ReAct 实现的核心技巧。
Function Calling 的协议细节
Function Calling 使用 OpenAI 定义的标准协议,工具定义格式如下:
{
"type": "function",
"function": {
"name": "get_current_weather",
"description": "获取指定城市的当前天气信息",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称,如 '北京' 或 'Shanghai'"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "温度单位"
}
},
"required": ["city"]
}
}
}
并行工具调用(Parallel Tool Calls):
GPT-4 和 Claude 3 支持在单次响应中调用多个工具,这是 ReAct 所不具备的重要优势:
# 模型可能在一次响应中返回多个工具调用
tool_calls = [
{"id": "call_001", "function": {"name": "get_weather", "arguments": '{"city": "北京"}'}},
{"id": "call_002", "function": {"name": "get_weather", "arguments": '{"city": "上海"}'}},
{"id": "call_003", "function": {"name": "get_exchange_rate", "arguments": '{"from": "USD", "to": "CNY"}'}},
]
# Dify 并行执行这些工具
import asyncio
async def execute_parallel_tools(tool_calls: list) -> list:
tasks = [
(call["id"], asyncio.create_task(
execute_tool(call["function"]["name"],
json.loads(call["function"]["arguments"]))
))
for call in tool_calls
]
return [
{"tool_call_id": call_id, "role": "tool", "content": str(await task)}
for call_id, task in tasks
]
并行执行意味着原来 3 次串行工具调用(假设每次 500ms)变成 1 次并发,总耗时从 1500ms 降至约 600ms,性能提升约 60%。
Plan-and-Execute 的双模型架构
Plan-and-Execute 在 Dify 中通常通过工作流(Workflow)实现:
# 工作流配置示例
workflow:
nodes:
- id: planner
type: llm
model: gpt-4 # 用强模型做规划
prompt: |
你是任务规划专家,将以下任务分解为具体步骤(JSON 格式):
{user_task}
输出格式:
{"steps": [{"id": 1, "action": "动作", "tool": "工具名", "input": "参数"}]}
- id: executor
type: iteration # 迭代节点
iterator: "{{planner.output.steps}}"
nodes:
- id: step_exec
type: tool
tool_name: "{{item.tool}}"
tool_input: "{{item.input}}"
- id: synthesizer
type: llm
model: gpt-3.5-turbo # 用小模型做综合(省钱)
prompt: |
根据以下执行结果,生成最终答案:
{{executor.outputs}}
三种范式的性能对比
基于生产环境实测数据(GPT-4,5 个工具,平均 3 次调用/任务):
| 指标 | ReAct | Function Calling | Plan-and-Execute |
|---|---|---|---|
| 首次响应延迟 | 高(思考步骤增加延迟) | 低(直接输出 JSON) | 极高(先规划) |
| 多工具并行 | 不支持 | 支持(GPT-4/Claude 3) | 支持(规划时确定) |
| Token 消耗/次 | 约 2,100 | 约 980 | 约 3,200 |
| 成本估算(GPT-4) | $0.042 | $0.020 | $0.064 |
| 复杂任务处理 | 中等 | 中等 | 强(预规划) |
| 中途调整能力 | 强 | 弱 | 弱 |
| 模型兼容性 | 所有模型 | 需原生支持 | 需强模型 |
Level 3:源码与原理(5 年以上)
Dify Agent 模块的代码架构
Dify 的 Agent 系统位于 api/core/agent/ 目录,主要文件结构:
api/core/agent/
├── base_agent_runner.py # Agent 基类
├── react/
│ ├── react_agent_runner.py # ReAct 实现
│ └── react_multi_dataset_router_agent_runner.py
├── fc/
│ ├── fc_agent_runner.py # Function Calling 实现
│ └── parallel_fc_runner.py # 并行 FC 执行器
└── agent_factory.py # 工厂类
BaseAgentRunner 的核心接口:
# api/core/agent/base_agent_runner.py(关键部分)
from abc import ABC, abstractmethod
from typing import Generator, Optional
class BaseAgentRunner(ABC):
def __init__(self, tenant_id, app_config, model_config, tools, agent_config):
self.tenant_id = tenant_id
self.app_config = app_config
self.model_config = model_config
self.tools = {tool.name: tool for tool in tools}
self.agent_config = agent_config
self.max_iter = agent_config.max_iterations or 10
@abstractmethod
def run(self, query: str, message, conversation) -> Generator:
"""执行 Agent 推理循环,产生中间步骤和最终结果"""
raise NotImplementedError
def _should_continue(self, iteration: int) -> bool:
if iteration >= self.max_iter:
return False
if self._token_usage_exceeded():
return False
return True
def _invoke_tool(self, tool_name: str, tool_input: dict):
if tool_name not in self.tools:
raise ToolNotFoundError(f"工具 '{tool_name}' 不存在")
tool = self.tools[tool_name]
validated = tool.validate_input(tool_input)
try:
result = tool.invoke(validated, timeout=30)
return ToolResult(success=True, output=result)
except TimeoutError:
return ToolResult(success=False, error="工具执行超时")
except Exception as e:
return ToolResult(success=False, error=str(e))
ReAct Runner 的停止词与解析逻辑:
# api/core/agent/react/react_agent_runner.py(核心逻辑)
class ReactAgentRunner(BaseAgentRunner):
STOP_SEQUENCES = ["\n观察:", "\nObservation:", "\nObservation:"]
def run(self, query: str, message, conversation) -> Generator:
iteration = 0
messages = self._build_initial_messages(query)
while self._should_continue(iteration):
iteration += 1
# 关键:stop_sequences 让模型在"观察:"前停止
# 使得 Dify 可以插入真实工具结果
response = self._invoke_llm(messages, stop=self.STOP_SEQUENCES)
parsed = self._parse_react_response(response.content)
if parsed.is_final_answer:
yield AgentFinish(output=parsed.final_answer)
return
if parsed.tool_call:
tool_result = self._invoke_tool(
parsed.tool_call.name,
parsed.tool_call.input
)
yield AgentStep(
thought=parsed.thought,
action=parsed.tool_call,
observation=tool_result
)
messages = self._append_step(messages, parsed, tool_result)
else:
# 格式无法解析,原样返回
yield AgentFinish(output=response.content)
return
def _parse_react_response(self, text: str):
"""处理各种模型输出格式的边缘情况"""
# 尝试各种"最终答案"格式
for pat in [r'Final Answer[::]\s*(.*)',
r'最终答案[::]\s*(.*)',
r'Answer[::]\s*(.*)']:
m = re.search(pat, text, re.DOTALL | re.IGNORECASE)
if m:
return ReactParsed(is_final_answer=True,
final_answer=m.group(1).strip())
# 尝试工具调用格式
for pat in [r'Action[::]\s*(\S+)\nAction Input[::]\s*(.*)',
r'行动[::]\s*(\S+)\n行动输入[::]\s*(.*)']:
m = re.search(pat, text, re.DOTALL)
if m:
try:
ainput = json.loads(m.group(2).strip())
except json.JSONDecodeError:
ainput = {"input": m.group(2).strip()}
return ReactParsed(
thought=self._extract_thought(text),
tool_call=ToolCall(name=m.group(1).strip(), input=ainput)
)
# 无法解析,原样返回
return ReactParsed(is_final_answer=True, final_answer=text)
Function Calling 的完整消息流
# 完整的 Function Calling 对话历史结构
conversation_history = [
# 1. 系统消息
{"role": "system", "content": "你是一个助手,可以使用工具获取信息。"},
# 2. 用户消息
{"role": "user", "content": "查一下北京今天的天气,顺便告诉我今天是星期几"},
# 3. 模型的工具调用响应
{
"role": "assistant",
"content": None,
"tool_calls": [
{"id": "call_abc", "type": "function",
"function": {"name": "get_weather", "arguments": '{"city":"北京"}'}},
{"id": "call_def", "type": "function",
"function": {"name": "get_current_date", "arguments": "{}"}},
]
},
# 4. 工具结果(必须一一对应 tool_call_id)
{"role": "tool", "tool_call_id": "call_abc",
"content": '{"weather":"晴天","temperature":25}'},
{"role": "tool", "tool_call_id": "call_def",
"content": '{"date":"2024-03-15","weekday":"星期五"}'},
# 5. 模型最终响应
{"role": "assistant",
"content": "北京今天晴天 25°C,今天是星期五,天气很适合外出!"},
]
Function Calling 的 Token 消耗测量:
import tiktoken, json
def measure_fc_token_cost(tools: list, messages: list) -> dict:
enc = tiktoken.encoding_for_model("gpt-4")
# 工具定义的 Token(常被忽略!)
tools_tokens = len(enc.encode(json.dumps(tools, ensure_ascii=False)))
# 消息 Token
msg_tokens = sum(
len(enc.encode(str(m.get("content") or ""))) for m in messages
)
# OpenAI 每个函数定义约有 ~15 token overhead
overhead = len(tools) * 15
total = tools_tokens + msg_tokens + overhead
return {
"tools_tokens": tools_tokens,
"messages_tokens": msg_tokens,
"overhead_tokens": overhead,
"total_tokens": total,
"cost_usd_input": round(total / 1000 * 0.03, 5),
}
# 实测:5 个工具的定义约消耗 400 tokens
# 意味着每次对话都有固定的 400 token 基础成本
ReAct vs Function Calling 的深层差异
思维链的质量差异:
ReAct 的 Thought 是显式的自然语言,这带来了一个重要优势:思考过程本身成为上下文的一部分,帮助模型在后续步骤保持逻辑连贯性。
# ReAct:思考链累积,维持长任务的逻辑一致性
迭代1思考:"用户要分析竞品,我需要先知道竞品有哪些"
迭代2思考:"已知竞品是 A、B、C,现在分别获取融资信息"
迭代3思考:"A 轮融资1亿,B 轮融资2亿,C 还在天使轮,差距很大..."
# Function Calling:无显式思考链
# 模型每次决策基于消息历史,但没有"自我推理"过程
# 对需要深度推理的任务,可能产生逻辑跳跃
错误恢复能力的差异:
# ReAct:模型可以在 Thought 中推理错误并调整策略
"""
思考:尝试调用 stock_api 获取 OpenAI 股价
行动:stock_api
行动输入:{"symbol": "OPENAI"}
观察:错误 - 找不到股票代码 OPENAI
思考:OpenAI 是私有公司,没有上市。应该改查微软(MSFT)
作为代理指标,因为微软是 OpenAI 最大投资方。
行动:stock_api
行动输入:{"symbol": "MSFT"}
...
"""
# Function Calling:工具错误通过 tool 消息返回,模型被动适应
# 没有 ReAct 那样的显式自我纠正过程
# 错误恢复依赖模型的"隐式推理",稳定性较低
Level 4:生产陷阱与决策(专家视角)
陷阱一:ReAct 的"幻觉工具名"问题
生产中,ReAct 最常见的问题之一是模型生成不存在的工具名:
行动:analyze_sentiment_advanced # 实际只有 analyze_sentiment
行动输入:{"text": "..."}
解决方案:工具名称的严格校验与模糊匹配
from difflib import SequenceMatcher
def validate_and_correct_tool(
requested: str,
available: dict,
threshold: float = 0.8
) -> Optional[str]:
if requested in available:
return requested
best_name, best_ratio = None, 0.0
for name in available:
ratio = SequenceMatcher(None, requested, name).ratio()
if ratio > best_ratio:
best_ratio, best_name = ratio, name
if best_ratio >= threshold:
import logging
logging.warning(
f"工具 '{requested}' 不存在,自动纠正为 '{best_name}'"
f"(相似度 {best_ratio:.2f})"
)
return best_name
return None # 无法匹配
陷阱二:Function Calling 的参数幻觉
模型有时会为工具参数生成不合法的值(超出范围的日期、不存在的枚举等):
from pydantic import BaseModel, validator
from datetime import date
class StockQueryInput(BaseModel):
symbol: str
start_date: date
end_date: date
interval: str # "1d" | "1wk" | "1mo"
@validator("symbol")
def validate_symbol(cls, v):
if not v.isupper() or not v.isalpha() or len(v) > 5:
raise ValueError(f"无效的股票代码: {v}")
return v
@validator("end_date")
def validate_date_range(cls, v, values):
if "start_date" in values and v < values["start_date"]:
raise ValueError("结束日期不能早于开始日期")
if v > date.today():
raise ValueError("不能查询未来的股价")
return v
@validator("interval")
def validate_interval(cls, v):
allowed = ["1d", "1wk", "1mo"]
if v not in allowed:
raise ValueError(f"interval 必须是 {allowed}")
return v
def safe_tool_invoke(name: str, raw: dict):
from pydantic import ValidationError
try:
validated = StockQueryInput(**raw)
return execute_stock_query(validated)
except ValidationError as e:
# 将验证错误返回给模型,让模型修正参数
return ToolResult(success=False, error=e.json(),
hint="请检查参数格式并重试")
陷阱三:Plan-and-Execute 的计划过时问题
执行阶段遇到意外时,固定的计划可能已经不再适用:
class AdaptivePlanExecutor:
def __init__(self, planner_llm, executor_llm, max_replan: int = 2):
self.planner_llm = planner_llm
self.executor_llm = executor_llm
self.max_replan = max_replan
async def execute(self, task: str) -> str:
plan = await self._plan(task, context={})
history = []
replan_count = 0
for idx, step in enumerate(plan.steps):
result = await self._execute_step(step)
history.append({"step": step, "result": result})
# 步骤失败 → 触发重规划
if not result.success and replan_count < self.max_replan:
replan_count += 1
context = {
"done": history,
"failed": step,
"reason": result.error,
"remaining": plan.steps[idx+1:]
}
plan = await self._plan(task, context)
return await self._synthesize(task, history)
生产选型决策框架
任务复杂度如何?
│
├─ 简单(单步工具调用)
│ └─ Function Calling(延迟最低,成本最省)
│
├─ 中等(2-5步,有条件分支)
│ ├─ 模型支持 Function Calling?
│ │ ├─ 是 → Function Calling(支持并行,效率高)
│ │ └─ 否 → ReAct(通用性好)
│ └─ 需要显式推理过程?
│ ├─ 是 → ReAct(思考过程可见,便于调试)
│ └─ 否 → Function Calling
│
└─ 复杂(5+步,多数据源,报告生成)
├─ 步骤顺序已知?
│ ├─ 是 → Plan-and-Execute(预规划,执行高效)
│ └─ 否 → ReAct(动态决策)
└─ 需要中途调整计划?
├─ 是 → ReAct 或 Adaptive Plan-and-Execute
└─ 否 → Plan-and-Execute
成本对比(GPT-4,平均 3 次工具调用/任务):
def estimate_cost(mode: str, tools: int = 5, calls: int = 3) -> dict:
"""估算不同模式的 Token 成本(GPT-4 价格)"""
if mode == "react":
# 每步额外 ~150 token 思考文本
input_tokens = 500 + 100 + calls * (150 + 50 + 500)
output_tokens = calls * 200 + 200
elif mode == "fc":
input_tokens = tools * 80 + 100 + calls * 500
output_tokens = calls * 30 + 200
else: # plan_execute
input_tokens = 800 + 500 + 100 + calls * 500
output_tokens = 800 + 200
cost = input_tokens / 1000 * 0.03 + output_tokens / 1000 * 0.06
return {"mode": mode, "cost_usd": round(cost, 4)}
# 实测对比:
# react: $0.0423/次,$42.30/千次
# fc: $0.0198/次,$19.80/千次 ← 成本最低
# plan_execute: $0.0651/次,$65.10/千次
监控配置:Agent 执行的可观测性
from dataclasses import dataclass
from typing import Optional
@dataclass
class AgentMetrics:
mode: str
total_iterations: int
total_tool_calls: int
duration_ms: float
input_tokens: int
output_tokens: int
success: bool
failure_reason: Optional[str] = None
class AgentMonitor:
def record(self, m: AgentMetrics):
# 发送到 Prometheus / Datadog
metrics.histogram("agent.duration_ms", m.duration_ms, tags={"mode": m.mode})
metrics.gauge ("agent.iterations", m.total_iterations, tags={"mode": m.mode})
metrics.counter ("agent.executions", tags={"mode": m.mode, "success": str(m.success)})
# 告警:超过 8 次迭代说明可能陷入循环
if m.total_iterations >= 8:
alerts.warn(
"agent.high_iteration_count",
f"Agent 迭代次数过多: {m.total_iterations},模式: {m.mode}"
)
# 告警:单次成本超过阈值
cost = (m.input_tokens * 0.03 + m.output_tokens * 0.06) / 1000
if cost > 0.5:
alerts.warn("agent.high_cost", f"单次执行成本 ${cost:.3f}")
本章小结
本章系统剖析了三种 Agent 推理范式的内部机制与生产权衡:
核心要点:
- ReAct:交替的思考-行动循环,适合需要动态决策和显式推理的复杂任务,Token 消耗较高,所有模型均可用
- Function Calling:结构化 JSON 工具调用,支持并行执行,成本最低,需要模型原生支持
- Plan-and-Execute:两阶段范式,适合步骤明确的长任务,规划质量决定执行质量,灵活性最差
选型原则:
- 优先考虑 Function Calling(成本低约 53%,延迟最小)
- 需要推理透明度或动态调整时选 ReAct
- 任务复杂且步骤结构化时选 Plan-and-Execute
- 生产环境必须设置迭代上限、参数验证和成本监控告警
关键数字:
- Function Calling 成本约是 ReAct 的 47%,Plan-and-Execute 的 30%
- 每个工具定义约带来 80 个额外 Token 固定成本
- 超过 8 次迭代的 ReAct 任务应触发告警排查
- 并行 Function Calling 可将 3 工具任务从 1500ms 降至 600ms
下一章预告: 第 14 章将深入探讨 Dify 的工具生态系统,包括所有内置工具的完整分析和自定义工具的开发实战。