開(kāi)發(fā)人員在MyScale構(gòu)建RAG系統(tǒng)的方式,從構(gòu)建帶有服務(wù)器端場(chǎng)景的提示到將這些場(chǎng)景引入GPT模型。
MyScale簡(jiǎn)化了將場(chǎng)景引入GPT的方式。例如,OpenAI公司的方法是通過(guò)Web UI將文件上傳到GPT平臺(tái)。同時(shí),MyScale允許開(kāi)發(fā)使用SQL WHERE子句混合結(jié)構(gòu)化數(shù)據(jù)過(guò)濾和語(yǔ)義搜索,以更低的成本處理和存儲(chǔ)更大的知識(shí)庫(kù),以及在多個(gè)GPT之間共享一個(gè)知識(shí)庫(kù)。
現(xiàn)在就可以在GPT商店試用MyScaleGPT,或者將MyScale的開(kāi)放知識(shí)庫(kù)與托管在Hugging Face上的API集成到應(yīng)用程序中。
BYOK:采用自己的知識(shí)
GPT在過(guò)去的一年中有了很大的發(fā)展,它在共享知識(shí)領(lǐng)域獲得的知識(shí)比最初發(fā)布時(shí)要多得多。然而,仍然有GPT一無(wú)所知或不確定的特定主題,例如特定領(lǐng)域的知識(shí)和當(dāng)前事件。因此,正如在之前的文章所描述的,必須將存儲(chǔ)在MyScale中的外部知識(shí)庫(kù)集成到GPT中,以提高其真實(shí)性和有用性。
當(dāng)開(kāi)發(fā)人員使用MyScale構(gòu)建RAG時(shí),將LLM引入他們的鏈(或堆棧)。這一次需要將MyScale數(shù)據(jù)庫(kù)帶到GPT平臺(tái)。不幸的是,目前還不可能直接在GPT和MyScale之間建立連接。因此,調(diào)整了查詢(xún)接口,將其公開(kāi)為REST API。
由于之前在OpenAI函數(shù)調(diào)用方面的成功,現(xiàn)在可以設(shè)計(jì)一個(gè)類(lèi)似的接口,其中GPT可以使用類(lèi)似SQL的過(guò)濾器字符串編寫(xiě)向量搜索查詢(xún)。在OpenAPI中的參數(shù)如下:
"parameters":[{"name":"subject","in":"query","description":"A sentence or phrase describes the subject you want to query.","required":true,"schema":{"type":"string"}},{"name":"where_str","in":"query","description":"a SQL-like where string to build filter","required":true,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"desired number of retrieved documents","schema":{"type":"integer","default":4}}]
有了這樣的接口,GPT可以用SQL編寫(xiě)的過(guò)濾器提取關(guān)鍵字來(lái)描述所需的查詢(xún)。
向不同的表提供查詢(xún)條目
有時(shí)可能需要查詢(xún)不同的表。這可以使用單獨(dú)的API條目來(lái)實(shí)現(xiàn)。每個(gè)API條目在其文檔下都有自己的模式和提示。GPT將讀取適用的API文檔,并將正確的查詢(xún)寫(xiě)入相應(yīng)的表。
值得注意的是,之前介紹的方法(例如自查詢(xún)檢索器和向量SQL)都需要?jiǎng)討B(tài)或半動(dòng)態(tài)提示來(lái)描述表結(jié)構(gòu)。與其相反,GPT的功能類(lèi)似于LangChain中的會(huì)話(huà)代理,其中代理使用不同的工具來(lái)查詢(xún)表。
例如,API條目可以在OpenAPI 3.0中編寫(xiě)如下:
JSON"paths":{// query entry to arxiv table"/get_related_arxiv":{"get":{// descriptions will be injected into the tool prompt// so that GPT will know how and when to use this query tool"description":"Get some related papers.""You should use schema here:\n""CREATE TABLE ArXiv (""? ? `id` String,""? ? `abstract` String,""? ? `pubdate` DateTime,""? ? `title` String,""? ? `categories` Array(String), -- arxiv category""? ? `authors` Array(String),""? ? `comment` String,""ORDER BY id","operationId":"get_related_arxiv","parameters":[// parameters mentioned above],}},// query entry to wiki table"/get_related_wiki":{"get":{"description":"Get some related wiki pages. ""You should use schema here:\n\n""CREATE TABLE Wikipedia (""? ? `id` String,""? ? `text` String,""? ? `title` String,""? ? `view` Float32,""? ? `url` String, -- URL to this wiki page""ORDER BY id\n""You should avoid using LIKE on long text columns.","operationId":"get_related_wiki","parameters":[// parameters mentioned above]}}}
根據(jù)這個(gè)代碼片段,GPT知道有兩個(gè)知識(shí)庫(kù)可以幫助回答用戶(hù)的問(wèn)題。
在為知識(shí)庫(kù)檢索配置GPT操作后,只需填寫(xiě)指令并告訴GPT如何查詢(xún)知識(shí)庫(kù),然后回答用戶(hù)問(wèn)題:
注:盡量回答問(wèn)題。隨意使用任何可用的工具來(lái)查找相關(guān)信息。在調(diào)用搜索函數(shù)時(shí),保留查詢(xún)中的所有詳細(xì)信息。使用MyScale知識(shí)庫(kù)查詢(xún)字符串?dāng)?shù)組時(shí),請(qǐng)使用has(column, value)進(jìn)行匹配。對(duì)于發(fā)布日期,使用parsedatetime32bestefort()將時(shí)間戳值從字符串格式轉(zhuǎn)換為日期時(shí)間對(duì)象,不使用這個(gè)函數(shù)轉(zhuǎn)換日期時(shí)間類(lèi)型的列。開(kāi)發(fā)人員應(yīng)該始終為其使用的文檔添加參考鏈接。
將數(shù)據(jù)庫(kù)托管為OpenAPI
GPT采用OpenAI 3.0標(biāo)準(zhǔn)下的API。有些應(yīng)用程序(例如數(shù)據(jù)庫(kù))沒(méi)有OpenAPI接口。因此,需要使用中間件將GPT與MyScale集成在一起。
開(kāi)發(fā)人員已經(jīng)在Hugging Face上托管了與OpenAI兼容的接口的數(shù)據(jù)庫(kù)。使用flask-restx app.py, funcs.py來(lái)簡(jiǎn)化和自動(dòng)化實(shí)現(xiàn),因此代碼小、干凈、易于閱讀。
這樣做的好處是提示和函數(shù)都綁定在一起了。因此,不需要過(guò)多考慮提示、功能和可擴(kuò)展性的組合;用人類(lèi)可讀的格式來(lái)寫(xiě)。GPT將從轉(zhuǎn)儲(chǔ)的OpenAI JSON文件中讀取這個(gè)文檔。
注:flask restx只生成Swagger 2.0格式的API。必須首先使用Swagger Editor將它們轉(zhuǎn)換為OpenAPI 3.0格式。你可以在Hugging Face上使用JSON API作為參考。
GPT使用API中的場(chǎng)景運(yùn)行
在適當(dāng)?shù)闹笇?dǎo)下,GPT將使用特殊函數(shù)仔細(xì)處理不同的數(shù)據(jù)類(lèi)型。這些數(shù)據(jù)類(lèi)型的示例包括ClickHouse SQL函數(shù),例如用于數(shù)組列的has(column, value)和用于時(shí)間戳列的parsedatetime32bestefort (value)。
在將正確的查詢(xún)發(fā)送給API之后,它(或API)將使用WHERE子句字符串中的過(guò)濾器構(gòu)造向量搜索查詢(xún)。返回的值被格式化為字符串,作為從數(shù)據(jù)庫(kù)檢索到的額外知識(shí)。正如以下的代碼示例所描述的,這個(gè)實(shí)現(xiàn)非常簡(jiǎn)單。
Python
1 class ArXivKnowledgeBase:
2? ? def __init__(self, embedding: SentenceTransformer) -> None:
3? ? ? ? # This is our open knowledge base that contains default.ChatArXiv and wiki.Wikipedia
4? ? ? ? self.db = clickhouse_connect.get_client(
5? ? ? ? ? ? host='msc-4a9e710a.us-east-1.aws.staging.myscale.cloud',
6? ? ? ? ? ? port=443,
7? ? ? ? ? ? username='chatdata',
8? ? ? ? ? ? password='myscale_rocks'
9? ? ? ? )
10? ? ? ? self.embedding: SentenceTransformer = INSTRUCTOR('hkunlp/instructor-xl')
11? ? ? ? self.table: str = 'default.ChatArXiv'
12? ? ? ? self.embedding_col = "vector"
13? ? ? ? self.must_have_cols: List[str] = ['id', 'abstract', 'authors', 'categories', 'comment', 'title', 'pubdate']
14
15
16? ? def __call__(self, subject: str, where_str: str = None, limit: int = 5) -> Tuple[str, int]:
17? ? ? ? q_emb = self.embedding.encode(subject).tolist()
18? ? ? ? q_emb_str = ",".join(map(str, q_emb))
19? ? ? ? if where_str:
20? ? ? ? ? ? where_str = f"WHERE {where_str}"
21? ? ? ? else:
22? ? ? ? ? ? where_str = ""
23? ? ? ? # Simply inject the query vector and where_str into the query
24? ? ? ? # And you can check it if you want
25? ? ? ? q_str = f"""
26? ? ? ? ? ? SELECT dist, {','.join(self.must_have_cols)}
27? ? ? ? ? ? FROM {self.table}
28? ? ? ? ? ? {where_str}
29? ? ? ? ? ? ORDER BY distance({self.embedding_col}, [{q_emb_str}])
30? ? ? ? ? ? ? ? AS dist ASC
31? ? ? ? ? ? LIMIT {limit}
32? ? ? ? ? ? """
33? ? ? ? docs = [r for r in self.db.query(q_str).named_results()]
34? ? ? ? return '\n'.join([str(d) for d in docs]), len(docs)
結(jié)論
GPT確實(shí)是OpenAI開(kāi)發(fā)者界面的重大改進(jìn)。開(kāi)發(fā)人員不需要編寫(xiě)太多代碼來(lái)構(gòu)建他們的聊天機(jī)器人,而且工具現(xiàn)在可以自帶提示。我們?yōu)镚PT創(chuàng)造一個(gè)生態(tài)系統(tǒng)是很美好的。另一方面,鼓勵(lì)開(kāi)源社區(qū)重新考慮將LLM和工具結(jié)合起來(lái)的現(xiàn)有方式。
因?yàn)橄嘈艑⑼獠恐R(shí)庫(kù)存儲(chǔ)在外部數(shù)據(jù)庫(kù)中,將會(huì)提高LLM的真實(shí)性和有用性。很多人正在尋找新的方法來(lái)整合像MyScale這樣的矢量數(shù)據(jù)庫(kù)和LLM。