AgentLoop 工具调用的本质问题与核心原则

1927 字
10 分钟
AgentLoop 工具调用的本质问题与核心原则

AgentLoop 工具调用的本质问题与核心原则#


一、从 10 个问题抽象本质#

┌──────────────────────────────────────────────────────────────┐
│ 10 个具体问题 → 5 个本质问题 │
├──────────────────────────────────────────────────────────────┤
│ │
│ 1. 并发控制(工具依赖) → 不确定性 │
│ 2. 参数验证(LLM参数) → 不确定性 │
│ 9. 事件顺序(完成顺序) → 不确定性 │
│ ───────────────────────────────────────────── │
│ 外部输入不可控:参数、结果、顺序 │
│ │
│ 3. 中断取消(中途干预) → 长时性 │
│ 5. 流式反馈(进度展示) → 长时性 │
│ ───────────────────────────────────────────── │
│ 执行时间长,需要中途介入 │
│ │
│ 4. 错误处理(失败影响) → 传播性 │
│ ───────────────────────────────────────────── │
│ 单点失败不应该扩散 │
│ │
│ 6. 执行拦截(权限确认) → 边界性 │
│ 7. 结果修改(输出控制) → 边界性 │
│ 2. 参数验证(输入校验) → 边界性 │
│ ───────────────────────────────────────────── │
│ 执行前/后都需要拦截/处理 │
│ │
│ 10. 上下文管理(状态分离) → 状态性 │
│ 8. 终止信号(循环控制) → 状态性 │
│ ───────────────────────────────────────────── │
│ 运行时状态 vs 持久化状态 │
│ │
└──────────────────────────────────────────────────────────────┘

二、本质问题详解#

问题 1:不确定性#

表现形式

  • 参数不确定:LLM 返回参数可能不符合 schema

    • 类型错误:number → string
    • 值错误:123 → “read”
    • 缺少字段:required 未提供
  • 结果不确定:工具返回结果可能不符合预期

    • 太长:10000 行
    • 格式不对:JSON → 纯文本
    • 敏感信息:不该暴露
  • 顺序不确定:并行执行完成顺序不可预测

    • tc1 先完成,tc0 后完成,但对话需要顺序
  • 依赖不确定:工具之间是否有依赖关系

    • readFile + writeFile → 可能冲突
    • Loop 不知道工具内部逻辑
  • LLM 行为不确定:LLM 不一定按预期调用工具

    • 可能同时调用多个
    • 可能不调用终止工具

问题 2:长时性#

表现形式

  • 执行时间长:工具可能执行几十秒甚至几分钟

    • 文件搜索、网络请求、大量数据处理
  • 用户中途取消:用户可能在执行中途想停止

    • 发现不需要了、发现错了、资源限制
  • 信息延迟:用户等待时看不到状态

    • 界面静止、不知道进度、不知道是否卡死
  • 资源占用:长时间占用资源

    • 网络连接、文件锁、内存

问题 3:传播性#

表现形式

  • 工具失败、Hook 失败、参数校验失败

传统处理

  • 抛错 → Loop catch → 决定是否继续
  • 抛错 → 整个流程中断
  • 抛错 → 之前的工具结果丢失

问题

  • 一个工具失败 → 整个任务失败
  • 其他工具执行白费
  • LLM 看不到错误信息,无法调整策略

问题 4:边界性#

表现形式

  • 执行前边界

    • 权限检查、资源限制、危险确认、参数修正、参数校验
  • 执行后边界

    • 结果裁剪、结果转换、敏感过滤、错误恢复、错误建议
  • 边界的作用

    • 防护:防止不该执行的操作
    • 修正:修正不符合预期的结果
    • 增强:增加额外信息或处理

问题 5:状态性#

表现形式

  • 运行时状态

    • 当前对话、当前工具、当前结果、动态增长
  • 持久化状态

    • 历史对话、本次产出、调用者关心的
  • 终止信号状态

    • terminate:工具返回
    • shouldStop:Loop判断
    • 被稀释的风险
  • 两者的冲突

    • 运行时需要完整,持久化只需要新增
    • 中途停止如何处理

三、核心解决原则#

