SpringBoot和Vue3实战阿里百炼大模型极简版

实战效果

刚开始用ppt录制的视频,导进来有声音,又通过视频转gif网站转成了图片

支持markdown格式显示,流式调用

前期准备

阿里云百炼控制台申请apikey和创建智能体应用得到appid,并配置到系统环境变量。

同时要注意使用的模型用量,记得开启免费额度用完即停

一个模型免费额度用完了可以到应用配置里切换成其他模型,同时在智能体应用配置里可以做两个配置,最大回复token可以改小一点,这样测试的次数会多一点。同时关闭自主思考enbale thinking,这样流式调用返回的结果会快一点

后端代码

jdk使用17版本,电脑是win7系统,IDEA版本是2021.3

控制器

java 复制代码
package com.xmliu.alidemo;

import com.alibaba.cloud.ai.dashscope.agent.DashScopeAgent;
import com.alibaba.cloud.ai.dashscope.agent.DashScopeAgentOptions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.chat.messages.AssistantMessage;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

@RestController
@RequestMapping("/ai")
public class BailianStreamController {

    private static final Logger logger = LoggerFactory.getLogger(BailianStreamController.class);
    private DashScopeAgent agent;

    @Value("${spring.ai.dashscope.agent.app-id}")
    private String appId;

    @CrossOrigin(origins = "http://localhost:3000")
    @GetMapping(value = "/bailian/agent/stream", produces = "text/event-stream;charset=UTF-8")
    public Flux<String> stream(@RequestParam(value = "message",
            defaultValue = "知识库文档主要内容是什么?") String message) {
        logger.info("----开始流式聊天----");
        return agent.stream(new Prompt(message, DashScopeAgentOptions.builder().withAppId(appId).build()))
                .map(response -> {
                    if (response == null || response.getResult() == null) {
                        logger.error("chat response is null");
                        // 空响应返回空串,最后统一处理
                        return "";
                    }
                    AssistantMessage app_output = response.getResult().getOutput();
                    String content = app_output.getText();
                    logger.info("content:\n{}\n\n", content);
                    return content != null ? content : "";
                })
                // 过滤空字符串
                .filter(content -> !content.isBlank())
                // 流结束追加标识
                .concatWith(Mono.just("data:__STREAM_END__"));
    }
}

配置文件

application.properties,其中appid和key配置在系统环境变量中,故代码里看不到具体的值

xml 复制代码
spring.application.name=alidemo
# appID
spring.ai.dashscope.agent.app-id=${APP_ID}
spring.ai.dashscope.agent.connect-timeout=30000
spring.ai.dashscope.agent.read-timeout=30000
# API Key
spring.ai.dashscope.api-key=${DASHSCOPE_API_KEY}
spring.ai.dashscope.logging.request-response=true

server.tomcat.connection-timeout=30000
server.servlet.session.timeout=30m
server.servlet.encoding.charset=UTF-8
server.servlet.encoding.enable=true
server.servlet.encoding.force=true

##server:
##  port: 9000

POM文件

xml 复制代码
<?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.2.10</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.xmliu</groupId>
    <artifactId>alidemo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>alidemo</name>
    <description/>
    <url/>
    <licenses>
        <license/>
    </licenses>
    <developers>
        <developer/>
    </developers>
    <scm>
        <connection/>
        <developerConnection/>
        <tag/>
        <url/>
    </scm>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud.ai</groupId>
            <artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
            <version>1.0.0.2</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
            <version>3.4.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
            <version>3.4.0</version>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.14.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <executions>
                    <execution>
                        <id>default-compile</id>
                        <phase>compile</phase>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                        <configuration>
                            <annotationProcessorPaths>
                                <path>
                                    <groupId>org.projectlombok</groupId>
                                    <artifactId>lombok</artifactId>
                                </path>
                            </annotationProcessorPaths>
                        </configuration>
                    </execution>
                    <execution>
                        <id>default-testCompile</id>
                        <phase>test-compile</phase>
                        <goals>
                            <goal>testCompile</goal>
                        </goals>
                        <configuration>
                            <annotationProcessorPaths>
                                <path>
                                    <groupId>org.projectlombok</groupId>
                                    <artifactId>lombok</artifactId>
                                </path>
                            </annotationProcessorPaths>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

前端代码

前端使用HbuilderX 5.07开发,nodejs版本是13.14.0,vue3开发

核心代码App.vue

