Dict.CN 在线词典, 英语学习, 在线翻译 ------------- MyGitee My腾云code My51cto

Happy_EveryDay

可以平凡 不可以平庸 无爱则无忧,无欲则无求,无怒而无敌,无怨才是佛。所有烦恼,都是放不下的执著 开源技群 328035181 MyGitee

博客园 首页 管理
1、pom
            • <properties>
              <java.version>17</java.version>
              <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
              <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
              <spring-boot.version>3.2.0</spring-boot.version>
              <spring-ai.version>1.0.0</spring-ai.version>
              <spring-ai-alibaba.version>1.0.0.2</spring-ai-alibaba.version>
              <jedis.version>5.2.0</jedis.version>
              </properties>
              <dependencies>
              <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-web</artifactId>
              </dependency>
              <!-- 阿里云通义千问(DashScope)starter -->
              <dependency>
              <groupId>com.alibaba.cloud.ai</groupId>
              <artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
              </dependency>
              <!--对话记忆 chat-memory-->
              <dependency>
              <groupId>org.springframework.ai</groupId>
              <artifactId>spring-ai-autoconfigure-model-chat-memory</artifactId>
              </dependency>
                <!-- Spring Security 依赖 -->
                <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-security</artifactId>
                </dependency>

              </dependencies>
              <dependencyManagement>
              <dependencies>
              <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-dependencies</artifactId>
              <version>${spring-boot.version}</version>
              <type>pom</type>
              <scope>import</scope>
              </dependency>
              <!-- 统一管理Spring AI依赖版本 -->
              <dependency>
              <groupId>org.springframework.ai</groupId>
              <artifactId>spring-ai-bom</artifactId>
              <version>${spring-ai.version}</version>
              <type>pom</type>
              <scope>import</scope>
              </dependency>
              <dependency>
              <groupId>com.alibaba.cloud.ai</groupId>
              <artifactId>spring-ai-alibaba-bom</artifactId>
              <version>${spring-ai-alibaba.version}</version>
              <type>pom</type>
              <scope>import</scope>
              </dependency>
              </dependencies>
              </dependencyManagement>
              <!-- Spring AI 里程碑/快照仓库(必须配置,否则依赖无法下载) -->
              <repositories>
              <repository>
              <id>spring-milestones</id>
              <name>Spring Milestones</name>
              <url>https://repo.spring.io/milestone</url>
              <snapshots>
              <enabled>false</enabled>
              </snapshots>
              </repository>
              <repository>
              <id>spring-snapshots</id>
              <name>Spring Snapshots</name>
              <url>https://repo.spring.io/snapshot</url>
              <releases>
              <enabled>false</enabled>
              </releases>
              </repository>
              </repositories>


              2、yml
              server:
              port: 18086
              spring:
              ai:
              dashscope:
              api-key: sk-8718a83408d7443xxxxxxxxx





              3、config
              import org.springframework.context.annotation.Bean;
              import org.springframework.context.annotation.Configuration;
              import org.springframework.security.config.Customizer;
              import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
              import org.springframework.security.config.annotation.web.builders.HttpSecurity;
              import org.springframework.security.config.annotation.web.configurers.FormLoginConfigurer;
              import org.springframework.security.core.userdetails.User;
              import org.springframework.security.core.userdetails.UserDetails;
              import org.springframework.security.core.userdetails.UserDetailsService;
              import org.springframework.security.crypto.password.NoOpPasswordEncoder;
              import org.springframework.security.crypto.password.PasswordEncoder;
              import org.springframework.security.provisioning.InMemoryUserDetailsManager;
              import org.springframework.security.web.SecurityFilterChain;

              @Configuration
              @EnableMethodSecurity
              public class SecurityConfig {
              @Bean
              public UserDetailsService userDetailsService() {
              UserDetails user = User.withUsername("user1")
              .password("pass1").roles("USER").build();
              UserDetails admin = User.withUsername("admin")
              .password("pass2").roles("ADMIN").build();

              return new InMemoryUserDetailsManager(user, admin);
              }

              @Bean
              public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
              http
              .authorizeHttpRequests(authz -> authz
              // 放行 /tool 接口,让AI对话可访问
              .requestMatchers("/tool").permitAll()
              // 其他请求需认证
              .anyRequest().authenticated()
              ).with(new FormLoginConfigurer<>(),Customizer.withDefaults());
              return http.build();
              }

              // 仅测试用。生产请使用更安全的加密方式
              @Bean
              public static org.springframework.security.crypto.password.PasswordEncoder
              passwordEncoder() {
              return NoOpPasswordEncoder.getInstance();
              }
              }





              4、service
              import org.springframework.stereotype.Service;

              //票务服务
              @Service
              public class TicketService {

              //退票
              public void cancel(String ticketNumber, String name) {
              // 实际业务逻辑:调用数据库/API执行退票
              System.out.println("退票成果");
              }
              }


               
              import org.springframework.ai.tool.ToolCallback;
              import org.springframework.ai.tool.annotation.Tool;
              import org.springframework.ai.tool.annotation.ToolParam;
              import org.springframework.ai.tool.definition.ToolDefinition;
              import org.springframework.ai.tool.method.MethodToolCallback;
              import org.springframework.beans.factory.annotation.Autowired;
              import org.springframework.security.access.prepost.PreAuthorize;
              import org.springframework.security.core.context.SecurityContextHolder;
              import org.springframework.stereotype.Service;
              import org.springframework.util.ReflectionUtils;
              import java.lang.reflect.Method;
              import java.util.List;

              @Service
              public class ToolService {

              @Autowired
              private TicketService ticketService;
              //
              // record cancelParam(String dsadsa,String fdasfda){}
              //
              // @Tool(description = "退票")
              // public String cancel(cancelParam param) {
              // ticketService.cancel(param.dsadsa(), param.fdasfda());
              // return "退票成功!";
              // }


              // record cancelParam(String mmmmmmmmmmqweqweqw,String oooooooooodsfsdds){}
              //
              // // @Tool告诉大模型提供了什么工具
              // @Tool(description = "根据订单号和乘客姓名办理机票退票业务,退票成功后会返还票款")
              // public String cancel(
              // //@ToolParam告诉大模型参数描述
              // cancelParam param) {
              // //先查询--->先校验
              // ticketService.cancel(param.mmmmmmmmmmqweqweqw(), param.oooooooooodsfsdds());
              // return "退票成功!";
              // }

              //record cancelParam(String ticketNumber,String name){}

              // @Tool告诉大模型提供了什么工具
              // @Tool(description = "退票")
              // public String cancel(
              // //@ToolParam告诉大模型参数描述
              // cancelParam param) {
              // //先查询--->先校验
              // ticketService.cancel(param.ticketNumber(), param.name());
              // return "退票成功!";
              // }

              // @Tool(description = "退票")
              // public String cancel(
              // //@TooLParam告诉大模型参数的描述 加严参数描述与校验
              // @ToolParam(description = "预定号,可以是纯数字") String ticketNumber,
              // @ToolParam(description = "真实人名(必填,必须为人的真实姓名,严禁用其他信息代替如缺失请传null)") String name) {
              // // 后端代码加强校验和兜底保护
              // //先查询--->先校验
              // ticketService.cancel(ticketNumber, name);
              // return "退票成功!";
              // }

              record cancelParam(String ticketNumber,String name){}

              // @Tool告诉大模型提供了什么工具
              @Tool(description = "退票")
              @PreAuthorize("hasRole('ADMIN')")
              public String cancel(
              //@TooLParam告诉大模型参数的描述 加严参数描述与校验
              @ToolParam(description = "预定号,可以是纯数字") String ticketNumber,
              @ToolParam(description = "真实人名(必填,必须为人的真实姓名,严禁用其他信息代替如缺失请传null)") String name) {
              // 后端代码加强校验和兜底保护
              // 获取当前登录用户信息
              String username = SecurityContextHolder.getContext()
              .getAuthentication()
              .getName();
              //先查询--->先校验
              ticketService.cancel(ticketNumber, name);
              return username + "退票成功!";
              }

              @Tool(description = "获取指定位置的天气,根据位置自动推算经纬度")
              public String getAirQuality(
              @ToolParam(description = "纬度") double latitude,
              @ToolParam(description = "经度") double longitude) {
              return "天晴";
              }

              /**
              * 模拟从数据库中动态根据当前用户角色读取tooLs
              * @param toolService
              * @return
              */
              public List<ToolCallback> getToolCallList(ToolService toolService) {
              //1.获取tools处理的方法
              Method method = ReflectionUtils.findMethod(ToolService.class,
              "cancel", String.class, String.class);
              //2.构建Tool定义信息 动态配置的方式@Tool @Toop
              ToolDefinition build = ToolDefinition.builder()
              .name("cancel")
              .description("退票")
              //对应@ToolParam
              .inputSchema("""
              {
              "type": "object",
              "properties": {
              "ticketNumber": {
              "type": "string",
              "description": "预定号,可以是纯数字"
              },
              "name": {
              "type": "string",
              "description": "真实人名"
              }
              },
              "required": ["ticketNumber", "name"]
              }
              """)
              .build();
              //一个Toolcallback对应一个tool
              ToolCallback toolCallback = MethodToolCallback.builder()
              .toolDefinition(build)
              .toolMethod(method)
              .toolObject(toolService) // 不能自己new,自己new不能解析依赖注
              .build();
              return List.of(toolCallback);

              }

              }





               

              5、controller
               
              
              
              import com.sb.dashscope18086.service.ToolService;
              import org.springframework.ai.chat.client.ChatClient;
              import org.springframework.beans.factory.annotation.Autowired;
              import org.springframework.stereotype.Controller;
              import org.springframework.web.bind.annotation.GetMapping;
              import org.springframework.web.bind.annotation.RequestMapping;
              import org.springframework.web.bind.annotation.RequestParam;
              import org.springframework.web.bind.annotation.ResponseBody;

              /**
              * @author Administrator
              */
              @RequestMapping("/openai")
              @ResponseBody
              @Controller
              public class ChatclientToolController {

              @Autowired
              private ChatClient.Builder chatClientBuilder;
              //
              @Autowired
              private ToolService toolService;

              // ChatClient chatClient;
              //
              // public ChatclientToolController(ChatClient.Builder chatClientBuilder, ToolService toolService) {
              // chatClient= chatClientBuilder
              // .defaultTools(toolService)
              // .build();
              // }

              @GetMapping("/simple/tool5")
              public String tool5(
              @RequestParam(value = "message",
              defaultValue = "讲个笑话") String message
              ) {
              // // 构建ChatClient并调用
              ChatClient chatClient = chatClientBuilder
              //
              //系统Prompt设定限制
              .build();
              String content = chatClient.prompt()
              .user(message)
              //.tools(toolService)//用 .tools() 替代 defaultTools()
              // .tools(toolService) 和 .toolCallbacks(...) 同时调用了,导致同一个 cancel 工具被注册了两次.
              //,触发了 Multiple tools with the same name 错误
              .toolCallbacks(toolService.getToolCallList(toolService))
              .call()
              .content();

              System.out.println(content);
              return content;
              }

              @GetMapping("/simple/tool6")
              public String tool6(
              @RequestParam(value = "message",
              defaultValue = "讲个笑话") String message
              ) {
              // // 构建ChatClient并调用
              ChatClient chatClient = chatClientBuilder
              //
              //系统Prompt设定限制
              .defaultSystem("""
              # 角色
              你是智能航空客服助手
              ## 要求
              "严禁随意补全或猜测工具调用参数。 参数如缺失或语义不准,请不要补充或随意传递,请直接放弃本次工具调用。"
              """)
              //.defaultTools(toolService)
              .build();
              String content = chatClient.prompt()
              .user(message)
              // .tools(toolService) 和 .toolCallbacks(...) 同时调用了,导致同一个 cancel 工具被注册了两次.
              //,触发了 Multiple tools with the same name 错误
              //.tools(toolService)//用 .tools() 替代 defaultTools()
              .toolCallbacks(toolService.getToolCallList(toolService))
              .call()
              .content();

              System.out.println(content);
              return content;
              }
              }







              import com.sb.dashscope18086.service.ToolService;
              import org.springframework.ai.chat.client.ChatClient;
              import org.springframework.stereotype.Controller;
              import org.springframework.web.bind.annotation.GetMapping;
              import org.springframework.web.bind.annotation.RequestMapping;
              import org.springframework.web.bind.annotation.RequestParam;
              import org.springframework.web.bind.annotation.ResponseBody;

              /**
              * @author Administrator
              */
              @RequestMapping("/openai")
              @ResponseBody
              @Controller
              public class ChatclientToolControllertest {
              // @Autowired
              // private ChatClient.Builder chatClientBuilder;
              // //
              // @Autowired
              // private ToolService toolService;

              ChatClient chatClient;

              public ChatclientToolControllertest(ChatClient.Builder chatClientBuilder, ToolService toolService) {
              chatClient= chatClientBuilder
              .defaultSystem("""
              # 角色
              你是智能航空客服助手
              ## 要求
              "严禁随意补全或猜测工具调用参数。 参数如缺失或语义不准,请不要补充或随意传递,请直接放弃本次工具调用。"
              """)
              //.defaultTools(toolService)
              //动态tooL设置defaultToolCallbacks
              // .tools(toolService) 和 .toolCallbacks(...) 同时调用了,导致同一个 cancel 工具被注册了两次.
              //,触发了 Multiple tools with the same name 错误
              .defaultToolCallbacks(toolService.getToolCallList(toolService))
              .build();
              }

              @GetMapping("/simple/tool7")
              public String tool7(
              @RequestParam(value = "message",
              defaultValue = "讲个笑话") String message
              ) {
              // // 构建ChatClient并调用
              // ChatClient chatClient = chatClientBuilder
              // //
              // //系统Prompt设定限制
              // .build();
              String content = chatClient.prompt()
              .user(message)
              //.tools(toolService)//用 .tools() 替代 defaultTools()
              .call()
              .content();

              System.out.println(content);
              return content;
              }


              }






              6、
              6.1 先登录

              image

               


              6.2
              http://localhost:18086/openai/simple/tool5?message=退票.赖宁.101991

              image

               

              6.3

              http://localhost:18086/openai/simple/tool6?message=退票.柴荣.B88801

              image

               


              6.4
              http://localhost:18086/openai/simple/tool7?message=退票.周太祖.10101

              image

               



posted on 2026-05-25 16:54  cn2025  阅读(5)  评论(0)    收藏  举报