
LlamaIndex • 2024-05-29
引入属性图索引:使用 LLM 构建知识图谱的强大新方法
我们很高兴地宣布 LlamaIndex 的一项新功能,它扩展了我们的知识图谱功能,使其更加灵活、可扩展和健壮。隆重推出属性图索引!
为何选择属性图?
传统的知识图谱表示方法,如知识三元组(主语、谓语、宾语),在表达能力上受到限制。它们缺乏以下能力:
- 为节点和关系分配标签和属性
- 将文本节点表示为向量嵌入
- 执行向量和符号检索
我们现有的 KnowledgeGraphIndex
受这些限制以及索引架构本身的普遍限制所困扰。
属性图索引解决了这些问题。通过使用带标签的属性图表示,它使得对知识图谱进行更丰富的建模、存储和查询成为可能。
使用属性图,您可以:
- 将节点和关系分类到具有相关元数据的类型中
- 将您的图视为向量数据库的超集,用于混合搜索
- 使用 Cypher 图查询语言表达复杂查询
这使得属性图成为使用 LLM 构建知识图谱的强大且灵活的选择。
构建您的图
属性图索引提供了几种从数据中提取知识图谱的方法,您可以随意组合使用:
1. 模式引导提取:在模式中定义允许的实体类型、关系类型及其连接。LLM 只会提取符合此模式的图数据。
from llama_index.indices.property_graph import SchemaLLMPathExtractor
entities = Literal["PERSON", "PLACE", "THING"]
relations = Literal["PART_OF", "HAS", "IS_A"]
schema = {
"PERSON": ["PART_OF", "HAS", "IS_A"],
"PLACE": ["PART_OF", "HAS"],
"THING": ["IS_A"],
}
kg_extractor = SchemaLLMPathExtractor(
llm=llm,
possible_entities=entities,
possible_relations=relations,
kg_validation_schema=schema,
strict=True, # if false, allows values outside of spec
)
2. 隐式提取:使用 LlamaIndex 的构造来指定数据中节点之间的关系。图将基于 node.relationships
属性构建。例如,当通过节点解析器处理文档时,PREVIOUS
、NEXT
和 SOURCE
关系将被捕获。
from llama_index.core.indices.property_graph import ImplicitPathExtractor
kg_extractor = ImplicitPathExtractor()
3. 自由形式提取:让 LLM 以自由形式直接从您的数据中推断实体、关系类型和模式。(这类似于当前的 KnowledgeGraphIndex
的工作方式。)
from llama_index.core.indices.property_graph import SimpleLLMPathExtractor
kg_extractor = SimpleLLMPathExtractor(llm=llm)
混合和匹配这些提取方法,以对您的图结构进行精细控制。
from llama_index.core import PropertyGraphIndex
index = PropertyGraphIndex.from_documents(docs, kg_extractors=[...])
嵌入
默认情况下,所有图节点都会被嵌入。虽然某些图数据库原生支持嵌入,您也可以在您的图数据库之上指定和使用 LlamaIndex 中的任何向量存储。
index = PropertyGraphIndex(..., vector_store=vector_store)
查询您的图
属性图索引支持多种查询技术,可以组合并同时运行。
1. 基于关键词/同义词的检索:将您的查询扩展为相关的关键词和同义词,并查找匹配的节点。
from llama_index.core.indices.property_graph import LLMSynonymRetriever
sub_retriever = LLMSynonymRetriever(index.property_graph_store, llm=llm)
2. 向量相似度:根据节点向量表示与您查询的相似度来检索节点。
from llama_index.core.indices.property_graph import VectorContextRetriever
sub_retriever = VectorContextRetriever(
index.property_graph_store,
vector_store=index.vector_store,
embed_model=embed_model,
)
3. Cypher 查询:使用富有表达力的 Cypher 图查询语言指定复杂的图模式并遍历多个关系。
from llama_index.core.indices.property_graph import CypherTemplateRetriever
from llama_index.core.bridge.pydantic import BaseModel, Field
class Params(BaseModel):
“””Parameters for a cypher query.”””
names: list[str] = Field(description=”A list of possible entity names or keywords related to the query.”)
cypher_query = """
MATCH (c:Chunk)-[:MENTIONS]->(o)
WHERE o.name IN $names
RETURN c.text, o.name, o.label;
"""
sub_retriever = CypherTemplateRetriever(
index.property_graph_store,
Params,
cypher_query,
llm=llm,
)
除了提供模板外,您还可以让 LLM 根据查询和数据库的上下文编写完整的 Cypher 查询。
from llama_index.core.indices.property_graph import TextToCypherRetriever
sub_retriever = TextToCypherRetriever(index.property_graph_store, llm=llm)
4. 自定义图遍历:通过对关键检索器组件进行子类化来定义您自己的图遍历逻辑。
这些检索器可以组合和构成,用于利用图结构和节点向量表示的混合搜索。
from llama_index.indices.property_graph import VectorContextRetriever, LLMSynonymRetriever
vector_retriever = VectorContextRetriever(index.property_graph_store, embed_model=embed_model)
synonym_retriever = LLMSynonymRetriever(index.property_graph_store, llm=llm)
retriever = index.as_retriever(sub_retrievers=[vector_retriever, synonym_retriever])
使用属性图存储
在底层,属性图索引使用 PropertyGraphStore
抽象来存储和检索图数据。您也可以直接使用此存储以进行更底层的控制。
此存储支持:
- 插入和更新节点、关系和属性
- 按 ID 或属性查询节点
- 从起始节点检索关系路径
- 执行 Cypher 查询(如果后端存储支持)
from llama_index.graph_stores.neo4j import Neo4jPGStore
graph_store = Neo4jPGStore(
username="neo4j",
password="password",
url="bolt://localhost:7687",
)
# insert nodes
nodes = [
EntityNode(name="llama", label="ANIMAL", properties={"key": "value"}),
EntityNode(name="index", label="THING", properties={"key": "value"}),
]
graph_store.upsert_nodes(nodes)
# insert relationships
relations = [
Relation(
label="HAS",
source_id=nodes[0].id,
target_id=nodes[1].id,
)
]
graph_store.upsert_relations(relations)
# query nodes
llama_node = graph_store.get(properties={"name": "llama"})[0]
# get relationship paths
paths = graph_store.get_rel_map([llama_node], depth=1)
# run Cypher query
results = graph_store.structured_query("MATCH (n) RETURN n LIMIT 10")
支持多种后端存储,包括内存、基于磁盘和 Neo4j。
了解更多
非常感谢我们的合作伙伴 Neo4j 在本次发布上的合作,特别是 Tomaz Bratanic 提供的详细集成指南和设计指导。
我们迫不及待地想看到您使用新的属性图索引构建出什么!一如既往,欢迎加入我们的 Discord,分享您的项目,提问并获得社区支持。
祝您构建愉快!
LlamaIndex 团队