欧美性20hd另类_特级毛片A级毛片免费观看站_公和熄小婷乱中文字幕_wwjizz_东京热com

如何用低代碼搭建訓(xùn)練一個(gè)專業(yè)知識(shí)庫(kù)問答GPT機(jī)器人

來源:依然基于Stable-Diffusion模型生成

距離上篇文章《低代碼xChatGPT,五步搭建AI聊天機(jī)器人》已經(jīng)過去3個(gè)多月,收到了很多小伙伴的關(guān)注和反饋,也幫助很多朋友快速低成本搭建了ChatGPT聊天應(yīng)用,未曾想這一段時(shí)間GPT熱度只增不減,加上最近國(guó)內(nèi)外各種LLM、文生圖多模態(tài)模型密集發(fā)布,開發(fā)者們也有了更高的要求。比如如何訓(xùn)練一個(gè)自己的GPT應(yīng)用,如何結(jié)合GPT和所在的專業(yè)領(lǐng)域知識(shí)來搭建AI應(yīng)用,像心理咨詢助手、個(gè)人知識(shí)庫(kù)助手等,看目前網(wǎng)上這方面資料還不多,今天我們就來拋個(gè)磚試試。

目前的預(yù)訓(xùn)練方式主要如下幾種:


(相關(guān)資料圖)

基于OpenAI的官方LLM模型,進(jìn)行fine-tune(費(fèi)用高,耗時(shí)長(zhǎng))基于開源的Alpaca.cpp本地模型(目前可在本地消費(fèi)級(jí)顯卡跑起來,對(duì)自己硬件有信心也可以試試)通過向量數(shù)據(jù)庫(kù)上下文關(guān)聯(lián)(輕量級(jí),費(fèi)用可控,速度快,包括昨天OPENAI官方昨天剛放出來的示例插件chatgpt-retrieval-plugin,也采用的這種方式)

低代碼實(shí)現(xiàn)的AI問答機(jī)器人效果如下:

這次還是用騰訊云微搭低代碼作為應(yīng)用搭建平臺(tái),來介紹如何快速搭建一個(gè)垂直領(lǐng)域的知識(shí)庫(kù)GPT問答機(jī)器人,今天的教程盡量避開了各種黑科技的封裝庫(kù)(沒有Langchain/Supabase/PineconeSDK全家桶),嘗試從最基本的實(shí)現(xiàn)原理來展開介紹,盡量讓大家知其所以然。新手開發(fā)者也可以試試,與其看各種GPT熱鬧,不如Make your hands dirty

一、準(zhǔn)備工作

在開始搭建垂直知識(shí)庫(kù)的問答機(jī)器人前,你需要做以下準(zhǔn)備:

微信小程序賬號(hào):如果您還沒有微信小程序賬號(hào),可以在微信公眾平臺(tái)注冊(cè)(如果沒有小程序,也可以發(fā)布為移動(dòng)端H5應(yīng)用)開通騰訊云微搭低代碼:微搭低代碼是騰訊云官方推出的一款低代碼開發(fā)工具,可以直接訪問騰訊云微搭官網(wǎng)免費(fèi)開通注冊(cè)O(shè)penAI賬號(hào):OpenAI賬號(hào)注冊(cè)也是免費(fèi)的,不過OpenAI有地域限制,網(wǎng)上方法很多在此不贅述。注冊(cè)成功后,可以登錄OpenAI的個(gè)人中心來獲取API KEY一個(gè)支持向量匹配的數(shù)據(jù)庫(kù)(本文以開源的PostgreSQL為例,你也可以使用Redis,或者NPM的HNSWlib包)

關(guān)于向量數(shù)據(jù)庫(kù),目前可選擇的方式有好幾種,可以使用PostgreSQL安裝vector向量擴(kuò)展,也可以使用Redis的Vector Similarity Search,還可以直接云函數(shù)使用HNSWLib庫(kù),甚至自行diy一個(gè)簡(jiǎn)單的基于文件系統(tǒng)的余弦相似度向量數(shù)據(jù)庫(kù),文末的 github/lowcode.ai也有簡(jiǎn)單示例代碼,僅做參考交流不建議在生產(chǎn)環(huán)境使用。

本教程適用人群和應(yīng)用類型:

