Migrer de Dialogflow ES vers les agents de conversation (Dialogflow CX)

Les agents de conversation (Dialogflow CX) vous offrent des outils et des commandes de conversation plus performants que les agents Dialogflow ES. Si votre agent Dialogflow ES gère des conversations complexes, envisagez de migrer vers les agents de conversation (Dialogflow CX).

Ce guide explique comment migrer un agent de Dialogflow ES vers les agents de conversation (Dialogflow CX). Ces deux types d'agents présentent de nombreuses différences fondamentales. Il n'existe donc pas de méthode simple pour effectuer cette migration.

Si vous utilisez ce guide pour une migration, veuillez nous faire part de vos commentaires positifs ou négatifs en cliquant sur le bouton Envoyer des commentaires ci-dessus. Nous utiliserons ces commentaires pour améliorer ce guide au fil du temps.

De manière générale, le processus recommandé est un processus hybride automatisé/manuel. Vous utiliserez un outil qui lit certaines de vos données d'agent Dialogflow ES, les écrit dans votre agent d'agent de conversation (Dialogflow CX) et capture une liste de tâches à faire. Vous recréez ensuite votre agent Conversational Agents (Dialogflow CX) complet en vous appuyant sur les bonnes pratiques, la liste de tâches et les données migrées par l'outil.

Comprendre les agents de conversation (Dialogflow CX)

Avant d'effectuer cette migration, vous devez avoir une bonne compréhension du fonctionnement des flux des agents conversationnels (Dialogflow CX). Vous pouvez commencer par:

Vous devez également lire d'autres documents de concept qui présentent des fonctionnalités dont vous aurez probablement besoin dans votre nouvel agent. Concentrez-vous sur les points suivants:

Comprendre les différences entre Dialogflow ES et les agents de conversation (Dialogflow CX)

Cette section présente les différences les plus importantes entre Dialogflow ES et les agents conversationnels (Dialogflow CX). Lorsque vous effectuerez les étapes de migration manuelles plus tard, consultez cette section pour obtenir des conseils.

Structure et contrôle du fil de conversation

Dialogflow ES fournit les éléments suivants pour contrôler la structure et le parcours de conversation:

  • Les intents constituent les éléments de base de l'agent. À tout moment de la conversation, un intent est mis en correspondance. Dans un sens, chaque intent est un nœud de la conversation.
  • Le contexte permet de contrôler la conversation. Le contexte permet de contrôler les intents qui peuvent être mis en correspondance à un moment donné. Le contexte expire après un certain nombre de tours de conversation. Par conséquent, ce type de contrôle peut être inexact pour les conversations longues.

Les agents de conversation (Dialogflow CX) fournissent une hiérarchie de ressources de structure et des commandes plus précises sur le parcours de conversation:

  • Les pages sont des nœuds de graphique pour la conversation. Les conversations des agents de conversation (Dialogflow CX) sont semblables aux machines à états. À tout moment de la conversation, une seule page est active. En fonction des données saisies par l'utilisateur final ou des événements, la conversation peut passer à une autre page. Il est courant qu'une page reste active pendant plusieurs tours de conversation.
  • Les flux sont des groupes de pages associées. Chaque flux doit gérer un sujet de conversation de haut niveau.
  • Les gestionnaires d'état permettent de contrôler les transitions et les réponses. Il existe trois types de gestionnaires d'état :
    • Route d'intent: contient un intent qui doit être mis en correspondance, des réponses facultatives et une transition de page facultative.
    • Route de condition: contient une condition à respecter, des réponses facultatives et une transition de page facultative.
    • Gestionnaire d'événements: contient un nom d'événement qui doit être appelé, des réponses facultatives et une transition de page facultative.
  • La portée permet de contrôler si un gestionnaire d'état peut être appelé. La plupart des gestionnaires sont associés à une page ou à un flux entier. Si la page ou le flux associés sont actifs, le gestionnaire est couvert et peut être appelé. Une route d'intent Conversational Agents (Dialogflow CX) dans le champ d'application est semblable à un intent Dialogflow ES avec un contexte d'entrée actif.

Lorsque vous concevez les flux et les pages de votre agent, assurez-vous de bien comprendre les conseils de la section "Flux" du guide de conception de l'agent.

Remplissage de formulaire

Dialogflow ES utilise le remplissage de cases pour collecter les paramètres requis auprès de l'utilisateur final:

  • Ces paramètres sont des paramètres d'intent marqués comme obligatoires.
  • La mise en correspondance de l'intent continue jusqu'à ce que tous les paramètres obligatoires soient collectés.
  • Vous pouvez définir une invite demandant à l'utilisateur final de fournir une valeur.

Les agents de conversation (Dialogflow CX) utilisent le remplissage de formulaires pour collecter les paramètres requis auprès de l'utilisateur final:

  • Ces paramètres sont associés à une page et sont collectés lorsque la page est active.
  • Vous utilisez des routes de condition pour les pages afin de déterminer si le remplissage du formulaire est terminé. Ces routes de condition mènent généralement à une autre page.
  • Vous pouvez définir une invite, ainsi que des gestionnaires de nouvelle invite pour gérer correctement plusieurs tentatives de collecte d'une valeur.

Transitions

Dialogflow ES passe automatiquement d'un intent à l'autre lorsque l'entrée de l'utilisateur final est mise en correspondance avec un intent. Cette correspondance ne peut se produire que pour les intents qui n'ont pas de contexte d'entrée ou qui ont un contexte d'entrée actif.

