基于TinyMce富文本編輯器的客服自研知識(shí)庫(kù)的技術(shù)探索和實(shí)踐
一、背景
二、富文本編輯器的選型
1. 編輯器的選擇
2. TinyMce編輯器模式的選擇
三、系統(tǒng)總覽
1. 知識(shí)創(chuàng)建鏈路
2. 知識(shí)采編
3. 應(yīng)用場(chǎng)景
四、問(wèn)題和解決方案
1. 解決圖片遷移問(wèn)題
2. 解決加載大量圖片帶來(lái)的頁(yè)面卡頓問(wèn)題
3. 模板縮略圖
4. 全局查找/替換
五、總結(jié)
一、背景
客服知識(shí)庫(kù)是一個(gè)集中管理和存儲(chǔ)與客服相關(guān)的信息和資源的系統(tǒng),在自研知識(shí)庫(kù)上線之前,得物采用的承接工具為第三方知識(shí)庫(kù)系統(tǒng)。伴隨著業(yè)務(wù)的發(fā)展,知識(shí)的維護(hù)體量、下游系統(tǒng)的使用面臨的問(wèn)題愈發(fā)明顯,而當(dāng)前的第三方采購(gòu)系統(tǒng),已經(jīng)較難滿足內(nèi)部系統(tǒng)間高效協(xié)作的訴求,基于以上業(yè)務(wù)訴求,我們自研了一套客服知識(shí)庫(kù)。
二、富文本編輯器的選型
以下是經(jīng)過(guò)調(diào)研后列出的多款富文本編輯器綜合對(duì)比情況:
圖片
編輯器的選擇
- 自研知識(shí)庫(kù)要求富文本編輯器具備表格的編輯能力,由于Quill不支持表格編輯能力(借助表格插件可以實(shí)現(xiàn)該能力,但經(jīng)過(guò)實(shí)際驗(yàn)證,插件提供的表格編輯能力不夠豐富,使用體驗(yàn)也較差),被首先被排除。
- wangEditor體驗(yàn)過(guò)程中發(fā)現(xiàn)標(biāo)題和列表(有序、無(wú)序)列表兩個(gè)功能互斥,體驗(yàn)不太好,而這兩個(gè)功能都是自研知識(shí)庫(kù)剛需功能,也被排除。
- Lexical是facebook推出的一款編輯器,雖功能很豐富,但相較于CKEditor和TinyMCE,文檔不夠完善,社區(qū)活躍性較低,插件不成熟,故優(yōu)先選擇CKEditor和TinyMCE。
CKEditor和TinyMCE經(jīng)過(guò)對(duì)比,由于當(dāng)前正在使用的第三方知識(shí)庫(kù)采用的是TinyMCE編輯器,選擇TinyMC在格式兼容上會(huì)更友好,對(duì)新老知識(shí)庫(kù)的遷移上更有利。且TinyMCE在功能豐富度上略占優(yōu)勢(shì),故最終選擇TinyMCE作為本系統(tǒng)文檔知識(shí)庫(kù)的編輯器。
TinyMce編輯器模式的選擇
經(jīng)典模式(默認(rèn)模式)
基于表單,使用表單某字段填充內(nèi)容,編輯器始終作為表單的一部分。內(nèi)部采用了iframe沙箱隔離,將編輯內(nèi)容與頁(yè)面進(jìn)行隔離。
※ 優(yōu)勢(shì)
樣式隔離好。
※ 劣勢(shì)
由于使用iframe,性能會(huì)差點(diǎn),尤其對(duì)于多實(shí)例編輯器。
內(nèi)聯(lián)模式(沉浸模式)
將編輯視圖與閱讀視圖合二為一,當(dāng)其被點(diǎn)擊后,元素才會(huì)被編輯器替換。而不是編輯器始終可見(jiàn),不能作為表單項(xiàng)使用。內(nèi)容會(huì)從它嵌入的頁(yè)面繼承CSS樣式表。
※ 優(yōu)勢(shì)
性能相對(duì)較好,頁(yè)面的編輯視圖與閱讀視圖合二為一,提供了無(wú)縫的體驗(yàn),實(shí)現(xiàn)了真正的所見(jiàn)即所得。
※ 劣勢(shì)
樣式容易受到頁(yè)面樣式的影響。
三、系統(tǒng)總覽
知識(shí)創(chuàng)建鏈路

