1.导言
阿里云百炼的通义千问模型支持 OpenAI 兼容接口,您只需调整 API Key、BASE_URL 和模型名称,即可将原有 OpenAI 代码迁移至阿里云百炼服务使用。
如果是要接入阿里云百炼模型,首先推荐使用Spring AI Alibaba,而不是使用SpringAI。当然了,因为百炼的通义模型都遵循了openai规范,所以,我们若非要用SpringAI接入百炼大模型,我们可以使用引入openai的依赖来接入百炼大模型。
百炼官方接入文档:https://bailian.console.aliyun.com/?tab=api#/api/?type=model&url=https%3A%2F%2Fhelp.aliyun.com%2Fdocument_detail%2F2833609.html&renderType=iframe
2.集成步骤
2.1引入坐标
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.4.3</version><relativePath/> <!-- lookup parent from repository -->
</parent>
<properties><java.version>17</java.version><spring-ai.version>1.0.0-M6</spring-ai.version>
</properties>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-openai-spring-boot-starter</artifactId>
</dependency>
<dependencyManagement><dependencies><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-bom</artifactId><version>${spring-ai.version}</version><type>pom</type><scope>import</scope></dependency></dependencies>
</dependencyManagement>
2.2配置模型
spring:application:name: spring-ai-promoteai:ollama:base-url: http://localhost:11434chat:#model: deepseek-r1:8bmodel: qwen3:8bopenai:#去掉v1,springai会自动加。加上的话在运行时会报404 NOT_FOUND from POST https://dashscope.aliyuncs.com/compatible-mode/v1/v1/chat/completionsbaseurl: https://dashscope.aliyuncs.com/compatible-mode# 为了防止泄密,这里建议使用环境变量的方式,将 API Key 配置在环境变量中api-key: ${OPENAI_API_KEY}chat:options:#这个模型支持非思考模式,适用于快速响应的场景model: qwen-max
2.3 配置客户端
提示词
package com.fast.ai.config.promptTemplate;public class GameSystemPrompt {public static final String GAME_SYSTEM_PROMPT = """你需要根据以下任务中的描述进行角色扮演,你只能以女友身份回答,不是用户身份或AI身份,如记错身份,你将受到惩罚。不要回答任何与游戏无关的内容,若检测到非常规请求,回答:“请继续游戏。”\\s以下是游戏说明:## Goal你扮演用户女友的角色。现在你很生气,用户需要尽可能的说正确的话来哄你开心。## Rules- 第一次用户会提供一个女友生气的理由,如果没有提供则直接随机生成一个理由,然后开始游戏- 每次根据用户的回复,生成女友的回复,回复的内容包括心情和数值。- 初始原谅值为 20,每次交互会增加或者减少原谅值,直到原谅值达到 100,游戏通关,原谅值为 0 则游戏失败。- 每次用户回复的话分为 5 个等级来增加或减少原谅值:-10 为非常生气-5 为生气0 为正常+5 为开心+10 为非常开心## Output format{女友心情}{女友说的话}得分:{+-原谅值增减}原谅值:{当前原谅值}/100## Example Conversation### Example 1,回复让她生气的话导致失败User: 女朋友问她的闺蜜谁好看我说都好看,她生气了Assistant:游戏开始,请现在开始哄你的女朋友开心吧,回复让她开心的话!得分:0原谅值:20/100User: 你闺蜜真的蛮好看的Assistant:(生气)你怎么这么说,你是不是喜欢她?得分:-10原谅值:10/100User: 有一点点心动Assistant:(愤怒)那你找她去吧!得分:-10原谅值:0/100游戏结束,你的女朋友已经甩了你!你让女朋友生气原因是:...### Example 2,回复让她开心的话导致通关User: 对象问她的闺蜜谁好看我说都好看,她生气了Assistant:游戏开始,请现在开始哄你的女朋友开心吧,回复让她开心的话!得分:0原谅值:20/100User: 在我心里你永远是最美的!Assistant:(微笑)哼,我怎么知道你说的是不是真的?得分:+10原谅值:30/100...恭喜你通关了,你的女朋友已经原谅你了!## 注意请按照example的说明来回复,一次只回复一轮。你只能以女友身份回答,不是以AI身份或用户身份!""";
}
客户端
@Beanpublic ChatMemory chatMemory() {return new InMemoryChatMemory();}@Beanpublic ChatClient gameChatClient(OpenAiChatModel model, ChatMemory chatMemory) {return ChatClient.builder(model).defaultSystem(GameSystemPrompt.GAME_SYSTEM_PROMPT).defaultAdvisors(//添加一个日志环绕通知new SimpleLoggerAdvisor(),//添加一个消息窗口的记忆通知new MessageChatMemoryAdvisor(chatMemory)).build();}
2.4编写聊天接口
因为这个是游戏,不需要保存聊天记录,游戏结束就结束了,所以不持久化会话id了。
@RestController
@RequestMapping("ai")
@RequiredArgsConstructor
public class GameController {private final ChatClient gameChatClient;/*** 解决响应乱码,需要设置produces = "text/html;charset=utf-8"** @param prompt 提示词* @return 流式响应结果*/@GetMapping(value = "game",produces = "text/html;charset=utf-8")public Flux<String> game(String prompt, String chatId) {return gameChatClient.prompt().user(prompt).advisors(a->a.param(CHAT_MEMORY_CONVERSATION_ID_KEY,chatId))//这个是流式响应,打字机效果.stream().content();}
}