From 160eca89771a003aa10df8ee1e2ad265870b58a6 Mon Sep 17 00:00:00 2001 From: jacoblee93 Date: Tue, 13 Aug 2024 14:03:36 -0700 Subject: [PATCH 1/4] Adds vector store docstrings --- .../integrations/vectorstores/memory.ipynb | 2 +- .../src/indexes/vector_stores/pinecone/mmr.ts | 45 ++---- langchain/src/vectorstores/memory.ts | 111 ++++++++++++- .../src/vectorstores/chroma.ts | 38 ++--- .../src/vectorstores/pgvector.ts | 150 +++++++++++++++++- .../src/vectorstores/supabase.ts | 133 +++++++++++++++- libs/langchain-pinecone/src/vectorstores.ts | 133 +++++++++++++++- 7 files changed, 547 insertions(+), 65 deletions(-) diff --git a/docs/core_docs/docs/integrations/vectorstores/memory.ipynb b/docs/core_docs/docs/integrations/vectorstores/memory.ipynb index 8943d85715a9..923ac8d2a746 100644 --- a/docs/core_docs/docs/integrations/vectorstores/memory.ipynb +++ b/docs/core_docs/docs/integrations/vectorstores/memory.ipynb @@ -19,7 +19,7 @@ "id": "ef1f0986", "metadata": {}, "source": [ - "# `MemoryVectorStore`\n", + "# MemoryVectorStore\n", "\n", "LangChain offers is an in-memory, ephemeral vectorstore that stores embeddings in-memory and does an exact, linear search for the most similar embeddings. The default similarity metric is cosine similarity, but can be changed to any of the similarity metrics supported by [ml-distance](https://mljs.github.io/distance/modules/similarity.html).\n", "\n", diff --git a/examples/src/indexes/vector_stores/pinecone/mmr.ts b/examples/src/indexes/vector_stores/pinecone/mmr.ts index 10a85253b3ea..2763917f735e 100644 --- a/examples/src/indexes/vector_stores/pinecone/mmr.ts +++ b/examples/src/indexes/vector_stores/pinecone/mmr.ts @@ -1,36 +1,23 @@ -/* eslint-disable @typescript-eslint/no-non-null-assertion */ -import { Pinecone } from "@pinecone-database/pinecone"; +import { MemoryVectorStore } from "langchain/vectorstores/memory"; +// Or other embeddings import { OpenAIEmbeddings } from "@langchain/openai"; -import { PineconeStore } from "@langchain/pinecone"; -// Instantiate a new Pinecone client, which will automatically read the -// env vars: PINECONE_API_KEY and PINECONE_ENVIRONMENT which come from -// the Pinecone dashboard at https://app.pinecone.io +const embeddings = new OpenAIEmbeddings({ + model: "text-embedding-3-small", +}); -const pinecone = new Pinecone(); +const vectorStore = new MemoryVectorStore(embeddings); -const pineconeIndex = pinecone.Index(process.env.PINECONE_INDEX!); +import type { Document } from "@langchain/core/documents"; -/** - * Pinecone allows you to partition the records in an index into namespaces. - * Queries and other operations are then limited to one namespace, - * so different requests can search different subsets of your index. - * Read more about namespaces here: https://docs.pinecone.io/guides/indexes/use-namespaces - * - * NOTE: If you have namespace enabled in your Pinecone index, you must provide the namespace when creating the PineconeStore. - */ -const namespace = "pinecone"; +const document1 = { pageContent: "foo", metadata: { baz: "bar" } }; +const document2 = { pageContent: "thud", metadata: { bar: "baz" } }; +const document3 = { pageContent: "i will be deleted :(", metadata: {} }; -const vectorStore = await PineconeStore.fromExistingIndex( - new OpenAIEmbeddings(), - { pineconeIndex, namespace } -); +const documents: Document[] = [document1, document2, document3]; +await vectorStore.addDocuments(documents); -/* Search the vector DB independently with meta filters */ -const results = await vectorStore.maxMarginalRelevanceSearch("pinecone", { - k: 5, - fetchK: 20, // Default value for the number of initial documents to fetch for reranking. - // You can pass a filter as well - // filter: {}, -}); -console.log(results); +const results = await vectorStore.similaritySearch("thud", 1); +for (const doc of results) { + console.log(`* ${doc.pageContent} [${JSON.stringify(doc.metadata, null)}]`); +} diff --git a/langchain/src/vectorstores/memory.ts b/langchain/src/vectorstores/memory.ts index 50c3fdc4526a..fc77840a77ab 100644 --- a/langchain/src/vectorstores/memory.ts +++ b/langchain/src/vectorstores/memory.ts @@ -29,9 +29,114 @@ export interface MemoryVectorStoreArgs { } /** - * Class that extends `VectorStore` to store vectors in memory. Provides - * methods for adding documents, performing similarity searches, and - * creating instances from texts, documents, or an existing index. + * In-memory, ephemeral vector store. + * + * Setup: + * Install `langchain`: + * + * ```bash + * npm install langchain + * ``` + * + * ## [Constructor args](https://api.js.langchain.com/classes/langchain.vectorstores_memory.MemoryVectorStore.html#constructor) + * + *
+ * Instantiate + * + * ```typescript + * import { MemoryVectorStore } from 'langchain/vectorstores/memory'; + * // Or other embeddings + * import { OpenAIEmbeddings } from '@langchain/openai'; + * + * const embeddings = new OpenAIEmbeddings({ + * model: "text-embedding-3-small", + * }); + * + * const vectorStore = new MemoryVectorStore(embeddings); + * ``` + *
+ * + *
+ * + *
+ * Add documents + * + * ```typescript + * import type { Document } from '@langchain/core/documents'; + * + * const document1 = { pageContent: "foo", metadata: { baz: "bar" } }; + * const document2 = { pageContent: "thud", metadata: { bar: "baz" } }; + * const document3 = { pageContent: "i will be deleted :(", metadata: {} }; + * + * const documents: Document[] = [document1, document2, document3]; + * + * await vectorStore.addDocuments(documents); + * ``` + *
+ * + *
+ * + *
+ * Similarity search + * + * ```typescript + * const results = await vectorStore.similaritySearch("thud", 1); + * for (const doc of results) { + * console.log(`* ${doc.pageContent} [${JSON.stringify(doc.metadata, null)}]`); + * } + * // Output: * thud [{"baz":"bar"}] + * ``` + *
+ * + *
+ * + * + *
+ * Similarity search with filter + * + * ```typescript + * const resultsWithFilter = await vectorStore.similaritySearch("thud", 1, { baz: "bar" }); + * + * for (const doc of resultsWithFilter) { + * console.log(`* ${doc.pageContent} [${JSON.stringify(doc.metadata, null)}]`); + * } + * // Output: * foo [{"baz":"bar"}] + * ``` + *
+ * + *
+ * + * + *
+ * Similarity search with score + * + * ```typescript + * const resultsWithScore = await vectorStore.similaritySearchWithScore("qux", 1); + * for (const [doc, score] of resultsWithScore) { + * console.log(`* [SIM=${score.toFixed(6)}] ${doc.pageContent} [${JSON.stringify(doc.metadata, null)}]`); + * } + * // Output: * [SIM=0.000000] qux [{"bar":"baz","baz":"bar"}] + * ``` + *
+ * + *
+ * + *
+ * As a retriever + * + * ```typescript + * const retriever = vectorStore.asRetriever({ + * searchType: "mmr", // Leave blank for standard similarity search + * k: 1, + * }); + * const resultAsRetriever = await retriever.invoke("thud"); + * console.log(resultAsRetriever); + * + * // Output: [Document({ metadata: { "baz":"bar" }, pageContent: "thud" })] + * ``` + *
+ * + *
*/ export class MemoryVectorStore extends VectorStore { declare FilterType: (doc: Document) => boolean; diff --git a/libs/langchain-community/src/vectorstores/chroma.ts b/libs/langchain-community/src/vectorstores/chroma.ts index 7cec56f83429..81731fbef087 100644 --- a/libs/langchain-community/src/vectorstores/chroma.ts +++ b/libs/langchain-community/src/vectorstores/chroma.ts @@ -49,24 +49,12 @@ export interface ChromaDeleteParams { * Chroma vector store integration. * * Setup: - * Install `@langchain/community` and `chromadb`, then clone the official `ChromaDB` repository. + * Install `@langchain/community` and `chromadb`. * * ```bash * npm install @langchain/community chromadb * ``` * - * ```bash - * git clone https://github.com/chroma-core/chroma.git - * ``` - * - * Next, navigate into the `chroma` directory and start the docker container: - * - * ```bash - * cd ./chroma - * - * docker compose up - * ``` - * * ## [Constructor args](https://api.js.langchain.com/classes/langchain_community_vectorstores_chroma.Chroma.html#constructor) * *
@@ -74,10 +62,15 @@ export interface ChromaDeleteParams { * * ```typescript * import { Chroma } from '@langchain/community/vectorstores/chroma'; + * // Or other embeddings * import { OpenAIEmbeddings } from '@langchain/openai'; * + * const embeddings = new OpenAIEmbeddings({ + * model: "text-embedding-3-small", + * }) + * * const vectorStore = new Chroma( - * new OpenAIEmbeddings(), + * embeddings, * { * collectionName: "foo", * url: "http://localhost:8000", // URL of the Chroma server @@ -92,13 +85,13 @@ export interface ChromaDeleteParams { * Add documents * * ```typescript - * import { Document } from '@langchain/core/documents'; + * import type { Document } from '@langchain/core/documents'; * - * const document1 = new Document({ pageContent: "foo", metadata: { baz: "bar" } }); - * const document2 = new Document({ pageContent: "thud", metadata: { bar: "baz" } }); - * const document3 = new Document({ pageContent: "i will be deleted :(" }); + * const document1 = { pageContent: "foo", metadata: { baz: "bar" } }; + * const document2 = { pageContent: "thud", metadata: { bar: "baz" } }; + * const document3 = { pageContent: "i will be deleted :(", metadata: {} }; * - * const documents = [document1, document2, document3]; + * const documents: Document[] = [document1, document2, document3]; * const ids = ["1", "2", "3"]; * await vectorStore.addDocuments(documents, { ids }); * ``` @@ -166,7 +159,7 @@ export interface ChromaDeleteParams { * * ```typescript * const retriever = vectorStore.asRetriever({ - * searchType: "mmr", + * searchType: "mmr", // Leave blank for standard similarity search * k: 1, * }); * const resultAsRetriever = await retriever.invoke("thud"); @@ -473,10 +466,7 @@ export class Chroma extends VectorStore { return instance; } - /** - * Imports the `ChromaClient` from the `chromadb` module. - * @returns A promise that resolves with an object containing the `ChromaClient` constructor. - */ + /** @ignore */ static async imports(): Promise<{ ChromaClient: typeof ChromaClientT; }> { diff --git a/libs/langchain-community/src/vectorstores/pgvector.ts b/libs/langchain-community/src/vectorstores/pgvector.ts index 662ce96d2889..ded20864b9f4 100644 --- a/libs/langchain-community/src/vectorstores/pgvector.ts +++ b/libs/langchain-community/src/vectorstores/pgvector.ts @@ -41,10 +41,152 @@ export interface PGVectorStoreArgs { } /** - * Class that provides an interface to a Postgres vector database. It - * extends the `VectorStore` base class and implements methods for adding - * documents and vectors, performing similarity searches, and ensuring the - * existence of a table in the database. + * PGVector vector store integration. + * + * Setup: + * Install `@langchain/community` and `pg`. + * + * If you wish to generate ids, you should also install the `uuid` package. + * + * ```bash + * npm install @langchain/community pg uuid + * ``` + * + * ## [Constructor args](https://api.js.langchain.com/classes/_langchain_community.vectorstores_pgvector.PGVectorStore.html#constructor) + * + *
+ * Instantiate + * + * ```typescript + * import { + * PGVectorStore, + * DistanceStrategy, + * } from "@langchain/community/vectorstores/pgvector"; + * + * // Or other embeddings + * import { OpenAIEmbeddings } from "@langchain/openai"; + * import { PoolConfig } from "pg"; + * + * const embeddings = new OpenAIEmbeddings({ + * model: "text-embedding-3-small", + * }); + * + * // Sample config + * const config = { + * postgresConnectionOptions: { + * type: "postgres", + * host: "127.0.0.1", + * port: 5433, + * user: "myuser", + * password: "ChangeMe", + * database: "api", + * } as PoolConfig, + * tableName: "testlangchainjs", + * columns: { + * idColumnName: "id", + * vectorColumnName: "vector", + * contentColumnName: "content", + * metadataColumnName: "metadata", + * }, + * // supported distance strategies: cosine (default), innerProduct, or euclidean + * distanceStrategy: "cosine" as DistanceStrategy, + * }; + * + * const vectorStore = await PGVectorStore.initialize(embeddings, config); + * ``` + *
+ * + *
+ * + *
+ * Add documents + * + * ```typescript + * import type { Document } from '@langchain/core/documents'; + * + * const document1 = { pageContent: "foo", metadata: { baz: "bar" } }; + * const document2 = { pageContent: "thud", metadata: { bar: "baz" } }; + * const document3 = { pageContent: "i will be deleted :(", metadata: {} }; + * + * const documents: Document[] = [document1, document2, document3]; + * const ids = ["1", "2", "3"]; + * await vectorStore.addDocuments(documents, { ids }); + * ``` + *
+ * + *
+ * + *
+ * Delete documents + * + * ```typescript + * await vectorStore.delete({ ids: ["3"] }); + * ``` + *
+ * + *
+ * + *
+ * Similarity search + * + * ```typescript + * const results = await vectorStore.similaritySearch("thud", 1); + * for (const doc of results) { + * console.log(`* ${doc.pageContent} [${JSON.stringify(doc.metadata, null)}]`); + * } + * // Output: * thud [{"baz":"bar"}] + * ``` + *
+ * + *
+ * + * + *
+ * Similarity search with filter + * + * ```typescript + * const resultsWithFilter = await vectorStore.similaritySearch("thud", 1, { baz: "bar" }); + * + * for (const doc of resultsWithFilter) { + * console.log(`* ${doc.pageContent} [${JSON.stringify(doc.metadata, null)}]`); + * } + * // Output: * foo [{"baz":"bar"}] + * ``` + *
+ * + *
+ * + * + *
+ * Similarity search with score + * + * ```typescript + * const resultsWithScore = await vectorStore.similaritySearchWithScore("qux", 1); + * for (const [doc, score] of resultsWithScore) { + * console.log(`* [SIM=${score.toFixed(6)}] ${doc.pageContent} [${JSON.stringify(doc.metadata, null)}]`); + * } + * // Output: * [SIM=0.000000] qux [{"bar":"baz","baz":"bar"}] + * ``` + *
+ * + *
+ * + *
+ * As a retriever + * + * ```typescript + * const retriever = vectorStore.asRetriever({ + * searchType: "mmr", // Leave blank for standard similarity search + * k: 1, + * }); + * const resultAsRetriever = await retriever.invoke("thud"); + * console.log(resultAsRetriever); + * + * // Output: [Document({ metadata: { "baz":"bar" }, pageContent: "thud" })] + * ``` + *
+ * + *
*/ export class PGVectorStore extends VectorStore { declare FilterType: Metadata; diff --git a/libs/langchain-community/src/vectorstores/supabase.ts b/libs/langchain-community/src/vectorstores/supabase.ts index e12eb260933d..e8875c3aab9d 100644 --- a/libs/langchain-community/src/vectorstores/supabase.ts +++ b/libs/langchain-community/src/vectorstores/supabase.ts @@ -46,8 +46,137 @@ export interface SupabaseLibArgs { } /** - * Class for interacting with a Supabase database to store and manage - * vectors. + * Supabase vector store integration. + * + * Setup: + * Install `@langchain/community` and `@supabase/supabase-js`. + * + * ```bash + * npm install @langchain/community @supabase/supabase-js + * ``` + * + * See https://js.langchain.com/v0.2/docs/integrations/vectorstores/supabase for + * instructions on how to set up your Supabase instance. + * + * ## [Constructor args](https://api.js.langchain.com/classes/_langchain_community.vectorstores_supabase.SupabaseVectorStore.html#constructor) + * + *
+ * Instantiate + * + * ```typescript + * import { SupabaseVectorStore } from "@langchain/community/vectorstores/supabase"; + * import { OpenAIEmbeddings } from "@langchain/openai"; + * + * import { createClient } from "@supabase/supabase-js"; + * + * const embeddings = new OpenAIEmbeddings({ + * model: "text-embedding-3-small", + * }); + * + * const supabaseClient = createClient( + * process.env.SUPABASE_URL, + * process.env.SUPABASE_PRIVATE_KEY + * ); + * + * const vectorStore = new SupabaseVectorStore(embeddings, { + * client: supabaseClient, + * tableName: "documents", + * queryName: "match_documents", + * }); + * ``` + *
+ * + *
+ * + *
+ * Add documents + * + * ```typescript + * import type { Document } from '@langchain/core/documents'; + * + * const document1 = { pageContent: "foo", metadata: { baz: "bar" } }; + * const document2 = { pageContent: "thud", metadata: { bar: "baz" } }; + * const document3 = { pageContent: "i will be deleted :(", metadata: {} }; + * + * const documents: Document[] = [document1, document2, document3]; + * const ids = ["1", "2", "3"]; + * await vectorStore.addDocuments(documents, { ids }); + * ``` + *
+ * + *
+ * + *
+ * Delete documents + * + * ```typescript + * await vectorStore.delete({ ids: ["3"] }); + * ``` + *
+ * + *
+ * + *
+ * Similarity search + * + * ```typescript + * const results = await vectorStore.similaritySearch("thud", 1); + * for (const doc of results) { + * console.log(`* ${doc.pageContent} [${JSON.stringify(doc.metadata, null)}]`); + * } + * // Output: * thud [{"baz":"bar"}] + * ``` + *
+ * + *
+ * + * + *
+ * Similarity search with filter + * + * ```typescript + * const resultsWithFilter = await vectorStore.similaritySearch("thud", 1, { baz: "bar" }); + * + * for (const doc of resultsWithFilter) { + * console.log(`* ${doc.pageContent} [${JSON.stringify(doc.metadata, null)}]`); + * } + * // Output: * foo [{"baz":"bar"}] + * ``` + *
+ * + *
+ * + * + *
+ * Similarity search with score + * + * ```typescript + * const resultsWithScore = await vectorStore.similaritySearchWithScore("qux", 1); + * for (const [doc, score] of resultsWithScore) { + * console.log(`* [SIM=${score.toFixed(6)}] ${doc.pageContent} [${JSON.stringify(doc.metadata, null)}]`); + * } + * // Output: * [SIM=0.000000] qux [{"bar":"baz","baz":"bar"}] + * ``` + *
+ * + *
+ * + *
+ * As a retriever + * + * ```typescript + * const retriever = vectorStore.asRetriever({ + * searchType: "mmr", // Leave blank for standard similarity search + * k: 1, + * }); + * const resultAsRetriever = await retriever.invoke("thud"); + * console.log(resultAsRetriever); + * + * // Output: [Document({ metadata: { "baz":"bar" }, pageContent: "thud" })] + * ``` + *
+ * + *
*/ export class SupabaseVectorStore extends VectorStore { declare FilterType: SupabaseMetadata | SupabaseFilterRPCCall; diff --git a/libs/langchain-pinecone/src/vectorstores.ts b/libs/langchain-pinecone/src/vectorstores.ts index b9e3be201326..3a99dbceb057 100644 --- a/libs/langchain-pinecone/src/vectorstores.ts +++ b/libs/langchain-pinecone/src/vectorstores.ts @@ -64,8 +64,137 @@ export type PineconeDeleteParams = { }; /** - * Class for managing and operating vector search applications with - * Pinecone, the cloud-native high-scale vector database + * Pinecone vector store integration. + * + * Setup: + * Install `@langchain/pinecone` and `@pinecone-database/pinecone` to pass a client in. + * + * ```bash + * npm install @langchain/pinecone @pinecone-database/pinecone + * ``` + * + * ## [Constructor args](https://api.js.langchain.com/classes/_langchain_pinecone.PineconeStore.html#constructor) + * + *
+ * Instantiate + * + * ```typescript + * import { PineconeStore } from '@langchain/pinecone'; + * // Or other embeddings + * import { OpenAIEmbeddings } from '@langchain/openai'; + * + * import { Pinecone as PineconeClient } from "@pinecone-database/pinecone"; + * + * const pinecone = new PineconeClient(); + * + * // Will automatically read the PINECONE_API_KEY and PINECONE_ENVIRONMENT env vars + * const pineconeIndex = pinecone.Index(process.env.PINECONE_INDEX!); + * + * const embeddings = new OpenAIEmbeddings({ + * model: "text-embedding-3-small", + * }); + * + * const vectorStore = await PineconeStore.fromExistingIndex(embeddings, { + * pineconeIndex, + * // Maximum number of batch requests to allow at once. Each batch is 1000 vectors. + * maxConcurrency: 5, + * // You can pass a namespace here too + * // namespace: "foo", + * }); + * ``` + *
+ * + *
+ * + *
+ * Add documents + * + * ```typescript + * import type { Document } from '@langchain/core/documents'; + * + * const document1 = { pageContent: "foo", metadata: { baz: "bar" } }; + * const document2 = { pageContent: "thud", metadata: { bar: "baz" } }; + * const document3 = { pageContent: "i will be deleted :(", metadata: {} }; + * + * const documents: Document[] = [document1, document2, document3]; + * const ids = ["1", "2", "3"]; + * await vectorStore.addDocuments(documents, { ids }); + * ``` + *
+ * + *
+ * + *
+ * Delete documents + * + * ```typescript + * await vectorStore.delete({ ids: ["3"] }); + * ``` + *
+ * + *
+ * + *
+ * Similarity search + * + * ```typescript + * const results = await vectorStore.similaritySearch("thud", 1); + * for (const doc of results) { + * console.log(`* ${doc.pageContent} [${JSON.stringify(doc.metadata, null)}]`); + * } + * // Output: * thud [{"baz":"bar"}] + * ``` + *
+ * + *
+ * + * + *
+ * Similarity search with filter + * + * ```typescript + * const resultsWithFilter = await vectorStore.similaritySearch("thud", 1, { baz: "bar" }); + * + * for (const doc of resultsWithFilter) { + * console.log(`* ${doc.pageContent} [${JSON.stringify(doc.metadata, null)}]`); + * } + * // Output: * foo [{"baz":"bar"}] + * ``` + *
+ * + *
+ * + * + *
+ * Similarity search with score + * + * ```typescript + * const resultsWithScore = await vectorStore.similaritySearchWithScore("qux", 1); + * for (const [doc, score] of resultsWithScore) { + * console.log(`* [SIM=${score.toFixed(6)}] ${doc.pageContent} [${JSON.stringify(doc.metadata, null)}]`); + * } + * // Output: * [SIM=0.000000] qux [{"bar":"baz","baz":"bar"}] + * ``` + *
+ * + *
+ * + *
+ * As a retriever + * + * ```typescript + * const retriever = vectorStore.asRetriever({ + * searchType: "mmr", // Leave blank for standard similarity search + * k: 1, + * }); + * const resultAsRetriever = await retriever.invoke("thud"); + * console.log(resultAsRetriever); + * + * // Output: [Document({ metadata: { "baz":"bar" }, pageContent: "thud" })] + * ``` + *
+ * + *
*/ export class PineconeStore extends VectorStore { declare FilterType: PineconeMetadata; From dcd8ff0f9df51fe309ef2795536d90370b06578d Mon Sep 17 00:00:00 2001 From: jacoblee93 Date: Tue, 13 Aug 2024 14:05:07 -0700 Subject: [PATCH 2/4] Revert --- .../src/indexes/vector_stores/pinecone/mmr.ts | 45 ++++++++++++------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/examples/src/indexes/vector_stores/pinecone/mmr.ts b/examples/src/indexes/vector_stores/pinecone/mmr.ts index 2763917f735e..143356b93a32 100644 --- a/examples/src/indexes/vector_stores/pinecone/mmr.ts +++ b/examples/src/indexes/vector_stores/pinecone/mmr.ts @@ -1,23 +1,36 @@ -import { MemoryVectorStore } from "langchain/vectorstores/memory"; -// Or other embeddings +/* eslint-disable @typescript-eslint/no-non-null-assertion */ +import { Pinecone } from "@pinecone-database/pinecone"; import { OpenAIEmbeddings } from "@langchain/openai"; +import { PineconeStore } from "@langchain/pinecone"; -const embeddings = new OpenAIEmbeddings({ - model: "text-embedding-3-small", -}); +// Instantiate a new Pinecone client, which will automatically read the +// env vars: PINECONE_API_KEY and PINECONE_ENVIRONMENT which come from +// the Pinecone dashboard at https://app.pinecone.io -const vectorStore = new MemoryVectorStore(embeddings); +const pinecone = new Pinecone(); -import type { Document } from "@langchain/core/documents"; +const pineconeIndex = pinecone.Index(process.env.PINECONE_INDEX!); -const document1 = { pageContent: "foo", metadata: { baz: "bar" } }; -const document2 = { pageContent: "thud", metadata: { bar: "baz" } }; -const document3 = { pageContent: "i will be deleted :(", metadata: {} }; +/** + * Pinecone allows you to partition the records in an index into namespaces. + * Queries and other operations are then limited to one namespace, + * so different requests can search different subsets of your index. + * Read more about namespaces here: https://docs.pinecone.io/guides/indexes/use-namespaces + * + * NOTE: If you have namespace enabled in your Pinecone index, you must provide the namespace when creating the PineconeStore. + */ +const namespace = "pinecone"; -const documents: Document[] = [document1, document2, document3]; -await vectorStore.addDocuments(documents); +const vectorStore = await PineconeStore.fromExistingIndex( + new OpenAIEmbeddings(), + { pineconeIndex, namespace } +); -const results = await vectorStore.similaritySearch("thud", 1); -for (const doc of results) { - console.log(`* ${doc.pageContent} [${JSON.stringify(doc.metadata, null)}]`); -} +/* Search the vector DB independently with meta filters */ +const results = await vectorStore.maxMarginalRelevanceSearch("pinecone", { + k: 5, + fetchK: 20, // Default value for the number of initial documents to fetch for reranking. + // You can pass a filter as well + // filter: {}, +}); +console.log(results); \ No newline at end of file From bf5c62a5a6880a9c5081054bef3bb365321254ef Mon Sep 17 00:00:00 2001 From: jacoblee93 Date: Tue, 13 Aug 2024 14:05:23 -0700 Subject: [PATCH 3/4] Revert --- examples/src/indexes/vector_stores/pinecone/mmr.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/src/indexes/vector_stores/pinecone/mmr.ts b/examples/src/indexes/vector_stores/pinecone/mmr.ts index 143356b93a32..10a85253b3ea 100644 --- a/examples/src/indexes/vector_stores/pinecone/mmr.ts +++ b/examples/src/indexes/vector_stores/pinecone/mmr.ts @@ -33,4 +33,4 @@ const results = await vectorStore.maxMarginalRelevanceSearch("pinecone", { // You can pass a filter as well // filter: {}, }); -console.log(results); \ No newline at end of file +console.log(results); From d40bb7eb7a7aeb911606061e299031598857fa80 Mon Sep 17 00:00:00 2001 From: jacoblee93 Date: Tue, 13 Aug 2024 14:42:00 -0700 Subject: [PATCH 4/4] Adds tool docstrings --- .../tools/duckduckgo_search.ipynb | 2 +- .../integrations/tools/tavily_search.ipynb | 2 +- .../src/tools/duckduckgo_search.ts | 65 ++++++++++++++++- .../src/tools/tavily_search.ts | 65 ++++++++++++++++- .../src/tools/wikipedia_query_run.ts | 64 +++++++++++++++-- libs/langchain-exa/src/tools.ts | 70 ++++++++++++++++++- 6 files changed, 257 insertions(+), 11 deletions(-) diff --git a/docs/core_docs/docs/integrations/tools/duckduckgo_search.ipynb b/docs/core_docs/docs/integrations/tools/duckduckgo_search.ipynb index e0053c4cd9b1..1ff5b72ffdea 100644 --- a/docs/core_docs/docs/integrations/tools/duckduckgo_search.ipynb +++ b/docs/core_docs/docs/integrations/tools/duckduckgo_search.ipynb @@ -30,7 +30,7 @@ "### Integration details\n", "\n", "| Class | Package | [PY support](https://python.langchain.com/docs/integrations/tools/ddg/) | Package latest |\n", - "| :--- | :--- | :---: | :---: | :---: |\n", + "| :--- | :--- | :---: | :---: |\n", "| [DuckDuckGoSearch](https://api.js.langchain.com/classes/langchain_community_tools_duckduckgo_search.DuckDuckGoSearch.html) | [`@langchain/community`](https://www.npmjs.com/package/@langchain/community) | ✅ | ![NPM - Version](https://img.shields.io/npm/v/@langchain/community?style=flat-square&label=%20&) |\n", "\n", "## Setup\n", diff --git a/docs/core_docs/docs/integrations/tools/tavily_search.ipynb b/docs/core_docs/docs/integrations/tools/tavily_search.ipynb index ec6b12c0a0dd..ff63e76ba54c 100644 --- a/docs/core_docs/docs/integrations/tools/tavily_search.ipynb +++ b/docs/core_docs/docs/integrations/tools/tavily_search.ipynb @@ -30,7 +30,7 @@ "### Integration details\n", "\n", "| Class | Package | [PY support](https://python.langchain.com/v0.2/docs/integrations/tools/tavily_search/) | Package latest |\n", - "| :--- | :--- | :---: | :---: | :---: |\n", + "| :--- | :--- | :---: | :---: |\n", "| [TavilySearchResults](https://api.js.langchain.com/classes/langchain_community_tools_tavily_search.TavilySearchResults.html) | [`@langchain/community`](https://www.npmjs.com/package/@langchain/community) | ✅ | ![NPM - Version](https://img.shields.io/npm/v/@langchain/community?style=flat-square&label=%20&) |\n", "\n", "## Setup\n", diff --git a/libs/langchain-community/src/tools/duckduckgo_search.ts b/libs/langchain-community/src/tools/duckduckgo_search.ts index 70c440253a1c..7bfd04307a89 100644 --- a/libs/langchain-community/src/tools/duckduckgo_search.ts +++ b/libs/langchain-community/src/tools/duckduckgo_search.ts @@ -24,8 +24,69 @@ export interface DuckDuckGoSearchParameters extends ToolParams { const DEFAULT_MAX_RESULTS = 10; /** - * Class for interacting with the DuckDuckGo search engine - * It extends the base Tool class to perform retrieval. + * DuckDuckGo tool integration. + * + * Setup: + * Install `@langchain/community` and `duck-duck-scrape`. + * + * ```bash + * npm install @langchain/community duck-duck-scrape + * ``` + * + * ## [Constructor args](https://api.js.langchain.com/classes/_langchain_community.tools_duckduckgo_search.DuckDuckGoSearch.html#constructor) + * + *
+ * Instantiate + * + * ```typescript + * import { DuckDuckGoSearch } from "@langchain/community/tools/duckduckgo_search"; + * + * const tool = new DuckDuckGoSearch({ maxResults: 1 }); + * ``` + *
+ * + *
+ * + *
+ * + * Invocation + * + * ```typescript + * await tool.invoke("what is the current weather in sf?"); + * + * // output: [{"title":"San Francisco, CA Current Weather | AccuWeather","link":"https://www.accuweather.com/en/us/san-francisco/94103/current-weather/347629","snippet":"Current weather in San Francisco, CA. Check current conditions in San Francisco, CA with radar, hourly, and more."}] + * ``` + *
+ * + *
+ * + *
+ * + * Invocation with tool call + * + * ```typescript + * // This is usually generated by a model, but we'll create a tool call directly for demo purposes. + * const modelGeneratedToolCall = { + * args: { + * input: "what is the current weather in sf?", + * }, + * id: "tool_call_id", + * name: tool.name, + * type: "tool_call", + * }; + * await tool.invoke(modelGeneratedToolCall); + * ``` + * + * ```text + * ToolMessage { + * "content": "[{\"title\":\"San Francisco, CA Weather Conditions | Weather Underground\",\"link\":\"https://www.wunderground.com/weather/us/ca/san-francisco\",\"snippet\":\"San Francisco Weather Forecasts. Weather Underground provides local & long-range weather forecasts, weatherreports, maps & tropical weather conditions for the San Francisco area.\"}]", + * "name": "duckduckgo-search", + * "additional_kwargs": {}, + * "response_metadata": {}, + * "tool_call_id": "tool_call_id" + * } + * ``` + *
*/ export class DuckDuckGoSearch extends Tool { private searchOptions?: SearchOptions; diff --git a/libs/langchain-community/src/tools/tavily_search.ts b/libs/langchain-community/src/tools/tavily_search.ts index a68f97d5e588..b83a042f7888 100644 --- a/libs/langchain-community/src/tools/tavily_search.ts +++ b/libs/langchain-community/src/tools/tavily_search.ts @@ -12,7 +12,70 @@ export type TavilySearchAPIRetrieverFields = ToolParams & { }; /** - * Tool for the Tavily search API. + * Tavily search API tool integration. + * + * Setup: + * Install `@langchain/community`. You'll also need an API key set as `TAVILY_API_KEY`. + * + * ```bash + * npm install @langchain/community + * ``` + * + * ## [Constructor args](https://api.js.langchain.com/classes/_langchain_community.tools_tavily_search.TavilySearchResults.html#constructor) + * + *
+ * Instantiate + * + * ```typescript + * import { TavilySearchResults } from "@langchain/community/tools/tavily_search"; + * + * const tool = new TavilySearchResults({ + * maxResults: 2, + * // ... + * }); + * ``` + *
+ * + *
+ * + *
+ * + * Invocation + * + * ```typescript + * await tool.invoke("what is the current weather in sf?"); + * ``` + *
+ * + *
+ * + *
+ * + * Invocation with tool call + * + * ```typescript + * // This is usually generated by a model, but we'll create a tool call directly for demo purposes. + * const modelGeneratedToolCall = { + * args: { + * input: "what is the current weather in sf?", + * }, + * id: "tool_call_id", + * name: tool.name, + * type: "tool_call", + * }; + * await tool.invoke(modelGeneratedToolCall); + * ``` + * + * ```text + * ToolMessage { + * "content": "...", + * "name": "tavily_search_results_json", + * "additional_kwargs": {}, + * "response_metadata": {}, + * "tool_call_id": "tool_call_id" + * } + * ``` + *
*/ export class TavilySearchResults extends Tool { static lc_name(): string { diff --git a/libs/langchain-community/src/tools/wikipedia_query_run.ts b/libs/langchain-community/src/tools/wikipedia_query_run.ts index d0166e5c58d0..2c2f6b066761 100644 --- a/libs/langchain-community/src/tools/wikipedia_query_run.ts +++ b/libs/langchain-community/src/tools/wikipedia_query_run.ts @@ -53,16 +53,70 @@ interface PageResult { } /** - * Class for interacting with and fetching data from the Wikipedia API. It - * extends the Tool class. - * @example + * Wikipedia query tool integration. + * + * Setup: + * Install `@langchain/community`. You'll also need an API key. + * + * ```bash + * npm install @langchain/community + * ``` + * + * ## [Constructor args](https://api.js.langchain.com/classes/_langchain_community.tools_wikipedia_query_run.WikipediaQueryRun.html#constructor) + * + *
+ * Instantiate + * * ```typescript - * const wikipediaQuery = new WikipediaQueryRun({ + * import { WikipediaQueryRun } from "@langchain/community/tools/wikipedia_query_run"; + * + * const tool = new WikipediaQueryRun({ * topKResults: 3, * maxDocContentLength: 4000, * }); - * const result = await wikipediaQuery.call("Langchain"); * ``` + *
+ * + *
+ * + *
+ * + * Invocation + * + * ```typescript + * await tool.invoke("what is the current weather in sf?"); + * ``` + *
+ * + *
+ * + *
+ * + * Invocation with tool call + * + * ```typescript + * // This is usually generated by a model, but we'll create a tool call directly for demo purposes. + * const modelGeneratedToolCall = { + * args: { + * input: "what is the current weather in sf?", + * }, + * id: "tool_call_id", + * name: tool.name, + * type: "tool_call", + * }; + * await tool.invoke(modelGeneratedToolCall); + * ``` + * + * ```text + * ToolMessage { + * "content": "...", + * "name": "wikipedia-api", + * "additional_kwargs": {}, + * "response_metadata": {}, + * "tool_call_id": "tool_call_id" + * } + * ``` + *
*/ export class WikipediaQueryRun extends Tool { static lc_name() { diff --git a/libs/langchain-exa/src/tools.ts b/libs/langchain-exa/src/tools.ts index 6bf52ad64ede..285ea7f66d0b 100644 --- a/libs/langchain-exa/src/tools.ts +++ b/libs/langchain-exa/src/tools.ts @@ -13,7 +13,75 @@ export type ExaSearchRetrieverFields< }; /** - * Tool for the Exa search API. + * Exa search tool integration. + * + * Setup: + * Install `@langchain/exa` and `exa-js`. You'll also need an API key. + * + * ```bash + * npm install @langchain/exa exa-js + * ``` + * + * ## [Constructor args](https://api.js.langchain.com/classes/_langchain_exa.ExaSearchResults.html#constructor) + * + *
+ * Instantiate + * + * ```typescript + * import { ExaSearchResults } from "@langchain/exa"; + * import Exa from "exa-js"; + * + * const client = new Exa(process.env.EXASEARCH_API_KEY); + * + * const tool = new ExaSearchResults({ + * client, + * searchArgs: { + * numResults: 2, + * }, + * }); + * ``` + *
+ * + *
+ * + *
+ * + * Invocation + * + * ```typescript + * await tool.invoke("what is the current weather in sf?"); + * ``` + *
+ * + *
+ * + *
+ * + * Invocation with tool call + * + * ```typescript + * // This is usually generated by a model, but we'll create a tool call directly for demo purposes. + * const modelGeneratedToolCall = { + * args: { + * input: "what is the current weather in sf?", + * }, + * id: "tool_call_id", + * name: tool.name, + * type: "tool_call", + * }; + * await tool.invoke(modelGeneratedToolCall); + * ``` + * + * ```text + * ToolMessage { + * "content": "...", + * "name": "exa_search_results_json", + * "additional_kwargs": {}, + * "response_metadata": {}, + * "tool_call_id": "tool_call_id" + * } + * ``` + *
*/ export class ExaSearchResults< T extends ContentsOptions = { text: true }