Repository: langchain
Issue: AttributeError: 'VectorStoreRetriever' object has no attribute 'embeddings'
Labels: Ɑ: vector store,investigate

### Checked other resources

- [X] I added a very descriptive title to this issue.
- [X] I searched the LangChain documentation with the integrated search.
- [X] I used the GitHub search to find a similar question and didn't find it.
- [X] I am sure that this is a bug in LangChain rather than my code.
- [x] The bug is not resolved by updating to the latest stable version of LangChain (or the specific integration package).

### Example Code

      from langchain.schema.document import Document
      from langchain_core.vectorstores import VectorStoreRetriever
      from langchain.retrievers import WikipediaRetriever
      from typing import List
      class RerankRetriever(VectorStoreRetriever):
          vectorstore: VectorStoreRetriever
          def get_relevant_documents(self, query: str) -> List[Document]:
              docs = self.vectorstore.get_relevant_documents(query=query)
              candidates = [doc.page_content for doc in docs]
              queries = [query]*len(candidates)
              features = tokenizer_rerank(queries, candidates,  padding=True, truncation=True, return_tensors="pt").to(device)
              with torch.no_grad():
                  scores = model_rerank(**features).logits
                  values, indices = torch.sum(scores, dim=1).sort()
                  # relevant_docs = docs[indices[0]]
              return [docs[indices[0]],docs[indices[1]]]
      class RerankWikiRetriever(VectorStoreRetriever):
          vectorstore: WikipediaRetriever
          def get_relevant_documents(self, query: str) -> List[Document]:
              docs = self.vectorstore.get_relevant_documents(query=query)
              candidates = [doc.page_content for doc in docs]
              queries = [query]*len(candidates)
              features = tokenizer_rerank(queries, candidates,  padding=True, truncation=True, return_tensors="pt").to(device)
              with torch.no_grad():
                  scores = model_rerank(**features).logits
                  values, indices = torch.sum(scores, dim=1).sort()
                  # relevant_docs = docs[indices[0]]
              return [docs[indices[0]],docs[indices[1]]]
        
        
        
          from langchain.retrievers import WikipediaRetriever
          from langchain.vectorstores import Qdrant
          from langchain.llms import HuggingFacePipeline
          from qdrant_client import QdrantClient
          from langchain.prompts import PromptTemplate
          from langchain.embeddings import HuggingFaceInferenceAPIEmbeddings
          from langchain.chains import RetrievalQA,MultiRetrievalQAChain
          from langchain.llms import VLLM
          from langchain.llms import HuggingFaceHub
          
          class LLMServe:
              def __init__(self) -> None:
                self.embeddings = self.load_embeddings()
                self.current_source = "wiki"
                self.retriever = self.load_retriever(retriever_name = self.current_source,embeddings=self.embeddings)
                self.pipe = self.load_model_pipeline(max_new_tokens=300)
                self.prompt = self.load_prompt_template()
                self.rag_pipeline = self.load_rag_pipeline(llm=self.pipe,
                                                      retriever=self.retriever,
                                                      prompt=self.prompt)
              def load_embeddings(self):
                embeddings = HuggingFaceInferenceAPIEmbeddings(
                    model_name=EMBEDDINGS_MODEL_NAME,
                    api_key = HUGGINGFACE_API_KEY,
                    #model_kwargs = {'device': "auto"}
                )
                return embeddings
          
      
      
          def load_retriever(self,retriever_name,embeddings):
            retriever=None
            if retriever_name == "wiki":
              retriever = RerankWikiRetriever(vectorstore = WikipediaRetriever(lang="vi",
                                             doc_content_chars_max=800,top_k_results=15))
            else:
              client = QdrantClient(
                  url=QDRANT_URL,api_key=QDRANT_API_KEY, prefer_grpc=False
              )
              db = Qdrant(client=client,
                          embeddings=embeddings,
                          collection_name=QDRANT_COLLECTION_NAME)
      
              retriever = RerankRetriever(vectorstore = db.as_retriever(search_kwargs={"k":15}))
      
            return retriever
      
          def load_model_pipeline(self,max_new_tokens=100):
            llm = VLLM(
                model=GENERATE_MODEL_NAME,
                trust_remote_code=True,  # mandatory for hf models
                max_new_tokens=max_new_tokens,
                  # temperature=1.0,
                  # top_k=50,
                  # top_p=0.9,
                top_k=10,
                top_p=0.95,
                temperature=0.4,
                dtype="half",
                vllm_kwargs={"quantization": "awq"}
            )
            return llm
      
          def load_prompt_template(self):
            # query_template = "Bạn là một trợ lý của trường Đại học Nguyễn Tất Thành. Hãy trả lời câu hỏi sau dựa trên ngữ cảnh, nếu ngữ cảnh không cung cấp câu trả lời hoặc không chắc chắn hãy trả lời 'Tôi không biết thông tin này, tuy nhiên đoạn thông tin dưới phần tham khảo có thể có câu trả lời cho bạn!' đừng cố tạo ra câu trả lời không có trong ngữ cảnh.\nNgữ cảnh: {context} \nCâu hỏi: {question}\nTrả lời: "
            # query_template = "Tham khảo ngữ cảnh:{context}\n\n### Câu hỏi:{question}\n\n### Trả lời:"
            query_template = "Bạn là một chatbot thông minh trả lời câu hỏi dựa trên ngữ cảnh (context).\n\n### Context:{context} \n\n### Human: {question}\n\n### Assistant:"
            prompt = PromptTemplate(template=query_template,
                              input_variables= ["context","question"])
            return prompt
      
          def load_rag_pipeline(self,llm,retriever,prompt):
            rag_pipeline = RetrievalQA.from_chain_type(
            llm=llm, chain_type='stuff',
            retriever=retriever,
            chain_type_kwargs={
            "prompt": prompt
            },
            return_source_documents=True)
            return rag_pipeline
      
          def rag(self,source):
            if source == self.current_source:
              return self.rag_pipeline
            else:
              self.retriever = self.load_retriever(retriever_name=source,embeddings=self.embeddings)
              self.rag_pipeline = self.load_rag_pipeline(llm=self.pipe,
                                            retriever=self.retriever,
                                            prompt=self.prompt)
              self.current_source = source
              return self.rag_pipeline
              
              app = LLMServe()
              
              from typing import Union
              from fastapi.middleware.cors import CORSMiddleware
              from fastapi.responses import JSONResponse
              from fastapi.encoders import jsonable_encoder
              from fastapi import FastAPI
              origins = ["*"]
              app_api = FastAPI()
              app_api.add_middleware(
                  CORSMiddleware,
                  allow_origins=origins,
                  allow_credentials=True,
                  allow_methods=["*"],
                  allow_headers=["*"],
              )
              
              @app_api.get("/")
              def read_root():
                  return "API RAG"
              
              @app_api.get("/rag/{source}")
              async def read_item(source: str, q: str | None = None):
                  if q:
                      data = app.rag(source=source)(q)
                      sources = []
                      for docs in data["source_documents"]:
                          sources.append(docs.to_json()["kwargs"])
                      res = {
                          "result" : data["result"],
                          "source_documents":sources
                      }
                      return JSONResponse(content=jsonable_encoder(res))
                  return None
                  
                                
              import nest_asyncio
              from pyngrok import ngrok
              import uvicorn
              ngrok.set_auth_token(NGROK_TOKEN)
              ngrok_tunnel = ngrok.connect(8000,domain=NGROK_STATIC_DOMAIN)
              print('Public URL:', ngrok_tunnel.public_url)
              nest_asyncio.apply()
              uvicorn.run(app_api, port=8000)


