成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

實(shí)戰(zhàn):如何使用圖數(shù)據(jù)庫提高向量搜索精確度?

數(shù)據(jù)庫 其他數(shù)據(jù)庫
在這篇博客文章中,我們實(shí)現(xiàn)了基于圖的元數(shù)據(jù)過濾器的示例,以提高向量搜索的準(zhǔn)確性。數(shù)據(jù)集擁有廣泛且相互關(guān)聯(lián)的選項(xiàng),這允許進(jìn)行更精細(xì)的預(yù)過濾查詢。結(jié)合圖數(shù)據(jù)表示和語言模型的函數(shù)調(diào)用功能,可以動(dòng)態(tài)生成 Cypher 語句,從而為結(jié)構(gòu)化過濾器提供了幾乎無限的可能性。

文本嵌入和向量搜索技術(shù)可以幫助我們根據(jù)文檔的含義及其相似性來檢索文檔。但當(dāng)需要根據(jù)日期或類別等特定標(biāo)準(zhǔn)來篩選信息時(shí),這些技術(shù)就顯得力不從心。為了解決這個(gè)問題,我們可以引入元數(shù)據(jù)過濾或過濾向量搜索,這允許我們根據(jù)用戶的特定需求來縮小搜索范圍。

圖片圖片

例如,用戶可能想要了解 2021 年實(shí)施的新政策。通過使用元數(shù)據(jù)過濾器,系統(tǒng)可以先篩選出 2021 年的文檔,然后在這些文檔中執(zhí)行向量相似性搜索,以找到與用戶興趣最相關(guān)的文檔。這種先進(jìn)行元數(shù)據(jù)過濾再執(zhí)行向量搜索的兩步策略,能夠顯著提高搜索的相關(guān)性和準(zhǔn)確性。

近期,Neo4j 引入了基于節(jié)點(diǎn)屬性的 LangChain 元數(shù)據(jù)過濾支持。由于圖形數(shù)據(jù)庫能夠存儲(chǔ)復(fù)雜的結(jié)構(gòu)化和非結(jié)構(gòu)化數(shù)據(jù),我們可以利用這些數(shù)據(jù)來執(zhí)行更精細(xì)的元數(shù)據(jù)過濾。

圖片圖片

以一個(gè)包含文章和組織信息的數(shù)據(jù)集為例,文章節(jié)點(diǎn)包含了文本和嵌入值,而與文章相關(guān)聯(lián)的組織節(jié)點(diǎn)則包含了日期、情感、作者等更多信息。通過這些信息,我們可以構(gòu)建復(fù)雜的查詢,以回答如

  • Rod Johnson 所在的公司是否實(shí)施了新的在家工作政策?
  • Neo4j 投資的公司是否有負(fù)面新聞?
  • 與為現(xiàn)代汽車供應(yīng)的公司相關(guān)的供應(yīng)鏈問題是否有任何值得注意的新聞?

等問題。

在本篇博客中,Tomaz Bratanic 將向我們展示如何結(jié)合 LangChain 和 OpenAI 函數(shù)調(diào)用代理來實(shí)現(xiàn)基于圖的元數(shù)據(jù)過濾。相關(guān)代碼已在 https://github.com/tomasonjo/blogs/blob/master/llm/graph_based_prefiltering.ipynb 上提供。

概覽

我們將使用 Neo4j 托管的公共演示服務(wù)器上的 companies 圖數(shù)據(jù)集。您可以通過以下憑據(jù)訪問該數(shù)據(jù)集:

URI: https://demo.neo4jlabs.com:7473/browser/
用戶名: companies
密碼: companies
數(shù)據(jù)庫: companies

圖片圖片

數(shù)據(jù)集的完整模式包括以 Organization 節(jié)點(diǎn)為中心的豐富信息,涵蓋供應(yīng)商、競爭對(duì)手、位置、董事會(huì)成員等。此外,還有提及特定組織的文章及其相應(yīng)的文本塊。

