Migrazione da Dialogflow ES a CX

Gli agenti Dialogflow CX ti forniscono controlli e strumenti più potenti per le conversazioni rispetto agli agenti Dialogflow ES. Se l'agente Dialogflow ES gestisce conversazioni complesse, ti consigliamo di eseguire la migrazione a Dialogflow CX.

Questa guida descrive come eseguire la migrazione di un agente da Dialogflow ES a Dialogflow CX. Questi due tipi di agenti presentano molte differenze fondamentali, perciò non esiste un modo semplice per eseguire questa migrazione.

Se utilizzi questa guida per una migrazione, invia un feedback positivo o negativo facendo clic sul Pulsante Invia feedback in alto. Utilizzeremo questo feedback per migliorare la guida nel tempo.

A livello generale, il processo consigliato è un processo ibrido automatizzato/manuale. Utilizzerai uno strumento che legge alcuni dati dell'agente Dialogflow ES, scrive i dati nell'agente Dialogflow CX, e acquisisce un elenco attività. Quindi ricrei il tuo agente CX completo seguendo le best practice, l'elenco delle cose da fare, e i dati migrati dallo strumento.

Informazioni su Dialogflow CX

Prima di tentare questa migrazione, dovresti avere una buona conoscenza di come funziona Dialogflow CX. Puoi iniziare da qui:

  1. Informazioni di base
  2. Video introduttivi
  3. Guide rapide

Dovresti inoltre leggere ulteriori documenti concettuali con funzionalità che probabilmente serviranno nel tuo nuovo agente. Concentrati sui seguenti aspetti:

Comprendere le differenze tra ES e CX

Questa sezione elenca le differenze più importanti tra Dialogflow ES e CX. Quando eseguirai i passaggi di migrazione manuale in un secondo momento, consulta questa sezione per istruzioni.

Controllo della struttura e del percorso di conversazione

ES fornisce quanto segue per il controllo della struttura e del percorso di conversazione:

  • Intenzioni sono utilizzati come componenti di base dell'agente. In qualsiasi momento della conversazione, la corrispondenza di un intent, e, in un certo senso, ogni intent è un nodo per la conversazione.
  • Contesto viene utilizzato per controllare la conversazione. Il contesto viene utilizzato per controllare quali intent possono essere abbinati in un determinato momento. Il contesto scade dopo un certo numero di turni di conversazione, quindi questo tipo di controllo può non essere preciso per le conversazioni lunghe.

CX fornisce una gerarchia di risorse della struttura e controlli più precisi sul percorso della conversazione:

  • Pagine sono nodi grafico per la conversazione. Le conversazioni CX sono simili alle macchine di stato. In qualsiasi momento della conversazione, una pagina è attiva. In base all'input o agli eventi dell'utente finale, la conversazione può passare a un'altra pagina. È comune che una pagina rimanga attiva per più turni di conversazione.
  • Flussi sono gruppi di pagine correlate. Ogni flusso deve gestire un argomento di conversazione di alto livello.
  • Gestori di stato per controllare le transizioni e le risposte. Esistono tre tipi di gestori dello stato:
    • Route dell'intent: contiene un intent che deve essere abbinato, risposte facoltative e transizione facoltativa delle pagine.
    • Route condizione: contiene una condizione che deve essere soddisfatta. risposte facoltative e transizione facoltativa delle pagine.
    • Gestore eventi: contiene un nome evento che deve essere richiamato, risposte facoltative e transizione facoltativa delle pagine.
  • Ambito viene utilizzato per controllare se è possibile chiamare un gestore di stati. La maggior parte dei gestori è associata a una pagina o a un intero flusso. Se la pagina o il flusso associato è attivo, il gestore è incluso nell'ambito e può essere chiamato. Una route per intent CX che rientra nell'ambito è simile a un intent ES con un contesto di input che sia attivo.