### Error Message and Stack Trace (if applicable)

AttributeError: 'VectorStoreRetriever' object has no attribute 'embeddings'

### Description

I encountered this error while trying to create a server on Google Colab to run my application. It successfully generated a public URL, but when I made a request to that URL, I encountered the error mentioned above. This is my first time asking questions like this, so if I missed any details, please let me know. Thank you very much.

### System Info

Public URL: https://natural-glider-willingly.ngrok-free.app/
INFO:     Started server process [218]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:8000/ (Press CTRL+C to quit)
INFO:     42.114.173.251:0 - "GET /rag/HUMG_db_v1?q=%C4%91i%E1%BB%81u%20ki%E1%BB%87n%20x%C3%A9t%20h%E1%BB%8Dc%20b%E1%BB%95ng HTTP/1.1" 500 Internal Server Error
<ipython-input-18-8f96afeb003a>:40: LangChainDeprecationWarning: The class `Qdrant` was deprecated in LangChain 0.0.37 and will be removed in 1.0. An updated version of the class exists in the :class:`~langchain-qdrant package and should be used instead. To use it run `pip install -U :class:`~langchain-qdrant` and import as `from :class:`~langchain_qdrant import Qdrant``.
  db = Qdrant(client=client,
<ipython-input-20-e07d1200679f>:23: LangChainDeprecationWarning: The method `Chain.__call__` was deprecated in langchain 0.1.0 and will be removed in 1.0. Use :meth:`~invoke` instead.
  data = app.rag(source=source)(q)
ERROR:    Exception in ASGI application
Traceback (most recent call last):
  File "/usr/local/lib/python3.10/dist-packages/uvicorn/protocols/http/httptools_impl.py", line 401, in run_asgi
    result = await app(  # type: ignore[func-returns-value]
  File "/usr/local/lib/python3.10/dist-packages/uvicorn/middleware/proxy_headers.py", line 60, in __call__
    return await self.app(scope, receive, send)
  File "/usr/local/lib/python3.10/dist-packages/fastapi/applications.py", line 1054, in __call__
    await super().__call__(scope, receive, send)
  File "/usr/local/lib/python3.10/dist-packages/starlette/applications.py", line 113, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/usr/local/lib/python3.10/dist-packages/starlette/middleware/errors.py", line 187, in __call__
    raise exc
  File "/usr/local/lib/python3.10/dist-packages/starlette/middleware/errors.py", line 165, in __call__
    await self.app(scope, receive, _send)
  File "/usr/local/lib/python3.10/dist-packages/starlette/middleware/cors.py", line 85, in __call__
    await self.app(scope, receive, send)
  File "/usr/local/lib/python3.10/dist-packages/starlette/middleware/exceptions.py", line 62, in __call__
    await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
  File "/usr/local/lib/python3.10/dist-packages/starlette/_exception_handler.py", line 62, in wrapped_app
    raise exc
  File "/usr/local/lib/python3.10/dist-packages/starlette/_exception_handler.py", line 51, in wrapped_app
    await app(scope, receive, sender)
  File "/usr/local/lib/python3.10/dist-packages/starlette/routing.py", line 715, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/usr/local/lib/python3.10/dist-packages/starlette/routing.py", line 735, in app
    await route.handle(scope, receive, send)
  File "/usr/local/lib/python3.10/dist-packages/starlette/routing.py", line 288, in handle
    await self.app(scope, receive, send)
  File "/usr/local/lib/python3.10/dist-packages/starlette/routing.py", line 76, in app
    await wrap_app_handling_exceptions(app, request)(scope, receive, send)
  File "/usr/local/lib/python3.10/dist-packages/starlette/_exception_handler.py", line 62, in wrapped_app
    raise exc
  File "/usr/local/lib/python3.10/dist-packages/starlette/_exception_handler.py", line 51, in wrapped_app
    await app(scope, receive, sender)
  File "/usr/local/lib/python3.10/dist-packages/starlette/routing.py", line 73, in app
    response = await f(request)
  File "/usr/local/lib/python3.10/dist-packages/fastapi/routing.py", line 301, in app
    raw_response = await run_endpoint_function(
  File "/usr/local/lib/python3.10/dist-packages/fastapi/routing.py", line 212, in run_endpoint_function
    return await dependant.call(**values)
  File "<ipython-input-20-e07d1200679f>", line 23, in read_item
    data = app.rag(source=source)(q)
  File "/usr/local/lib/python3.10/dist-packages/langchain_core/_api/deprecation.py", line 182, in warning_emitting_wrapper
    return wrapped(*args, **kwargs)
  File "/usr/local/lib/python3.10/dist-packages/langchain/chains/base.py", line 389, in __call__
    return self.invoke(
  File "/usr/local/lib/python3.10/dist-packages/langchain/chains/base.py", line 170, in invoke
    raise e
  File "/usr/local/lib/python3.10/dist-packages/langchain/chains/base.py", line 160, in invoke
    self._call(inputs, run_manager=run_manager)
  File "/usr/local/lib/python3.10/dist-packages/langchain/chains/retrieval_qa/base.py", line 151, in _call
    docs = self._get_docs(question, run_manager=_run_manager)
  File "/usr/local/lib/python3.10/dist-packages/langchain/chains/retrieval_qa/base.py", line 271, in _get_docs
    return self.retriever.invoke(
  File "/usr/local/lib/python3.10/dist-packages/langchain_core/retrievers.py", line 227, in invoke
    **self._get_ls_params(**kwargs),
  File "/usr/local/lib/python3.10/dist-packages/langchain_core/vectorstores/base.py", line 1063, in _get_ls_params
    if self.vectorstore.embeddings:
  File "/usr/local/lib/python3.10/dist-packages/pydantic/main.py", line 856, in __getattr__
    raise AttributeError(f'{type(self).__name__!r} object has no attribute {item!r}')
AttributeError: 'VectorStoreRetriever' object has no attribute 'embeddings'