【问题标题】:Using the chat bots response as a trigger word in Azure chatbot framework在 Azure 聊天机器人框架中使用聊天机器人响应作为触发词
【发布时间】:2025-12-18 22:35:01
【问题描述】:

我正在使用 Azure 中的机器人框架开发一个聊天机器人,我目前正在尝试使用我的聊天机器人响应作为用户触发词来将用户问题存储在表存储中,例如当机器人响应“我”时m 抱歉,我没有给你答案。请尝试改写你的问题”它记录了用户的第一个问题,例如“我如何飞行?”。

对此的任何帮助将不胜感激!

【问题讨论】:

  • when the bot responds with "I’m Sorry, I don’t have an answer for you. Please try and rephrase your question" it logs the users first question for example "How do I fly?". 您是否将机器人应用程序与 QnA maker 服务集成?您的机器人会在何时以及在什么条件下回复该特定消息?
  • 是的,当知识库不包含对用户查询的响应时,机器人会响应此消息。我想保存它,以便在机器人找不到响应时添加用户查询。 @FeiHan

标签: c# azure triggers botframework chatbot


【解决方案1】:

这是实现此目的的一种方法。您可以将每个问题文本存储在 Dictionary 中,并在未正确回答查询时将其发送到永久存储中。

首先,创建一个静态字典来保存值:

public static class Utils
{
    public static Dictionary<string, string> MessageDictionary = new Dictionary<string, string>();
}

其次,在您的消息控制器中,您可以存储来自每个用户的每条消息,当您的机器人收到消息时,如下所示:

    public async Task<HttpResponseMessage> Post([FromBody] Activity activity)
    {
        if (activity.Type == ActivityTypes.Message)
        {
            var userId = activity.From.Id;
            var message = activity.Text;
            if (!Utils.MessageDictionary.ContainsKey(userId))
            {
                ConnectorClient connector = new ConnectorClient(new System.Uri(activity.ServiceUrl));
                var reply = activity.CreateReply();

                //save all incoming messages to a dictionary
                Utils.MessageDictionary.Add(userId, message);

                // this can be removed it just confirms it was saved
                reply.Text = $"Message saved {userId} - {Utils.MessageDictionary[userId]}";
                await connector.Conversations.ReplyToActivityAsync(reply);
            }
            await Conversation.SendAsync(activity, () => new Dialogs.RootDialog());
        }

        else
        {
            HandleSystemMessage(activity);
        }

        var response = Request.CreateResponse(HttpStatusCode.OK);
        return response;
    }

Nest 创建一个继承自IBotToUser 的类,该类可以在消息发送给用户之前拦截它。如果返回给用户的文本是您提供的文本“对不起,我没有给您答案。请尝试改写您的问题”,我们将在此处将消息保存到永久存储:

public sealed class CustomBotToUser : IBotToUser
{
    private readonly IBotToUser inner;
    private readonly IConnectorClient client;

    public CustomBotToUser(IBotToUser inner, IConnectorClient client)
    {
        SetField.NotNull(out this.inner, nameof(inner), inner);
        SetField.NotNull(out this.client, nameof(client), client);
    }


    public async Task PostAsync(IMessageActivity message,
        CancellationToken cancellationToken = default(CancellationToken))
    {
        if (message.Text == "I’m Sorry, I don’t have an answer for you. Please try and rephrase your question")
        {
            //save to permanant storage here
            //if you would like to use a database
            //I have a very simple database bot example here
            //https://github.com/JasonSowers/DatabaseBotExample
        }

        //user is the recipient
        var userId = message.Recipient.Id;

        //remove entry from dictionary
        Utils.MessageDictionary.Remove(userId);

        //this is just for testing purposes and can be removed
        try
        {
            await inner.PostAsync($"{userId} - {Utils.MessageDictionary[userId]}");
        }
        catch (Exception e)
        {
            await inner.PostAsync($"No entry found for {userId}");
        }
        await inner.PostAsync((Activity) message, cancellationToken);
    }

    public IMessageActivity MakeMessage()
    {
        return inner.MakeMessage();
    }
}

您还需要使用 Autofac 在您的 Global.asax 中注册此类,使 Aplication_Start() 方法看起来像这样:

    protected void Application_Start()
    {
        GlobalConfiguration.Configure(WebApiConfig.Register);

        Conversation.UpdateContainer(
        builder =>
        {
            builder.RegisterModule(new AzureModule(Assembly.GetExecutingAssembly()));

            // Bot Storage: Here we register the state storage for your bot. 
            // Default store: volatile in-memory store - Only for prototyping!
            // We provide adapters for Azure Table, CosmosDb, SQL Azure, or you can implement your own!
            // For samples and documentation, see: [https://github.com/Microsoft/BotBuilder-Azure](https://github.com/Microsoft/BotBuilder-Azure)
            var store = new InMemoryDataStore();

            // Other storage options
            // var store = new TableBotDataStore("...DataStorageConnectionString..."); // requires Microsoft.BotBuilder.Azure Nuget package 
            // var store = new DocumentDbBotDataStore("cosmos db uri", "cosmos db key"); // requires Microsoft.BotBuilder.Azure Nuget package 

            builder.Register(c => store)
                .Keyed<IBotDataStore<BotData>>(AzureModule.Key_DataStore)
                .AsSelf()
                .SingleInstance();

            builder
                .RegisterType<CustomBotToUser>()
                .Keyed<IBotToUser>(typeof(LogBotToUser));
        });
    }

这是我分享的Global.asax 代码的重要部分:

        builder
            .RegisterType<CustomBotToUser>()
            .Keyed<IBotToUser>(typeof(LogBotToUser));

【讨论】: