对 Watson Assistant V2 中的任何查询获得相同的响应:Watson-Unity-SDK

Getting Same response to any query in Watson Assistant V2 : Watson-Unity-SDK

我刚到了可以使用 Unity 设置 Watson Assistant V2 并尝试与我使用单一技能创建的助手交谈的地步。我需要进一步的帮助来设置助手以使用我的 Unity 应用程序。

在助手的 V1 中,可以定位工作区,并且响应返回意图、访问的节点等。我的查询得到了正确处理,响应与 IBM 云仪表板中 "try it" 应用程序的响应相同。

虽然在新版本中,我对发送给助手的任何查询都得到了相同的响应。我如何定位正确的技能或将正确的设置传递给助手以获得正确的响应?

IMAGE - Unity log showing assistant responses

[IMAGE - 在仪表板上试用 Google 助理][2]

我用来发送查询和获取响应的代码是:

IEnumerator TokenExample()
{
    //  Create IAM token options and supply the apikey. IamUrl is the URL used to get the 
    //  authorization token using the IamApiKey. It defaults to https://iam.bluemix.net/identity/token
    TokenOptions iamTokenOptions = new TokenOptions()
    {
        IamApiKey = "API KEY",
        IamUrl = "https://iam.bluemix.net/identity/token"

    };
    //  Create credentials using the IAM token options

    _credentials = new Credentials(iamTokenOptions, "https://gateway-fra.watsonplatform.net/assistant/api");
    while (!_credentials.HasIamTokenData())
        yield return null;

    _assistant = new Assistant(_credentials);
    _assistant.VersionDate = "2018-11-01";

    Debug.Log(_assistant.GetServiceID()); // returns "AssitantV2"

}

public void PingAssistantV2() // triggered from a button press in UI
{
    _assistant.CreateSession(OnCreateSession, OnFail, AssistantID); // Assistant ID is entered through the Inspector

}

public void OnCreateSession(SessionResponse response, Dictionary<string, object> customData)
{
    Log.Debug("ExampleAssistantV2.OnMessage()", "Assistant: Create Session Response: {0}", customData["json"].ToString());

    string _si = response.SessionId;
    Debug.Log("SessionID: " +_si);

    MessageInput mi = new MessageInput();
    mi.Text = Query.textComponent.text; // get user query from an input field in unity UI


    MessageRequest messageRequest = new MessageRequest()
    {
        Input = mi

    };
    Debug.LogFormat("<b> Query Sent: {0} </b>", Query.textComponent.text);
    if (response.SessionId != null ) _assistant.Message(OnMessage, OnFail, AssistantID, _si, messageRequest);
}

private void OnMessage(MessageResponse AssistantResponse, Dictionary<string, object> customData)
{
    Log.Debug("ExampleAssistant.OnMessage()", "Response: {0}", customData["json"].ToString());
    Debug.LogFormat("<b> SUCCESS </b>");
    Debug.Log(customData["json"].ToString());

    //  Convert resp to fsdata
    fsData fsdata = null;
    fsResult r = _serializer.TrySerialize(AssistantResponse.GetType(), AssistantResponse, out fsdata);
    if (!r.Succeeded)
        throw new WatsonException(r.FormattedMessages);

    //  Convert fsdata to MessageResponse
    IBM.WatsonDeveloperCloud.Assistant.v2.MessageResponse messageResponse = new IBM.WatsonDeveloperCloud.Assistant.v2.MessageResponse();
    object obj = messageResponse;
    r = _serializer.TryDeserialize(fsdata, obj.GetType(), ref obj);
    if (!r.Succeeded)
        throw new WatsonException(r.FormattedMessages);

    Response.text = AssistantResponse.Output.Generic.First().Text; // send response to unity UI text box

}

private void OnFail(RESTConnector.Error error, Dictionary<string, object> customData)
{
    Log.Debug("OnFail()", "Failed: {0}", error.ToString());
    Debug.LogFormat("<b> Failed </b>");
    Debug.Log(error.ToString());
}

编辑以解决@Taj 的评论

即使使用 SDK 中的 assistant V2 示例,问题仍然存在:

Wrong Unity Responses v/s appropriate responses in dashboardtrail

SDK中的例子采用的代码:

