惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

雷峰网
雷峰网
博客园 - 聂微东
酷 壳 – CoolShell
酷 壳 – CoolShell
宝玉的分享
宝玉的分享
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
罗磊的独立博客
Hugging Face - Blog
Hugging Face - Blog
T
Tailwind CSS Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
IT之家
IT之家
博客园_首页
博客园 - 三生石上(FineUI控件)
博客园 - 叶小钗
Apple Machine Learning Research
Apple Machine Learning Research
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
量子位
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
人人都是产品经理
人人都是产品经理
美团技术团队
小众软件
小众软件
Jina AI
Jina AI
S
SegmentFault 最新的问题
博客园 - Franky
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com

博客园 - work hard work smart

Java 常见面试问题 手撕java常用代码 WebStorm 创建react工程 构建企业级 Text-to-SQL Agent:基于 LangGraph 的智能数据查询系统设计 Harness 工程:驾驭 AI Agent 的工程化艺术 DeepAgents 多智能体架构实战:从设计模式到后端选型 Vue 自定义组件完全指南:从零构建待办事项应用 使用 LangChain + Hugging Face 构建文本向量化服务 SQLAlchemy 使用详解 Python 中使用 Elasticsearch 的完整指南 Qdrant 向量数据库使用指南 OpenEvals 快速入门:LLM 评估指南 DeepEval 快速入门:LLM 应用评估指南 LangSmith 批量评估完全指南 Qwen-Agent 入门指南:快速构建智能体应用 LangSmith 集成实战:从追踪到评估的完整指南 初识 go-zero:一款让你写后端更规范、更高效的 Go 微服务框架 RAG 中为什么需要 Rerank,以及如何使用 Rerank LangChain4j RAG 核心组件与组合方式 如何使用 Elasticsearch 进行全文检索和向量检索 MinerU Docker 部署指南 5 分钟上手:为 Cline 配置一个免费的 MCP 天气服务 Neo4j 图数据库安装与 Spring Boot 集成实战指南 LangFuse 实战指南:用 @observe 三行代码给 LLM 应用加上全链路追踪 Spring AI 提示词模板实战:告别硬编码,实现提示词工程化管理 LangChain4j 实战指南:用 Java 轻松构建 AI 应用 Spring AI 对话短期记忆实战:让大模型拥有"记忆力" Spring AI 提示词工程实战:让大模型更懂你的意图 Spring AI ChatClient 深度解析:优雅构建大模型应用的利器 Spring AI Alibaba DashScopeChatModel 实战
Function Call 深度解析:让大模型从"嘴炮"到&quot...
work hard work smart · 2026-06-01 · via 博客园 - work hard work smart

摘要:大语言模型只能聊天不能做事?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 Schema
  • Function<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");  // 仅管理员
}

八、局限性

  1. 依赖模型支持:GPT-3.5/4、Qwen、Claude 支持,早期模型不支持
  2. 函数数量限制:函数描述占用 Token,建议按需注册
  3. 复杂参数:文件、图片等复杂对象处理麻烦

替代方案: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

  1. 描述要具体@Description("查询库存数量和仓库位置")@Description("查询库存")
  2. 参数带示例@JsonPropertyDescription("商品名,比如 iPhone 15 Pro")
  3. 按需注册:根据场景注册函数,不要一次性全注册
  4. 异常处理:捕获异常,返回友好错误信息

❌ DON'T

  1. 简单问题不调用:"你好" 直接回答,不要调用函数
  2. 返回不要过大:分页返回,不要一次返回 10 万条数据
  3. 注意权限:敏感操作需要权限验证

十一、总结

Function Call 让大模型从"聊天机器人"进化为"智能助手":

  • 核心价值:实时数据、业务集成、精确计算、权限控制
  • 两种实现:函数注册(复杂业务)、工具注解(简单功能)
  • 关键要点:描述要具体、参数带示例、按需注册、异常处理

参考资源