我們將實(shí)現(xiàn)一個(gè) OpenAI 代理,它可以根據(jù)用戶輸入動(dòng)態(tài)生成 Cypher 語句,并從圖形數(shù)據(jù)庫檢索相關(guān)文本塊。這個(gè)工具將提供四個(gè)可選輸入?yún)?shù):

  • 主題:用戶感興趣的特定信息或主題。
  • 組織:用戶希望查詢信息的組織。
  • 國家:用戶感興趣的組織的國家。
  • 情感:文章的情感傾向。

我們將根據(jù)這些輸入?yún)?shù)動(dòng)態(tài)構(gòu)建相應(yīng)的 Cypher 語句,從圖形數(shù)據(jù)庫檢索相關(guān)信息,并利用大型語言模型(LLM)生成最終答案。

要跟隨代碼實(shí)踐,您將需要一個(gè) OpenAI API 密鑰。

功能實(shí)現(xiàn)

我們從設(shè)置 Neo4j 的連接憑證和相關(guān)連接開始。

import os

os.environ["OPENAI_API_KEY"] = "sk-"
os.environ["NEO4J_URI"] = "neo4j+s://demo.neo4jlabs.com"
os.environ["NEO4J_USERNAME"] = "companies"
os.environ["NEO4J_PASSWORD"] = "companies"
os.environ["NEO4J_DATABASE"] = "companies"

embeddings = OpenAIEmbeddings()
graph = Neo4jGraph()
vector_index = Neo4jVector.from_existing_index(
 embeddings,
 index_name="news"
)

我們使用 OpenAI 的文本嵌入技術(shù),您需要一個(gè) API 密鑰來使用它。接下來,我們定義了與 Neo4j 的連接,這使我們能夠執(zhí)行任意的 Cypher 語句。最后,我們創(chuàng)建了一個(gè) Neo4jVector 連接,它可以通過查詢現(xiàn)有的向量索引來檢索信息。目前,我們不能將向量索引與預(yù)過濾方法結(jié)合使用,只能與后過濾方法結(jié)合使用。但本文將專注于預(yù)過濾方法與全面向量相似性搜索的結(jié)合使用。

本文的核心是一個(gè)名為 get_organization_news 的函數(shù),它能夠根據(jù)用戶的需求動(dòng)態(tài)生成 Cypher 查詢語句并檢索相關(guān)信息。為了清晰起見,我將代碼分成了多個(gè)部分。

  • 首先,我們定義了一組輸入?yún)?shù),這些參數(shù)都是可選的文字輸入。特別地,topic 參數(shù)用來在文檔中搜索特定的信息。在實(shí)際應(yīng)用中,我們會(huì)將 topic 參數(shù)的值用于向量相似性搜索。另外三個(gè)參數(shù)則用于展示預(yù)過濾的方法。如果所有預(yù)過濾參數(shù)都沒有提供,我們可以直接利用現(xiàn)有的向量索引來檢索相關(guān)文檔。如果提供了預(yù)過濾參數(shù),我們會(huì)開始構(gòu)建一個(gè)基礎(chǔ)的 Cypher 查詢語句,這個(gè)語句將用于后續(xù)的預(yù)過濾元數(shù)據(jù)方法。我們使用 CYPHER runtime = parallel parallelRuntimeSupport=all 指令來告訴 Neo4j 數(shù)據(jù)庫,在可能的情況下使用 并行運(yùn)行時(shí)。然后,我們準(zhǔn)備一個(gè)匹配語句來選擇 Chunk 節(jié)點(diǎn)和它們關(guān)聯(lián)的 Article 節(jié)點(diǎn)。
