C# 在Cosmos DB中管理状态,而不是在内存中管理机器人到人的切换场景
我正在开发一个具有人工切换功能(人机对话)的机器人,机器人负责整个通信。用户可以启动与bot的通信,如果他对bot的响应不满意,他可以请求人工的进一步帮助 Bot能够使用第三方系统将用户连接到实时代理。Bot将对话框中的消息与回调url一起转发到此系统的API端点。此第三方系统使用回调机制传递代理在此指定url上编写的消息 我已经创建了一个API控制器端点,并将其作为回调url传递到此系统。当代理发送消息时,系统将通知此端点。它是一个简单的WebAPI控制器,与Bot框架没有直接联系 虽然我在Cosmos DB中维护了机器人的对话和用户状态,并且它有一些属性包含聊天连接状态,比如(ChatConnected、ChatClosed等)。现在,为了将这些消息通知传递给bot,我维护了两个并发字典,一个用于会话引用,另一个用于上下文C# 在Cosmos DB中管理状态,而不是在内存中管理机器人到人的切换场景,c#,.net-core,botframework,C#,.net Core,Botframework,我正在开发一个具有人工切换功能(人机对话)的机器人,机器人负责整个通信。用户可以启动与bot的通信,如果他对bot的响应不满意,他可以请求人工的进一步帮助 Bot能够使用第三方系统将用户连接到实时代理。Bot将对话框中的消息与回调url一起转发到此系统的API端点。此第三方系统使用回调机制传递代理在此指定url上编写的消息 我已经创建了一个API控制器端点,并将其作为回调url传递到此系统。当代理发送消息时,系统将通知此端点。它是一个简单的WebAPI控制器,与Bot框架没有直接联系 虽然我在C
- 会话引用有助于使用ContinueConversationAsync将代理消息从bot传递给用户
- TurnContext有助于在会话关闭时管理和更新这些属性的状态等,还可以使用它在某个非活动期后发送消息,因为最后一个回合有活动时间戳
private readonly ConcurrentDictionary<string, ITurnContext> TurnContextReferences;
private void AddTurnContext(ITurnContext turnContext, string sessionId)
{
if (turnContext != null && !string.IsNullOrWhiteSpace(sessionId))
{
//Add the Session Id and TurnContext to dictionary
TurnContextReferences.AddOrUpdate(sessionId, turnContext, (key, newValue) => turnContext);
}
}
任何需要仔细思考的想法都将受到欢迎。会话引用包含活动中信息的子集,而活动只是回合上下文的一个属性,因此会话引用包含回合上下文中信息的子集。保存会话引用和话轮上下文是多余的,因为如果保存话轮上下文,那么您就已经拥有了会话引用中的所有信息 也就是说,试图保存回合上下文是一个非常糟糕的主意。如果您需要一些不在会话引用中的信息,只需保存这些特定信息即可。例如,您可以创建自己的类,该类包含一个对话引用和一个时间戳,该时间戳表示来自该对话的最后一条消息的时间
public class ConversationInfo
{
[JsonProperty(PropertyName = "conversationReference")]
public ConversationReference ConversationReference { get; set; }
[JsonProperty(PropertyName = "timestamp")]
public DateTimeOffset Timestamp { get; set; }
}
h2h的意思是“人与人”还是“移交给人”还是什么?@KyleDelaney,它的意思是“人与人”,但“移交给人”也是正确的。@KyleDelaney,如果我的问题需要澄清或不清楚的话。请随意评论,我会改正的。谢谢谢谢你编辑你的问题。现在有点清楚了,但仍然很长。我不认为TJ能够看到你提到他的地方,因为他没有对这个问题发表评论,向特定的人寻求帮助通常不是一个好主意。谢谢你的回答。我知道保持turncontext并不是最好的做法,但问题是我需要更新需要turncontext的状态。这是错误的。保存状态所需的所有信息都在对话引用中。我建议你投票并接受这个答案,然后问一个新问题,解释为什么你认为你需要保存一个回合上下文来更新状态,并询问你如何在没有回合上下文的情况下更新状态。我认为ConversationReference包含使用Continue Conversation发送消息的相关信息,因为它服务URL等,但TurnContext具有实际的TurnState字典,该字典将更新并持久保存到Cosmos。另外,我不需要写一个新的状态属性或新的文档,这通常和直接写Cosmos一样好。文档中有一些例子。但是我必须在实际的bot状态下获取和更新属性,我使用自定义ConversationDataModel添加了一些附加属性。所以不要认为没有TurnContext是可能的。我今天添加了一个新的。一旦我有了一个通俗易懂的答案,我会接受去造福他人。谢谢,有一段时间我对这项工作分心了,但又回到了这项工作中。我已经实现了创建一个带有ConversationReference的模型类的建议,以及我需要从Activity类中获得的一些附加属性。因此,它变得重量轻,可串行化以存储在Cosmos DB中。谢谢。
//Inside API Controller
//Get the TurnContext from the Dictionary
TurnContextReferences.TryGetValue(sessionStateChangedEventData.SessionId, out ITurnContext turnContext);
if (turnContext != null)
{
var conversationData = await BotStateAccessors.ConversationStateAccessor.GetAsync(turnContext, () => new ConversationStateDataModel());
if (!conversationData.LiveAgentChatClosed)
{
conversationData.LiveAgentChatClosed = true;
await BotStateAccessors.ConversationStateAccessor.SetAsync(turnContext, conversationData);
await BotConversationState.SaveChangesAsync(turnContext);
}
}
public class ConversationInfo
{
[JsonProperty(PropertyName = "conversationReference")]
public ConversationReference ConversationReference { get; set; }
[JsonProperty(PropertyName = "timestamp")]
public DateTimeOffset Timestamp { get; set; }
}