Los agentes de Dialogflow CX te ofrecen controles y herramientas de conversación más potentes que los agentes de Dialogflow ES. Si tu agente de Dialogflow ES gestiona conversaciones complejas, te recomendamos que migres a Dialogflow CX.
En esta guía se describe cómo migrar un agente de Dialogflow ES a Dialogflow CX. Estos dos tipos de agentes tienen muchas diferencias fundamentales, por lo que no hay una forma sencilla de realizar esta migración.
Si utilizas esta guía para una migración, envíanos tus comentarios (positivos o negativos) haciendo clic en el botón Enviar comentarios de arriba. Usaremos estos comentarios para mejorar esta guía con el tiempo.
En términos generales, el proceso recomendado es un proceso híbrido automatizado y manual. Usarás una herramienta que leerá algunos de los datos de tu agente de Dialogflow ES, escribirá esos datos en tu agente de Dialogflow CX y creará una lista de tareas. A continuación, vuelve a crear tu agente completo de Dialogflow CX siguiendo las prácticas recomendadas, la lista de tareas y los datos que ha migrado la herramienta.
Información sobre Dialogflow CX
Antes de intentar esta migración, debes tener un conocimiento sólido de cómo funcionan los flujos de Dialogflow CX. Puedes empezar aquí:
También deberías leer otros documentos conceptuales que incluyan funciones que probablemente necesites en tu nuevo agente. Céntrate en lo siguiente:
- Información general sobre la consola
- Agentes
- Flows
- Páginas
- Controladores de estado
- Intenciones
- Parámetros
- Cumplimientos
- Webhooks
Conocer las diferencias entre Dialogflow ES y Dialogflow CX
En esta sección se enumeran las diferencias más importantes entre Dialogflow ES y Dialogflow CX. Cuando realice los pasos de migración manual más adelante, consulte esta sección para obtener ayuda.
Estructura y control de la ruta de conversación
Dialogflow ES ofrece lo siguiente para controlar la estructura y la ruta de la conversación:
- Los intentos se usan como elementos básicos del agente. En cualquier momento de la conversación, se identifica una intención y, en cierto modo, cada intención es un nodo de la conversación.
- Context se usa para controlar la conversación. El contexto se usa para controlar qué intents se pueden asociar en un momento dado. El contexto caduca después de un determinado número de turnos de conversación, por lo que este tipo de control puede ser impreciso en conversaciones largas.
Dialogflow CX proporciona una jerarquía de recursos de estructura y controles más precisos sobre la ruta de la conversación:
- Las páginas son nodos de gráfico de la conversación. Las conversaciones de Dialogflow CX son similares a las máquinas de estados. En cualquier momento de la conversación, solo una página está activa. En función de las entradas o los eventos del usuario final, la conversación puede pasar a otra página. Es habitual que una página permanezca activa durante varios turnos de conversación.
- Los flujos son grupos de páginas relacionadas. Cada flujo debe abordar un tema de conversación de alto nivel.
- Los gestores de estado
se usan para controlar las transiciones y las respuestas.
Hay tres tipos de controladores de estado:
- Ruta de intención: contiene una intención que debe coincidir, respuestas opcionales y una transición de página opcional.
- Ruta de condición: contiene una condición que se debe cumplir, respuestas opcionales y una transición de página opcional.
- Gestor de eventos: contiene un nombre de evento que se debe invocar, respuestas opcionales y una transición de página opcional.
- Scope se usa para controlar si se puede llamar a un controlador de estado. La mayoría de los controladores están asociados a una página o a un flujo completo. Si la página o el flujo asociados están activos, el controlador estará en el ámbito y se podrá llamar. Una ruta de intención de Dialogflow CX en el ámbito es similar a una intención de Dialogflow ES con un contexto de entrada activo.
Cuando diseñes los flujos y las páginas de tu agente, asegúrate de entender los consejos de la sección de flujo de la guía de diseño de agentes.
Rellenar formularios
Dialogflow ES usa el relleno de espacios para recoger los parámetros necesarios del usuario final:
- Estos parámetros son parámetros de intención marcados como obligatorios.
- La intención se sigue asociando hasta que se recogen todos los parámetros obligatorios.
- Puedes definir una petición para que el usuario final proporcione un valor.
Dialogflow CX usa el relleno de formularios para recoger los parámetros obligatorios del usuario final:
- Estos parámetros están asociados a una página y se recogen mientras la página está activa.
- Usa rutas de condición para las páginas para determinar que se ha completado el formulario. Estas rutas de condición suelen llevar a otra página.
- Puedes definir una petición, así como gestores de repetición de peticiones para gestionar correctamente varios intentos de recoger un valor.
Transiciones
Dialogflow ES pasa automáticamente de una intención a otra cuando la entrada del usuario final coincide con una intención. Esta coincidencia solo puede producirse en las intenciones que no tengan ningún contexto de entrada o en las que tengan un contexto de entrada activo.
Dialogflow CX pasa de una página a otra cuando un controlador de estado del ámbito cumple sus requisitos y proporciona un destino de transición. Con estas transiciones, puedes guiar a los usuarios finales de forma fiable a través de las conversaciones. Hay varias formas de controlar estas transiciones:
- La coincidencia de intents puede activar una ruta de intent.
- Si se cumple una condición, se puede activar una ruta de condición.
- La invocación de un evento puede activar un controlador de eventos.
- Los controladores de repetición de peticiones pueden provocar una transición cuando el usuario final no proporciona un valor después de varios intentos.
- Puedes usar objetivos de transición simbólicos para los objetivos de transición.
Respuestas del agente
Las respuestas de los agentes de Dialogflow ES se envían al usuario final cuando se encuentra una coincidencia con una intención:
- El agente puede seleccionar un mensaje para la respuesta de una lista de posibles respuestas.
- Las respuestas pueden ser específicas de una plataforma, que puede usar formatos de respuesta enriquecida.
- Las respuestas se pueden activar mediante webhooks.
Las respuestas del agente de Dialogflow CX se envían al usuario final cuando se llama al cumplimiento. A diferencia del cumplimiento de Dialogflow ES, que siempre implica un webhook, el cumplimiento de Dialogflow CX puede implicar o no una llamada a un webhook, en función de si el recurso de cumplimiento tiene un webhook configurado. El procesamiento controla tanto las respuestas estáticas como las dinámicas basadas en las respuestas de webhook. Hay varias formas de crear respuestas del agente:
- La respuesta se puede proporcionar a cualquier tipo de controlador de estado.
- Se pueden concatenar varias respuestas durante una conversación mediante la cola de respuestas. En algunos casos, esta función puede simplificar el diseño de tu agente.
- Dialogflow CX no admite respuestas específicas de la plataforma integradas. Sin embargo, ofrece varios tipos de respuesta, incluida una carga útil personalizada que se puede usar para respuestas específicas de la plataforma.
Parámetros
Los parámetros de Dialogflow ES tienen las siguientes características:
- Solo se define en intents.
- Se define mediante la entrada del usuario final, eventos, webhooks y llamadas a la API.
- Se hace referencia a ellos en las respuestas, las peticiones de parámetros, el código de webhook y los valores de los parámetros:
- El formato de referencia básico es
$parameter-name. - Las referencias admiten la sintaxis de sufijo
.original,.partialy.recent. - Las referencias pueden especificar el contexto activo:
#context-name.parameter-name. - Las referencias pueden especificar parámetros de evento:
#event-name.parameter-name.
- El formato de referencia básico es
Los parámetros de Dialogflow CX tienen las siguientes características:
- Se define en las intenciones y los formularios de página.
- Los parámetros de intent y de formulario se propagan a los parámetros de sesión, donde se pueden consultar durante la sesión.
- Se define mediante la entrada del usuario final, los webhooks, los parámetros predefinidos de la respuesta y las llamadas a la API.
- Se hace referencia a él en las respuestas, las peticiones de parámetros, los controladores de repetición de peticiones, los preajustes de parámetros y el código de webhook:
- El formato de referencia es
$session.params.parameter-idpara los parámetros de sesión y$intent.params.parameter-idpara los parámetros de intent. - Las referencias de parámetros de intents admiten la sintaxis de sufijo
.originaly.resolved. Los parámetros de sesión no admiten esta sintaxis.
- El formato de referencia es
Entidades del sistema
Dialogflow ES admite muchas entidades de sistema.
Dialogflow CX admite muchas de las mismas entidades de sistema, pero hay algunas diferencias. Al migrar, comprueba que las entidades de sistema que usas en Dialogflow ES también sean compatibles con Dialogflow CX en el mismo idioma. Si no es así, deberías crear entidades personalizadas para estos casos.
Eventos
Los eventos de Dialogflow ES tienen las siguientes características:
- Se puede invocar desde llamadas a la API o webhooks para que coincida con una intención.
- Puede definir parámetros.
- Un pequeño número de eventos se invoca mediante plataformas de integración.
Los eventos de Dialogflow CX tienen las siguientes características:
- Se puede invocar desde llamadas a APIs o webhooks para llamar a un controlador de eventos.
- No se pueden definir parámetros.
- Muchos eventos integrados se pueden usar para gestionar la falta de entrada del usuario final, la entrada del usuario final no reconocida, los parámetros invalidados por un webhook y los errores de webhook.
- Las invocaciones se pueden controlar con las mismas reglas de ámbito que otros controladores de estado.
Intents integrados
Dialogflow ES admite los siguientes intents predefinidos:
A continuación, se describe la compatibilidad de Dialogflow CX con las intenciones integradas:
- Se admiten los intents de bienvenida.
- No se han proporcionado intenciones de reserva. En su lugar, usa los eventos no-match en los controladores de eventos.
- En el caso de los ejemplos negativos, usa la intención negativa predeterminada.
- No se proporcionan intents de seguimiento predefinidos. Debes crear estas intenciones según lo requiera tu agente. Por ejemplo, probablemente tengas que crear una intención para gestionar las respuestas negativas a una pregunta del agente ("no", "no, gracias", "no, no quiero", etc.). Los intents de Dialogflow CX se pueden reutilizar en todo el agente, por lo que solo tiene que definirlos una vez. Si usas diferentes rutas de intención para estas intenciones comunes en distintos ámbitos, tendrás mucho más control sobre la conversación.
Webhooks
Los webhooks de Dialogflow ES tienen las siguientes características:
- Puedes configurar un servicio de webhook para el agente.
- Cada intención se puede marcar para que use el webhook.
- No hay asistencia integrada para gestionar errores de webhook.
- Los webhooks usan las acciones o los nombres de intent para determinar desde qué parte del agente se ha llamado.
- La consola proporciona el editor insertado.
Los webhooks de Dialogflow CX tienen las siguientes características:
- Puedes configurar varios servicios de webhook para el agente.
- Cada respuesta puede especificar opcionalmente una llamada de webhook.
- Hay asistencia integrada para la gestión de errores de webhooks.
- Un webhook de fulfillment de Dialogflow CX contiene una etiqueta. Esta etiqueta es similar a una acción de Dialogflow ES, pero solo se usa cuando se llama a webhooks. El servicio de webhook puede usar estas etiquetas para determinar desde qué parte del agente se ha llamado.
- La consola no tiene un editor de código de webhook integrado. Es habitual usar Cloud Run functions, pero hay muchas opciones.
Cuando migres a Dialogflow CX, tendrás que cambiar el código de tu webhook, ya que las propiedades de solicitud y respuesta son diferentes.
Integraciones
Las integraciones de Dialogflow ES y las integraciones de Dialogflow CX admiten diferentes plataformas. En las plataformas compatibles con ambos tipos de agentes, puede haber diferencias en la configuración.
Si la integración de Dialogflow ES que estabas usando no es compatible con Dialogflow CX, puede que tengas que cambiar de plataforma o implementar la integración tú mismo.
Más funciones exclusivas de Dialogflow CX
Dialogflow CX ofrece muchas otras funciones. Te recomendamos que uses estas funciones durante la migración. Por ejemplo:
- NLU avanzado
- Ajustes de voz avanzados (sensibilidad al final de la frase, tiempo de espera sin voz, etc.)
- Historial de cambios
- Lógica condicional
- Entrada de DTMF para integraciones de telefonía
- Webhooks específicos del entorno
- Experimentos
- Grupos de rutas
- Buscar datos de agentes
- Ajustes de seguridad (redacción y retención de datos)
- Funciones del sistema para respuestas y condiciones avanzadas
- Casos de prueba
- Validación de datos de agentes
Prácticas recomendadas
Antes de migrar, familiarízate con las prácticas recomendadas para diseñar agentes de Dialogflow CX. Muchas de estas prácticas recomendadas de Dialogflow CX son similares a las de Dialogflow ES, pero algunas son exclusivas de Dialogflow CX.
Acerca de la herramienta de migración
La herramienta de migración copia la mayor parte de los datos de Dialogflow ES en tu agente de Dialogflow CX y escribe en un archivo TODO una lista de elementos que deben migrarse manualmente. La herramienta solo copia los tipos de entidades personalizadas y las frases de entrenamiento de la intención. Te recomendamos que personalices esta herramienta para adaptarla a tus necesidades específicas.
Código de la herramienta de migración
Este es el código de la herramienta. Deberías revisar el código de esta herramienta para saber qué hace. Puede que quieras cambiar este código para gestionar situaciones específicas en tu agente. En los pasos que se indican a continuación, ejecutarás esta herramienta.
// 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() }
Migración de tipos de entidades con la herramienta
Los tipos de entidad de Dialogflow ES y los tipos de entidad de Dialogflow CX son muy similares, por lo que son el tipo de datos más fácil de migrar. La herramienta simplemente copia los tipos de entidades tal cual.
Migración de intenciones de herramientas
Los intentos de Dialogflow ES y los intentos de Dialogflow CX son muy diferentes.
Las intenciones de Dialogflow ES se usan como los componentes básicos del agente y contienen frases de entrenamiento, respuestas, contexto para controlar la conversación, configuraciones de webhook, eventos, acciones y parámetros de relleno de espacios.
Dialogflow CX ha movido la mayoría de estos datos a otros recursos. Los intents de Dialogflow CX solo tienen frases de entrenamiento y parámetros, lo que hace que los intents se puedan reutilizar en todo el agente. La herramienta solo copia estos dos tipos de datos de intención en tus intenciones de Dialogflow CX.
Limitaciones de la herramienta de migración
La herramienta de migración no admite lo siguiente:
- Megaagentes: la herramienta no puede leer de varios subagentes, pero puedes llamar a la herramienta varias veces para cada subagente.
- Agentes multilingües: debe modificar la herramienta para crear frases de entrenamiento y entradas de entidad multilingües.
- Verificación de entidades del sistema en idiomas distintos del inglés: la herramienta crea elementos TODO cuando encuentra entidades del sistema que no son compatibles con Dialogflow CX, partiendo de la base de que el inglés es el idioma predeterminado y de que se usa la región de EE. UU. La compatibilidad con entidades del sistema varía según el idioma y la región. En el caso de otros idiomas y regiones, debes modificar la herramienta para que realice esta comprobación.
Pasos esenciales para la migración
En las siguientes subsecciones se describen los pasos que se deben seguir para realizar la migración. No es necesario que sigas estos pasos de forma manual en orden, y puede que incluso tengas que hacerlos simultáneamente o en un orden diferente. Lee los pasos y empieza a planificar los cambios antes de aplicarlos.
Después de ejecutar la herramienta de migración, puedes volver a crear tu agente de Dialogflow CX. Aún tendrás que hacer una cantidad considerable de trabajo de migración, pero la mayor parte de los datos introducidos manualmente estarán en tu agente de Dialogflow CX y en el archivo TAREAS.
Crear un agente de Dialogflow CX
Si aún no lo has hecho, crea tu agente de Dialogflow CX. Asegúrate de usar el mismo idioma predeterminado que tu agente de Dialogflow ES.
Ejecutar la herramienta de migración
Sigue estos pasos para ejecutar la herramienta:
- Si aún no lo has hecho, instala Go en tu máquina.
- Crea un directorio para el código de la herramienta llamado
migrate. - Copia el código de la herramienta de arriba
en un archivo de este directorio llamado
main.go. - Modifica el código si es necesario para tu caso.
Crea un módulo de Go en este directorio. Por ejemplo:
go mod init migrateInstala las bibliotecas de cliente de Go de Dialogflow ES V2 y Dialogflow CX V3:
go get cloud.google.com/go/dialogflow/apiv2 go get cloud.google.com/go/dialogflow/cx/apiv3Asegúrate de haber configurado la autenticación de la biblioteca de cliente.
Ejecuta la herramienta y guarda el resultado en un archivo:
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
Solucionar problemas con la herramienta de migración
Si se producen errores al ejecutar la herramienta, comprueba lo siguiente:
| Error | Resolución |
|---|---|
| Error de RPC que indica que una parte de una frase de entrenamiento menciona un parámetro que no se ha definido en el intent. | Esto puede ocurrir si has usado la API de Dialogflow ES para crear parámetros de intención de forma incoherente con las frases de entrenamiento. Para solucionar este problema, cambia el nombre del parámetro de Dialogflow ES en la consola, comprueba que tus frases de entrenamiento usen el parámetro correctamente y haz clic en Guardar. Esto también puede ocurrir si tus frases de entrenamiento hacen referencia a parámetros que no existen. |
Después de corregir los errores, tendrás que borrar las intenciones y las entidades del agente de Dialogflow CX antes de volver a ejecutar la herramienta de migración.
Mover datos de intenciones de Dialogflow ES a Dialogflow CX
La herramienta migra las frases de entrenamiento y los parámetros de los intents a los intents de Dialogflow CX, pero hay muchos otros campos de intents de Dialogflow ES que se deben migrar manualmente.
Es posible que una intención de Dialogflow ES necesite una página de Dialogflow CX correspondiente, una intención de Dialogflow CX correspondiente o ambas.
Si se usa una coincidencia de intención de Dialogflow ES para pasar la conversación de un nodo de conversación concreto a otro, debes tener dos páginas en tu agente relacionadas con esta intención:
- La página original que contiene la ruta de intención, que pasará a la página siguiente: la ruta de intención de la página original puede tener mensajes de cumplimiento de Dialogflow CX similares a las respuestas de intención de Dialogflow ES. Puede que tengas muchas rutas de intención en esta página. Mientras la página original esté activa, estas rutas de intención pueden llevar la conversación por muchos caminos posibles. Muchos intents de Dialogflow ES compartirán la misma página original de Dialogflow CX.
- La página siguiente, que es el destino de la transición de la ruta de intención de la página original: El cumplimiento de entrada de Dialogflow CX de la página siguiente puede tener mensajes de cumplimiento de Dialogflow CX similares a las respuestas de intención de Dialogflow ES.
Si una intención de Dialogflow ES contiene parámetros obligatorios, debes crear una página de Dialogflow CX correspondiente con los mismos parámetros en un formulario.
Es habitual que una intención y una página de Dialogflow CX compartan la misma lista de parámetros, lo que significa que una sola intención de Dialogflow ES tiene una página y una intención de Dialogflow CX correspondientes. Cuando se encuentra una coincidencia con una intención de Dialogflow CX que tiene parámetros en una ruta de intención, la conversación suele pasar a una página con los mismos parámetros. Los parámetros extraídos de la coincidencia de intención se propagan a los parámetros de sesión, que se pueden usar para rellenar parcial o totalmente los parámetros de formulario de la página.
Los intents de reserva y los intents de seguimiento predefinidos no existen en Dialogflow CX. Consulta los intentos integrados.
En la siguiente tabla se describe cómo asignar datos de intenciones específicos de Dialogflow ES a recursos de Dialogflow CX:
| Datos de intenciones de Dialogflow ES | Datos de Dialogflow CX correspondientes | Acción necesaria |
|---|---|---|
| Frases de preparación | Frases de preparación de intents | Migrado por la herramienta. La herramienta comprueba la compatibilidad con entidades del sistema y crea elementos de tareas pendientes para las entidades del sistema no compatibles. |
| Respuestas del agente | Mensajes de respuesta de cumplimiento | Consulta las respuestas del agente. |
| Contexto para el control de la conversación | Ninguno | Consulta Control de la estructura y de la ruta de conversación. |
| Ajuste de webhook | Configuración de webhook de fulfillment | Consulta webhooks. |
| Eventos | Gestores de eventos a nivel de flujo o de página | Consulta eventos. |
| Acciones | Etiquetas de webhook de cumplimiento | Consulta webhooks. |
| Parámetros | Parámetros de intención o parámetros de formulario de página | Migrado a parámetros de intent por la herramienta. Si los parámetros son obligatorios, la herramienta crea elementos TODO para migrar a una página. Consulta los parámetros. |
| Peticiones de parámetros | Peticiones de parámetros de formulario de página | Consulta Rellenar formularios. |
Crear flujos
Crea un flujo para cada tema de conversación de alto nivel. Los temas de cada flujo deben ser distintos para que la conversación no vaya y venga entre flujos con frecuencia.
Si usabas un megaagente, cada subagente debería convertirse en uno o varios flujos.
Empezar con rutas de conversación básicas
Lo mejor es probar el agente con el simulador mientras se hacen cambios. Por lo tanto, al principio debes centrarte en las rutas de conversión básicas al principio de la conversación y hacer pruebas a medida que vayas haciendo cambios. Una vez que funcionen, pasa a las rutas de conversación más detalladas.
Controladores de estado a nivel de flujo y a nivel de página
Al crear controladores de estado, plantéate si deben aplicarse a nivel de flujo o de página. Un controlador a nivel de flujo está en el ámbito siempre que el flujo (y, por lo tanto, cualquier página del flujo) esté activo. Un controlador a nivel de página solo está en el ámbito cuando la página en cuestión está activa. Los controladores a nivel de flujo son similares a las intenciones de Dialogflow ES sin contexto de entrada. Los controladores a nivel de página son similares a las intenciones de Dialogflow ES con contexto de entrada.
Código de webhook
Las propiedades de solicitud y respuesta de webhook son diferentes en Dialogflow CX. Consulta la sección sobre webhooks.
Conectores de conocimiento
Dialogflow CX aún no admite conectores de conocimientos. Tendrás que implementarlos como intenciones normales o esperar a que Dialogflow CX admita conectores de conocimientos.
Configuración de los agentes
Revisa los ajustes de tu agente de Dialogflow ES y los ajustes de tu agente de Dialogflow CX según sea necesario.
Usar el archivo TODO
La herramienta de migración genera un archivo CSV. Los elementos de esta lista se centran en datos concretos que pueden requerir atención. Importa este archivo a una hoja de cálculo. Resuelve cada elemento de la hoja de cálculo usando una columna para marcar la finalización.
Migración del uso de la API
Si tu sistema usa la API de Dialogflow ES para llamadas en tiempo de ejecución o de diseño, tendrás que actualizar este código para usar la API de Dialogflow CX. Si solo usas las llamadas de detección de intenciones en el tiempo de ejecución, esta actualización debería ser bastante sencilla.
Integraciones
Si tu agente usa integraciones, consulta la sección de integraciones y haz los cambios necesarios.
Pasos de migración recomendados
En las siguientes subsecciones se describen los pasos recomendados para la migración.
Validación
Usa la validación de agentes para comprobar que tu agente sigue las prácticas recomendadas.
Pruebas
Mientras sigues los pasos de la migración manual descritos anteriormente, debes probar tu agente con el simulador. Una vez que parezca que tu agente funciona correctamente, compara las conversaciones entre tus agentes de Dialogflow ES y Dialogflow CX, y verifica que el comportamiento sea similar o mejor.
Mientras pruebas estas conversaciones con el simulador, debes crear casos de prueba para evitar regresiones en el futuro.
Entornos
Revisa tus entornos de Dialogflow ES y actualiza tus entornos de Dialogflow CX según sea necesario.