大家好,我是你们的技术火锅博主,今天我们要涮的不是羊肉,而是让本地部署的DeepSeek大模型在你的SpringBoot应用中"咕嘟咕嘟"沸腾起来!全程高能预警,附带前后端完整代码,保证你吃完这顿还能打包源码回家二次烹饪~
一、食材准备(环境依赖)
先来看看我们的技术火锅底料配方:
xml
<!-- 先来口汤底:SpringBoot父级配方 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.5</version>
<relativePath/>
</parent>
<dependencies>
<!-- 主菜:Web魔法锅 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 响应式火焰喷射器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<!-- 智能锅铲(HTTP客户端) -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.12.0</version>
</dependency>
<!-- 灵魂调味料(Lombok) -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- JSON解剖刀 -->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20231013</version>
</dependency>
</dependencies>
🚀 火力升级指南
二、熬制汤底(SpringBoot后端篇)
2.1 灵魂蘸料 - DeepSeek客户端
java
@Component
@Slf4j
public class DeepSeekChef {
private static final String LOCAL_API = "http://192.168.1.88:8080/deepseek/v1/chat/completions";
public Flux<String> cookStreamResponse(String prompt) {
return WebClient.create()
.post()
.uri(LOCAL_API)
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.bodyValue(createRequest(prompt))
.retrieve()
.bodyToFlux(String.class)
.map(this::extractContent)
.onErrorResume(e -> {
log.error("厨房失火啦!", e);
return Flux.just("🔥 厨师把锅烧穿了:" + e.getMessage());
});
}
private String extractContent(String json) {
// JSON解析逻辑(记得处理流式响应中的delta内容)
return new JSONObject(json).optString("content", "");
}
}
2.2 传菜窗口 - SSE控制器
java
@RestController
@RequestMapping("/ai-diner")
public class AIController {
@Autowired
private DeepSeekChef chef;
@GetMapping(path = "/stream-chat", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<ServerSentEvent<String>> streamChat(@RequestParam String message) {
return chef.cookStreamResponse(message)
.map(content -> ServerSentEvent.<String>builder()
.data(content)
.build())
.doOnComplete(() -> log.info("👨🍳 用户已光盘!"));
}
}
三、摆盘艺术(Vue前端篇)
3.1 智能涮锅界面
vue
<template>
<div class="ai-wok">
<div class="bubble-area">
<div v-for="(msg, index) in messages" :key="index"
class="bubble" :class="{ 'ai-bubble': msg.role === 'AI' }">
<span class="streaming" v-if="msg.streaming">{{ msg.content }}█</span>
<template v-else>{{ msg.content }}</template>
</div>
</div>
<div class="control-panel">
<input v-model="inputMsg" @keyup.enter="sendMsg" />
<button @click="sendMsg" :disabled="isCooking">
{{ isCooking ? '烹饪中...' : '上菜!' }}
</button>
</div>
</div>
</template>
3.2 核心火候控制
javascript
<script>
export default {
data() {
return {
inputMsg: '',
messages: [],
isCooking: false,
eventSource: null
}
},
methods: {
sendMsg() {
if (!this.inputMsg.trim()) return;
this.messages.push({
role: 'AI',
content: '',
streaming: true
});
const index = this.messages.length - 1;
this.isCooking = true;
this.eventSource = new EventSource(`/ai-diner/stream-chat?message=${encodeURIComponent(this.inputMsg)}`);
this.eventSource.onmessage = (e) => {
this.messages[index].content += e.data;
this.$nextTick(() => window.scrollTo(0, document.body.scrollHeight));
};
this.eventSource.onerror = () => {
this.isCooking = false;
this.eventSource.close();
};
this.inputMsg = '';
}
}
}
</script>
四、摆盘效果展示
(想象一下这里有个实时生成文字的打字机效果动图)
五、涮锅秘诀(关键技术点)
- 流式管道搭建:采用Spring WebFlux的Flux响应式流,像传送带一样持续输送"美味数据"
- SSE协议加持:比WebSocket更轻量的实时通讯方案,完美契合流式场景
- 防粘锅处理:前端消息队列的动态索引管理,防止多并发请求导致的数据混乱
- 异常熔断机制:通过onErrorResume保证即使厨房着火也不影响餐厅营业
六、涮后总结
现在你的本地DeepSeek已经像海底捞的服务员一样随时待命啦!通过这套方案,我们实现了:
✅ 本地模型的安全调用
✅ 丝滑的流式交互体验
✅ 完整的推理过程可视化
✅ 火锅级...哦不,企业级的稳定服务
最后友情提示:吃火锅别忘加麻酱,调代码记得加日志!遇到任何"糊锅"问题,欢迎在评论区涮(酸)我~