如何使用MyScale將知識庫引入OpenAI的GPT
譯文譯者 | 李睿
審校 | 重樓
2023年11月6日,OpenAI公司對外發布了ChatGPT。在這個無代碼平臺上,專業(或業余)開發人員可以使用工具和提示構建定制的GPT或聊天機器人,有效地改變他們與OpenAI GPT的交互。以前的交互(LangChain或LlamaIndex)強制使用動態提示從GPT檢索響應。現在,OpenAI GPT通過調用外部API或工具來處理動態提示。
這也改變了開發人員在MyScale構建RAG系統的方式,從構建帶有服務器端場景的提示到將這些場景引入GPT模型。
MyScale簡化了將場景引入GPT的方式。例如,OpenAI公司的方法是通過Web UI將文件上傳到GPT平臺。同時,MyScale允許開發使用SQL WHERE子句混合結構化數據過濾和語義搜索,以更低的成本處理和存儲更大的知識庫,以及在多個GPT之間共享一個知識庫。
現在就可以在GPT商店試用MyScaleGPT,或者將MyScale的開放知識庫與托管在Hugging Face上的API集成到應用程序中。
BYOK:采用自己的知識
GPT在過去的一年中有了很大的發展,它在共享知識領域獲得的知識比最初發布時要多得多。然而,仍然有GPT一無所知或不確定的特定主題,例如特定領域的知識和當前事件。因此,正如在之前的文章所描述的,必須將存儲在MyScale中的外部知識庫集成到GPT中,以提高其真實性和有用性。
當開發人員使用MyScale構建RAG時,將LLM引入他們的鏈(或堆棧)。這一次需要將MyScale數據庫帶到GPT平臺。不幸的是,目前還不可能直接在GPT和MyScale之間建立連接。因此,調整了查詢接口,將其公開為REST API。
由于之前在OpenAI函數調用方面的成功,現在可以設計一個類似的接口,其中GPT可以使用類似SQL的過濾器字符串編寫向量搜索查詢。在OpenAPI中的參數如下:
"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條目來實現。每個API條目在其文檔下都有自己的模式和提示。GPT將讀取適用的API文檔,并將正確的查詢寫入相應的表。
值得注意的是,之前介紹的方法(例如自查詢檢索器和向量SQL)都需要動態或半動態提示來描述表結構。與其相反,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
]
}
}
}
根據這個代碼片段,GPT知道有兩個知識庫可以幫助回答用戶的問題。
在為知識庫檢索配置GPT操作后,只需填寫指令并告訴GPT如何查詢知識庫,然后回答用戶問題:
注:盡量回答問題。隨意使用任何可用的工具來查找相關信息。在調用搜索函數時,保留查詢中的所有詳細信息。使用MyScale知識庫查詢字符串數組時,請使用has(column, value)進行匹配。對于發布日期,使用parsedatetime32bestefort()將時間戳值從字符串格式轉換為日期時間對象,不使用這個函數轉換日期時間類型的列。開發人員應該始終為其使用的文檔添加參考鏈接。
將數據庫托管為OpenAPI
GPT采用OpenAI 3.0標準下的API。有些應用程序(例如數據庫)沒有OpenAPI接口。因此,需要使用中間件將GPT與MyScale集成在一起。
開發人員已經在Hugging Face上托管了與OpenAI兼容的接口的數據庫。使用flask-restx app.py, funcs.py來簡化和自動化實現,因此代碼小、干凈、易于閱讀。
這樣做的好處是提示和函數都綁定在一起了。因此,不需要過多考慮提示、功能和可擴展性的組合;用人類可讀的格式來寫。GPT將從轉儲的OpenAI JSON文件中讀取這個文檔。
注:flask restx只生成Swagger 2.0格式的API。必須首先使用Swagger Editor將它們轉換為OpenAPI 3.0格式。你可以在Hugging Face上使用JSON API作為參考。
GPT使用API中的場景運行
在適當的指導下,GPT將使用特殊函數仔細處理不同的數據類型。這些數據類型的示例包括ClickHouse SQL函數,例如用于數組列的has(column, value)和用于時間戳列的parsedatetime32bestefort (value)。
在將正確的查詢發送給API之后,它(或API)將使用WHERE子句字符串中的過濾器構造向量搜索查詢。返回的值被格式化為字符串,作為從數據庫檢索到的額外知識。正如以下的代碼示例所描述的,這個實現非常簡單。
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開發者界面的重大改進。開發人員不需要編寫太多代碼來構建他們的聊天機器人,而且工具現在可以自帶提示。我們為GPT創造一個生態系統是很美好的。另一方面,鼓勵開源社區重新考慮將LLM和工具結合起來的現有方式。
因為相信將外部知識庫存儲在外部數據庫中,將會提高LLM的真實性和有用性。很多人正在尋找新的方法來整合像MyScale這樣的矢量數據庫和LLM。
原文標題:Bring Your Knowledge Base Into OpenAI’s GPTs With MyScale,作者:Fangrui Liu