Spring AI 1.x 系列【6】集成 DeepSeek + 智谱 GLM,实现多模型一键切换的 AI 聊天助手

Spring AI 1.x 系列【6】集成 DeepSeek + 智谱 GLM,实现多模型一键切换的 AI 聊天助手

文章目录

1. 项目介绍

从零搭建一套 AI 聊天助手,基于 Spring AI 同时集成 DeepSeek 和 智谱 GLM 两大主流模型,实现前端一键切换模型流式对话等完整功能。

1.1 功能演示

顶部下拉框一键切换 DeepSeek / 智谱GLM 模型:

在这里插入图片描述

支持消息流式输出:

在这里插入图片描述

1.2 技术栈

核心技术栈:

  • 前端Thymeleaf + SSE 流式输出。
  • 后端Spring Boot 3.5.x + Spring AI 1.1.2
  • AI模型DeepSeek Chat、智谱 GLM-4

2. 环境准备

2.1 申请 API Key

DeepSeek:前往 DeepSeek 开放平台 创建 API Key
智谱 AI:前往 智谱开放平台 创建 API Key

2.2 创建工程

工程结构如下:

在这里插入图片描述

2.3 Maven 核心依赖

pom.xml 中引入 Spring AI 相关依赖,同时支持 DeepSeek 和智谱:

<?xml version="1.0" encoding="UTF-8"?><projectxmlns="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>com.study</groupId><artifactId>study-spring-ai</artifactId><version>0.0.1-SNAPSHOT</version><relativePath>../pom.xml</relativePath></parent><groupId>com.example</groupId><artifactId>ai-chat-demo</artifactId><version>0.0.1-SNAPSHOT</version><name>ai-chat-demo</name><description>ai-chat-demo</description><properties><java.version>17</java.version><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!--DeepSeek--><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-model-deepseek</artifactId></dependency><!--智谱AI--><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-model-zhipuai</artifactId></dependency><!-- Thymeleaf for web UI --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

3. 后端实现

3.1 配置文件

配置两大模型的 API 信息:

server:port:8081spring:application:name: ai-chat-demo ai:chat:client:enabled:false# DeepSeek 配置deepseek:api-key: 你的 DeepSeek API Key base-url: https://api.deepseek.com model: deepseek-chat # 智谱 GLM 配置zhipu:api-key: 你的 智谱 API Key base-url: https://open.bigmodel.cn/api/paas model: glm-4

3.2 对话客户端配置类

创建两个独立的 ChatClient Bean,分别对应 DeepSeek 和智谱:

@ConfigurationpublicclassChatClientConfig{@Bean("zhiPuAiChatClient")publicChatClientzhiPuAiChatClient(ZhiPuAiChatModel zhiPuAiChatModel){returnChatClient.builder(zhiPuAiChatModel).build();}@Bean("deepSeekChatClient")publicChatClientdeepSeekChatClient(DeepSeekChatModel deepSeekChatModel){returnChatClient.builder(deepSeekChatModel).build();}}

3.3 对话生成访问接口

通过 model 参数动态选择模型,兼容普通接口和流式接口:

importorg.springframework.ai.chat.client.ChatClient;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.beans.factory.annotation.Qualifier;importorg.springframework.http.MediaType;importorg.springframework.stereotype.Controller;importorg.springframework.web.bind.annotation.*;importreactor.core.publisher.Flux;importjava.util.Map;importjava.util.UUID;@ControllerpublicclassChatController{// 注入 DeepSeek 和智谱的 ChatClientprivatefinalChatClient deepSeekChatClient;privatefinalChatClient zhiPuAiChatClient;// 构造方法注入多个 ChatClient(替换原有单一注入)@AutowiredpublicChatController(@Qualifier("deepSeekChatClient")ChatClient deepSeekChatClient,@Qualifier("zhiPuAiChatClient")ChatClient zhiPuAiChatClient){this.deepSeekChatClient = deepSeekChatClient;this.zhiPuAiChatClient = zhiPuAiChatClient;}// 首路由,返回聊天页面@GetMapping("/")publicStringchatPage(){return"chat";}/** * 非流式生成接口(支持模型切换) * * @param message 用户消息 * @param model 模型名称(deepseek/zhipu,默认deepseek) * @return 模型回复 */@GetMapping("/ai/generate")@ResponseBodypublicMap<String,String>generate(@RequestParam(value ="message", defaultValue ="你好")String message,@RequestParam(value ="model", defaultValue ="deepseek")String model){try{// 根据模型名称获取对应的 ChatClientChatClient targetClient =getChatClientByModel(model);String response = targetClient.prompt().user(message).call().content();returnMap.of("generation", response,"usedModel", model);// 新增返回使用的模型,方便前端确认}catch(Exception e){returnMap.of("generation","错误: "+ e.getMessage(),"usedModel", model);}}/** * 流式生成接口(支持模型切换) * * @param message 用户消息 * @param model 模型名称(deepseek/zhipu,默认deepseek) * @return 流式响应 */@GetMapping(value ="/ai/generate/stream", produces =MediaType.TEXT_EVENT_STREAM_VALUE)@ResponseBodypublicFlux<String>generateStream(@RequestParam(value ="message", defaultValue ="你好")String message,@RequestParam(value ="model", defaultValue ="deepseek")String model){try{// 根据模型名称获取对应的 ChatClientChatClient targetClient =getChatClientByModel(model);return targetClient.prompt().user(message).stream().content().onErrorResume(e ->Flux.just("错误: "+ e.getMessage()));}catch(IllegalArgumentException e){// 模型名称错误时返回提示returnFlux.just("错误: "+ e.getMessage());}}/** * 创建新会话,返回新的会话ID * * @return 新会话ID */@GetMapping("/api/conversation/new")@ResponseBodypublicMap<String,String>newConversation(){returnMap.of("conversationId",UUID.randomUUID().toString());}/** * 核心:根据模型名称获取对应的 ChatClient * * @param model 模型名称(deepseek/zhipu) * @return 对应的 ChatClient * @throws IllegalArgumentException 模型不支持时抛出异常 */privateChatClientgetChatClientByModel(String model){returnswitch(model.toLowerCase()){case"deepseek"-> deepSeekChatClient;case"zhipu","glm"-> zhiPuAiChatClient;default->thrownewIllegalArgumentException("不支持的模型:"+ model);};}}

4. 前端页面

resources/templates 目录下创建聊天界面 chat.html ,重点涉及:

  • 接收后端流式响应(SSE/Server-Sent Events)处理,实现实时打字效果。
  • 模型切换下拉框,传递 model 参数。
<!DOCTYPEhtml><htmllang="zh-CN"xmlns:th="http://www.thymeleaf.org"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width, initial-scale=1.0"><title>AI聊天助手</title><style>*{margin: 0;padding: 0;box-sizing: border-box;}body{font-family:'Arial','Microsoft YaHei', sans-serif;background:linear-gradient(135deg, #f9e7d8 0%, #f5d6b8 50%, #e8c8a0 100%);height: 100vh;overflow: hidden;position: relative;}.chat-container{width: 95%;max-width: 900px;height: 90vh;background:rgba(255, 255, 255, 0.95);border-radius: 20px;box-shadow: 0 10px 30px rgba(222, 184, 135, 0.15);display: flex;flex-direction: column;overflow: hidden;position: relative;margin: 20px auto;border: 2px solid #e6b89c;}.chat-header{background:linear-gradient(90deg, #e69c68 0%, #d98850 100%);color: white;padding: 18px;text-align: center;font-size: 1.6rem;font-weight: 600;position: relative;display: flex;justify-content: space-between;align-items: center;}.chat-header-title{flex: 1;text-align: center;}/* 新增:模型选择下拉框样式 */.model-selector{background:rgba(255, 255, 255, 0.2);border: 1px solid rgba(255, 255, 255, 0.3);color: white;padding: 8px 16px;border-radius: 20px;font-size: 0.9rem;cursor: pointer;transition: all 0.3s ease;margin-left: 10px;outline: none;}.model-selector:hover{background:rgba(255, 255, 255, 0.3);}.model-selector option{background: #d98850;color: white;border: none;}.new-chat-btn{background:rgba(255, 255, 255, 0.2);border: 1px solid rgba(255, 255, 255, 0.3);color: white;padding: 8px 16px;border-radius: 20px;cursor: pointer;font-size: 0.9rem;transition: all 0.3s ease;margin-right: 10px;}.new-chat-btn:hover{background:rgba(255, 255, 255, 0.3);transform:translateY(-2px);}.header-placeholder{width: 80px;}.chat-messages{flex: 1;padding: 20px;overflow-y: auto;background:radial-gradient(circle at 20% 30%,rgba(249, 231, 216, 0.1) 0%, transparent 50%),radial-gradient(circle at 80% 70%,rgba(232, 200, 160, 0.1) 0%, transparent 50%);}.message{margin-bottom: 20px;display: flex;animation: fadeIn 0.5s ease-out;}@keyframes fadeIn{from{opacity: 0;transform:translateY(20px)scale(0.95);}to{opacity: 1;transform:translateY(0)scale(1);}}.user-message{justify-content: flex-end;}.ai-message{justify-content: flex-start;}.message-content{max-width: 75%;padding: 15px 20px;border-radius: 20px;font-size: 1.1rem;line-height: 1.5;position: relative;box-shadow: 0 2px 10px rgba(222, 184, 135, 0.1);border: 2px solid transparent;}.user-message .message-content{background:linear-gradient(135deg, #f0b890 0%, #e69c68 100%);color: white;border-color: #d98850;border-bottom-right-radius: 8px;}.ai-message .message-content{background:linear-gradient(135deg, #faf6f0 0%, #f9e7d8 100%);color: #333;border-color: #e6b89c;border-bottom-left-radius: 8px;}.chat-input{padding: 20px;background: #faf6f0;border-top: 2px solid #e6b89c;display: flex;gap: 15px;position: relative;}.message-input{flex: 1;padding: 15px 20px;border: 2px solid #e6b89c;border-radius: 30px;font-size: 1.1rem;outline: none;background:rgba(255, 255, 255, 0.9);transition: all 0.3s ease;box-shadow: 0 2px 8px rgba(222, 184, 135, 0.1);}.message-input:focus{border-color: #d98850;box-shadow: 0 2px 15px rgba(217, 136, 80, 0.2);transform:scale(1.01);}.send-button{padding: 15px 30px;background:linear-gradient(135deg, #e69c68 0%, #d98850 100%);color: white;border: none;border-radius: 30px;font-size: 1.1rem;font-weight: 600;cursor: pointer;transition: all 0.3s ease;box-shadow: 0 2px 10px rgba(217, 136, 80, 0.2);}.send-button:hover{transform:translateY(-2px);box-shadow: 0 4px 15px rgba(217, 136, 80, 0.3);}.send-button:active{transform:translateY(0);}.send-button::after{content:"→";margin-left: 8px;display: inline-block;transition: transform 0.3s ease;}.send-button:hover::after{transform:translateX(5px);}.send-button:disabled{opacity: 0.6;cursor: not-allowed;transform: none;box-shadow: none;}.typing-indicator{display: none;padding: 15px 20px;background:linear-gradient(135deg, #faf6f0 0%, #f9e7d8 100%);border: 2px solid #e6b89c;border-radius: 20px;border-bottom-left-radius: 8px;margin-bottom: 20px;position: relative;}.typing-indicator.show{display: flex;align-items: center;}.typing-dots{display: flex;align-items: center;gap: 6px;}.typing-dot{width: 10px;height: 10px;background: #d98850;border-radius: 50%;animation: typing 1.4s infinite ease-in-out;}.typing-dot:nth-child(1){animation-delay: 0s;}.typing-dot:nth-child(2){animation-delay: 0.2s;}.typing-dot:nth-child(3){animation-delay: 0.4s;}@keyframes typing{0%, 60%, 100%{transform:translateY(0)scale(1);opacity: 0.7;}30%{transform:translateY(-8px);opacity: 1;}}.welcome-message{text-align: center;color: #555;font-size: 1.2rem;margin: 30px 0;padding: 30px;background:linear-gradient(135deg, #fff 0%, #faf6f0 100%);border-radius: 20px;border: 2px solid #e6b89c;box-shadow: 0 4px 15px rgba(222, 184, 135, 0.1);}.welcome-message h3{color: #d98850;margin-bottom: 15px;font-size: 1.5rem;font-weight: 600;}.welcome-message p{line-height: 1.6;}.chat-messages::-webkit-scrollbar{width: 8px;}.chat-messages::-webkit-scrollbar-track{background:rgba(249, 231, 216, 0.2);border-radius: 4px;}.chat-messages::-webkit-scrollbar-thumb{background:linear-gradient(135deg, #e69c68 0%, #d98850 100%);border-radius: 4px;}.chat-messages::-webkit-scrollbar-thumb:hover{background:linear-gradient(135deg, #d98850 0%, #c87840 100%);}</style></head><body><divclass="chat-container"><divclass="chat-header"><!-- 新增:模型选择下拉框 --><selectclass="model-selector"id="modelSelector"><optionvalue="deepseek">DeepSeek</option><optionvalue="zhipu">智谱GLM</option></select><spanclass="chat-header-title">AI 聊天助手</span><buttonclass="new-chat-btn"id="newChatBtn">新对话</button></div><divclass="chat-messages"id="chatMessages"><divclass="welcome-message"id="welcomeMessage"><h3>欢迎使用AI 聊天助手</h3><p>你可以随时提出问题,我会尽力解答<br> 期待与你愉快交流!</p></div></div><divclass="typing-indicator"id="typingIndicator"><divclass="typing-dots"><divclass="typing-dot"></div><divclass="typing-dot"></div><divclass="typing-dot"></div></div><spanstyle="margin-left: 15px;color: #d98850;font-weight: 600;">正在思考中...</span></div><divclass="chat-input"><inputtype="text"class="message-input"id="messageInput"placeholder="请输入你想说的话..."autocomplete="off"><buttonclass="send-button"id="sendButton">发送</button></div></div><script>const chatMessages = document.getElementById('chatMessages');const messageInput = document.getElementById('messageInput');const sendButton = document.getElementById('sendButton');const typingIndicator = document.getElementById('typingIndicator');const welcomeMessage = document.getElementById('welcomeMessage');const newChatBtn = document.getElementById('newChatBtn');// 新增:获取模型选择器DOMconst modelSelector = document.getElementById('modelSelector');// 当前会话ID(用于记忆功能)let conversationId ='default';// 创建新会话asyncfunctioncreateNewConversation(){try{const response =awaitfetch('/api/conversation/new');const data =await response.json(); conversationId = data.conversationId;// 清空聊天消息 chatMessages.innerHTML ='';// 显示欢迎消息const newWelcome = document.createElement('div'); newWelcome.className ='welcome-message'; newWelcome.id ='welcomeMessage'; newWelcome.innerHTML =` <h3>欢迎使用AI 聊天助手</h3> <p>你可以随时提出问题,我会尽力解答<br> 期待与你愉快交流!</p> `; chatMessages.appendChild(newWelcome); console.log('新会话已创建:', conversationId);}catch(error){ console.error('创建新会话失败:', error);// 即使失败也生成一个本地ID conversationId ='local-'+ Date.now();}}// 发送消息函数(使用流式接口)asyncfunctionsendMessage(){const message = messageInput.value.trim();if(!message)return;// 隐藏欢迎消息const welcomeMsg = document.getElementById('welcomeMessage');if(welcomeMsg){ welcomeMsg.style.display ='none';}// 添加用户消息到聊天界面addMessage(message,'user');// 清空输入框 messageInput.value ='';// 显示正在输入指示器showTypingIndicator();// 禁用发送按钮 sendButton.disabled =true;// 预先创建AI消息容器(用于流式显示)const aiMessageDiv =createAIMessageContainer();try{// 新增:获取选中的模型值const selectedModel = modelSelector.value;// 修改:请求URL中添加model参数const response =awaitfetch(`/ai/generate/stream?message=${encodeURIComponent(message)}&conversationId=${encodeURIComponent(conversationId)}&model=${encodeURIComponent(selectedModel)}`,{method:'GET',headers:{'Accept':'text/event-stream',}});if(!response.ok){thrownewError(`HTTP error! status: ${response.status}`);}// 隐藏正在输入指示器(开始接收数据时隐藏)hideTypingIndicator();// 读取流式响应const reader = response.body.getReader();const decoder =newTextDecoder();let fullResponse ='';while(true){const{ done, value }=await reader.read();if(done)break;// 解码数据块const chunk = decoder.decode(value,{stream:true});// SSE 格式:每行以 "data:" 开头const lines = chunk.split('\n');for(const line of lines){if(line.startsWith('data:')){const data = line.substring(5).trim();if(data){ fullResponse += data;// 更新AI消息内容updateAIMessageContent(aiMessageDiv, fullResponse);}}elseif(line.trim()&&!line.startsWith(':')){// 处理非标准SSE格式(直接返回文本) fullResponse += line;updateAIMessageContent(aiMessageDiv, fullResponse);}}}// 如果没有收到任何内容if(!fullResponse){updateAIMessageContent(aiMessageDiv,'抱歉,没有收到回复。');}}catch(error){// 隐藏正在输入指示器hideTypingIndicator();// 显示错误消息updateAIMessageContent(aiMessageDiv,'抱歉,处理你的请求时出现了错误,请稍后再试。'); console.error('Error:', error);}finally{// 重新启用发送按钮 sendButton.disabled =false; messageInput.focus();}}// 创建AI消息容器(用于流式显示)functioncreateAIMessageContainer(){const messageDiv = document.createElement('div'); messageDiv.className ='message ai-message';const contentDiv = document.createElement('div'); contentDiv.className ='message-content'; contentDiv.textContent =''; messageDiv.appendChild(contentDiv); chatMessages.appendChild(messageDiv);// 滚动到最新消息 chatMessages.scrollTop = chatMessages.scrollHeight;return contentDiv;}// 更新AI消息内容(流式更新)functionupdateAIMessageContent(contentDiv, content){ contentDiv.textContent = content;// 滚动到最新消息 chatMessages.scrollTop = chatMessages.scrollHeight;}// 添加消息到聊天界面(保留用于用户消息)functionaddMessage(content, sender){const messageDiv = document.createElement('div'); messageDiv.className =`message ${sender}-message`;const contentDiv = document.createElement('div'); contentDiv.className ='message-content'; contentDiv.textContent = content; messageDiv.appendChild(contentDiv); chatMessages.appendChild(messageDiv);// 滚动到最新消息 chatMessages.scrollTop = chatMessages.scrollHeight;}// 显示正在输入指示器functionshowTypingIndicator(){ typingIndicator.classList.add('show'); chatMessages.scrollTop = chatMessages.scrollHeight;}// 隐藏输入指示器functionhideTypingIndicator(){ typingIndicator.classList.remove('show');}// 事件监听器 sendButton.addEventListener('click', sendMessage); messageInput.addEventListener('keypress',(e)=>{if(e.key ==='Enter'&&!e.shiftKey){ e.preventDefault();sendMessage();}});// 新对话按钮 newChatBtn.addEventListener('click', createNewConversation);// 页面加载完成后聚焦输入框 document.addEventListener('DOMContentLoaded',()=>{ messageInput.focus();});</script></body></html>

Read more

计算机Java毕设实战-基于Spring Boot的教育机构师资资源管理系统设计与实现基于Web的师资管理系统设计与实现【完整源码+LW+部署说明+演示视频,全bao一条龙等】

计算机Java毕设实战-基于Spring Boot的教育机构师资资源管理系统设计与实现基于Web的师资管理系统设计与实现【完整源码+LW+部署说明+演示视频,全bao一条龙等】

java毕业设计-基于springboot的(源码+LW+部署文档+全bao+远程调试+代码讲解等) 博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围::小程序、SpringBoot、SSM、JSP、Vue、PHP、Java、python、爬虫、数据可视化、大数据、物联网、机器学习等设计与开发。 主要内容:免费开题报告、任务书、全bao定制+中期检查PPT、代码编写、🚢文编写和辅导、🚢文降重、长期答辩答疑辅导、一对一专业代码讲解辅导答辩、模拟答辩演练、和理解代码逻辑思路。 特色服务内容:答辩必过班 (全程一对一技术交流,帮助大家顺利完成答辩,

Linux网络 | 理解Web路径 以及 实现一个简单的helloworld网页

Linux网络 | 理解Web路径 以及 实现一个简单的helloworld网页

前言:本节内容承接上节课的http相关的概念, 主要是实现一个简单的接收http协议请求的服务。这个程序对于我们理解后面的http协议的格式,报头以及网络上的资源的理解, 以及本节web路径等等都有着重要作用。 可以说我们就用代码来理解这些东西。 那么废话不多说, 现在开始我们的学习吧。         ps:本节内容建议先看一下上一篇文章http的相关概念哦:linux网络 | 深度学习http的相关概念-ZEEKLOG博客 目录  准备文件  makefile HttpServer.hpp 类内成员 封装sockfd start  ThreadRun  全部代码 运行结果 响应书写 Web路径  准备文件         首先准备文件: 这里面Httpserver.cc用来运行接收http请求的服务。 HttpServer.hpp用来定义http请求。Log.hpp就是一个打印日志的小组件, Socket.hpp同样是套接字的组件。 到使用直接调用相关接口即可。(Log.hpp和Socket.hpp如何实现不讲解, 如果想要知道

前端八股文面经大全:字节前端一面(2026-2-1)·面经深度解析

前端八股文面经大全:字节前端一面(2026-2-1)·面经深度解析

前言 大家好,我是木斯佳。 在这个春节假期,当大家都在谈论返乡、团圆与休息时,作为一名技术人,我的思考却不由自主地转向了行业的「冬」与「春」。 相信很多人都感受到了,在AI浪潮的席卷之下,前端领域的门槛在变高,纯粹的“增删改查”岗位正在肉眼可见地减少。曾经热闹非凡的面经分享,如今也沉寂了许多。但我们都知道,市场的潮水退去,留下的才是真正在踏实准备、努力沉淀的人。学习的需求,从未消失,只是变得更加务实和深入。 正值春节,也是复盘与规划的好时机。结合ZEEKLOG这次「春节代码贺新年」活动所提倡的“用技术视角记录春节、复盘成长”,我决定在这个假期持续更新专栏,帮助年后参加春招的同学。 这个专栏的初衷很简单:拒绝过时的、流水线式的PDF引流贴,专注于收集和整理当下最新、最真实的前端面试资料。 我会在每一份面经和八股文的基础上,尝试从面试官的角度去拆解问题背后的逻辑,而不仅仅是提供一份静态的背诵答案。无论你是校招还是社招,目标是中大厂还是新兴团队,只要是真实发生、有价值的面试经历,我都会在这个专栏里为你沉淀下来。 温馨提示:市面上的面经鱼龙混杂,

无需编程!Fun-ASR WebUI界面手把手操作教程

无需编程!Fun-ASR WebUI界面手把手操作教程 你是不是也遇到过这些情况:会议录音堆在文件夹里没时间听,客户语音留言转文字总出错,培训音频想整理成笔记却要花半天?别再复制粘贴到网页版工具、别再折腾Python环境、更别担心“CUDA out of memory”报错——今天这篇教程,专为完全不写代码的人准备。 Fun-ASR WebUI 是钉钉联合通义实验室推出的语音识别系统,由开发者“科哥”深度优化并封装成开箱即用的图形界面。它不是命令行里的冰冷指令,也不是需要配置10个参数才能跑起来的实验项目,而是一个像微信一样点点就能用的本地语音转文字工具。全程不需要安装Python包、不用改配置文件、不用查GPU型号——只要你会打开浏览器,就能把一段30分钟的采访音频,5分钟内变成带标点、分段清晰、数字自动规整的可编辑文本。 下面我将带你从零开始,像教朋友一样,一步步操作每一个按钮、解释每一处设置、避开所有新手踩坑点。你不需要懂“VAD”是什么,也不用知道“ITN”怎么拼,只需要跟着做,就能立刻上手。 1. 启动与访问:两步打开你的语音助手