Les agents de conversation (Dialogflow CX) passent d'une page à l'autre lorsqu'un gestionnaire d'état dans le champ d'application répond à ses exigences et fournit une cible de transition. Grâce à ces transitions, vous pouvez guider de manière fiable les utilisateurs finaux dans les conversations. Vous pouvez contrôler ces transitions de plusieurs façons:

  • La mise en correspondance des intents peut déclencher une route d'intent.
  • Le respect d'une condition peut déclencher une route de condition.
  • L'appel d'un événement peut déclencher un gestionnaire d'événements.
  • Les gestionnaires de nouvelles invites peuvent provoquer une transition lorsque l'utilisateur final ne fournit pas de valeur après plusieurs tentatives.
  • Vous pouvez utiliser des cibles de transition symboliques pour les cibles de transition.

Réponses de l'agent

Les réponses des agents Dialogflow ES sont envoyées à l'utilisateur final lorsqu'un intent est mis en correspondance:

  • L'agent peut sélectionner un message pour la réponse parmi une liste de réponses possibles.
  • Les réponses peuvent être spécifiques à une plate-forme, qui peut utiliser des formats de réponse riches.
  • Les réponses peuvent être générées par des webhooks.

Les réponses des agents de conversation (Dialogflow CX) sont envoyées à l'utilisateur final lorsque l'exécution est appelée. Contrairement au traitement Dialogflow ES, qui implique toujours un webhook, le traitement des agents conversationnels (Dialogflow CX) peut ou non impliquer l'appel d'un webhook, selon que la ressource de traitement dispose d'un webhook configuré. Les réponses statiques et dynamiques basées sur les réponses webhook sont contrôlées par le traitement. Il existe plusieurs façons de créer des réponses d'agent:

  • Le traitement peut être fourni à n'importe quel type de gestionnaire d'état.
  • Plusieurs réponses peuvent être concatenatées lors d'un tour de conversation via la file d'attente de réponses. Dans certains cas, cette fonctionnalité peut simplifier la conception de votre agent.
  • Les agents de conversation (Dialogflow CX) ne sont pas compatibles avec les réponses intégrées spécifiques à une plate-forme. Cependant, il fournit plusieurs types de réponses, y compris une charge utile personnalisée qui peut être utilisée pour les réponses spécifiques à la plate-forme.

Paramètres

Les paramètres Dialogflow ES présentent les caractéristiques suivantes:

  • Défini uniquement dans les intents.
  • Défini par l'entrée de l'utilisateur final, les événements, les webhooks et les appels d'API.
  • Références dans les réponses, les invites de paramètres, le code du webhook et les valeurs de paramètre :
    • Le format de référence de base est $parameter-name.
    • Les références acceptent la syntaxe des suffixes .original, .partial et .recent.
    • Les références peuvent spécifier le contexte actif: #context-name.parameter-name.
    • Les références peuvent spécifier des paramètres d'événement: #event-name.parameter-name.

Les paramètres des agents de conversation (Dialogflow CX) présentent les caractéristiques suivantes:

  • Définis dans les intents et les formulaires de page.
  • Les paramètres d'intent et de formulaire sont propagés vers les paramètres de session, où ils peuvent être référencés pendant toute la durée de la session.
  • Défini par l'entrée de l'utilisateur final, les webhooks, le préréglage de paramètres de traitement et les appels d'API.
  • Références dans les réponses, les invites de paramètres, les gestionnaires d'invites de nouvelle tentative, les préréglages de paramètres et le code du webhook :
    • Le format de référence est $session.params.parameter-id pour les paramètres de session et $intent.params.parameter-id pour les paramètres d'intent.
    • Les références de paramètres d'intent sont compatibles avec la syntaxe des suffixes .original et .resolved. Cette syntaxe n'est pas compatible avec les paramètres de session.

Entités système

Dialogflow ES est compatible avec de nombreuses entités système.

Les agents conversationnels (Dialogflow CX) acceptent de nombreuses entités système, mais il existe quelques différences. Lors de la migration, vérifiez que les entités système que vous utilisez dans Dialogflow ES sont également compatibles avec les agents de conversation (Dialogflow CX) pour la même langue. Sinon, vous devez créer des entités personnalisées pour ces éléments.

Événements

Les événements Dialogflow ES présentent les caractéristiques suivantes:

  • Peut être appelé à partir d'appels d'API ou de webhooks pour correspondre à un intent.
  • Peut définir des paramètres.
  • Un petit nombre d'événements sont appelés par les plates-formes d'intégration.

Les événements des agents de conversation (Dialogflow CX) présentent les caractéristiques suivantes:

  • Peut être appelé à partir d'appels d'API ou de webhooks pour appeler un gestionnaire d'événements.
  • Impossible de définir des paramètres.
  • De nombreux événements intégrés peuvent être utilisés pour gérer l'absence d'entrée de l'utilisateur final, l'entrée de l'utilisateur final non reconnue, les paramètres invalidés par un webhook et les erreurs de webhook.
  • Les invocations peuvent être contrôlées par les mêmes règles de champ d'application que les autres gestionnaires d'état.

Intents intégrés

Dialogflow ES est compatible avec les intents intégrés suivants:

Vous trouverez ci-dessous la compatibilité des agents de conversation (Dialogflow CX) avec les intents intégrés:

  • Les intents de bienvenue sont acceptés.
  • Les intents de remplacement ne sont pas fournis. Utilisez plutôt les événements de non-correspondance dans les gestionnaires d'événements.
  • Pour les exemples négatifs, utilisez l'intent négatif par défaut.
  • Aucun intent de suivi prédéfini n'est fourni. Vous devez créer ces intents selon les besoins de votre agent. Par exemple, vous devrez probablement créer un intent pour gérer les réponses négatives à une question d'agent ("non", "non merci", "non, je ne le fais pas", etc.). Les intents des agents de conversation (Dialogflow CX) sont réutilisables dans votre agent. Vous n'avez donc pas besoin de les définir qu'une seule fois. L'utilisation de différents chemins d'intent pour ces intents courants, dans différents champs d'application, vous permet de mieux contrôler la conversation.

