療知識(shí)圖譜問(wèn)答系統(tǒng):從圖譜構(gòu)建到Neo4j查詢的完整鏈路解析)
從接觸醫(yī)療知識(shí)圖譜問(wèn)答系統(tǒng)這個(gè)方向開(kāi)始我陸陸續(xù)續(xù)看過(guò)不少開(kāi)源項(xiàng)目但這個(gè)倉(cāng)庫(kù)給我的印象特別深。它沒(méi)有堆砌復(fù)雜的模型而是用一套完整但門(mén)檻不高的工程鏈路把醫(yī)學(xué)知識(shí)結(jié)構(gòu)化、自然語(yǔ)言問(wèn)句理解、圖數(shù)據(jù)庫(kù)查詢這三件事串了起來(lái)。這篇文章就是我對(duì) QASystemOnMedicalKG-master 的探索記錄包含代碼閱讀思路、知識(shí)圖譜構(gòu)建細(xì)節(jié)、問(wèn)答鏈路拆解、復(fù)現(xiàn)時(shí)踩過(guò)的坑以及我基于這套系統(tǒng)做的改進(jìn)實(shí)驗(yàn)。如果你想快速入門(mén)醫(yī)療垂直領(lǐng)域的問(wèn)答系統(tǒng)或者正在糾結(jié)知識(shí)圖譜到底怎么落地這篇記錄應(yīng)該能給你一個(gè)比較完整的參考。我先把話說(shuō)在前面這個(gè)項(xiàng)目不是那種開(kāi)箱即用、放上生產(chǎn)環(huán)境就能直接服役的成品它是很好的教學(xué)樣板和學(xué)習(xí)骨架。你需要理解它的設(shè)計(jì)邏輯再根據(jù)業(yè)務(wù)數(shù)據(jù)去做二次改造。下文我會(huì)按照我自己的閱讀順序來(lái)展開(kāi)——先看整體架構(gòu)再看圖譜構(gòu)建然后是問(wèn)答引擎核心最后聊查詢性能和踩坑經(jīng)驗(yàn)。1. 先摸清楚項(xiàng)目到底在做什么三大模塊與一條主鏈路1.1 從目錄結(jié)構(gòu)反推系統(tǒng)架構(gòu)拿到一個(gè)開(kāi)源項(xiàng)目我一般不會(huì)急著去跑代碼而是先看目錄結(jié)構(gòu)和入口腳本。這套系統(tǒng)最直觀的劃分是三個(gè)部分?jǐn)?shù)據(jù)準(zhǔn)備、圖譜構(gòu)建與導(dǎo)入、問(wèn)答服務(wù)。數(shù)據(jù)準(zhǔn)備負(fù)責(zé)把原始的醫(yī)學(xué)資料整理成結(jié)構(gòu)化三元組圖譜構(gòu)建部分負(fù)責(zé)把這些三元組清洗、去重、關(guān)聯(lián)最終導(dǎo)入圖數(shù)據(jù)庫(kù)問(wèn)答服務(wù)則接收用戶輸入的中文問(wèn)句完成意圖識(shí)別、實(shí)體抽取、查詢語(yǔ)句生成和答案返回。這種分層非常清晰也符合大多數(shù)知識(shí)圖譜問(wèn)答項(xiàng)目的基本套路。我建議你在看任何類(lèi)似項(xiàng)目時(shí)都先問(wèn)自己一個(gè)問(wèn)題這個(gè)項(xiàng)目的數(shù)據(jù)源頭是什么數(shù)據(jù)是怎么變成圖的用戶輸入是怎么被路由到圖查詢的把這三個(gè)問(wèn)題的答案找出來(lái)整個(gè)項(xiàng)目的主干脈絡(luò)就清楚了。1.2 數(shù)據(jù)是醫(yī)療問(wèn)答系統(tǒng)的血液醫(yī)療知識(shí)圖譜問(wèn)答系統(tǒng)最核心的資產(chǎn)不是算法而是數(shù)據(jù)。這個(gè)項(xiàng)目里的數(shù)據(jù)主要由疾病、癥狀、藥物、食物、檢查項(xiàng)目等實(shí)體類(lèi)型以及它們之間的語(yǔ)義關(guān)系組成。比如“高血壓”和“頭暈”之間是“表現(xiàn)為”的關(guān)系“糖尿病”和“胰島素”之間是“推薦用藥”的關(guān)系。為什么要用知識(shí)圖譜而不是傳統(tǒng)的表格因?yàn)獒t(yī)療知識(shí)本身是網(wǎng)狀結(jié)構(gòu)。一個(gè)疾病關(guān)聯(lián)多種癥狀一種癥狀又可能指向多種疾病一種藥物有適用癥也可能有禁忌癥。這種多對(duì)多、跨層級(jí)、帶語(yǔ)義標(biāo)簽的關(guān)系用二維表表達(dá)非常吃力但用圖來(lái)表達(dá)就非常自然。圖數(shù)據(jù)庫(kù)里節(jié)點(diǎn)是實(shí)體邊是關(guān)系用戶可以順著某條路徑去檢索“從疾病出發(fā)經(jīng)過(guò)癥狀節(jié)點(diǎn)再到達(dá)相關(guān)檢查項(xiàng)目”這類(lèi)多跳問(wèn)題。這個(gè)項(xiàng)目把這一整套流程都串了起來(lái)。我在探索時(shí)的體會(huì)是它的價(jià)值不在某個(gè)單點(diǎn)算法有多強(qiáng)而在讓你看到一條完整的、可以被復(fù)刻的落地鏈路。這也是我推薦從它入手的原因。2. 知識(shí)圖譜構(gòu)建疾病、癥狀、藥物之間如何被結(jié)構(gòu)化2.1 實(shí)體類(lèi)型與關(guān)系類(lèi)型的設(shè)計(jì)先聊實(shí)體類(lèi)型。這套系統(tǒng)把醫(yī)療領(lǐng)域信息抽象成六個(gè)左右的實(shí)體類(lèi)別包括疾病、癥狀、藥物、食物、檢查項(xiàng)目、身體部位等。每種實(shí)體在圖中都有對(duì)應(yīng)的節(jié)點(diǎn)標(biāo)簽節(jié)點(diǎn)屬性一般是名稱(chēng)、別名、所屬科室、常見(jiàn)程度等。關(guān)系類(lèi)型則圍繞疾病展開(kāi)比如疾病和癥狀之間的“表現(xiàn)為”、疾病和藥物之間的“推薦用藥”、疾病和檢查項(xiàng)目之間的“適合檢查”、疾病和食物之間的“宜吃”和“忌吃”等。這個(gè)設(shè)計(jì)看起來(lái)不復(fù)雜但它是后續(xù)所有問(wèn)答邏輯的基礎(chǔ)。因?yàn)閱?wèn)答系統(tǒng)生成查詢語(yǔ)句時(shí)本質(zhì)上就是把用戶問(wèn)句里的實(shí)體和意圖映射為圖上的節(jié)點(diǎn)和關(guān)系。比如用戶問(wèn)“感冒應(yīng)該吃什么藥”系統(tǒng)要做兩件事識(shí)別出“感冒”這個(gè)疾病實(shí)體再判斷出意圖是“推薦用藥”然后生成一條從疾病節(jié)點(diǎn)到藥物節(jié)點(diǎn)的查詢路徑。如果關(guān)系類(lèi)型設(shè)計(jì)得不夠明確這一步就會(huì)非常難受。我特別想強(qiáng)調(diào)命名規(guī)范的重要性。這個(gè)項(xiàng)目里關(guān)系類(lèi)型大多采用統(tǒng)一的動(dòng)詞短語(yǔ)比如“HAS_SYMPTOM”“RECOMMEND_DRUG”。我建議你在自己的項(xiàng)目里也保持這種清晰的命名習(xí)慣因?yàn)樵趯?xiě)問(wèn)答模板時(shí)這些關(guān)系名會(huì)被直接拼進(jìn)查詢語(yǔ)句命名越一致模板維護(hù)成本越低。2.2 數(shù)據(jù)清洗與導(dǎo)入Neo4j的細(xì)節(jié)圖譜構(gòu)建里最花時(shí)間的往往不是設(shè)計(jì)而是清洗。原始數(shù)據(jù)可能來(lái)自醫(yī)療百科、結(jié)構(gòu)化表格或人工整理基本都會(huì)包含重復(fù)實(shí)體、同義名稱(chēng)、空屬性、亂碼字符等問(wèn)題。比如同一個(gè)藥物在不同數(shù)據(jù)源里可能寫(xiě)作“阿司匹林”和“乙酰水楊酸”如果不做歸一化圖譜里就會(huì)出現(xiàn)兩個(gè)孤立的節(jié)點(diǎn)查詢時(shí)用戶說(shuō)哪個(gè)都只能查到一半。我當(dāng)時(shí)復(fù)現(xiàn)這個(gè)項(xiàng)目時(shí)數(shù)據(jù)處理部分主要做了三類(lèi)操作。第一是去重按實(shí)體名稱(chēng)歸一化后合并重復(fù)節(jié)點(diǎn)。第二是補(bǔ)全關(guān)系只保留兩個(gè)節(jié)點(diǎn)都存在的三元組避免產(chǎn)生懸掛節(jié)點(diǎn)。第三是字段清洗把科室、藥品劑量等屬性中的空格、換行、特殊符號(hào)去掉統(tǒng)一格式。導(dǎo)入Neo4j這一步也有講究。這個(gè)項(xiàng)目的數(shù)據(jù)規(guī)模不大常規(guī)做法是用Cypher的LOAD CSV或者直接通過(guò)Python驅(qū)動(dòng)批量寫(xiě)入。批量寫(xiě)入時(shí)要注意把節(jié)點(diǎn)先創(chuàng)建完再創(chuàng)建邊否則會(huì)出現(xiàn)“關(guān)系引用了不存在的節(jié)點(diǎn)”這類(lèi)錯(cuò)誤。如果數(shù)據(jù)量更大比如幾十萬(wàn)以上節(jié)點(diǎn)就得考慮使用Neo4j Admin Import這樣的離線導(dǎo)入工具把數(shù)據(jù)轉(zhuǎn)成CSV頭文件再導(dǎo)入速度快好幾個(gè)數(shù)量級(jí)。3. 問(wèn)答引擎核心鏈路從自然語(yǔ)言到Cypher查詢3.1 中文問(wèn)句的識(shí)別與實(shí)體鏈接問(wèn)答鏈路是整個(gè)系統(tǒng)最讓人興奮的部分。用戶輸入是一句口語(yǔ)化的中文問(wèn)句比如“高血壓病人平時(shí)吃什么降壓藥比較好”而系統(tǒng)內(nèi)部需要把它轉(zhuǎn)成一條可執(zhí)行的圖查詢。這個(gè)轉(zhuǎn)換過(guò)程大體分為兩步先抽取實(shí)體再判斷意圖。實(shí)體抽取這一層項(xiàng)目采用了詞典與分詞工具結(jié)合的方式。思路是準(zhǔn)備一個(gè)包含疾病名、癥狀名、藥物名的自定義詞典在分詞階段就盡量讓專(zhuān)業(yè)術(shù)語(yǔ)完整切分。比如“高血壓”這個(gè)詞如果按普通分詞可能被切出“血壓”有了詞典約束才能把它作為一個(gè)完整實(shí)體返回。我實(shí)測(cè)下來(lái)這個(gè)方案對(duì)常見(jiàn)的疾病名、藥物名覆蓋效果不錯(cuò)遇到不認(rèn)識(shí)的專(zhuān)有名詞就會(huì)失效所以后期又補(bǔ)充了基于規(guī)則的回退機(jī)制當(dāng)詞典匹配不到時(shí)嘗試從原文中提取包含“疾病”“藥物”等后綴詞的片段再和圖譜里的節(jié)點(diǎn)模糊匹配。實(shí)體鏈接則是把抽取出的實(shí)體名映射到圖譜中的具體節(jié)點(diǎn)。這里有個(gè)隱藏問(wèn)題一個(gè)實(shí)體可能有多個(gè)名字。我在改進(jìn)時(shí)加了一張同義詞映射表把凡是節(jié)點(diǎn)屬性中包含別名的表述都指向主節(jié)點(diǎn)例如“高血壓”和“essential hypertension”這樣的中外文表述。就這一個(gè)改動(dòng)讓問(wèn)答命中率提升了不止一點(diǎn)點(diǎn)。3.2 模板解析的多個(gè)分支意圖識(shí)別的作用是決定用戶到底要問(wèn)什么。這個(gè)項(xiàng)目把意圖劃分為若干類(lèi)常見(jiàn)的包括疾病癥狀查詢、疾病治療用藥查詢、疾病宜吃忌吃查詢、疾病檢查項(xiàng)目查詢、科室查詢等。每個(gè)意圖類(lèi)型對(duì)應(yīng)至少一個(gè)查詢模板模板里預(yù)留實(shí)體槽位比如“{疾病}吃什么藥”對(duì)應(yīng)“推薦用藥”。模板匹配的具體思路是把問(wèn)句和預(yù)定義好的句式規(guī)則做比對(duì)。這里不是靠深度學(xué)習(xí)模型而是靠規(guī)則加關(guān)鍵詞權(quán)重。比如句子中出現(xiàn)了“癥狀”“表現(xiàn)”“什么感覺(jué)”等詞系統(tǒng)判斷意圖偏向癥狀查詢出現(xiàn)“吃什么藥”“治療”“用藥”等詞則偏向用藥查詢。這種做法的優(yōu)點(diǎn)是實(shí)現(xiàn)簡(jiǎn)單、完全可控缺點(diǎn)是覆蓋不全換一種沒(méi)見(jiàn)過(guò)的問(wèn)法就可能誤判。我在自己的改進(jìn)實(shí)驗(yàn)里給每個(gè)意圖類(lèi)型都增加了正例和反例句子通過(guò)小規(guī)模分類(lèi)模型做增強(qiáng)效果比純規(guī)則穩(wěn)定了一些。3.3 一個(gè)完整問(wèn)答示例我拿“糖尿病有哪些常見(jiàn)并發(fā)癥”這個(gè)問(wèn)句走了一遍完整鏈路。分詞階段自定義詞典把“糖尿病”和“并發(fā)癥”都識(shí)別為詞條實(shí)體抽取階段系統(tǒng)從圖譜中找到疾病節(jié)點(diǎn)“糖尿病”意圖判斷階段句子中出現(xiàn)“并發(fā)癥”這個(gè)關(guān)鍵詞系統(tǒng)把它歸類(lèi)到并發(fā)癥查詢模板緊接著模板實(shí)例化生成一條查詢語(yǔ)句從糖尿病節(jié)點(diǎn)出發(fā)沿著表示并發(fā)關(guān)系的邊找到相關(guān)聯(lián)的疾病節(jié)點(diǎn)返回這些節(jié)點(diǎn)的名稱(chēng)。這條查詢?cè)跀?shù)據(jù)庫(kù)里執(zhí)行后返回的結(jié)果可能是“糖尿病腎病”“糖尿病視網(wǎng)膜病變”等。系統(tǒng)再把節(jié)點(diǎn)名稱(chēng)包裝成一句自然語(yǔ)言答案返回給用戶。整個(gè)過(guò)程從輸入到響應(yīng)在本地環(huán)境上大概只需要幾百毫秒。這個(gè)速度對(duì)于教學(xué)演示完全夠用也說(shuō)明在數(shù)據(jù)量可控時(shí)規(guī)則加圖查詢的方案遠(yuǎn)比想象中高效。4. 圖數(shù)據(jù)庫(kù)的選型觀察與查詢性能體驗(yàn)4.1 為什么不能直接用關(guān)系型數(shù)據(jù)庫(kù)很多人會(huì)問(wèn)醫(yī)療數(shù)據(jù)實(shí)體不算多用MySQL也能存為什么非要引入圖數(shù)據(jù)庫(kù)我自己探索后的理解是圖數(shù)據(jù)庫(kù)的核心優(yōu)勢(shì)不在基礎(chǔ)查詢而在多跳關(guān)聯(lián)和路徑檢索。醫(yī)療領(lǐng)域最常問(wèn)的問(wèn)題之一就是“這種癥狀可能是哪些疾病引起的”這個(gè)查詢本質(zhì)上是從癥狀節(jié)點(diǎn)出發(fā)反查所有連到它的疾病節(jié)點(diǎn)可能還要繼續(xù)跳到對(duì)應(yīng)的檢查項(xiàng)目或用藥建議。這種查詢?nèi)绻藐P(guān)系表實(shí)現(xiàn)通常需要設(shè)計(jì)多張關(guān)聯(lián)表寫(xiě)一串JOIN語(yǔ)句而且關(guān)系層級(jí)越深SQL越復(fù)雜。在圖數(shù)據(jù)庫(kù)里這只是一個(gè)沿邊遍歷的操作。這套項(xiàng)目使用的是圖數(shù)據(jù)庫(kù)領(lǐng)域最主流的Neo4j它的查詢語(yǔ)言Cypher對(duì)路徑遍歷的表達(dá)非常直接比如匹配一條關(guān)系鏈就是簡(jiǎn)單地描述節(jié)點(diǎn)和關(guān)系的連接模式。我個(gè)人的觀察是對(duì)于關(guān)系類(lèi)型固定、查詢模式清晰的垂直領(lǐng)域圖數(shù)據(jù)庫(kù)的思維模型天然更匹配。它逼迫你把業(yè)務(wù)關(guān)系建模成圖這個(gè)建模過(guò)程本身就是對(duì)領(lǐng)域知識(shí)的一次梳理。4.2 索引、參數(shù)化與查詢延遲實(shí)際跑通問(wèn)答之后我開(kāi)始關(guān)注性能問(wèn)題。在這個(gè)項(xiàng)目的小規(guī)模圖譜上直接查詢幾乎沒(méi)有壓力但不代表可以忽略索引。醫(yī)療圖譜雖然在單個(gè)實(shí)體類(lèi)型上節(jié)點(diǎn)數(shù)量有限但如果以后擴(kuò)展到幾十萬(wàn)實(shí)體、上百萬(wàn)關(guān)系沒(méi)有索引的查詢性能會(huì)迅速惡化。我在驗(yàn)證時(shí)給疾病名、癥狀名、藥物名的名稱(chēng)屬性都加了索引。加索引前某些模糊匹配查詢能明顯感覺(jué)到延遲加索引后即便是全庫(kù)掃描類(lèi)的匹配也順滑很多。這個(gè)經(jīng)驗(yàn)可以通用到所有圖數(shù)據(jù)庫(kù)項(xiàng)目先確認(rèn)哪些實(shí)體屬性會(huì)被當(dāng)成查詢?nèi)肟谠籴槍?duì)這些屬性建立索引千萬(wàn)不要等用戶來(lái)吐槽慢。另外我還建議查詢語(yǔ)句里盡量使用參數(shù)化寫(xiě)法不要把所有實(shí)體值硬拼到查詢字符串里。參數(shù)化不僅能讓數(shù)據(jù)庫(kù)做執(zhí)行計(jì)劃緩存更重要的是能避免查詢注入和特殊字符引發(fā)的解析錯(cuò)誤。這一點(diǎn)很多做知識(shí)圖譜問(wèn)答的初學(xué)者容易忽略覺(jué)得數(shù)據(jù)是自己導(dǎo)進(jìn)去的沒(méi)必要防注入。但等到實(shí)體名里出現(xiàn)引號(hào)、括號(hào)、特殊符號(hào)時(shí)你就知道參數(shù)化有多重要了。5. 復(fù)現(xiàn)過(guò)程中踩過(guò)的坑與排查思路5.1 CSV導(dǎo)入時(shí)報(bào)錯(cuò)的根因第一次按文檔復(fù)現(xiàn)時(shí)我在數(shù)據(jù)導(dǎo)入環(huán)節(jié)就卡住了?,F(xiàn)象是CSV文件里明明有數(shù)據(jù)但導(dǎo)入報(bào)錯(cuò)說(shuō)找不到字段或者節(jié)點(diǎn)沖突。排查鏈路從文件編碼開(kāi)始最后定位到兩個(gè)問(wèn)題一個(gè)是文件是含BOM的UTF-8編碼解析時(shí)把首列列名帶上了不可見(jiàn)字符另一個(gè)是同一實(shí)體在CSV里出現(xiàn)了多行重復(fù)創(chuàng)建后觸發(fā)了唯一性沖突。這兩個(gè)問(wèn)題在真實(shí)項(xiàng)目中非常典型。我的解決方法是先統(tǒng)一文件編碼為無(wú)BOM的UTF-8再在寫(xiě)入前對(duì)實(shí)體名做一次歸一化校驗(yàn)保證同一主鍵只寫(xiě)入一次。如果你想避開(kāi)同類(lèi)問(wèn)題這里有個(gè)實(shí)用經(jīng)驗(yàn)寫(xiě)導(dǎo)入腳本之前先單獨(dú)把數(shù)據(jù)讀出來(lái)看一眼列名和數(shù)據(jù)類(lèi)型不要默認(rèn)源文件干凈。5.2 分詞與實(shí)體匹配失敗問(wèn)答鏈路里我遇到最影響體驗(yàn)的問(wèn)題是分詞。比如“阿司匹林腸溶片”這種帶劑型的藥物名標(biāo)準(zhǔn)詞典可能只收錄“阿司匹林”分詞后“腸溶片”變成普通詞導(dǎo)致實(shí)體抽取只能抽到半個(gè)名字。更麻煩的是“小兒感冒顆?!边@類(lèi)包含修飾語(yǔ)的長(zhǎng)詞條詞典不維護(hù)完整詞表的話幾乎百分百切錯(cuò)。我當(dāng)時(shí)的排錯(cuò)思路是把問(wèn)答模塊單獨(dú)做日志輸出把每個(gè)問(wèn)句的分詞結(jié)果、候選實(shí)體和最終匹配節(jié)點(diǎn)全部打印出來(lái)。當(dāng)答案錯(cuò)誤時(shí)往回看分詞結(jié)果基本就能定位是詞典問(wèn)題、實(shí)體鏈接問(wèn)題還是模板問(wèn)題。用這個(gè)辦法我一次性發(fā)現(xiàn)了二十多個(gè)需要補(bǔ)充進(jìn)自定義詞典的藥物和疾病詞條。后續(xù)迭代時(shí)我建議你把分詞結(jié)果和匹配節(jié)點(diǎn)也加入監(jiān)控日志這比單看最終答案好不好用要高效得多。5.3 模板覆蓋不足的應(yīng)對(duì)規(guī)則模板的天然短板是覆蓋不全。這個(gè)項(xiàng)目?jī)?nèi)置了一些問(wèn)法模板但換成口語(yǔ)化表達(dá)就可能匹配失敗。比如“血壓高的人該注意什么”這句話系統(tǒng)可能無(wú)法直接判斷它等價(jià)于“高血壓的注意事項(xiàng)”。最初我選擇不斷加模板后來(lái)發(fā)現(xiàn)模板越加越多維護(hù)成本急劇上升。后來(lái)我換了一個(gè)思路先對(duì)問(wèn)句做標(biāo)準(zhǔn)化改寫(xiě)把口語(yǔ)說(shuō)法映射成核心句式再做意圖判斷。比如“血壓高”“血壓偏高”先歸一化為“高血壓”“該注意什么”“要當(dāng)心什么”歸一化為“注意事項(xiàng)”。這樣模板數(shù)量不需要膨脹意圖識(shí)別準(zhǔn)確率反而提高了。這個(gè)經(jīng)驗(yàn)我覺(jué)得很值得分享在垂直領(lǐng)域問(wèn)答里與其堆模板不如先做問(wèn)句改寫(xiě)。6. 項(xiàng)目能怎么改進(jìn)把Demo做成可用產(chǎn)品的方向6.1 同義詞與實(shí)體鏈接增強(qiáng)在探索這個(gè)項(xiàng)目的基礎(chǔ)上我做了一輪增強(qiáng)實(shí)驗(yàn)核心是補(bǔ)全同義詞映射。醫(yī)療領(lǐng)域的同義詞非常多包括中文別名、英文縮寫(xiě)、商品名和通用名。比如不同品牌的降壓藥商品名可能完全不同但本質(zhì)成分是同一種藥。如果不做同義詞歸一用戶在問(wèn)答時(shí)就會(huì)頻繁遭遇“查不到”。我的實(shí)現(xiàn)方式是在圖譜中給實(shí)體節(jié)點(diǎn)增加“別名”屬性在實(shí)體鏈接階段先按標(biāo)準(zhǔn)名精準(zhǔn)匹配匹配不到再按別名模糊匹配。這一層補(bǔ)充并不復(fù)雜但對(duì)問(wèn)答體驗(yàn)的提升非常明顯。如果你也打算在醫(yī)療垂直領(lǐng)域做產(chǎn)品建議在一開(kāi)始就把同義詞表設(shè)計(jì)成獨(dú)立可維護(hù)的數(shù)據(jù)文件讓醫(yī)學(xué)人員可以持續(xù)補(bǔ)充。6.2 從單輪到多輪與澄清原始項(xiàng)目的交互基本限定在單輪問(wèn)答用戶問(wèn)一句系統(tǒng)答一句如果實(shí)體有歧義會(huì)直接選第一個(gè)。這在真實(shí)醫(yī)療場(chǎng)景里風(fēng)險(xiǎn)很大。一個(gè)“心臟疼”的用戶可能指的是心絞痛也可能指的是胃食管反流引起的胸痛系統(tǒng)不應(yīng)該直接給答案而應(yīng)該反問(wèn)澄清。我在這套系統(tǒng)上增加了一個(gè)很輕量的澄清機(jī)制當(dāng)候選實(shí)體超過(guò)一個(gè)并且各候選實(shí)體之間的答案差異較大時(shí)先把候選實(shí)體列給用戶讓用戶選擇后再繼續(xù)查詢。雖然這只是多輪交互的雛形但已經(jīng)把體驗(yàn)從“命令式查詢”往前推了一大步。醫(yī)療問(wèn)答涉及生命安全寧可多問(wèn)一句也不要武斷給結(jié)論。6.3 評(píng)估方式與個(gè)人體會(huì)最后聊聊評(píng)估。這類(lèi)項(xiàng)目的效果不能只看幾個(gè)例子跑通了就算完。我建議整理一份一百到兩百條的真實(shí)問(wèn)句集覆蓋各個(gè)意圖類(lèi)型人工標(biāo)注正確答案再批量跑系統(tǒng)統(tǒng)計(jì)準(zhǔn)確率和無(wú)答案率。我對(duì)原系統(tǒng)做了一輪實(shí)測(cè)統(tǒng)計(jì)結(jié)果顯示在模板覆蓋范圍內(nèi)準(zhǔn)確率很高但出了覆蓋范圍無(wú)答案率明顯上升。這正是規(guī)則系統(tǒng)的分水嶺。改進(jìn)之后我用同義詞、問(wèn)句改寫(xiě)和澄清機(jī)制把無(wú)答案率往下壓了不少。整個(gè)過(guò)程讓我對(duì)醫(yī)療知識(shí)圖譜問(wèn)答有了更深的理解這類(lèi)系統(tǒng)的天花板其實(shí)不取決于算法多先進(jìn)而取決于知識(shí)庫(kù)的完整度和業(yè)務(wù)規(guī)則的合理設(shè)計(jì)。如果后續(xù)要進(jìn)入生產(chǎn)環(huán)境我會(huì)考慮引入更強(qiáng)的實(shí)體識(shí)別模型同時(shí)保留規(guī)則系統(tǒng)作為兜底讓兩種方案互相補(bǔ)位。如果你正在研究這個(gè)項(xiàng)目我的建議很直接先別急著換模型把知識(shí)圖譜的數(shù)據(jù)質(zhì)量打磨到位把提問(wèn)模板吃透再用真實(shí)問(wèn)句做一輪完整的評(píng)估。這個(gè)項(xiàng)目最好的地方就是給了你一個(gè)完整的基線讓你能在上面快速驗(yàn)證自己的想法。等這一輪跑完你對(duì)醫(yī)療問(wèn)答里那些“看似簡(jiǎn)單但藏滿細(xì)節(jié)”的問(wèn)題心里就有底了。