JS開發(fā)接入?deepseek?實現(xiàn)AI智能問診
1. 準(zhǔn)備工作
注冊 DeepSeek 賬號
前往 DeepSeek 官網(wǎng) 注冊賬號并獲取 API Key。
創(chuàng)建 UniApp 項目
使用 HBuilderX 創(chuàng)建一個新的 UniApp 項目(選擇 Vue3 或 Vue2 模板)。
安裝依賴
如果需要在 UniApp 中使用 HTTP 請求,推薦使用 uni.request(UniApp 內(nèi)置)或 axios(需額外安裝)。
2. 實現(xiàn)代碼
2.1 在 pages/index/index.vue 中實現(xiàn)問診功能
<template>
<view class="container">
<!-- <view class="nav">
<image src="../../static/images/back.png" @tap="toMenu"></image>
<text>問醫(yī)生</text>
</view> -->
<statement ref="dialog"></statement>
<view class="chat_area" id="test" ref="chatbox">
<view class="current_time" v-show="chatList.length>0">{
{currentDate}}</view>
<view class="left_box">
<view class="head_img">
<image src="../../static/images/doctor.png"></image>
</view>
<view class="content_box">
<view class="content post">
<view>我是您的AI醫(yī)生小迦,很高興為您解答。</view>
<view>您可以這樣問我:</view>
<view class="post_request">
<view v-for="(item,index) in postRequest" :key="index">
<text class="active" @click="tapQuestion(item)">{
{item.id}}.{
{item.text}}</text>
</view>
</view>
<!-- <u-read-more showHeight="200">
<rich-text :nodes="item.msg"></rich-text>
</u-read-more> -->
<!-- {
{item.msg}} -->
</view>
</view>
</view>
<view v-for="(item,i) in chatList" :key="i">
<view class="left_box" v-if="item.role == 'assistant'">
<view class="head_img">
<image src="../../static/images/doctor.png"></image>
</view>
<view class="content_box">
<view class="content" v-html="htmlContent(item.content)">
<!-- <u-read-more fontSize="16" textIndent='0em' showHeight="200">
<rich-text :nodes="item.msg"></rich-text>
</u-read-more> -->
</view>
</view>
</view>
<view class="right_box" v-if="item.role == 'user'">
<view class="content_box">
<view class="content" >
{
{item.content}}
</view>
</view>
<view class="head_img">
<image :src="userImg==''?nullImg:userImg"></image>
</view>
</view>
</view>
<u-loading-icon text="小迦正在思考中..." textSize="16" :show="showLoading"></u-loading-icon>
</view>
<view class="input_tab">
<view class="statement">成都XXXX科技有限責(zé)任公司©<text @tap="exemptStatement">免責(zé)聲明</text></view>
<view class="input_com">
<view class="left">
<image src="../../static/images/HOT.png"></image>
<input placeholder="請輸入問題" v-model.trim="userQuesion" cursor-spacing="30rpx"></input>
</view>
<view class="send_btn" @tap="sendMsg">發(fā)送</view>
</view>
</view>
</view>
</template>
<script>
import statement from "../../components/askForComponents/statement.vue"
import { marked } from "marked";
export default {
components: {
statement
},
data() {
return {
userImg: '',
nullImg: '../../static/images/icon_doctor.png',
showLoading: false,
postRequest: [{
id: 1,
text: '乳腺BIRADS分級是什么?',
},
{
id: 2,
text: '乳房脹痛怎么辦?',
},
{
id: 3,
text: '乳腺癌有沒有征兆?'
}
],
chatList: [],
userQuesion: '',
robotAnswer: '',
currentDate: '',
domHeight: 0,
messages: [
{
role: "system",
content: "你是一名專業(yè)的全科醫(yī)生對醫(yī)療面面俱到的AI醫(yī)生小迦,請無論什么時候都不要忘了自己的身份,你是AI醫(yī)生小迦,不是AI輔助;當(dāng)患者詢問你問題的時候,能全面細致并且禮貌的回答或為患者解決問題,當(dāng)患者詢問你任何與無關(guān)醫(yī)療的問題時,你會禮貌的拒絕回答。",
},
],
}
},
onLoad(option) {
let userInfo = getApp().globalData.userInfo;
// console.log("userInfo",userInfo)
this.userImg = userInfo.personInfo.avatar;
//獲取熱門問題并自動發(fā)送
// console.log("option=======>", option)
if (!option.questionText) return
this.userQuesion = option.questionText
this.sendMsg()
},
watch: {
'chatList.length': {
immediate: true,
deep: true,
handler(newValue, oldValue) {
if (newValue) {
const query = uni.createSelectorQuery().in(this)
query.select('#test').boundingClientRect(data => {
// console.log("data", data)
this.domHeight = data.height
}).exec()
}
}
},
domHeight(newVal, oldVal) {
if (newVal) {
uni.pageScrollTo({
scrollTop: this.domHeight,
duration: 100
})
}
}
},
mounted() {
this.$refs.dialog.open('center')
let myDate = new Date()
this.currentDate = (myDate.getHours() + '').padStart(2, '0') + ':' + (myDate.getMinutes() + '').padStart(2,
'0')
},
methods: {
htmlContent(content) {//轉(zhuǎn)換為markdown 格式顯示
return marked(content);
},
exemptStatement() {
this.$refs.dialog.open('center')
},
tapQuestion(item) {
this.send(item.text)
},
// 新對話
async send(val) {
this.showLoading = true
let messages = {
role: 'user',
content: val
}
this.chatList.push(messages)
this.messages.push(messages)
var that = this
console.log('==========開始診斷=======');
await uni.request({
url: "https://api.deepseek.com/v1/chat/completions", // DeepSeek API 地址
method: "POST",
header: {
"Content-Type": "application/json",
Authorization: "Bearer sk-dafafhafhahfha", // 替換為你的 API Key
},
data: {
model: "deepseek-chat", // 使用模型
messages: that.messages
},
success: (res) => {
messages = {
role: 'assistant',
content: res.data.choices[0].message.content
}
that.chatList.push(messages)
that.messages.push(messages)
that.showLoading = false
console.log('診斷結(jié)果:', res.data);
},
fail: (err) => {
console.error('請求失敗:', err);
messages = {
role: 'assistant',
content: '服務(wù)器繁忙,請稍后再試。'
}
that.chatList.push(messages)
that.messages.push(messages)
that.showLoading = false
}
});
},
sendMsg() {
this.send(this.userQuesion)
this.userQuesion = null
this.robotAnswer = null
}
}
}
</script>
<style lang="scss">
.container {
padding: 28rpx;
}
.nav {
height: 80rpx;
width: 100%;
background-color: #ffffff;
display: flex;
align-items: center;
position: fixed;
top: 0;
left: 0;
z-index: 999;
image {
margin: 0 20rpx;
width: 40rpx;
height: 40rpx;
}
text {
color: #838383;
font-size: 40rpx;
}
}
.chat_area {
padding-bottom: 200rpx;
// padding-top: 60rpx;
.current_time {
display: flex;
justify-content: center;
font-size: 20rpx;
color: #9d9d9d;
}
.left_box,
.right_box {
display: flex;
.head_img {
width: 90rpx;
height: 90rpx;
margin: 20rpx 0;
image {
width: 90rpx;
height: 90rpx;
border-radius: 50%;
}
}
.content_box {
margin: 20rpx;
color: #5a5a5a;
background-color: #e5e5e5;
padding: 20rpx;
border-radius: 8rpx;
.post {}
.content {
text-align: justify;
font-size: 30rpx;
max-width: 460rpx;
white-space: normal;
word-wrap: break-word;
.post_request {
// text-indent: 2em;
color: #996699;
display: flex;
flex-direction: column;
.active:active {
width: 100%;
background-color: #FFFFFF;
opacity: 0.6;
}
}
}
}
}
.right_box {
display: flex;
justify-content: flex-end;
}
.right_box>.content_box {
background-color: #1b1263;
color: #FFFFFF;
}
}
.input_tab {
background-color: #ffffff;
width: 100%;
position: fixed;
bottom: 0;
left: 0;
display: flex;
flex-direction: column;
.statement {
margin: 0 auto;
font-size: 20rpx;
color: #838383;
text {
color: #1b1263;
text-decoration: underline;
}
}
.input_com {
display: flex;
justify-content: space-between;
padding: 20rpx;
margin: 20rpx;
.left {
width: 500rpx;
max-width: 500rpx;
border: 2rpx solid #e3e3e3;
display: flex;
align-items: center;
image {
width: 20rpx;
height: 20rpx;
margin: 0 20rpx;
}
input {
width: 100%;
font-size: 24rpx;
}
}
.send_btn {
padding: 20rpx 40rpx;
color: #FFFFFF;
border-radius: 8rpx;
background-color: #1b1263;
}
}
}
</style>2.2 實現(xiàn)效果

