提起長連接,我們并不陌生,最常見的長連接非websocket莫屬了。即使沒有在項目中實際用過,至少也應該有所接觸。長連接指在一次網絡通信中,客戶端與服務器之間建立一條持久的連接,可以在多次請求和響應中重復使用該連接。這種方式的優點是減少了連接建立和關閉的開銷,提高了通信效率,但需要注意控制連接的數量,避免資源浪費。短連接則是每次請求和響應都建立一個新的連接,完成后立即關閉,需要頻繁進行連接建立和關閉,效率相對較低。但是這種方式更加靈活,適用于請求量較小、請求頻率不高的場景。
最近項目在引用ChatGPT智能小助手,最開始采用的是當ChatGPT回答完成后一次性返回答案。但這種方式受限于網絡及服務較慢的原因導致用戶需要等待較長時間,極大的降低了用戶的使用體驗。經過項目組成員商議決定采取答案逐字返回的形式,以便于用戶能更快的得到反饋。?
關于長連接技術,主要考慮兩種方案websocket和sse
1.websocket概念:WebSocket是HTML5定義的新協議,實現了服務器與客戶端之間的全雙工通信。WebSocket連接一旦建立,客戶端和服務器端處于平等地位,可以相互發送數據,不存在請求和響應的區別。
?2、websocket優劣勢:優勢在于實現了雙向通信,劣勢在于服務器端的邏輯非常復雜。現在針對不同的后臺語言有不同的插件可以使用。
3、sse概念:SSE(Server-Sent Events)是HTML5新增的功能,允許服務器將數據推送到客戶端。與長輪詢和短輪詢不同,SSE不需要客戶端先發送請求,而是在服務器端數據有更新時立即發送到客戶端
4、sse優劣勢:優勢在于節約資源,提升應用性能。SSE可以實現只要服務器端數據有更新,就可以馬上發送到客戶端,不需要建立或保持大量的客戶端發往服務器端的請求。另外,SSE的實現非常簡單,并且不需要依賴其他插件。劣勢在于不是雙向通信,只能后臺向前臺推送。
5、相同點:都是基于tcp,都是可靠的傳輸協議
6、不同點:
1、sse在chatgpt中的應用
前端代碼
import { fetchEventSource } from '@microsoft/fetch-event-source'
let answerContent=''
fetchEventSource('/chatgptApi/chatgpt_qa_stream', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ messages }),
async onopen(response) {
if (response.ok && response.status===200) {
console.log('連接成功')
} else {
console.log('連接異常')
}
},
async onmessage(event) {
// 表示整體結束
if (event.data==='[DONE]') {
console.log('結束')
return
}
if (event.data) {
const data=JSON.parse(event.data)
answerContent +=data.content
}
},
async onerror(error) {
console.error('Error:', error)
},
async onclose() {
console.log('關閉連接')
}
})
后端代碼
const http=require('http');
const yun=express();
const eventServer=http.createServer((req, res)=> {
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
'Access-Control-Allow-Origin': "*",
'Access-Control-Allow-Headers': 'Content-Type,Content-Length,Authorization,Accept,X-Requested-With',
'Access-Control-Allow-Methods': 'PUT,POST,GET,DELETE,OPTIONS'
});
setInterval(()=> {
// 事件要用兩個\n結束
res.write('data: The server time is: ' + new Date() + '\n\n');
}, 1000);
req.connection.addListener('close', ()=> {
console.log('SSE connection closed!');
}, false);
}).listen(4001);
??2、websockt在即時聊天中的應用
前端代碼
// 創建WebSocket對象
let ws=new WebSocket('ws://localhost:8888')
// 連接成功后的回調函數
ws.onopen=function (params) {
console.log('客戶端連接成功')
// 向服務器發送消息
ws.send('hello')
};
// 從服務器接受到信息時的回調函數
ws.onmessage=function (e) {
console.log('收到服務器響應', e.data)
};
// 連接關閉后的回調函數
ws.onclose=function(evt) {
console.log("關閉客戶端連接");
};
// 連接失敗后的回調函數
ws.onerror=function (evt) {
console.log("連接失敗了");
};
// 監聽窗口關閉事件,當窗口關閉時,主動去關閉websocket連接,防止連接還沒斷開就關閉窗口,這樣服務端會拋異常。
window.onbeforeunload=function() {
ws.close();
}
后端代碼
/ 引入插件
const ws=require('nodejs-websocket')
// 只要有用戶鏈接,函數就會執行,會給當前鏈接的用戶創建一個connect對象
const server=ws.createServer((connect)=>{
console.log('連接成功')
// console.log(connect)
// 注冊text事件 ,接收用戶傳遞過來的數據
connect.on('text',data=>{
console.log('接收客戶端數據---->', data)
// 給所有用戶發送消息
broadcast(server,data+"--返回數據")
})
// 連接斷開,觸發事件close
connect.on('close',()=>{
console.log('用戶鏈接斷開--close')
})
// 用戶鏈接斷開
connect.on('error',err=>{
console.log('err', err)
})
}).listen(3001,()=>{
console.log('websocket服務啟動成功了')
})
// 給所有人發消息
function broadcast(server,msg){
server.connections.forEach(element=> {
element.send(msg)
});
}
sse在chatgpt案例中的應用
作者:京東物流 田雷雷
來源:京東云開發者社區 自猿其說Tech
I激蕩70載,身處操作系統演變的中心位置,在ChatGPT、文心一言等AIGC產品,GPT-4、Stable Diffusion、Midjourney等AI大模型的加持下,程序員現有的編程范式將會遭到怎樣的沖擊?面向的全新AI應用時代,開發者的思維、開發方式、工具又該做出怎樣的改變?
繼“新程序員:人工智能新十年”大會探討程序員進入下一個AI十年的準則之后,3月25日,CSDN、《新程序員》聯合主辦的“新程序員大會(NPCon):AIGC 與大模型技術應用峰會”于北京環球貿易中心正式拉開帷幕。
在本次大會上午場的主論壇現場,CSDN創始人&董事長、極客幫創投創始合伙人蔣濤,創新工場AI工程院執行院長、SeedV實驗室創始人王詠剛,華為云智能化軟件研發首席專家王千祥,42章經創始人曲凱,在CSDN副總裁鄒欣的主持下,就技術人如何利用通用人工智能、ChatGPT、AIGC、大模型、AI編程等重要話題,給出了干貨滿滿的解答。
直播回放:https://live.csdn.net/room-iframe/programmer_editor/2OmZkkQB
以下是“AIGC與大模型技術應用峰會”主論壇的演講精華。
GPT是人工智能時代的Windows
在CSDN創始人&董事長、極客幫創投創始合伙人蔣濤發表的《大模型時代的新應用開發者》主題演講中,他提出AI時代的到來,為開發者產業帶來了三大紅利:人人都是開發者,家家都是技術公司,萬億技術云大生態。
CSDN創始人&董事長、極客幫創投創始合伙人 蔣濤
據蔣濤介紹:“CSDN的最新開發者數據也證實了這一點。目前CSDN注冊用戶數超過4200萬,去年新增了600萬用戶,新增用戶中有60%都是大學生和高中生,高校計算機專業學生覆蓋度90%,非常的年輕化。”
事實上,技術的演進所經歷的階段宛如一個輪回,回顧2011年,全球化移動應用市場大門打開之際,掘金海外還是瞄準國內市場、專注iOS還是Android亦或者是HTML5跨平臺開發等都成為開發者抉擇的方向。
12年后,開發者再次站在選擇的十字路口,正如技術社區三倍速定律所彰顯的那樣,“一個技術要進入到真正的生態應用里,首先是在學術界被大家認可,接著進入到工程界,最后才進入大眾視野。因此技術社區的動向往往能反映出未來的技術趨勢”。從數據中,可以明顯感知到GPT正在以前所未有的速度成為人工智能時代的Windows,AI發展也正處于iPhone 4時刻。
而為真實呈現ChatGPT等自動化編程工具對開發者的影響,蔣濤也分享了CSDN 最新上線的AI編程測試方法。同時,在大會現場,CSDN面向所有用戶群體,重磅發布了一款快速開發GPT應用工具——InsCod(https://inscode.csdn.net)。
最后,蔣濤對于想要加入這場AI浪潮的開發者建議道,首先要去學表達,學會善用Prompt;第二要學英文,因為前沿技術的英文資料更新速度更快;第三,發揮想象力,開始行動。
學會Prompt,就能完成AI開發?
“我發現我們這些老一代程序員今天被AI技術的發展拉到了一個和剛畢業的大學生一樣的門檻上,我不認為我做了十幾年的自然語言處理技術,比一個今天剛畢業的大學生使用ChatGPT、GPT開發的應用有任何優勢,這是一個我非常焦慮的時代和時刻”,創新工場AI工程院執行院長,SeedV實驗室創始人王詠剛在主論壇上如是說道。
創新工場AI工程院執行院長,SeedV實驗室創始人 王詠剛
王詠剛表示,今天所有的計算機、系統都會被 AI 去重新改寫,重新定義。這也引發了無數人思考:未來的程序員真的會被簡化為提示詞的編寫員嗎?然后由提示詞操縱 AI?是不是這樣一個非常簡單的范式,就可以總結未來所有的 AI 開發?
就個人觀點來看,王詠剛給出了否定的答案,其表示,“未來的 AI 開發應該是一種多范式的開發流程”。在他看來,世界上的任務天然地分為兩類,一類是天生的不確定性任務,一類就是天生的確定性任務。這也讓未來 AI 編程呈現出兩種典型的范式:
第一種編程范式是適用于端到端的感知類任務、創造性任務、探索性任務,它可以通過提示詞得到結果。
第二個范式是強調控制力、結果確定性、計算精準性的應用任務。在這個任務里面,我們不能放任所有的事情都交給大模型一次來解決問題,大模型可能需要通過引入插件的方式,調用非常多的后臺服務。
最后,王詠剛也分享道,“人類工程師在這個范式里被降級了,我覺得沒辦法,我們只能承認我的命運,我們也只能去擁抱這個時代,所以現在的我們,應該盡量少說話,早日開始行動起來。”
AI編程的邊界在何處?
緊接著,華為云智能化軟件研發首席專家王千祥在發表《AI編程:無盡的前沿》主題演講中表示,AI編程基于GPT的代碼生成取得了很大的突破。
華為云智能化軟件研發首席專家 王千祥
在王千祥看來,GPT代碼生成原理主要分為兩個階段:訓練階段,關鍵問題在于學什么和怎么學;生成階段,通過自然語言輸入,經過線上GPT模型,然后生成代碼。
對于AI編程的邊界究竟在哪里,王千祥通過GPT-4技術報告和微軟研究院的報告發現,AI大模型在多數情況下超越了人類的編程能力,但是其距離頂尖程序員還有很大的差距。
王千祥認為,AI編程肯定會超越Coding編程,因為現有的ChatGPT、GPT-4大模型工具的能力覆蓋到了代碼補全、翻譯代碼、解釋代碼、DeBug等多個維度。未來,這些工具必將覆蓋到設計、搜索、遷移、運營等多流程中。
同時,王千祥也希望AI編程背后的新模型可以將統計方法與規則方法(常識)融合起來,并能適時地進行反饋學習,以及通過健康的生態得到良好的發展。
用生成式AI打通商業
在ChatGPT、大模型徹底改變開發者編程方式之際,大家可以用它實現出什么,站在需求的角度來看,42章經創始人曲凱帶來了《生成式 AI 的商業化落地思考》的主題演講。
42章經創始人 曲凱
他認為,中國肯定會有自己的大模型,也可以有。因為可以把大模型這個事情定性成為一個工程問題,而不是一個技術問題,發現新大陸難,抵達新大陸實則沒那么難。
具體來說,現如今大模型主要帶來了三個維度的能力與改變:
在實際的落地場景和機會上,曲凱認為簡單講不外乎這三類:大模型、中間層、應用層。其中,最大的機會集中在應用層:
不過,在開發者、企業嘗試過程中,曲凱也分享了可能會面臨的五大壁壘,包括:自己做大模型、自己有私有化數據、用戶使用過程中有數據飛輪效應、用戶有網絡效應、有復雜的業務流系統等。
圓桌對話:ChatGPT 大航海時代
在上午主論壇的圓桌對話環節,由CSDN戰略合作總監閆輝主持,CSDN 創始人&董事長、極客幫創投創始合伙人蔣濤,創新工場 AI 工程院執行院長、SeedV 實驗室創始人王詠剛,華為云智能化軟件研發首席專家王千祥,42 章經創始人曲凱作為嘉賓的圓桌對話正式展開,五位技術專家以“ ChatGPT 大航海時代”為主題,共論 ChatGPT 開辟的新領域、新應用、新機遇。
“我特別同意這是一個ChatGPT大航海時代,這是一個新時代的開始,如果再加一點,我覺得這不是一個在地球上的大航海時代,而是一個星際旅行的大航海時代”,創新工場 AI工程院執行院長、SeedV 實驗室創始人王詠剛分享道。
他表示,人類發現美洲之后,然后在上面去建工廠、做開發,包括美國的西部大開發,實際都是以歐洲規則來進行的。因此,這也有可能引發一些擔憂,目前大家用GPT開發程序,都是在PC、移動終端上進行開發,以及遵循相關的規則。不過,再過3-5年規則有可能會發生變化。宛如在星際旅行時,到了一個星球,這個星球可能像在電影上看到了,它可能特別接近一個黑洞,它的引力場、時間、行為全都不一樣了,在這個時候,如果開發者的應用開發還在按照在移動時代、PC時代那樣的方式繼續做,可能就不適用了,這是3-5年后可能會出現的局面。
當談及在開辟出大航海時代之后,ChatGPT反向會推動哪些維度進步時,CSDN創始人&董事長、極客幫創投創始合伙人蔣濤表示,GPT的能力匯集了所有的知識庫,此時人類與它比拼的不是已有的知識,而是看它能否為我們產生新的知識,當然,這里新的知識并不是說讓GPT寫一篇科幻小說等等。更為重要的是,如果它的增量是科學發現,那么,我們現在社會的進步都是無盡的前沿。因此,他認為,未來我們可能會經歷3-5年的前GPT時代,GPT會通過人類的提示等不斷改進,但是5年之后,也許GPT會產生我們根本無法想象的事情,就如十幾年前,眾人無法想象出現在我們使用智能手機的現狀。
華為云智能化軟件研發首席專家王千祥則認為,ChatGPT 中可以將不同語言之間實現無縫轉換的功能,具有兩面性。一方面,大航海時代的確促進了很多交流;另一方面,也導致強勢文化更強,有很多弱勢文化可能被壓縮了。這一點在大模型方面也是類似的,包括我們在訓練大模型時,有時用中文語料訓練的效果不行,但帶上英文的效果就好。所以,ChatGPT 到來對我們文化影響力如何,還是需要持兩面看待。
對于未來可能會創造的機遇,42章經創始人曲凱表示,“很多東西在當下是很難推出來的,就像十年前,我們很難想到現在最流行的應用是抖音之類的產品、最早的小紅書只不過就是一個PDF……因此,我認為當前大家需要做的就是,先用起來,不用想那么多,還是站在用戶需求的角度,看看當下的技術到底能實現什么東西,在這個過程當中再不斷去調整。”
除了對大模型技術和AI新時代開發者未來發展的思考,在本次AIGC與大模型技術應用峰會上,我們還特設了“AIGC與大模型技術應用”與“AI編程技術應用”兩大論壇,以及ChatGPT應用創新營特色活動。
分論壇1:大模型是通往AGI的必由之路嗎?
其中,在“AIGC與大模型技術應用論壇”上,五位深入大模型應用的產業界代表分別帶來了他們對于AIGC和大模型的思考,以及行業多年的實踐經驗,深入展現國內大模型技術生態。
首先帶來演講的是文因互聯工程VP兼首席科學家宋劼。在她看來,ChatGPT的出現宣示著新的人工智能發展契機的到來。具體到金融領域,她發表了《探索新技術之大模型在金融AIGC領域的前景與應用》的主題演講。
文因互聯工程VP兼首席科學家 宋劼
“在過去一段時間內,我們主動、被動接受到了有關ChatGPT和AIGC的各類討論,大多圍繞趨勢、影響等維度展開。在強監管背景下,ChatGPT在金融領域落地有哪些局限性?金融機構應該如何構建自己的優勢,以應對當下發展 ?”
在本次分享中,宋劼從技術分析及場景應用方面,對AIGC商業化落地的可行性和路徑進行探討,從中尋找可能的業務增長點。
此外,在宋劼看來:“金融領域的大模型終將實現,我們會成為整個歷史浪潮中微小但有力的一份子。哥倫布就曾經錯誤地認為自己到達了印度,但他開辟的新航路依舊影響了全人類。無論這一次科技浪潮的最后能否完全實現通用人工智能(AGI),我們都已經走出了重要的一步。”
緊接著,來自網易伏羲實驗室的資深研究員,NLP研究組及多模態算法負責人張榮升,以多年在這一技術領域的積累發表了《文本及多模態預訓練技術的研究與應用》的演講,介紹了網易伏羲在大模型上的技術積累,包括文本、多模態理解和生成預訓練模型的建設,同時分享了大模型在歌詞輔助創作、智能對話、文字游戲、互聯網搜索推薦、AI繪畫等落地場景的應用。
“ChatGPT的交互方式是大眾化的,它真正理解使用者意圖的能力也是革命性的。預訓練模型在未來的趨勢會朝多模態方向發展,大模型的使用會越來越流行。”張榮升如是表示。
網易伏羲實驗室資深研究員,NLP研究組及多模態算法負責人 張榮升
超對稱技術首席科學家吳恒魁則在演講中基于“重整化理論”,對大語言模型的涌現現象建立數學框架。據他表示,超大參數語言模型遵循scaling law,即將參數和訓練量擴大,能看到模型產生接近人類的邏輯和復雜推理能力,這樣的現象屬于復雜系統的涌現。而通過提出基于統計力學的連續相變理論來解釋語言模型的涌現行為,為引入量子場論的重整化機制建立數學框架,這是他此次演講的主要內容。
“大模型出現人類級別的邏輯和復雜推理能力是一種涌現行為,而隨著模型復雜度增加,預測下一個詞的GPT模型可能遵從“連續相變”的規律出現新的涌現行為。”吳恒魁講道。
來自華院計算人工智能實驗室資深研究員蔡華,在本場論壇發表了《讓數字人更具個性和情感:ChatGPT技術的思考啟示》的演講。
他的演講聚焦在ChatGPT為通用語音技術帶來的變革上,其中的重點便是如何能夠為數字人賦予個性和情感。同時,以華院計算實施的具體實踐為例,說明了對話式框架的搭建,以及如何將對話與知識融合。同時,也指出了知識圖譜如何能夠讓對話交互變得有感情和富有個性。
華院計算人工智能實驗室資深研究員 蔡華
“大模型提供了更強大、更智能的交互方式,讓虛擬數字人更有溫度。未來的數字人將能理解他人的感受和情感,與他人進行個性化的互動。”蔡華表示。
最后,本場論壇主持人,句子互動創始人 & CEO,微軟人工智能最具價值專家 (AI MVP)李佳芮從開發者切實應用的角度,說明了她對于ChatGPT如何從0到1的構思,從技術原理、發展背景、應用場景和prompt等多個角度,說明了未來AGI時代的開發者需要哪些思維和技能。
句子互動創始人&CEO,微軟人工智能最具價值專家 (AI MVP)李佳芮
“工業革命解決了‘重復體力勞動’的事情,人工智能未來解決‘重復腦力勞動’的事情。對話式人工智能已經到來,人類最終會與AI「共生」,讓機器做機器擅長的事情,讓人類發揮人類的特長,讓人工智能拓展人類智能。”李佳芮最后總結道。
從AIGC、大模型,到通用人工智能 主題圓桌對話
了解更多,請查看回放鏈接:
https://live.csdn.net/room/programmer_editor/Nc8cfWuo
分論壇2:AI編程的現狀與未來
另一場主題為“AI編程技術應用論壇”主要為給開發者提供更多產學研界的前沿技術和實踐案例。為此,論壇邀請到五位深入AI編程的卓越開發者,分享他們技術實踐。
首先,由微軟亞洲研究院高級研究工程師盧帥帶來主題為《基于預訓練的代碼理解與生成》的講解。他的演講聚焦于“代碼智能”,包括剖析基于人工智能技術的自動化程序理解和生成極大地提高程序開發者的生產力,如何開發出大規模通用預訓練模型,并將其使用到軟件開發生命周期的各個方面,包括代碼補全、代碼搜索、代碼審查、缺陷檢測及修復等方面。
微軟亞洲研究院高級研究工程師 盧帥
“未來AI編程的發展趨勢是一方面探討如何利用大模型來完成任務,另一方面思考如何進化它,以覆蓋更廣泛的智能代碼場景。”盧帥如是表示。
接著,aiXcoder聯合創始人郝逸洋分享了大語言模型時代下應該如何進行代碼的生成。包括如何利用LLM的技術進行代碼開發輔助、代碼模型和自然語言模型的區別,以及對交互式多模態LLM(如ChatGPT,GPT4)加持下的智能化軟件開發的暢想。
在他看來:“如果 AI 作為操作系統可以直接控制硬件,程序員就能解放雙手去編寫驅動、操作系統和軟件或是研發新的硬件,這就是軟件 3.0 的圖景。”
aiXcoder聯合創始人 郝逸洋
華為云PaaS技術創新LAB 技術專家申博基于華為云CodeArts Snap的實踐,作了《GPT-4時代,重新思考AI編程》的分享。他的思考涉及包括生成式AI能做什么、邊界在哪里,以及如何落地實現的各個方面。在他看來,我們需要重新思考AI編程,通過與現有工具的結合,軟件分析及語言模型的實現,未來增強型的AI編程助手一定會出現。
華為云PaaS技術創新LAB技術專家 申博
“當模型越來越大,對硬件性能要求越來越高,有可能會遇到“數據荒”的問題,我們能否讓 AI 自我演進,通過自我生成數據的方式學習,以達到與大數據同樣的效果?未來自我創造智能是個有前途的方向。”申博表示。
來自清華大學知識工程實驗室研究助理鄭勤鍇則分享了關于CodeGeeX的實踐。和很多大模型是通過海外的架構和硬件進行訓練不同,CodeGeeX最大的特點是通過國產AI框架和硬件來實現訓練,減少了核心技術被卡的風險。在本次報告中,鄭勤鍇分享了這款插件自動代碼生成與預訓練模型的產生背景、如何進行模型實現、VS Code與JetBrains IEDs插件介紹與功能,以及未來開源開發計劃等方面。
關于程序員需要提升的能力,鄭勤鍇認為,“在將來,程序員需要具備一些更高級的技能和思維,比如Geek(極客)思維,開發者應該更加注重這方面的培養。”
清華大學知識工程實驗室研究助理 鄭勤鍇
最后,中國科學院軟件研究所研究員、博士生導師王俊杰,分享了基于Pre-trained Large Language Model(LLM)的軟件自動化測試的主題演講,包括指出自動化測試仍存在哪些導致效率低下的問題,以及如何利用大規模的預訓練模型來自動生成測試輸入等。
中國科學院軟件研究所研究員、博士生導師 王俊杰
“現在的大模型可能有些時候對開發人員來說有點‘不太專業’,但對測試人員來說‘剛剛好’。”王俊杰如此表示。
AI編程現狀與未來,成就大模型時代應用開發者 主題圓桌對話
了解更多,請查看回放鏈接:
https://live.csdn.net/room/csdnlive5/CCEAhsEs
同時,隨著人工智能和大數據技術的不斷發展,AIGC和大模型技術已經成為了各行各業的重要發展方向。在本次AIGC與大模型技術應用峰會上,我們還特設了ChatGPT應用創新營特色活動。
ChatGPT應用創新營活動現場
小組討論
此次,我們深入探討了大模型技術對開發者的影響與潛在的研發應用場景、未來發展趨勢,也不難看出,我們正在AIGC、大模型的引領下站在AI智能感知階段的C位,而屬于AIGC、大模型的時代也才剛剛開始。
未來,我們也期待AIGC和大模型技術將為我們帶來更加智能化和高效化的工作流程、更加精準和個性化的服務、更加安全和可靠的系統,以及更加優秀和有趣的人機交互體驗。
在去年年底 ChatGPT 剛火的時候我就有一個想法,它能不能幫我讀一下晦澀難懂的保險條款,告訴我它到底在講什么?到底什么病能賠多少錢?甚至能告訴我里面是不是藏有一些坑?但是當我把條款內容復制到 ChatGPT 時,我們會發現,它直接告訴你:“太長了,它受不了”。
當我們自己打開 openai 的文檔,我們才明白:哦,原來它接受的最大長度是 4096個 tokens。但這個 一個 token 到底是多長呢?暫時還不知道,反正就是有這么個上限。很顯然,我們的保險條款遠遠的超過了它的上限,因為我才復制兩三頁的內容它就 Error 了。
但我們還是納悶,不應該啊,ChatGPT 不應該很強嗎?它的官方例子可是擺了幾十個案例,看網上的各種文章,它似乎在文字與編碼領域,遠超絕大數人類,怎么會連個保險條款都無法承受。
我想從這個案例中看看有沒有其他路子,可惜確實沒有合適的案例能解決我這種超長文本的訴求。于是我停止了這個想法,并先回家過了個快樂的新年。
但在最近,在我的不屑但可能沒啥意義的努力下,我幾乎完成了這個想法。先放幾個截圖給大家看看。
問螞蟻爆款「好醫保長期醫療」幾個問題的答案:
問市面上很火的「達爾文7號重疾」的問題及答案:
如果你仔細看,你會發現,它已經能非常準確的回答這幾個很多保險小白常問的問題了。那我到底是怎么實現的呢?這篇文章來一探究竟。
在我開始正文之前,先讓 ChatGPT 跟大家做個簡單介紹。
所以本文標題其實不對,準確說應該是「如何讓 openai 的 API 幫我讀懂保險條款」。因為我其實是調用了 openai 提供的 API 能力來滿足需求的。更準確來說是調用了其 GPT-3 的一些模型,而不是掛代理直接問 ChatGPT。但為了大部分讀者容易理解,就先取一個不恰當的標題了。
后文中,我將會以 GPT 通用指代我所調用的 openai 的 API 服務。
話說在新年回來后,ChatGPT 仍愈演愈烈,因此我又來了點兒興趣,并嘗試把 GPT 接入我一個年久失修的個人公眾號。就在這個接入的過程中,為了解決接入遇到的不少問題,我看了不少文檔。果然是開卷有益,實干興邦啊。過程中我又接觸學習了一些有用知識。其中最重要的是兩個點知識:
其一是:GPT 的多輪對話是如何實現的?其實很簡單,就是把歷史對話都存起來,然后按照時序重新拼接,再加上這次的問題,合并一起作為 prompt再傳給 GPT 即可。
其二就是,如何讓 GPT 理解超長文本知識并做問題回答?我在逛 openai 官方文檔的時候,發現了其實人家早早就想到了這個問題,并貼心的準備好了教程文檔。這在我上一篇 ChaGPT 的文章中也已提到:公眾號如何快速接入 ChatGPT & DALL.E
How to build an AI that can answer questions about your website:https://platform.openai.com/docs/tutorials/web-qa-embeddings
Question Answering using Embeddings:https://github.com/openai/openai-cookbook/blob/main/examples/Question_answering_using_embeddings.ipynb
它的思路其實很好理解,詳細來說,主要是分幾步:
原來如此,那么我只要把保險條款分段向量化,再根據用戶提問匹配到相應的那段內容再回答不就好了嗎。簡單,上手吧。
這個問題似乎正如「把大象放入冰箱」。描述起來很簡單,真正要做起來就舉步維艱。
在我們面前最大的問題就是,到底怎么把這個文檔做分割?
最簡單的方案自然是,把保險條款按頁碼一頁一頁分塊,如果一頁內容也超了,那我們就半頁半頁分塊。但這忽略了一個最大的問題,就像大象的各個器官并非水平均分分布一樣,知識內容并非是按頁碼分割的。一個知識可能第三頁正好起了個標題,第四頁才是詳細的描述。而向量化匹配的時候,卻可能只匹配到第三頁的內容。比如這個「好醫保長期醫療」的責任免除條款,就很容易丟失下半部分的免除責任,造成回答準確性降低。
除此外,這樣的分割還容易讓 GPT “學壞”。因為粗暴的按頁分割,很容易把無關的知識傳給 GPT,導致它可能會因為這些無關的信息返回錯誤的答案。比如如下關于用戶信息告知的條款:前一頁內容如下:
后一頁內容如下:
如果你詢問的問題是:“如果投保時年齡填寫錯誤,理賠時會怎么樣”。那很有可能你只會將第一頁內容傳給 GPT,它將會告訴你保司不承擔任何責任,并不退回保險費。
而用我實現的服務所拼接的知識塊,得到的版本答案如下:
顯然這個問題得到了準確回答。
以上兩個案例比較生動的說明了分割的重要性。
懂得了很多道理,也依舊過不好這一生。 - ChatGPT也不知道是誰說的
如何分割文檔?其實這個也很好想方案,只是比較難搞。**保險條款是有文章結構的,只要咱們可以按文章標題給文檔做結構化就好了。**最終文檔就會成為這樣的一個文檔樹:
interface INode {
title: string;
content: string;
children: INode[]
}
type DocTree=INode[]
然后我們在深度遍歷這個文檔樹,去識別每個節點所包含的所有內容的長度,達到一定閾值就剪下來作為一個「知識塊」。這就像剪一個西蘭花 ,按自己可以含進去的大小,一朵朵剪下來。
通過這樣的手段,我們就能在滿足知識文本長度的限制下,切下最為連續完整的知識內容。這其實很簡單,但如果一定要裝逼取個算法名的話,那我稱之為:西蘭花算法。
但在我們切割西蘭花之前,還有一個棘手的問題,怎么把一個條款文檔先變成一棵西蘭花(一顆文檔樹)?
因為后文很多內容都跟這個tokens相關,所以我必須得提前介紹一下。有時間的同學可以直接看官網介紹文檔:沒時間的同學可以繼續聽我簡單總結一下:
OK,掌握這些知識就足夠理解我們后文的內容了。
我們可以先看看市面比較火爆的醫療與重疾險產品的條款。發現其實保險大部分條款是有一定格式標準的。幾乎都是嵌套數字標題 + 內容。那是否可以依據一定的規則,識別出那部分是標題,然后根據標題做切割即可?比如說,根據 「數字 + ·? + 數字?」的正則做匹配。雖然我正則寫不來,但是 ChatGPT 寫的來呀:
const text='1 React 1.1 react hooks 的使用技巧 1.2 react suspense 的作用 2 Vue 2.1 Vue compostion api 的使用技巧';
const regex=/(\d+\.?\d*)\s(\w+)/g;
const matches=text.matchAll(regex);
const result=[];
for (const match of matches) {
result.push(match[1] + ' ' + match[2]);
}
console.log(result);
// output
['1 React', '1.1 react', '1.2 react', '2 Vue', '2.1 Vue']
雖然它的回答不夠完美,但是基本夠我們繼續下一步編碼了。于是我嘗試把 PDF 的全文內容復制出來,并做分割。然后我就會發現幾個很麻煩的地方:
所以我們復制出來的文本是這樣的:
module.exports=`2.3 等待期
自本合同生效(或最后復效)之日起 90 日內,被保險人因意外傷害4以外的原因, 被保險人因意外傷害發生上述情形的,無等待
被確診患有本合同約定的輕癥疾病5、中癥疾病6、重大疾病7的,我們不承擔保險
責任,這 90 日的時間稱為等待期。
期。
輕癥疾病 中癥疾病
重大疾病
本合同的保險責任分為基本部分和可選部分。
,本合 ,退還
等待期內,我們的具體做法見下表:
等待期內發生的情形
我們的做法
不承擔本合同“2.4 保險責任”中約定的保險責任
同繼續有效
不承擔本合同“2.4 保險責任”中約定的保險責任
您已交的本合同保險費8(不計利息),
本合同終止
2.4 保險責任
1 保單生效對應日:本合同生效日每年(或半年、季、月)的對應日為保單年(或半年、季、月)生效對應日。若當月 無對應的同一日,則以該月最后一日為保單生效對應日。
2 保單年度:自本合同生效日或年生效對應日零時起至下一個年生效對應日零時止為一個保單年度。
3 保險費約定交納日:分期交納保險費的,首期保險費后的年交、半年交、季交或月交保險費約定交納日分別為本合同
的保單年生效對應日、半年生效對應日、季生效對應日或月生效對應日。`
所以,如果只是粗暴的根據某種標題規則來做分割,那我們只會得到錯亂的結果。
那我們人眼是如何從頁面中知道它是標題的呢?我們自然是根據這個文案的位置、大小,綜合了我們的歷史經驗來判斷它是不是標題。也就是說,要想真正從一段文本中做很好的標題識別以及內容分割,必須要獲取這段文本的其他元數據。
我的下意識,自然是希望還有 AI 的能力。我把 PDF 轉圖片,都傳給某個 AI,它很聰明,幫我 OCR 識別文檔并做好了充分的文檔結構化。
但我在 openai 官網并沒有找到這樣的 api 能力提供。由于我的 AI 儲備非常薄弱,我也很難在網上找到可以滿足我訴求的開源工具。而且根據我很可能不成熟的感覺,我感覺現在訓練出來的開源 AI 模型,頂多只是識別出文字以及文字所在的絕對位置,也很難幫我直接把文檔給按照標題結構化了。真有這樣的需求,可能需要我自己準備大量材料來訓練。這似乎再一次難倒了我。
于是我又想到了 pdf.js這個工具。我們 C端 部分投保協議就是利用這個工具包,把 PDF 文檔轉成 DOM 渲染到頁面上。雖然我之前并沒有使用過,但我相信它肯定可以拿到 PDF 上很多元數據,否則不可能做到還原成 DOM 去渲染。我甚至想,它有沒有可能直接幫我轉成一顆 根據標題已經結構化好的 DOM 樹。
在我使用pdf.js后,我發現,剛才稍微想的有點多了,但也足夠用了。它能把 PDF 文檔的文字塊以及這個文字塊的文字與大小信息 解構出來。比如這樣:
[{
"str": "2.4",
"dir": "ltr",
"width": 13.2,
"height": 10.56,
"transform": [10.56, 0, 0, 10.56, 346.03, 285.05],
"fontName": "g_d0_f1",
"hasEOL": false,
"pageNum": 4
},
{
"str": " 保險責任",
"dir": "ltr",
"width": 42.24,
"height": 10.56,
"transform": [10.56, 0, 0, 10.56, 364.39, 285.05],
"fontName": "g_d0_f12",
"hasEOL": false,
"pageNum": 4
}]
其中的 width與height決定了文字塊的大小,transform決定了文字塊在文檔上的絕對位置信息。pdf.js也是根據這些信息,把 PDF 內容以絕對位置與大小一個個的轉成 DOM 并繪制在網頁上。它不理解前后語序與內容結果,它只是粗暴的拼裝。
但這對我來說已經夠用了,有了這些信息,我就能分析出哪些文字塊是標題,哪些文字塊是正文的正常數字,哪些內容塊是底部的注釋內容。比如說:
等等等等吧,除此外,我們還需要判斷什么時候到注釋內容,什么是頁碼內容。因為這些內容都要做一些特殊處理。另外就是不同文檔可能有些特殊的邊界情況要處理一下。
雖然說這依舊很人肉,不智能,但至少能把路走通了。至于有些不是以 x.x.x 這樣的數字做標題的文檔,比如:第一章、第一節什么的,還是能拓展的,但就先不考慮了。
事情走到這一步,大問題就沒有了。但實際應用的時候,我們還是會發現一個小問題,就是很多小節的內容其實比較長,我們能做相似性映射的知識塊其實往往不僅一塊。當我們拼接多塊知識的時候,內容又超出了。而如果我們只拼接一塊內容,知識又不夠完整。這又讓我們抓耳撓腮了。
我仔細看了看這些小節的內容,我覺得,其實這段文本,要是用文言文來說,可能還可以再短一點(漢語真是博大精深)。但是我覺得如果讓 GPT 幫我把它轉成文言文的話,用戶提問的問題很可能就映射不到了。當然,我也真的試了一下,發現 text-davinci-003這個模型似乎在文言文領域也不太行,保險條款它很難轉成文言文。
但我有了另外一個思路,就是保險條款其實廢話還是有些多的,我可以讓 GPT 幫我做一些摘要性的總結,且盡量不丟失最核心的有效知識。在我網上搜索這塊相關的知識時,發現 NLP 領域有一種叫「命名實體識別(https://baike.baidu.com/item/%E5%91%BD%E5%90%8D%E5%AE%9E%E4%BD%93%E8%AF%86%E5%88%AB/6968430)」的技術,常用于搜索引擎、信息提取、問答系統中。不管三七二十一了,openai 這么強大,那我就這么讓它幫我這么做吧。
async function getSummary({ content, tokenLength }) {
const promptContext=`'''{{content}}'''基于命名實體識別構建內容摘要:`;
const contentTokenLength=tokenLength || encode(content).length;
const promptContextTokenLength=encode(promptContext).length;
const completion=await openai.createCompletion({
model: 'text-davinci-003',
prompt: promptContext.replace('{{content}}', content),
// 1000 ~ 4096,最大也不能超過1000
max_tokens: Math.min(
4096 - contentTokenLength - promptContextTokenLength,
1000,
),
temperature: 0,
});
return strip(completion?.data?.choices?.[0].text, ['\n']);
}
實際測試下來,這樣的方式相比直接總結摘要,從最終效果來看,返回的結果會穩定很多,且返回的知識不會只說到一半。具體原因也不懂,有資深的大佬可以幫忙指點一下。
經過這樣摘要化以后,我們就能把一段較長的知識文本給有效縮短。當用戶問起相關知識時,可以調用更多的知識塊來回答用戶。
事情走到這一步,你可能以為就真沒啥問題了。但實際上我們又遇到了個小麻煩。就是有部分小節的內容依舊還是太長了。就像一顆基因變異的西蘭花 。
我已經剪到最小的分支了,但這個最小的分支依舊超過了max_tokens的限制。這又難倒我了,現在我該怎么分割它?這似乎回到了我最開始遇到的問題。不過好在,這些變異的西蘭花并沒有動畫靈能百分百中的那么夸張,大部分還只是 略超 max_tokens一些,幾乎不會超過其兩倍。而自己觀察這些超出去的內容,往往是兩種類型。
我們發現這些小節的內容,其實并不適合分割。比如藥品列表要是分割成兩塊接近max_tokens的知識內容,一次性問答只能獲取其中一塊知識。這就會導致回答錯誤。比如你問有多少種藥品可以報銷,它自然會算錯。責任也是一樣。
但這些小節有另外一個方向,就是壓縮內容。里面有很多文字其實是相似的,比如一堆的社保目錄內/外。比如責任內容中頻繁出現的:惡性腫瘤``保險金``被保險人等等。我們只要做一本字典,把這些很長的重復性文字,用另外一種特殊的較短的字符指代。這段長文本就會瞬間被壓縮到較短的文本,我們再連同字典一起發給 GPT,讓它再翻譯回來并做摘要化,于是就繞過了max_tokens的限制。
但問題又來了,說的容易,代碼怎么知道哪些文字是一段詞語?如果代碼不知道哪些文字是一段詞語,又怎么做字典映射。總不能自己先把所有可能的詞匯都預先想好吧。雖然保險有一些專業術語可以提前預設,但總歸有更多的未知的。
這就引出了 NLP 領域的另外一門技術,分詞。很開心的是,在中文領域,且在 node.js 生態中,有一個比較好用的分詞工具「結巴分詞-https://github.com/yanyiwu/nodejieba」。不出意外,這也是 ChatGPT 告訴我的。
運用這個結巴分詞,我們就可以把一段內容分割成一個個詞匯,同時也支持傳入用戶預設的詞匯字典。這樣我們就能知道哪些詞匯在一段文本中被重復使用多次。對于這些詞匯,我們再用一個最短的字符去映射它。
const nodejieba=require('nodejieba');
nodejieba.load({
userDict: './userdict.utf8',
});
const longText='相學長白天吃飯,相學長中午也吃飯,相學長晚上還吃飯';
const words=nodejieba.cut(longText);
console.log(words);
// output
['相學長','白天','吃飯',',','相學長','中午','也','吃飯',',','相學長','晚上','還','吃飯'];
為了映射的字符盡量的短,我也是撓了一下腦袋,本來最簡單就是一個特殊字符加上從1遞增的數字就好了,比如這樣:*${index}。但是這個方式經過我實測,壓縮完的tokens效果還不夠極致。考慮到我們都是基本是中文環境,我最終選擇了 26個字母大小寫 + 24個拉丁字母大小寫作為索引:
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZαβγδεζηθικλμνξοπρστυφχψωΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ
根據第 0 步的知識,我們知道,千萬別用 emoji 去做字典索引。
這樣我們就得到最多100個索引,當然如果內容中已有出現具體的字母,最好還是針對該段內容剔除該字母。經過實際測試,這樣的壓縮效果會比數字映射法稍微好一些。且經過實測,這樣問 openai 依舊能得到正確答案。舉個例子:上文中的,相學長白天吃飯,相學長中午也吃飯,相學長晚上還吃飯會被轉化成,a白天b,a中午也b,a晚上還b|上文中,a:相學長,b:吃飯我們把這句話拿去問 GPT:相學長每天都在做什么。它能給出正確的回答:相學長每天都在吃飯。
除了字典法壓縮外,其實還有一個也比較顯著的手段。就是把全角字符全部轉成半角字符。在我的實際測試中,一段 8247 個tokens長度的內容。換半角相比不換半角,能多壓縮 580 個tokens,簡直是效果驚人!
其實不僅僅超過max_tokens的文本需要壓縮。我建議超過 3000 tokens的文本都得壓縮一下。因為 openai 最大的 4096 個token限制。并非是限制 prompt。而是限制 prompt+ 它的答案。也就是說,當我們做摘要化的時候,如果我們提供的原始內容越長,它能返回的摘要就越短。這顯然不符合我們的訴求。所以,雖然文章中這里寫著是第三步,但實際操作時,壓縮其實是第二步,壓縮需要在摘要化之前。
也是因為max_tokens的計算涵蓋了 GPT 的回答內容,所以當我們根據用戶提問拼接知識塊的時候,不能按照 max_tokens的限制去打滿內容,盡量留出 幾百到一千的 tokens給 GPT 做回答。
在我實操過程中呢,其實還存在一個文檔的內容,怎么壓縮也壓縮不到預期的長度。我確實選擇了逃避,因為這段內容是無數個疾病的詳細介紹,我騙自己說這些詳細介紹并沒太大用。因此最終我做了一個特殊處理,如果是這個超長的疾病介紹,我就只保留了疾病標題,去掉了疾病的內容。
針對這種,再壓縮也解決不了的問題,我目前確實還沒找到非常好的解法。
最終經過我們對 PDF 文檔的分割、壓縮、小節內容摘要化、轉成嵌套文檔樹,最終再上一個西蘭花算法。我們就能完成對這個 PDF 文檔的合理分割了。最終我們再把分割后的內容做向量化處理,就能實現一個比較好的基于超長保單文檔的保險產品問答服務。
其實其他領域的文檔也差不多,只要這個文檔結構比較好切割。
相關代碼開源,有興趣的同學自己下載繼續研究吧~ https://github.com/wuomzfx/pdfGPT
關于到底怎么做向量化、怎么做匹配,我在本文就不多說了,這個還是比較容易了。包括其他還有一些特殊的處理,比如怎么把注釋內容拼接到正文里。這些都可以在源碼中方便尋找到。其他可能還稍微需要一點工具知識的,就是 node 中如何做兩個 embedding 向量的相似性匹配。用 @stblib/blas這個 npm 包就行。DEMO 示例:
const ddot=require('@stdlib/blas/base/ddot');
const x=new Float64Array(questionEmbedding);
const y=new Float64Array(knowledgeEmbedding);
const result=ddot(x.length, x, 1, y, 1),
如果還有哪里不明白的,歡迎評論區或者先嘗試問下 ChatGPT~
感覺人工智能的時代真的要到來了,連我這種 AI 小白,似乎都已經能完成一個可能真的能投入使用的服務。我再整個小程序,糊個頁面,把一些異常容錯機制再完善完善。再稍微整個爬蟲,從保險行業協會網站幫用戶快捷找到相關的保險條款。我幾乎就能實現一個幫助用戶回答保險產品的應用了。
亦或者,我可以自己預設一些問題。通過這些問題,我可以從保險條款中結構化出很多有效的信息,比如保額保費、責任細節、投保年限、續保年限等等。結構化之后,我又可以直接做不同產品的對比,根據用戶的要求推薦比較合適的保險產品。這是一件挺有可能的事情,我嘗試把之前的兩個問答作為對比再次問 GPT 推薦哪款產品,它的回答比較中肯且有用。
總之,新的 AI 基礎設施,已經能成為現在大部分工程師的有利工具。在某些垂直領域做一些深入研究,通過這些工具,AI 就能發揮出意想不到的作用,我們可以快速的產出各種有意思的產品。就好像 HTML5 跟 小程序 帶來一系列有意思的 輕量APP 一樣。相信,AI 浪潮在這兩年就要席卷而來了~~
作者:相學長
來源:微信公眾號:相學長
出處:https://mp.weixin.qq.com/s/xZrNlyqT67oQy6Tpf7LGZQ
*請認真填寫需求信息,我們會在24小時內與您取得聯系。