Exploring Weaviate Langchain: A Thorough Guide

The Weaviate Langchain has been the talk of the town for a while now and in the world of cutting-edge technologies, Weaviate emerges as a promising future of vector databases. Unlike traditional databases, Weaviate stands out as an open-source solution designed to store data objects and vector embeddings from machine learning models, seamlessly scaling into the realm of billions of data objects.

Exploring Weaviate Langchain

The deployment of Weaviate Langchain can be done in many different ways based on your requirements. For instance, you can either connect to a Weaviate Cloud Services instance or a local Docker instance. To do this, you have to follow the installation instructions. You can use Weaviate Cloud Services for both development and production environments.

On the other hand, you can choose docker-compose, a containerized deployment method mainly used for development projects. Or, you can opt for Kubernetes, ideal for scalable and containerized deployments. However, this approach is commonly utilized in production setups. Both Docker Compose and Kubernetes setup use a “yaml” file to customize weaviate instances, which is known as “docker-compose.yml” or “values.yaml” respectively. These files will be consistently denoted as configuration yaml files in the documentation.

Prerequisites 

Firstly, you have to install the “weaviate-client” package, and then you have to set the relevant environment variables. To get the OpenAPI Key, you can use “OpenAIEmbeddings.”

!pip install weaviate-client

import getpass
import os

os.environ["OPENAI_API_KEY"] = getpass.getpass("OpenAI API Key:")
WEAVIATE_URL = getpass.getpass("WEAVIATE_URL:")
os.environ["WEAVIATE_API_KEY"] = getpass.getpass("WEAVIATE_API_KEY:")
WEAVIATE_API_KEY = os.environ["WEAVIATE_API_KEY"]

Here is a simple example demonstrating the basics of performing a similarity search.

!pip install langchain

from langchain.document_loaders import TextLoader
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.text_splitter import CharacterTextSplitter
from langchain.vectorstores import Weaviate

loader = TextLoader("../../modules/state_of_the_union.txt")
documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
docs = text_splitter.split_documents(documents)

embeddings = OpenAIEmbeddings()

# Connect with Weaviate
db = Weaviate.from_documents(docs, embeddings, weaviate_url=WEAVIATE_URL, by_text=False)

# Conduct a Similarity Search
query = "What did the president say about Ketanji Brown Jackson"
docs = db.similarity_search(query)

# Display the Burst of Information
print(docs[0].page_content)

Authentication

Authentication is activated by default in Weaviate instances. This provides an option for the users to choose either a username/password combination or an API key.

import weaviate

client = weaviate.Client(
    url=WEAVIATE_URL, auth_client_secret=weaviate.AuthApiKey(WEAVIATE_API_KEY)
)

# Create a Vector Store in Weaviate
vectorstore = Weaviate.from_documents(
    documents, embeddings, client=client, by_text=False
)

# Display the Weaviate Object
print(vectorstore)

Maximal marginal relevance search (MMR)

There are many options if you want to know how to use Weaviate as a retriever. Additionally, you can use maximal marginal relevance search (MMR), an alternative approach to similarity search. Go through the code snippet below to get a clear idea.

!pip install database as DB
import DB

# Set up a Retrieval Object with MMR
retriever = DB.as_retriever(search_type="mmr")

# Retrieve Relevant Documents
retriever = DB.as_retriever(search_kwargs={"k": int(get_env_var('TARGET_SOURCE_CHUNKS')),
                                           "filter":{'$and': [{'user_id': {'$eq': user_id}},
                                                              {'category_id': {'$eq': cat_id}}]}})
#Specifying Retrieving
retriever = DB.as_retriever(search_kwargs={"k": int(get_env_var('TARGET_SOURCE_CHUNKS')),
                                           "filter":{'user_id': {'$in': [user_id_1, user_id_2]}}})
# Display the Gem of Information
print(relevant_docs[0].page_content)

Now, let’s explore the process of conducting question-answering via an index. This can be achieved by utilizing the “RetrievalQAWithSourcesChain,” which is responsible for looking up the documents from an Index.

!pip install langchain

from langchain.chains import RetrievalQAWithSourcesChain
from langchain.llms import OpenAI

# Read the State of the Union
with open("../../modules/state_of_the_union.txt") as f:
    state_of_the_union = f.read()

# Split the Text into Chunks
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
texts = text_splitter.split_text(state_of_the_union)

# Create a Weaviate Vector Store
docsearch = Weaviate.from_texts(
    texts,
    embeddings,
    weaviate_url=WEAVIATE_URL,
    by_text=False,
    metadatas=[{"source": f"{i}-pl"} for i in range(len(texts))],
)

