Spring AI 函数调用(Function Call)系统设计方案

发布于:2025-05-07 ⋅ 阅读:(5) ⋅ 点赞:(0)

一、系统概述与设计目标

1.1 核心目标

从零构建一个灵活、安全、高效的函数调用系统,使大语言模型能够在对话中调用应用程序中的方法,同时保持良好的开发体验和企业级特性。

1.2 主要功能需求

  • 支持通过注解将普通Java方法标记为可被AI调用的函数
  • 自动生成符合LLM要求的函数描述和参数定义
  • 安全地解析和执行模型的函数调用请求
  • 处理并返回执行结果给模型
  • 提供扩展点以支持不同LLM提供商的特定实现

1.3 设计原则

  • 开发便捷性:使用声明式注解,减少开发者的工作量
  • 安全可控:严格的调用权限和参数验证
  • 高度可扩展:模块化设计,易于扩展新功能
  • 与Spring生态集成:利用Spring的依赖注入、AOP等优势

二、系统架构设计

2.1 整体架构图

┌─────────────────────────────────────┐
│             应用层                   │
│  ┌─────────────┐   ┌──────────────┐ │
│  │用户定义的工具│   │  业务服务    │ │
│  └─────────────┘   └──────────────┘ │
└───────────────────────┬─────────────┘
                        │
┌───────────────────────▼─────────────┐
│           Spring AI 函数调用系统     │
│  ┌─────────────┐   ┌──────────────┐ │
│  │工具注册中心 │   │ 函数调用引擎 │ │
│  └─────────────┘   └──────────────┘ │
│  ┌─────────────┐   ┌──────────────┐ │
│  │参数转换器   │   │ 结果处理器   │ │
│  └─────────────┘   └──────────────┘ │
└───────────────────────┬─────────────┘
                        │
┌───────────────────────▼─────────────┐
│           模型集成层                 │
│  ┌─────────────┐   ┌──────────────┐ │
│  │OpenAI适配器 │   │其他模型适配器│ │
│  └─────────────┘   └──────────────┘ │
└───────────────────────┬─────────────┘
                        │
┌───────────────────────▼─────────────┐
│           外部LLM接口                │
│  ┌─────────────┐   ┌──────────────┐ │
│  │OpenAI API   │   │其他模型API   │ │
│  └─────────────┘   └──────────────┘ │
└─────────────────────────────────────┘

2.2 核心组件

  1. 工具注册中心(Tool Registry):管理所有可用工具的元数据和实例
  2. 函数调用引擎(Function Call Engine):处理模型函数调用请求,执行目标方法
  3. 参数转换器(Parameter Converter):转换JSON参数为Java对象
  4. 结果处理器(Result Handler):处理方法执行结果,转换为标准格式
  5. 模型适配器(Model Adapter):适配不同LLM提供商的特定API和格式要求

三、详细设计与核心代码实现

3.1 注解定义

package org.springframework.ai.function;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 标记一个方法为AI可调用的工具函数
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Tool {
   
    /**
     * 工具名称,如果不提供则使用方法名
     */
    String name() default "";
    
    /**
     * 工具描述,将发送给LLM帮助其理解工具用途
     */
    String description() default "";
    
    /**
     * 是否直接返回结果而不传递给模型
     */
    boolean returnDirect() default false;
}

/**
 * 标记方法参数,提供参数描述和类型信息
 */
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface Param {
   
    /**
     * 参数名称
     */
    String name() default "";
    
    /**
     * 参数描述
     */
    String description() default "";
    
    /**
     * 是否必需
     */
    boolean required() default true;
}

3.2 工具描述模型

package org.springframework.ai.function.model;

import java.util.List;

/**
 * 工具描述,会被转换为JSON Schema发送给LLM
 */
public class ToolDescription {
   
    private String name;
    private String description;
    private List<ParameterDescription> parameters;
    private boolean returnDirect;

    // getters, setters, constructors

    /**
     * 转换为OpenAI格式的函数定义
     */
    public Map<String, Object> toOpenAiFunctionDefinition() {
   
        Map<String, Object> function = new HashMap<>();
        function.put("name", this.name);
        function.put("description", this.description);
        
        Map<String, Object> parametersSchema = new HashMap<>();
        parametersSchema.put("type", "object");
        
        Map<String, Object> properties = new HashMap<>();
        List<String> required = new ArrayList<>();
        
        for (ParameterDescription param : parameters) {
   
            Map<String, Object> property = new HashMap<>();
            property.put("type", param.getType());
            property.put("description", param.getDescription());
            
            properties.put(param.getName(), property);
            
            if (param.isRequired()) {
   
                required.add(param.getName());
            }
        }
        
        parametersSchema.put("properties", properties);
        parametersSchema.put("required", required);
        function.put("parameters", parametersSchema);
        
        return function;
    }
}

/**
 * 参数描述
 */
public class ParameterDescription {
   
    private String name;
    private String description;
    private String type;
    private boolean required;
    
    // getters, setters, constructors
}

3.3 工具注册中心

package org.springframework.ai.function.registry;

import org.springframework.ai.function.Tool;
import org.springframework.ai.function.model.ToolDescription;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * 工具注册中心,管理所有可用工具
 */
@Component
public class ToolRegistry {
   
    
    private final Map<String, ToolRegistration> registeredTools = new ConcurrentHashMap<>();
    private final ApplicationContext applicationContext;
    private final ToolDescriptionGenerator descriptionGenerator;
    
    @Autowired
    public ToolRegistry(ApplicationContext applicationContext

网站公告

今日签到

点亮在社区的每一天
去签到