UNPKG

@langchain/core

Version:
136 lines (135 loc) 5.65 kB
import { Document } from "../documents/document.js"; import { BaseExampleSelector } from "./base.js"; function sortedValues(values) { return Object.keys(values) .sort() .map((key) => values[key]); } /** * Class that selects examples based on semantic similarity. It extends * the BaseExampleSelector class. * @example * ```typescript * const exampleSelector = await SemanticSimilarityExampleSelector.fromExamples( * [ * { input: "happy", output: "sad" }, * { input: "tall", output: "short" }, * { input: "energetic", output: "lethargic" }, * { input: "sunny", output: "gloomy" }, * { input: "windy", output: "calm" }, * ], * new OpenAIEmbeddings(), * HNSWLib, * { k: 1 }, * ); * const dynamicPrompt = new FewShotPromptTemplate({ * exampleSelector, * examplePrompt: PromptTemplate.fromTemplate( * "Input: {input}\nOutput: {output}", * ), * prefix: "Give the antonym of every input", * suffix: "Input: {adjective}\nOutput:", * inputVariables: ["adjective"], * }); * console.log(await dynamicPrompt.format({ adjective: "rainy" })); * ``` */ export class SemanticSimilarityExampleSelector extends BaseExampleSelector { constructor(data) { super(data); Object.defineProperty(this, "vectorStoreRetriever", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "exampleKeys", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "inputKeys", { enumerable: true, configurable: true, writable: true, value: void 0 }); this.exampleKeys = data.exampleKeys; this.inputKeys = data.inputKeys; if (data.vectorStore !== undefined) { this.vectorStoreRetriever = data.vectorStore.asRetriever({ k: data.k ?? 4, filter: data.filter, }); } else if (data.vectorStoreRetriever) { this.vectorStoreRetriever = data.vectorStoreRetriever; } else { throw new Error(`You must specify one of "vectorStore" and "vectorStoreRetriever".`); } } /** * Method that adds a new example to the vectorStore. The example is * converted to a string and added to the vectorStore as a document. * @param example The example to be added to the vectorStore. * @returns Promise that resolves when the example has been added to the vectorStore. */ async addExample(example) { const inputKeys = this.inputKeys ?? Object.keys(example); const stringExample = sortedValues(inputKeys.reduce((acc, key) => ({ ...acc, [key]: example[key] }), {})).join(" "); await this.vectorStoreRetriever.addDocuments([ new Document({ pageContent: stringExample, metadata: example, }), ]); } /** * Method that selects which examples to use based on semantic similarity. * It performs a similarity search in the vectorStore using the input * variables and returns the examples with the highest similarity. * @param inputVariables The input variables used for the similarity search. * @returns Promise that resolves with an array of the selected examples. */ async selectExamples(inputVariables) { const inputKeys = this.inputKeys ?? Object.keys(inputVariables); const query = sortedValues(inputKeys.reduce((acc, key) => ({ ...acc, [key]: inputVariables[key] }), {})).join(" "); const exampleDocs = await this.vectorStoreRetriever.invoke(query); const examples = exampleDocs.map((doc) => doc.metadata); if (this.exampleKeys) { // If example keys are provided, filter examples to those keys. return examples.map((example) => this.exampleKeys.reduce((acc, key) => ({ ...acc, [key]: example[key] }), {})); } return examples; } /** * Static method that creates a new instance of * SemanticSimilarityExampleSelector. It takes a list of examples, an * instance of Embeddings, a VectorStore class, and an options object as * parameters. It converts the examples to strings, creates a VectorStore * from the strings and the embeddings, and returns a new * SemanticSimilarityExampleSelector with the created VectorStore and the * options provided. * @param examples The list of examples to be used. * @param embeddings The instance of Embeddings to be used. * @param vectorStoreCls The VectorStore class to be used. * @param options The options object for the SemanticSimilarityExampleSelector. * @returns Promise that resolves with a new instance of SemanticSimilarityExampleSelector. */ static async fromExamples(examples, embeddings, vectorStoreCls, options = {}) { const inputKeys = options.inputKeys ?? null; const stringExamples = examples.map((example) => sortedValues(inputKeys ? inputKeys.reduce((acc, key) => ({ ...acc, [key]: example[key] }), {}) : example).join(" ")); const vectorStore = await vectorStoreCls.fromTexts(stringExamples, examples, // metadatas embeddings, options); return new SemanticSimilarityExampleSelector({ vectorStore, k: options.k ?? 4, exampleKeys: options.exampleKeys, inputKeys: options.inputKeys, }); } }