Webhooks

Les webhooks Dialogflow ES présentent les caractéristiques suivantes:

  • Vous pouvez configurer un service de webhook pour l'agent.
  • Chaque intent peut être marqué comme utilisant le webhook.
  • Aucune fonctionnalité intégrée n'est disponible pour gérer les erreurs de webhook.
  • Les actions ou noms d'intent sont utilisés par les webhooks pour déterminer dans quelle partie de l'agent ils ont été appelés.
  • La console fournit l'éditeur intégré.

Les webhooks des agents de conversation (Dialogflow CX) présentent les caractéristiques suivantes:

  • Vous pouvez configurer plusieurs services webhook pour l'agent.
  • Chaque fulfillment peut éventuellement spécifier un appel de webhook.
  • La gestion des erreurs des webhooks est intégrée.
  • Un webhook de traitement des agents de conversation (Dialogflow CX) contient une balise. Cette balise est semblable à une action Dialogflow ES, mais elle n'est utilisée que lors de l'appel de webhooks. Le service webhook peut utiliser ces balises pour déterminer à partir de quel emplacement de l'agent il a été appelé.
  • La console ne dispose pas d'un éditeur de code webhook intégré. Il est courant d'utiliser Cloud Functions, mais il existe de nombreuses options.

Lorsque vous passez aux agents de conversation (Dialogflow CX), vous devez modifier votre code de webhook, car les propriétés de requête et de réponse sont différentes.

Intégrations

Les intégrations Dialogflow ES et les intégrations d'agents de conversation (Dialogflow CX) sont compatibles avec différentes plates-formes. Pour les plates-formes compatibles avec les deux types d'agents, des différences de configuration peuvent exister.

Si l'intégration Dialogflow ES que vous utilisiez n'est pas compatible avec les agents conversationnels (Dialogflow CX), vous devrez peut-être changer de plate-forme ou implémenter l'intégration vous-même.

Autres fonctionnalités réservées aux agents de conversation (Dialogflow CX)

De nombreuses autres fonctionnalités ne sont disponibles que pour les agents de conversation (Dialogflow CX). Nous vous recommandons d'utiliser ces fonctionnalités lors de la migration. Exemple :

Bonnes pratiques

Avant de migrer, familiarisez-vous avec les bonnes pratiques de conception des agents conversationnels (Dialogflow CX). Bon nombre de ces bonnes pratiques pour les agents de conversation (Dialogflow CX) sont similaires aux bonnes pratiques pour Dialogflow ES, mais certaines sont propres aux agents de conversation (Dialogflow CX).

À propos de l'outil de migration

L'outil de migration copie l'essentiel des données Dialogflow ES dans votre agent Conversational Agents (Dialogflow CX) et écrit dans un fichier TODO une liste d'éléments à migrer manuellement. L'outil ne copie que les types d'entités personnalisées et les expressions d'entraînement d'intent. Nous vous conseillons de personnaliser cet outil en fonction de vos besoins spécifiques.

Code de l'outil de migration

Voici le code de l'outil. Vous devez examiner le code de cet outil pour comprendre son fonctionnement. Vous pouvez modifier ce code pour gérer des situations spécifiques dans votre agent. Vous allez exécuter cet outil dans les étapes ci-dessous.

// Package main implements the ES to CX migration tool.
package main

import (
	"context"
	"encoding/csv"
	"flag"
	"fmt"
	"os"
	"strings"
	"time"

	v2 "cloud.google.com/go/dialogflow/apiv2"
	proto2 "cloud.google.com/go/dialogflow/apiv2/dialogflowpb"
	v3 "cloud.google.com/go/dialogflow/cx/apiv3"
	proto3 "cloud.google.com/go/dialogflow/cx/apiv3/cxpb"
	"google.golang.org/api/iterator"
	"google.golang.org/api/option"
)

// Commandline flags
var v2Project *string = flag.String("es-project-id", "", "ES project")
var v3Project *string = flag.String("cx-project-id", "", "CX project")
var v2Region *string = flag.String("es-region-id", "", "ES region")
var v3Region *string = flag.String("cx-region-id", "", "CX region")
var v3Agent *string = flag.String("cx-agent-id", "", "CX region")
var outFile *string = flag.String("out-file", "", "Output file for CSV TODO items")
var dryRun *bool = flag.Bool("dry-run", false, "Set true to skip CX agent writes")

// Map from entity type display name to fully qualified name.
var entityTypeShortToLong = map[string]string{}

// Map from ES system entity to CX system entity
var convertSystemEntity = map[string]string{
	"sys.address":         "sys.address",
	"sys.any":             "sys.any",
	"sys.cardinal":        "sys.cardinal",
	"sys.color":           "sys.color",
	"sys.currency-name":   "sys.currency-name",
	"sys.date":            "sys.date",
	"sys.date-period":     "sys.date-period",
	"sys.date-time":       "sys.date-time",
	"sys.duration":        "sys.duration",
	"sys.email":           "sys.email",
	"sys.flight-number":   "sys.flight-number",
	"sys.geo-city-gb":     "sys.geo-city",
	"sys.geo-city-us":     "sys.geo-city",
	"sys.geo-city":        "sys.geo-city",
	"sys.geo-country":     "sys.geo-country",
	"sys.geo-state":       "sys.geo-state",
	"sys.geo-state-us":    "sys.geo-state",
	"sys.geo-state-gb":    "sys.geo-state",
	"sys.given-name":      "sys.given-name",
	"sys.language":        "sys.language",
	"sys.last-name":       "sys.last-name",
	"sys.street-address":  "sys.location",
	"sys.location":        "sys.location",
	"sys.number":          "sys.number",
	"sys.number-integer":  "sys.number-integer",
	"sys.number-sequence": "sys.number-sequence",
	"sys.ordinal":         "sys.ordinal",
	"sys.percentage":      "sys.percentage",
	"sys.person":          "sys.person",
	"sys.phone-number":    "sys.phone-number",
	"sys.temperature":     "sys.temperature",
	"sys.time":            "sys.time",
	"sys.time-period":     "sys.time-period",
	"sys.unit-currency":   "sys.unit-currency",
	"sys.url":             "sys.url",
	"sys.zip-code":        "sys.zip-code",
}

