【架構】使用MyScale將知識庫引入OpenAI的GPT

開發(fā)人員在MyScale構建RAG系統(tǒng)的方式,從構建帶有服務器端場景的提示到將這些場景引入GPT模型。

MyScale簡化了將場景引入GPT的方式。例如,OpenAI公司的方法是通過Web UI將文件上傳到GPT平臺。同時,MyScale允許開發(fā)使用SQL WHERE子句混合結構化數(shù)據(jù)過濾和語義搜索,以更低的成本處理和存儲更大的知識庫,以及在多個GPT之間共享一個知識庫。

現(xiàn)在就可以在GPT商店試用MyScaleGPT,或者將MyScale的開放知識庫與托管在Hugging Face上的API集成到應用程序中。

BYOK:采用自己的知識

GPT在過去的一年中有了很大的發(fā)展,它在共享知識領域獲得的知識比最初發(fā)布時要多得多。然而,仍然有GPT一無所知或不確定的特定主題,例如特定領域的知識和當前事件。因此,正如在之前的文章所描述的,必須將存儲在MyScale中的外部知識庫集成到GPT中,以提高其真實性和有用性。

當開發(fā)人員使用MyScale構建RAG時,將LLM引入他們的鏈(或堆棧)。這一次需要將MyScale數(shù)據(jù)庫帶到GPT平臺。不幸的是,目前還不可能直接在GPT和MyScale之間建立連接。因此,調整了查詢接口,將其公開為REST API。

由于之前在OpenAI函數(shù)調用方面的成功,現(xiàn)在可以設計一個類似的接口,其中GPT可以使用類似SQL的過濾器字符串編寫向量搜索查詢。在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編寫的過濾器提取關鍵字來描述所需的查詢。

向不同的表提供查詢條目

有時可能需要查詢不同的表。這可以使用單獨的API條目來實現(xiàn)。每個API條目在其文檔下都有自己的模式和提示。GPT將讀取適用的API文檔,并將正確的查詢寫入相應的表。

值得注意的是,之前介紹的方法(例如自查詢檢索器和向量SQL)都需要動態(tài)或半動態(tài)提示來描述表結構。與其相反,GPT的功能類似于LangChain中的會話代理,其中代理使用不同的工具來查詢表。

例如,API條目可以在OpenAPI 3.0中編寫如下:

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ù)這個代碼片段,GPT知道有兩個知識庫可以幫助回答用戶的問題。

在為知識庫檢索配置GPT操作后,只需填寫指令并告訴GPT如何查詢知識庫,然后回答用戶問題:

注:盡量回答問題。隨意使用任何可用的工具來查找相關信息。在調用搜索函數(shù)時,保留查詢中的所有詳細信息。使用MyScale知識庫查詢字符串數(shù)組時,請使用has(column, value)進行匹配。對于發(fā)布日期,使用parsedatetime32bestefort()將時間戳值從字符串格式轉換為日期時間對象,不使用這個函數(shù)轉換日期時間類型的列。開發(fā)人員應該始終為其使用的文檔添加參考鏈接。

將數(shù)據(jù)庫托管為OpenAPI

GPT采用OpenAI 3.0標準下的API。有些應用程序(例如數(shù)據(jù)庫)沒有OpenAPI接口。因此,需要使用中間件將GPT與MyScale集成在一起。

開發(fā)人員已經(jīng)在Hugging Face上托管了與OpenAI兼容的接口的數(shù)據(jù)庫。使用flask-restx app.py, funcs.py來簡化和自動化實現(xiàn),因此代碼小、干凈、易于閱讀。

這樣做的好處是提示和函數(shù)都綁定在一起了。因此,不需要過多考慮提示、功能和可擴展性的組合;用人類可讀的格式來寫。GPT將從轉儲的OpenAI JSON文件中讀取這個文檔。

注:flask restx只生成Swagger 2.0格式的API。必須首先使用Swagger Editor將它們轉換為OpenAPI 3.0格式。你可以在Hugging Face上使用JSON API作為參考。

GPT使用API中的場景運行

在適當?shù)闹笇拢珿PT將使用特殊函數(shù)仔細處理不同的數(shù)據(jù)類型。這些數(shù)據(jù)類型的示例包括ClickHouse SQL函數(shù),例如用于數(shù)組列的has(column, value)和用于時間戳列的parsedatetime32bestefort (value)。

在將正確的查詢發(fā)送給API之后,它(或API)將使用WHERE子句字符串中的過濾器構造向量搜索查詢。返回的值被格式化為字符串,作為從數(shù)據(jù)庫檢索到的額外知識。正如以下的代碼示例所描述的,這個實現(xià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)

結論

GPT確實是OpenAI開發(fā)者界面的重大改進。開發(fā)人員不需要編寫太多代碼來構建他們的聊天機器人,而且工具現(xiàn)在可以自帶提示。我們?yōu)镚PT創(chuàng)造一個生態(tài)系統(tǒng)是很美好的。另一方面,鼓勵開源社區(qū)重新考慮將LLM和工具結合起來的現(xiàn)有方式。

因為相信將外部知識庫存儲在外部數(shù)據(jù)庫中,將會提高LLM的真實性和有用性。很多人正在尋找新的方法來整合像MyScale這樣的矢量數(shù)據(jù)庫和LLM。

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容