using BotSharp.Plugin.KnowledgeBase.Utilities; using Tensorflow.NumPy; namespace BotSharp.Plugin.KnowledgeBase.MemVecDb; public class MemoryVectorDb : IVectorDb { private readonly Dictionary _collections = new Dictionary(); private readonly Dictionary> _vectors = new Dictionary>(); public string Name => "MemoryVector"; public async Task CreateCollection(string collectionName, int dim) { _collections[collectionName] = dim; _vectors[collectionName] = new List(); } public async Task> GetCollections() { return _collections.Select(x => x.Key).ToList(); } public Task> GetCollectionData(string collectionName, KnowledgeFilter filter) { throw new NotImplementedException(); } public async Task> Search(string collectionName, float[] vector, IEnumerable fields, int limit = 5, float confidence = 0.5f, bool withVector = false) { if (!_vectors.ContainsKey(collectionName)) { return new List(); } var similarities = VectorUtility.CalCosineSimilarity(vector, _vectors[collectionName]); // var similarities = VectorUtility.CalEuclideanDistance(vector, _vectors[collectionName]); var results = np.argsort(similarities).ToArray() .Reverse() .Take(limit) .Select(i => new KnowledgeSearchResult { Data = new Dictionary { { "text", _vectors[collectionName][i].Text } }, Score = similarities[i], Vector = withVector ? _vectors[collectionName][i].Vector : null, }) .ToList(); return await Task.FromResult(results); } public async Task Upsert(string collectionName, string id, float[] vector, string text, Dictionary? payload = null) { _vectors[collectionName].Add(new VecRecord { Id = id, Vector = vector, Text = text }); return true; } public Task DeleteCollectionData(string collectionName, string id) { throw new NotImplementedException(); } }