適用人群:有前后端基礎(chǔ)的開發(fā)者(有一定技術(shù)背景的非開發(fā)者也可以體驗(yàn))應(yīng)用類型:小程序 或 H5應(yīng)用(基于微搭一碼多端特性,可以發(fā)布為Web應(yīng)用,點(diǎn)擊原文鏈接可體驗(yàn)作者基于微搭搭建的文檔GPT機(jī)器人)

二、搭建聊天機(jī)器人界面

如何使用低代碼進(jìn)行界面搭建的詳細(xì)過程,在之前的文章中《低代碼xChatGPT,五步搭建AI聊天機(jī)器人》已經(jīng)有過詳細(xì)的教程介紹,這里就不再繼續(xù)展開。

另外,大家也可以使用微搭官方的聊天模板,這樣的話界面這一步直接跳過,開箱即用,附微搭低代碼GPT聊天應(yīng)用模板地址

完成界面配置之后,大家重點(diǎn)關(guān)注下圖中頁(yè)面設(shè)計(jì)模塊的”發(fā)送“按鈕的事件配置即可,在后續(xù)會(huì)提到。

三、配置后端邏輯

與之前機(jī)器人的實(shí)現(xiàn)直接調(diào)用遠(yuǎn)程API不同,這次由于需要針對(duì)專業(yè)的領(lǐng)域知識(shí)進(jìn)行預(yù)處理以及向量化,重點(diǎn)會(huì)涉及3個(gè)部分:

讀取待訓(xùn)練的文檔數(shù)據(jù)并進(jìn)行向量化,之后存入向量數(shù)據(jù)庫(kù)通過query的向量化結(jié)果與數(shù)據(jù)庫(kù)向量進(jìn)行相似度匹配,并返回關(guān)聯(lián)文本結(jié)果結(jié)合返回的關(guān)聯(lián)文本和query來構(gòu)建上下文生成prompt

可以通過下圖了解向量搜索實(shí)現(xiàn)GPT Context的大致原理:

由上圖可見,主要是兩個(gè)處理流程,一個(gè)文檔數(shù)據(jù)的向量化預(yù)處理,一個(gè)是查詢時(shí)的向量匹配和Context構(gòu)造處理,這兩個(gè)處理我們都可以使用騰訊云低代碼的云函數(shù)來實(shí)現(xiàn)(當(dāng)然第一步的預(yù)處理也可以在本地電腦完成)

1. 將知識(shí)庫(kù)文檔數(shù)據(jù)向量化

首先,將所需要的預(yù)處理的知識(shí)庫(kù)內(nèi)容放在某個(gè)目錄下,遍歷知識(shí)庫(kù)目錄下的所有文檔文件(本文文件格式以markdown為例),將文本分塊后結(jié)構(gòu)化存儲(chǔ)在本地json文件。

如果數(shù)據(jù)量小,分塊后的結(jié)構(gòu)化數(shù)據(jù)也可以直接放在內(nèi)存中,本地化json主要便于在大量文本預(yù)處理時(shí),遇到網(wǎng)絡(luò)等異常時(shí),能夠在斷點(diǎn)處重啟預(yù)處理

關(guān)鍵代碼如下:

本教程涉及的完整代碼已放到https://github.com/enimo/lowcode.ai中,可按需下載試驗(yàn),也可直接上傳到微搭低代碼的云函數(shù)中運(yùn)行)

function splitDocuments(files, chunkSize) {let docSize = chunkSize || 1000;let textString = "";let index = 0;let documents = [];for(let i = 0, len = files.length; i < len; i++) {if(files[i] && files[i].content) {textString = files[i].content;}else {textString = fs.readFileSync(files[i], "utf8");}textString = textString.replace(/\n|\r/g, " ").replace(/<.*?>/g,"")    let start = 0;    while (start < textString.length) {      const end = start + docSize;      const chunk = textString.slice(start, end);      documents.push({ docIndex: index++, fileIndex: files[i].fileIndex, filename: files[i].filename || files[i], content: chunk });      start = end;}  }  fs.writeFileSync("./docstore.json", JSON.stringify(documents));  return documents;}

上述代碼用途主要是在得到遍歷后的文件路徑數(shù)組files后,對(duì)文件進(jìn)行切塊處理,分塊大小可按需調(diào)整,一般建議在1000~2000之間(切換主要為兼容GPT API的單次token限制及成本控制)

