跳到主要内容

工具调用机制面试速查

对应模块

本文对应 FunctionCall详细解析 模块全部文档的面试考点提炼。工具调用是Agent的核心能力之一,面试中经常跟Agent一起追问。

Q1:Function Calling的完整流程是什么?模型真的"执行"了函数吗?

模型没有执行任何函数。它只输出了一段结构化文本(函数名+参数JSON),真正的执行在外部代码里完成。

完整流程:

  1. 开发者定义工具列表(name + description + parameters JSON Schema)发给模型
  2. 模型判断用户意图,决定是否需要调工具、调哪个、参数是什么
  3. 模型输出工具调用指令(结构化JSON)
  4. 外部代码解析指令 → 实际执行函数 → 拿到结果
  5. 把执行结果再发给模型 → 模型基于结果生成最终回答

模型的工作只是"决策",不是"执行"。这点务必说清楚。

📖 认识工具调用机制


Q2:模型是怎么判断"该调哪个工具"的?工具描述为什么这么重要?

模型靠工具的description来理解每个工具的用途。在推理时,它把用户意图跟所有工具描述做匹配,选择最契合的。

所以description的质量直接决定选择准确率。常见问题:

  • 描述太模糊("处理数据")→ 模型不知道什么时候该选它
  • 描述有歧义(两个工具描述像)→ 模型经常选错
  • 缺少使用场景说明 → 模型在边界case上犯错

好的描述要包含:这个工具做什么、什么时候该用它、什么时候不该用它。

📖 工具设计原则与最佳实践


Q3:Spring AI中工具调用怎么实现?@Tool注解的原理?

Spring AI通过注解声明工具,框架自动处理注册和调用:

@Tool(description = "根据城市名查询实时天气信息,返回温度和天况")
public WeatherInfo getWeather(@Param("city") String city) {
return weatherService.query(city);
}

原理:框架扫描所有@Tool注解的方法 → 提取方法签名生成JSON Schema → 注册到工具列表 → 模型选择调用时,框架通过反射执行对应方法 → 把返回值序列化后送回模型。

相比手动拼JSON Schema,注解方式的好处是类型安全、IDE有提示、修改方法签名时Schema自动同步。

📖 Spring AI工具调用实战


Q4:ToolCallback的源码执行链路是怎样的?

Spring AI内部的工具调用链路(简化版):

模型返回tool_call → ChatClient解析出函数名和参数 → 从ToolCallbackRegistry中按名字找到对应的ToolCallback → 调用callback.call(参数) → 得到结果字符串 → 封装成ToolResponseMessage → 追加到消息列表再次发给模型。

关键类:

  • FunctionCallback:工具的抽象接口
  • ToolCallbackProvider:工具注册和发现
  • DefaultToolCallingManager:执行编排,处理多工具并行调用

面试中如果被问"你看过源码吗",可以聊ToolCallback的生命周期和错误处理机制。

📖 ToolCallback源码解析


Q5:工具设计有哪些原则?什么样的工具让模型容易选对?

命名清晰:函数名本身就是语义(getWeather比tool_001好)。

职责单一:每个工具做一件事。别搞一个万能工具接收type参数分支处理。

描述精准:说清楚做什么、什么时候用、什么时候不用。

参数最少化:能不要的参数就不要。模型需要从用户对话中提取每个参数,参数越多出错概率越高。

返回值结构化:返回JSON而不是自然语言长文本。方便模型解析和后续使用。

幂等安全:查询类工具可以随便调,写入类工具要有确认机制或标记dangerous。

📖 工具设计原则与最佳实践


Q6:工具数量太多(超过20个)模型选择准确率下降怎么办?

几种策略:

分类路由:先用一个轻量判断确定任务类别,再只把该类别的工具集暴露给模型。

动态加载:默认只注册核心工具,根据对话上下文动态追加相关工具。

分层工具:设计一个"导航工具",模型先调它获取可用工具列表,再调具体工具。

Skills机制:本项目的方案——按需加载能力模块,平时只暴露摘要索引(30-50 Token/个),选中后才加载完整定义。

📖 从结构化输出到可靠的工具调用

🎁优惠