面试知识库
极高 进阶

Function Calling与工具编排#

一句话答案#

Function Calling 是 LLM 调用外部工具的核心机制,通过输出结构化 JSON 指定工具名和参数,配合多步依赖管理和参数校验实现复杂任务编排。

核心要点

1. Function Calling 工作流程#

用户提问 → LLM 推理
  ├── 直接回答 → 返回用户
  └── 需要工具 → 输出 tool_call JSON(工具名+参数)
       → Runtime 校验参数 → 执行函数 → 结果回传 LLM
       → LLM 继续推理(可能再次调用工具)
plaintext

2. Tool Schema 设计原则#

原则说明反例
描述精确说清用途、何时用/不用、参数含义”处理数据”(太模糊)
参数约束enum/required/类型严格限定无约束的 string
最小权限只暴露必要参数暴露 SQL 直接执行
幂等设计相同参数多次调用结果一致每次调用都创建新记录

3. 多步工具依赖管理#

  • 顺序依赖:查用户→查订单→查物流(前者输出是后者输入)
  • 并行调用:独立工具并行执行(查天气 + 查日历)
  • 拓扑排序:复杂依赖图用 DAG 拓扑排序确定执行顺序

4. 工具幻觉与防御#

LLM 可能调用不存在的工具或编造参数。

防御手段:

  • Schema 白名单校验:工具名必须在已注册列表中
  • 参数类型检查:严格按 JSON Schema 校验
  • 枚举值约束:限定参数取值范围

5. 错误处理链路#

工具调用
  ├── 参数校验失败 → 提示 LLM 修正参数重试
  ├── 执行超时(>5s)→ 重试1次(指数退避)
  ├── 执行异常 → 降级到备选工具
  └── 无可用工具 → LLM 直接回答或提示用户
plaintext

6. 各家 API 的关键参数(以官方文档为准)#

能力OpenAI(推荐 Responses API)Anthropic Claude(Messages API)Google Gemini
工具定义tools 中的 function(name/description/parameters)tools 中的 name/description/input_schema,可选 input_examplesfunction_declarations
Schema 严格遵循strict: true:每个对象 additionalProperties: false、所有字段列入 required,可选字段用 null 类型表示;Responses API 会尽量把 schema 规范成 strict,不兼容时退回 best-effort工具定义上设 strict: true(strict tool use)有 VALIDATED 模式约束调用符合 schema
选择策略tool_choice:auto(默认)/ required / none / 指定函数 / allowed_tools(限定子集)tool_choice:auto(有工具时默认)/ any / tool(指定工具)/ none;部分模型不支持强制调用(any/tool 返回 400),此时用 auto + strict模式 AUTO(默认)/ ANY / NONE / VALIDATED,可限定允许调用的函数名
并行调用parallel_tool_calls: false 可保证每轮最多调一个工具tool_choice 里的 disable_parallel_tool_use支持并行调用和串联(compositional)调用
结果回传function_call_output,按 call_id 对应tool_result 内容块,按 tool_use_id 对应functionResponse

要点:强制调用(required/any)时模型不会先输出解释文字;需要”保证调用 + 保证入参合法”时,常见组合是强制调用 + strict schema,模型不支持强制调用时用 auto + strict 或改用结构化输出。

7. 工具选择不一定交给 LLM#

工具少、选择条件能写成几个布尔信号(是否模糊、是否要时效、是否要记忆等)时,一种取舍是用规则引擎做路由:延迟从一次模型调用降到微秒级,结果确定、能写单元测试断言、每次决策带 reason 写进 trace;代价是新增工具或意图时要改规则,覆盖不到的长尾要回退给 LLM。另一种常见结构是同一个工具实现走两个入口:内部 Agent 用 Function Calling 直接调,外部客户端通过 MCP Server 暴露,Schema 只定义一次。

面试回答(2分钟版)

Function Calling是LLM调用外部工具的核心机制。工作流程是这样的:用户提问后LLM推理判断是否需要工具,如果需要就输出一段结构化的JSON,包含工具名和参数,由Runtime执行后把结果回传给LLM继续推理。这个过程可能循环多次直到生成最终答案。工具Schema设计是关键,要遵循几个原则:描述要精确不能模糊,参数要有类型和枚举约束防止LLM编造值,遵循最小权限原则只暴露必要参数,关键操作要设计为幂等的。多步工具编排分两种:有依赖关系的串行执行比如先查用户再查订单,独立的工具可以并行调用提高效率。工具幻觉是常见问题,LLM可能调用不存在的工具或编造参数,需要通过Schema白名单和参数校验来防御。错误处理要有降级链路:参数错误提示LLM修正重试,执行超时用指数退避重试一次,执行失败降级到备选工具,实在不行让LLM直接回答。高风险工具比如删除数据或发邮件要加人工审批环节。各家API都提供了控制参数:strict让参数严格符合Schema,tool_choice控制自动、强制或禁止调用,并行调用也能关掉。结合项目时可以讲:工具选择交给LLM还是规则、在哪一层做参数校验、用什么数据验证效果。

追问与易错

追问方向:

  • Schema 设计太粗太细怎么权衡?工具描述多长合适? → 描述要说清做什么、什么时候用/不用、每个参数的含义和限制,参数用 enum/required 强约束。过粗导致工具幻觉(LLM 编造参数)。Anthropic 官方建议每个工具描述至少 3–4 句,复杂工具更多,复杂入参可加 input_examples;控制 token 的办法是合并相近工具、按需加载工具,而不是把描述砍到一句
  • 多步工具依赖怎么避免死循环?最大深度怎么设? → 检测连续相同工具+相同参数的调用立即终止,设 max_steps(5-15)。用 DAG 拓扑排序管理依赖,有环则报错
  • 高风险工具(删数据、发邮件)怎么加人工审批环节? → 工具分三级权限:read-only 自动执行、write 需用户确认、admin 需管理员审批。LangGraph 的 Human-in-the-loop 断点天然支持
  • 并行工具调用的结果怎么合并回 Context? → 每个工具结果带调用 ID(OpenAI 的 call_id、Claude 的 tool_use_id)对应回原调用,独立工具并行执行后统一追加,有依赖的串行等待
  • 怎么保证模型一定调工具、且参数合法? → 强制调用(OpenAI tool_choice: "required" 或指定函数;Claude any/tool)+ strict: true;模型不支持强制调用时用 auto + strict,或改用结构化输出
  • 工具选择一定要交给 LLM 吗? → 不一定。条件能写成少量布尔信号时用规则引擎更快、可测、可追溯,代价是扩展要改规则,长尾仍回退 LLM

易错点:

  • ❌ “让 LLM 自己决定所有参数” → 必须做强类型校验,LLM 会编造不存在的枚举值;开了 strict 也只保证格式,业务合法性(权限、归属)仍要服务端校验
  • ❌ “工具描述越短越省越好” → 描述是影响工具选择准确率的首要因素;要省 token 应合并相近工具、按需加载,而不是写得含糊
  • ❌ “工具调用失败就报错” → 应该有降级链路:重试→备选工具→纯 LLM 回答
  • ❌ “业务上下文(租户、用户)让 LLM 填参数” → 这类值应由服务端注入(如 Spring AI 的 ToolContext),不经过模型,防止越权