其次,對(duì)分塊的文本進(jìn)行向量化并存入向量數(shù)據(jù)庫(kù),關(guān)鍵代碼如下:

async function initVector(sql, docs){    const maxElements = docs.length || 500; // 最多處理500個(gè)    for (let j = 0; j < maxElements; j++ ) {        const input = docs[j].content;        const filename = docs[j].filename;        const fileIndex = docs[j].fileIndex        const docIndex = docs[j].docIndex        // 通過根據(jù)訓(xùn)練日志返回?cái)帱c(diǎn)docIndex,調(diào)整 docIndex 的值,確保從斷點(diǎn)繼續(xù)向量化        if(docIndex >= 0 &&  docIndex < 1000 ){            log("start embedding fileIndex: ", fileIndex, "docIndex: ", docIndex, "filename:", filename);            const embedding = await embedding(input);            const embeddingArr = "[" + embedding + "]";            const metadata = { filename, "doclength": maxElements, index: j };            const insertRet = await sql`              INSERT INTO documents ( content, appcode, metadata, embedding )              VALUES              ( ${input}, "wedadoc",  ${metadata}, ${embeddingArr} )`            await delay(1000); // 如果embedding API并發(fā)請(qǐng)求限制,可設(shè)置隨機(jī)數(shù)sleep        }        else {          continue;        }    }    return true;}

上述文本向量化的存儲(chǔ)過程中,涉及到調(diào)用OpenAI的embedding模型進(jìn)行向量轉(zhuǎn)化,這里使用text-embedding-ada-002模型(這個(gè)文本向量化過程也可以不使用OpenAI的官方模型,有部分開源模型可代替)

async function embedding (text) {    const raw_text = text.replace(/\n|\r/g, " ");    const embeddingResponse = await fetch(        OPENAI_URL + "/v1/embeddings",        {          method: "POST",          headers: {            "Authorization": `Bearer ${OPENAI_API_KEY}`,            "Content-Type": "application/json"          },          body: JSON.stringify({            input: raw_text,            model: "text-embedding-ada-002"          })        }    );    const embeddingData = await embeddingResponse.json();        const [{ embedding }] = embeddingData.data;    log({embedding});    return embedding;}

以上,一個(gè)文檔知識(shí)庫(kù)的向量化預(yù)處理就基本完成了,接下來看看怎么實(shí)現(xiàn)基于query的搜索邏輯。

2. 實(shí)現(xiàn)query的向量化搜索

我們?cè)谏弦徊街幸呀?jīng)完成了文本數(shù)據(jù)的向量化存儲(chǔ)。接下來,可以基于用戶提交的query來進(jìn)行相似度搜索,關(guān)鍵代碼如下:

async function searchKnn(question, k, sql){    const embedding = await embedding(question);    const embeddingArr = "[" + embedding + "]";    const result = await sql`SELECT * FROM match_documents(${embeddingArr},"wedadoc", 0.1, ${k})`    return result;}

上述代碼將query同樣轉(zhuǎn)化為向量后,再去上一步向量化后的數(shù)據(jù)庫(kù)中進(jìn)行相似搜索,得到最終與query最匹配的上下文,其中有一個(gè)預(yù)定義的SQL函數(shù)match_documents,主要用作文本向量的匹配搜索,具體會(huì)在后面介紹,在 github/lowcode.ai中也有詳細(xì)的定義和說明。

最后,我們工具拿到的搜索返回值,來構(gòu)造GPT 3.5接口的prompt上下文,關(guān)鍵代碼如下:

async function getChatGPT (query, documents){    let contextText = "";    if (documents) {        for (let i = 0; i < documents.length; i++) {            const document = documents[i];            const content = document.content;              const url = encodeURI(document.metadata["filename"]);            contextText += `${content.trim()}\n SOURCE: ${url}\n---\n`;        }    }    const systemContent = `You are a helpful assistant. When given CONTEXT you answer questions using only that information,and you always format your output in markdown. `;    const userMessage = `CONTEXT:      ${contextText}      USER QUESTION:       ${query}`;    const messages = [        {          role: "system",          content: systemContent        },        {          role: "user",          content: userMessage        }    ];      const chatResponse = await fetch(        OPENAI_URL + "/v1/chat/completions",        {            method: "POST",            headers: {                "Authorization": `Bearer ${OPENAI_API_KEY}`,                "Content-Type": "application/json"            },            body: JSON.stringify({                "model": "gpt-3.5-turbo",                 "messages": messages,                "temperature": 0.3,                 "max_tokens": 2000,            })        }    );    return await chatResponse.json();}

