Agent Loop 核心机制详解
1672 字
8 分钟
Agent Loop 核心机制详解
Agent Loop 核心机制详解
一、核心功能点拆解
1.1 双入口设计
agentLoop() → 新对话开始,添加新消息到上下文agentLoopContinue() → 从现有上下文继续,用于重试场景记忆口诀:一个入口两种模式 —— 新建或继续
1.2 双层循环架构
外层循环 (while true)├── 处理 follow-up messages(循环后的额外消息)└── 内层循环 (while hasMoreToolCalls || pendingMessages) ├── 处理 steering messages(转向消息) ├── 流式获取 assistant 响应 ├── 执行工具调用 └── 检查终止条件记忆口诀:外层管消息队列,内层管执行流程
1.3 三种消息注入机制
| 机制 | 触发时机 | 用途 |
|---|---|---|
prompts | 启动时 | 初始用户输入 |
steeringMessages | 每个 turn 开始前 | 中途干预方向 |
followUpMessages | 循环结束时 | 延续对话 |
1.4 工具执行两种模式
// 并行执行(默认)executeToolCallsParallel() → Promise.all() 同时执行
// 串行执行executeToolCallsSequential() → for...of 顺序执行触发条件:
config.toolExecution === "sequential"- 任一工具的
executionMode === "sequential"
1.5 工具执行三阶段
prepareToolCall()├── 参数验证├── beforeToolCall 钩子└── 返回 prepared/immediate
executePreparedToolCall()├── tool.execute()└── 发送 partial update 事件
finalizeExecutedToolCall()├── afterToolCall 钩子└── 修改/增强结果二、遇到的问题 → 抽象提炼
问题 1:重试时如何保持上下文?
场景:LLM 返回错误,需要重试但不能丢失已执行的工具结果。
抽象:状态连续性问题 —— 如何在不重新开始的情况下继续执行?
解决原则:
- 分离”新建”和”继续”两种入口
- 继续时验证最后一消息不是 assistant(必须是 user 或 toolResult)
- 保持 context.messages 不变,只追加新消息
问题 2:流式响应如何实时更新?
场景:LLM 流式返回 token,需要实时显示进度。
抽象:部分状态管理 —— 如何在数据不完整时管理状态?
解决原则:
- 使用
partialmessage 表示不完整状态 - 每次事件到来时替换
context.messages[-1] - 区分
message_start(初始)、message_update(增量)、message_end(完整)
// 关键模式:就地更新context.messages[context.messages.length - 1] = partialMessage;问题 3:工具调用何时并行、何时串行?
场景:读取文件的工具可以并行,但创建 git commit 的工具需要串行。
抽象:依赖关系建模 —— 如何表达工具间的依赖?
解决原则:
- 工具级别配置
executionMode - 混合模式检测:任一 sequential → 全部串行
- 保持结果顺序与调用顺序一致
问题 4:如何在循环中注入外部指令?
场景:用户在 agent 执行过程中输入新指令,需要改变方向。
抽象:控制流中断 —— 如何在不可中断的操作中注入控制?
解决原则:
- Steering messages:在每个 turn 之前检查,用于改变方向
- Follow-up messages:在循环结束时检查,用于延续任务
- 分离”注入点”和”执行点”
// 注入点设计pendingMessages = (await config.getSteeringMessages?.()) || [];// 执行点设计for (const message of pendingMessages) { currentContext.messages.push(message);}问题 5:API Key 过期怎么办?
场景:长时间运行的 agent,API key 可能中途过期。
抽象:凭证生命周期管理 —— 动态资源获取。
解决原则:
- 每次调用前通过
getApiKey()动态获取 - 回退机制:
resolvedApiKey = await getApiKey() || config.apiKey
三、面试/分享核心讲述点
开场:一句话概括
“Agent Loop 是一个事件驱动的对话循环,它管理 LLM 和工具之间的交互,通过双层循环处理用户干预,通过三阶段执行保证工具调用的可控性。“
核心架构图(手绘风格)
用户输入 │ ▼┌─────────────────────────────────┐│ agentLoop / agentLoopContinue │└─────────────────────────────────┘ │ ▼┌─────────────────────────────────┐│ 外层循环:follow-up 消息检查 │◄────────┐└─────────────────────────────────┘ │ │ │ ▼ │┌─────────────────────────────────┐ ││ 内层循环:工具调用执行 │ ││ ├─ steering messages 注入 │ ││ ├─ 流式 assistant 响应 │ ││ ├─ 工具执行(并行/串行) │ ││ └─ 终止条件检查 │ │└─────────────────────────────────┘ │ │ │ ▼ │有 follow-up? ───── 是 ────────────────────┘ │ 否 ▼ 结束面试高频问题
Q1: 为什么需要双层循环?
回答要点:
- 内层循环:处理 LLM → 工具 → LLM 的自动循环(如:调用工具后又产生新工具调用)
- 外层循环:处理 agent “想停下来”但外部有新任务的情况(如:用户在等待时输入了新指令)
- 设计思想:分离”自主循环”和”外部驱动”,让 agent 既有自主性又能被干预
Q2: 工具执行的 prepare/execute/finalize 三阶段解决了什么问题?
回答要点:
prepare → 验证 + 钩子干预(可以阻止执行)execute → 真正执行 + 实时更新finalize → 结果增强(可以修改返回内容)- 解耦:把验证、执行、后处理分离
- 可扩展:通过钩子实现权限控制、日志、监控
- 可测试:每个阶段可单独测试
- 错误隔离:一个阶段的错误不影响其他阶段的清理
Q3: 流式响应如何保证消息完整性?
回答要点:
- partial message 模式:始终在 context 中维护一个”当前正在构建”的消息
- 事件驱动更新:每次收到 delta 就替换 partial
- 最终一致性:
response.result()返回完整消息,确保最后状态正确 - 边界处理:处理
start→update*→end和直接done两种路径
// 两种路径case "start": context.messages.push(partial); // 添加占位case "done": context.messages[-1] = final; // 替换为完整四、设计模式提炼
4.1 事件流模式
定义:将异步操作建模为事件序列,消费者通过事件类型响应。
好处:
- UI 可以细粒度响应
- 易于测试和调试
- 支持中间状态持久化
4.2 钩子链模式
定义:在操作前后插入自定义逻辑。
钩子点:
beforeToolCall:权限检查、参数修改、阻止执行afterToolCall:结果修改、日志、清理prepareNextTurn:上下文压缩、模型切换transformContext:消息过滤、重排序
4.3 延迟执行模式
定义:将异步操作表示为函数,按需执行。
好处:
- 统一处理立即结果和异步操作
- 支持并行优化
- 保持顺序一致性
五、记忆卡片
卡片 1:双入口
agentLoop:新建对话agentLoopContinue:继续对话(最后一消息必须是 user/toolResult)
卡片 2:双层循环
- 外层:
follow-up消息(延续任务) - 内层:
toolCalls+steering消息(自主执行)
卡片 3:三阶段工具执行
prepare:验证 + 钩子(可阻止)execute:执行 + 实时更新finalize:结果增强
卡片 4:三种消息注入
prompts:启动时steering:每 turn 前follow-up:循环结束时
卡片 5:两种工具执行
parallel:Promise.all(默认)sequential:for…of(工具配置或全局配置)
支持与分享
如果这篇文章对你有帮助,欢迎分享给更多人或赞助支持!
Agent Loop 核心机制详解
https://firefly.cuteleaf.cn/posts/learn-pi/agent-loop/12-AgentLoop核心机制/ 相关文章 智能推荐
1
Agent Loop 核心架构解析
pi 基于 agent-loop.ts 源码分析,理解双层循环架构、四大核心机制、五大问题抽象
2
Loop与Agent 问题驱动的架构设计分析
pi 从表面问题出发,抽象本质问题,推导核心原则,展示技术实现的完整设计过程,理解agent-loop.ts与agent.ts的分层职责
3
AgentLoop 工具调用的本质问题与核心原则
pi 从10个具体问题抽象出5个本质问题,推导出5个核心原则:声明式设计、传递式控制、结果式错误、Hook统一拦截、双层分离
4
AgentState 代理状态详解
pi 掌握代理的配置快照与运行时状态管理,理解系统提示、对话历史、流式输出的核心字段
5
AgentTool 代理工具详解
pi 掌握代理工具的五要素设计,理解参数预处理、可中断执行、细粒度并发控制的机制
随机文章 随机推荐