// Issues found for the CSV output
var issues = [][]string{
	{"Field", "Issue"},
}

// logIssue logs an issue for the CSV output
func logIssue(field string, issue string) {
	issues = append(issues, []string{field, issue})
}

// convertEntityType converts an ES entity type to CX
func convertEntityType(et2 *proto2.EntityType) *proto3.EntityType {
	var kind3 proto3.EntityType_Kind
	switch kind2 := et2.Kind; kind2 {
	case proto2.EntityType_KIND_MAP:
		kind3 = proto3.EntityType_KIND_MAP
	case proto2.EntityType_KIND_LIST:
		kind3 = proto3.EntityType_KIND_LIST
	case proto2.EntityType_KIND_REGEXP:
		kind3 = proto3.EntityType_KIND_REGEXP
	default:
		kind3 = proto3.EntityType_KIND_UNSPECIFIED
	}
	var expansion3 proto3.EntityType_AutoExpansionMode
	switch expansion2 := et2.AutoExpansionMode; expansion2 {
	case proto2.EntityType_AUTO_EXPANSION_MODE_DEFAULT:
		expansion3 = proto3.EntityType_AUTO_EXPANSION_MODE_DEFAULT
	default:
		expansion3 = proto3.EntityType_AUTO_EXPANSION_MODE_UNSPECIFIED
	}
	et3 := &proto3.EntityType{
		DisplayName:           et2.DisplayName,
		Kind:                  kind3,
		AutoExpansionMode:     expansion3,
		EnableFuzzyExtraction: et2.EnableFuzzyExtraction,
	}
	for _, e2 := range et2.Entities {
		et3.Entities = append(et3.Entities, &proto3.EntityType_Entity{
			Value:    e2.Value,
			Synonyms: e2.Synonyms,
		})
	}
	return et3
}

// convertParameterEntityType converts a entity type found in parameters
func convertParameterEntityType(intent string, parameter string, t2 string) string {
	if len(t2) == 0 {
		return ""
	}
	t2 = t2[1:] // remove @
	if strings.HasPrefix(t2, "sys.") {
		if val, ok := convertSystemEntity[t2]; ok {
			t2 = val
		} else {
			t2 = "sys.any"
			logIssue("Intent<"+intent+">.Parameter<"+parameter+">",
				"This intent parameter uses a system entity not supported by CX English agents. See the migration guide for advice. System entity: "+t2)
		}
		return fmt.Sprintf("projects/-/locations/-/agents/-/entityTypes/%s", t2)
	}
	return entityTypeShortToLong[t2]
}

