广告位 · header_banner

Function Calling 进阶:并行调用、延迟调用与人工接管

Function Calling 不只是”传参数”

很多人把 Function Calling 当成”给模型一把瑞士军刀”,结果生产环境跑两天就出问题。原因很简单:工具调用的工程复杂度在多轮 / 失败 / 并发 / 接管这一类长尾,本篇把真正能在 2026 年生产环境用的进阶模式整理成清单。

模式 1:并行调用 (parallel tool use)

当用户问题可以拆成多个互相独立的子任务,模型应该一次返回多个 tool_calls 而不是循环调用。比如”今天北京和上海的天气怎么样”应该是 2 个并行调用,而不是 2 轮串行。

实操要点:

  • tool schema 标注 parallel_tool_calls: true
  • 客户端实现上用 Promise.all 之类并发;
  • 失败隔离——某个工具失败不影响其他;
  • 汇总阶段给模型回原始结果,让它整合,不要自己”拼接”再给。

模式 2:延迟工具调用 (deferred tool use)

有些工具结果是”异步”的——比如审批流、定时任务、第三方工单系统。模型不能一直等,让它把任务挂起、告诉你”什么时候回到这个会话继续”。

常见实现:

  • 工具返回 {status: "pending", task_id: ..., check_url: ...}
  • 客户端把 task_id 与 session 绑定;
  • Webhook 把结果回填,模型下一轮接着看;
  • 配套需要:超时、回查、失败重试。

模式 3:错误恢复 (self-correcting)

工具调用报错是常态,不是异常。模型要能”看到错误 → 改参数 → 再试”,但要警惕无限循环。

关键设计:

  • 工具的错误返回里要有机器可读的错误码(如 {error_code: "INVALID_ARG", field: "city", hint: "请提供完整城市名"}),而不是自由文本;
  • 给模型最多 3 次重试机会;
  • 超限后转人工接管(human-in-the-loop),模型输出”我做不到,请人类协助”;
  • 把每次失败记到日志,别让它悄无声息。

模式 4:人工接管 (human-in-the-loop)

真正严肃的系统都必须有”暂停问人类”的能力——不是事后审计,是事前拦截。实现方式:

  • 指定需要审批的工具(如转账、删库、发邮件);
  • 模型调用前先输出”我打算调用 X,参数是 Y,是否同意?”;
  • UI 弹审批按钮;人类响应后工具真正执行;
  • 用 session 状态机管理”等待人类 → 审批 → 执行 → 继续”的流转。

模式 5:工具调用的成本与限速

Function Calling 在多步流程里很容易”无限调用”。必须从前端到后端都有限速:

  • 单回合上限:如 5 个工具 / 回合;
  • 整个会话上限:如 30 个工具 / session;
  • 工具速率隔离:对外部 API 工具单独限速,避免被外部 API 拉黑;
  • 成本预估:UI 上告诉用户”这一轮调用大约 ¥0.5″,避免账单失控。

模式 6:工具描述工程

工具描述是 Function Calling 的”prompt 工程”——大部分团队都做得很草率。建议:

  • 每个参数都有 description,告诉模型何时填、什么时候不填;
  • 工具说明里写明”返回格式”,让模型知道消化结果时怎么用;
  • 列举常见错例,例如”城市参数填中文名而非英文 ID”;
  • 避免一次定义 30+ 个工具,模型会互相混淆。建议单轮 tool_choice ≤ 12 个候选,需要时分页路由。

把这套模式凑齐的代价

上面 6 个模式不是”加几行代码”——每个都是 1-3 周工作量。生产系统的 Function Calling 不再是 LLM 的事,它是分布式系统工程。要么一开始就留够工程时间,要么先用 LangGraph / LlamaIndex 这种框架的现成能力,别从零写。

工具调用是 Agent 真正的护城河,做得好坏决定了产品能不能”上线不翻车”。

广告位 · footer_banner
广告位 · sidebar_rect