/**
* Copyright 2018 IBM Corp. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using IBM.Watson.DeveloperCloud.Connection;
using IBM.Watson.DeveloperCloud.Logging;
using IBM.Watson.DeveloperCloud.Utilities;
using IBM.WatsonDeveloperCloud.Assistant.v2;
using UnityEngine;
using TMPro;

namespace IBM.Watson.DeveloperCloud.Services.Assistant.v2
{
    public class ExampleAssistantV2 : MonoBehaviour
    {
        #region PLEASE SET THESE VARIABLES IN THE INSPECTOR
        [Space(10)]
        [Tooltip("The service URL (optional). This defaults to \"https://gateway.watsonplatform.net/assistant/api\"")]
        [SerializeField]
        private string _serviceUrl;
        [Tooltip("The assistantId to run the example.")]
        [SerializeField]
        private string _assistantId;
        [Tooltip("The version date with which you would like to use the service in the form YYYY-MM-DD.")]
        [SerializeField]
        private string _versionDate;
        [Header("CF Authentication")]
        [Tooltip("The authentication username.")]
        [SerializeField]
        private string _username;
        [Tooltip("The authentication password.")]
        [SerializeField]
        private string _password;
        [Header("IAM Authentication")]
        [Tooltip("The IAM apikey.")]
        [SerializeField]
        private string _iamApikey;
        [Tooltip("The IAM url used to authenticate the apikey (optional). This defaults to \"https://iam.bluemix.net/identity/token\".")]
        [SerializeField]
        private string _iamUrl;
        #endregion

        private Assistant _service;

        private bool _createSessionTested = false;
        private bool _messageTested = false;
        private bool _deleteSessionTested = false;
        private string _sessionId;

        public TMP_InputField query;
        public TextMeshProUGUI response;

        private void Start()
        {
            LogSystem.InstallDefaultReactors();
            Runnable.Run(CreateService());
        }



        private IEnumerator CreateService()
        {
            //  Create credential and instantiate service
            Credentials credentials = null;
            if (!string.IsNullOrEmpty(_username) && !string.IsNullOrEmpty(_password))
            {
                //  Authenticate using username and password
                credentials = new Credentials(_username, _password, _serviceUrl);
            }
            else if (!string.IsNullOrEmpty(_iamApikey))
            {
                //  Authenticate using iamApikey
                TokenOptions tokenOptions = new TokenOptions()
                {
                    IamApiKey = _iamApikey,
                    IamUrl = _iamUrl
                };

                credentials = new Credentials(tokenOptions, _serviceUrl);

                //  Wait for tokendata
                while (!credentials.HasIamTokenData())
                    yield return null;
            }
            else
            {
                throw new WatsonException("Please provide either username and password or IAM apikey to authenticate the service.");
            }

            _service = new Assistant(credentials);
            _service.VersionDate = _versionDate;

            Runnable.Run(SessionCreate());
        }

        private IEnumerator SessionCreate()
        {
            Log.Debug("ExampleAssistantV2.Examples()", "Attempting to CreateSession");
            _service.CreateSession(OnCreateSession, OnFail, _assistantId);

            while (!_createSessionTested)
            {
                yield return null;
            }

        }

        private IEnumerator Examples()
        {


            Log.Debug("ExampleAssistantV2.Examples()", "Attempting to Message");

            MessageInput mi = new MessageInput(); // construct a messgae input
            mi.Text = query.textComponent.text;


            MessageRequest messageRequest = new MessageRequest() // construct a message request
            {
                Input = mi

            };

            Log.Debug("ExampleAssistantV2.OnDeleteSession()", "<b>Query: </b> <b>{0}</b>", messageRequest.Input.Text);

            _service.Message(OnMessage, OnFail, _assistantId, _sessionId,messageRequest); // send a message request

            while (!_messageTested)
            {
                yield return null;
            }

            //Log.Debug("ExampleAssistantV2.Examples()", "Attempting to DeleteSession");
            //_service.DeleteSession(OnDeleteSession, OnFail, _assistantId, _sessionId);

            //while (!_deleteSessionTested)
            //{
            //    yield return null;
            //}

            //Log.Debug("ExampleAssistantV2.Examples()", "Assistant examples complete.");
        }

        private void OnDeleteSession(object response, Dictionary<string, object> customData)
        {
            Log.Debug("ExampleAssistantV2.OnDeleteSession()", "Session deleted.");
            _createSessionTested = true;
        }

        private void OnMessage(MessageResponse _response, Dictionary<string, object> customData)
        {
            _messageTested = true;
            response.text = _response.Output.Generic.First().Text; // trying to get response

            Log.Debug("ExampleAssistantV2.OnDeleteSession()", "<b>RESPONSE: </b> <b>{0}</b>", response.text);
        }

        private void OnCreateSession(SessionResponse response, Dictionary<string, object> customData)
        {
            Log.Debug("ExampleAssistantV2.OnCreateSession()", "Session: <b>{0}</b>", response.SessionId);
            _sessionId = response.SessionId;
            _createSessionTested = true;

        }

        private void OnFail(RESTConnector.Error error, Dictionary<string, object> customData)
        {
            Log.Debug("ExampleAssistantV2.OnFail()", "Call failed: {0}: {1}", error.ErrorCode, error.ErrorMessage);
        }

        public void PingAssitant ()
        {
            Runnable.Run(Examples());
        }
    }
}

我从你的日志中看到,你每次发消息都有一个新的sessionId。您无需在每次发送消息时都创建会话。会话应在对话期间持续存在。我将对 CreateSession 的调用移至您的 TokenExample() 并在您拥有 sessionId 后调用 PingAssistantV2()

string _si = "";

IEnumerator TokenExample()
{
    //  Create IAM token options and supply the apikey. IamUrl is the URL used to get the 
    //  authorization token using the IamApiKey. It defaults to https://iam.bluemix.net/identity/token
    TokenOptions iamTokenOptions = new TokenOptions()
    {
        IamApiKey = "API KEY",
        IamUrl = "https://iam.bluemix.net/identity/token"

    };
    //  Create credentials using the IAM token options

    _credentials = new Credentials(iamTokenOptions, "https://gateway-fra.watsonplatform.net/assistant/api");
    while (!_credentials.HasIamTokenData())
        yield return null;

    _assistant = new Assistant(_credentials);
    _assistant.VersionDate = "2018-11-01";

    Debug.Log(_assistant.GetServiceID()); // returns "AssitantV2"

    _assistant.CreateSession(OnCreateSession, OnFail, AssistantID); // Assistant ID is entered through the Inspector
}

public void PingAssistantV2() // triggered from a button press in UI
{
    MessageInput mi = new MessageInput();
    mi.Text = Query.textComponent.text; // get user query from an input field in unity UI

    MessageRequest messageRequest = new MessageRequest()
    {
        Input = mi

    };
    Debug.LogFormat("<b> Query Sent: {0} </b>", Query.textComponent.text);
    if (response.SessionId != null ) _assistant.Message(OnMessage, OnFail, AssistantID, _si, messageRequest);
}

public void OnCreateSession(SessionResponse response, Dictionary<string, object> customData)
{
    Log.Debug("ExampleAssistantV2.OnMessage()", "Assistant: Create Session Response: {0}", customData["json"].ToString());

    _si = response.SessionId;
    Debug.Log("SessionID: " +_si);

    PingAssistantV2();
}

private void OnMessage(MessageResponse AssistantResponse, Dictionary<string, object> customData)
{
    Log.Debug("ExampleAssistant.OnMessage()", "Response: {0}", customData["json"].ToString());
    Debug.LogFormat("<b> SUCCESS </b>");
    Debug.Log(customData["json"].ToString());

    //  Convert resp to fsdata
    fsData fsdata = null;
    fsResult r = _serializer.TrySerialize(AssistantResponse.GetType(), AssistantResponse, out fsdata);
    if (!r.Succeeded)
        throw new WatsonException(r.FormattedMessages);

    //  Convert fsdata to MessageResponse
    IBM.WatsonDeveloperCloud.Assistant.v2.MessageResponse messageResponse = new IBM.WatsonDeveloperCloud.Assistant.v2.MessageResponse();
    object obj = messageResponse;
    r = _serializer.TryDeserialize(fsdata, obj.GetType(), ref obj);
    if (!r.Succeeded)
        throw new WatsonException(r.FormattedMessages);

    Response.text = AssistantResponse.Output.Generic.First().Text; // send response to unity UI text box

}

private void OnFail(RESTConnector.Error error, Dictionary<string, object> customData)
{
    Log.Debug("OnFail()", "Failed: {0}", error.ToString());
    Debug.LogFormat("<b> Failed </b>");
    Debug.Log(error.ToString());
}

@taj 您在 https://github.com/watson-developer-cloud/unity-sdk/archive/develop.zip 的开发分支正在运行!感谢您致力于解决这个问题。我没有足够的代表来支持你的回答,但是,你好!

@taj 在 WDC Slack 频道上提供的工作代码:

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using IBM.Watson.DeveloperCloud.Connection;
using IBM.Watson.DeveloperCloud.Logging;
using IBM.Watson.DeveloperCloud.Utilities;
using IBM.WatsonDeveloperCloud.Assistant.v2;
using UnityEngine;
using TMPro;
namespace IBM.Watson.DeveloperCloud.Services.Assistant.v2
{
    public class ExampleAssistantV2b : MonoBehaviour
    {
        #region PLEASE SET THESE VARIABLES IN THE INSPECTOR
        [Space(10)]
        [Tooltip("The service URL (optional). This defaults to \"https://gateway.watsonplatform.net/assistant/api\"")]
        [SerializeField]
        private string _serviceUrl;
        [Tooltip("The assistantId to run the example.")]
        [SerializeField]
        private string _assistantId;
        [Tooltip("The version date with which you would like to use the service in the form YYYY-MM-DD.")]
        [SerializeField]
        private string _versionDate;
        [Header("CF Authentication")]
        [Tooltip("The authentication username.")]
        [SerializeField]
        private string _username;
        [Tooltip("The authentication password.")]
        [SerializeField]
        private string _password;
        [Header("IAM Authentication")]
        [Tooltip("The IAM apikey.")]
        [SerializeField]
        private string _iamApikey;
        [Tooltip("The IAM url used to authenticate the apikey (optional). This defaults to \"https://iam.bluemix.net/identity/token\".")]
        [SerializeField]
        private string _iamUrl;
        #endregion
        private Assistant _service;
        private string _sessionId;
        public TMP_InputField query;
        public TextMeshProUGUI response;
        public List<string> testQueryList;
        public int queryNum = 0;
        private void Start()
        {
            LogSystem.InstallDefaultReactors();
            testQueryList = new List<string>()
            {
                "",
                "What are your hours?",
                "Are you open on Christmas?",
                "I would like to make an appointment",
                "Friday at 12pm",
                "yes"
            };
            Runnable.Run(CreateService());
        }
        private IEnumerator CreateService()
        {
            //  Create credential and instantiate service
            Credentials credentials = null;
            if (!string.IsNullOrEmpty(_username) && !string.IsNullOrEmpty(_password))
            {
                //  Authenticate using username and password
                credentials = new Credentials(_username, _password, _serviceUrl);
            }
            else if (!string.IsNullOrEmpty(_iamApikey))
            {
                //  Authenticate using iamApikey
                TokenOptions tokenOptions = new TokenOptions()
                {
                    IamApiKey = _iamApikey,
                    IamUrl = _iamUrl
                };
                credentials = new Credentials(tokenOptions, _serviceUrl);
                //  Wait for tokendata
                while (!credentials.HasIamTokenData())
                    yield return null;
            }
            else
            {
                throw new WatsonException("Please provide either username and password or IAM apikey to authenticate the service.");
            }
            _service = new Assistant(credentials);
            _service.VersionDate = _versionDate;
            SessionCreate();
        }
        private void SessionCreate()
        {
            Log.Debug("ExampleAssistantV2.Examples()", "Attempting to CreateSession");
            _service.CreateSession(OnCreateSession, OnFail, _assistantId);
        }
        private void Examples()
        {
            Log.Debug("ExampleAssistantV2.Examples()", "Attempting to Message");
            MessageInput mi = new MessageInput(); // construct a messgae input
            //mi.Text = query.textComponent.text;
            mi.Text = testQueryList[queryNum];
            MessageRequest messageRequest = new MessageRequest() // construct a message request
            {
                Input = mi
            };
            Log.Debug("ExampleAssistantV2.OnDeleteSession()", "<b>Query: </b> <b>{0}</b>", messageRequest.Input.Text);
            _service.Message(OnMessage, OnFail, _assistantId, _sessionId, messageRequest); // send a message request
        }
        private void OnMessage(MessageResponse _response, Dictionary<string, object> customData)
        {
            //response.text = _response.Output.Generic[0].Text; // trying to get response
            string assistantResponse = _response.Output.Generic[0].Text; // trying to get response
            Log.Debug("ExampleAssistantV2.OnDeleteSession()", "<b>RESPONSE: </b> <b>{0}</b>", assistantResponse);
            queryNum++;
        }
        private void OnCreateSession(SessionResponse response, Dictionary<string, object> customData)
        {
            Log.Debug("ExampleAssistantV2.OnCreateSession()", "Session: <b>{0}</b>", response.SessionId);
            _sessionId = response.SessionId;
        }
        private void OnFail(RESTConnector.Error error, Dictionary<string, object> customData)
        {
            Log.Debug("ExampleAssistantV2.OnFail()", "Call failed: {0}: {1}", error.ErrorCode, error.ErrorMessage);
        }
        public void PingAssitant()
        {
            Examples();
        }
    }
}