Vespa 向量存储演示
如果您在 Colab 上打开这个笔记本,您可能需要安装 LlamaIndex 🦙。
%pip install llama-index-vector-stores-vespa llama-index pyvespaimport osimport openai
os.environ["OPENAI_API_KEY"] = "sk-..."openai.api_key = os.environ["OPENAI_API_KEY"]from llama_index.core import VectorStoreIndexfrom llama_index.vector_stores.vespa import VespaVectorStorefrom IPython.display import Markdown, display让我们插入一些文档。
from llama_index.core.schema import TextNode
nodes = [ TextNode( text="The Shawshank Redemption", metadata={ "author": "Stephen King", "theme": "Friendship", "year": 1994, }, ), TextNode( text="The Godfather", metadata={ "director": "Francis Ford Coppola", "theme": "Mafia", "year": 1972, }, ), TextNode( text="Inception", metadata={ "director": "Christopher Nolan", "theme": "Fiction", "year": 2010, }, ), TextNode( text="To Kill a Mockingbird", metadata={ "author": "Harper Lee", "theme": "Mafia", "year": 1960, }, ), TextNode( text="1984", metadata={ "author": "George Orwell", "theme": "Totalitarianism", "year": 1949, }, ), TextNode( text="The Great Gatsby", metadata={ "author": "F. Scott Fitzgerald", "theme": "The American Dream", "year": 1925, }, ), TextNode( text="Harry Potter and the Sorcerer's Stone", metadata={ "author": "J.K. Rowling", "theme": "Fiction", "year": 1997, }, ),]初始化 VespaVectorStore
Section titled “Initilizing the VespaVectorStore”为了让入门变得非常简单,我们提供了一个模板Vespa应用程序,该程序将在初始化向量存储时部署。
这是一个巨大的抽象层,有无限的机会可以根据您的需求来定制和调整 Vespa 应用程序。但现在,让我们保持简单,使用默认模板进行初始化。
from llama_index.core import StorageContext
vector_store = VespaVectorStore()storage_context = StorageContext.from_defaults(vector_store=vector_store)index = VectorStoreIndex(nodes, storage_context=storage_context)node_to_delete = nodes[0].node_idnode_to_deletevector_store.delete(ref_doc_id=node_to_delete)from llama_index.core.vector_stores.types import ( VectorStoreQuery, VectorStoreQueryMode,)query = VectorStoreQuery( query_str="Great Gatsby", mode=VectorStoreQueryMode.TEXT_SEARCH, similarity_top_k=1,)result = vector_store.query(query)resultretriever = index.as_retriever(vector_store_query_mode="default")results = retriever.retrieve("Who directed inception?")display(Markdown(f"**Retrieved nodes:**\n {results}"))retriever = index.as_retriever(vector_store_query_mode="semantic_hybrid")results = retriever.retrieve("Who wrote Harry Potter?")display(Markdown(f"**Retrieved nodes:**\n {results}"))query_engine = index.as_query_engine()response = query_engine.query("Who directed inception?")display(Markdown(f"**Response:** {response}"))query_engine = index.as_query_engine( vector_store_query_mode="semantic_hybrid", verbose=True)response = query_engine.query( "When was the book about the wizard boy published and what was it called?")display(Markdown(f"**Response:** {response}"))display(Markdown(f"**Sources:** {response.source_nodes}"))注意: 此元数据过滤由llama-index执行,在vespa外部完成。如需使用原生且性能更优的过滤功能,您应当使用Vespa自身的过滤能力。
更多信息请参阅 Vespa 文档。
from llama_index.core.vector_stores import ( FilterOperator, FilterCondition, MetadataFilter, MetadataFilters,)
# Let's define a filter that will only allow nodes that has the theme "Fiction" OR is published after 1997
filters = MetadataFilters( filters=[ MetadataFilter(key="theme", value="Fiction"), MetadataFilter(key="year", value=1997, operator=FilterOperator.GT), ], condition=FilterCondition.OR,)
retriever = index.as_retriever(filters=filters)result = retriever.retrieve("Harry Potter")display(Markdown(f"**Result:** {result}"))为了让入门变得非常简单,我们提供了一个模板Vespa应用程序,该程序将在初始化向量存储时部署。这消除了首次设置Vespa时的一些复杂性,但对于严肃的使用场景,我们强烈建议您阅读Vespa文档并根据您的需求定制应用程序。
提供的Vespa应用模板如下所示:
from vespa.package import ( ApplicationPackage, Field, Schema, Document, HNSW, RankProfile, Component, Parameter, FieldSet, GlobalPhaseRanking, Function,)
hybrid_template = ApplicationPackage( name="hybridsearch", schema=[ Schema( name="doc", document=Document( fields=[ Field(name="id", type="string", indexing=["summary"]), Field(name="metadata", type="string", indexing=["summary"]), Field( name="text", type="string", indexing=["index", "summary"], index="enable-bm25", bolding=True, ), Field( name="embedding", type="tensor<float>(x[384])", indexing=[ "input text", "embed", "index", "attribute", ], ann=HNSW(distance_metric="angular"), is_document_field=False, ), ] ), fieldsets=[FieldSet(name="default", fields=["text", "metadata"])], rank_profiles=[ RankProfile( name="bm25", inputs=[("query(q)", "tensor<float>(x[384])")], functions=[Function(name="bm25sum", expression="bm25(text)")], first_phase="bm25sum", ), RankProfile( name="semantic", inputs=[("query(q)", "tensor<float>(x[384])")], first_phase="closeness(field, embedding)", ), RankProfile( name="fusion", inherits="bm25", inputs=[("query(q)", "tensor<float>(x[384])")], first_phase="closeness(field, embedding)", global_phase=GlobalPhaseRanking( expression="reciprocal_rank_fusion(bm25sum, closeness(field, embedding))", rerank_count=1000, ), ), ], ) ], components=[ Component( id="e5", type="hugging-face-embedder", parameters=[ Parameter( "transformer-model", { "url": "https://github.com/vespa-engine/sample-apps/raw/master/simple-semantic-search/model/e5-small-v2-int8.onnx" }, ), Parameter( "tokenizer-model", { "url": "https://raw.githubusercontent.com/vespa-engine/sample-apps/master/simple-semantic-search/model/tokenizer.json" }, ), ], ) ],)请注意,字段 id、metadata、text 和 embedding 是集成工作所必需的。
模式名称也必须为 doc,并且排名配置文件必须命名为 bm25、semantic 和 fusion。
除此之外,您可以根据需要自由修改,例如更换嵌入模型、添加更多字段或更改排序表达式。
更多详细信息,请查看这个关于混合搜索的Pyvespa示例笔记本。