【问题标题】:Connection issues with Translator Text API version 3.0 - Microsoft Azure QnA chat bot文本翻译 API 3.0 版的连接问题 - Microsoft Azure QnA 聊天机器人
【发布时间】:2018-07-02 16:58:23
【问题描述】:

我想将我的 Azure QnA 聊天机器人与翻译层认知系统连接起来。我使用这个页面作为参考:https://docs.microsoft.com/en-us/azure/cognitive-services/translator/quickstart-csharp-translate

我在 C#Microsoft Azure 的在线代码编辑器 中进行此操作。

很遗憾,我无法连接到翻译层(至少看起来是这样的)。

当我尝试调试它时,我可以看到它停在这个特定的部分:

var response = await client.SendAsync(request);

var responseBody = await response.Content.ReadAsStringAsync();

我检查了网络超时错误,有很多 (20) 个。他们都说“向您的机器人发送此消息时出错:HTTP 状态代码 GatewayTimeout”。

我可以正常“build.cmd”,没有任何错误,当我尝试执行 Debug.WriteLine 或 Console.WriteLine 时,什么都没有打印出来(我什至在 VS 和 Emulator 中尝试过)

与上面的链接相比,我唯一不同的是我在私有方法之外定义了“主机”和“密钥”:

private static async Task<string> TranslateQuestionToEnglish (...)

所以,我想把任何单词翻译成英文。 当我取出这两行代码并使用静态值测试一个方法时,它显然可以工作(与 QnA 和其他一切一起)。

稍后,我在“Task MessageReceivedAsync”中调用此方法。

我创建了一个翻译认知服务,我从那里得到的唯一东西是“Keys”中的第一个密钥,并在此方法中使用它。 这是我从创建的认知服务中唯一需要的吗?

我不确定的另一件事,如果这件事有问题,那就是当我访问所有资源时,我可以看到我的 qnatestbot(网络应用程序机器人)和 translate_test(认知服务)的类型为“全球”位置,而我的 qnatestbot(应用程序服务)是“西欧”位置类型。他们在不同地区的事情会产生问题吗? 我应该把它们都放在西欧吗(因为我在德国)?

虽然,现在我查看 translate_test(cognitive services) 端点,我可以看到它是 ...api.congitivemicrosft.com/.../v1.0。 p>

但是,当我创建一个资源时,它是这样自动创建的,而我没有指定它? 我该如何改变它?

我希望有人成功地遇到了这样的问题并可以帮助我。提前谢谢你