def get_organization_news(
 topic: Optional[str] = None,
 organization: Optional[str] = None,
 country: Optional[str] = None,
 sentiment: Optional[str] = None,
) -> str:
 # 如果沒有預(yù)過濾條件,我們可以直接使用向量索引進(jìn)行搜索
 if topic and not organization and not country and not sentiment:
     return vector_index.similarity_search(topic)
 # 使用并行運(yùn)行時(shí)(如果可用)
 base_query = (
     "CYPHER runtime = parallel parallelRuntimeSupport=all "
     "MATCH (c:Chunk)<-[:HAS_CHUNK]-(a:Article) WHERE "
 )
 where_queries = []
 params = {"k": 5}  # 設(shè)置要檢索的文本塊數(shù)量
  • 接下來,我們動(dòng)態(tài)地向 Cypher 語句添加元數(shù)據(jù)過濾器。我們從 Organization 過濾器開始。
if organization:
    # 將組織名稱映射到數(shù)據(jù)庫中的候選項(xiàng)
    candidates = get_candidates(organization)
    if len(candidates) > 1:  # 如果候選選項(xiàng)太多,則需要用戶進(jìn)一步明確
        return f"請(qǐng)明確指出用戶指的是以下哪個(gè)組織:{candidates}"
    # 添加一個(gè)過濾條件,篩選出提及特定組織的 articles
    where_queries.append(f"EXISTS {{(a)-[:MENTIONS]->(:Organization {{name: $organization}})}}")
    # 將組織名稱作為參數(shù)傳入
    params["organization"] = candidates[0]

如果系統(tǒng)識(shí)別出用戶感興趣的特定組織,我們會(huì)使用 get_candidates 函數(shù)將該組織的名稱映射到數(shù)據(jù)庫中的候選項(xiàng)。如果找到多個(gè)匹配項(xiàng),我們會(huì)要求用戶進(jìn)一步明確。如果沒有找到多個(gè)匹配項(xiàng),我們會(huì)添加一個(gè)過濾條件,篩選出提及特定組織的 articles。為了安全起見,我們使用參數(shù)化查詢而不是直接拼接查詢字符串。

  • 隨后,我們處理用戶可能基于提及的組織的國家進(jìn)行預(yù)過濾的情況。
if country:
    # 由于國家名稱標(biāo)準(zhǔn)化,不需要額外的映射
    where_queries.append(f"EXISTS {{(a)-[:MENTIONS]->(:Organization)-[:IN_CITY]->()-[:IN_COUNTRY]->(:Country {{name: $country}})}}")
    params["country"] = country

由于國家名稱通常是標(biāo)準(zhǔn)化的,我們不需要將國家名稱映射到數(shù)據(jù)庫中的值,因?yàn)榇笮驼Z言模型(LLM)已經(jīng)熟悉大多數(shù)國家的名稱。

  • 隨后,我們處理情感元數(shù)據(jù)的過濾。
if sentiment:
    if sentiment == "positive":
        where_queries.append("a.sentiment > $sentiment")
        params["sentiment"] = 0.5
    else:
        where_queries.append("a.sentiment < $sentiment")
        params["sentiment"] = -0.5

我們要求 LLM 僅接受正面或負(fù)面兩種情感輸入值,并將這些值映射到適當(dāng)?shù)倪^濾器上。

  • 對(duì)于 topic 參數(shù),我們采取了略有不同的處理方式,因?yàn)樗挥糜陬A(yù)過濾,而是用于向量相似性搜索。
if topic:  # 執(zhí)行向量比較
    vector_snippet = (
        "WITH c, a, vector.similarity.cosine(c.embedding,$embedding) AS score "
        "ORDER BY score DESC LIMIT toInteger($k)"
    )
    params["embedding"] = embeddings.embed_query(topic)
else:  # 只返回最新的數(shù)據(jù)
    vector_snippet = "WITH c, a ORDER BY a.date DESC LIMIT toInteger($k)"

如果系統(tǒng)識(shí)別出用戶對(duì)新聞中的特定主題感興趣,我們使用主題輸入的文本嵌入來找到最相關(guān)的文檔。如果沒有識(shí)別出特定主題,我們簡單地返回最新的幾篇文章,并避免向量相似性搜索。

  • 最后,我們將 Cypher 語句組合起來,并用它來從數(shù)據(jù)庫中檢索信息。
return_snippet = "RETURN '#title ' + a.title + '\n#date ' + toString(a.date) + '\n#text ' + c.text AS output"

