Copilot Chat: Adding Copilot support for chroma#1989
Copilot Chat: Adding Copilot support for chroma#1989jsboige wants to merge 14 commits intomicrosoft:mainfrom
Conversation
merge upstream
merge upstream
merge upstream
merge upstream
…ollection list rather than to
dmytrostruk
left a comment
There was a problem hiding this comment.
Hi @jsboige , thank you for contribution!
Answering your PR description:
Regarding memory store exception inconsistency: we need to do some work for better exception handling, and we already started the process (Issue: #1669). While things like CollectionSafeMemoryStore should temporarily fix an issue, I would probably focus on resolving root problem instead of adding the workaround.
In your changes, for Search operations you added CheckAndCreateCollectionAsync. But I'm not sure I understand the flow here: we try to search something in collection, which doesn't exist, so we create that collection, and the result will be always empty?
In general, methods like SaveInformationAsync and SafeReferenceAsync should create a collection if it doesn't exist, while methods like GetNearestMatchesAsync should throw an exception if we try to search in non-existent collection. In this way we can notify developers that something is wrong in their searching logic.
This flow should be aligned across all memory stores, and that's our goal in scope of global exception handling refactoring task.
Regarding DoesCollectionExistAsync method in Chroma - I don't see an issue in handling exception in case if collection doesn't exist - it's just the way how Chroma API is designed and ChromaMemoryStore, as API consumer, handles that. I don't see an advantage in listing all collections to find one (to avoid exception handling) instead of trying to get one directly.
While I do agree, that logging it as Error is a mistake, so I would change that to Warning or even Debug.
Please let me know if that makes sense. Thank you!
|
Hi @dmytrostruk,
Well I'm sorry I wasn't more precise in my description. The current issue is that with the current flow, with each Http request, the current chat session memory is searched for before the chat history memory items are added to it. It only crashes with chroma on first load (qdrant mutes the exception and then the collection is properly created). Accordingly, my fix was more some temporary patch before a better decision is made.
Sure, that was just a suggestion to prevent the crash. The thing is, as far as I can see, unlike QDrant, Chroma currently really does not like that use, and has a proper crash. 2023-07-13 17:23:29 chroma-server-1 | 2023-07-13 15:23:29 ERROR chromadb.server.fastapi Collection chat-documents-28763999-4538-4d90-918b-1ac90bbaa960 does not exist Accordingly, it felt wrong to me to trigger that crash "just" from calling "DoesCollectionExistAsync", whereas I would have been less uncomfortable with triggering that crash from searching a non existing collection. |
I'm in progress :)
My point here is that we shouldn't perform any check or creation action on
As long as Chroma server is not stopped/crashed because of that error, it should be fine. I don't mind listing collections as well, because I'm not sure there will be a case with big number of collections, that could impact the performance (although theoretically it's still possible). I just don't see big advantage in making that change (yet). Maybe we can do some performance/stress testing and check which approach works faster/more reliable. |
|
@dmytrostruk OK based on your last remarks I reverted my initial safeguards:
To fix the first issue, we have to decide whether to:
Addressing the second issue seems out of scope of this PR, and would require further investigations about the best way to test for collection existence in Chroma. Maybe change the existing error message though:
If this is to be used by "DoesCollectionExistAsync", it shouldn't probably log an error when collection does not exist. Since instrumentation was part of your last PRs, what do you suggest we use instead? |
|
Note that as of the end of today, Copilot Chat will be renamed and moved to its own repo: https://github.com/microsoft/chat-copilot You will want to close this PR and open a corresponding one in that repo instead. |
@glahaye Noted, I will make a new PR in the new repo. |
@dmytrostruk Any thoughts on this? |
|
@jsboige Sorry for delayed response. Regarding first issue, I think Regarding second issue about collection existence and logging, there are two cases:
So, we can log it as Regarding alignment between different connectors - we should definitely do that at some point. And I think that for
In this case it will be easier to differentiate two scenarios and react on them appropriately. Please let me know if that makes sense. |
|
@jsboige thanks for all the hard work! |
|
I'm going ahead and closing this PR. It's equivalent in the proper repo is microsoft/chat-copilot#62 |
### Motivation and Context <!-- Thank you for your contribution to the copilot-chat repo! Please help reviewers and future users, providing the following information: 1. Why is this change required? 2. What problem does it solve? 3. What scenario does it contribute to? 4. If it fixes an open issue, please link to the issue here. --> This is a continuation of PR microsoft/semantic-kernel#1989 from the previous repo. It accounts for [last comments](microsoft/semantic-kernel#1989 (comment)) from @dmytrostruk. Another PR will be made on SK repo for chroma connector updates. ### Description <!-- Describe your changes, the overall approach, the underlying design. These notes will help understanding how your code works. Thanks! --> This PR adds chroma DB as an alternative memory store available for the copilot chat. Because chroma client raises exceptions with non existing collections, safeguards were added to account for memory search performed before the collections were created. ### Contribution Checklist <!-- Before submitting this PR, please make sure: --> - [x] The code builds clean without any errors or warnings - [x] The PR follows the [Contribution Guidelines](https://github.com/microsoft/copilot-chat/blob/main/CONTRIBUTING.md) and the [pre-submission formatting script](https://github.com/microsoft/copilot-chat/blob/main/CONTRIBUTING.md#development-scripts) raises no violations - [ ] All unit tests pass, and I have added new tests where possible - [x] I didn't break anyone 😄 --------- Co-authored-by: Gil LaHaye <gillahaye@microsoft.com> Co-authored-by: Desmond Howard <dehoward@microsoft.com>
### Motivation and Context <!-- Thank you for your contribution to the semantic-kernel repo! Please help reviewers and future users, providing the following information: 1. Why is this change required? 2. What problem does it solve? 3. What scenario does it contribute to? 4. If it fixes an open issue, please link to the issue here. --> This is an attempt to account for the [following PR](#1989 (comment)). Chroma logs an error when calling DoesCollectionExistAsync on a non existing collection, it should log at debug level instead Also Volatile Store and QDrant return an empty collection when calling GetNearestMatchesAsync whereas Chroma throws an exception. This PR aligns behavior with other stores. ### Description <!-- Describe your changes, the overall approach, the underlying design. These notes will help understanding how your code works. Thanks! --> Align chroma store behavior with other common memory stores ### Contribution Checklist <!-- Before submitting this PR, please make sure: --> - [ ] The code builds clean without any errors or warnings - [ ] The PR follows the [SK Contribution Guidelines](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md) and the [pre-submission formatting script](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md#development-scripts) raises no violations - [ ] All unit tests pass, and I have added new tests where possible - [ ] I didn't break anyone 😄 --------- Co-authored-by: Dmytro Struk <13853051+dmytrostruk@users.noreply.github.com> Co-authored-by: Lee Miller <lemiller@microsoft.com>
…#2215) ### Motivation and Context <!-- Thank you for your contribution to the semantic-kernel repo! Please help reviewers and future users, providing the following information: 1. Why is this change required? 2. What problem does it solve? 3. What scenario does it contribute to? 4. If it fixes an open issue, please link to the issue here. --> This is an attempt to account for the [following PR](microsoft#1989 (comment)). Chroma logs an error when calling DoesCollectionExistAsync on a non existing collection, it should log at debug level instead Also Volatile Store and QDrant return an empty collection when calling GetNearestMatchesAsync whereas Chroma throws an exception. This PR aligns behavior with other stores. ### Description <!-- Describe your changes, the overall approach, the underlying design. These notes will help understanding how your code works. Thanks! --> Align chroma store behavior with other common memory stores ### Contribution Checklist <!-- Before submitting this PR, please make sure: --> - [ ] The code builds clean without any errors or warnings - [ ] The PR follows the [SK Contribution Guidelines](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md) and the [pre-submission formatting script](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md#development-scripts) raises no violations - [ ] All unit tests pass, and I have added new tests where possible - [ ] I didn't break anyone 😄 --------- Co-authored-by: Dmytro Struk <13853051+dmytrostruk@users.noreply.github.com> Co-authored-by: Lee Miller <lemiller@microsoft.com>
…#2215) ### Motivation and Context <!-- Thank you for your contribution to the semantic-kernel repo! Please help reviewers and future users, providing the following information: 1. Why is this change required? 2. What problem does it solve? 3. What scenario does it contribute to? 4. If it fixes an open issue, please link to the issue here. --> This is an attempt to account for the [following PR](microsoft#1989 (comment)). Chroma logs an error when calling DoesCollectionExistAsync on a non existing collection, it should log at debug level instead Also Volatile Store and QDrant return an empty collection when calling GetNearestMatchesAsync whereas Chroma throws an exception. This PR aligns behavior with other stores. ### Description <!-- Describe your changes, the overall approach, the underlying design. These notes will help understanding how your code works. Thanks! --> Align chroma store behavior with other common memory stores ### Contribution Checklist <!-- Before submitting this PR, please make sure: --> - [ ] The code builds clean without any errors or warnings - [ ] The PR follows the [SK Contribution Guidelines](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md) and the [pre-submission formatting script](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md#development-scripts) raises no violations - [ ] All unit tests pass, and I have added new tests where possible - [ ] I didn't break anyone 😄 --------- Co-authored-by: Dmytro Struk <13853051+dmytrostruk@users.noreply.github.com> Co-authored-by: Lee Miller <lemiller@microsoft.com>
### Motivation and Context <!-- Thank you for your contribution to the copilot-chat repo! Please help reviewers and future users, providing the following information: 1. Why is this change required? 2. What problem does it solve? 3. What scenario does it contribute to? 4. If it fixes an open issue, please link to the issue here. --> This is a continuation of PR microsoft/semantic-kernel#1989 from the previous repo. It accounts for [last comments](microsoft/semantic-kernel#1989 (comment)) from @dmytrostruk. Another PR will be made on SK repo for chroma connector updates. ### Description <!-- Describe your changes, the overall approach, the underlying design. These notes will help understanding how your code works. Thanks! --> This PR adds chroma DB as an alternative memory store available for the copilot chat. Because chroma client raises exceptions with non existing collections, safeguards were added to account for memory search performed before the collections were created. ### Contribution Checklist <!-- Before submitting this PR, please make sure: --> - [x] The code builds clean without any errors or warnings - [x] The PR follows the [Contribution Guidelines](https://github.com/microsoft/copilot-chat/blob/main/CONTRIBUTING.md) and the [pre-submission formatting script](https://github.com/microsoft/copilot-chat/blob/main/CONTRIBUTING.md#development-scripts) raises no violations - [ ] All unit tests pass, and I have added new tests where possible - [x] I didn't break anyone 😄 --------- Co-authored-by: Gil LaHaye <gillahaye@microsoft.com> Co-authored-by: Desmond Howard <dehoward@microsoft.com>
### Motivation and Context <!-- Thank you for your contribution to the copilot-chat repo! Please help reviewers and future users, providing the following information: 1. Why is this change required? 2. What problem does it solve? 3. What scenario does it contribute to? 4. If it fixes an open issue, please link to the issue here. --> This is a continuation of PR microsoft/semantic-kernel#1989 from the previous repo. It accounts for [last comments](microsoft/semantic-kernel#1989 (comment)) from @dmytrostruk. Another PR will be made on SK repo for chroma connector updates. ### Description <!-- Describe your changes, the overall approach, the underlying design. These notes will help understanding how your code works. Thanks! --> This PR adds chroma DB as an alternative memory store available for the copilot chat. Because chroma client raises exceptions with non existing collections, safeguards were added to account for memory search performed before the collections were created. ### Contribution Checklist <!-- Before submitting this PR, please make sure: --> - [x] The code builds clean without any errors or warnings - [x] The PR follows the [Contribution Guidelines](https://github.com/microsoft/copilot-chat/blob/main/CONTRIBUTING.md) and the [pre-submission formatting script](https://github.com/microsoft/copilot-chat/blob/main/CONTRIBUTING.md#development-scripts) raises no violations - [ ] All unit tests pass, and I have added new tests where possible - [x] I didn't break anyone 😄 --------- Co-authored-by: Gil LaHaye <gillahaye@microsoft.com> Co-authored-by: Desmond Howard <dehoward@microsoft.com>
Motivation and Context
Please help reviewers and future users, providing the following information:
Copilot sample application supports semantic memory stores, but currently only volatile, Qdrant and AzureCognitiveSearch are available
Adds open source Chroma to available memory store options
Building a chat copilot app relying on Chroma
Description
This PR attempts at adding Chroma as an available option for Copilot chat.
Adding the option is more or less straight forward, but it then raises 2 issues about missing memory collections that should be discussed before this PR can be merged:
The first has to do with the way SemanticTextMemory is implemented and used in copilot chat application: methods "SaveInformationAsync" and "SaveReferenceAsync" perform a check whether the target collection exist and create it if needed, whereas "SearchAsync" assumes the collection does exist. Accordingly, copilot chat application makes use of those without safeguards, and the later does not break because QDrant Memory store silences the corresponding exceptions whereas Chroma memory store throws them agressively, e.g through GetCollectionOrThrowAsync.
Accordingly, it might be worth considering:
For now, as a temporary mediating artefact, in order to prevent a crash from the copilot chat app, a "CollectionSafeMemoryStore" class was introduced to wrap the Chroma memory store, it tests for collection existence and creates it accordingly before running search queries.
Furthermore, in the chroma memory store, the DoesCollectionExistAsync method relies on the GetCollectionAsync private method, which triggers a chroma Error when the collection does not exist, which triggers a client exception, that is caught and logged as an error, and then muted. So even accounting for the previous issue, testing for collection existence ends up triggering and logging errors.
A distinct way to implement DoesCollectionExistAsync that does not trigger a chroma error relies on GetCollectionsAsync, iterating through the list of existing collections to find the target collection name.
Note that QDrant also relies on testing the get collection web method, but it does rely on a more graceful 40x response whereas chroma exhibit an actual exception and returns status 500, hinting that it is not the appropriate way to test for collection existence. It might be discussed whether it will pose a scaling issue when the list of collection increases a lot, but in the mean time this alternate implementation is proposed as part of this PR for now.
Contribution Checklist