Hello,
Yes, your speculation is correct.
In your code snippet, the ActionRunLLM class has an attribute self.llm_state. Since this attribute is defined within the class itself, it’s shared across all instances of the class.
When multiple conversations are handled concurrently by the action server, each conversation will essentially be using the same ActionRunLLM class instance. This means that when the run method is executed for different conversations, the self.llm_state attribute will be overwritten for each conversation, leading to unexpected behavior.
Here’s how you can fix this:
Make llm_state a local variable within the run method:
Python
class ActionRunLLM(Action):
def name(self) -> Text:
return "action_run_llm"
def other_method(self, llm_state):
# do something with llm_state
async def run(
self,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: Dict[Text, Any],
) -> List[Dict[Text, Any]]:
llm_state = tracker.get_slot("llm_state")
self.other_method(llm_state)
return []
By defining llm_state within the run method, it becomes a local variable specific to each conversation, preventing the issue of shared state.
Use a thread-local storage mechanism:
If you need to maintain some state across method calls within the same thread (for a specific conversation), you can use a thread-local storage mechanism. This allows you to store data that is specific to the current thread of execution.
Python
from threading import local
class ActionRunLLM(Action):
_thread_local = local()
def name(self) -> Text:
return "action_run_llm"
def other_method(self):
llm_state = self._thread_local.llm_state
# do something with llm_state
async def run(
self,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: Dict[Text, Any],
) -> List[Dict[Text, Any]]:
self._thread_local.llm_state = tracker.get_slot("llm_state")
self.other_method()
return []
This approach ensures that each thread (representing a conversation) has its own isolated llm_state.
Key takeaway:
When dealing with concurrent execution in an action server, be mindful of shared state within your action classes. Use techniques like local variables or thread-local storage to avoid unexpected behavior.
Best Regards