llama_index [问题]:使用嵌入进行知识图谱搜索得到空结果

4ktjp1zp  于 4个月前  发布在  其他
关注(0)|答案(3)|浏览(48)

问题验证

  • 我已经在文档和discord上寻找答案。

问题

我尝试在发送给查询引擎的查询中使用retriever_mode="embedding"。当我第一次为知识图谱创建时,这可以工作。但是当我第二次加载图谱(即知识图谱已经被创建)时,对查询的响应是空的。没有检索到三元组。
以下是我如何创建数据库并进行查询的方法:

import kuzu
db = kuzu.Database("llamaindex_crypto_10")
from llama_index.graph_stores.kuzu import KuzuGraphStore
graph_store = KuzuGraphStore(db)
storage_context = StorageContext.from_defaults(graph_store=graph_store)
index = KnowledgeGraphIndex(
    [],
    storage_context=storage_context,
    include_embeddings=True,
    max_triplets_per_chunk=25,
    llm=llm_openai
)

query_engine = index.as_query_engine(
    response_mode="tree_summarize",
    verbose=False,
    llm=llm_openai,
    include_text=False,
    max_keywords_per_query=20,
    retriever_mode="embedding",
    use_global_node_triplets=True,
    max_knowledge_sequence=15,
    num_chunks_per_query=10,
    similarity_top_k=10,
    )

我正在使用以下代码单独插入知识图谱三元组:
index.upsert_triplet_and_node(tuple1, node1, include_embeddings=True)
我尝试了Kuzu、neo4j和nebula,它们都有这个问题。我是否需要在某个地方传递向量存储索引?或者是否有其他缺失的参数?

7xllpg7q

7xllpg7q1#

嘿@shalinanvai!我在这里帮助你解决任何bug、问题或贡献。让我们一起解决这个问题!

你遇到的问题是由于_retrieve_embedding方法在KnowledgeGraphIndex类中没有实现。这个方法对于基于嵌入的检索至关重要,目前引发了一个NotImplementedError,表示功能尚未可用。

以下是相关代码的部分内容,显示该方法尚未实现:

def _retrieve_embedding(self, query_bundle: QueryBundle) -> List[NodeWithScore]:
    """Retrieve in embedding mode."""
    if self._retriever_mode not in ["embedding", "keyword_embedding"]:
        return []
    # TBD: will implement this later with vector store.
    raise NotImplementedError

要解决此问题,你需要实现_retrieve_embedding方法来处理基于嵌入的检索。在实现此方法之前,当加载已经创建的知识图谱1(https://github.com/run-llama/llama_index/blob/main/llama-index-core/llama_index/core/indices/knowledge_graph/retrievers.py)2(https://github.com/run-llama/llama_index/blob/main/llama-index-legacy/llama_index/legacy/indices/knowledge_graph/retrievers.py)时,retriever_mode="embedding"将无法正常工作。

  • 要继续与Dosu交流,请提及@dosu。*
zxlwwiss

zxlwwiss2#

看起来在检索器模式为"hybrid"时,基于嵌入的检索正确实现了。这是准确的吗?

dtcbnfnu

dtcbnfnu3#

是的,retriever_mode="hybrid"模式已正确实现用于KnowledgeGraphIndex类的嵌入检索。
来自代码的支持证据:

  • KGTableRetriever类有一个处理不同检索模式的方法,包括HYBRID
  • retriever_mode设置为HYBRID时,该方法将关键字检索和嵌入检索结合在一起。
  • 嵌入检索使用get_top_k_embeddings函数进行,该函数检索最相似的前k个嵌入。
  • 从关键字和嵌入方法检索到的结果被组合、去重并根据需要截断。

以下是相关的代码片段:

if (
    self._retriever_mode != KGRetrieverMode.KEYWORD
    and len(self._index_struct.embedding_dict) > 0
):
    query_embedding = self._service_context.embed_model.get_text_embedding(
        query_bundle.query_str
    )
    all_rel_texts = list(self._index_struct.embedding_dict.keys())

    rel_text_embeddings = [
        self._index_struct.embedding_dict[_id] for _id in all_rel_texts
    ]
    similarities, top_rel_texts = get_top_k_embeddings(
        query_embedding,
        rel_text_embeddings,
        similarity_top_k=self.similarity_top_k,
        embedding_ids=all_rel_texts,
    )
    logger.debug(
        f"Found the following rel_texts+query similarites: {similarities!s}"
    )
    logger.debug(f"Found the following top_k rel_texts: {rel_texts!s}")
    rel_texts.extend(top_rel_texts)

elif len(self._index_struct.embedding_dict) == 0:
    logger.warning(
        "Index was not constructed with embeddings, skipping embedding usage..."
    )

# remove any duplicates from keyword + embedding queries
if self._retriever_mode == KGRetrieverMode.HYBRID:
    rel_texts = list(set(rel_texts))
    # remove shorter rel_texts that are substrings of longer rel_texts
    rel_texts.sort(key=len, reverse=True)
    for i in range(len(rel_texts)):
        for j in range(i + 1, len(rel_texts)):
            if rel_texts[j] in rel_texts[i]:
                rel_texts[j] = ""
    rel_texts = [rel_text for rel_text in rel_texts if rel_text != ""]
    # truncate rel_texts
    rel_texts = rel_texts[: self.max_knowledge_sequence]

此外,KGTableRetriever类设计为支持不同的检索模式,包括HYBRID,如其初始化参数和KGRetrieverMode枚举中指定的那样。这确保了混合检索模式正确实现且功能正常。

  • 要继续与Dosu交谈,请提及@dosu。*

相关问题