<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      【原】無腦操作:IDEA + maven + SpringAI + 訊飛星火大模型實現簡單智能對話

      1、實現效果

      圖片1

       

      2、設置pom.xml

       1 <?xml version="1.0" encoding="UTF-8"?>
       2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       3          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
       4     <modelVersion>4.0.0</modelVersion>
       5     <parent>
       6         <groupId>org.springframework.boot</groupId>
       7         <artifactId>spring-boot-starter-parent</artifactId>
       8         <version>3.4.4</version>
       9         <relativePath/> <!-- lookup parent from repository -->
      10     </parent>
      11     <groupId>cn.temptation</groupId>
      12     <artifactId>studyAI</artifactId>
      13     <version>0.0.1-SNAPSHOT</version>
      14     <name>studyAI</name>
      15     <description>studyAI</description>
      16     <url/>
      17 
      18     <properties>
      19         <java.version>17</java.version>
      20         <spring-ai.version>1.0.3</spring-ai.version>
      21     </properties>
      22 
      23     <dependencyManagement>
      24         <dependencies>
      25             <dependency>
      26                 <groupId>org.springframework.ai</groupId>
      27                 <artifactId>spring-ai-bom</artifactId>
      28                 <version>1.0.3</version>
      29                 <type>pom</type>
      30                 <scope>import</scope>
      31             </dependency>
      32         </dependencies>
      33     </dependencyManagement>
      34 
      35     <dependencies>
      36         <!-- Lombok -->
      37         <dependency>
      38             <groupId>org.projectlombok</groupId>
      39             <artifactId>lombok</artifactId>
      40             <version>1.18.22</version>
      41         </dependency>
      42         <!-- web -->
      43         <dependency>
      44             <groupId>org.springframework.boot</groupId>
      45             <artifactId>spring-boot-starter-web</artifactId>
      46         </dependency>
      47         <!-- thymeleaf -->
      48         <dependency>
      49             <groupId>org.springframework.boot</groupId>
      50             <artifactId>spring-boot-starter-thymeleaf</artifactId>
      51         </dependency>
      52         <!-- spark4j -->
      53         <dependency>
      54             <groupId>io.github.briqt</groupId>
      55             <artifactId>xunfei-spark4j</artifactId>
      56             <version>1.3.0</version>
      57         </dependency>
      58         <!-- 熱部署 -->
      59         <dependency>
      60             <groupId>org.springframework.boot</groupId>
      61             <artifactId>spring-boot-devtools</artifactId>
      62             <optional>true</optional>
      63         </dependency>
      64     </dependencies>
      65 
      66     <build>
      67         <plugins>
      68             <plugin>
      69                 <groupId>org.springframework.boot</groupId>
      70                 <artifactId>spring-boot-maven-plugin</artifactId>
      71             </plugin>
      72         </plugins>
      73     </build>
      74 
      75 </project>

       

      3、設置application.yaml

      圖片2

      圖片3

       1 spring:
       2   application:
       3     name: iflytek-ai
       4   thymeleaf:
       5     cache: false
       6 
       7 xunfei:
       8   client:
       9     appId: 從訊飛開放平臺上找到自己的應用的APPID
      10     apiSecret: 從訊飛開放平臺上找到自己的應用的APISecret
      11     apiKey: 從訊飛開放平臺上找到自己的應用的APIKey
      12 
      13 server:
      14   port: 80

       

      4、整個程序結構如下圖所示:

      圖片4

       

      5、編寫SparkConfig.java配置類

       1 package cn.temptation.config;
       2 
       3 import io.github.briqt.spark4j.SparkClient;
       4 import lombok.Data;
       5 import org.springframework.boot.context.properties.ConfigurationProperties;
       6 import org.springframework.context.annotation.Bean;
       7 import org.springframework.context.annotation.Configuration;
       8 
       9 @Configuration
      10 @ConfigurationProperties(prefix = "xunfei.client")
      11 @Data
      12 public class SparkConfig {
      13     private String appid;
      14     private String apiSecret;
      15     private String apiKey;
      16 
      17     @Bean
      18     public SparkClient sparkClient() {
      19         SparkClient sparkClient = new SparkClient();
      20         sparkClient.appid = this.appid;
      21         sparkClient.apiSecret = this.apiSecret;
      22         sparkClient.apiKey = this.apiKey;
      23 
      24         return sparkClient;
      25     }
      26 }

       

      6、使用xunfei-spark4j時,想使用免費的Spark Lite時,有一個坑,因為SparkApiVersion枚舉的結構如下:

       1 public enum SparkApiVersion {
       2     V1_5("v1.1", "https://spark-api.xf-yun.com/v1.1/chat", "general"),
       3     V2_0("v2.1", "https://spark-api.xf-yun.com/v2.1/chat", "generalv2"),
       4     V3_0("v3.1", "https://spark-api.xf-yun.com/v3.1/chat", "generalv3"),
       5     V3_5("v3.5", "https://spark-api.xf-yun.com/v3.5/chat", "generalv3.5"),
       6     V4_0("v4.0", "https://spark-api.xf-yun.com/v4.0/chat", "4.0Ultra");
       7 
       8     private final String version;
       9     private final String url;
      10     private final String domain;
      11 
      12     private SparkApiVersion(String version, String url, String domain) {
      13         this.version = version;
      14         this.url = url;
      15         this.domain = domain;
      16     }
      17 
      18     public String getVersion() {
      19         return this.version;
      20     }
      21 
      22     public String getUrl() {
      23         return this.url;
      24     }
      25 
      26     public String getDomain() {
      27         return this.domain;
      28     }
      29 }

      這里找不到免費的Spark Lite,所以需要自己修改。編寫EnumReflectionUtil.java反射工具類。

      1 public class EnumReflectionUtil {
      2     public static void setEnumField(Enum<?> enumConstant, String fieldName, Object newValue) throws Exception {
      3         Field field = enumConstant.getClass().getDeclaredField(fieldName);
      4         field.setAccessible(true);
      5         field.set(enumConstant, newValue);
      6     }
      7 }

       

      7、編寫聊天處理類ChatWithController.java

       1 @Controller
       2 public class ChatWithController {
       3     // 初始化客戶端
       4     @Resource
       5     private SparkClient sparkClient;
       6 
       7     // 通過反射類,在使用大模型時,指定使用免費的Spark Lite大模型
       8     @PostConstruct
       9     public void init() throws Exception {
      10         // 修改 V1_5 的版本信息
      11         EnumReflectionUtil.setEnumField(SparkApiVersion.V1_5, "version", "v1.1");
      12         EnumReflectionUtil.setEnumField(SparkApiVersion.V1_5, "url", "https://spark-api.xf-yun.com/v1.1/chat");
      13         EnumReflectionUtil.setEnumField(SparkApiVersion.V1_5, "domain", "lite");
      14     }
      15 
      16     // AI預設System角色的條件
      17     public static final String PRECONDITION = "你是 iflytek";
      18 
      19     // 跳轉前端頁面
      20     @RequestMapping("/")
      21     public String index() {
      22         return "index";
      23     }
      24 
      25     // 和訊飛星火大模型Spark Lite對話
      26     @RequestMapping(value = "/chat", produces = "application/json")
      27     public ResponseEntity<?> sendHttpToSpark(@RequestBody Map<String, String> map) {
      28         // 消息列表
      29         List<SparkMessage> messages = new ArrayList<>();
      30         // 設置System角色,則使用下句
      31 //        messages.add(SparkMessage.systemContent(PRECONDITION));
      32         // 獲取前端輸入的對話內容,設置User角色
      33         messages.add(SparkMessage.userContent(map.get("message")));
      34 
      35         // 構造請求
      36         SparkRequest sparkRequest = SparkRequest.builder()
      37                 .messages(messages)
      38                 .apiVersion(SparkApiVersion.V1_5)
      39                 .build();
      40 
      41         SparkSyncChatResponse chatResponse = sparkClient.chatSync(sparkRequest);
      42 
      43         String responseContent = chatResponse.getContent();
      44 
      45         Map<String, Object> response = new HashMap<>();
      46         response.put("response", responseContent);
      47 
      48         return ResponseEntity.ok(response);
      49     }
      50 }

       

      8、編寫前端交互頁面index.html

        1 <!DOCTYPE html>
        2 <html lang="zh-CN">
        3 <head>
        4     <meta charset="UTF-8">
        5     <meta name="viewport" content="width=device-width, initial-scale=1.0">
        6     <title>AI 智能助手</title>
        7     <link href="https://cdn.bootcdn.net/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
        8     <style>
        9         :root {
       10             --primary-color: #4a90e2;
       11             --secondary-color: #f5f5f5;
       12             --success-color: #34d399;
       13             --error-color: #ef4444;
       14         }
       15 
       16         * {
       17             box-sizing: border-box;
       18             margin: 0;
       19             padding: 0;
       20         }
       21 
       22         body {
       23             font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
       24             background: #f0f2f5;
       25             min-height: 100vh;
       26         }
       27 
       28         .container {
       29             max-width: 1200px;
       30             margin: 0 auto;
       31             padding: 20px;
       32         }
       33 
       34         .chat-container {
       35             background: white;
       36             border-radius: 12px;
       37             box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
       38             height: 80vh;
       39             display: flex;
       40             flex-direction: column;
       41         }
       42 
       43         #chat-box {
       44             flex: 1;
       45             overflow-y: auto;
       46             padding: 20px;
       47             scroll-behavior: smooth;
       48         }
       49 
       50         .message {
       51             display: flex;
       52             gap: 12px;
       53             margin-bottom: 16px;
       54         }
       55 
       56         .message.user {
       57             flex-direction: row-reverse;
       58         }
       59 
       60         .avatar {
       61             width: 40px;
       62             height: 40px;
       63             border-radius: 50%;
       64             background: var(--secondary-color);
       65             display: flex;
       66             align-items: center;
       67             justify-content: center;
       68             flex-shrink: 0;
       69         }
       70 
       71         .message-content {
       72             max-width: 70%;
       73             padding: 12px 16px;
       74             border-radius: 12px;
       75             position: relative;
       76         }
       77 
       78         .user .message-content {
       79             background: var(--primary-color);
       80             color: white;
       81             border-radius: 12px 12px 0 12px;
       82         }
       83 
       84         .bot .message-content {
       85             background: var(--secondary-color);
       86             border-radius: 12px 12px 12px 0;
       87         }
       88 
       89         .input-area {
       90             border-top: 1px solid #eee;
       91             padding: 16px;
       92             display: flex;
       93             gap: 12px;
       94             background: white;
       95         }
       96 
       97         #user-input {
       98             flex: 1;
       99             padding: 12px;
      100             border: 1px solid #e2e8f0;
      101             border-radius: 8px;
      102             font-size: 16px;
      103             transition: all 0.3s ease;
      104         }
      105 
      106         #user-input:focus {
      107             outline: none;
      108             border-color: var(--primary-color);
      109             box-shadow: 0 0 0 3px rgba(74, 144, 226, 0.2);
      110         }
      111 
      112         button {
      113             padding: 12px 24px;
      114             background: var(--primary-color);
      115             color: white;
      116             border: none;
      117             border-radius: 8px;
      118             cursor: pointer;
      119             transition: all 0.2s ease;
      120             display: flex;
      121             align-items: center;
      122             gap: 8px;
      123         }
      124 
      125         button:hover {
      126             background: #357abd;
      127             transform: translateY(-1px);
      128         }
      129 
      130         button:disabled {
      131             background: #94a3b8;
      132             cursor: not-allowed;
      133         }
      134 
      135         @media (max-width: 768px) {
      136             .container {
      137                 padding: 10px;
      138             }
      139 
      140             .message-content {
      141                 max-width: 85%;
      142             }
      143         }
      144     </style>
      145 </head>
      146 <body>
      147 <div class="container">
      148     <h1 style="margin-bottom: 20px; color: #1e293b;">AI 智能助手 <i class="fas fa-robot"></i></h1>
      149 
      150     <div class="chat-container">
      151         <div id="chat-box">
      152             <div class="message bot">
      153                 <div class="avatar"><i class="fas fa-robot"></i></div>
      154                 <div class="message-content">您好!我是智能助手,可以回答各種問題...</div>
      155             </div>
      156         </div>
      157 
      158         <div class="input-area">
      159             <input type="text" id="user-input" placeholder="輸入消息...">
      160             <button onclick="sendMessage()" id="send-btn">
      161                 <i class="fas fa-paper-plane"></i> 發送
      162             </button>
      163         </div>
      164     </div>
      165 </div>
      166 
      167 <script>
      168     let isSending = false
      169 
      170     // 消息處理
      171     async function sendMessage() {
      172         if (isSending) return
      173 
      174         const input = document.getElementById('user-input')
      175         const message = input.value.trim()
      176         if (!message) return
      177 
      178         isSending = true
      179         input.disabled = true
      180         document.getElementById('send-btn').disabled = true
      181 
      182         try {
      183             appendMessage(message, 'user')
      184             input.value = ''
      185 
      186             const response = await fetch('/chat', {
      187                 method: 'POST',
      188                 headers: {'Content-Type': 'application/json'},
      189                 body: JSON.stringify({message})
      190             })
      191 
      192             const data = await response.json()
      193             if (response.ok) {
      194                 appendMessage(data.response, 'bot')
      195             } else {
      196                 appendMessage(`錯誤:${data.error}`, 'bot')
      197             }
      198         } catch (error) {
      199             appendMessage('網絡請求失敗', 'bot')
      200         } finally {
      201             isSending = false
      202             input.disabled = false
      203             document.getElementById('send-btn').disabled = false
      204             input.focus()
      205         }
      206     }
      207 
      208     function appendMessage(message, sender) {
      209         const chatBox = document.getElementById('chat-box')
      210         const isUser = sender === 'user'
      211 
      212         const messageEl = document.createElement('div')
      213         messageEl.className = `message ${isUser ? 'user' : 'bot'}`
      214         messageEl.innerHTML = `
      215                 <div class="avatar">
      216                     ${isUser ? '<i class="fas fa-user"></i>' : '<i class="fas fa-robot"></i>'}
      217                 </div>
      218                 <div class="message-content">${message}</div>
      219             `
      220 
      221         chatBox.appendChild(messageEl)
      222         chatBox.scrollTop = chatBox.scrollHeight
      223     }
      224 
      225     // 回車發送
      226     document.getElementById('user-input').addEventListener('keypress', (e) => {
      227         if (e.key === 'Enter' && !e.shiftKey) {
      228             e.preventDefault()
      229             sendMessage()
      230         }
      231     })
      232 </script>
      233 </body>
      234 </html>

       

      本文編寫過程中參考了網絡上一些大佬的經驗,在此一并感謝。

       拋磚引玉,期待更多人研究訊飛星火大模型...

      posted @ 2025-10-24 09:30  {name:"代碼屠夫"}  閱讀(43)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 九九热中文字幕在线视频| 白水县| 丰满的少妇一区二区三区| 亚洲中文字幕无码久久精品1| 九九热在线视频免费观看| 国产日韩AV免费无码一区二区三区 | 亚洲国产成人精品无色码| 阳新县| 日韩av毛片福利国产福利| 亚洲精品乱码久久久久久蜜桃不卡| 91中文字幕在线一区| 亚洲精品成人无限看| 三上悠亚精品二区在线观看| 性欧美VIDEOFREE高清大喷水| 熟妇人妻久久春色视频网| 中文字幕国产精品资源| 成人年无码av片在线观看| 中文字幕av无码免费一区| 丝袜人妻一区二区三区网站| 国产精品三级爽片免费看| 正在播放国产真实哭都没用| 国产深夜福利在线免费观看| 亚洲av无码精品色午夜蛋壳| 国产综合色在线精品| 免费国精产品wnw2544| 综合激情网一区二区三区| 人妻少妇精品视频专区| 丰满岳乱妇一区二区三区| 韩国美女福利视频一区二区| 亚洲日韩成人无码不卡网站| 中国国产免费毛卡片| 亚洲国产成人综合熟女| 亚洲av成人一区在线| 亚洲欧美日韩国产精品一区二区 | 国产第一页浮力影院入口| 无人区码一码二码三码区| 亚洲国产精品日韩在线| 蜜臀久久综合一本av| 国产极品美女高潮抽搐免费网站| 国产精品无码v在线观看| 日本边添边摸边做边爱喷水|