函数调用基础

什么是函数调用

函数调用(Function Calling)是大模型的核心能力,允许模型识别用户意图并将其转化为结构化函数调用。通过这种方式,模型可以与外部系统交互,执行数据查询、API调用、工具使用等操作,并将结果整合到对话中。

核心价值

函数调用使大模型能够实时获取业务系统数据,弥补知识时效性限制,提供更精准、实时的回答,显著增强模型在专业领域的应用价值。

核心优势: 将非结构化自然语言转换为结构化参数,实现人机交互到系统操作的无缝衔接,大幅提升业务流程自动化水平。

业务场景说明

通过自然语言告诉大模型"帮我查询小明同学的数学成绩",大模型会自动识别意图、匹配函数、提取参数,最终调用后端代码查询数据库并返回结果。

sequenceDiagram
    participant User as User
    participant ChatGPT as ChatGPT
    participant API as Math Score API
    
    User->>ChatGPT: 输入自然语言请求:<br/>张三数学成绩怎么样?
    
    Note over ChatGPT: 分析提取参数: 张三
    
    ChatGPT->>API: 调用数学成绩API
    
    API-->>ChatGPT: 返回张三成绩
    
    ChatGPT-->>User: 输出张三成绩

执行流程

函数调用的完整执行流程包括用户输入、函数匹配、参数提取、业务执行和结果返回五个阶段:

graph LR
    A[用户输入自然语言] --> B{用户是否指定函数?}
    B -->|否| C[向量搜索匹配函数]
    B -->|是| D[直接使用指定函数]
    C --> E{找到匹配函数?}
    E -->|否| F[返回提示信息]
    E -->|是| G[更新上下文函数名]
    D --> H[获取AI函数助手]
    G --> H
    H --> I[大模型提取参数]
    I --> J[执行参数校验]
    J --> K[调用业务逻辑]
    K --> L[流式返回结果]

自动匹配函数机制

向量搜索匹配

当用户未明确指定函数时,系统通过向量相似度搜索自动匹配语义最相近的函数。这种机制让用户无需记忆函数名称,只需用自然语言描述需求即可。

核心实现逻辑:

// 使用向量搜索查找FUNCTION类型的函数
EmbeddingSearchResult<TextSegment> searchResult = EmbeddingProvider.search(
    chatMessageDTO.getContent(),
    metadataKey(EmbedBizTypeEnums.Fields.type)
        .isEqualTo(EmbedBizTypeEnums.FUNCTION.getType())
);

// 如果未找到匹配函数,返回提示信息
if (Objects.isNull(searchResult) || searchResult.matches().isEmpty()) {
    return Flux.just(new AiMessageResultDTO("未找到相关功能,请点击下方+按钮选择目标功能"));
}

// 获取最匹配的函数名并更新到上下文
String functionName = searchResult.matches().get(0).embedded().metadata().getString(TEMP_ID);
chatMessageDTO.getExtDetails().setFuncName(functionName);
ChatMessageContextHolder.set(chatMessageDTO);
函数描述的重要性

向量搜索的匹配精度完全取决于函数描述的准确性。务必在 functionDesc() 方法中清晰、详细地描述函数功能和适用场景。

流式响应处理

系统使用 Reactor 响应式编程模型实现流式返回,提升用户体验:

// 获取对应模型的AI函数助手
AiFunctionAssistantService aiFunctionAssistant = modelProvider
    .getAiFunctionAssistant(chatMessageDTO.getModelName())
    .getValue();

// 流式处理用户请求并返回结果
return aiFunctionAssistant.chatFlux(chatMessageDTO.getContent())
    .map(AiMessageResultDTO::new);

开发自定义函数

定义接收实体类

当用户在前端输入自然语言查询(如"小明成绩是多少?")时,需要将非结构化查询转换为后端可处理的结构化JSON数据。定义接收实体类用于接收大模型解析后的参数:

@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonClassDescription("学生信息")
public class StudentRequest extends BaseAiRequest {
    @FieldPrompt("学生姓名")
    private String studentName;
}
注解说明

@JsonClassDescription 用于描述实体类用途,@FieldPrompt 用于提示大模型该字段的含义,这些描述信息会影响参数提取的准确性。

实现函数接口

@Component
@RequiredArgsConstructor
public class MathScoreFunctionCalling implements FunctionCalling<StudentRequest> {

    /**
     * 功能描述,多个函数时AI根据描述选择调用哪个函数
     */
    @Override
    public String functionDesc() {
        return "学生成绩查询助手: 能根据您的描述帮您查询学生的数学成绩";
    }

    /**
     * 参数校验,大模型返回的数据不一定稳定,必须进行业务校验
     */
    @Override
    public R checkParams(StudentRequest studentRequest, PigxUser userDetails,
                         ChatMessageDTO.ExtDetails extDetails) {
        if (StrUtil.isBlank(studentRequest.getStudentName())) {
            return R.failed("学生姓名不能为空");
        }
        return R.ok();
    }

    /**
     * 业务处理逻辑
     */
    @Override
    public R<String> handle(StudentRequest studentRequest, PigxUser userDetails,
                            ChatMessageDTO.ExtDetails extDetails) {
        // 模拟根据学生姓名查询数学成绩
        if ("小明".equals(studentRequest.getStudentName())) {
            return R.ok("98");
        }
        return R.failed("查询失败,学生信息不存在");
    }
}
必须实现参数校验

所有业务函数必须实现 checkParams() 方法进行严格的参数校验,因为大模型返回的数据不一定稳定可靠。

测试使用

在前端的 AI 联动界面中,您可以使用自然语言进行各种提问,例如"查询小明的数学成绩"、"小明这次考试考得怎么样"或"告诉我小明的成绩"等。系统会自动理解您的意图,调用相应的函数,并准确返回小明的数学成绩。

函数调用测试示例

业务应用场景

函数调用是连接大模型能力与业务系统的关键桥梁。通过将业务功能封装为标准化接口,实现自然语言到结构化操作的智能转换。

教育行业: 智能成绩分析

业务场景: 家长询问"小明最近三次数学考试的平均分是多少?"

实现方式: ScoreAnalysisFunction 对接学校考试系统,自动解析时间范围、学科类型、统计维度,动态计算指定维度的学习趋势。

业务价值: 减少教师30%的重复查询工作,提升家长服务响应速度至秒级。

电商行业: 订单状态追踪

业务场景: 用户提问"我昨天买的手机发货了吗?订单号23456"

实现方式: OrderQueryFunction 自动提取订单号,对接ERP系统实时查询。通过JWT token验证用户身份,确保订单数据隔离。

业务价值: 降低客服中心50%的常规查询量,提升用户自助服务率。

医疗行业: 检查报告解读

业务场景: 患者询问"上周三做的血常规报告有什么异常指标?"

实现方式: MedicalReportFunction 对接HIS系统,智能标记异常数据,结合医学知识图谱进行指标关联分析。

业务价值: 缩短患者报告解读等待时间从2天到实时响应。