• 已删除用户
陈永强
陈永强
发布于 2026-06-04 / 5 阅读
0

SpringBoot LangChain4j Tool工具(五)

SpringBoot LangChain4j Tool工具(五)

链接:https://langchain4j.cn/tutorials/tools.html

一、LangChain4j 工具(函数调用)

提前写好的方法或者函数,使得LLM能够通过提示词调用对应的方法。

注解@Tool 代表是一个工具函数,LLM通过@Tool提示词选择调用的函数

简单示例:

public class AddSum {
    @Tool("计算两个数相加")
    public Integer addSum(Integer a, Integer b) {
        return a + b;
    }
}
//工具配置
assistant = AiServices.builder(Assistant.class)
        .chatModel(ollamaChatModel)
        .chatMemoryProvider(getChatMemoryProvider("12345"))
        .contentRetriever(contentRetriever)
        //配置工具
        .tools(new AddSum())
        .build();

二、工具的动态配置

官网配置如下

自定义配置

public static   Map<ToolSpecification,ToolExecutor> setTool(ToolConfig toolConfig) {
        Map<ToolSpecification,ToolExecutor> map = new HashMap();
        //参数转换
        List jsonObject = JSONObject.parseObject(toolConfig.getParameters(), List.class);
        Map<String, JsonSchemaElement> properties = new LinkedHashMap<>();
        jsonObject.forEach(item -> {
            ToolParameter toolParameter = JSONObject.parseObject(item.toString(), ToolParameter.class);
            //工具参数放入
            properties.put(toolParameter.getName(), getJsonSchemaElement(toolParameter.getType(), toolParameter.getDescription()));
        });
        ToolSpecification toolSpecification = ToolSpecification.builder()
                .name(toolConfig.getName())//工具名称
                .description(toolConfig.getDescription())//工具描述
                //参数配置
                .parameters(JsonObjectSchema.builder()
                        .addProperties(properties).build())
                .build();
        //执行函数的工作者 执行器
        ToolExecutor toolExecutor = (toolExecutionRequest, memoryId) -> {
            Map<String, Object> arguments = JSONObject.parseObject( toolExecutionRequest.arguments(), Map.class);
            //使用具体的执行器
            Object o = ExecutorTool.executeSpring("com.ruoyi.system.service.IRagEmbeddingConfigService", "selectAll",applicationContext);
            log.info(JSONObject.toJSONString(o));
            return "今天天气很好!!" ;
        };
        map.put(toolSpecification,toolExecutor);
        return map;

    }
@GetMapping("/chat")
    public String test(String msg) {
        HttpClientBuilder httpClientBuilder = new SpringRestClientBuilder();
        if (assistant == null) {
            ChatModel ollamaChatModel = OllamaChatModel.builder()
                    .baseUrl("http://192.168.2.136:11434")
                    .modelName("qwen3:8b")
                    .httpClientBuilder(httpClientBuilder)
                    .logRequests(true)
                    .logResponses(true)
                    .build();
            //RAG 知识库
            RagConfig vo = ragConfigService.selectRagConfigById(1L);
            if(!StringUtils.isNull(vo)) {
                //向量模型 配置
                RagEmbeddingUseConfig ragEmbeddingUseConfigVo = ragEmbeddingUseConfigService
                        .selectRagEmbeddingUseConfigById(vo.getEmbeddingUseConfigId());
                RagEmbeddingConfig ragEmbeddingConfigVo = ragEmbeddingConfigService
                        .selectRagEmbeddingConfigById(ragEmbeddingUseConfigVo.getEmbeddingConfigId());
                vo.setRagEmbeddingConfig(ragEmbeddingConfigVo);
                vo.setRagEmbeddingUseConfig(ragEmbeddingUseConfigVo);
            }
            //配置RAG
            ContentRetriever contentRetriever = RagConfigTool.getContentRetriever(vo);
            //工具配置,以后可以从数据库拿到相关配置
            ToolConfig toolConfig = new ToolConfig();
            toolConfig.setDescription("查询天气");
            toolConfig.setName("查询天气");
            ToolParameter toolParameter = new ToolParameter();
            toolParameter.setType("String");
            toolParameter.setDescription("查询的天气位置");
            toolParameter.setName("local");
            toolConfig.setParameters(JSONObject.toJSONString(toolParameter));
            ToolConfigTool.setApplicationContext(applicationContext);
            //生成对应的工具
            Map<ToolSpecification, ToolExecutor> map = ToolConfigTool.setTool(toolConfig);
            ToolProvider toolProvider = (toolProviderRequest) -> ToolProviderResult.builder().addAll(map).build();
            //用list 以后可以支持多工具
            List<ToolProvider> toolProviders = new ArrayList<>();
            toolProviders.add(toolProvider);
            //工具配置
            assistant = AiServices.builder(Assistant.class)
                    .chatModel(ollamaChatModel)
                    .chatMemoryProvider(getChatMemoryProvider("123451"))
                    .contentRetriever(contentRetriever)
                    //配置工具
//                    .tools(new AddSum())
                    //添加工具
                    .toolProviders(toolProviders)
                    .build();

        }
        String chat = assistant.chat("12345", msg);
        return chat;
    }
@Slf4j
//执行器方法 
public class ExecutorTool {
    //使用的SpringBoot中的方法
    public static Object executeSpring(String beanName, String methodName, org.springframework.context.ApplicationContext applicationContext)  {
        try {
//            Object bean1 = applicationContext.getBean(beanName);
            Object bean = SpringUtils.getBean(getClass(beanName));
//            Object bean = applicationContext.getBean(beanName);
            Class<?> aClass = bean.getClass();
            Method method = aClass.getMethod(methodName);
            method.setAccessible(true);
            Object invoke = method.invoke(bean);
            return invoke;
        }catch (Exception e){
            log.error(e.getMessage(),e);
            return "方法执行异常";
        }
    }
    public static Class<?> getClass (String beanName)  {
        Class<IRagEmbeddingConfigService> iRagEmbeddingConfigServiceClass = IRagEmbeddingConfigService.class;
        return iRagEmbeddingConfigServiceClass;

    }
}

三、测试

控制台打印的日志返回调用到了正确的方法。

三、groovy 工具使用

pom 依赖

       <!--            groovy引擎 执行java脚本 -->
            <dependency>
                <groupId>org.codehaus.groovy</groupId>
                <artifactId>groovy-all</artifactId>
                <version>3.0.22</version>
                <type>pom</type>
            </dependency>

使用

@Component
public class GroovyClassExecutor {
    private final GroovyClassLoader classLoader = new GroovyClassLoader();
    /**
     * 执行Groovy脚本(完整类)
     * @param script 完整的Groovy类源码
     * @param methodName 要执行的方法名
     * @param params 方法参数
     * @return 执行结果
     */
    public Object execute(String script, String methodName, Object... params) throws Exception {
        // 1. 编译脚本为Class
        Class<?> clazz = classLoader.parseClass(script);
        // 2. 创建实例
        GroovyObject groovyObject = (GroovyObject) clazz.getDeclaredConstructor().newInstance();
        // 3. 调用方法
        return groovyObject.invokeMethod(methodName, params);
    }
}
//groovy 调用
public static Object getBean () throws Exception {
    GroovyClassExecutor bean = SpringUtils.getBean(GroovyClassExecutor.class);
    Object execute = bean.execute("public String returnString(String result) {\n" +
            "        return result+System.currentTimeMillis();\n" +
            "    }", "returnString", "hello world");
    return execute;
}

日志有返回调用结果的日志返回