Skip to content

MemoryRecord struct is not public visible. This blocks extending the storage system #202

Closed

Description

I have a large number of text files already embedded, embedding vectors are stored in a single file (embedding.jsonz). I would like to add these files to the memory system. However It turns out I could not reuse SemanticTextMemory class with my own IMemoryStore implementation.
The reason is SemanticTextMemory expects the result from storage is MemoryRecord, which is an internal type. my storage system could not create this type inside my code.
suggestions:

  1. Make MemoryRecord class public.
  2. Re-design the memory system. Current memory system is heavly over-cooked. Too many nested generic interface. As storage system heavyly rely on data serialize/deserialize and there's 5 key elements total (collection,key,content,content-type,embedding). A simple and lightweight data structure would be much better.
    Thanks

Activity

  1. dluc commented on Mar 29, 2023

    @dluc
    Contributor

    Clock Set Bird (@JohnMasen) thanks for raising the issue, I can see that navigating that part of the SDK can be challenging. I think it would be useful providing an example to cover this scenario. Abby Harrison (@awharrison-28) could we reproduce this scenario and verify that one can actually bring their own memory data, either embeddings, raw data or both?

  2. JohnMasen commented on Mar 29, 2023

    @JohnMasen
    Author

    suggested storage interface

    public struct MemoryRecord
    {
        public string? Collection;//null=default collection
        public string Key;
        public string Value;
        public string Value_ContentType; //default is text/plain (string), could be others, we can leave this for further use
        public readonlyspan<float>?  Embedding; //this coul be empty if retrieve from storage
    }
    
    Public Interface IMemoryStorage
    {
        void InsertOrUpdate(MemoryRecord value);
        MemoryRecord Retrieve(string collection, string key);
        void Remove(string collection,string key);
        void Purge(string collection);
        void InsertOrUpdateBatch(iEnumertable<MemroyRecord> itemList); 
       IEnumertable<MemoryRecord> Query(readonlyspan<float> queryEmbedding, float relevance=0.75f, int top=1);
    }
  3. JohnMasen commented on Mar 29, 2023

    @JohnMasen
    Author

    As every thing is stored as string, user may confused what if I want store a plan text and a content with referenced URL?
    there're 2 solutions:

    1. Store them in different collections, and use different deserialized to handle the data.
    2. use Value_ContentType to identify. for example: "text/plan"=text content,"jsonObject/[mytype]"=a user type

    The key is underline storage system should NOT take care of the exact content type (usage). Using nested generic interface as data causes storage system may not return the exact type like it was stored. Keep it simple, please.

  4. awharrison-28 commented on Mar 29, 2023

    @awharrison-28
    Contributor

    Hi Clock Set Bird (@JohnMasen), thank you for your feedback. I have hit a similar challenges and have been working on the story for passing vector metadata between storage schemas.

    • Memory - Qdrant Vector Database Connector #210 : reference for how we currently expect IMemoryStore to be implemented. Note that the PR contains a change to IEmbeddingWithMetadata expecting a string representation of the metadata (dotnet/src/SemanticKernel/Memory).
    • your suggestion of public string Value_ContentType is also high priority. I agree that it is very important for users to provide custom metadata to their storage not necessarily enforced by the kernel. This will make your suggestion of IMemoryStore : IDataStore<IEmbeddingWithMetadata> -> IMemoryStore : IDataStore<MemoryRecord> much easier.

    We also understand that the nested generics are noisy. It's certainly something we want to address in a cleaner fashion where possible.

    TLDR; Lots of improvements to Memory are in work. I'll keep this thread updated with relevant PRs.

  5. JohnMasen commented on Mar 30, 2023

    @JohnMasen
    Author

    Glad to see such a quick response. Expecting the new version :)

  6. awharrison-28 commented on Apr 4, 2023

    @awharrison-28
    Contributor

    Clock Set Bird (@JohnMasen) A number of the points you called out are addressed in #308. Note that MemoryRecord is already public as of #250. Adding a value string to MemoryRecord is coming soon among some other QoL changes to SemanticTextMemory.

  7. JohnMasen commented on Apr 6, 2023

    @JohnMasen
    Author

    That's great! very appreacted for your guys hard work!

  8. JohnMasen commented on Apr 11, 2023

    @JohnMasen
    Author

    I found the latest nuget package (0.10.72.1-preview) is not using the lastest change. Will these changes be included in the next version?

  9. awharrison-28 commented on Apr 11, 2023

    @awharrison-28
    Contributor

    Yes, these changes will be included in the next version. I believe we will be rolling it out today.

  10. awharrison-28 commented on Apr 12, 2023

    @awharrison-28
    Contributor

    Clock Set Bird (@JohnMasen) PR is out that adds an optional valueString field to MemoryRecord. IMemoryStore get/search methods now optionally return the embedding to the user too (defaults to false).

    Once those changes propagate to the latest nuget package, can we consider this issue closed?

  11. JohnMasen commented on Apr 13, 2023

    @JohnMasen
    Author

    Abby Harrison (@awharrison-28) By upgrading to the lastest package, I confirm the fix is done, please feel free to close the issue.
    Great job, guys!

  12. awharrison-28 commented on Apr 13, 2023

    @awharrison-28
    Contributor

    Clock Set Bird (@JohnMasen) following up here, the next package release adds a field to MemoryRecordMetadata for custom metadata strings and Get/Search memories calls can optionally return the actual embedding (defaulting to not).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions