跳到主要内容
← 返回文章列表
面试题-AI相关2026/10/19约 9 分钟读完

Tool Calling 完整执行链路:从天气查询到前端状态设计

通过“查询深圳明天天气”的场景,梳理 Tool Calling 中模型、BFF、外部工具和前端的职责边界,并总结工具校验、结果回传、二次生成与 UI 状态设计。

Tool Calling 完整执行链路:从天气查询到前端状态设计
文章目录 22

题目信息

  • 领域 :LLM 基础、Tool Calling / Agent、AI 前端

  • 难度 :L1 基础认知(初级)

  • 预计用时 :10–15 分钟

  • 题型 :场景题

  • 考察方向 :理解模型、BFF、外部工具和前端在 Tool Calling 中各自承担的职责,以及一次工具调用如何形成完整闭环。

面试题

用户向 AI 助手提问:

深圳明天天气怎么样,适合跑步吗?

系统向模型声明了 getWeather 工具,模型返回:

{
  "id": "call_123",
  "name": "getWeather",
  "arguments": {
    "city": "深圳"
  }
}

请回答:

  1. 从收到这段工具调用到向用户展示最终答案,模型、BFF、天气服务和前端分别需要完成什么?

  2. BFF 能否直接根据模型返回的 name 和 arguments 执行工具?至少需要进行哪些检查?

  3. 获得天气数据后,为什么通常还要把结果传回模型,再请求模型生成一次?

  4. 工具执行期间和执行失败时,前端应该展示什么状态?

我的回答

第一问

收到这段工具调用,也就是模型收到用户的提示词后,推理出需要调用工具,并输出工具名称、参数和工具调用 ID。

BFF 接收到这个请求后,会根据 name 找到对应工具,然后将参数传给工具。工具服务商在这个场景中就是天气服务,它会根据参数返回对应的数据。

BFF 获取数据后再将结果传给模型。模型根据用户偏好、系统提示词和用户提示词,整理出对应回答,再经过 BFF 输出给前端。前端接收响应后,将最终结果显示出来。

第二问

BFF 不能直接执行模型返回的工具调用,至少应该检查:

  • name 是否能与现有工具匹配;

  • 参数是否合法;

  • 参数是否符合工具规范。

第三问

天气服务返回的数据可能包含未来多天的信息,而用户询问的是明天的天气,因此需要模型从工具结果中整理出符合用户问题的答案。

第四问

工具执行期间,前端应该展示“正在调用某某工具”。

调用失败后,前端应该展示“某某工具调用失败”。

面试点评

评分

总分:74 / 100

  • 正确性 :33 / 40

  • 原理理解 :15 / 20

  • 工程应用 :13 / 20

  • 边界与权衡 :5 / 10

  • 面试表达 :8 / 10

回答正确的部分

回答已经覆盖 Tool Calling 的核心执行链路:

用户提问
→ 模型生成 tool call
→ BFF 校验并执行工具
→ 天气服务返回数据
→ BFF 将工具结果回传模型
→ 模型生成最终回答
→ 前端展示

其中有三个关键判断是正确的:

  1. 模型负责提出工具调用,而不是直接执行天气服务。

  2. BFF 不能盲目信任模型输出,需要校验工具名称和参数。

  3. 前端需要向用户展示工具执行中和执行失败的状态。

整体执行顺序清楚,已经达到 Tool Calling 的基础认知要求。

遗漏的部分

1. 缺少工具调用关联信息

BFF 将工具结果传回模型时,需要携带对应的 tool_call_id,例如 call_123。

如果模型同时调用多个工具:

[
  {
    "id": "call_weather",
    "name": "getWeather"
  },
  {
    "id": "call_air",
    "name": "getAirQuality"
  }
]

BFF 必须确保天气数据关联到 call_weather,空气质量数据关联到 call_air。

如果缺少调用 ID,模型可能无法判断每一份工具结果对应哪次调用。

2. BFF 的校验范围不够完整

除了检查工具名称和参数格式,BFF 通常还需要处理:

  • 工具白名单;

  • JSON Schema 参数校验;

  • 用户身份认证;

  • 工具调用权限;

  • 业务授权;

  • 调用超时;

  • 请求取消;

  • 调用频率限制;

  • 并发数量限制;

  • 第三方服务错误;

  • 日志与链路追踪;

  • 敏感信息脱敏。

3. 前端状态设计不够完整

除了“正在调用”和“调用失败”,一个完整的 AI 工具调用界面还可以区分:

正在分析问题
→ 正在查询天气
→ 天气查询完成
→ 正在组织答案
→ 回答完成

异常情况下则可能进入:

工具调用失败
工具调用超时
请求已取消
模型生成失败

不同的状态应该对应不同的提示信息和恢复操作。

需要修正的部分

1. 再次调用模型的根本原因不是天气数据量大

天气服务可能返回未来 7~15 天的数据,但这不是必须再次调用模型的根本原因。

即使天气服务只返回明天一天的数据:

{
  "date": "2026-10-20",
  "temperature": "22℃",
  "weather": "小雨",
  "windLevel": 4
}

这些仍然只是结构化事实。

用户真正询问的是:

明天天气怎么样,适合跑步吗?

模型还需要结合天气数据进行判断,并把结构化数据转换成自然语言:

深圳明天有小雨,风力为 4 级。室外跑步可能受到降雨影响,建议改为室内运动,或者等待雨停后再跑。

因此,第二次调用模型的核心目的,是让模型结合原始问题、上下文和工具结果完成推理与表达。

2. 前端不一定接收流式响应

回答中提到前端会接收二进制流并逐个显示,但 Tool Calling 并不一定使用流式协议。

常见的返回方式包括:

  • 一次性返回 JSON;

  • 使用 SSE 持续返回事件;

  • 使用 WebSocket 双向传输消息;

  • 使用其他自定义流式协议。

网络底层传输的确是字节,但前端需要先完成:

字节数据
→ 文本解码
→ 协议解析
→ 完整事件
→ 状态更新
→ 页面渲染

前端不能简单地把每一个网络分片直接显示出来,因为一个完整的 SSE 事件或 JSON 数据可能被拆到多个网络分片中。

推荐答案与原理解析

一次 Tool Calling 的完整链路

完整流程可以分为以下十个步骤。

第一步:用户提交问题

用户在前端输入:

深圳明天天气怎么样,适合跑步吗?

前端把用户消息发送给 BFF。

第二步:BFF 请求模型

BFF 将以下内容发送给模型:

  • 用户消息;

  • 系统提示词;

  • 会话上下文;

  • 可用工具定义;

  • 工具参数约束。

例如:

{
  "name": "getWeather",
  "description": "查询指定城市的天气",
  "parameters": {
    "type": "object",
    "properties": {
      "city": {
        "type": "string",
        "description": "城市名称"
      }
    },
    "required": ["city"]
  }
}

第三步:模型生成工具调用

模型判断自己缺少实时天气信息,因此不会直接编造答案,而是生成:

{
  "id": "call_123",
  "name": "getWeather",
  "arguments": {
    "city": "深圳"
  }
}

模型在这里做的是“提出工具调用请求”,而不是直接执行工具。

第四步:BFF 校验工具调用

模型输出属于不可信输入,BFF 不能直接执行。

BFF 至少需要检查:

工具名称是否在白名单中
参数是否符合 JSON Schema
当前用户是否有调用权限
是否超过调用频率限制
是否存在危险或异常参数

工具注册表可以采用类似下面的结构:

type ToolHandler = (args: unknown) => Promise<unknown>;

const toolRegistry: Record<string, ToolHandler> = {
  getWeather,
  getAirQuality
};

只有注册表中明确存在的工具才能执行。

不能让模型动态指定任意函数、命令或者请求地址。

第五步:BFF 执行天气工具

校验通过后,BFF 调用天气服务:

const weatherResult = await getWeather({
  city: "深圳"
});

同时还应该设置超时和取消信号:

const controller = new AbortController();

const timer = setTimeout(() => {
  controller.abort();
}, 5000);

try {
  const result = await getWeather(
    { city: "深圳" },
    { signal: controller.signal }
  );

  return result;
} finally {
  clearTimeout(timer);
}

第六步:天气服务返回数据

天气服务可能返回:

{
  "city": "深圳",
  "date": "2026-10-20",
  "weather": "小雨",
  "temperature": "22℃",
  "humidity": "82%",
  "windLevel": 4
}

这是外部工具提供的事实数据,还不是最终回答。

第七步:BFF 回传工具结果

BFF 将工具结果连同调用 ID 回传给模型:

{
  "type": "tool_result",
  "tool_call_id": "call_123",
  "content": {
    "city": "深圳",
    "date": "2026-10-20",
    "weather": "小雨",
    "temperature": "22℃",
    "humidity": "82%",
    "windLevel": 4
  }
}

tool_call_id 用于建立以下关联:

模型提出的工具调用
       ↕
BFF 返回的工具结果

第八步:模型生成最终答案

模型根据以下内容继续生成:

  • 用户原始问题;

  • 系统提示词;

  • 会话上下文;

  • 天气工具返回的数据。

最终可能生成:

深圳明天有小雨,气温约为 22℃,湿度较高并伴有 4 级风。室外跑步体验可能不佳,建议选择室内运动;如果雨停,可以适当缩短跑步时间并注意防滑。

第九步:BFF 返回最终结果

BFF 可以选择:

  • 一次性返回完整 JSON;

  • 使用 SSE 流式返回;

  • 使用 WebSocket 返回。

如果使用 SSE,BFF 需要把模型输出编码为完整事件,前端则需要正确处理跨网络分片的数据。

第十步:前端更新页面

前端根据执行阶段更新状态:

正在分析问题
正在调用天气工具
天气查询成功
正在生成回答
回答完成

如果执行失败,则根据错误类型显示:

参数错误
无权调用工具
天气服务超时
天气服务不可用
模型生成失败
请求已取消

模型、BFF、工具与前端的职责边界

模型的职责

模型负责:

  • 理解用户意图;

  • 判断是否需要工具;

  • 选择工具;

  • 生成调用参数;

  • 结合工具结果进行推理;

  • 生成自然语言回答。

模型不应该负责:

  • 直接保存 API Key;

  • 直接决定最终权限;

  • 绕过 BFF 调用第三方服务;

  • 执行任意函数或系统命令;

  • 将自身输出视为可信参数。

BFF 的职责

BFF 负责:

  • 保存模型和第三方服务密钥;

  • 维护工具白名单;

  • 校验工具名称和参数;

  • 完成身份认证和权限判断;

  • 执行工具;

  • 设置超时、取消和限流;

  • 关联 tool_call_id;

  • 回传工具结果;

  • 记录日志和调用链路;

  • 统一处理错误。

BFF 是 Tool Calling 链路中的主要安全边界。

外部工具的职责

天气服务等外部工具负责:

  • 执行具体业务能力;

  • 返回真实数据;

  • 提供明确的成功或失败结果。

工具返回的数据也不一定完全可信,BFF 仍然需要检查数据结构、大小和异常内容。

前端的职责

前端负责:

  • 收集用户输入;

  • 发起和取消请求;

  • 展示工具执行状态;

  • 解析普通响应或流式事件;

  • 展示最终答案;

  • 显示失败原因;

  • 提供合理的重试入口;

  • 避免重复提交;

  • 清理请求和页面资源。

前端状态设计

可以用状态机管理一次工具调用:

type ToolCallStatus =
  | "idle"
  | "requesting"
  | "validating"
  | "running"
  | "succeeded"
  | "generating"
  | "completed"
  | "failed"
  | "cancelled";

各状态可以对应不同的 UI:

状态

页面提示

可用操作

requesting

正在分析问题

取消

validating

正在检查工具参数

取消

running

正在查询深圳天气

取消

succeeded

天气查询完成

等待模型生成

generating

正在组织答案

停止生成

completed

回答完成

复制、重新生成

failed

天气查询失败

重试

cancelled

请求已取消

重新发送

相比只展示统一的“加载中”,明确的状态可以帮助用户理解系统正在执行什么,也方便前端处理取消、失败和重试。

推荐面试口述答案

模型收到用户问题后,判断需要调用 getWeather,并输出工具名称、参数和 tool_call_id。BFF 不能直接信任模型输出,而是要先检查工具是否在白名单中、参数是否符合 schema,以及当前用户是否有调用权限,同时设置限流、超时和取消机制。

校验通过后,BFF 调用天气服务,再将工具结果连同对应的 tool_call_id 回传给模型。模型结合用户原问题和天气数据完成推理,生成最终自然语言回答,最后由 BFF 通过普通 JSON 或 SSE 返回前端。

前端应该展示正在分析、正在调用工具、正在生成答案、完成、失败和取消等状态。如果调用失败,还要根据错误类型决定是否允许用户重试。

最终总结

这道题的核心不是记住某个模型 SDK 的具体写法,而是明确 Tool Calling 中各层的职责:

模型:提出调用决策
BFF:校验并执行工具
外部服务:提供事实数据
模型:解释数据并生成回答
前端:展示过程、结果和异常

需要重点掌握四个关键结论:

  1. 模型只是提出工具调用,真正执行工具的是应用服务。

  2. 模型输出属于不可信输入,BFF 必须建立工具白名单和参数校验。

  3. 工具结果需要通过 tool_call_id 与原调用建立关联。

  4. 前端不仅要展示最终答案,还要展示工具执行、模型生成、失败和取消等中间状态。

评论

0 条

评论会在审核后展示,邮箱不会公开。

正在确认登录状态

5000 / 5000