Quando progetti i flussi e le pagine dell'agente, assicurati di comprendere i consigli sezione relativa al flusso della guida alla progettazione dell'agente.

Compilazione di moduli

Usi ES riempimento degli slot per raccogliere i parametri richiesti dall'utente finale:

  • Questi parametri sono parametri di intent contrassegnati come obbligatori.
  • L'intent continua a essere abbinato fino a quando non vengono raccolti tutti i parametri richiesti.
  • Puoi definire un prompt per chiedere all'utente finale di fornire un valore.

Utilizzo dell'esperienza CX compilazione di moduli per raccogliere i parametri richiesti dall'utente finale:

  • Questi parametri sono associati a una pagina e vengono raccolti mentre la pagina è attiva.
  • Puoi usare le route delle condizioni per le pagine al fine di determinare compilazione dei moduli completata. Queste route delle condizioni in genere passano a un'altra pagina.
  • Puoi definire un prompt e gestori delle richieste di ripetizione per gestire agevolmente più tentativi di raccolta di un valore.

Transizioni

ES passa automaticamente da un intent all'altro quando input utente finale corrisponde a un'intenzione. Questa corrispondenza può verificarsi solo per gli intent che non hanno alcun contesto di input o intent che hanno un contesto di input attivo.

Transizioni CX da una pagina all'altra quando un gestore dello stato nell'ambito soddisfa i suoi requisiti. e fornisce un obiettivo di transizione. Con queste transizioni, puoi guidare in modo affidabile gli utenti finali nelle conversazioni. Esistono diversi modi per controllare queste transizioni:

  • La corrispondenza di intent può attivare una route per intent.
  • Soddisfare una condizione può attivare una route della condizione.
  • La chiamata di un evento può attivare un gestore di eventi.
  • I gestori di richieste ripetute possono causare una transizione in caso di errore dell'utente finale per fornire un valore dopo più tentativi.
  • Puoi utilizzare la modalità target per la transizione simbolica per i target della transizione.

Risposte dell'agente

Le risposte dell'agente ES vengono inviate all'utente finale quando viene trovato un intent:

  • L'agente può selezionare un solo messaggio per la risposta da un elenco di possibili risposte.
  • Le risposte possono essere specifiche della piattaforma, il che consente di utilizzare formati avanzati di risposta.
  • Le risposte possono essere generate dai webhook.

Le risposte dell'agente CX vengono inviate all'utente finale quando fulfillment . A differenza del fulfillment ES, che prevede sempre un webhook, Il fulfillment CX può comportare o meno la chiamata a un webhook, a seconda che per la risorsa di completamento sia stato configurato un webhook. Risposte sia statiche che dinamiche basate sulle risposte webhook sono controllate dal fulfillment. Esistono diversi modi per creare risposte all'agente:

  • L'evasione può essere fornita a qualsiasi tipo di gestore dello stato.
  • Durante un turno di conversazione possono essere concatenate più risposte tramite coda di risposte. In alcuni casi, questa funzionalità può semplificare la progettazione dell'agente.
  • CX non supporta le risposte integrate specifiche della piattaforma. Tuttavia, fornisce più tipi di risposta, incluso un payload personalizzato che può essere utilizzato per risposte specifiche della piattaforma.

Parametri

Parametri ES presentano le seguenti caratteristiche:

  • Definite solo negli intent.
  • Impostato in base a input utente finale, eventi, webhook e chiamate API.
  • Ci sono riferimenti in risposte, prompt di parametri, codice webhook e valori parametro:
      .
    • Il formato di riferimento di base è $parameter-name.
    • I riferimenti supportano la sintassi dei suffissi .original, .partial e .recent.
    • I riferimenti possono specificare il contesto attivo: #context-name.parameter-name.
    • I riferimenti possono specificare i parametri evento: #event-name.parameter-name.

