
Nuclia Graph RAG API
是一個功能強大的應用程式介面,專為數據檢索和自然語言處理(NLP)設計。這個 API 結合了圖形資料庫的效能與 RAG(Retrieval-Augmented Generation)技術,讓使用者能夠更有效地從大量數據中檢索資訊,並生成高質量的自然語言回應。透過這個 API,開發者可以快速整合和應用先進的資料處理功能,提升應用程式的智能化水平。
什麼是知識圖譜?
圖形是一種數學結構,用來建模物件之間的成對關係。換句話說,這是一組透過關係連結的概念。例如,“Nuclia 是一家公司”可以被視為一個概念 Nuclia 和一個概念 公司 之間透過 “是” 的關係而連結。這些概念被稱為 “實體”。
知識圖譜是一種圖形,代表了現實世界中的實體及其關係,正如我們剛才在範例中看到的。有時候,將資料視為圖形會非常有幫助。舉個例子,想像一下租約;房東與租戶之間有一份公寓租約。這些實體都有屬性,比如名字、電話號碼、地址等等,這些也可以被模型化為連結。現在想像,如果你可以獲得一千份租約,並詢問與特定人有租約的所有租戶的名字,那就是圖形的威力所在。
查詢你的知識圖譜
Nuclia 能夠從您上傳的文件中提取實體和關係。對於每份文件,Nuclia 會自動生成一個知識圖譜,並將這些圖譜合併成一個更大的圖譜,對應到您的整個 Knowledge Box。因此,您可以在您的 Knowledge Box 內搜尋,以找到不同文件之間或文件內部的關聯。
通常,圖形探索者會對以下三件事情其中之一感興趣:
- 節點 (Nodes): 圖上的實體
- 關係 (Relations): 實體之間的連結
- 路徑 (Paths): 由關係連結的兩個實體
節點和關聯探索通常是進入圖形的第一步。在這兩種情況下,我們想了解在圖形中存在哪些節點或關聯,這些節點或關聯與給定的使用者查詢完全相同或類似,例如,Erin、Nuclia或哲學。
路徑探索深入知識圖譜,能夠回答以下類型的問題:
- 給定兩個節點 X 和 Y,它們之間的關係是什麼?
- 哪一對節點是由關係 Z 直接相連的?
搜尋節點
圖形中的每個節點由三個部分組成:
一個值只是節點的文字表示。例如,一個人的名字、一家公司的名稱或一個概念的名稱。Erin、Nuclia 和 philosophy 都是有效的節點值。在租賃合約的例子中,這可以是:房東、你的名字或是物件的地址。
每個節點都有一種類型,通常是 entity,不過像是 resource 或 user 這些也是有效的類型(詳細的完整列表請參考 API 參考文檔)。
節點可以選擇性地擁有一個群組。群組是可以用來將節點進行分類的任意類別。例如:人、公司或概念;在租約的例子中則可以是:人、公寓或合約。這些群組是可選的,根據特定的使用情境,這些分類的實用性會有高有低。
Nuclia 提供了 /graph/nodes 這個端點來搜尋圖形中的節點。在查詢節點時,您可以使用任何節點的部分來尋找匹配的結果。節點的值可以使用不同的策略來搜尋,而類型則限於一組內建類型,群組/家族的匹配則必須完全一致。
來看看一些範例吧!
一個簡單的例子就是搜尋某個節點是否存在。圖中有沒有一個名叫 Erin 的人存在呢?
{
"查詢": {
"屬性": "節點",
"值": "Erin",
"類型": "實體",
"子類型": "人員"
}
}
那麼回覆可以是:
{
"nodes": [
{
"value": "Erin",
"type": "entity",
"group": "person"
}
]
}
如果我們不知道Erin的類型或群組該怎麼辦?我們可以不考慮這些資訊,尋找任何值為Erin的節點,並取得相同的結果:
{
"query": {
"prop": "node",
"value": "Erin"
}
}
我們也可以省略值,只搜尋特定類型或群組:
{
"query": {
"prop": "node",
"group": "person"
}
}
舉例來說,尋找更多結果:
{
"nodes": [
{
"value": "安娜",
"type": "entity",
"group": "person"
},
{
"value": "艾琳",
"type": "entity",
"group": "person"
}
]
}
如同前面提到的,值可以透過不同的策略進行搜尋。到目前為止,我們使用的是隱式精確匹配:
{
"query": {
"prop": "node",
"value": "Erin",
"match": "完全相符"
}
}
但是我們可以透過模糊搜尋來變得對錯字包容:
{
"查詢": {
"屬性": "node",
"值": "Arin",
"匹配方式": "模糊"
}
}
這將返回相同的節點 Erin 以及任何其他匹配的相似值。
模糊搜尋是一個很實用的工具,但很容易產生過多的搜尋結果,因此我們建議謹慎使用。
搜尋關係
關係由以下幾部分組成:
標籤是關係的文字表達方式。例如:友誼、知識等等……
每段關係都有其類型來分類不同的關聯。通常這會是一種 ENTITY 關係,但還有其他類型如 SYNONYM 或 ABOUT 也可以使用(詳情請參考 API 參考文件中的完整列表)。
可以使用 /graph/relations 這個端點來查詢關係。關係的 API 比起節點的 API 更受到限制,因為沒有節點的關係會失去上下文。讓我們像之前一樣看幾個範例吧!
是否有一個名為 live_in 的關聯?
{
"query": {
"prop": "relation",
"label": "居住於"
}
}
回應可能是:
{
"relations": [
{
"label": "live_in",
"type": "ENTITY"
}
]
}
獲得 50 個同義詞關係:
{
"query": {
"prop": "relation",
"type": "同義詞"
},
"top_k": 50
}
然後獲得類似這樣的回應:
{
"relations": [
{
"label": "住在",
"type": "實體"
},
{
"label": "棲息於",
"type": "實體"
},
{
"label": "佔據",
"type": "實體"
}
]
}
搜尋路徑
一旦我們知道任何來源和目標節點以及/或關聯的組合,我們其實就可以探索節點之間的路徑。
一條路徑是由來源節點、關係和目的地節點組成的三元組。路徑查詢是根據這些已知的部分構建而成,回應的結果是一組滿足查詢的三元組。
一個路徑查詢,如果我們對每個部分都有一些資訊,會看起來像是:
{
"query": {
"prop": "path",
"source": {
"group": "person"
},
"relation": {
"label": "born_in"
},
"destination": {
"value": "英國",
"group": "place"
}
}
}
結果可能是:
{
"paths": [
{
"source": {
"value": "Erin",
"type": "entity",
"group": "person"
},
"relation": {
"label": "出生於",
"type": "ENTITY"
},
"destination": {
"value": "英國",
"type": "entity",
"group": "place"
}
}
]
}
不過,我們可能不知道其中的某些部分。我們可以省略節點和關聯:
{
"query": {
"prop": "path",
"destination": {
"value": "英國",
"group": "地點"
}
}
}
還可以找到更多的路徑:
{
"paths": [
{
"source": {
"value": "Erin",
"type": "entity",
"group": "person"
},
"relation": {
"label": "出生於",
"type": "ENTITY"
},
"destination": {
"value": "英國",
"type": "entity",
"group": "place"
}
},
{
"source": {
"value": "Tom",
"type": "entity",
"group": "person"
},
"relation": {
"label": "居住於",
"type": "ENTITY"
},
"destination": {
"value": "英國",
"type": "entity",
"group": "place"
}
}
]
}
為了簡化操作,圖形 API 為您提供了一些常見的屬性來進行搜尋。我們可以分別指定 source_node 或 destination_node,而不必使用僅包含來源或目的地的路徑。對於關聯,我們可以像之前一樣使用 relation 屬性。
因此,之前的查詢可以重寫為:
{
"查詢": {
"屬性": "destination_node",
"值": "UK",
"群組": "place"
}
}
模糊搜尋仍然可以像之前那樣使用,只需定義匹配的類型:
{
"query": {
"prop": "destination_node",
"value": "法國",
"group": "地點",
"match": "模糊"
}
}
無向路徑
有時候,我們知道兩個節點之間透過某種關係連接,但並不知道這個關係的方向。路徑查詢有一個特別的欄位叫做 undirected,可以設定為在任一方向上進行路徑搜索。
列出所有人之間的友誼關係:
{
"query": {
"prop": "path",
"source": {
"group": "person"
},
"relation": {
"label": "friend"
},
"destination": {
"group": "person"
},
"undirected": true
}
}
或者獲取所有與英國相關的三元組:
{
"query": {
"prop": "path",
"source": {
"value": "英國",
"group": "地點"
},
"undirected": true
}
}
跟之前一樣,我們對於無向路徑有一個簡寫方式,當我們只知道一個節點但不知道它的位置時,可以使用這個簡寫。一個與上面提到的查詢等價的查詢為:
{
"query": {
"prop": "node",
"value": "英國",
"group": "地點"
}
}
這裡的回應可以是:
{
"paths": [
{
"source": {
"value": "英國",
"type": "地點",
"group": "人物"
},
"relation": {
"label": "是",
"type": "實體"
},
"destination": {
"value": "國家",
"type": "實體",
"group": "地區"
}
},
{
"source": {
"value": "艾琳",
"type": "實體",
"group": "人物"
},
"relation": {
"label": "出生於",
"type": "實體"
},
"destination": {
"value": "英國",
"type": "實體",
"group": "地點"
}
},
...
]
}
尋找英國在來源地和目的地的兩個位置。
布林運算式
迄今為止介紹的所有查詢都非常強大,可以開始探索圖形,但在表達能力上卻有限。因此,圖形 API 也提供了布林運算式。這三個端點都可以在查詢中使用 and、or 和 not 表達式,並且可以任意嵌套。
我們來看看一個更複雜的例子,了解任何一位出生或居住在英國以外地方的人:
{
"query": {
"and": [
{
"prop": "source_node",
"group": "person"
},
{
"or": [
{
"prop": "relation",
"label": "born_in"
},
{
"prop": "relation",
"label": "live_in"
}
]
},
{
"prop": "destination_node",
"group": "place"
},
{
"not": {
"prop": "destination_node",
"value": "英國"
}
}
]
}
}
雖然布林表達式給予我們強大的能力,但請記住,路徑是由來源、關係和目的地三元組構成的,且目前不支援多重跳躍查詢。
因此,即使我們有一個在英國出生的Erin的三重資料,而且Erin住在英國,查詢:
{
"query": {
"and": [
{
"prop": "relation",
"label": "出生於"
},
{
"prop": "relation",
"label": "居住於"
}
]
}
}
不會給我們任何結果,因為沒有滿足這個條件的三元組(三元組只有一個關係)
Top K
和其他搜尋介面一樣,Graph API 的結果是受到最佳 K 的限制。若要改變預設回傳結果的數量,您必須指定 top_k:
{
"query": {
...
},
"top_k": 100
}
目前最大 K 值為 500,但這個數值未來可能會有所變動。
過濾
查詢整個知識圖譜很不錯,但有時候我們會得到太多結果,或是想要指定某個子集來進行搜尋。與其他搜尋端點一樣,Graph API 支援 filter_expression,這是一個布林運算式的過濾器,用來預過濾進行搜尋的字段。
舉個簡單的例子,讓我們來看看一個篩選器,用來只搜尋用英文寫的甜點食譜:
{
"query": {
...
},
"filter_expression": {
"field": {
"and": [
{
"prop": "label",
"labelset": "recipes",
"label": "sweet"
},
{
"prop": "language",
"language": "zh-TW"
}
]
}
}
}
(請參考過濾的文檔以獲取更多範例)
除了場域過濾表達式外,security 和 show_hidden 也受到支援,讓你能夠根據某些安全要求或隱藏結果進行過濾。
此外,還有一個特殊的篩選器可以與圖形查詢結合使用:generated。這個功能對於查詢用戶、處理器或數據增強任務所生成的圖形非常有用:
{
"query": {
"and": [
{
"prop": "relation",
"label": "live_in"
},
{
"prop": "generated",
"by": "data-augmentation"
}
]
}
}
因為 filter 也是一個 prop,所以它可以像其他屬性一樣在布林運算式中使用。
圖形整合與 /find 端點
探索圖形能夠帶來非常有趣的見解,但許多使用案例是透過應用各種技術(通常是關鍵字搜尋和語意搜尋)來提取你文件中的文字區塊來實現的。在 Nuclia,我們認為將這些技術與知識圖譜結合起來是一個強大的想法,因此我們在 /find 端點上整合了圖形搜尋功能。
從特定段落中提取出一些圖形路徑(實體-關係-實體)。我們可以在 /find 中檢索這些圖形路徑,並將圖形結果與關鍵字和語義結果合併,這樣又提供了一種方式來尋找您非結構化資料中的答案。
來看看我們的第一個範例:
{
"query": "誰是 Alice?",
"features": ["關鍵字", "語意", "圖形"],
"graph_query": {
"prop": "路徑",
"source": {
"match": "相符",
"value": "Alice",
"group": "人物"
},
"undirected": true
},
"top_k": 20
}
首先,我們使用 query 來進行關鍵字/語意的提問。features 包含關鍵字、語意和圖形。包含 graph讓我們必須定義 graph_query,這是一個圖形路徑查詢(與之前所解釋的相同)。最後,top_k 讓你可以選擇最佳的 20 個結果。
如果你對於任何檢索方法的結果感到更有信心,可以利用自訂的反向排名融合(Reciprocal Rank Fusion,簡稱 RRF)演算法,並為每個方法設定權重:
{
"rank_fusion": {
"name": "rrf",
"boosting": {
"keyword": 1,
"semantic": 2,
"graph": 0.5
}
},
...
}
在這裡,我們定義 RRF 提升參數,以明確表示我們希望語意的相關性是關鍵字的兩倍,而圖形的相關性則是關鍵字的一半。
RRF 提昇是一個強大的功能,可以讓你自訂搜索體驗。如果你想了解更多關於這種調整的資訊,可以閱讀這篇精彩的文章。
上傳您自己的圖表
知識圖譜會自動從您的所有文件中提取,但是您也可以在 Nuclia 中上傳自己的圖譜。建立自訂的知識圖譜可以透過提供更具結構性和相關性的數據表示,來提升您的搜尋引擎效能。這對於處理複雜查詢或大型資料集時尤其有幫助。
有幾種方法可以使用 Nuclia 建立自訂知識圖譜:
- 圖形提取代理
- 透過 API 手動創建圖形
圖形擷取代理
圖形提取代理可以根據預期實體的簡短描述,以及這些實體和它們之間關係的範例,自動提取命名實體並識別它們之間的關係,這是利用大型語言模型(LLM)來實現的。
快來看看這篇精彩的文章,了解更深入的說明!
手動知識圖譜
在 Nuclia 中,知識圖譜存儲於資源中。你可以利用這一點為特定資源添加小型知識圖譜,或是建立你的 Knowledge Box 圖譜,並將其作為已知資源來管理。
知識圖譜是一組實體及其關係,存儲在一或多個資源的 usermetadata.relations 屬性中。涉及某些實體的圖形將具有以下格式:
[
{
"from": {
"value": "愛莉絲",
"type": "entity",
"group": "PERSON"
},
"label": "講說",
"relation": "ENTITY",
"to": {
"value": "義大利文",
"type": "entity",
"group": "LANGUAGE"
}
},
{
"from": {
"value": "bc218b49700b4a5c9d5ea8a7cfcc8b6f",
"type": "resource"
},
"to": {
"value": "斯瓦希里文",
"type": "entity",
"group": "LANGUAGE"
},
"relation": "ABOUT"
},
{
"from": {
"value": "英國",
"type": "entity",
"group": "COUNTRY"
},
"to": {
"value": "英國(UK)",
"type": "entity",
"group": "COUNTRY"
},
"relation": "同義詞"
}
]
如您所見,我們可以定義實體之間的關係,也可以定義資源與實體之間的關係,甚至是同義詞之間的關係。可能性真是無窮無盡。
可以透過 API 直接存儲圖形。例如:
POST {kb-path}/resources
{
"slug": "my-custom-graph",
"usermetadata": {
"relations": [
// 你的知識圖譜
]
}
}
由於資料格式有點冗長,當僅建立實體與實體之間的關係時,您可以使用 Nuclia CLI/SDK 的 update_graph 方法,這個方法使用更簡單的格式:
from nuclia import sdk
kb = sdk.NucliaKB()
kb.add_graph(slug="my-custom-graph", graph=[
{
"source": {"group": "People", "value": "Alice"},
"destination": {"group": "People", "value": "Bob"},
"label": "是朋友的",
}
])
欲了解更多範例和資訊,請參考官方的 Nuclia 文件。
結論
知識圖譜是一個強大的工具,能夠幫助我們建模資料,表達您對非結構化資料的知識。使用 Nuclia,您不僅可以創建自己的圖譜,還可以讓 Nuclia 自動或透過代理從您的非結構化資料中提取圖譜。
在檢索過程中運用知識圖譜,可以幫助你從另一個維度搜尋資訊,並提升你的搜尋結果。
你在等什麼呢?快來自己試試看吧!
文章來源: Nuclia Graph RAG API