complete_query = (
    base_query + " AND ".join(where_queries) + vector_snippet + return_snippet
)

# 從數(shù)據(jù)庫檢索信息
data = graph.query(complete_query, params)
print(f"Cypher: {complete_query}\n")
# 在打印前安全地移除嵌入
params.pop('embedding', None)
print(f"參數(shù): {params}")
return "###文章: ".join([el["output"] for el in data])

我們通過組合所有查詢片段來構(gòu)建最終的 complete_query。然后,我們使用動(dòng)態(tài)生成的 Cypher 語句從數(shù)據(jù)庫檢索信息并返回結(jié)果。讓我們通過一個(gè)示例輸入來看看生成的 Cypher 語句。

get_organization_news(
  organizatinotallow='neo4j',
  sentiment='positive',
  topic='遠(yuǎn)程工作'
)

# Cypher: CYPHER runtime = parallel parallelRuntimeSupport=all
# MATCH (c:Chunk)<-[:HAS_CHUNK]-(a:Article) WHERE 
# EXISTS {(a)-[:MENTIONS]->(:Organization {name: $organization})} AND 
# a.sentiment > $sentiment 
# WITH c, a, vector.similarity.cosine(c.embedding,$embedding) AS score 
# ORDER BY score DESC LIMIT toInteger($k) 
# RETURN '#title ' + a.title + '\n#date ' + toString(a.date) + '\n#text ' + c.text AS output

# 參數(shù): {'k': 5, 'organization': 'Neo4j', 'sentiment': 0.5}

動(dòng)態(tài)查詢生成按預(yù)期工作,能夠從數(shù)據(jù)庫中檢索到相關(guān)的信息。

構(gòu)建新聞信息代理工具

接下來,我們將創(chuàng)建一個(gè)代理工具,用于處理新聞信息查詢。首先,我們需要為輸入?yún)?shù)編寫一些說明。

fewshot_examples = """{輸入:Google員工的健康福利在新聞中有哪些?查詢:健康福利}
{輸入:關(guān)于Google的最新正面新聞是什么?查詢:無}
{輸入:有關(guān)VertexAI和Google的新聞?dòng)心男坎樵儯篤ertexAI}
{輸入:關(guān)于Google的新產(chǎn)品有哪些新聞?查詢:新產(chǎn)品}
"""

class NewsInput(BaseModel):
    topic: Optional[str] = Field(
        descriptinotallow="除了組織、國家和情感傾向之外,如果您對(duì)其他特定信息或話題感興趣,請(qǐng)告訴我們。以下是一些示例:"
        + fewshot_examples
    )
    organization: Optional[str] = Field(
        descriptinotallow="您希望了解信息的組織名稱"
    )
    country: Optional[str] = Field(
        descriptinotallow="您感興趣的組織的所在國家。請(qǐng)使用正式的國家名稱,例如‘美利堅(jiān)合眾國’或‘法國’。"
    )
    sentiment: Optional[str] = Field(
        descriptinotallow="您想要查詢的文章情感傾向", enum=["正面", "負(fù)面"]
    )

在定義預(yù)過濾參數(shù)時(shí),我遇到了一些困難,特別是如何讓 topic 參數(shù)按預(yù)期工作。為了解決這個(gè)問題,我提供了一些示例,幫助語言模型更好地理解用戶的需求。同時(shí),我們還向模型提供了關(guān)于國家名稱格式的指導(dǎo),并對(duì)情感傾向選項(xiàng)進(jìn)行了枚舉。

現(xiàn)在,我們可以定義一個(gè)自定義工具,為其指定一個(gè)名稱和一段包含使用說明的描述。

class NewsTool(BaseTool):
    name = "新聞信息工具"
    description = (
        "當(dāng)你需要在新聞中查找相關(guān)信息時(shí),這個(gè)工具會(huì)非常有用。"
    )
    args_schema:Type[BaseModel] = NewsInput

    def _run(
        self,
        topic: Optional[str] = None,
        organization: Optional[str] = None,
        country: Optional[str] = None,
        sentiment: Optional[str] = None,
        run_manager: Optional[CallbackManagerForToolRun] = None,
    ) -> str:
        ""“使用這個(gè)工具來獲取新聞信息。”""
        return get_organization_news(topic, organization, country, sentiment)