┌──────────────────────────────────────────────────────────────┐
│ 5 个本质问题 → 5 个核心原则 │
├──────────────────────────────────────────────────────────────┤
│ │
│ 不确定性 → 声明式设计 │
│ ───────────────────────────────────── │
│ ├─ 工具自声明:executionMode │
│ ├─ 兼容层声明:prepareArguments │
│ ├─ Schema 声明:参数结构 │
│ ├─ 替换语义:明确意图 │
│ └─ 顺序分离:不同用途不同顺序 │
│ │
│ 长时性 → 传递式控制 │
│ ───────────────────────────────────── │
│ ├─ AbortSignal 传递 │
│ ├─ onUpdate 回调 │
│ ├─ 各层自主响应 │
│ ├─ 流式非阻塞 │
│ │
│ 传播性 → 结果式错误 │
│ ───────────────────────────────────── │
│ ├─ 错误包装成 result │
│ ├─ isError 标记 │
│ ├─ 流程不中断 │
│ ├─ LLM 看到错误 │
│ │
│ 边界性 → Hook 统一拦截 │
│ ───────────────────────────────────── │
│ ├─ beforeToolCall:执行前 │
│ ├─ afterToolCall:执行后 │
│ ├─ 双重验证:兼容 + 校验 │
│ ├─ 统一入口 │
│ │
│ 状态性 → 双层分离 │
│ ───────────────────────────────────── │
│ ├─ currentContext:运行时 │
│ ├─ newMessages:产出 │
│ ├─ shouldStop:主动判断 │
│ │
└──────────────────────────────────────────────────────────────┘

四、核心原则详解#

原则 1:声明式设计#

核心思想:让组件自己声明特性,而非外部猜测。

对比传统方式

传统方式声明式方式
Loop 猜测工具是否有依赖
Loop 猜测参数是否符合
Loop 猜测结果是否需要修改
问题:Loop不知道工具内部逻辑,猜测可能错误
工具声明 executionMode
工具声明 prepareArguments
工具声明 schema
Hook 声明 block/reason
优势:组件知道自己,声明准确,灵活配置

原则 2:传递式控制#

核心思想:传递信号而非主动控制。

对比传统方式

传统方式传递式方式
Loop 发现取消 → 强制中断工具
Loop 发现超时 → 强制停止执行
问题:工具类型多样,Loop不知道如何中断,可能资源泄漏
Loop 传递 AbortSignal
Tool 收到 signal → 自己决定如何响应
Hook 收到 signal → 自己决定如何响应
优势:各层自主,工具知道如何安全停止

原则 3:结果式错误#

核心思想:错误也是结果,而非中断。

对比传统方式

传统方式结果式方式
tool.execute() 抛错
→ Loop catch
→ 流程中断
→ 其他工具白费
问题:传播性,单点失败扩散,LLM看不到错误
tool.execute() 抛错
→ Loop 包装
→ { content: “Error: xxx”, isError: true }
→ 加入对话
→ LLM 看到错误
→ 流程继续
优势:不传播,单点失败不扩散,LLM可以调整策略

原则 4:Hook 统一拦截#

核心思想:边界统一处理,而非分散。

对比传统方式

传统方式Hook统一方式
工具内部检查权限
工具内部裁剪结果
工具内部过滤敏感
问题:工具职责混乱,重复代码,难维护
beforeToolCall:所有执行前处理
afterToolCall:所有执行后处理
工具只负责执行
优势:职责分离,统一入口,易维护

原则 5:双层分离#

核心思想:运行时 vs 持久化,而非混淆。

对比传统方式

传统方式双层方式
一个 context
├─ 包含所有历史
├─ 包含本次新增
├─ 返回给调用者
问题:调用者拿到整个历史,可能重复保存,调用者不灵活
currentContext:运行时完整
newMessages:本次产出
优势:调用者灵活,不重复,关注点分离

五、一句话总结#

本质问题:
不确定性 + 长时性 + 传播性 + 边界性 + 状态性
核心原则:
声明式设计 + 传递式控制 + 结果式错误 + Hook统一拦截 + 双层分离
对应关系:
不确定性 → 声明式设计(组件自声明)
长时性 → 传递式控制(信号传递)
传播性 → 结果式错误(错误即结果)
边界性 → Hook统一拦截(边界集中)
状态性 → 双层分离(运行时/持久化)

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或赞助支持!

赞助
AgentLoop 工具调用的本质问题与核心原则
https://firefly.cuteleaf.cn/posts/learn-pi/agent-loop/13-工具调用本质问题/
作者
AltumSisy
发布于
2026-06-13
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
AltumSisy
Hello, I'm AltumSisy.
公告
欢迎来到我的博客!这是一则示例公告。
音乐
封面

音乐

暂未播放

0:00 0:00
暂无歌词
分类
标签
站点统计
文章
32
分类
3
标签
25
总字数
68,347
运行时长
0
最后活动
0 天前

文章目录