// convertIntent converts an ES intent to CX
func convertIntent(intent2 *proto2.Intent) *proto3.Intent {
	if intent2.DisplayName == "Default Fallback Intent" ||
		intent2.DisplayName == "Default Welcome Intent" {
		return nil
	}

	intent3 := &proto3.Intent{
		DisplayName: intent2.DisplayName,
	}

	// WebhookState
	if intent2.WebhookState != proto2.Intent_WEBHOOK_STATE_UNSPECIFIED {
		logIssue("Intent<"+intent2.DisplayName+">.WebhookState",
			"This intent has webhook enabled. You must configure this in your CX agent.")
	}

	// IsFallback
	if intent2.IsFallback {
		logIssue("Intent<"+intent2.DisplayName+">.IsFallback",
			"This intent is a fallback intent. CX does not support this. Use no-match events instead.")
	}

	// MlDisabled
	if intent2.MlDisabled {
		logIssue("Intent<"+intent2.DisplayName+">.MlDisabled",
			"This intent has ML disabled. CX does not support this.")
	}

	// LiveAgentHandoff
	if intent2.LiveAgentHandoff {
		logIssue("Intent<"+intent2.DisplayName+">.LiveAgentHandoff",
			"This intent uses live agent handoff. You must configure this in a fulfillment.")
	}

	// EndInteraction
	if intent2.EndInteraction {
		logIssue("Intent<"+intent2.DisplayName+">.EndInteraction",
			"This intent uses end interaction. CX does not support this.")
	}

	// InputContextNames
	if len(intent2.InputContextNames) > 0 {
		logIssue("Intent<"+intent2.DisplayName+">.InputContextNames",
			"This intent uses context. See the migration guide for alternatives.")
	}

	// Events
	if len(intent2.Events) > 0 {
		logIssue("Intent<"+intent2.DisplayName+">.Events",
			"This intent uses events. Use event handlers instead.")
	}

	// TrainingPhrases
	var trainingPhrases3 []*proto3.Intent_TrainingPhrase
	for _, tp2 := range intent2.TrainingPhrases {
		if tp2.Type == proto2.Intent_TrainingPhrase_TEMPLATE {
			logIssue("Intent<"+intent2.DisplayName+">.TrainingPhrases",
				"This intent has a training phrase that uses a template (@...) training phrase type. CX does not support this.")
		}
		var parts3 []*proto3.Intent_TrainingPhrase_Part
		for _, part2 := range tp2.Parts {
			parts3 = append(parts3, &proto3.Intent_TrainingPhrase_Part{
				Text:        part2.Text,
				ParameterId: part2.Alias,
			})
		}
		trainingPhrases3 = append(trainingPhrases3, &proto3.Intent_TrainingPhrase{
			Parts:       parts3,
			RepeatCount: 1,
		})
	}
	intent3.TrainingPhrases = trainingPhrases3

	// Action
	if len(intent2.Action) > 0 {
		logIssue("Intent<"+intent2.DisplayName+">.Action",
			"This intent sets the action field. Use a fulfillment webhook tag instead.")
	}

	// OutputContexts
	if len(intent2.OutputContexts) > 0 {
		logIssue("Intent<"+intent2.DisplayName+">.OutputContexts",
			"This intent uses context. See the migration guide for alternatives.")
	}

	// ResetContexts
	if intent2.ResetContexts {
		logIssue("Intent<"+intent2.DisplayName+">.ResetContexts",
			"This intent uses context. See the migration guide for alternatives.")
	}

	// Parameters
	var parameters3 []*proto3.Intent_Parameter
	for _, p2 := range intent2.Parameters {
		if len(p2.Value) > 0 && p2.Value != "$"+p2.DisplayName {
			logIssue("Intent<"+intent2.DisplayName+">.Parameters<"+p2.DisplayName+">.Value",
				"This field is not set to $parameter-name. This feature is not supported by CX. See: https://cloud.google.com/dialogflow/es/docs/intents-actions-parameters#valfield.")
		}
		if len(p2.DefaultValue) > 0 {
			logIssue("Intent<"+intent2.DisplayName+">.Parameters<"+p2.DisplayName+">.DefaultValue",
				"This intent parameter is using a default value. CX intent parameters do not support default values, but CX page form parameters do. This parameter should probably become a form parameter.")
		}
		if p2.Mandatory {
			logIssue("Intent<"+intent2.DisplayName+">.Parameters<"+p2.DisplayName+">.Mandatory",
				"This intent parameter is marked as mandatory. CX intent parameters do not support mandatory parameters, but CX page form parameters do. This parameter should probably become a form parameter.")
		}
		for _, prompt := range p2.Prompts {
			logIssue("Intent<"+intent2.DisplayName+">.Parameters<"+p2.DisplayName+">.Prompts",
				"This intent parameter has a prompt. Use page form parameter prompts instead. Prompt: "+prompt)
		}
		if len(p2.EntityTypeDisplayName) == 0 {
			p2.EntityTypeDisplayName = "@sys.any"
			logIssue("Intent<"+intent2.DisplayName+">.Parameters<"+p2.DisplayName+">.EntityTypeDisplayName",
				"This intent parameter does not have an entity type. CX requires an entity type for all parameters..")
		}
		parameters3 = append(parameters3, &proto3.Intent_Parameter{
			Id:         p2.DisplayName,
			EntityType: convertParameterEntityType(intent2.DisplayName, p2.DisplayName, p2.EntityTypeDisplayName),
			IsList:     p2.IsList,
		})
		//fmt.Printf("Converted parameter: %+v\n", parameters3[len(parameters3)-1])
	}
	intent3.Parameters = parameters3

	// Messages
	for _, message := range intent2.Messages {
		m, ok := message.Message.(*proto2.Intent_Message_Text_)
		if ok {
			for _, t := range m.Text.Text {
				warnings := ""
				if strings.Contains(t, "#") {
					warnings += " This message may contain a context parameter reference, but CX does not support this."
				}
				if strings.Contains(t, ".original") {
					warnings += " This message may contain a parameter reference suffix of '.original', But CX only supports this for intent parameters (not session parameters)."
				}
				if strings.Contains(t, ".recent") {
					warnings += " This message may contain a parameter reference suffix of '.recent', but CX does not support this."
				}
				if strings.Contains(t, ".partial") {
					warnings += " This message may contain a parameter reference suffix of '.partial', but CX does not support this."
				}
				logIssue("Intent<"+intent2.DisplayName+">.Messages",
					"This intent has a response message. Use fulfillment instead."+warnings+" Message: "+t)
			}
		} else {
			logIssue("Intent<"+intent2.DisplayName+">.Messages",
				"This intent has a non-text response message. See the rich response message information in the migration guide.")
		}
		if message.Platform != proto2.Intent_Message_PLATFORM_UNSPECIFIED {
			logIssue("Intent<"+intent2.DisplayName+">.Platform",
				"This intent has a message with a non-default platform. See the migration guide for advice.")
		}
	}

	return intent3
}

// migrateEntities migrates ES entities to your CX agent
func migrateEntities(ctx context.Context) error {
	var err error

	// Create ES client
	var client2 *v2.EntityTypesClient
	options2 := []option.ClientOption{}
	if len(*v2Region) > 0 {
		options2 = append(options2,
			option.WithEndpoint(*v2Region+"-dialogflow.googleapis.com:443"))
	}
	client2, err = v2.NewEntityTypesClient(ctx, options2...)
	if err != nil {
		return err
	}
	defer client2.Close()
	var parent2 string
	if len(*v2Region) == 0 {
		parent2 = fmt.Sprintf("projects/%s/agent", *v2Project)
	} else {
		parent2 = fmt.Sprintf("projects/%s/locations/%s/agent", *v2Project, *v2Region)
	}

	// Create CX client
	var client3 *v3.EntityTypesClient
	options3 := []option.ClientOption{}
	if len(*v3Region) > 0 {
		options3 = append(options3,
			option.WithEndpoint(*v3Region+"-dialogflow.googleapis.com:443"))
	}
	client3, err = v3.NewEntityTypesClient(ctx, options3...)
	if err != nil {
		return err
	}
	defer client3.Close()
	parent3 := fmt.Sprintf("projects/%s/locations/%s/agents/%s", *v3Project, *v3Region, *v3Agent)

	// Read each V2 entity type, convert, and write to V3
	request2 := &proto2.ListEntityTypesRequest{
		Parent: parent2,
	}
	it2 := client2.ListEntityTypes(ctx, request2)
	for {
		var et2 *proto2.EntityType
		et2, err = it2.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			return err
		}
		fmt.Printf("Entity Type: %s\n", et2.DisplayName)

		if *dryRun {
			convertEntityType(et2)
			continue
		}

		request3 := &proto3.CreateEntityTypeRequest{
			Parent:     parent3,
			EntityType: convertEntityType(et2),
		}
		et3, err := client3.CreateEntityType(ctx, request3)
		entityTypeShortToLong[et3.DisplayName] = et3.Name
		if err != nil {
			return err
		}

		// ES and CX each have a quota limit of 60 design-time requests per minute
		time.Sleep(2 * time.Second)
	}
	return nil
}