最后,我們需要定義一個(gè)代理執(zhí)行器。這里,我使用了之前實(shí)現(xiàn)的 OpenAI 代理的 LCEL 實(shí)現(xiàn)。

llm = ChatOpenAI(temperature=0, model="gpt-4-turbo", streaming=True)
tools = [NewsTool()]

llm_with_tools = llm.bind(functinotallow=[format_tool_to_openai_function(t) for t in tools])

prompt = ChatPromptTemplate.from_messages(
    [
        (
            "system",
            “你是一個(gè)樂于助人的助手,可以找到關(guān)于電影的信息并進(jìn)行推薦。如果工具需要進(jìn)一步的問題,請(qǐng)確保向用戶詢問以獲得澄清。確保在后續(xù)問題中包含任何需要澄清的可用選項(xiàng)。只做用戶明確請(qǐng)求的事情。”
        ),
        MessagesPlaceholder(variable_name="chat_history"),
        ("user", "{input}"),
        MessagesPlaceholder(variable_name="agent_scratchpad"),
    ]
)

agent = (
    {
        "input": lambda x: x["input"],
        "chat_history": lambda x: _format_chat_history(x["chat_history"])
        if x.get("chat_history")
        else [],
        "agent_scratchpad": lambda x: format_to_openai_function_messages(
            x["intermediate_steps"]
        ),
    }
    | prompt
    | llm_with_tools
    | OpenAIFunctionsAgentOutputParser()
)

agent_executor = AgentExecutor(agent=agent, tools=tools)

這個(gè)代理工具可以用于檢索新聞信息。我們還添加了 聊天記錄 消息占位符,這樣代理就可以進(jìn)行對(duì)話,并允許提出后續(xù)問題和回復(fù)。

實(shí)施測試

讓我們嘗試幾個(gè)查詢,看看生成的 Cypher 語句和參數(shù)是什么樣的。

agent_executor.invoke(
  {"輸入": "關(guān)于 neo4j 的一些正面新聞是什么?"}
)

# Cypher: CYPHER runtime = parallel parallelRuntimeSupport=all 
# MATCH (c:Chunk)<-[:HAS_CHUNK]-(a:Article) WHERE 
# EXISTS {(a)-[:MENTIONS]->(:Organization {name: $organization})} AND 
# a.sentiment > $sentiment WITH c, a 
# ORDER BY a.date DESC LIMIT toInteger($k) 
# RETURN '#標(biāo)題 ' + a.title + '日期 ' + toString(a.date) + '文本 ' + c.text AS output
# 參數(shù): {'k': 5, 'organization': 'Neo4j', 'sentiment': 0.5}

生成的 Cypher 語句是有效的。由于沒有指定具體的主題,它返回了提到 Neo4j 的最后五篇正面文章的文本塊。讓我們嘗試一個(gè)更復(fù)雜的例子:

agent_executor.invoke(
   {"輸入": "關(guān)于法國公司的員工幸福感,有哪些最新的負(fù)面新聞?"}
)

# Cypher: CYPHER runtime = parallel parallelRuntimeSupport=all 
# MATCH (c:Chunk)<-[:HAS_CHUNK]-(a:Article) WHERE 
# EXISTS {(a)-[:MENTIONS]->(:Organization)-[:IN_CITY]->()-[:IN_COUNTRY]->(:Country {name: $country})} AND 
# a.sentiment < $sentiment 
# WITH c, a, vector.similarity.cosine(c.embedding,$embedding) AS score 
# ORDER BY score DESC LIMIT toInteger($k) 
# RETURN '#標(biāo)題 ' + a.title + '日期 ' + toString(a.date) + '文本 ' + c.text AS output
# 參數(shù): {'k': 5, 'country': 'France', 'sentiment': -0.5, 'topic': '員工幸福感'}