Parametri CX presentano le seguenti caratteristiche:

  • Definite negli intent e nei moduli delle pagine.
  • L'intent e i parametri di modulo propagata ai parametri di sessione, dove sono disponibili come riferimento per tutta la durata della sessione.
  • Impostato in base a input utente finale, webhook preimpostazione dei parametri di completamento, e chiamate API.
  • Ci sono riferimenti in risposte, prompt di parametri, gestori di richieste di conferma predefiniti di parametri e codice webhook:
    • Il formato di riferimento per i parametri di sessione è $session.params.parameter-id e $intent.params.parameter-id per i parametri di intent.
    • I riferimenti dei parametri di intent supportano la sintassi dei suffissi .original e .resolved. I parametri di sessione non supportano questa sintassi.

Entità di sistema

ES supporta molti entità di sistema.

CX supporta molti dei entità di sistema, ma ci sono alcune differenze. Durante la migrazione, verificare che le entità di sistema che utilizzi in Spagna sono supportati anche da CX per la stessa lingua. In caso contrario, per queste entità è necessario creare entità personalizzate.

Eventi

Eventi ES presentano le seguenti caratteristiche:

  • Può essere richiamato dalle chiamate API o dai webhook per corrispondere a un intent.
  • Consente di impostare parametri.
  • Un numero ridotto di eventi viene richiamato dalle piattaforme di integrazione.

Eventi CX presentano le seguenti caratteristiche:

  • Può essere richiamato dalle chiamate API o dai webhook per chiamare un gestore di eventi.
  • Impossibile impostare i parametri.
  • Molti eventi integrati possono essere usati per gestire assenza di input utente finale, input non riconosciuto da parte dell'utente finale invalidati da un webhook ed errori di webhook.
  • Le chiamate possono essere controllate dallo stesso regole di ambito come altri gestori di stato.

Intent integrati

ES supporta i seguenti intent integrati:

Di seguito viene descritto il supporto CX per gli intent integrati:

  • Intent di benvenuto sono supportati.
  • Non sono forniti intent di riserva. Utilizza la nessuna corrispondenza nei gestori di eventi.
  • Per gli esempi negativi, utilizza la intent negativo predefinito.
  • Gli intent di follow-up predefiniti non sono forniti. Devi creare questi intent come richiesto dall'agente. Ad esempio: dovrai probabilmente creare un'intenzione per gestire risposte negative a una domanda dell'agente ("no", "no grazie", "no, non lo so" e così via). Gli intent dell'esperienza cliente sono riutilizzabili nell'agente, quindi devi definirli una sola volta. Usando route di intent diverse per questi intent comuni, in ambiti diversi, ti offre un maggiore controllo sulla conversazione.

Webhook

Webhook ES presentano le seguenti caratteristiche:

  • Puoi configurare un servizio webhook per l'agente.
  • Ogni intent può essere contrassegnato come se utilizzasse il webhook.
  • Non è disponibile un supporto integrato per la gestione degli errori relativi ai webhook.
  • Le azioni di intent o i nomi di intent vengono utilizzati dai webhook per determinare da dove è stato chiamato l'agente.
  • La console fornisce editor in linea.

Webhook CX presentano le seguenti caratteristiche:

  • Puoi configurare più servizi webhook per l'agente.
  • Ogni fulfillment può facoltativamente specificare una chiamata webhook.
  • È disponibile il supporto integrato gestione degli errori del webhook.
  • Un webhook di fulfillment CX contiene un . Questo tag è simile a un'azione ES, ma viene utilizzato solo quando si chiamano i webhook. Il servizio webhook può utilizzare questi tag per determinare da dove è stato chiamato l'agente.
  • La console non dispone di un editor di codice webhook integrato. È pratica comune utilizzare Cloud Functions, ma ci sono molte opzioni.

Quando esegui la migrazione a CX, devi modificare il codice webhook, perché le proprietà di richiesta e risposta sono diverse.

Integrazioni

Integrazioni ES e Integrazioni CX supportano diverse piattaforme. Per le piattaforme supportate da entrambi i tipi di agente, potrebbero esserci differenze nella configurazione.

