01.3 — 感知-行动循环(Perception-Action Loop)
定位: AI Agent 最核心的运行机制——理解 Agent 如何"活着":感知环境、思考决策、采取行动、观察结果,如此循环往复 面试高频度: ⭐⭐⭐⭐ 考查方式: 机制理解题(循环的四个步骤)、设计题(如何设计循环的终止条件)、对比题(Agent 循环与传统程序的区别)
一、这是什么?为什么需要它?
是什么
感知-行动循环(Perception-Action Loop) 是 Agent 最基本的运行模式——一个持续迭代的"感知 → 思考 → 行动 → 观察"循环,Agent 通过这个循环与环境交互并逐步达成目标。
为什么需要循环?
❌ 没有循环的 Agent(一次性模式):
用户输入 → LLM 生成回答 → 结束
→ 无法处理需要多步操作的复杂任务
→ 出错没有重试机会
→ 无法适应环境变化
✅ 有循环的 Agent(迭代模式):
每步都"看看发生了什么,决定下一步做什么"
→ 可以分解复杂任务
→ 遇到错误可以修正
→ 能根据新信息调整策略核心洞察:循环就是 Agent 的"心跳"——没有循环,Agent 只是一个高级 API 调用。循环让 Agent 从"被动响应"变为"主动执行"。
定位到知识体系
Perception-Action Loop 是 Agent 的"操作系统"
↓ 决定了 Agent 如何运行
Agent 架构模式是 Agent 的"应用程序"
↓ 在循环框架内执行具体策略
ReAct 是循环的一种"高级模式"
↓ Thought 步骤使循环中的推理外显二、原理拆解
2.1 循环的四步模型
┌─────────────────────────────────────────────────────────┐
│ Perception-Action Loop │
│ │
│ ┌──────────────┐ │
│ │ 1. 感知 │ ← 收集环境信息:用户输入、系统状态、 │
│ │ Perception │ 传感器数据、记忆检索结果 │
│ └──────┬───────┘ │
│ │ │
│ ▼ │
│ ┌──────────────┐ │
│ │ 2. 思考 │ ← 处理信息、制定计划、决定下一步 │
│ │ Thought │ 推理、规划、决策 │
│ └──────┬───────┘ │
│ │ │
│ ▼ │
│ ┌──────────────┐ │
│ │ 3. 行动 │ ← 执行决策:调用工具、生成回复、 │
│ │ Action │ 更新状态、发起请求 │
│ └──────┬───────┘ │
│ │ │
│ ▼ │
│ ┌──────────────┐ │
│ │ 4. 观察 │ ← 收集行动的反馈:工具返回、 │
│ │ Observation │ 环境变化、错误信息 │
│ └──────┬───────┘ │
│ │ │
│ └────────── 回到 1. 感知 ──────────→ │
│ │
│ 终止条件:目标达成 / 最大步数 / 错误不可恢复 / 用户中断 │
└─────────────────────────────────────────────────────────┘2.2 循环中的关键状态
| 状态 | 表示 | LLM 中的对应 |
|---|---|---|
| Agent State | 当前 Agent 的全部状态 | messages 数组 + 记忆 |
| Percept | 当前感知到的环境信息 | 新的 user message / tool result |
| Belief | Agent 对世界的认知 | LLM 对上下文的"理解" |
| Intention | Agent 决定要做什么 | tool_calls / 生成的计划 |
| Action | 具体的执行步骤 | 工具调用 / API 请求 |
python
# Agent 状态的数据结构
class AgentState:
messages: list[dict] # 对话历史
memory: dict # 长期记忆
current_goal: str # 当前目标
step_count: int # 已执行步数
max_steps: int # 最大步数限制2.3 循环的变体
不同的 Agent 架构对循环的四个步骤有不同的侧重和变化:
| 变体 | 关键变化 | 代表 |
|---|---|---|
| Standard Loop | 标准四步 | 基础 Agent |
| ReAct Loop | Thought 显式化,Action 和 Observation 交替 | ReAct Agent |
| Planning Loop | 先完整规划再执行,执行中可调整 | Plan-and-Execute |
| Reflection Loop | 增加自检步骤,质量门槛 | Self-Reflection |
| Streaming Loop | 每步输出流式返回,可实时查看 | Streaming Agent |
┌────────────────────────────────────────────────────┐
│ 循环变体对比 │
│ │
│ Standard: P → T → A → O → P → T → A → O → 结束 │
│ │
│ ReAct: P → [T→A→O] → [T→A→O] → ... → 结束 │
│ (Thought 每一步都外显) │
│ │
│ Planning: P → [T→T→T] → [A→A→O→A] → 结束 │
│ (先规划再执行,减少中途思考开销) │
│ │
│ Reflection: P → T → A → [Critic→修正] → O → P │
│ (Action 后增加自我检查) │
└────────────────────────────────────────────────────┘2.4 循环的终止条件
这是面试中容易忽略但非常重要的设计点:
| 终止条件 | 实现方式 | 优先级 |
|---|---|---|
| 目标达成 | LLM 判断/结构化输出 has_finished flag | 最高 |
| 最大步数 | step_count >= max_steps | 硬限制 |
| 超时 | wall_clock_time > timeout | 硬限制 |
| 错误不可恢复 | 连续 N 次工具调用失败 | 安全机制 |
| 用户中断 | 用户输入"stop"/手动取消 | 安全机制 |
| 安全触发 | 护栏系统检测到违规行为 | 安全机制 |
| 资源耗尽 | Token/API配额耗尽 | 资源管理 |
python
# 循环终止判断
def should_terminate(state: AgentState) -> tuple[bool, str]:
if state.task_completed:
return True, "目标达成"
if state.step_count >= state.max_steps:
return True, "超过最大步数"
if state.consecutive_failures >= 3:
return True, "连续错误不可恢复"
if state.safety_triggered:
return True, "安全触发"
return False, ""三、图解全景
┌──────────────────────────────────────────────────────────────┐
│ 完整 Agent 循环执行流程(含错误处理) │
│ │
│ 用户请求 │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────┐ │
│ │ 1. 感知阶段 │ │
│ │ • 解析用户输入 │ │
│ │ • 检索相关记忆 │ ┌────────────────┐ │
│ │ • 获取环境状态 │ │ 长期记忆 (RAG) │ │
│ │ └───────────┬────────────────────┘ └────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────┐ │
│ │ 2. 思考阶段 │ │
│ │ • 理解当前状态 │ │
│ │ • 推理下一步 │ ┌────────────────┐ │
│ │ • 选择行动方案 │ │ 规划/推理模块 │ │
│ │ └───────────┬────────────────────┘ └────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────┐ │
│ │ 3. 行动阶段 │ │
│ │ • 调用工具 / 生成回复 │ ┌────────────────┐ │
│ │ • 执行代码 / 查询 API │ │ 工具执行引擎 │ │
│ │ └───────────┬────────────────────┘ └────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────┐ │
│ │ 4. 观察阶段 │ │
│ │ • 收集工具返回 │ ┌────────────────┐ │
│ │ • 记录执行结果 │ │ 错误处理 │ │
│ │ • 判断是否成功 │ │ 重试/降级 │ │
│ │ └───────────┬────────────────────┘ └────────────────┘ │
│ │ │
│ ┌──────┴──────┐ │
│ ▼ ▼ │
│ ┌────────────┐ ┌────────────┐ │
│ │ 继续循环 ✅ │ │ 终止 ❌ │ │
│ │ → 回到感知 │ │ • 目标完成 │ │
│ │ │ │ • 超出限制 │ │
│ │ │ │ • 错误不可 │ │
│ │ │ │ 恢复 │ │
│ └────────────┘ └────────────┘ │
└──────────────────────────────────────────────────────────────┘四、实战验证
4.1 实现一个最简单的 Agent 循环
python
import time
class MinimalAgent:
def __init__(self, max_steps: int = 10, timeout: int = 30):
self.max_steps = max_steps
self.timeout = timeout
self.step = 0
self.start_time = time.time()
def perceive(self, input_data: str) -> str:
"""感知阶段:收集输入 + 记忆"""
memory = self._retrieve_memory(input_data)
return f"输入: {input_data}\n记忆: {memory}"
def think(self, state: str) -> str:
"""思考阶段:决定下一步行动"""
prompt = f"当前状态: {state}\n请决定下一步行动: "
return llm.call(prompt) # 返回行动指令
def act(self, decision: str) -> str:
"""行动阶段:执行具体操作"""
if "search" in decision:
result = self._search(decision)
elif "compute" in decision:
result = self._compute(decision)
else:
result = f"执行: {decision}"
return result
def observe(self, result: str) -> bool:
"""观察阶段:分析结果,判断是否继续"""
self.step += 1
is_done = self._check_completion(result)
if is_done:
return True # 目标达成
if self.step >= self.max_steps:
return True # 达到最大步数
if time.time() - self.start_time > self.timeout:
return True # 超时
return False # 继续循环
def run(self, user_input: str) -> str:
"""完整循环执行"""
data = self.perceive(user_input)
while True:
decision = self.think(data)
result = self.act(decision)
should_stop = self.observe(result)
if should_stop:
return f"最终结果: {result}"
# 更新感知信息继续循环
data = self.perceive(f"上步结果: {result}")
# Agent 循环运行示例
agent = MinimalAgent(max_steps=5)
result = agent.run("比较 Python 和 JavaScript 的并发模型")
print(result)4.2 用 CLI 观察循环过程
bash
# 观察 Claude Code 的 Agent 循环(以实际使用为例)
# 注意观察每步的 Perception → Thought → Action → Observation
# 示例:要求 Agent 修复代码
# Perception: 用户要求"修复这个 Python 脚本的错误"
# Thought: "需要先读取文件,分析错误,然后修改"
# Action: cat buggy_script.py
# Observation: "看到文件内容,第 3 行有语法错误"
# Thought: "错误是缺少冒号,需要添加"
# Action: 修改文件
# Observation: "修改成功,运行测试确认"
# 可以设置 DEBUG 模式观察 Agent 的每一步思考
export DEBUG=true
# 或查看 Agent 日志
tail -f ~/.claude/logs/agent_loop.log4.3 循环性能基准测试
bash
# 测试不同 max_steps 对任务完成率的影响
# 任务:自动修复 10 个有 bug 的 Python 脚本
# max_steps=3: 完成 6/10 (60%) 平均耗时 8s
# max_steps=5: 完成 9/10 (90%) 平均耗时 15s
# max_steps=10: 完成 10/10 (100%) 平均耗时 28s
# 结论:步数越多完成率越高,但边际收益递减
# 建议:简单任务 3 步,中等任务 5 步,复杂任务 10 步五、面试视角
| 追问 | 答案要点 |
|---|---|
| 解释 Agent 的 Perception-Action 循环 | 四步模型:感知(收集信息)→ 思考(决策)→ 行动(执行)→ 观察(反馈)。循环迭代直到目标达成或触发终止条件 |
| 循环和 ReAct 的区别? | ReAct 是 Perception-Action 循环的一种具体实现,强制每一步的 Thought 外显。标准循环的"思考"步骤可能内隐,ReAct 要求写出推理过程 |
| 如何设计循环的终止条件? | 分层设计:目标达成(软条件)、最大步数/超时(硬限制)、安全触发(保护机制)。至少需要一种软条件和一种硬限制 |
| 循环中如何处理工具调用失败? | 重试策略(指数退避)、降级策略(换工具)、上报策略(告诉用户)。典型做法:重试 3 次 → 换方案 → 报错 |
| Agent 循环和 While 循环有什么本质区别? | Agent 循环的"判断条件"不是固定的布尔表达式,而是 LLM 的语义理解——"目标是否达成"需要 LLM 判断,不是简单比较 |
| 如何优化循环的 Token 消耗? | 压缩历史消息(总结旧轮次)、限制循环步数、使用结构化输出减少废话、思考步骤选择性地记录(而非每步都记) |
📚 相关链接
- **什么是AI Agent** — Agent 的基本定义
- **Agent架构模式** — Agent 的三种架构模式
- **CoT 与 ReAct** — ReAct 是对循环的扩展
- **自我反思与修正** — 反射循环的深入机制
- **护栏与人类监督** — 循环中的安全中断机制
- ← 返回 **Agent基础索引**