語言模型代理正確地生成了預(yù)過濾參數(shù),并且還識(shí)別出了一個(gè)特定的“員工幸福感”主題。這個(gè)主題被用作向量相似性搜索的輸入,使我們能夠進(jìn)一步優(yōu)化檢索過程。

總結(jié)

在這篇博客文章中,我們實(shí)現(xiàn)了基于圖的元數(shù)據(jù)過濾器的示例,以提高向量搜索的準(zhǔn)確性。數(shù)據(jù)集擁有廣泛且相互關(guān)聯(lián)的選項(xiàng),這允許進(jìn)行更精細(xì)的預(yù)過濾查詢。結(jié)合圖數(shù)據(jù)表示和語言模型的函數(shù)調(diào)用功能,可以動(dòng)態(tài)生成 Cypher 語句,從而為結(jié)構(gòu)化過濾器提供了幾乎無限的可能性。

此外,你的代理可以擁有檢索非結(jié)構(gòu)化文本的工具,如本文所示,以及能夠檢索結(jié)構(gòu)化信息的其他工具,這使得知識(shí)圖譜成為許多 RAG應(yīng)用的理想解決方案。

責(zé)任編輯:武曉燕 來源: AI小智
相關(guān)推薦

2022-12-05 08:00:00

數(shù)據(jù)庫向量化數(shù)據(jù)庫性能

2025-04-03 16:02:14

2022-04-18 09:00:00

數(shù)據(jù)庫向量機(jī)器學(xué)習(xí)

2020-12-28 08:26:51

Python機(jī)器學(xué)習(xí)數(shù)據(jù)集

2023-07-28 08:00:00

人工智能向量數(shù)據(jù)庫

2009-08-17 22:52:41

IT運(yùn)維管理Mocha ITOM工摩卡

2010-04-06 13:58:33

2023-01-05 08:00:00

2023-11-27 00:58:00

數(shù)據(jù)庫AI

2011-05-19 11:33:38

數(shù)據(jù)庫訪問速度

2024-11-21 08:00:00

向量搜索人工智能

2010-04-27 16:41:07

Oracle性能

2025-06-30 08:32:00

2025-04-01 07:30:00

2023-07-20 20:54:09

2024-05-22 12:07:12

向量數(shù)據(jù)庫AI

2025-05-26 02:44:00

向量數(shù)據(jù)庫傳統(tǒng)數(shù)據(jù)庫向量化

2010-04-07 17:45:22

Oracle位圖索引

2022-06-28 15:00:28

數(shù)據(jù)庫性能操作系統(tǒng)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 超碰伊人久久 | 日韩欧美中文在线 | 国产美女永久免费无遮挡 | 久久男人 | 久久久国产一区 | 五月天天丁香婷婷在线中 | 午夜精品久久久久久久久久久久久 | 国产免费福利 | 97起碰| 国产高清精品一区二区三区 | 亚洲 中文 欧美 日韩 在线观看 | 一区二区三区电影在线观看 | 国产婷婷在线视频 | 欧美日韩精品在线一区 | 欧美久久精品一级黑人c片 91免费在线视频 | 一区二区小视频 | 欧美成人h版在线观看 | 日韩免费高清视频 | 欧美另类视频 | 人人人干| 日韩av在线一区 | 日韩和的一区二在线 | 久久久综合网 | 国产99久久精品一区二区永久免费 | 日韩精品三区 | 久久精品一级 | 久久国产视频播放 | 成人在线视频免费观看 | 黄色片网此 | h视频在线免费观看 | 久久中文字幕一区 | 国产乱码精品一区二区三区五月婷 | 午夜国产一区 | 国产精品久久久久久久久久久免费看 | 精品乱码一区二区三四区视频 | 国产精品精品久久久 | 精久久久 | 欧美日韩电影一区二区 | 一区二区三区中文字幕 | 国产精品免费一区二区 | 欧美一级毛片在线播放 |