知識(shí)采編
結(jié)構(gòu)化段落
為了對(duì)知識(shí)文檔做更細(xì)顆粒度的解析,客服知識(shí)庫(kù)采用了結(jié)構(gòu)化段落的設(shè)計(jì)思想,每個(gè)段落都會(huì)有一個(gè)唯一標(biāo)志,且支持對(duì)文檔的每個(gè)段落單獨(dú)設(shè)置標(biāo)簽,這樣在后期的知識(shí)檢索、分類時(shí),便可以精確定位到知識(shí)文檔的具體段落,如下圖所示。
知識(shí)文檔編輯頁(yè)面
應(yīng)用場(chǎng)景
客服知識(shí)庫(kù)的主要應(yīng)用場(chǎng)景如下:
知識(shí)檢索
基于傳統(tǒng)的ES檢索能力,用于知識(shí)庫(kù)的檢索,檢索要使用的知識(shí),且可以直接在工作臺(tái)打開(kāi)對(duì)應(yīng)的知識(shí)并瀏覽,并可以定位、滾動(dòng)到具體的知識(shí)段落。同時(shí)還會(huì)高亮顯示知識(shí)文檔中匹配到的搜索關(guān)鍵字。
圖片
智能問(wèn)答(基于大模型能力和知識(shí)庫(kù)底層數(shù)據(jù)的訓(xùn)練)
※ RAG出話
輔助客服了解用戶的真實(shí)意圖,可用于客服作業(yè)時(shí)的參考。
原理闡述:RAG是一種結(jié)合了檢索和生成技術(shù)的人工智能系統(tǒng)。它是大型語(yǔ)言模型的一種,但特別強(qiáng)調(diào)檢索和生成的結(jié)合。RAG的最主要的工作流程包括:
- 檢索階段:系統(tǒng)會(huì)根據(jù)用戶的查詢,從客服知識(shí)庫(kù)中檢索出相關(guān)信息。這些信息可能包括知識(shí)庫(kù)內(nèi)容、訂單信息和商品信息等。
- 生成階段:RAG使用檢索到的信息來(lái)增強(qiáng)其生成過(guò)程。這意味著,生成模型在生成文本時(shí),會(huì)考慮到檢索到的相關(guān)信息,以生成更準(zhǔn)確、更相關(guān)的回答。你可以直接將搜索到的內(nèi)容返回給用戶也可以通過(guò)LLM模型結(jié)合后生成給用戶。
※ 答案推薦
可以根據(jù)用戶搜索內(nèi)容、上下文場(chǎng)景(如訂單信息、商品信息)輔助客服更高效的獲取答案。
流程示意:
圖片
圖片
※ 聯(lián)網(wǎng)搜索
當(dāng)RAG出話由于拒識(shí)沒(méi)有結(jié)果時(shí),便嘗試進(jìn)行聯(lián)網(wǎng)搜索給出結(jié)果,可作為RAG能力失效后的補(bǔ)充能力。
原理闡述:底層使用了第三方提供的聯(lián)網(wǎng)問(wèn)答Agent服務(wù)。在進(jìn)行聯(lián)網(wǎng)搜索之前,會(huì)對(duì)用戶的查詢信息進(jìn)行風(fēng)控校驗(yàn),風(fēng)控校驗(yàn)通過(guò)后,再進(jìn)行【指定意圖清單】過(guò)濾,僅對(duì)符合意圖的查詢才可以進(jìn)行聯(lián)網(wǎng)搜索。
圖片
圖片
四、問(wèn)題和解決方案
解決圖片遷移問(wèn)題
背景
在新老知識(shí)遷移的過(guò)程中,由于老知識(shí)庫(kù)中的圖片鏈接的域名是老知識(shí)庫(kù)的域名,必須要有老知識(shí)庫(kù)的登錄臺(tái)信息,才能在新知識(shí)庫(kù)中訪問(wèn)并渲染。為了解決這個(gè)問(wèn)題,我們對(duì)用戶粘貼的動(dòng)作進(jìn)行了監(jiān)聽(tīng),并對(duì)復(fù)制內(nèi)容的圖片鏈接進(jìn)行了替換。
時(shí)序圖
圖片
核心邏輯
/**
* 替換編輯器中的圖片URL
* @param content
* @param editor 編輯器實(shí)例
* @returns 替換后的內(nèi)容
*/
export const replaceImgUrlOfEditor = (content, editor) => {
// 提取出老知識(shí)中的圖片訪問(wèn)鏈接
const oldImgUrls = extractImgSrc(content);
// 調(diào)用接口獲取替換后的圖片訪問(wèn)鏈接
const newImageUrls = await service.getNewImageUrl(oldImgUrls);
// 將老知識(shí)庫(kù)的圖片鏈接替換成新的可訪問(wèn)的鏈接
newContent = replaceImgSrc(newContent, replacedUrls.imgUrls);
// 使用新的數(shù)據(jù)更新編輯器視圖
editor.updateView(newContent);
};解決加載大量圖片帶來(lái)的頁(yè)面卡頓問(wèn)題
背景
知識(shí)庫(kù)內(nèi)含有大量的圖片,當(dāng)我們打開(kāi)一篇知識(shí)時(shí),系統(tǒng)往往因?yàn)樵诙虝r(shí)間內(nèi)加載、渲染大量的圖片而陷入卡頓當(dāng)中,無(wú)法對(duì)頁(yè)面進(jìn)行其他操作。這個(gè)問(wèn)題在老知識(shí)庫(kù)中尤為嚴(yán)重,也是研發(fā)新知識(shí)庫(kù)過(guò)程中我們需要重點(diǎn)解決的問(wèn)題。
解決方案
我們對(duì)圖片進(jìn)行了懶加載處理:當(dāng)打開(kāi)一篇知識(shí)時(shí),只加載和渲染可見(jiàn)視圖以內(nèi)的圖片,剩余的圖片只有滾動(dòng)到可見(jiàn)視圖內(nèi)才開(kāi)始加載、渲染。
由于我們要渲染的內(nèi)容的原始數(shù)據(jù)是一段html字符串,一篇知識(shí)文檔的最小可渲染單元是段落(結(jié)構(gòu)化段落),而一個(gè)段落的內(nèi)容大小事先是不知道的,因此傳統(tǒng)的滾動(dòng)加載方式在這里并不適用:比如當(dāng)滾動(dòng)到需要加載下一段落的位置時(shí),如果該段落的內(nèi)容特別大且包含較多圖片時(shí),依然會(huì)存在卡頓的現(xiàn)象。
我們采用正則匹配的方式,識(shí)別出知識(shí)文檔的html中所有的 <img> 標(biāo)簽(將文檔的html視作一段字符串),并給 <img> 標(biāo)簽插入 loading="lazy" 的屬性,具備該屬性的圖片在到達(dá)可視視圖內(nèi)的時(shí)候才會(huì)加載圖片資源并渲染,從而實(shí)現(xiàn)懶加載的效果,大大節(jié)省了知識(shí)文檔初次渲染的性能開(kāi)銷。并且該過(guò)程處理的是渲染知識(shí)文檔前的html字符串,而非真實(shí)的dom操作,所以不會(huì)帶來(lái)重繪、重排等性能問(wèn)題。
知識(shí)文檔渲染的完整鏈路
圖片
模板縮略圖
背景
在知識(shí)模板列表頁(yè)或者在創(chuàng)建新知識(shí)選擇模板時(shí),需要展示模板內(nèi)容的縮略圖,由于每個(gè)模板內(nèi)容都不一樣,同時(shí)縮略圖中需要可以看到該模板靠前的內(nèi)容,以便用戶除了依靠模板標(biāo)題之外還可以依靠一部分的模板內(nèi)容選擇合適的模板。
解決方案
在保存知識(shí)模板前,通過(guò)截屏的方式保存一個(gè)模板的截圖,上傳截圖到cdn并保存cdn鏈接,再對(duì)截圖進(jìn)行一定的縮放調(diào)整,即可作為模板的縮略圖。
時(shí)序圖
圖片
實(shí)際效果
模板列表中縮略圖展示效果:
圖片
新建知識(shí)時(shí)縮略圖展示效果:
圖片
全局查找/替換
背景
知識(shí)庫(kù)采用了結(jié)構(gòu)化段落的設(shè)計(jì)思想,技術(shù)實(shí)現(xiàn)上,每個(gè)段落都是一個(gè)獨(dú)立的編輯器實(shí)例。這樣實(shí)現(xiàn)帶來(lái)一個(gè)弊端:使用編輯器的搜索和替換功能時(shí),查找范圍僅限于當(dāng)前聚焦的編輯器,無(wú)法同時(shí)對(duì)所有編輯器進(jìn)行查找和替換,增加了業(yè)務(wù)方的編輯費(fèi)力度。
解決方案
調(diào)研、擴(kuò)展編輯器的查找/替換插件的源碼,調(diào)度和聯(lián)動(dòng)多編輯器的查找/替換API從而實(shí)現(xiàn)全局范圍內(nèi)的查找/替換。
※ 插件源碼剖析
通過(guò)對(duì)插件源碼的分析,我們發(fā)現(xiàn)插件的查找/替換功能是基于4個(gè)基本的API實(shí)現(xiàn)的: find 、 replace 、 next 、 prev 、 done 。
※ 設(shè)計(jì)思路
通過(guò)在多個(gè)編輯器中加入一個(gè)調(diào)度器來(lái)控制編輯器之間的接力從而實(shí)現(xiàn)全局的查找/替換。同時(shí)擴(kuò)展插件的API,輔助調(diào)度器在多編輯器之間進(jìn)行調(diào)度。
※ 插件源碼API擴(kuò)展
- hasMatched:判斷當(dāng)前編輯器是否匹配到關(guān)鍵字。
- hasReachTop:判斷當(dāng)前編輯器是否已到達(dá)所查找關(guān)鍵字的最前一個(gè)。
- hasReachBottom:判斷當(dāng)前編輯器是否已到達(dá)所查找關(guān)鍵字的最后一個(gè)。
- current:滾動(dòng)到編輯器當(dāng)前匹配到的關(guān)鍵字的位置。
- clearCurrentSelection:對(duì)編輯器當(dāng)前匹配到的關(guān)鍵字取消高亮效果。
圖片
UI替換
屏蔽插件自帶的查找/替換的彈窗,實(shí)現(xiàn)一個(gè)支持全局操作的查找/替換的彈窗:使用了react-rnd組件庫(kù)實(shí)現(xiàn)可拖拽彈窗,如下圖所示:
圖片
「查找」
※ 期望效果
當(dāng)用戶輸入關(guān)鍵字并點(diǎn)擊查找時(shí),需要在文檔中(所有編輯器中)標(biāo)記出(加上特定的背景色)所有匹配到該關(guān)鍵字的文本,并高亮顯示出第一個(gè)匹配文本。
※ 流程圖
圖片
「下一個(gè)」
※ 期望效果
當(dāng)用戶點(diǎn)擊「下一個(gè)」時(shí),需要高亮顯示下一個(gè)匹配結(jié)果并滾動(dòng)到該匹配結(jié)果的位置。
※ 流程圖
圖片
五、總結(jié)
在新版客服知識(shí)庫(kù)的研發(fā)和落地過(guò)程中,我們基于TinyMce富文本編輯器的基礎(chǔ)上,進(jìn)行了功能擴(kuò)展和定制。這期間既有參考過(guò)同類產(chǎn)品(飛書(shū)文檔、語(yǔ)雀)的方案,也有根據(jù)實(shí)際應(yīng)用場(chǎng)景進(jìn)行了創(chuàng)新。截止目前已完成1000+老知識(shí)庫(kù)的順利遷移,系統(tǒng)穩(wěn)定運(yùn)行。
自研過(guò)程中我們解決了老版知識(shí)庫(kù)系統(tǒng)的卡頓和無(wú)法滿足定制化需求的問(wèn)題。并在這些基本需求得到滿足的情況下,通過(guò)優(yōu)化交互方式和知識(shí)文檔的加載、渲染性能等方式進(jìn)一步提升了使用體驗(yàn)。
后續(xù)我們會(huì)結(jié)合用戶的反饋和實(shí)際使用需求進(jìn)一步優(yōu)化和擴(kuò)展客服知識(shí)庫(kù)的功能,也歡迎有同樣應(yīng)用場(chǎng)景的同學(xué)一起交流想法和意見(jiàn)。





