// migrateIntents migrates intents to your CX agent
func migrateIntents(ctx context.Context) error {
	var err error

	// Create ES client
	var client2 *v2.IntentsClient
	options2 := []option.ClientOption{}
	if len(*v2Region) > 0 {
		options2 = append(options2,
			option.WithEndpoint(*v2Region+"-dialogflow.googleapis.com:443"))
	}
	client2, err = v2.NewIntentsClient(ctx, options2...)
	if err != nil {
		return err
	}
	defer client2.Close()
	var parent2 string
	if len(*v2Region) == 0 {
		parent2 = fmt.Sprintf("projects/%s/agent", *v2Project)
	} else {
		parent2 = fmt.Sprintf("projects/%s/locations/%s/agent", *v2Project, *v2Region)
	}

	// Create CX client
	var client3 *v3.IntentsClient
	options3 := []option.ClientOption{}
	if len(*v3Region) > 0 {
		options3 = append(options3,
			option.WithEndpoint(*v3Region+"-dialogflow.googleapis.com:443"))
	}
	client3, err = v3.NewIntentsClient(ctx, options3...)
	if err != nil {
		return err
	}
	defer client3.Close()
	parent3 := fmt.Sprintf("projects/%s/locations/%s/agents/%s", *v3Project, *v3Region, *v3Agent)

	// Read each V2 entity type, convert, and write to V3
	request2 := &proto2.ListIntentsRequest{
		Parent:     parent2,
		IntentView: proto2.IntentView_INTENT_VIEW_FULL,
	}
	it2 := client2.ListIntents(ctx, request2)
	for {
		var intent2 *proto2.Intent
		intent2, err = it2.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			return err
		}
		fmt.Printf("Intent: %s\n", intent2.DisplayName)
		intent3 := convertIntent(intent2)
		if intent3 == nil {
			continue
		}

		if *dryRun {
			continue
		}

		request3 := &proto3.CreateIntentRequest{
			Parent: parent3,
			Intent: intent3,
		}
		_, err := client3.CreateIntent(ctx, request3)
		if err != nil {
			return err
		}

		// ES and CX each have a quota limit of 60 design-time requests per minute
		time.Sleep(2 * time.Second)
	}
	return nil
}

// checkFlags checks commandline flags
func checkFlags() error {
	flag.Parse()
	if len(*v2Project) == 0 {
		return fmt.Errorf("Need to supply es-project-id flag")
	}
	if len(*v3Project) == 0 {
		return fmt.Errorf("Need to supply cx-project-id flag")
	}
	if len(*v2Region) == 0 {
		fmt.Printf("No region supplied for ES, using default\n")
	}
	if len(*v3Region) == 0 {
		return fmt.Errorf("Need to supply cx-region-id flag")
	}
	if len(*v3Agent) == 0 {
		return fmt.Errorf("Need to supply cx-agent-id flag")
	}
	if len(*outFile) == 0 {
		return fmt.Errorf("Need to supply out-file flag")
	}
	return nil
}

// closeFile is used as a convenience for defer
func closeFile(f *os.File) {
	err := f.Close()
	if err != nil {
		fmt.Fprintf(os.Stderr, "ERROR closing CSV file: %v\n", err)
		os.Exit(1)
	}
}

func main() {
	if err := checkFlags(); err != nil {
		fmt.Fprintf(os.Stderr, "ERROR checking flags: %v\n", err)
		os.Exit(1)
	}
	ctx := context.Background()
	if err := migrateEntities(ctx); err != nil {
		fmt.Fprintf(os.Stderr, "ERROR migrating entities: %v\n", err)
		os.Exit(1)
	}
	if err := migrateIntents(ctx); err != nil {
		fmt.Fprintf(os.Stderr, "ERROR migrating intents: %v\n", err)
		os.Exit(1)
	}
	csvFile, err := os.Create(*outFile)
	if err != nil {
		fmt.Fprintf(os.Stderr, "ERROR opening output file: %v", err)
		os.Exit(1)
	}
	defer closeFile(csvFile)
	csvWriter := csv.NewWriter(csvFile)
	if err := csvWriter.WriteAll(issues); err != nil {
		fmt.Fprintf(os.Stderr, "ERROR writing CSV output file: %v", err)
		os.Exit(1)
	}
	csvWriter.Flush()
}

Migration des types d'entités à l'aide d'un outil

Les types d'entités Dialogflow ES et les types d'entités des agents de conversation (Dialogflow CX) sont très similaires. Il s'agit donc du type de données le plus facile à migrer. L'outil copie simplement les types d'entités tels quels.

Migration des intents à l'aide d'un outil

Les intents Dialogflow ES et les intents des agents de conversation (Dialogflow CX) sont très différents.

Les intents Dialogflow ES sont utilisés comme éléments de base de l'agent. Ils contiennent des phrases d'entraînement, des réponses, un contexte pour le contrôle des conversations, des configurations de webhook, des événements, des actions et des paramètres de remplissage de cases.

