个人可以做企业网站,Wordpress现有数据库表,为什么sem的工资都不高,腾讯云 怎样建设网站思路分析#xff1a;
如何实现用户终止AI正在进行的回答#xff1f;
分析实现思路如下#xff1a;
首先是在用户点击发送后#xff0c;切换终止对话#xff0c;点击后大模型终止对话#xff0c;停止sse#xff0c;不再接收后端的消息。同时因为对话记录存入数据库是后…思路分析
如何实现用户终止AI正在进行的回答
分析实现思路如下
首先是在用户点击发送后切换终止对话点击后大模型终止对话停止sse不再接收后端的消息。同时因为对话记录存入数据库是后端的任务所以这里也要在后端增加一个接口处理。
前端有三种情况
还未接收到回答 此时直接将对话内容切换为 用户已终止回答返回后端的doc和ans都为空 已经显示了知识库的检索内容doc但是还未显示回答 因为dac是一次生成的而不是多次拼接所以doc只有 有和没有 两种情况返回后端的docans置空 显示了回答 终止接收sse给answer拼接上“当前回答已经终止。返回后端前端已经展示的answer后端加入数据库作为历史记录
代码实现
因为后端插入是原子性插入所以要同时返回用户请求问题和当前回答接口设置如下
class StopChat(BaseModel):conv_id: strquery: strcurrent_docs: List[str] | None []current_ans: str | None button实现
首先实现点击发送后按钮的变化
将发送按钮转变为停止直到用户停止或者回答结束再改为发送
通过currentAiReply.value判断当前回答的状态如果为true则表明ai正在回答将按钮改为停止如果为false表明当前暂时没有回答button为发送。
实现changeButton方法如下
//改变button状态
const changeButton () {if(currentAiReply.valuetrue){button.value.text停止;button.value.typeinfo;}else{button.value.text发送;button.value.typeprimary;}
}在onSend(button点击方法)和ssechat的onclose中在currentAiReply状态改变时分别调用该方法即可改变按钮状态。
用户终止回答
然后实现用户点击停止后终止ai回答并回复后端此时ai生成内容。
考虑到后端已经实现了拼接字符串所以返回后端的doc和ans都是中断的原文但是返回给用户的还是需要再次拼接上 “\n(用户已终止对话)\n”。
如何实现
首先使用abort终止当前请求并加上一个bool判断终止字符串的拼接。
const controller new AbortController();
const signal controller.signal;加上一个bool判断终止字符串的拼接
//用户是否终止当前回答 默认为未终止
let isUserAbort ref(false);在sse的onmessage中加上判断如果isUerAbort为false就继续拼接否则不执行。
然后在onSend按钮中修改逻辑
当回答处于第一种情况还没有返回值时也就是当前的AIReplay为 大模型正在生成回答请耐心等待’,‘wait’);
不做任何更改
当回答处于第二种情况时有docs返回但是还没有回答生成修改docs为ssechat中的docs
//第二种情况有docs返回但是还没有回答生成else if(latestMsg.aiTypedocs){returnData.current_docscurrentDocs.value;}第三种情况时修改返回的docs和ans //第三种情况有回答生成else if(latestMsg.aiTypetext){//要记得添加docsreturnData.current_docscurrentDocs.value;returnData.current_anslatestMsg.content;}接下来调用stopChat接口如果返回值为200,分别对三种情况进行如下修改:
第一种情况
if(latestMsg.aiTypewait){msgList.pop();AIReplay((用户已终止对话)\n,text);
}第二种情况
if( latestMsg.aiTypedocs){AIReplay((用户已终止对话)\n,text);
}第三种情况
else if(latestMsg.aiTypetext){latestMsg.contentlatestMsg.content\n(用户已终止对话)\n;
}最后改变按钮的状态
currentAiReply.valuefalse;
changeButton();关键点分析
实验的过程中我遇到了一些问题主要有以下几点
aiType-typedocs的返回格式问题
aiType-type
尝试请求如下 响应为
{code: 500,msg: 终止对话失败,data: {error: unsupported operand type(s) for : NoneType and str}
}但是查看longchat的后端返回的200 log输出发现明明条件满足都是根本没有执行if中对三个状态的判断。
重新审查代码意识到了msgList中设置了type和aiType其中type是用来判断当前回答是用户的还是ai的aiType是用来判断ai回答的类型比如docstext和wait。
将判断条件中的type改为aiType即可。
docs的返回格式问题
接口要求的docs格式为list我的返回值是onMessage中得到的currentDocs.valueparsedData.data.docs;
成功调用接口但是从历史记录重新进入问答定位错误显示docs解析失败。
那就只有数据库的docs存储有问题。
查看正确可以解析的回答格式 对比错误的回答格式可以发现两个问题
当前的docs中少了键值对是直接将list作为docs插入缺少新的嵌套插入的是list而不是字符串
这两个问题都需要更改后端接口更改如下
# 在列表推导式中,将列表中的每个元素转换为字符串。
docs:{docs:[str(x) for x in sc.current_docs]}重新运行在第一种情况下点击终止时报错终止失败报错如下 这个是因为后端有校验将current_docs的默认返回值改为[]即可
还有就是查看历史记录时要考虑到用户终止后docs为空的情况不输出增加length判断即可
if(docs.length!0){extractTextFromSpan(docs)AIReplay(参考\ndocs.join(),docs);
}测试问题
周易第一卦是什么周易第二卦是什么周易第三卦是什么周易第四卦是什么周易第五卦是什么周易第六卦是什么周易第七卦是什么
实现效果
第一种情况 第二种情况 第三种情况