javascript 复制代码
<template>
	<h1 class="box">阿里百炼大模型智能体应用测试</h1>
	<div class="chat-container">
		<div class="reply-content">
			<span v-html="parsedReply"></span>
			<span v-if="errorMsg" class="error-tip">{{errorMsg}}</span>
		</div>
		<div class="input-area">
			<input @keyup.enter="send" v-model="question" class="chat-input" placeholder="输入问题" />
			<button @click="send" class="send-button" :class="{disabled:isLoading}" :disabled="isLoading">发送</button>
		</div>
	</div>
</template>

<script setup>
	import {
		ref,
		computed,
		nextTick
	} from 'vue'
	import {
		marked
	} from 'marked'
	const question = ref('')
	const reply = ref('')
	const isLoading = ref(false)
	const errorMsg = ref('')

	const parsedReply = computed(() => {
		return marked.parse(reply.value)
	})
	// 调用后端接口
	const send = async () => {
		console.log("点击了按钮")
		if (!question.value.trim()) return;
		isLoading.value = true
		reply.value = ''
		errorMsg.value = ''

		try {
			const url =
				`http://127.0.0.1:8080/ai/bailian/agent/stream?message=${encodeURIComponent(question.value)}`
			const eventSoure = new EventSource(url)

			eventSoure.onmessage = (e) => {
				console.log('e.data==', e.data)
				if ('data:__STREAM_END__' === e.data) {
					console.log('--------------结束-----------------------------', e.data)
					eventSoure.close()
					isLoading.value = false;
					return;
				}
				errorMsg.value = '';
				reply.value += e.data;
			}
			eventSoure.onerror = (err) => {
				if (eventSoure.readyState === 2) {
					console.log("正常结束")
				} else {
					eventSoure.close()
					errorMsg.value = '接口请求失败,请稍后再试'
					console.error('接口错误1', err)
				}
				isLoading.value = false

			}
		} catch (error) {
			isLoading.value = false
			errorMsg.value = '接口异常,请稍后再试'
			console.error('接口异常', error)
		}
	}
</script>

<style>
	.error-tip {
		color: #ff4d4f;
		font-size: 14px;
	}

	.loading-tip {
		color: #666;
		font-size: 14px;
	}

	.chat-container {
		max-width: 800px;
		margin: 20px auto;
		padding: 0 20px;
	}

	.input-area {
		display: flex;
		gap: 10px;
		margin-top: 20px;
	}

	.chat-input {
		flex: 1;
		padding: 12px 16px;
		border: 1px solid #e0e0e0;
		border-radius: 8px;
		font-size: 14px;
		outline: none;
		transition: border-color 0.2s;
	}

	.chat-input :focus {
		border-color: #1677ff;
	}

	.send-button {
		padding: 0 24px;
		background-color: #1677ff;
		color: white;
		border: none;
		border-radius: 8px;
		font-size: 14px;
		cursor: pointer;
	}

	.send-button.disabled {
		background-color: #cccccc;
		cursor: not-allowed;
	}

	.send-button :hover {
		background-color: #0f5fd7;
	}

	.blink {
		animation: blink 1.2s infinite;
	}

	@keyframes blink {

		0%,
		100% {
			opacity: 0;
		}

		50% {
			opacity: 1;
		}
	}

	.reply-content {
		text-align: left;
		min-height: 40px;
		margin: 20px 0;
	}

	.reply-content h1 {
		font-size: 20px;
		font-weight: bold;

	}

	.reply-content code {
		background: #f5f5f5;
		padding: 2px 4px;
	}

	.box {
		text-align: center;
	}
</style>
相关推荐
csdn2015_1 小时前
java springboot 文件导入,判断第一列的值是否有重复
java·windows·spring boot
GHL2842710901 小时前
python通过API调用Coze智能体学习
学习·ai
阿丰资源1 小时前
基于Springboot+mysql的在线兼职平台(附源码)
spring boot·后端·mysql
怪祝浙1 小时前
从简单项目入手Java(学生系统)V6(Web版本 Spring Boot3 MySQL Vue3 MyBatis)
java·spring boot·mysql
AIGC大时代2 小时前
阿里千问接入淘宝后,AI 购物能不能被信任?
科技·ai·科普
少许极端2 小时前
AI修炼记3-RAG
人工智能·ai·原型模式·rag
maxmaxma2 小时前
Claude Code集成DeepSeek-V4-pro全栈开发 - hooks 安全扫描
ai
蜡台3 小时前
Vue + SpringBoot 实现 WebSocket 基于 Sec-WebSocket-Protocol 传参鉴权(避坑指南)
vue.js·spring boot·websocket·sec
进阶的猿猴3 小时前
Rsa简单实现接口到期限制(springBoot)
java·spring boot·后端