Reputation: 539
I try to use a perfectly valid and populated Pinecone index as a vectorstore in my langchain implementation. However, the chains don't load or operate with the vectorstore in any way.
for example, this code:
question = "What is your experience?"
llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0.1)
pc_index = pinecone.Index(index_name)
print(pc_index.describe_index_stats())
pc_interface = Pinecone.from_existing_index(
index_name,
embedding=OpenAIEmbeddings(),
namespace="SessionIndex"
)
qa_chain = RetrievalQA.from_chain_type(
llm,
retriever=pc_interface.as_retriever(),
)
print(qa_chain.run(question))
returns:
{'dimension': 1536,
'index_fullness': 0.0,
'namespaces': {'SessionIndex': {'vector_count': 40}},
'total_vector_count': 40}
As an AI language model, I don't have personal experiences like humans do. However, I have been trained on a wide range of data sources, including books, articles, and websites, to provide information and assist with various topics. Is there something specific you would like to know or discuss?
The index contains a number of entries related to personal experience of a person. If I use RetrievalQAWithSourcesChain and get the len() of sources, it prints 0.
How do I make Pinecone indexes work with Langchain?
Upvotes: 2
Views: 3797
Reputation: 4773
How you create the vector store is important. It is best to stick with langchain.
The return_source_documents=True
parameter in RetrievalQA
will let you see which source documents wer used.
If you don't have a vector store yet, here is how you would create it and use it as a retriever:
from langchain.chains import RetrievalQA
import pinecone
from langchain.vectorstores import Pinecone
vectorstore = Pinecone.from_documents(docs,embed,index_name, namespace="myspace")
retriever = vectorstore.as_retriever()
question = "What is your experience?"
llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0.1)
## return_source_documents=True will let you see which source documents were used
qa_chain = RetrievalQA.from_chain_type(llm,retriever=retriever, return_source_documents=True)
print(qa_chain.run(question))
If you already have a vector store that you created in another session, here is how you would load it and use it as a retriever:
from langchain.chains import RetrievalQA
import pinecone
from langchain.vectorstores import Pinecone
vectorstore = Pinecone.from_existing_index(index_name=index_name, embedding = embed, namespace="myspace")
retriever = vectorstore.as_retriever()
question = "What is your experience?"
llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0.1)
## return_source_documents=True will let you see which source documents were used
qa_chain = RetrievalQA.from_chain_type(llm,retriever=retriever, return_source_documents=True)
print(qa_chain.run(question))
Upvotes: 0
Reputation: 111
as you noted in the comments, chances are the document insertion was done in some "non-standard" way (though you did not share the insertion code).
Generally, it is preferrable to stay within the LangChain tooling for insertions if you plan to later run queries in LangChain. The reason is, LangChain has a uniform interface to let you see all the vector stores it supports as "looking the same", even though internally they might use different storage models for their data.
Pinecone indices, for instance, have only two notions associated to a vector: an "id" and a "metadata" (a dict). So, the Pinecone plugin for LC has to stuff all the input texts in a "text" field of the metadata being put in the index (and extract it back when retrieving).
This is different from what other LangChain-supported vector stores do. For example, if you look at the Cassandra/Astra DB integration you'll see a table with an explicit column for the input texts. You can see this in this notebook that illustrates how to use that vector store (with a full example). And by the way, if you don't stray off the LangChain abstraction level, you can swap one vector store for the other with essentially no changes in your code ... exactly because of the above uniformization step LangChain does.
So, back to Pinecone and LangChain. There are several ways to put rows in a vector store with LangChain, essentially dependent on what is your source (a PDF, a web page, a manual list of strings, text files ... whatever). There are a lot of supported "document loaders", see here.
Here is what you can do in the simplest case, that of having an explicit list of strings in your program, to put them into the store (again, note: this code is essentially vector-store-agnostic). The metadatas
part can be left out if so desired.
texts = [
"I grew up in a tall house.",
"My neighbours were very kind",
"I never felt compelled to do the dishes",
]
metadatas = [
{"source": "my_life"},
{"source": "my_life"},
{"source": "my_secrets"},
]
pc_interface.add_texts(texts=texts, metadatas=metadatas)
After runnig the above, I could test that your example will return something like:
Based on the given context, it seems that the speaker grew up in a tall house and had kind neighbors.
Note that if you look closely at the plugin implementation you notice something surprising: namely, the Pinecone client upsert
method, which in the documentation seems to require a dictionary describing the entry to insert, can work equally well with a 3-tuple (id, vector, metadata dict).
To summarize: if you leave the LangChain layer, do so at your own risk.
Also: you can find more examples of the idioms to load documents in a vector store with LangChain here and also in this full sample app. These examples work with Astra DB, but as said above if you don't leave that abstraction you shouldn't be concerned with the lowe-level changes in storage model. And, you may find it convenient to broaden your experience to other vector stores :)
Cheers!
Upvotes: 2