Spring AI Alibaba使用

Spring AI Alibaba使用

起男 101 2025-04-03

Spring AI Alibaba使用

简单访问

导入依赖

        <dependency>
            <groupId>com.alibaba.cloud.ai</groupId>
            <artifactId>spring-ai-alibaba-starter</artifactId>
            <version>1.0.0-M5.1</version>
        </dependency>

如果中央仓库找不到则添加:

    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

配置文件

spring:
  ai:
    dashscope:
      api-key: XXXX
      chat:
        options:
          model: qwen-plus

controller

@RestController
@RequestMapping("/ai")
public class ChatController {
    @Autowired
    @Qualifier("dashscopeChatModel")
    private ChatModel chatModel;

    @GetMapping("chat/{message}")
    public String chat(@PathVariable String message){
        return chatModel.call(message);
    }
    
    @GetMapping("chat2/{message}")
    public String chat2(@PathVariable String message){
        ChatClient chatClient = ChatClient.create(chatModel);
        return chatClient.prompt()
                .user(message)
                .call()
                .content();
    }
}

流式输出

    @GetMapping(value = "stream/{message}",produces = "text/stream;charset=UTF-8")
    public Flux<String> stream(@PathVariable String message){
        return chatModel.stream(message);
    }

定制化访问

    @GetMapping("/opt/{message}")
    public String opt(@PathVariable String message) {
        DashScopeChatOptions options = DashScopeChatOptions.builder()
                .withTopK(1024)
                .withTemperature(0.7)
                .withModel("deepseek-r1")
                .build();
        return chatModel.call(new Prompt(message,options)).getResult().getOutput().getText();
    }

角色预设

@RestController
@RequestMapping("ai")
public class AIController {

    private final ChatClient client;

    public AIController(ChatClient.Builder builder, ChatMemory memory) {
        this.client = builder
                .defaultSystem("""
                        你是一个航空公司的客服,请以友好且乐于助人的方式来回复
                        今天的日期是{current_date}
                        在提供预定或取消预定之前,必须获取用户姓名和手机号
                        询问之前检查历史是否已经获取消息
                        """)
                .build();
    }

    @GetMapping("chat/{message}")
    public String chat(@PathVariable String message) {
        return client.prompt()
                .user(message)
                .system(promptSystemSpec ->
                        promptSystemSpec.param("current_date", LocalDate.now().toString()))//传递参数
                .call()
                .content();
    }
}

结构化输出

简单对象

    @GetMapping("entity/{message}")
    public production entity(@PathVariable String message){
        return ChatClient.builder(chatModel).build()
                .prompt()
                .user(message)
                .call()
                .entity(production.class);
    }

集合对象

    @GetMapping("list/{message}")
    public List<production> list(@PathVariable String message){
        return ChatClient.builder(chatModel).build()
                .prompt()
                .user(message)
                .call()
                .entity(new ParameterizedTypeReference<List<production>>() {});
    }

对话记忆

添加配置

	//存储位置
	@Bean
    public ChatMemory chatMemory(){
        return new InMemoryChatMemory();//内存
    }

controller

@RestController
@RequestMapping("ai")
public class AIController {

    private final ChatClient client;

    public AIController(ChatClient.Builder builder, ChatMemory memory) {
        this.client = builder
                .defaultAdvisors(new PromptChatMemoryAdvisor(memory))
                .build();
    }

    @GetMapping("chat/{message}")
    public String chat(@PathVariable String message) {
        return client.prompt()
                .user(message)
                .advisors(advisorSpec -> advisorSpec.param(AbstractChatMemoryAdvisor.CHAT_MEMORY_RETRIEVE_SIZE_KEY,10))//控制记忆的数量
                .call()
                .content();
    }
}

使用Ollama

导入依赖

        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-ollama-spring-boot-starter</artifactId>
            <version>1.0.0-M6</version>
        </dependency>

添加配置

spring:
  ai:
    ollama:
      base-url: http://localhost:11434
      chat:
        model: deepseek-r1:14b

controller

@RestController
@RequestMapping("ollama")
public class OllamaController {
    @Autowired
    @Qualifier("ollamaChatModel")
    private ChatModel chatModel;

    @GetMapping("chat/{message}")
    public String chat(@PathVariable String message) {
        return chatModel.call(message);
    }
}

生成图片

添加配置

spring:
  ai:
    dashscope:
      api-key: xxxx
      image:
        options:
          model: wanx2.1-t2i-turbo

controller

@Controller
@RequestMapping("image")
public class ImageController {

    @Autowired
    @Qualifier("dashScopeImageModel")
    private ImageModel imageModel;

    @GetMapping("{message}")
    public String image(@PathVariable("message") String message) {
        ImagePrompt ip = new ImagePrompt(message);
        ImageResponse response = imageModel.call(ip);
        return "redirect:"+response.getResult().getOutput().getUrl();
    }

    @GetMapping("opt/{message}")
    public String option(@PathVariable("message") String message) {
        ImageOptions options = ImageOptionsBuilder.builder()
                .model("wanx2.1-t2i-turbo")
                .width(1024)
                .height(1024)
                .build();
        ImagePrompt ip = new ImagePrompt(message,options);
        ImageResponse response = imageModel.call(ip);
        return "redirect:"+response.getResult().getOutput().getUrl();
    }
}

向量模型

@RestController
@RequestMapping("embedding")
public class EmbeddingController {
    @Autowired
    @Qualifier("dashscopeEmbeddingModel")
    private EmbeddingModel embeddingModel;

    @GetMapping("emb1/{message}")
    public Object emb1(@PathVariable String message) {
        return embeddingModel.embed(message);
    }
}

function call

tool

    public record Reserve(String name,String phoneNumber){

    }

    @Bean
    @Description("处理预定")
    public Function<Reserve,String> reserve(){
        return reserve -> {
            System.out.println(reserve.name());
            System.out.println(reserve.phoneNumber());
            return "预定成功";
        };
    }

controller

@RestController
@RequestMapping("ai")
public class AIController {

    private final ChatClient client;

    public AIController(ChatClient.Builder builder, ChatMemory memory) {
        this.client = builder
                .defaultFunctions("reserve")//指定使用的tool的bean名称
                .build();
    }

    @GetMapping("chat/{message}")
    public String chat(@PathVariable String message) {
        return client.prompt()
                .user(message)
                .call()
                .content();
    }
}

RAG

配置向量数据库

    @Bean
    public VectorStore vectorStore(EmbeddingModel model){
        return new SimpleVectorStore(model);
    }

初始化数据

    @Bean
    CommandLineRunner commandLineRunner(VectorStore vectorStore,
                                        @Value("classpath:rag/t1.txt") Resource resource){
        return args -> {
            vectorStore.write( //写入
                    new TokenTextSplitter().transform( //转换
                            new TextReader(resource).read() //读取
                    )
            );
        };
    }

controller

    @Autowired
    private VectorStore vectorStore;

    @GetMapping("chat/{message}")
    public String chat(@PathVariable String message) {
        return client.prompt()
                .user(message)
                .advisors(new QuestionAnswerAdvisor(vectorStore,SearchRequest.builder().query(message).build()))//查询条件
                .call()
                .content();
    }