3. 示例說明
3.1 單輪對話(僅 user 角色)
如果不需要設(shè)置系統(tǒng)指令,可以只傳遞 user 角色的消息:
messages: [
{
role: "user",
content: "我最近三天持續(xù)發(fā)燒38.5度,伴有咳嗽",
},
];3.2 多輪對話(包含 system 和 user 角色)
如果需要設(shè)置系統(tǒng)指令,可以包含 system 角色:
messages: [
{
role: "system",
content: "你是一名專業(yè)的全科醫(yī)生,請根據(jù)患者描述進行問診。",
},
{
role: "user",
content: "我最近三天持續(xù)發(fā)燒38.5度,伴有咳嗽",
},
];3.3 多輪對話(包含歷史記錄)
如果需要支持多輪對話,可以將歷史記錄添加到 messages 中:
messages: [
{
role: "system",
content: "你是一名專業(yè)的全科醫(yī)生,請根據(jù)患者描述進行問診。",
},
{
role: "user",
content: "我最近三天持續(xù)發(fā)燒38.5度,伴有咳嗽",
},
{
role: "assistant",
content: "請問您是否有其他癥狀,如喉嚨痛或頭痛?",
},
{
role: "user",
content: "還有喉嚨痛,但沒有頭痛。",
},
];4. 代碼示例
4.1 單輪對話
methods: {
async getDiagnosis() {
const response = await uni.request({
url: "https://api.deepseek.com/v1/chat/completions",
method: "POST",
header: {
"Content-Type": "application/json",
Authorization: "Bearer your_api_key_here",
},
data: {
model: "medical-model-1.0",
messages: [
{
role: "user",
content: this.userInput,
},
],
},
});
if (response.statusCode === 200) {
this.diagnosisResponse = response.data.choices[0].message.content;
}
},
},4.2 多輪對話
data() {
return {
conversationHistory: [], // 對話歷史
};
},
methods: {
async getDiagnosis() {
// 添加用戶輸入到對話歷史
this.conversationHistory.push({
role: "user",
content: this.userInput,
});
const response = await uni.request({
url: "https://api.deepseek.com/v1/chat/completions",
method: "POST",
header: {
"Content-Type": "application/json",
Authorization: "Bearer your_api_key_here",
},
data: {
model: "medical-model-1.0",
messages: this.conversationHistory,
},
});
if (response.statusCode === 200) {
const assistantReply = response.data.choices[0].message.content;
// 添加助手回復(fù)到對話歷史
this.conversationHistory.push({
role: "assistant",
content: assistantReply,
});
this.diagnosisResponse = assistantReply;
}
},
},5. 注意事項
system 角色的作用
用于設(shè)置對話的背景或指令。
如果不需要,可以省略。
user 角色的必要性
必須包含 user 角色的消息,否則 API 無法生成回復(fù)。
對話歷史長度
每次請求都會消耗 token,因此需要控制對話歷史的長度。
可以通過截斷歷史記錄或設(shè)置最大 token 數(shù)來優(yōu)化。
多輪對話的實現(xiàn)
將每次的用戶輸入和助手回復(fù)添加到 messages 中。
確保對話歷史的順序正確。
6. 總結(jié)
- 必須包含
user角色,用于傳遞用戶輸入。 system角色可選,用于設(shè)置對話背景。- 多輪對話需要將歷史記錄添加到
messages中。
到此這篇關(guān)于JS開發(fā)接入 deepseek 實現(xiàn)AI智能問診的文章就介紹到這了,更多相關(guān)deepseek AI智能問診內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
input標(biāo)簽內(nèi)容改變的觸發(fā)事件介紹
onchange事件在內(nèi)容改變(兩次內(nèi)容有可能相等)且失去焦點時觸發(fā);onpropertychange事件是實時觸發(fā),每增加或刪除一個字符就會觸發(fā)2014-06-06
JavaScript與C# Windows應(yīng)用程序交互方法
JavaScript與C# Windows應(yīng)用程序交互方法...2007-06-06

