2 Commits

  1. BIN
      黄永兴学习笔记/4.1黄永兴-项目案例笔记.docx
  2. 3
      黄永兴学习笔记/智能客服demo/SpringAIAlibaba/.mvn/wrapper/maven-wrapper.properties
  3. 10
      黄永兴学习笔记/智能客服demo/SpringAIAlibaba/SpringAIAlibaba.iml
  4. 127
      黄永兴学习笔记/智能客服demo/SpringAIAlibaba/pom.xml
  5. 13
      黄永兴学习笔记/智能客服demo/SpringAIAlibaba/src/main/java/com/example/springaialibaba/SpringAiAlibabaApplication.java
  6. 177
      黄永兴学习笔记/智能客服demo/SpringAIAlibaba/src/main/java/com/example/springaialibaba/controller/CustomerServiceController.java
  7. 13
      黄永兴学习笔记/智能客服demo/SpringAIAlibaba/src/main/resources/application.yml
  8. 13
      黄永兴学习笔记/智能客服demo/SpringAIAlibaba/src/test/java/com/example/springaialibaba/SpringAiAlibabaApplicationTests.java
  9. 13
      黄永兴学习笔记/智能客服demo/SpringAIAlibaba/target/classes/application.yml
  10. BIN
      黄永兴学习笔记/智能客服demo/SpringAIAlibaba/target/classes/com/example/springaialibaba/SpringAiAlibabaApplication.class
  11. BIN
      黄永兴学习笔记/智能客服demo/SpringAIAlibaba/target/classes/com/example/springaialibaba/controller/CustomerServiceController.class
  12. BIN
      黄永兴学习笔记/智能客服demo/SpringAIAlibaba/target/test-classes/com/example/springaialibaba/SpringAiAlibabaApplicationTests.class

BIN
黄永兴学习笔记/4.1黄永兴-项目案例笔记.docx

3
黄永兴学习笔记/智能客服demo/SpringAIAlibaba/.mvn/wrapper/maven-wrapper.properties

@ -0,0 +1,3 @@
wrapperVersion=3.3.4
distributionType=only-script
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.14/apache-maven-3.9.14-bin.zip

10
黄永兴学习笔记/智能客服demo/SpringAIAlibaba/SpringAIAlibaba.iml

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
<component name="AdditionalModuleElements">
<content url="file://$MODULE_DIR$" dumb="true">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
</content>
</component>
</module>

127
黄永兴学习笔记/智能客服demo/SpringAIAlibaba/pom.xml