Les agents de conversation (Dialogflow CX) ont déplacé la plupart de ces données vers d'autres ressources. Les intents des agents de conversation (Dialogflow CX) ne comportent que des phrases d'entraînement et des paramètres, ce qui les rend réutilisables dans l'agent. L'outil ne copie que ces deux types de données d'intent dans vos intents d'agents de conversation (Dialogflow CX).

Limites de l'outil de migration

L'outil de migration n'est pas compatible avec les éléments suivants:

  • Méga-agents: l'outil ne peut pas lire à partir de plusieurs sous-agents, mais vous pouvez l'appeler plusieurs fois pour chaque sous-agent.
  • Agents multilingues: vous devez modifier l'outil pour créer des expressions d'entraînement et des entrées d'entités multilingues.
  • Validation des entités système pour les langues autres que l'anglais : l'outil crée des éléments "À FAIRE" lorsqu'il détecte des entités système qui ne sont pas compatibles avec les agents conversationnels (Dialogflow CX), en supposant que l'anglais est la langue par défaut et qu'il utilise une région des États-Unis. La compatibilité des entités système varie selon la langue et la région. Pour les autres langues et régions, vous devez modifier l'outil pour effectuer cette vérification.

Étapes essentielles de la migration

Les sous-sections suivantes décrivent les étapes de migration à suivre. Vous n'avez pas besoin de suivre ces étapes manuelles dans l'ordre. Vous devrez peut-être même les effectuer simultanément ou dans un ordre différent. Lisez les étapes et commencez à planifier vos modifications avant de les apporter.

Après avoir exécuté l'outil de migration, vous pouvez recréer votre agent Conversational Agents (Dialogflow CX). Vous devrez toujours effectuer une bonne partie de la migration, mais la majeure partie des données saisies manuellement sera présente dans votre agent Conversational Agents (Dialogflow CX) et dans le fichier TODO.

Créer votre agent Conversational Agents (Dialogflow CX)

Si vous ne l'avez pas déjà fait, créez votre agent Conversational Agents (Dialogflow CX). Veillez à utiliser la même langue par défaut que celle de votre agent Dialogflow ES.

Exécuter l'outil de migration

Pour exécuter l'outil, procédez comme suit:

  1. Si ce n'est pas déjà fait, installez Go sur votre machine.
  2. Créez un répertoire pour le code de l'outil appelé migrate.
  3. Copiez le code de l'outil ci-dessus dans un fichier de ce répertoire appelé main.go.
  4. Modifiez le code si nécessaire pour votre cas.
  5. Créez un module Go dans ce répertoire. Exemple :

    go mod init migrate
    
  6. Installez les bibliothèques clientes Go Dialogflow ES V2 et Conversational Agents (Dialogflow CX) V3:

    go get cloud.google.com/go/dialogflow/apiv2
    go get cloud.google.com/go/dialogflow/cx/apiv3
    
  7. Assurez-vous d'avoir configuré l'authentification des bibliothèques clientes.

  8. Exécutez l'outil et enregistrez la sortie dans un fichier:

    go run main.go -es-project-id=<ES_PROJECT_ID> -cx-project-id=<CX_PROJECT_ID> \
    -cx-region-id=<CX_REGION_ID> -cx-agent-id=<CX_AGENT_ID> -out-file=out.csv
    

Résoudre les problèmes liés à l'outil de migration

Si des erreurs se produisent lorsque vous exécutez l'outil, vérifiez les points suivants:

Erreur Solution
Erreur RPC indiquant qu'une partie d'une phrase d'entraînement mentionne un paramètre non défini pour l'intent. Cela peut se produire si vous avez déjà utilisé l'API Dialogflow ES pour créer des paramètres d'intent de manière incohérente avec les expressions d'entraînement. Pour résoudre ce problème, renommez le paramètre Dialogflow ES dans la console, vérifiez que vos phrases d'entraînement utilisent correctement le paramètre, puis cliquez sur "Enregistrer". Cela peut également se produire si vos phrases d'entraînement font référence à des paramètres inexistants.

Après avoir corrigé les erreurs, vous devez supprimer les intents et les entités de l'agent Conversational Agents (Dialogflow CX) avant d'exécuter à nouveau l'outil de migration.

Transférer les données d'intent Dialogflow ES vers des agents de conversation (Dialogflow CX)

L'outil migre les phrases et les paramètres d'entraînement des intents vers les intents des agents de conversation (Dialogflow CX), mais de nombreux autres champs d'intent Dialogflow ES doivent être migrés manuellement.

Un intent Dialogflow ES peut nécessiter une page Conversational Agents (Dialogflow CX) correspondante, un intent Conversational Agents (Dialogflow CX) correspondant, ou les deux.

Si une correspondance d'intent Dialogflow ES est utilisée pour faire passer la conversation d'un nœud de conversation particulier à un autre, vous devez avoir deux pages dans votre agent associées à cet intent:

  • Page d'origine contenant la route d'intent, qui mène à la page suivante : la route d'intent de la page d'origine peut contenir des messages de traitement des agents conversationnels (Dialogflow CX) semblables aux réponses d'intent Dialogflow ES. Cette page peut contenir de nombreux chemins d'intent. Lorsque la page d'origine est active, ces routes d'intent peuvent faire passer la conversation vers de nombreux chemins possibles. De nombreux intents Dialogflow ES partageront la même page d'origine des agents de conversation (Dialogflow CX) correspondante.
  • La page suivante, qui est la cible de transition pour l'itinéraire de l'intent sur la page d'origine : le traitement de l'entrée des agents de conversation (Dialogflow CX) pour la page suivante peut comporter des messages de traitement des agents de conversation (Dialogflow CX) semblables aux réponses d'intent de Dialogflow ES.