# Set Up the Retrieval Chain for QA
chain = RetrievalQAWithSourcesChain.from_chain_type(
    OpenAI(temperature=0), chain_type="stuff", retriever=docsearch.as_retriever()
)

# Ask a Question
result = chain(
    {"question": "What did the president say about Justice Breyer"},
    return_only_outputs=True,
)

# Display the Artful Response
print(result['answer'])

Retrieval-Augmented Generation

Here is the code snippet of retrieval-augmented generation for question-answering:

retriever = !pip install langchain-core

from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough

rag_chain = (
    {"context": retriever, "question": RunnablePassthrough()}
    | prompt
    | llm
    | StrOutputParser()
)

rag_chain.invoke("What did the president say about Justice Breyer")

Sequential Chains

Chains allow us to merge multiple LLM references. The name itself conveys that sequential chains execute their links one after another or in a sequential manner. These chains take one input/output and then use the production for the next step.

Combine Documents Chain

LLMs are restricted by token lengths because of the computational cost required for processing and storing longer sequences of tokens. As the sequence length increases, more memory and processing power are needed to operate on it. This can be a substantial challenge even for robust computing systems.

LLMs integrate with semantic search due to their limited input window. For instance, using a blog post as input alongside questions allows LLMs to answer the questions. However, handling entire books or extensive search results requires smart approaches. This is the reason for using the “CombineDocuments chain.” But remember that no method is universally superior; performance depends on your application’s specific needs.

Stuffing: This straightforward method involves taking related documents from the database and stuffing them into the prompt. It’s simple but may need help with lengthy documents exceeding the context length.

Map Reduce: Map Reduce involves applying an initial prompt to each data chunk. Therefore, it is passed through the language model and generates multiple responses. A subsequent prompt is created to merge all the initial outputs into one. This approach needs numerous calls to the Language Model.

Refine: Refine is a remarkable method because it has a local memory. For instance, if you instruct a language model to summarize documents individually, it uses the summaries generated so far to shape the next output. This iterative process continues until all documents have been thoroughly processed.

Map Rerank: In Map Rerank, an initial prompt is executed, which requests the model to provide a relevance score. After that, this score is processed by the language model, which assigns a score depending on the certainty of the answer. Following this, the documents are ranked, and the top two are incorporated into the language model to generate a single response.

Tool Use

Tool use involves enhancing language models with the ability to use various tools. For example, we can connect a Language Model (LLM) to vector databases, calculators, or code executors. A good example involves a language model writing Python code for the bubble sort algorithm, and the generated code is executed through a Python REPL (Read-Eval-Print Loop). Python REPL refers to a code executor that is implemented in langchain. After execution, the output is printed, and the language model assesses the correctness of the code based on this output.

Exploring ChatVectorDB

Langchain’s collection of preconfigured chains stands out as the best feature of all. These preconfigured chains are known as ChatVectorDB chains. This chain empowers you to construct a Language Model (LLM) capable of storing chat history and retrieving context from Weaviate to enhance generation. The chat history in the given chain uses the “stuff” configuration of CombineDocuments which signifies that we take the chat history that can be accommodated within our context window and use it for a query reformulation prompt. The specific prompt is outlined below:

_template = """Given the following conversation and a follow-up question, rephrase the follow-up question to be a standalone question.

Chat History:
{chat_history}
Follow-Up Input: {question}
Standalone question:"""

The resulting prompt guides the language model in generating answers, utilizing Weaviate’s search results for context.

Prompt_template = """Use the following pieces of context to answer the question at the end. If you don't know the answer, just say that you don't know, don't try to make up an answer.
 {context}
Question: {question}
Helpful Answer:"""

FAQs

What is Weaviate’s primary function?

Weaviate is a vector database that stores data objects and vector embeddings from machine learning models. It excels in seamlessly scaling to handle billions of data objects, making it a versatile solution for various applications.

How can I deploy Weaviate? 

Weaviate offers flexible deployment options, allowing you to connect to a Weaviate Cloud Services instance or set up a local Docker instance. The installation instructions provided serve as a gateway to unlocking the potential of this innovative vector database.

How does Weaviate Langchain handle authentication?

Weaviate prioritizes security through authentication. The provided code elegantly establishes a secure connection, ensuring that every interaction with Weaviate is authenticated and safeguarded.

Conclusion

In conclusion, Weaviate is a powerful and flexible open-source vector database that offers efficient data management capabilities by accommodating billions of data objects. This article thoroughly explores Weaviate Langchain’s deployment methods, authentication options, and its utilization in diverse scenarios, from similarity searches and maximal marginal relevance searches to question-answering via retrieval-augmented generation. We Hope that you have got a clear idea about Weaviate Langchain and its features from this article.

Reference

  1. Weaviate
  2. LangChain

Leave a Comment