ComponentsVector storesZepOn this pageZepZep is an open source long-term memory store for LLM applications. Zep makes it easy to add relevant documents,
chat history memory & rich user data to your LLM app's prompts.Note: The ZepVectorStore works with Documents and is intended to be used as a Retriever.
It offers separate functionality to Zep's ZepMemory class, which is designed for persisting, enriching
and searching your user's chat history.Why Zep's VectorStore? 🤖🚀​Zep automatically embeds documents added to the Zep Vector Store using low-latency models local to the Zep server.
The Zep client also offers async interfaces for all document operations. These two together with Zep's chat memory
functionality make Zep ideal for building conversational LLM apps where latency and performance are important.Installation​Follow the Zep Quickstart Guide to install and get started with Zep.Usage​You'll need your Zep API URL and optionally an API key to use the Zep VectorStore.
See the Zep docs for more information.In the examples below, we're using Zep's auto-embedding feature which automatically embed documents on the Zep server
using low-latency embedding models.Note​These examples use Zep's async interfaces. Call sync interfaces by removing the a prefix from the method names.If you pass in an Embeddings instance Zep will use this to embed documents rather than auto-embed them.
You must also set your document collection to isAutoEmbedded === false. If you set your collection to isAutoEmbedded === false, you must pass in an Embeddings instance.Load or create a Collection from documents​from uuid import uuid4from langchain.document_loaders import WebBaseLoaderfrom langchain.text_splitter import RecursiveCharacterTextSplitterfrom langchain.vectorstores import ZepVectorStorefrom langchain.vectorstores.zep import CollectionConfigZEP_API_URL = "http://localhost:8000"  # this is the API url of your Zep instanceZEP_API_KEY = "<optional_key>"  # optional API Key for your Zep instancecollection_name = f"babbage{uuid4().hex}"  # a unique collection name. alphanum only# Collection config is needed if we're creating a new Zep Collectionconfig = CollectionConfig(    name=collection_name,    description="<optional description>",    metadata={"optional_metadata": "associated with the collection"},    is_auto_embedded=True,  # we'll have Zep embed our documents using its low-latency embedder    embedding_dimensions=1536  # this should match the model you've configured Zep to use.)# load the documentarticle_url = "https://www.gutenberg.org/cache/epub/71292/pg71292.txt"loader = WebBaseLoader(article_url)documents = loader.load()# split it into chunkstext_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=0)docs = text_splitter.split_documents(documents)# Instantiate the VectorStore. Since the collection does not already exist in Zep,# it will be created and populated with the documents we pass in.vs = ZepVectorStore.from_documents(docs,                                   collection_name=collection_name,                                   config=config,                                   api_url=ZEP_API_URL,                                   api_key=ZEP_API_KEY                                   )# wait for the collection embedding to completeasync def wait_for_ready(collection_name: str) -> None:    from zep_python import ZepClient    import time    client = ZepClient(ZEP_API_URL, ZEP_API_KEY)    while True:        c = await client.document.aget_collection(collection_name)        print(            "Embedding status: "            f"{c.document_embedded_count}/{c.document_count} documents embedded"        )        time.sleep(1)        if c.status == "ready":            breakawait wait_for_ready(collection_name)    Embedding status: 0/402 documents embedded    Embedding status: 0/402 documents embedded    Embedding status: 402/402 documents embeddedSimarility Search Query over the Collection​# query itquery = "what is the structure of our solar system?"docs_scores = await vs.asimilarity_search_with_relevance_scores(query, k=3)# print resultsfor d, s in docs_scores:    print(d.page_content, " -> ", s, "\n====\n")    Tables necessary to determine the places of the planets are not less    necessary than those for the sun, moon, and stars. Some notion of the    number and complexity of these tables may be formed, when we state that    the positions of the two principal planets, (and these are the most    necessary for the navigator,) Jupiter and Saturn, require each not less    than one hundred and sixteen tables. Yet it is not only necessary to    predict the position of these bodies, but it is likewise expedient to  ->  0.8998482592744614     ====        tabulate the motions of the four satellites of Jupiter, to predict the    exact times at which they enter his shadow, and at which their shadows    cross his disc, as well as the times at which they are interposed    between him and the Earth, and he between them and the Earth.        Among the extensive classes of tables here enumerated, there are several    which are in their nature permanent and unalterable, and would never    require to be recomputed, if they could once be computed with perfect  ->  0.8976143854195493     ====        the scheme of notation thus applied, immediately suggested the    advantages which must attend it as an instrument for expressing the    structure, operation, and circulation of the animal system; and we    entertain no doubt of its adequacy for that purpose. Not only the    mechanical connexion of the solid members of the bodies of men and    animals, but likewise the structure and operation of the softer parts,    including the muscles, integuments, membranes, &c. the nature, motion,  ->  0.889982614061763     ====Search over Collection Re-ranked by MMR​query = "what is the structure of our solar system?"docs = await vs.asearch(query, search_type="mmr", k=3)for d in docs:    print(d.page_content, "\n====\n")    Tables necessary to determine the places of the planets are not less    necessary than those for the sun, moon, and stars. Some notion of the    number and complexity of these tables may be formed, when we state that    the positions of the two principal planets, (and these the most    necessary for the navigator,) Jupiter and Saturn, require each not less    than one hundred and sixteen tables. Yet it is not only necessary to    predict the position of these bodies, but it is likewise expedient to     ====        the scheme of notation thus applied, immediately suggested the    advantages which must attend it as an instrument for expressing the    structure, operation, and circulation of the animal system; and we    entertain no doubt of its adequacy for that purpose. Not only the    mechanical connexion of the solid members of the bodies of men and    animals, but likewise the structure and operation of the softer parts,    including the muscles, integuments, membranes, &c. the nature, motion,     ====        tabulate the motions of the four satellites of Jupiter, to predict the    exact times at which they enter his shadow, and at which their shadows    cross his disc, as well as the times at which they are interposed    between him and the Earth, and he between them and the Earth.        Among the extensive classes of tables here enumerated, there are several    which are in their nature permanent and unalterable, and would never    require to be recomputed, if they could once be computed with perfect     ====Filter by MetadataUse a metadata filter to narrow down results. First, load another book: "Adventures of Sherlock Holmes"# Let's add more content to the existing Collectionarticle_url = "https://www.gutenberg.org/files/48320/48320-0.txt"loader = WebBaseLoader(article_url)documents = loader.load()# split it into chunkstext_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=0)docs = text_splitter.split_documents(documents)await vs.aadd_documents(docs)await wait_for_ready(collection_name)    Embedding status: 402/1692 documents embedded    Embedding status: 402/1692 documents embedded    Embedding status: 552/1692 documents embedded    Embedding status: 702/1692 documents embedded    Embedding status: 1002/1692 documents embedded    Embedding status: 1002/1692 documents embedded    Embedding status: 1152/1692 documents embedded    Embedding status: 1302/1692 documents embedded    Embedding status: 1452/1692 documents embedded    Embedding status: 1602/1692 documents embedded    Embedding status: 1692/1692 documents embeddedWe see results from both books. Note the source metadata​query = "Was he interested in astronomy?"docs = await vs.asearch(query, search_type="similarity", k=3)for d in docs:    print(d.page_content, " -> ", d.metadata, "\n====\n")    by that body to Mr Babbage:--'In no department of science, or of the    arts, does this discovery promise to be so eminently useful as in that    of astronomy, and its kindred sciences, with the various arts dependent    on them. In none are computations more operose than those which    astronomy in particular requires;--in none are preparatory facilities    more needful;--in none is error more detrimental. The practical    astronomer is interrupted in his pursuit, and diverted from his task of  ->  {'source': 'https://www.gutenberg.org/cache/epub/71292/pg71292.txt'}     ====        possess all knowledge which is likely to be useful to him in his work,    and this I have endeavored in my case to do. If I remember rightly, you    on one occasion, in the early days of our friendship, defined my limits    in a very precise fashion.”        “Yes,” I answered, laughing. “It was a singular document. Philosophy,    astronomy, and politics were marked at zero, I remember. Botany    variable, geology profound as regards the mud-stains from any region  ->  {'source': 'https://www.gutenberg.org/files/48320/48320-0.txt'}     ====        in all its relations; but above all, with Astronomy and Navigation. So    important have they been considered, that in many instances large sums    have been appropriated by the most enlightened nations in the production    of them; and yet so numerous and insurmountable have been the    difficulties attending the attainment of this end, that after all, even    navigators, putting aside every other department of art and science,    have, until very recently, been scantily and imperfectly supplied with  ->  {'source': 'https://www.gutenberg.org/cache/epub/71292/pg71292.txt'}     ====Let's try again using a filter for only the Sherlock Holmes document.​filter = {    "where": {"jsonpath": "$[*] ? (@.source == 'https://www.gutenberg.org/files/48320/48320-0.txt')"},}docs = await vs.asearch(query, search_type="similarity", metadata=filter, k=3)for d in docs:    print(d.page_content, " -> ", d.metadata, "\n====\n")    possess all knowledge which is likely to be useful to him in his work,    and this I have endeavored in my case to do. If I remember rightly, you    on one occasion, in the early days of our friendship, defined my limits    in a very precise fashion.”        “Yes,” I answered, laughing. “It was a singular document. Philosophy,    astronomy, and politics were marked at zero, I remember. Botany    variable, geology profound as regards the mud-stains from any region  ->  {'source': 'https://www.gutenberg.org/files/48320/48320-0.txt'}     ====        the light shining upon his strong-set aquiline features. So he sat as I    dropped off to sleep, and so he sat when a sudden ejaculation caused me    to wake up, and I found the summer sun shining into the apartment. The    pipe was still between his lips, the smoke still curled upward, and the    room was full of a dense tobacco haze, but nothing remained of the heap    of shag which I had seen upon the previous night.        “Awake, Watson?” he asked.        “Yes.”        “Game for a morning drive?”  ->  {'source': 'https://www.gutenberg.org/files/48320/48320-0.txt'}     ====        “I glanced at the books upon the table, and in spite of my ignorance    of German I could see that two of them were treatises on science, the    others being volumes of poetry. Then I walked across to the window,    hoping that I might catch some glimpse of the country-side, but an oak    shutter, heavily barred, was folded across it. It was a wonderfully    silent house. There was an old clock ticking loudly somewhere in the    passage, but otherwise everything was deadly still. A vague feeling of  ->  {'source': 'https://www.gutenberg.org/files/48320/48320-0.txt'}     ====PreviousXataNextZillizWhy Zep's VectorStore? 🤖🚀InstallationUsageNoteLoad or create a Collection from documentsSimarility Search Query over the CollectionSearch over Collection Re-ranked by MMRWe see results from both books. Note the source metadataLet's try again using a filter for only the Sherlock Holmes document.