Function Call 深度解析:让大模型从"嘴炮"到"实干"的技术革命
Posted on 2026-06-01 22:17 work hard work smart 阅读(45) 评论(0) 收藏 举报摘要:大语言模型只能聊天不能做事?Function Call 技术让大模型能够调用外部函数、执行实际操作。本文深度解析其核心原理、两种实现方式和生产实践。
一、痛点:大模型的"残疾"困境
场景重现
假设你问 AI:"订单 20240115001 现在到哪了?"
传统模型的局限:无法访问外部系统,只能回答"我不知道"
Function Call 的突破:
用户:订单 20240115001 到哪了?
大模型 → 调用 trackOrder("20240115001")
→ 返回:"已发货,顺丰 SF1234567890"
→ 回答:"您的订单已发货,顺丰快递 SF1234567890"
二、什么是 Function Call?
Function Call 让大模型在对话中主动识别需要调用的外部函数,自动生成参数,并基于返回结果生成回答。
核心流程:
graph LR
A[用户提问] --> B[大模型分析意图]
B --> C{需要调用函数?}
C -->|是| D[生成函数调用]
D --> E[框架执行函数]
E --> F[返回结果给大模型]
F --> G[生成最终回答]
C -->|否| G
三、Function Call 的工作原理
1. 函数注册:Java → JSON Schema
框架通过注解将函数转换为大模型能理解的 JSON Schema:
public LogisticsInfo trackOrder(OrderTrackRequest request) {
return logisticsService.query(request.orderId());
}
// 自动生成的 JSON Schema
{
"name": "trackOrder",
"description": "根据订单号查询物流状态",
"parameters": {
"orderId": {
"type": "string",
"description": "订单编号,比如 20240115001"
}
}
}
2. 调用流程
用户提问 → 框架发送函数描述给大模型
→ 大模型返回函数调用请求
→ 框架执行业务函数
→ 将结果返回大模型
→ 大模型生成最终回答
四、为什么需要 Function Call?
| 场景 | 问题 | 解决方案 |
|---|---|---|
| 实时数据 | 模型不知道实时汇率 | 调用 API 获取最新数据 |
| 业务集成 | 无法访问订单系统 | 调用企业内部服务 |
| 精确计算 | 大模型数学计算易出错 | 调用计算器函数 |
| 权限控制 | 敏感操作需要验证 | 框架拦截+权限检查 |
五、Spring AI 实战:函数注册方式
1. 引入依赖
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>
2. 配置文件
spring:
ai:
openai:
api-key: your-api-key
base-url: https://dashscope.aliyuncs.com/compatible-mode/
chat:
options:
model: qwen-plus
temperature: 0.7
3. 定义 Request/Response
public record StockQueryRequest(
@JsonProperty(required = true, value = "productName")
@JsonPropertyDescription("商品名称,比如 iPhone 15 Pro")
String productName
) {}
public record StockInfo(int quantity, String warehouse) {}
4. 注册函数(Spring AI 特性)
@Configuration
public class FunctionConfig {
@Bean
@Description("根据商品名称查询库存")
public Function<StockQueryRequest, StockInfo> checkStockFunction(
InventoryService inventoryService) {
return inventoryService::checkProductStock;
}
}
Spring AI 关键点:
@Bean:将函数注册为 Spring Bean@Description:函数描述,Spring AI 会自动转换为 JSON SchemaFunction<Request, Response>:Spring AI 标准函数接口
5. 调用函数(Spring AI API)
@RestController
@RequestMapping("/function")
public class FunctionCallController {
@Autowired
private OpenAiChatModel chatModel;
@GetMapping("/chat")
public String chat(@RequestParam("query") String query) {
return chatModel.call(
Prompt.builder()
.functions("checkStockFunction") // Spring AI 函数名
.userMessage(query)
.build()
).getContent();
}
}
测试:
curl "http://localhost:8013/function/chat?query=iPhone15Pro库存多少?"
# 输出:iPhone 15 Pro 当前库存 156 台,存放于上海仓。
六、Spring AI 实战:工具注解方式
更简洁的方式,Spring AI 提供了 @Tool 注解:
public class InventoryTools {
@Tool(description = "根据商品名称查询库存")
public String checkStock(
@ToolParam(description = "商品名称,比如 iPhone 15 Pro")
String productName) {
// 查询逻辑
return "库存 " + quantity + " 台,仓库:" + warehouse;
}
}
Spring AI 关键点:
@Tool:Spring AI 工具注解,自动注册为可用函数@ToolParam:参数描述,Spring AI 自动生成 JSON Schema
调用方式
chatModel.call(
Prompt.builder()
.tools(new InventoryTools()) // Spring AI 直接传入工具实例
.userMessage(query)
.build()
).getContent();
两种方式对比
| 维度 | 函数注册(@Bean) | 工具注解(@Tool) |
|---|---|---|
| 代码量 | 较多(需 Configuration) | 简洁 |
| 灵活性 | 高(依赖注入) | 中 |
| Spring 集成 | 完全集成 | 部分集成 |
| 适用场景 | 复杂业务 | 简单功能 |
七、高级应用
1. 多函数协同
// 注册多个函数,大模型自动选择
@Bean @Description("查询库存")
public Function<StockQueryRequest, StockInfo> checkStock(...) { ... }
@Bean @Description("计算折扣价格")
public Function<PriceRequest, PriceResponse> calculatePrice(...) { ... }
// 用户:"iPhone 15 Pro 有货吗?买 10 台多少钱?"
// 大模型自动调用 checkStock 和 calculatePrice
2. 动态注册
// 根据用户权限动态注册函数
Prompt.Builder builder = Prompt.builder();
builder.functions("checkStock", "calculatePrice"); // 所有用户
if (user.isAdmin()) {
builder.functions("deleteProduct"); // 仅管理员
}
八、局限性
- 依赖模型支持:GPT-3.5/4、Qwen、Claude 支持,早期模型不支持
- 函数数量限制:函数描述占用 Token,建议按需注册
- 复杂参数:文件、图片等复杂对象处理麻烦
替代方案:ReAct 模式
通过 Prompt 引导模型按格式思考,不依赖原生 Function Call:
Thought: 我需要做什么
Action: 使用什么工具
Action Input: 工具参数
Observation: 工具返回结果
Final Answer: 最终回答
| 维度 | Function Call | ReAct |
|---|---|---|
| 实现复杂度 | 低 | 高 |
| 可靠性 | 高(结构化) | 中 |
| 灵活性 | 中 | 高(任意模型) |
九、Spring AI 配置与完整示例
完整配置
server:
port: 8013
spring:
ai:
openai:
api-key: sk-xxx
base-url: https://dashscope.aliyuncs.com/compatible-mode/
chat:
options:
model: qwen-plus
temperature: 0.7
maxTokens: 5000
Spring AI 完整代码
// 1. Service 层
@Service
public class InventoryService {
public StockInfo checkProductStock(StockQueryRequest request) {
int quantity = database.queryStock(request.productName());
String warehouse = database.getWarehouseLocation(request.productName());
return new StockInfo(quantity, warehouse);
}
public record StockQueryRequest(
@JsonProperty(required = true, value = "productName")
@JsonPropertyDescription("商品名称,比如 iPhone 15 Pro")
String productName
) {}
public record StockInfo(int quantity, String warehouse) {}
}
// 2. 配置层
@Configuration
public class FunctionConfig {
@Bean
@Description("根据商品名称查询库存")
public Function<StockQueryRequest, StockInfo> checkStockFunction(
InventoryService inventoryService) {
return inventoryService::checkProductStock;
}
}
// 3. 控制器层
@RestController
@RequestMapping("/function")
public class FunctionCallController {
@Autowired
private OpenAiChatModel chatModel;
@GetMapping("/chat")
public String chat(@RequestParam("query") String query) {
return chatModel.call(
Prompt.builder()
.functions("checkStockFunction")
.userMessage(query)
.build()
).getContent();
}
}
十、最佳实践
✅ DO
- 描述要具体:
@Description("查询库存数量和仓库位置")❌@Description("查询库存") - 参数带示例:
@JsonPropertyDescription("商品名,比如 iPhone 15 Pro") - 按需注册:根据场景注册函数,不要一次性全注册
- 异常处理:捕获异常,返回友好错误信息
❌ DON'T
- 简单问题不调用:"你好" 直接回答,不要调用函数
- 返回不要过大:分页返回,不要一次返回 10 万条数据
- 注意权限:敏感操作需要权限验证
十一、总结
Function Call 让大模型从"聊天机器人"进化为"智能助手":
- 核心价值:实时数据、业务集成、精确计算、权限控制
- 两种实现:函数注册(复杂业务)、工具注解(简单功能)
- 关键要点:描述要具体、参数带示例、按需注册、异常处理
参考资源:
作者:Work Hard Work Smart
出处:http://www.cnblogs.com/linlf03/
欢迎任何形式的转载,未经作者同意,请保留此段声明!
浙公网安备 33010602011771号