What are the differences between vector store retriever invoke() and getRelevantDocuments()?

158 Views Asked by At

Here are the code snippet,

const vectorStore = await PineconeStore.fromExistingIndex(embeddings, {
  pineconeIndex,
});
const retriever = vectorStore.asRetriever();

// what are the differences between invoke() and getRelevantDocuments?
await retriever.invoke("How to make a cake?");
await retriever.getRelevantDocuments("How to make a cake?");

I seem to have difficulty to search from the API reference that describe these two functions. Do you know when should we use invoke() and getRelevantDocuments?

1

There are 1 best solutions below

0
Andrew Nguonly On

In this context, calling await retriever.invoke("How to make a cake?") and await retriever.getRelevantDocuments("How to make a cake?") have the same result, but the two methods belong to different interfaces.

getRelevantDocuments()

getRelevantDocuments() belongs to the BaseRetrieverInterface, which VectorStoreRetriever implements. vectorStore.asRetriever() returns a VectorStoreRetriever instance (a subclass of BaseRetriever).

You can call getRelevantDocuments() directly if your use case utilizes ONLY the retriever.

References

  1. BaseRetrieverInterface (GitHub)
  2. BaseRetriever.getRelevantDocuments() (GitHub)

invoke()

invoke() belongs to the RunnableInterface, which BaseRetrieverInterface extends. The implementation of invoke() is in the BaseRetriever class. The current implementation (0.1.28) of invoke() calls getRelevantDocuments() directly.

async invoke(
  input: string,
  options?: RunnableConfig
): Promise<DocumentInterface<Metadata>[]> {
  return this.getRelevantDocuments(input, ensureConfig(options));
}

So why are both invoke() and getRelevantDocuments() needed? invoke() is needed because the chain abstraction in LangChain is arbitrary with respect to which runnable abstractions (prompt templates, retrievers, models, output parsers, etc) exist in a chain.

For example, a chain can be composed of a retriever and a model. In order to maintain a common API that can be called to run the chain, each runnable abstraction (retriever and model) should have the invoke() method. Another chain can be composed of a model and an output parser. For the same reasons as before, each runnable abstraction (model and output parser) should have the invoke() method.

If your use case requires a chain, call invoke().

References

  1. RunnableInterface (GitHub)
  2. BaseRetriever.invoke() (GitHub)