@ -0,0 +1,127 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.13</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>SpringAIAlibaba</artifactId>
<version>1.1.2.0</version>
<name>SpringAIAlibaba</name>
<description>SpringAIAlibaba</description>
<properties>
<java.version>17</java.version>
<!-- 阿里云DashScope SDK版本(官方要求>=2.15.0) -->
<dashscope.version>2.22.13</dashscope.version>
<!-- RxJava版本(适配DashScope SDK) -->
<rxjava.version>2.2.21</rxjava.version>
</properties>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-bom</artifactId>
<version>1.1.2.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>1.1.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-extensions-bom</artifactId>
<version>1.1.2.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- Spring AI Alibaba Agent Framework -->
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-agent-framework</artifactId>
<version>1.1.2.0</version>
</dependency>
<!-- DashScope ChatModel 支持(如果使用其他模型,请跳转 Spring AI 文档选择对应的 starter) -->
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
<version>1.1.2.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>io.projectreactor.addons</groupId>
<artifactId>reactor-adapter</artifactId>
<version>3.5.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- 1. 阿里云DashScope官方SDK(解决所有dashscope包报红) -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dashscope-sdk-java</artifactId>
<version>${dashscope.version}</version>
</dependency>
<!-- 2. RxJava 2.x(解决io.reactivex.Flowable报红) -->
<dependency>
<groupId>io.reactivex.rxjava2</groupId>
<artifactId>rxjava</artifactId>
<version>${rxjava.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

13
黄永兴学习笔记/智能客服demo/SpringAIAlibaba/src/main/java/com/example/springaialibaba/SpringAiAlibabaApplication.java

@ -0,0 +1,13 @@
package com.example.springaialibaba;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringAiAlibabaApplication {
public static void main(String[] args) {
SpringApplication.run(SpringAiAlibabaApplication.class, args);
}
}

177
黄永兴学习笔记/智能客服demo/SpringAIAlibaba/src/main/java/com/example/springaialibaba/controller/CustomerServiceController.java

@ -0,0 +1,177 @@
package com.example.springaialibaba.controller;
import com.alibaba.cloud.ai.dashscope.agent.DashScopeAgent;
import com.alibaba.cloud.ai.dashscope.agent.DashScopeAgentOptions;
import com.alibaba.dashscope.app.Application;
import com.alibaba.dashscope.app.ApplicationParam;
import com.alibaba.dashscope.app.ApplicationResult;
import com.alibaba.dashscope.app.FlowStreamMode;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import io.reactivex.Flowable;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.http.MediaType;
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.RestController;
import reactor.adapter.rxjava.RxJava2Adapter;
import reactor.core.publisher.Flux;
import java.nio.charset.StandardCharsets;
@Slf4j
@RestController
@RequiredArgsConstructor //使用RequiredArgsConstructor注解自动注入final类型的字段
@RequestMapping("/customer")
public class CustomerServiceController {
//注入Spring AI Alibaba Agent
//@Autowired
private final DashScopeAgent dashScopeAgent;
/**
* 智能客服接口非流式同步获取结果
* @param question 用户问题
* @return 知识库标准答案
*/
@GetMapping("/service")
public String customerService(@RequestParam("question") String question) {
try {
/*
DashScopeAgentOptions 是工作流 / 智能体的调用参数它只负责触发工作流不负责修改大模型的推理参数
因为 Spring AI Alibaba 的自动配置在工作流Agent模式下不生效
*/
//
/* ChatResponse response = dashScopeAgent.call(
new Prompt(question, DashScopeAgentOptions.builder()
.appId("df04e1abf24a416c8702260e88863ac4")
.build()
)
);
return response.getResult().getOutput().getText();*/
ApplicationParam param = ApplicationParam.builder()
// 若没有配置环境变量可用百炼API Key将下行替换为.apiKey("sk-xxx")但不建议在生产环境中直接将API Key硬编码到代码中以减少API Key泄露风险
.apiKey(System.getenv("sk-f7d2253302b547c7a2fe257673cb854b"))
.appId("df04e1abf24a416c8702260e88863ac4")
.prompt(question)
.build();
Application application = new Application();
ApplicationResult result = application.call(param);
return result.getOutput().getText();
} catch (Exception e) {
log.error("客服调用失败", e);
return "抱歉,智能客服暂时无法响应,请联系人工客服。";
}
}
// 官方原生流式调用1:1对照文档
@GetMapping(value = "/service2", produces = MediaType.TEXT_HTML_VALUE + ";charset=UTF-8")
public Flux<String> customerService2(
@RequestParam("question") String question,
HttpServletResponse response
) {
//设置字符编码为UTF-8,解决中文乱码问题
response.setCharacterEncoding("UTF-8");
try {
// ==============================================
// 官方原版写法
// ==============================================
ApplicationParam param = ApplicationParam.builder()
.apiKey("sk-f7d2253302b547c7a2fe257673cb854b") // 你的API Key
.appId("df04e1abf24a416c8702260e88863ac4")
.prompt(question)
.incrementalOutput(true) // 官方流式必须开
.flowStreamMode(FlowStreamMode.MESSAGE_FORMAT) // 设置为流模式
.build();
Application application = new Application();
// 官方流式调用
Flowable<ApplicationResult> resultFlowable = application.streamCall(param);
// RxJava Flowable Spring Flux用于SSE输出
// 正确的流式处理逻辑
System.out.println(resultFlowable);
/* return Flux.create(sink -> {
resultFlowable.subscribe(
res -> {
try {
if (res != null && res.getOutput() != null) {
String content = null;
if ("stop".equals(res.getOutput().getFinishReason())) {
// 流结束
content = res.getOutput().getText();
if (content != null && !content.trim().isEmpty()) {
sink.next("data: " + content + "\n\n");
}
} else {
// 流式输出
if (res.getOutput().getWorkflowMessage() != null &&
res.getOutput().getWorkflowMessage().getMessage() != null) {
content = res.getOutput().getWorkflowMessage()
.getMessage().getContent();
if (content != null && !content.trim().isEmpty()) {
sink.next("data: " + content + "\n\n");
}
}
}
}
} catch (Exception e) {
log.error("处理响应异常", e);
}
},
error -> {
log.error("流式调用异常", error);
sink.next("data: 服务调用异常\n\n");
sink.complete();
},
() -> {
log.info("流式调用完成");
sink.complete();
}
);
});*/
// RxJava适配器 flowable 转换为 flux
return RxJava2Adapter.flowableToFlux(resultFlowable)
.map(this::extractContent)
.filter(content -> content != null && !content.trim().isEmpty())
.map(content -> "data: " + content + "\n\n");
} catch (Exception e) {
log.error("客服调用失败", e);
return Flux.error(e);
}
}
// ApplicationResult 中提取内容
private String extractContent(ApplicationResult res) {
if (res == null || res.getOutput() == null) return null;
if ("stop".equals(res.getOutput().getFinishReason())) {
return res.getOutput().getText();
} else if (res.getOutput().getWorkflowMessage() != null &&
res.getOutput().getWorkflowMessage().getMessage() != null) {
return res.getOutput().getWorkflowMessage().getMessage().getContent();
}
return null;
}
}

13
黄永兴学习笔记/智能客服demo/SpringAIAlibaba/src/main/resources/application.yml

@ -0,0 +1,13 @@
server:
port: 8080
spring:
ai:
dashscope:
# 核心:工作流应用的AppId
agent:
app-id: df04e1abf24a416c8702260e88863ac4
# 核心:你的API-Key
api-key: sk-f7d2253302b547c7a2fe257673cb854b
# 业务空间ID
workspace-id: llm-fuczq7vkh8vyz716

13
黄永兴学习笔记/智能客服demo/SpringAIAlibaba/src/test/java/com/example/springaialibaba/SpringAiAlibabaApplicationTests.java

@ -0,0 +1,13 @@
package com.example.springaialibaba;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class SpringAiAlibabaApplicationTests {
@Test
void contextLoads() {
}
}

13
黄永兴学习笔记/智能客服demo/SpringAIAlibaba/target/classes/application.yml

@ -0,0 +1,13 @@
server:
port: 8080
spring:
ai:
dashscope:
# 核心:工作流应用的AppId
agent:
app-id: df04e1abf24a416c8702260e88863ac4
# 核心:你的API-Key
api-key: sk-f7d2253302b547c7a2fe257673cb854b
# 业务空间ID
workspace-id: llm-fuczq7vkh8vyz716

BIN
黄永兴学习笔记/智能客服demo/SpringAIAlibaba/target/classes/com/example/springaialibaba/SpringAiAlibabaApplication.class

BIN
黄永兴学习笔记/智能客服demo/SpringAIAlibaba/target/classes/com/example/springaialibaba/controller/CustomerServiceController.class

BIN
黄永兴学习笔记/智能客服demo/SpringAIAlibaba/target/test-classes/com/example/springaialibaba/SpringAiAlibabaApplicationTests.class

Loading…
Cancel
Save