Nous vous amènerons au point où vous pourrez créer Slack Bot et Line Bot en utilisant Watson même sans aucune connaissance.
[Mis à jour le 6 juin 2019] Ce message a été écrit à l'époque de Watson Conversation, le prédécesseur de Watson Assistant, et bien que les captures d'écran soient encore anciennes, les idées et les opérations de base de Watson Assitant Ne change pas, veuillez donc le lire comme le dernier environnement. </ font>
■ Je voudrais aborder les points suivants.
(1) Introduction à la réflexion, création d'un compte ② Méthode de conception du flux de dialogue en utilisant "Réservation d'hôtel" comme exemple ③ Utilisation du contexte, utilisation pratique de diverses fonctions non mentionnées dans le didacticiel ** ④ Comment créer un lien avec la logique Java ** ← Cet article ⑤ Créez un chatbot avec Watson + Java + Slack
Cette fois, dans la partie 4, je vais expliquer ** ④ Comment créer un lien avec la logique Java **.
Cliquez ici pour la dernière fois → ③ Utilisation du contexte, utilisation pratique de diverses fonctions non mentionnées dans le tutoriel.
Cette fois, nous lierons la logique Java et Watson Conversation.
Tout d'abord, créez un espace de travail simple pour vérifier le fonctionnement du programme.
Le ** fichier d'espace de travail (JSON) ** pour la vérification des opérations peut être téléchargé à partir de ce qui suit. https://riversun.github.io/wcs/org.riversun.WcsContextTestJa.zip
Si vous importez ceci, vous aurez un espace de travail avec seulement deux nœuds comme indiqué ci-dessous.
{
"context": {
"myParam01": "banana",
"myParam02": "apple",
"myParam03": 7777,
"myParam04": true,
"myParam05": {
"subParam01": "orange",
"subParam02": "lemon"
}
},
...
}
La réponse de ce nœud est
** Vous avez dit " Input.text?>". La valeur de la variable de contexte myRemoteParam est " Context ['myRemoteParam']?>". ** **
Renvoie le texte d'entrée de l'utilisateur et la variable de contexte ** myRemoteParam **.
Pour exécuter le flux de dialogue Watson Conversation à partir d'un programme Java, les ** WorkspaceId **, ** Username ** et ** Password ** de l'espace de travail sont requis.
Pour les voir, cliquez sur l'icône ** déployer ** sur le côté gauche de l'éditeur de boîte de dialogue comme indiqué ci-dessous pour ouvrir le volet ** déployer ** et sélectionnez l'onglet ** Informations d'identification **. Notez respectivement ** WorkspaceId **, ** Username ** et ** Password **. Vous les utiliserez plus tard dans votre programme Java.
L'exemple de code présenté ci-dessous peut être obtenu à partir du référentiel public suivant. https://github.com/riversun/watson-conversation-java-examples-ja
Vous trouverez ci-dessous le code qui envoie un message texte à Watson. Définissez également la variable Context de Java sur Watson Conversation.
WcsExample01.java
package org.example.wcs;
import org.riversun.wcs.WcsClient;
import com.ibm.watson.developer_cloud.conversation.v1.model.MessageResponse;
public class WcsExample01 {
private static final String WCS_USERNAME = "EDIT_ME_USERNAME_HERE";
private static final String WCS_PASSWORD = "EDIT_ME_PASSWORD_HERE";
private static final String WCS_WORKSPACE_ID = "EDIT_ME_WORKSPACE_ID_HERE";
public static void main(String[] args)
{
String wcsClientId = "dummy_user_id";
WcsClient watson = new WcsClient(WCS_USERNAME, WCS_PASSWORD, WCS_WORKSPACE_ID);
MessageResponse wcsWelcomeRes = watson.startConversation(wcsClientId);
System.out.println("FROM WATSON:" + wcsWelcomeRes.getTextConcatenated(""));
final String ctxKey = "myRemoteParam";
final String ctxValue = "I need you!";
watson.put(wcsClientId, ctxKey, ctxValue);
final String myMessage01 = "Hi! Watson";
MessageResponse wcsRes01 = watson.sendMessage(wcsClientId, myMessage01);
System.out.println("FROM WATSON:" + wcsRes01.getTextConcatenated(""));
}
}
private static final String WCS_USERNAME = "EDIT_ME_USERNAME_HERE";//username
private static final String WCS_PASSWORD = "EDIT_ME_PASSWORD_HERE";//password
private static final String WCS_WORKSPACE_ID = "EDIT_ME_WORKSPACE_ID_HERE";//workspaceId
Tout d'abord, définissez les informations d'identification pour accéder à Watson. Modifiez la partie suivante du code et remplacez-la par le ** workspaceId, username, password ** que vous avez vu précédemment dans le volet ** deploy **.
String wcsClientId = "dummy_user_id";
Lorsque vous travaillez avec Watson Conversation à l'aide de la bibliothèque d'assistance Donnez un ID utilisateur unique pour identifier l'utilisateur (ici, le nom de la variable est wcsClientId. Notez qu'il est complètement différent du nom d'utilisateur de l'espace de travail).
L'ID utilisateur n'est pas un concept propre à Watson Conversation, mais lorsque plusieurs utilisateurs interagissent avec le bot en même temps avec un chat bot, etc., comme indiqué ci-dessous, l'état d'interaction entre l'utilisateur et le chat bot est conservé pour chaque utilisateur (bien entendu). Doit être
Par conséquent, comme dans cet exemple, même un utilisateur peut accéder à Watson en attribuant un ID utilisateur pour plus de commodité. (À propos, dans le traitement interne de Watson, un ID appelé conversationId est attribué pour chaque session de conversation plutôt que pour chaque utilisateur.)
WcsClient watson = new WcsClient(username,password,workspaceId);
Nouveau la classe WcsClient. Cette classe communique avec la conversation watson
MessageResponse wcsWelcomeRes = watson.startConversation(wcsClientId);
System.out.println("FROM WATSON:" + wcsWelcomeRes.getTextConcatenated(""));
Le premier appel utilise la méthode ** # startConversation **. Je pense que le nœud de Watson Conversation est souvent un ** nœud de bienvenue **, mais ** #startConversation ** exécute ce ** nœud de bienvenue **. Recevez la réponse de Watson en tant que ** MessageResponse **.
** #getTextConcatenated ** sert à obtenir la réponse de Watson sous forme de chaîne.
(La réponse réelle de Watson est un type de tableau JSON String (= List
final String ctxKey = "myRemoteParam";
final String ctxValue = "I need you!";
watson.put(wcsClientId, ctxKey, ctxValue);
En utilisant ** watson.put (ID utilisateur, nom de variable de contexte, valeur de variable de contexte) **, la ** variable de contexte ** de Watson Conversation est définie du côté logique Java.
Ici, j'ai mis la valeur "** I need you! **" à la variable de contexte nommée ** myRemoteParam **.
À ce stade, le contexte est conservé uniquement dans la logique Java et il sera reflété du côté Watson lors du prochain accès à Watson à partir de la logique Java.
final String myMessage01 = "Hi! Watson";
MessageResponse wcsRes01 = watson.sendMessage(wcsClientId, myMessage01);
System.out.println("FROM WATSON:" + wcsRes01.getTextConcatenated(""));
Envoyez un message texte à Watson avec ** #sendMessage (ID utilisateur, message) **. À ce moment, la variable de contexte définie précédemment est reflétée du côté Watson.
Ici, le message "** Salut! Watson **" est envoyé depuis la logique Java.
À propos, la réponse du nœud ** Show_Context_node ** du côté Watson Conversation est Vous avez dit "**" Input.text?> ". La valeur de la variable de contexte myRemoteParam est " Context ['myRemoteParam']?>". ** "
Par conséquent, la réponse de Watson reçue du côté logique Java est la suivante.
réponse
「Hi!Vous avez dit «Watson». La valeur de la variable de contexte myRemoteParam est "J'ai besoin de vous!"est.
final String myMessage02 = "Hello! Watson";
String wcsResText = watson.sendMessageForText(wcsClientId, myMessage02);
System.out.println("FROM WATSON:" + wcsResText);
** # sendMessageForText ** envoie un message texte à Watson comme ** # sendMessage **, mais comme il reçoit également la réponse de Watson sous forme de texte, cette méthode est la plus simple pour envoyer et recevoir du texte.
De plus, si vous utilisez ** # sendMessageForText **, vous pouvez omettre ** # startConversation ** (c'est-à-dire exécuter *** startConversation ** dans le premier ** # sendMessageForText **). ), Si vous souhaitez créer un chatbot qui envoie et reçoit simplement du texte, la méthode ** # sendMessageForText ** est tout ce dont vous avez besoin.
Lorsque vous exécutez WcsExample01.java, il sera affiché sur la console comme ci-dessous
Résultat d'exécution
FROM WATSON:Bonjour, je suis Watson
FROM WATSON:「Hi!Vous avez dit «Watson». La valeur de la variable de contexte myRemoteParam est "J'ai besoin de vous!"est.
FROM WATSON:「Hello!Vous avez dit «Watson». La valeur de la variable de contexte myRemoteParam est "J'ai besoin de vous!"est.
Pour exécuter le code ci-dessus, définissez les bibliothèques dépendantes comme suit
maven
<dependency>
<groupId>org.riversun</groupId>
<artifactId>wcs</artifactId>
<version>1.0.2</version>
</dependency>
gradle
compile 'org.riversun:wcs:1.0.2'
Nous avons préparé watson-conversation-service-for-java comme bibliothèque d'aide pour l'exécution de Watson Conversation à partir de Java. Cette bibliothèque est une extension de la [bibliothèque de base] bien conçue (https://github.com/watson-developer-cloud/java-sdk) pour les chatbots multi-utilisateurs.
Voici un exemple d'obtention de la variable Context définie du côté Watson Conversation.
WcsExample02.java
package org.example.wcs;
import java.util.Map;
import org.riversun.wcs.WcsClient;
public class WcsExample02 {
private static final String WCS_USERNAME = "EDIT_ME_USERNAME_HERE";
private static final String WCS_PASSWORD = "EDIT_ME_PASSWORD_HERE";
private static final String WCS_WORKSPACE_ID = "EDIT_ME_WORKSPACE_ID_HERE";
public static void main(String[] args)
{
String wcsClientId = "dummy_user_id";
WcsClient watson = new WcsClient(WCS_USERNAME, WCS_PASSWORD, WCS_WORKSPACE_ID);
watson.startConversation(wcsClientId);
String myParam01 = watson.getAsString(wcsClientId, "myParam01");
System.out.println("myParam01=" + myParam01);
String myParam02 = watson.getAsString(wcsClientId, "myParam02");
System.out.println("myParam02=" + myParam02);
Integer myParam03 = watson.getAsInteger(wcsClientId, "myParam03");
System.out.println("myParam03=" + myParam03);
Boolean myParam04 = watson.getAsBoolean(wcsClientId, "myParam04");
System.out.println("myParam04=" + myParam04);
Map<String, Object> myParam05 = watson.getAsMap(wcsClientId, "myParam05");
String subParam01 = (String) myParam05.get("subParam01");
System.out.println("myParam05.subParam01=" + subParam01);
String subParam02 = (String) myParam05.get("subParam02");
System.out.println("myParam05.subParam02=" + subParam02);
}
}
Comme vu ci-dessus, les variables de contexte définies dans le nœud ** Welcome_node ** du côté Watson Conversation sont les suivantes.
{
"context": {
"myParam01": "banana",
"myParam02": "apple",
"myParam03": 7777,
"myParam04": true,
"myParam05": {
"subParam01": "orange",
"subParam02": "lemon"
}
}
}
Par exemple, pour obtenir la variable de contexte ci-dessus "** myParam01 **" du côté Java, procédez comme suit.
String myParam01 = watson.getAsString(Identifiant d'utilisateur, "myParam01");
De plus, dans le cas d'un objet composite (imbriqué) tel que la variable de contexte "** myParam05 **", obtenez-le sous la forme ** Map ** comme indiqué ci-dessous. Les données sont stockées imbriquées sous ** Map **.
**Map<String, Object> myParam05 = watson.getAsMap(wcsClientId, "myParam05");**
Le tableau ci-dessous montre également comment accéder à d'autres types.
** Méthode pour obtenir la variable de contexte de conversation Watson à partir de la logique Java **
Type de variable de contexte | Définition de la méthode | Type de retour |
---|---|---|
Type de chaîne | #getAsString(Identifiant d'utilisateur,Nom de la variable de contexte) | String |
Type numérique(Type entier) | #getAsInteger(Identifiant d'utilisateur,Nom de la variable de contexte) | Integer |
Type numérique(Type double) | #getAsDouble(Identifiant d'utilisateur,Nom de la variable de contexte) | Double |
Type booléen | #getAsBoolean(Identifiant d'utilisateur,Nom de la variable de contexte) | Boolean |
Type complexe(Si le JSON est imbriqué) | #getAsMap(Identifiant d'utilisateur,Nom de la variable de contexte) | Map |
Dans les deux exemples ci-dessus, nous avons principalement examiné l'envoi et la réception de texte (String) et l'échange de variables de contexte, mais vous pouvez en fait obtenir diverses informations entre Watson et la logique Java.
** Informations pouvant être obtenues **
information | La description |
---|---|
Input | Informations d'entrée utilisateur |
Output | Informations de sortie de Watson. Les informations autres que le texte peuvent être incluses de manière flexible dans la sortie |
Context | Informations sur les variables de contexte |
Intents | Intention déterminée par Watson en fonction du texte d'entrée de l'utilisateur(Plusieurs) |
Entities | Entité extraite par Watson en fonction du texte d'entrée de l'utilisateur(Plusieurs) |
Voici un exemple d'accès à diverses informations réellement incluses dans la réponse de Watson à partir de la logique Java.
public class WcsExample03 {
private static final String WCS_USERNAME = "EDIT_ME_USERNAME_HERE";
private static final String WCS_PASSWORD = "EDIT_ME_PASSWORD_HERE";
private static final String WCS_WORKSPACE_ID = "EDIT_ME_WORKSPACE_ID_HERE";
public static void main(String[] args)
{
String wcsClientId = "dummy_user_id";
WcsClient watson = new WcsClient(WCS_USERNAME, WCS_PASSWORD, WCS_WORKSPACE_ID);
MessageResponse res = watson.startConversation(wcsClientId);
Map<String, Object> context = res.getContext();
Map<String, Object> input = res.getInput();
String inputText = res.getInputText();
List<Intent> intents = res.getIntents();
List<Entity> entities = res.getEntities();
Map<String, Object> output = res.getOutput();
List<String> text = res.getText();
String textConcatenated = res.getTextConcatenated("");
System.out.println("Response JSON from Watson=\n" + res.toString());
}
}
Étant donné que Java a une bibliothèque d'assistance, il n'y a pas beaucoup de scènes où la logique Java analyse directement JSON, mais la réponse réelle de Watson Conversation est la suivante.
Réponse de Watson Conversation
{
"context": {
"system": {
"dialog_stack": [
{
"dialog_node": "root"
}
],
"dialog_turn_counter": 2.0,
"dialog_request_counter": 2.0,
"_node_output_map": {
"Welcome_Node": [
0.0
],
"Show_Context_Node": [
0.0
]
},
"branch_exited": true,
"branch_exited_reason": "completed"
},
"conversation_id": "xxxx-xxxxxx-xxxxx-xxxx",
"myParam05": {
"subParam01": "orange",
"subParam02": "lemon"
},
"myRemoteParam": "I need you!",
"myParam03": 7777.0,
"myParam04": true,
"myParam01": "banana",
"myParam02": "apple"
},
"entities": [],
"intents": [],
"output": {
"text": [
"「Hi!Vous avez dit «Watson». La valeur de la variable de contexte myRemoteParam est "J'ai besoin de vous!"est."
],
"nodes_visited": [
"Show_Context_Node"
],
"log_messages": []
},
"input": {
"text": "Hi!Watson"
}
}
Cette section est un petit plus.
C'est un peu difficile d'essayer l'interaction Watson Conversation avec juste une application console Java, j'ai donc créé une interface graphique simple.
・ Tout le code source est dans le référentiel suivant https://github.com/riversun/watson-examples-java-chatbot
・ Le flux de dialogue est le ** Chatbot de réservation d'hôtel (version améliorée) ** introduit Dernière fois. Vous pouvez télécharger le fichier d'espace de travail (JSON) à partir de ce qui suit. https://riversun.github.io/wcs/org.riversun.HotelReservationV2.zip
@SuppressWarnings("serial")
public class WatsonChat extends JFrame {
private static final String WATSON_CONVERSATION_USERNAME = "EDIT HERE";
private static final String WATSON_CONVERSATION_PASSWORD = "EDIT HERE";
private static final String WATCON_CONVERSATION_WORKSPACE_ID = "EDIT HERE";
private static final String WCS_CLIENT_ID = "dummy_user_id";
private static final int WIDTH_PX = 640;
private static final int HEIGHT_PX = 480;
private final WcsClient mWatson = new WcsClient(WATSON_CONVERSATION_USERNAME, WATSON_CONVERSATION_PASSWORD, WATCON_CONVERSATION_WORKSPACE_ID);
private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();
private final StringBuilder mSb = new StringBuilder();
private final JTextArea mTextArea = new JTextArea();
private final JTextField mTextBox = new JTextField("");
public static void main(String args[]) {
EDTHandler.post(new Runnable() {
public void run() {
System.setProperty("jsse.enableSNIExtension", "false");
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException |
IllegalAccessException | UnsupportedLookAndFeelException e) {
}
final WatsonChat frame = new WatsonChat();
frame.setVisible(true);
}
});
}
public WatsonChat() {
EDTHandler.post(new Runnable() {
@Override
public void run() {
buildGUI();
sendMessageOnFirst();
}
});
}
boolean onUserInputText(String userInputText) {
addTextIntoHistory("YOU:" + userInputText + "\n");
sendMessageToWatson(WCS_CLIENT_ID, userInputText);
return true;
}
void onClearButtonPressed() {
mSb.setLength(0);
EDTHandler.post(new Runnable() {
@Override
public void run() {
mTextArea.setText(mSb.toString());
}
});
mWatson.clearConversation(WCS_CLIENT_ID);
sendMessageOnFirst();
}
void sendMessageOnFirst() {
mExecutor.submit(new Runnable() {
@Override
public void run() {
MessageResponse welcomeRes = mWatson.startConversation(WCS_CLIENT_ID);
addTextIntoHistory("WATSON:" + welcomeRes.getTextConcatenated("") + "\n");
unlockTextBox();
}
});
}
void sendMessageToWatson(String wcsClientId, String userInputText) {
mExecutor.submit(new Runnable() {
@Override
public void run() {
final String watsonOutputText = mWatson.sendMessageForText(wcsClientId, userInputText);
addTextIntoHistory("WATSON:" + watsonOutputText);
unlockTextBox();
}
});
}
void addTextIntoHistory(String text) {
mSb.append(text);
EDTHandler.post(new Runnable() {
@Override
public void run() {
mTextArea.setText(mSb.toString());
}
});
}
void unlockTextBox() {
EDTHandler.post(new Runnable() {
@Override
public void run() {
mTextBox.setEditable(true);
mTextBox.requestFocus();
mTextBox.getCaret().setVisible(true);
mTextBox.setCaretPosition(0);
}
});
}
void buildGUI() {
setTitle("Chat with Watson");
setSize(WIDTH_PX, HEIGHT_PX);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JLinearLayout layoutParent = new JLinearLayout().setChildOrientation(Orientation.VERTICAL).setPadding(5);
final JLinearLayout layoutHeader = new JLinearLayout().setChildOrientation(Orientation.HORIZONTAL).setPadding(5, 0, 5, 0);
final JLinearLayout layoutCenter = new JLinearLayout().setChildOrientation(Orientation.VERTICAL).setPadding(5, 0, 5, 0);
final JLinearLayout layoutFooter = new JLinearLayout().setChildOrientation(Orientation.VERTICAL).setPadding(5);
JLabel lbChatHistory = new JLabel("Chat History:");
JButton btClear = new JButton("Clear");
btClear.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
onClearButtonPressed();
}
});
mTextArea.setLineWrap(true);
mTextArea.setMargin(new Insets(4, 4, 4, 4));
mTextArea.setEditable(false);
JScrollPane textAreaScroll = new JScrollPane(mTextArea);
textAreaScroll.setBorder(new LineBorder(Color.black, 1, true));
JLabel lbInputText = new JLabel("Input Text: (press ENTER-KEY to send)");
mTextBox.setBorder(new LineBorder(Color.black, 1, true));
mTextBox.setEditable(false);
Font font = mTextBox.getFont().deriveFont(Font.PLAIN, 20f);
mTextBox.setFont(font);
mTextBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
final String userInputText = mTextBox.getText();
if ("".equals(userInputText)) {
return;
}
mTextBox.setEditable(false);
final boolean consumed = onUserInputText(userInputText);
if (consumed) {
mTextBox.setText("");
}
}
});
addWindowListener(new WindowAdapter() {
public void windowOpened(WindowEvent e) {
mTextBox.requestFocus();
}
});
layoutHeader.addView(lbChatHistory, 1.0d);
layoutHeader.addView(btClear, 0d);
layoutCenter.addView(textAreaScroll);
layoutFooter.addView(lbInputText);
layoutFooter.addView(mTextBox);
layoutParent.addView(layoutHeader, 0.0d);
layoutParent.addView(layoutCenter, 1.0d);
layoutParent.addView(layoutFooter, 0.0d);
JPanel mainPanel = layoutParent.getAsPanel();
Container contentPane = getContentPane();
contentPane.add(mainPanel, BorderLayout.CENTER);
}
}
void sendMessageToWatson(String wcsClientId, String userInputText) {
mExecutor.submit(new Runnable() {
@Override
public void run() {
final String watsonOutputText = mWatson.sendMessageForText(wcsClientId, userInputText);
addTextIntoHistory("WATSON:" + watsonOutputText);
unlockTextBox();
}
});
}
La clé de ce code est principalement résumée ici.
Le texte saisi dans le champ de texte (en bas) est envoyé à Watson avec ** # sendMessageForText **. Le résultat est reçu sous forme de texte et affiché dans la zone de texte (en haut) de l'exigence d'historique.
La partie ** unlockTextBox ** déverrouille le champ de texte. Si vous ne verrouillez pas le champ de texte lors de la communication avec Watson, le texte suivant sera envoyé avant que le résultat ne soit renvoyé.
Le reste est une partie courante dans le traitement de l'interface graphique, mais c'est la partie de ** mExecutor.submit **, mais en utilisant Thread Executor, la communication avec Watson est effectuée dans un autre thread. Si vous synchronisez ici, l'interface graphique sera verrouillée lors de la communication avec Watson.
Cette fois, j'ai présenté comment lier la logique Java et Watson Conversation et exécuter le flux de dialogue de Watson Conversation à partir de Java.
--Exemple de référentiel de code https://github.com/riversun/watson-conversation-java-examples-ja
La prochaine fois souhaite se connecter avec des frontaux tels que Slack et LINE pour créer des applications de chat bot telles que Slack Bot et LINE Bot.
Recommended Posts