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;
}日志有返回调用结果的日志返回