Se l'integrazione ES che stavi utilizzando non è supportata da CX, potresti dover cambiare piattaforma o implementare l'integrazione autonomamente.

Altre funzionalità solo per CX

Esistono molte altre funzionalità fornite solo da CX. Ti consigliamo di utilizzare queste funzionalità durante la migrazione. Ad esempio:

Best practice

Prima di eseguire la migrazione, acquisire familiarità con Best practice di progettazione degli agenti CX. Molte di queste best practice per l'esperienza cliente sono simili alle best practice ES, ma alcune sono specifiche di CX.

Informazioni sullo strumento di migrazione

Lo strumento di migrazione copia la maggior parte dei dati ES nell'agente CX, e scrive in un file TODO con un elenco di voci di cui è necessario eseguire la migrazione manuale. Lo strumento copia solo tipi di entità personalizzate e frasi di addestramento per intent. Ti consigliamo di personalizzare questo strumento in base alle tue esigenze specifiche.

Codice strumento di migrazione

Ecco il codice dello strumento. Devi esaminare il codice di questo strumento, per aiutarti a comprenderne la funzione. Ti consigliamo di modificare questo codice per gestire situazioni specifiche nel tuo agente. Nei passaggi riportati di seguito, eseguirai questo strumento.

// 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()
}

Migrazione degli strumenti dei tipi di entità

Tipi di entità ES e Tipi di entità CX sono molto simili, quindi sono il tipo di dati più facile da migrare. Lo strumento copia i tipi di entità così come sono.

Migrazione degli intent da parte degli strumenti

Intent ES e Intent CX sono molto diverse.

Gli intent ES sono utilizzati come componenti di base dell'agente. e contengono frasi di addestramento, per il controllo della conversazione, configurazioni webhook, eventi, azioni e parametri di riempimento degli slot.

Dialogflow CX ha spostato la maggior parte di questi dati in altre risorse. Gli intent CX hanno solo frasi e parametri di addestramento, rendendo gli intent riutilizzabili in tutto l'agente. Lo strumento copia solo questi due tipi di dati sugli intent nei tuoi intent CX.

Limitazioni dello strumento di migrazione

Lo strumento di migrazione non supporta quanto segue:

  • Mega agenti: lo strumento non è in grado di leggere da più sub-agenti. ma puoi richiamare lo strumento più volte per ciascun sub-agente.
  • Agenti multilingue: è necessario modificare lo strumento. per creare frasi di addestramento e voci di entità multilingue.
  • Verifica delle entità di sistema per le lingue diverse dall'inglese: Lo strumento crea elementi TODO quando trova entità di sistema che non sono supportata da CX, partendo dal presupposto che l'inglese sia la lingua predefinita, e che utilizza una regione degli Stati Uniti. Il supporto delle entità di sistema varia in base alla lingua e alla regione. Per altre lingue e regioni, devi modificare lo strumento per eseguire questo controllo.

Passaggi fondamentali della migrazione

Le seguenti sottosezioni descrivono i passaggi da seguire per la migrazione. Non è necessario seguire questi passaggi manuali nell'ordine indicato, e potresti dover eseguire questi passaggi contemporaneamente o in un ordine diverso. Leggi i passaggi e inizia a pianificare le modifiche prima di apportare modifiche.

Dopo aver eseguito lo strumento di migrazione, puoi ricreare l'agente CX. Dovrai ancora fare una discreta quantità di lavoro per la migrazione, ma la maggior parte dei dati inseriti manualmente sarà presente nell'agente CX e il file TODO.

Crea l'agente Dialogflow CX

Se non l'hai già fatto, crea l'agente Dialogflow CX. Assicurati di utilizzare la stessa lingua predefinita dell'agente ES.

Esegui lo strumento di migrazione

Per eseguire lo strumento:

  1. Se non l'hai già fatto, installare Go sul tuo computer.
  2. Crea una directory per il codice dello strumento denominato migrate.
  3. Copia il codice strumento riportato sopra in un file di questa directory denominato main.go.
  4. Modifica il codice, se necessario, per il tuo caso.
  5. Crea un Modulo Go in questa directory. Ad esempio:

    go mod init migrate
    
  6. Installa le librerie client di Dialogflow ES V2 e Dialogflow CX V3 Go:

    go get cloud.google.com/go/dialogflow/apiv2
    go get cloud.google.com/go/dialogflow/cx/apiv3
    
  7. Assicurati di aver configurato autenticazione tramite libreria client.

  8. Esegui lo strumento e salva l'output in un file:

    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
    

Risoluzione dei problemi dello strumento di migrazione

Se si verificano errori durante l'esecuzione dello strumento, controlla quanto segue:

Errore Risoluzione
Errore RPC relativo a una parte della frase di addestramento menzionando un parametro non definito per l'intent. Questo può accadere se in precedenza hai utilizzato l'API ES per creare parametri di intent in un modo non coerente con le frasi di addestramento. Per risolvere il problema, rinomina il parametro ES dalla console, verifica che le frasi di addestramento utilizzino il parametro correttamente, poi fai clic su Salva. Questo può succedere anche se le frasi di addestramento fanno riferimento a parametri inesistenti.

Dopo aver corretto gli errori, dovrai rimuovere dall'agente CX intent ed entità prima di eseguire nuovamente lo strumento di migrazione.

Spostamento dei dati sugli intent di Spagna in CX

Lo strumento migra frasi e parametri per l'addestramento degli intent in intent CX. ma ci sono molti altri campi per intent ES di cui eseguire la migrazione manuale.

Un intent ES potrebbe necessitare di una pagina CX corrispondente un intent CX corrispondente, o entrambe le cose.

Se per la transizione della conversazione viene utilizzata una corrispondenza di intent ES da un determinato nodo di conversazione all'altro, dovresti avere due pagine nell'agente correlate a questo intent:

  • La pagina originale che contiene la route per intent che passerà alla pagina successiva: La route per intent nella pagina originale potrebbero avere messaggi di completamento dell'esperienza CX simili alle risposte di intent di ES. In questa pagina potrebbero essere presenti molte route di intent. Mentre la pagina originale è attiva, queste route per intent possono eseguire la transizione a molti percorsi possibili. Molti intent ES condividono la stessa pagina originale CX corrispondente.
  • Nella pagina successiva, che è il target di transizione per il percorso per intent nella pagina originale: Come soddisfare le richieste di assistenza CX per la pagina successiva potrebbero avere messaggi di completamento dell'esperienza CX simili alle risposte di intent di ES.

Se un intent ES contiene parametri obbligatori, devi creare una pagina CX corrispondente con gli stessi parametri in un modulo.

Capita spesso che un intent CX e una pagina CX condividano lo stesso elenco di parametri, che a un singolo intent ES corrisponde a una pagina CX. e un intent CX corrispondente. Quando viene trovata una corrispondenza per un intent CX con parametri in una route per intent, spesso la conversazione passa a una pagina con gli stessi parametri. I parametri estratti dalla corrispondenza di intent vengono propagata ai parametri di sessione, disponibili per compilare completamente o parzialmente i parametri del modulo della pagina.

Gli intent di riserva e gli intent di follow-up predefiniti non esistono in CX. Vedi gli intent integrati.

La tabella seguente descrive come mappare dati di intent specifici dalle risorse ES a CX:

