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 也提供了布林運算式。這三個端點都可以在查詢中使用 andor 和 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

You cannot copy content of this page