【问题讨论】:

    标签: c# azure botframework chatbot


    【解决方案1】:

    我想将我的 Azure QnA 聊天机器人与翻译层认知系统连接起来。我使用这个页面作为参考:https://docs.microsoft.com/en-us/azure/cognitive-services/translator/quickstart-csharp-translate

    我尝试创建一个示例来满足您的要求:将用户输入翻译成英文并将翻译文本传递给 QnAMaker 对话框,该示例在本地和 Azure 上都可以正常工作,您可以参考。

    在 MessagesController 中:

    [BotAuthentication]
    public class MessagesController : ApiController
    {
    
        static string uri = "https://api.cognitive.microsofttranslator.com/translate?api-version=3.0&to=en";
        static string key = "{the_key}";
    
        /// <summary>
        /// POST: api/Messages
        /// receive a message from a user and send replies
        /// </summary>
        /// <param name="activity"></param>
        [ResponseType(typeof(void))]
        public virtual async Task<HttpResponseMessage> Post([FromBody] Activity activity)
        {
            // check if activity is of type message
            if (activity.GetActivityType() == ActivityTypes.Message)
            {
                if (activity.Text != null)
                {
                    var textinEN = await TranslateQuestionToEnglish(activity.Text);
                    activity.Text = textinEN;
                }
    
                await Conversation.SendAsync(activity, () => new RootDialog());
            }
            else
            {
                HandleSystemMessage(activity);
            }
            return new HttpResponseMessage(System.Net.HttpStatusCode.Accepted);
        }
    
        private static async Task<string> TranslateQuestionToEnglish(string text)
        {
            System.Object[] body = new System.Object[] { new { Text = text } };
            var requestBody = JsonConvert.SerializeObject(body);
    
            using (var client = new HttpClient())
            using (var request = new HttpRequestMessage())
            {
                request.Method = HttpMethod.Post;
                request.RequestUri = new Uri(uri);
                request.Content = new StringContent(requestBody, Encoding.UTF8, "application/json");
                request.Headers.Add("Ocp-Apim-Subscription-Key", key);
    
                var response = await client.SendAsync(request);
                var responseBody = await response.Content.ReadAsStringAsync();
    
                dynamic jsonResponse = JsonConvert.DeserializeObject(responseBody);
                var textinen = jsonResponse[0]["translations"][0]["text"].Value;
    
                return textinen;
            }
        }
    
        private Activity HandleSystemMessage(Activity message)
        {
            if (message.Type == ActivityTypes.DeleteUserData)
            {
                // Implement user deletion here
                // If we handle user deletion, return a real message
            }
            else if (message.Type == ActivityTypes.ConversationUpdate)
            {
                // Handle conversation state changes, like members being added and removed
                // Use Activity.MembersAdded and Activity.MembersRemoved and Activity.Action for info
                // Not available in all channels
            }
            else if (message.Type == ActivityTypes.ContactRelationUpdate)
            {
                // Handle add/remove from contact lists
                // Activity.From + Activity.Action represent what happened
            }
            else if (message.Type == ActivityTypes.Typing)
            {
                // Handle knowing tha the user is typing
            }
            else if (message.Type == ActivityTypes.Ping)
            {
            }
    
            return null;
        }
    }
    

    在对话框中:

    [Serializable]
    public class RootDialog : IDialog<object>
    {
        public async Task StartAsync(IDialogContext context)
        {
            /* Wait until the first message is received from the conversation and call MessageReceviedAsync 
            *  to process that message. */
            context.Wait(this.MessageReceivedAsync);
        }
    
        private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
        {
            /* When MessageReceivedAsync is called, it's passed an IAwaitable<IMessageActivity>. To get the message,
                *  await the result. */
            var message = await result;
    
            var qnaAuthKey = GetSetting("QnAAuthKey"); 
            var qnaKBId = Utils.GetAppSetting("QnAKnowledgebaseId");
            var endpointHostName = Utils.GetAppSetting("QnAEndpointHostName");
    
            // QnA Subscription Key and KnowledgeBase Id null verification
            if (!string.IsNullOrEmpty(qnaAuthKey) && !string.IsNullOrEmpty(qnaKBId))
            {
                // Forward to the appropriate Dialog based on whether the endpoint hostname is present
                if (string.IsNullOrEmpty(endpointHostName))
                    await context.Forward(new BasicQnAMakerPreviewDialog(), AfterAnswerAsync, message, CancellationToken.None);
                else
                    await context.Forward(new BasicQnAMakerDialog(), AfterAnswerAsync, message, CancellationToken.None);
            }
            else
            {
                await context.PostAsync("Please set QnAKnowledgebaseId, QnAAuthKey and QnAEndpointHostName (if applicable) in App Settings. Learn how to get them at https://aka.ms/qnaabssetup.");
            }
    
        }
    
        private async Task AfterAnswerAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
        {
            // wait for the next user message
            context.Wait(MessageReceivedAsync);
        }
    
        public static string GetSetting(string key)
        {
            var value = Utils.GetAppSetting(key);
            if (String.IsNullOrEmpty(value) && key == "QnAAuthKey")
            {
                value = Utils.GetAppSetting("QnASubscriptionKey"); // QnASubscriptionKey for backward compatibility with QnAMaker (Preview)
            }
            return value;
        }
    }
    
    // Dialog for QnAMaker Preview service
    [Serializable]
    public class BasicQnAMakerPreviewDialog : QnAMakerDialog
    {
        // Go to https://qnamaker.ai and feed data, train & publish your QnA Knowledgebase.
        // Parameters to QnAMakerService are:
        // Required: subscriptionKey, knowledgebaseId, 
        // Optional: defaultMessage, scoreThreshold[Range 0.0 – 1.0]
        public BasicQnAMakerPreviewDialog() : base(new QnAMakerService(new QnAMakerAttribute(RootDialog.GetSetting("QnAAuthKey"), Utils.GetAppSetting("QnAKnowledgebaseId"), "No good match in FAQ.", 0.5)))
        { }
    }
    
    // Dialog for QnAMaker GA service
    [Serializable]
    public class BasicQnAMakerDialog : QnAMakerDialog
    {
        // Go to https://qnamaker.ai and feed data, train & publish your QnA Knowledgebase.
        // Parameters to QnAMakerService are:
        // Required: qnaAuthKey, knowledgebaseId, endpointHostName
        // Optional: defaultMessage, scoreThreshold[Range 0.0 – 1.0]
        public BasicQnAMakerDialog() : base(new QnAMakerService(new QnAMakerAttribute(RootDialog.GetSetting("QnAAuthKey"), Utils.GetAppSetting("QnAKnowledgebaseId"), "No good match in FAQ.", 0.5, 1, Utils.GetAppSetting("QnAEndpointHostName"))))
        { }
    
    }
    

    测试结果:

    注意:如果在本地运行机器人应用程序,我们可以使用 ConfigurationManager.AppSettings["QnAKnowledgebaseId"]; 从 web.config 访问 QnAKnowledgebaseId 等设置。更多信息请参考this SO thread

    【讨论】:

    • 你为什么要在 MessagesController 中创建一个方法和其他所有内容。我试图在 dialog.cs 中创建所有这些?您是否也认为我上面解释的版本问题也会产生问题? (创建的认知服务的端点显示“v1.0”?
    • Why are you creating a method and everything else in MessagesController. I have tried to create all of them in dialog.cs? 怎么了?任何文档都表明我不能在 MessagesController 中执行此操作,并且必须像您一样将逻辑放入 dialog.cs 中?
    • Do you also think that the version thing that i explained above makes the problems as well? 您是否尝试使用您的密钥单独运行“Translate text with C#”并检查它是否可以按预期工作?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-03
    • 2018-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-31
    相关资源
    最近更新 更多