Dati sull'intent ES Dati CX corrispondenti Azione richiesta
Frasi di addestramento Frasi per l'addestramento dell'intent Migrazione eseguita dallo strumento. Lo strumento verifica il supporto delle entità di sistema e crea elementi TODO per entità di sistema non supportate.
Risposte dell'agente Messaggi di risposta di evasione ordine Vedi le risposte degli agenti.
Contesto per il controllo della conversazione Nessuno Vedi Controllo della struttura e del percorso di conversazione.
Impostazione webhook Configurazione del webhook di fulfillment Vedi webhook.
Eventi Gestori di eventi a livello di flusso o di pagina Vedi gli eventi.
Azioni Tag webhook di fulfillment Vedi webhook.
Parametri Parametri di intent e/o parametri del modulo di pagina Migrazione ai parametri per intent in base allo strumento. Se i parametri sono richiesti, lo strumento crea elementi TODO di cui è possibile eseguire la migrazione in una pagina. Vedi parametri.
Prompt di parametri Prompt dei parametri del modulo della pagina Consulta la sezione Compilazione di moduli.

Crea flussi

Crea un flusso per ogni argomento della conversazione di alto livello. Gli argomenti di ogni flusso devono essere distinti, in modo che la conversazione non passi frequentemente da un flusso all'altro.

Se usavi un mega-agente, ogni sub-agente deve diventare uno o più flussi.

Iniziare con i percorsi di conversazione di base

È meglio testare l'agente con il simulatore durante l'iterazione delle modifiche. Inizialmente dovresti concentrarti sui percorsi di conversazione di base all'inizio della conversazione, e testarli man mano che apporti modifiche. Una volta risolti i problemi, passare a percorsi di conversazione più dettagliati.

Gestori di stato a livello di flusso e di pagina

Quando crei gestori di stato, valuta se devono essere applicati a livello di flusso o di pagina. Un gestore a livello di flusso è incluso nell'ambito ogni volta che il flusso (e quindi qualsiasi pagina del flusso) è attivo. Un gestore a livello di pagina ha ambito solo quando la pagina specifica è attiva. I gestori a livello di flusso sono simili agli intent ES senza contesto di input. I gestori a livello di pagina sono simili agli intent ES con contesto di input.

Codice webhook

Le proprietà della richiesta e della risposta webhook sono diverse per CX. Consulta le dei webhook.

Connettori di conoscenza

CX non supporta connettori di conoscenza . Dovrai implementarli come intent normali o attendere fino a Dialogflow CX supporta i connettori di conoscenza.

Impostazioni dell'agente

Controlla il tuo Impostazioni agente ES, e regolare Impostazioni agente CX dell'oggetto o eliminare definitivamente una versione archiviata, in base alle necessità.

Utilizza il file TODO

Lo strumento di migrazione produce un file CSV. Gli elementi di questo elenco sono incentrati su dati specifici che potrebbero richiedere attenzione. Importa questo file in un foglio di lavoro. Risolvi ogni elemento del foglio di lavoro utilizzando una colonna per contrassegnare il completamento.

Migrazione dell'utilizzo delle API

Se il sistema utilizza l'API ES per le chiamate in fase di runtime o progettazione, devi aggiornare questo codice per utilizzare API CX. Se utilizzi solo le chiamate di rilevamento dell'intent in fase di runtime, questo aggiornamento dovrebbe essere abbastanza semplice.

Integrazioni

Se l'agente utilizza le integrazioni, controlla nella sezione delle integrazioni, e apportare le modifiche necessarie.

Le seguenti sottosezioni descrivono i passaggi consigliati per la migrazione.

Convalida

Utilizza le funzionalità di convalida degli agenti per verificare che l'agente segua le best practice.

Test

Mentre esegui la procedura di migrazione manuale sopra riportata, devi testare l'agente utilizzando simulatore. Quando l'agente funziona, confrontare le conversazioni tra gli agenti ES e CX, e verificare che il comportamento sia simile o migliorato.

Durante il test delle conversazioni con il simulatore, dovresti creare casi di test per evitare regressioni future.

Ambienti

Controlla il tuo Ambienti ES e aggiorna Ambienti CX dell'oggetto o eliminare definitivamente una versione archiviata, in base alle necessità.