目录
[一、Router & Planner-Executor & Human in the Loop的关系](#一、Router & Planner-Executor & Human in the Loop的关系)
[2.1 Plan-and-Execute 模式](#2.1 Plan-and-Execute 模式)
[2.2 Loop Executing](#2.2 Loop Executing)
[2.3 ReAct 模式](#2.3 ReAct 模式)
[三、Human in the Loop(人在环)](#三、Human in the Loop(人在环))
[3.1 人工介入方式选型](#3.1 人工介入方式选型)
一、Router & Planner-Executor & Human in the Loop的关系
一句话总结Router、Planner-Executor、Human in the Loop三者之间的关系:Router决定"谁来处理",Planner-Executor决定"怎么处理",Human in the Loop决定"处理得对不对"------三者分别是Agent系统的入口层、执行层、控制层,共同构成完整的Agent架构。
| 组件 | 核心问题 | 选型维度 |
|---|---|---|
| Router | 谁来处理? | * 路由方式:基于规则?基于LLM?基于机器学习? * 路由粒度:粗粒度(分大类)?细粒度(分到具体处理)? * 路由策略:单一路由?级联路由?备用路由? * 兜底策略:无法路由时怎么办? |
| Planner-Executor | 怎么处理? | * 执行模式:ReAct?Loop Executing?Plan-and-Execute? * 规划粒度:粗规划?细规划?动态规划? * 步骤执行:串行?并行?有依赖? * 失败处理:重试?回退?重规划? |
| Human in the Loop | 质量如何保证? | * 介入时机:每个节点?关键节点?异常时? * 介入深度:审批?确认?建议?完全人工? * 介入方式:同步?异步?批量? * 反馈机制:如何收集人工反馈? |
二、Router(路由)
| 模式 | 速度 | 成本 | 准确性 | 适用场景 | 不适用场景 |
|---|---|---|---|---|---|
| 规则路由 | ⚡⚡⚡ 快 | 💰 低 | ⭐⭐ 一般 | 意图明确、变化少 | 表达多样、新意图 |
| LLM路由 | ⚡⚡ 中 | 💰💰 中 | ⭐⭐⭐⭐ 高 | 表达多样、需要理解 | 延迟敏感、超高调用量 |
| 多级路由 | ⚡ 中 | 💰 中 | ⭐⭐⭐ 高 | 复杂业务、多层级 | 业务简单 |
| 学习型路由 | ⚡⚡ 中 | 💰💰💰 高 | ⭐⭐⭐⭐ 可优化 | 数据充足、持续优化 | 数据少、冷启动 |
二、Planner-Executor(规划-执行模式)
| 模式 | 规划方式 | 灵活性 | 开销 | 透明度 | 适用场景 |
|---|---|---|---|---|---|
| Plan-and-Execute | 一次性完整规划 | ⭐⭐ 低 | ⭐ 低 | ⭐ 低 | 任务固定、步骤明确、性能要求高 |
| Loop Executing | 先粗规划+循环调整 | ⭐⭐⭐⭐ 高 | ⭐⭐⭐⭐ 高 | ⭐⭐⭐ 中 | 任务复杂、环境变化、容错要求高 |
| ReAct | 无规划,边做边想 | ⭐⭐⭐ 中 | ⭐⭐⭐ 中 | ⭐⭐⭐⭐⭐ 高 | 需要透明度、调试友好、推理过程 |
| Mixed Initiative | 用户参与规划 | ⭐⭐⭐⭐⭐ 高 | ⭐⭐⭐⭐⭐ 高 | ⭐⭐⭐⭐⭐ 高 | 用户需控制、高价值决策 |
2.1 Plan-and-Execute 模式
- 核心流程:一次性生成完整计划,执行过程中不修改计划;
- 代码示例:
python
class PlanAndExecute:
"""
Plan-and-Execute: 先规划,后执行
特点:规划阶段一次性产出完整计划,执行阶段按计划执行
"""
def __init__(self, llm, tools):
self.llm = llm
self.tools = tools
def run(self, task):
# Phase 1: 规划阶段
plan = self.create_plan(task)
# Phase 2: 执行阶段
results = []
for step in plan.steps:
result = self.execute_step(step)
results.append({"step": step.name, "result": result})
# 检查是否需要终止(计划明确时通常不终止)
if step.is_final and result.success:
break
# Phase 3: 整合结果
return self.integrate_results(results, plan.goal)
def create_plan(self, task):
"""一次性生成完整计划"""
prompt = f"""
任务目标:{task}
请将任务分解为具体的执行步骤。
每个步骤应该:
1. 有明确的输入输出
2. 可独立执行
3. 有清晰的完成标准
输出格式:
步骤1: [描述]
步骤2: [描述]
...
计划应该覆盖从开始到最终结果的完整路径。
"""
response = self.llm.invoke(prompt)
return Plan.parse(response)
def execute_step(self, step):
"""按计划执行单个步骤"""
# 找到对应工具
tool = self.find_tool(step.required_tool)
# 准备输入(可能包含前序步骤的结果)
input_data = self.prepare_input(step, step.context)
# 执行
result = tool.execute(input_data)
return result
2.2 Loop Executing
- 核心流程:先做粗粒度规划,每执行一步则重新评估,调整规划;
- 示例代码:
python
class LoopExecuting:
"""
Loop Executing: 计划-执行-评估-调整 循环
特点:每步执行后评估,根据结果动态调整计划
"""
def __init__(self, planner, executor, max_loops=10):
self.planner = planner
self.executor = executor
self.max_loops = max_loops
def run(self, task):
# Phase 1: 初始规划
current_plan = self.planner.create_plan(task)
context = {} # 共享上下文,存储中间结果
for loop in range(self.max_loops):
# Phase 2: 检查计划是否完成
if current_plan.is_complete():
return current_plan.final_result
# Phase 3: 获取当前步骤
current_step = current_plan.get_next_step()
# Phase 4: 执行
result = self.executor.execute(current_step, context)
# Phase 5: 评估结果
evaluation = self.planner.evaluate_result(
step=current_step,
result=result,
goal=task,
context=context
)
# Phase 6: 根据评估结果调整
if evaluation.status == "success":
# 成功:更新上下文,标记步骤完成
context[current_step.name] = result
current_plan.mark_complete(current_step)
elif evaluation.status == "failed":
# 失败:尝试替代方案或重新规划
alternatives = current_plan.get_alternatives(current_step)
if alternatives:
# 有替代方案:使用替代
current_plan.replace_step(current_step, alternatives[0])
else:
# 无替代方案:需要重新规划
if loop < self.max_loops - 1:
current_plan = self.planner.replan(
task,
current_plan,
failed_step=current_step,
error=result.error
)
else:
raise MaxLoopsExceededError(f"After {self.max_loops} loops")
elif evaluation.status == "needs_adjustment":
# 需要调整:对计划做局部修改
current_plan.adjust(current_step, evaluation.adjustments)
elif evaluation.status == "goal_changed":
# 目标变化:重新规划
current_plan = self.planner.replan(
task,
current_plan,
new_goal=evaluation.new_goal
)
raise MaxLoopsExceededError()
2.3 ReAct 模式
- 核心流程:基于现状,思考下一步,执行后再思考下一步;
- 示例代码:
python
class ReActAgent:
"""
ReAct: Reasoning + Acting
核心:交替进行推理和行动,Thought驱动Action
"""
def __init__(self, llm, tools, max_steps=15):
self.llm = llm
self.tools = tools
self.max_steps = max_steps
self.history = [] # 存储 (thought, action, observation)
def run(self, task):
observation = "" # 初始观察为空
for step in range(self.max_steps):
# Step 1: Thought - 分析现状,思考下一步
thought = self.reason(task, self.history, observation)
# 记录思考
self.history.append({"thought": thought})
# Step 2: Action - 决定行动
action = self.decide_action(thought, task)
# 结束检查
if action["type"] == "finish":
return action["result"]
# Step 3: Execute - 执行行动
if action["type"] == "tool":
result = self.execute_tool(action["name"], action["input"])
elif action["type"] == "search":
result = self.execute_search(action["query"])
elif action["type"] == "calculate":
result = self.execute_calculation(action["expression"])
else:
result = self.execute_direct(action)
# Step 4: Observation - 观察结果
observation = self.observe_result(result, action)
# 记录到历史
self.history[-1]["action"] = action
self.history[-1]["observation"] = observation
# 循环检测
if self.detect_loop(self.history):
raise LoopDetectedError()
# 进度检查
if step == self.max_steps - 1:
raise MaxStepsExceededError()
raise MaxStepsExceededError()
def reason(self, task, history, observation):
"""Thought阶段:推理分析"""
history_text = self.format_history(history)
prompt = f"""
当前任务:{task}
历史操作:
{history_text}
上一步结果:{observation}
请分析:
1. 当前任务进展到哪里了?
2. 上一步结果说明什么?
3. 下一步应该做什么?
你的思考应该清晰、有逻辑,能够指导下一步行动。
"""
return self.llm.invoke(prompt)
def decide_action(self, thought, task):
"""Action阶段:决定行动"""
tools_desc = "\n".join([f"- {name}: {t.desc}" for name, t in self.tools.items()])
prompt = f"""
思考结论:{thought}
任务:{task}
可用工具:
{tools_desc}
基于思考结论,决定下一步行动。
如果任务已经完成,返回finish。
如果有明确行动需要执行,返回tool调用。
如果需要更多信息,返回search或calculate。
返回格式(JSON):
{{
"type": "tool|finish|search|calculate",
"name": "tool_name if tool",
"input": "tool input if tool",
"query": "search query if search",
"expression": "expression if calculate",
"result": "final result if finish",
"reason": "为什么做这个选择"
}}
"""
return self.llm.invoke(prompt, format="json")
def execute_tool(self, tool_name, tool_input):
"""执行工具"""
tool = self.tools.get(tool_name)
if not tool:
raise ToolNotFoundError(f"Tool {tool_name} not found")
return tool.execute(tool_input)
def observe_result(self, result, action):
"""Observation阶段:整理观察结果"""
if action["type"] == "tool":
return f"执行{action['name']}完成,结果:{result}"
elif action["type"] == "search":
return f"搜索'{action['query']}'找到{len(result)}条结果"
else:
return str(result)
def format_history(self, history):
"""格式化历史"""
if not history:
return "无历史操作"
lines = []
for i, h in enumerate(history):
lines.append(f"步骤{i+1}:")
lines.append(f" 思考: {h.get('thought', '')}")
if "action" in h:
lines.append(f" 行动: {h['action']}")
if "observation" in h:
lines.append(f" 结果: {h['observation']}")
return "\n".join(lines)
def detect_loop(self, history, window=3):
"""检测循环:最近几步是否重复"""
if len(history) < window * 2:
return False
# 检查最近window步是否有循环
recent = [h.get("action", {}).get("name") for h in history[-window:]]
previous = [h.get("action", {}).get("name") for h in history[-window*2:-window]]
return recent == previous
三、Human in the Loop(人在环)
基于以下原因,我们需要引入人工介入:
- 幻觉问题:LLM可能生成看似正确但错误的内容;
- 知识局限:无法获取实时或私域信息;
- 道德边界:无法判断某些决策的伦理影响;
- 容错能力:某些高风险操作需要人工确认;
- 异常处理:超出预设场景的边界情况;
3.1 人工介入方式选型
| 等级 | 名称 | 触发条件 | 人工动作 | 适用场景 |
|---|---|---|---|---|
| Level 0 | 不介入 | 无 | 无 | 低风险、可逆、量大 |
| Level 1 | 事后复核 | 抽样/风险标记 | 抽查、标记 | 量大、容错空间 |
| Level 2 | 关键节点介入 | 高风险/低置信度 | 审批、确认 | 需要审批的操作 |
| Level 3 | 全程可介入 | 高风险操作 | 暂停、修改、取消 | 高价值交易、合规要求 |
| Level 4 | 人工主导 | 复杂决策/用户请求 | 决策、执行 | AI无法处理的情况 |