I’ve been trying to find the ideal user experience for Web Requests, and in the process have developed a fairly reliable method for tracking user state across ephemeral user ID resets, which while not 100%, can be pretty darn close.
ephemeral_user_id = request.headers.get('Openai-Ephemeral-User-Id', 'unknown') conversation_id = request.headers.get('Openai-Conversation-Id', 'unknown') # Check if a unique user object exists for the given ephemeral_user_id or conversation_id async with unique_users_lock: user = None for unique_user in unique_users.values(): if ephemeral_user_id in unique_user.ephemeral_user_ids or conversation_id in unique_user.conversation_ids: user = unique_user break # If no matching user is found, create a new one if user is None: user = UniqueUser(conversation_id, ephemeral_user_id) unique_users[ephemeral_user_id] = user else: # Update the user's ephemeral_user_ids and conversation_ids user.ephemeral_user_ids.add(ephemeral_user_id) user.conversation_ids.add(conversation_id) user.update_last_seen() # Check for any other unique users with the same conversation_id or ephemeral_user_id and merge them keys_to_remove =  for key, unique_user in unique_users.items(): if user is not unique_user and (conversation_id in unique_user.conversation_ids or ephemeral_user_id in unique_user.ephemeral_user_ids): user.merge(unique_user) # Mark the merged user for removal from the unique_users dictionary keys_to_remove.append(key) # Remove the merged users from the unique_users dictionary for key in keys_to_remove: del unique_users[key]
It assumes a User object containing a list of ephemeral user ID’s and conversation ID’s that are associated with that unique user. And each time the ephemeral changes, assuming it changes and you’re still working with any o your conversations in your recent history, it will find the overlap and consolidate your various identifiers user an up-to-date Unique User object.
The edge case of all edge cases is your user comes back to ChatGPT, gets a new Ephemeral assigned, starts a new Conversation, and never returns. In this instance, you may technically have a duplicate user.