上述代碼中核心是上下文的構(gòu)造,由于GPT3.5之后的接口,支持指定role,可以將相關(guān)系統(tǒng)角色的prompt放在了systemContent中,至于/v1/chat/completions接口入?yún)⒄f明由于之前的文章中有過介紹,這里也不贅述,有任何疑問大家也可以到「漫話開發(fā)者」公眾號(hào)留言詢問。

以上,query的搜索部分完成了,到此所有后端接口的核心邏輯也都完成了,可以看到幾個(gè)關(guān)鍵流程的實(shí)現(xiàn)是不是很簡(jiǎn)單呢。

3. 將所涉及代碼部署到微搭低代碼的云函數(shù)中

完成后端代碼開發(fā)后,接下來就是把相應(yīng)的運(yùn)行代碼部署到微搭低代碼的云函數(shù)中,綜上可知,主要是兩部分的后端代碼,一部分文檔的向量化并入庫(kù)(這部分本地Node環(huán)境運(yùn)行亦可),另一部分就是實(shí)現(xiàn)搜索詞匹配構(gòu)建prompt后調(diào)用GPT接口查詢了。

微搭低代碼的云函數(shù)入口,可以在數(shù)據(jù)源->APIs->云函數(shù)中找到,如下圖所示:

如果第一次使用云函數(shù),需要點(diǎn)擊圖中鏈接跳轉(zhuǎn)到云開發(fā)云函數(shù)中進(jìn)行云函數(shù)的新建,如下圖所示:

新建完成后,點(diǎn)擊進(jìn)入云函數(shù)詳情頁(yè),選擇”函數(shù)代碼“Tab,然后在下面的提交方法下拉框中選擇”本地上傳ZIP包“即可上傳前面完成的后端邏輯代碼,也可以直接下載 github/lowcode.ai打包后上傳。上傳成功后,第一次保存別忘了點(diǎn)擊”保存并安裝依賴“來安裝對(duì)應(yīng)的npm包。

在完成云函數(shù)新建和代碼上傳后,回到上一步的微搭數(shù)據(jù)源APIs界面中刷新頁(yè)面,即可看到剛剛新建好的云函數(shù)openai,選中該云函數(shù),并按要求正確填寫對(duì)應(yīng)的出入?yún)⒔Y(jié)構(gòu),測(cè)試方法效果并保存后,即可在第一章的前端界面”發(fā)送“按鈕中綁定調(diào)用數(shù)據(jù)源事件進(jìn)行調(diào)用了。

4. 完成開發(fā)聯(lián)調(diào),發(fā)布應(yīng)用

完成上述后端邏輯以及云函數(shù)配置后,可以切到編輯器的頁(yè)面設(shè)計(jì)模塊,回到第一章的界面設(shè)計(jì)來進(jìn)行事件的配置,完成后點(diǎn)擊編輯器右上角的“發(fā)布”按鈕,可以選擇發(fā)布到你已綁定的小程序,也可以直接發(fā)布Web端H5/PC應(yīng)用。

至此,一個(gè)垂直知識(shí)庫(kù)的AI問答機(jī)器人應(yīng)用基本就搭建完成了。

四、附錄說明

1 數(shù)據(jù)庫(kù)PostgreSQL的初始化

本文中采用的PostgreSQL作為向量數(shù)據(jù)庫(kù),其中涉及到的建表結(jié)構(gòu)定義參考如下:

create table documents (  id bigserial primary key,  content text, -- corresponds to Document.pageContent  metadata json, -- corresponds to Document.metadata  embedding vector(1536) -- 1536 works for OpenAI embeddings, change if needed);

涉及的SQL函數(shù)match_documents的定義參考如下,其中query_embedding表示query關(guān)鍵詞的向量值,similarity_threshold表示相似度,一般情況下要求不低于0.1,數(shù)值越低相似度也越低,match_count表示匹配后的返回條數(shù),一般情況下2條左右,取決于前文的分塊chunk定義大小。