Si un intent Dialogflow ES contient des paramètres obligatoires, vous devez créer une page d'agents conversationnels (Dialogflow CX) correspondante avec les mêmes paramètres dans un formulaire.

Il est courant qu'un intent Conversational Agents (Dialogflow CX) et une page Conversational Agents (Dialogflow CX) partagent la même liste de paramètres, ce qui signifie qu'un seul intent Dialogflow ES a une page Conversational Agents (Dialogflow CX) et un intent Conversational Agents (Dialogflow CX) correspondants. Lorsqu'un intent d'agent conversationnel (Dialogflow CX) avec des paramètres dans une route d'intent est mis en correspondance, la conversation passe souvent à une page avec les mêmes paramètres. Les paramètres extraits de la correspondance d'intent sont propagés vers les paramètres de session, qui peuvent être utilisés pour remplir partiellement ou entièrement les paramètres du formulaire de la page.

Les intents de remplacement et les intents de suivi prédéfinis n'existent pas dans les agents de conversation (Dialogflow CX). Consultez la section Intents intégrés.

Le tableau suivant décrit comment mapper des données d'intent spécifiques de Dialogflow ES sur des ressources d'agents de conversation (Dialogflow CX) :

Données d'intent Dialogflow ES Données des agents de conversation (Dialogflow CX) correspondantes Action requise
Phrases d'entraînement Phrases d'entraînement d'intent Migré par outil. L'outil vérifie la compatibilité avec les entités système et crée des éléments "À FAIRE" pour les entités système non compatibles.
Réponses de l'agent Messages de réponse de traitement Consultez les réponses de l'agent.
Contexte pour le contrôle de la conversation Aucun Consultez la section Structure et contrôle du fil de conversation.
Paramètre du webhook Configuration du webhook de traitement Voir Webhooks.
Événements Gestionnaires d'événements au niveau du flux ou de la page Voir Événements.
Actions Balises de webhook de traitement Voir Webhooks.
Paramètres Paramètres d'intent et/ou paramètres de formulaire de page Migration vers les paramètres d'intent par outil. Si les paramètres sont obligatoires, l'outil crée des tâches à effectuer pour éventuellement migrer vers une page. Consultez la section Paramètres.
Requêtes de paramètres Invites de paramètres de formulaire de page Voir Remplissage de formulaires.

Créer des flux

Créez un flux pour chaque sujet de conversation général. Les sujets de chaque flux doivent être distincts, afin que la conversation ne passe pas fréquemment d'un flux à l'autre.

Si vous utilisiez un méga-agent, chaque sous-agent doit devenir un ou plusieurs flux.

Commencer par des parcours de conversation de base

Il est préférable de tester votre agent avec le simulateur pendant que vous itérez sur les modifications. Vous devez donc vous concentrer d'abord sur les parcours de conversation de base au début de la conversation, puis effectuer des tests à mesure que vous apportez des modifications. Une fois que vous avez fait fonctionner ces éléments, passez à des chemins de conversation plus détaillés.

Gestionnaires d'état au niveau du flux et au niveau de la page

Lorsque vous créez des gestionnaires d'état, réfléchissez à la nécessité de les appliquer au niveau du flux ou de la page. Un gestionnaire au niveau du flux est couvert chaque fois que le flux (et donc toute page du flux) est actif. Un gestionnaire au niveau de la page n'est dans le champ d'application que lorsque la page en question est active. Les gestionnaires au niveau du flux sont semblables aux intents Dialogflow ES sans contexte d'entrée. Les gestionnaires au niveau de la page sont semblables aux intents Dialogflow ES avec contexte d'entrée.

Code webhook

Les propriétés de requête et de réponse du webhook sont différentes pour les agents de conversation (Dialogflow CX). Consultez la section Webhooks.

Connecteurs de connaissances

Les agents de conversation (Dialogflow CX) ne sont pas encore compatibles avec les connecteurs de connaissances. Vous devrez les implémenter en tant qu'intents normaux ou attendre que les agents de conversation (Dialogflow CX) acceptent les connecteurs de connaissances.

Paramètres de l'agent

Vérifiez les paramètres de l'agent Dialogflow ES et ajustez les paramètres de l'agent Conversational Agents (Dialogflow CX) si nécessaire.

Utiliser le fichier TODO

L'outil de migration génère un fichier CSV. Les éléments de cette liste sont axés sur des données spécifiques qui peuvent nécessiter une attention particulière. Importez ce fichier dans une feuille de calcul. Résolvez chaque élément de la feuille de calcul, en utilisant une colonne pour marquer la fin.

Migration de l'utilisation de l'API

Si votre système utilise l'API Dialogflow ES pour les appels au moment de l'exécution ou de la conception, vous devrez mettre à jour ce code pour utiliser l'API des agents conversationnels (Dialogflow CX). Si vous n'utilisez que les appels de détection d'intent au moment de l'exécution, cette mise à jour devrait être assez simple.

Intégrations

Si votre agent utilise des intégrations, consultez la section sur les intégrations et apportez les modifications nécessaires.

Les sous-sections suivantes décrivent les étapes de migration recommandées.

Validation

Utilisez la validation de l'agent pour vérifier qu'il respecte les bonnes pratiques.

Tests

Lorsque vous effectuez les étapes de migration manuelles ci-dessus, vous devez tester votre agent avec le simulateur. Une fois que votre agent semble fonctionner, vous devez comparer les conversations entre vos agents Dialogflow ES et vos agents de conversation (Dialogflow CX), et vérifier que le comportement est similaire ou amélioré.

Lorsque vous testez ces conversations avec le simulateur, vous devez créer des scénarios de test pour éviter les futures régressions.

Environnements

Passez en revue vos environnements Dialogflow ES et mettez à jour vos environnements d'agents de conversation (Dialogflow CX) si nécessaire.