UNPKG

@jackhua/mini-langchain

Version:

A lightweight TypeScript implementation of LangChain with cost optimization features

92 lines 3.38 kB
"use strict"; /** * Base vector store interface and implementations */ Object.defineProperty(exports, "__esModule", { value: true }); exports.VectorStore = exports.VectorStoreSearchType = void 0; /** * Vector store search type */ var VectorStoreSearchType; (function (VectorStoreSearchType) { VectorStoreSearchType["SIMILARITY"] = "similarity"; VectorStoreSearchType["MMR"] = "mmr"; })(VectorStoreSearchType || (exports.VectorStoreSearchType = VectorStoreSearchType = {})); /** * Base vector store interface */ class VectorStore { constructor(embeddings) { this.embeddings = embeddings; } /** * Max marginal relevance search */ async maxMarginalRelevanceSearch(query, options = {}) { const { k = 4, fetchK = 20, lambda = 0.5, filter } = options; // Embed query const queryEmbedding = await this.embeddings.embedQuery(query); // Fetch more candidates const candidates = await this.similaritySearchVectorWithScore(queryEmbedding, fetchK, filter); // MMR algorithm const selected = new Set(); const selectedDocs = []; while (selectedDocs.length < k && selected.size < candidates.length) { let bestScore = -Infinity; let bestIdx = -1; for (let i = 0; i < candidates.length; i++) { if (selected.has(i)) continue; const [doc, simScore] = candidates[i]; // Calculate diversity score let diversityScore = Infinity; for (const selectedIdx of selected) { const [selectedDoc] = candidates[selectedIdx]; const diversity = this.calculateDiversity(doc, selectedDoc); diversityScore = Math.min(diversityScore, diversity); } // MMR score const mmrScore = lambda * simScore - (1 - lambda) * (1 - diversityScore); if (mmrScore > bestScore) { bestScore = mmrScore; bestIdx = i; } } if (bestIdx !== -1) { selected.add(bestIdx); selectedDocs.push(candidates[bestIdx][0]); } else { break; } } return selectedDocs; } /** * Calculate diversity between two documents */ calculateDiversity(doc1, doc2) { // Simple text-based diversity (can be overridden) const text1 = doc1.pageContent.toLowerCase(); const text2 = doc2.pageContent.toLowerCase(); const words1 = new Set(text1.split(/\s+/)); const words2 = new Set(text2.split(/\s+/)); const intersection = new Set([...words1].filter(x => words2.has(x))); const union = new Set([...words1, ...words2]); return intersection.size / union.size; } /** * Create vector store from texts */ static async fromTexts(texts, metadatas, embeddings, dbConfig) { throw new Error('fromTexts must be implemented by subclass'); } /** * Create vector store from documents */ static async fromDocuments(docs, embeddings, dbConfig) { throw new Error('fromDocuments must be implemented by subclass'); } } exports.VectorStore = VectorStore; //# sourceMappingURL=base.js.map