create or replace function match_documents (  query_embedding vector(1536),  similarity_threshold float,  match_count int)returns table (  id bigint,  content text,  metadata json,  similarity float)language plpgsqlas $$begin  return query  select    documents.id,    documents.content,    documents.metadata,    1 - (documents.embedding <=> query_embedding) as similarity  from documents  where 1 - (documents.embedding <=> query_embedding) > similarity_threshold    order by documents.embedding <=> query_embedding  limit match_count;end;$$;

所有上述的內(nèi)容數(shù)據(jù)庫(kù)SQL schema以及部分訓(xùn)練備用文本數(shù)據(jù)都已經(jīng)放到github,大家可以關(guān)注定期更新,按需采用: github/lowcode.ai

2 體驗(yàn)試用

可以通過Web端體驗(yàn)作者搭建的Web版文檔機(jī)器人,同時(shí)得益于微搭低代碼的一碼多端,同步發(fā)布了一個(gè)小程序版本,大家可以掃碼體驗(yàn)。

低代碼文檔AI小程序

由于目前自建向量庫(kù)的性能局限以及有限的預(yù)處理文檔數(shù)據(jù),響應(yīng)可能比較慢,準(zhǔn)確性偶爾也會(huì)差強(qiáng)人意,還請(qǐng)各位看官諒解,抽時(shí)間再持續(xù)優(yōu)化了,本文還是以技術(shù)方案的探討交流為主。

3 最后

通過本教程的介紹,你已經(jīng)基本熟悉了如何使用微搭低代碼快速搭建垂直知識(shí)庫(kù)的AI問答機(jī)器人了,有任何疑問可以留言。

用低代碼創(chuàng)建一個(gè)GPT的聊天應(yīng)用很簡(jiǎn)單,實(shí)現(xiàn)一個(gè)垂直領(lǐng)域的AI問答應(yīng)用也不難。未來不管被AI替代也好,新的開發(fā)者時(shí)代來了,先動(dòng)手試試,make your hands dirty first, enjoy~

關(guān)鍵詞:

    為你推薦

    如何用低代碼搭建訓(xùn)練一個(gè)專業(yè)知識(shí)庫(kù)問答GPT機(jī)器人

    距離上篇文章《低代碼xChatGPT,五步搭建AI聊天機(jī)器人》已經(jīng)過去3個(gè)多月,收到了很多小伙伴的關(guān)注和反饋,也幫助很多朋友快速低成本搭建了Chat

    來源:騰訊云 23-03-29

    steam商店頁(yè)面加載不出來/Steam商店頁(yè)面打不開解決方法-每日信息

    最近一段時(shí)間很多玩家都有遇到過使用steam時(shí)不正常,下面是關(guān)于steam商店頁(yè)面加載不出來 Steam商店頁(yè)面打不開解決方法,如果你也有同樣的問題

    來源:?jiǎn)袅▎袅?/span> 23-03-29

    速看:2023年?山西中級(jí)會(huì)計(jì)考試報(bào)名網(wǎng)址是什么?

    2023年山西中級(jí)會(huì)計(jì)考試報(bào)名網(wǎng)址是什么?根據(jù)山西2023年中級(jí)會(huì)計(jì)職稱報(bào)名簡(jiǎn)章,山西2023年中級(jí)會(huì)計(jì)考試報(bào)名網(wǎng)址是“全國(guó)會(huì)計(jì)資格評(píng)價(jià)網(wǎng)”。山

    來源:永圖教育 23-03-29

    “國(guó)潮”與“運(yùn)動(dòng)化”組合拳 試駕全新紅旗H6

    隨著全新紅旗H6的到來,不僅讓我們看到這家央企“敢為天下先”的一面,更是用最符合時(shí)代脈搏的氣息,為中國(guó)汽車產(chǎn)業(yè)基底刷上一層亮色。-更多汽

    來源:網(wǎng)通社 23-03-29

    熱點(diǎn)聚焦:夏夢(mèng)雅律師團(tuán)隊(duì):夸大機(jī)動(dòng)車的“自動(dòng)駕駛”功能導(dǎo)致事故是誰(shuí)的責(zé)任?

    目前大多數(shù)機(jī)動(dòng)車的自動(dòng)駕駛系統(tǒng)都達(dá)到了L1級(jí)別,此階段的輔助駕駛功能主要是通過傳感、信號(hào)處理、通訊和計(jì)算機(jī)等技術(shù)更好的辨別車輛周圍的環(huán)

    來源:搜狐汽車 23-03-29
    返回頂部