From 7789aeaad9032763805da324d743bc664bddd2e8 Mon Sep 17 00:00:00 2001 From: xiangpei <xiangpei@timesnew.cn> Date: 星期五, 18 四月 2025 17:17:26 +0800 Subject: [PATCH] 改为对接java而不是直接调langchain --- src/components/AiChat.vue | 164 ++++++++++++++++++++++++++++++++++++------------------ 1 files changed, 109 insertions(+), 55 deletions(-) diff --git a/src/components/AiChat.vue b/src/components/AiChat.vue index b372582..486e8cf 100644 --- a/src/components/AiChat.vue +++ b/src/components/AiChat.vue @@ -1,5 +1,5 @@ <template> - <div style="position: relative;height:calc(100vh - 20px);width: 100%;display: flex;justify-content: center"> + <div style="height:calc(100vh - 20px);width: 100%;display: flex;justify-content: center"> <!-- 鑱婂ぉ娑堟伅鍒楄〃 --> <div class="chat-messages"> <div @@ -11,8 +11,11 @@ <div class="avatar"> <img :src="getAvatar(message.role)" alt="avatar" /> </div> - <div class="content"> - <div class="text" :ref="'msg' + index">{{ message.content }}</div> + <div v-if="!message.content && message.role == 'assistant'" v-loading="!message.content && message.role == 'assistant'"> + + </div> + <div v-else class="content"> + <div class="text" :ref="'msg' + index" v-html="getHtml(message.content)"></div> <div v-if="message.role === 'assistant'"> <div v-show="msgIndex === message" class="msg-op-list"> <el-button class="copy" v-show="false"/> @@ -37,7 +40,7 @@ <!-- 杈撳叆妗� --> <div class="chat-input"> - <div style="position: relative;width: 100%;box-sizing: border-box;"> + <div style="position: relative;width: 800px;box-sizing: border-box;"> <el-input v-model="inputMessage" type="textarea" @@ -59,7 +62,7 @@ </div> </div> <div class="send-but-warp"> - <div class="send-but"> + <div class="send-but" @click="sendMessage"> <svg t="1743144485359" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1261" width="36" height="36"> <path fill="#409eff" d="M512 85.333333c234.666667 0 426.666667 192 426.666667 426.666667s-192 426.666667-426.666667 426.666667S85.333333 746.666667 85.333333 512 277.333333 85.333333 512 85.333333z m-6.4 234.666667c-4.266667 2.133333-6.4 2.133333-12.8 8.533333l-153.6 153.6c-12.8 12.8-12.8 32 0 44.8 12.8 12.8 32 12.8 44.8 0l96-96V682.666667c0 17.066667 14.933333 32 32 32s32-14.933333 32-32V430.933333l96 96c12.8 12.8 32 12.8 44.8 0s12.8-32 0-44.8l-153.6-153.6c-6.4-6.4-8.533333-8.533333-12.8-8.533333s-8.533333-2.133333-12.8 0z" p-id="1262"></path> </svg> @@ -74,53 +77,46 @@ <script> import ClipboardJS from 'clipboard'; -import {sendKbMsg} from "@/api/chat"; import {Message} from "element-ui"; +const markdownIt = require('markdown-it')(); export default { name: 'AiChat', data() { return { + chatId: null, + messages: [], // 鐢ㄤ簬椤甸潰灞曠ず鐨勫璇濆垪琛� netSearchEnable: false, - messages: [ - { - role: 'assistant', - content: '浣犲ソ锛佹垜鏄綘鐨� AI 鍔╂墜锛屾湁浠�涔堝彲浠ュ府浣犵殑鍚楋紵', - }, - { - role: 'user', - content: '浣犲ソ锛佹垜鏄綘鐨� AI 鍔╂墜锛屾湁浠�涔堝彲浠ュ府浣犵殑鍚楋紵', - }, - ], inputMessage: '', sendMsgForm: { query: "", mode: "local_kb", - kb_name: "samples", - top_k: 3, - score_threshold: 2, + kbName: "SouthWest_Neclear_Develepment_KB", + topK: 3, + scoreThreshold: 2, history: [ - { - "content": "鎴戜滑鏉ョ帺鎴愯鎺ラ緳锛屾垜鍏堟潵锛岀敓榫欐椿铏�", - "role": "user" - }, - { - "content": "铏庡ご铏庤剳", - "role": "assistant" - } + ], stream: true, - model: "qwen:7b", - temperature: 0.7, - max_tokens: 0, - prompt_name: "default", - return_direct: false + model: "Qwen25-32B-Instruct", + temperature: 1.15, + maxTokens: 512, + promptName: "default", + returnDirect: false }, msgIndex: null, - msgRole: null + msgRole: null, + chunkRef: null, // ai鍥炵瓟涓存椂鏁版嵁 + haveThinkStart: false, // ai鍥炵瓟鍝嶅簲鏁版嵁鏄惁鏈塼hink鏍囩 + haveThinkEnd: false, // ai鍥炵瓟鍝嶅簲鏁版嵁鏄惁鏈塼hink鏍囩 + controller: null, // ai鍥炵瓟璇锋眰鎺у埗鍣紝鍙互鏍规嵁涓氬姟涓柇璇锋眰 }; }, methods: { + // md娓叉煋涓篽tml + getHtml(md) { + return markdownIt.render(md) + }, changeNetEnable() { this.netSearchEnable = ! this.netSearchEnable }, @@ -129,11 +125,9 @@ e.preventDefault(); // 闃绘榛樿鎹㈣琛屼负 }, handleMouseEnter(msgIndex) { - console.log("榧犳爣绉诲叆", msgIndex) this.msgIndex = msgIndex }, handleMouseLeave() { - console.log("榧犳爣绉婚櫎") this.msgIndex = null }, // 閲嶆柊鐢熸垚 @@ -167,27 +161,90 @@ return roleNames[role]; }, - // 鍙戦�佹秷鎭� async sendMessage() { if (this.inputMessage.trim() === '') return; - // 娣诲姞鐢ㄦ埛娑堟伅 - this.messages.push({ - role: 'user', - content: this.inputMessage, - }); - this.sendMsgForm.query = this.inputMessage - // 娓呯┖杈撳叆妗� - this.inputMessage = ''; + // 鍒濆鍖栫姸鎬� + this.chunkRef = ''; + this.haveThinkStart = false; + this.haveThinkEnd = false; + this.controller = new AbortController(); - sendKbMsg(this.sendMsgForm).then(res => { - console.log(res, "鎷垮埌鍥炲浜嗭紒锛�") - this.messages.push({ - role: 'assistant', - content: '杩欐槸涓�鏉� AI 鍥炲銆�', + // 娣诲姞鐢ㄦ埛娑堟伅鍜屽崰浣嶅姪鐞嗘秷鎭� + this.messages.push( + { role: 'user', content: this.inputMessage }, + { role: 'assistant', content: '' } + ); + this.sendMsgForm.query = this.inputMessage; + this.inputMessage = ''; + const assistantIndex = this.messages.length - 1; + try { + const response = await fetch('/api/chat/send/msg', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + "Accept": 'text/event-stream', + 'Cache-Control': 'no-cache, no-transform' + }, + signal: this.controller.signal, + body: JSON.stringify(this.sendMsgForm) }); - }) - }, + + if (!response.ok) throw new Error(`HTTP ${response.status}`); + + const reader = response.body.getReader(); + const decoder = new TextDecoder(); + let jsonBuffer = ''; + + // eslint-disable-next-line no-constant-condition + while (true) { + const { done, value } = await reader.read(); + if (done) { + this.sendMsgForm.history.push({ role: 'user', content: this.inputMessage }) + this.sendMsgForm.history.push({ role: 'assistant', content: this.messages[assistantIndex].content }) + break; + } + + const chunk = decoder.decode(value, { stream: true }); + const lines = chunk.split('\n'); + + for (const line of lines) { + if (!line.startsWith('data:')) continue; + + const rawData = line.slice(5).trim(); + if (rawData === '[DONE]') continue; + + try { + jsonBuffer += rawData; + const data = JSON.parse(jsonBuffer); + jsonBuffer = ''; + let content = ''; + if (data.docs) { + for (let i = 0; i < data.docs.length; i++) { + content += data.docs[i] + } + } else { + content = data?.choices?.[0]?.delta?.content || ''; + } + if (!content) continue; + // 瀹炴椂鏇存柊 + this.messages[assistantIndex].content += content; + this.messages[assistantIndex].content = this.messages[assistantIndex].content.replace(/<\/?think>/g, ''); + await this.$nextTick(); + } catch { + // JSON涓嶅畬鏁达紝绛夊緟涓嬫鏁版嵁 + continue; + } + } + } + } catch (error) { + if (error.name !== 'AbortError') { + console.error('Request failed:', error); + this.messages[assistantIndex].content = '璇锋眰寮傚父'; + } + } + } + }, }; </script> @@ -229,9 +286,7 @@ .chat-messages { padding: 16px; margin-top: 14px; - overflow-y: auto; width: 800px; - height: 680px; } .message { @@ -280,9 +335,8 @@ } .chat-input { - padding: 16px; background-color: #fff; - width: 800px; + width: 100%; display: flex; flex-direction: row; justify-content: center; -- Gitblit v1.8.0