Von Dialogflow ES zu Dialogflow CX migrieren

Dialogflow CX-Agents bieten Ihnen leistungsstärkere Steuerelemente und Tools für Unterhaltungen als Dialogflow ES-Agents. Wenn Ihr Dialogflow ES-Agent komplexe Unterhaltungen verarbeitet, sollten Sie eine Migration zu Dialogflow CX in Betracht ziehen.

In diesem Leitfaden wird beschrieben, wie Sie einen Agent von Dialogflow ES zu Dialogflow CX migrieren. Diese beiden Agent-Typen weisen viele grundlegende Unterschiede auf, sodass es keine einfache Möglichkeit gibt, diese Migration durchzuführen.

Wenn Sie diese Anleitung für eine Migration verwenden, geben Sie uns bitte positives oder negatives Feedback, indem Sie oben auf die Schaltfläche Feedback geben klicken. Wir werden dieses Feedback nutzen, um diesen Leitfaden im Laufe der Zeit zu verbessern.

Im Allgemeinen wird ein hybrider Prozess aus automatisierten und manuellen Schritten empfohlen. Sie verwenden ein Tool, das einige Ihrer Dialogflow ES-Agent-Daten liest, diese Daten in Ihren Dialogflow CX-Agent schreibt und eine Aufgabenliste erstellt. Anschließend erstellen Sie Ihren gesamten Dialogflow CX-Agenten neu. Dabei können Sie die Best Practices, die TODO-Liste und die vom Tool migrierten Daten nutzen.

Dialogflow CX

Bevor Sie diese Migration durchführen, sollten Sie sich mit der Funktionsweise von Dialogflow CX-Abläufen vertraut machen. Hier können Sie beginnen:

Lesen Sie sich auch zusätzliche Konzeptdokumente durch, die Funktionen enthalten, die Sie wahrscheinlich in Ihrem neuen Agent benötigen. Konzentrieren Sie sich auf Folgendes:

Unterschiede zwischen Dialogflow ES und Dialogflow CX

In diesem Abschnitt werden die wichtigsten Unterschiede zwischen Dialogflow ES und Dialogflow CX aufgeführt. Wenn Sie später manuelle Migrationsschritte ausführen, sollten Sie sich an diesem Abschnitt orientieren.

Struktur und Steuerung des Unterhaltungsverlaufs

Dialogflow ES bietet Folgendes für die Struktur und die Steuerung des Unterhaltungspfads:

  • Intents sind die Bausteine des Agents. Zu jedem Zeitpunkt der Unterhaltung wird ein Intent abgeglichen. Jeder Intent ist gewissermaßen ein Knoten für die Unterhaltung.
  • Kontext wird verwendet, um die Unterhaltung zu steuern. Mit Kontext wird gesteuert, welche Intents zu einem bestimmten Zeitpunkt zugeordnet werden können. Der Kontext läuft nach einer bestimmten Anzahl von Unterhaltungsrunden ab. Daher kann diese Art der Steuerung bei langen Unterhaltungen ungenau sein.

Dialogflow CX bietet eine Hierarchie von Strukturressourcen und genauere Steuerelemente für den Unterhaltungspfad:

  • Seiten sind Diagrammknoten für die Unterhaltung. Dialogflow CX-Unterhaltungen ähneln Zustandsmaschinen. Zu jedem Zeitpunkt der Unterhaltung ist eine Seite aktiv. Basierend auf Endnutzereingaben oder Ereignissen kann die Unterhaltung zu einer anderen Seite wechseln. Es ist üblich, dass eine Seite über mehrere Unterhaltungsrunden hinweg aktiv bleibt.
  • Abläufe sind Gruppen von zusammengehörigen Seiten. Jeder Ablauf sollte ein übergeordnetes Gesprächsthema behandeln.
  • Zustands-Handler werden verwendet, um Übergänge und Antworten zu steuern. Es gibt drei Arten von Zustands-Handlern:
    • Intent-Route: Enthält einen Intent, der abgeglichen werden muss, optionale Antworten und einen optionalen Seitenübergang.
    • Bedingungsroute: Enthält eine Bedingung, die erfüllt sein muss, optionale Antworten und einen optionalen Seitenübergang.
    • Ereignis-Handler: Enthält einen Ereignisnamen, der aufgerufen werden muss, optionale Antworten und einen optionalen Seitenübergang.
  • Mit Scope wird gesteuert, ob ein Zustands-Handler aufgerufen werden kann. Die meisten Handler sind einer Seite oder einem gesamten Ablauf zugeordnet. Wenn die zugehörige Seite oder der zugehörige Ablauf aktiv ist, liegt der Handler im Bereich und kann aufgerufen werden. Eine Dialogflow CX-Intent-Route im Bereich ähnelt einem Dialogflow ES-Intent mit einem aktiven Eingabekontext.

Achten Sie beim Entwerfen der Abläufe und Seiten Ihres Agents darauf, dass Sie die Hinweise im Abschnitt zu Abläufen im Leitfaden zum Agent-Design berücksichtigen.

Formular ausfüllen

Dialogflow ES verwendet die Slot-Füllung, um erforderliche Parameter vom Endnutzer zu erfassen:

  • Diese Parameter sind Intent-Parameter, die als erforderlich gekennzeichnet sind.
  • Der Intent wird so lange zugeordnet, bis alle erforderlichen Parameter erfasst wurden.
  • Sie können einen Prompt definieren, in dem der Endnutzer aufgefordert wird, einen Wert anzugeben.

In Dialogflow CX wird das Ausfüllen von Formularen verwendet, um erforderliche Parameter vom Endnutzer zu erfassen:

  • Diese Parameter sind mit einer Seite verknüpft und werden erfasst, wenn die Seite aktiv ist.
  • Sie verwenden Bedingungsrouten für Seiten, um festzustellen, ob das Ausfüllen des Formulars abgeschlossen ist. Diese Bedingungsrouten führen in der Regel zu einer anderen Seite.
  • Sie können einen Prompt sowie Handler für erneute Prompts definieren, um mehrere Versuche zum Erfassen eines Werts zu verarbeiten.

Übergänge

Dialogflow ES wechselt automatisch von einem Intent zum nächsten, wenn die Endnutzereingabe einem Intent zugeordnet wird. Diese Übereinstimmung kann nur für Intents ohne Eingabekontext oder Intents mit einem aktiven Eingabekontext erfolgen.

In Dialogflow CX wird von einer Seite zur nächsten gewechselt, wenn ein State-Handler im Bereich seine Anforderungen erfüllt und ein Übergangsziel angibt. Mithilfe dieser Übergänge können Sie Endnutzer zuverlässig durch Unterhaltungen führen. Es gibt mehrere Möglichkeiten, diese Übergänge zu steuern:

  • Die Intent-Zuordnung kann eine Intent-Route auslösen.
  • Wenn eine Bedingung erfüllt ist, kann eine Bedingungsroute ausgelöst werden.
  • Durch das Aufrufen eines Ereignisses kann ein Event-Handler ausgelöst werden.
  • Handler für erneute Eingabeaufforderungen können einen Übergang auslösen, wenn der Endnutzer nach mehreren Versuchen keinen Wert angibt.
  • Sie können symbolische Umstellungsziele für Umstellungsziele verwenden.

Antworten des KI-Agenten

Antworten von Dialogflow ES-Agents werden an den Endnutzer gesendet, wenn ein Intent abgeglichen wird:

  • Der Kundenservicemitarbeiter kann eine Nachricht für die Antwort aus einer Liste möglicher Antworten auswählen.
  • Antworten können plattformspezifisch sein und Rich-Response-Formate verwenden.
  • Antworten können durch Webhooks ausgelöst werden.

Antworten von Dialogflow CX-Agents werden an den Endnutzer gesendet, wenn der Fulfillment-Aufruf erfolgt. Im Gegensatz zur Dialogflow ES-Auftragsausführung, bei der immer ein Webhook beteiligt ist, kann bei der Dialogflow CX-Auftragsausführung ein Webhook aufgerufen werden oder nicht, je nachdem, ob für die Auftragsausführungsressource ein Webhook konfiguriert ist. Sowohl statische als auch dynamische Antworten, die auf Webhook-Antworten basieren, werden durch die Auftragsausführung gesteuert. Es gibt mehrere Möglichkeiten, Agent-Antworten zu erstellen:

  • Die Auftragsausführung kann für jeden Typ von Status-Handler bereitgestellt werden.
  • Mehrere Antworten können während einer Unterhaltungsrunde über die Antwortwarteschlange verkettet werden. Diese Funktion kann die Entwicklung Ihres Agents in einigen Fällen vereinfachen.
  • Dialogflow CX unterstützt keine integrierten plattformspezifischen Antworten. Es bietet jedoch mehrere Antworttypen, darunter eine benutzerdefinierte Nutzlast, die für plattformspezifische Antworten verwendet werden kann.

Parameter

Dialogflow ES-Parameter haben die folgenden Merkmale:

  • Nur in Intents definiert.
  • Wird durch Endnutzereingaben, Ereignisse, Webhooks und API-Aufrufe festgelegt.
  • Wird in Antworten, Parameteraufforderungen, Webhook-Code und Parameterwerten referenziert:
    • Das grundlegende Referenzformat ist $parameter-name.
    • Referenzen unterstützen die Suffixsyntax .original, .partial und .recent.
    • In Referenzen kann der aktive Kontext angegeben werden: #context-name.parameter-name.
    • In Verweisen können Ereignisparameter angegeben werden: #event-name.parameter-name.

Dialogflow CX-Parameter haben die folgenden Eigenschaften:

  • In Intents und Seitenformularen definiert.
  • Intent- und Formularparameter werden an Sitzungsparameter weitergegeben, wo sie für die Dauer der Sitzung referenziert werden können.
  • Wird durch Endnutzereingaben, Webhooks, Voreinstellungen für Ausführungsparameter und API-Aufrufe festgelegt.
  • Wird in Antworten, Parameteraufforderungen, Handlern für erneute Aufforderungen, Parametervoreinstellungen und Webhook-Code referenziert:
    • Das Referenzformat ist $session.params.parameter-id für Sitzungsparameter und $intent.params.parameter-id für Intent-Parameter.
    • Bei Verweisen auf Intent-Parameter wird die Suffix-Syntax .original und .resolved unterstützt. Diese Syntax wird für Sitzungsparameter nicht unterstützt.

Systementitäten

Dialogflow ES unterstützt viele Systementitäten.

Dialogflow CX unterstützt viele der gleichen System-Entities, es gibt jedoch einige Unterschiede. Prüfen Sie bei der Migration, ob die Systementitäten, die Sie in Dialogflow ES verwenden, auch in Dialogflow CX für dieselbe Sprache unterstützt werden. Andernfalls sollten Sie benutzerdefinierte Entitäten dafür erstellen.

Ereignisse

Dialogflow ES-Ereignisse haben die folgenden Merkmale:

  • Kann über API-Aufrufe oder Webhooks aufgerufen werden, um eine Intention abzugleichen.
  • Parameter können festgelegt werden.
  • Eine kleine Anzahl von Ereignissen wird von Integrationsplattformen aufgerufen.

Dialogflow CX-Ereignisse haben die folgenden Merkmale:

  • Kann über API-Aufrufe oder Webhooks aufgerufen werden, um einen Ereignis-Handler aufzurufen.
  • Parameter können nicht festgelegt werden.
  • Viele integrierte Ereignisse können verwendet werden, um fehlende oder nicht erkannte Endnutzereingaben, durch einen Webhook ungültig gemachte Parameter und Webhook-Fehler zu verarbeiten.
  • Aufrufe können durch dieselben Bereichsregeln wie andere Status-Handler gesteuert werden.

Integrierte Intents

Dialogflow ES unterstützt die folgenden integrierten Intents:

Im Folgenden wird die Unterstützung von integrierten Intents in Dialogflow CX beschrieben:

  • Begrüßungs-Intents werden unterstützt.
  • Fallback-Intents sind nicht verfügbar. Verwenden Sie stattdessen die no-match-Ereignisse in Event-Handlern.
  • Verwenden Sie für negative Beispiele den Standard-Intent für Negativbeispiele.
  • Vordefinierte Follow-up-Intents sind nicht verfügbar. Sie müssen diese Intents nach Bedarf für Ihren Agent erstellen. Sie müssen beispielsweise wahrscheinlich einen Intent erstellen, um negative Antworten auf eine Agent-Frage zu verarbeiten („Nein“, „Nein, danke“, „Nein, das möchte ich nicht“ usw.). Dialogflow CX-Intents können in Ihrem Agent wiederverwendet werden. Sie müssen sie also nur einmal definieren. Wenn Sie für diese häufigen Intents unterschiedliche Intent-Routen in verschiedenen Bereichen verwenden, haben Sie viel mehr Kontrolle über die Unterhaltung.

Webhooks

Dialogflow ES-Webhooks haben die folgenden Eigenschaften:

  • Sie können einen Webhook-Dienst für den Agent konfigurieren.
  • Für jede Intention kann angegeben werden, dass der Webhook verwendet wird.
  • Es gibt keine integrierte Unterstützung für die Verarbeitung von Webhook-Fehlern.
  • Intent-Aktionen oder Intent-Namen werden von Webhooks verwendet, um zu ermitteln, wo im Agent der Aufruf erfolgt ist.
  • Die Konsole bietet den Inline-Editor.

Dialogflow CX-Webhooks haben die folgenden Eigenschaften:

  • Sie können mehrere Webhook-Dienste für den Agent konfigurieren.
  • Für jede Auftragsausführung kann optional ein Webhook-Aufruf angegeben werden.
  • Es gibt integrierte Unterstützung für die Fehlerbehandlung von Webhooks.
  • Ein Dialogflow CX-Webhook zur Auftragsausführung enthält ein Tag. Dieses Tag ähnelt einer Dialogflow ES-Aktion, wird aber nur beim Aufrufen von Webhooks verwendet. Der Webhook-Dienst kann diese Tags verwenden, um zu ermitteln, wo im Agent er aufgerufen wurde.
  • Die Konsole hat keinen integrierten Code-Editor für Webhooks. Häufig werden Cloud Run Functions verwendet, aber es gibt viele Optionen.

Wenn Sie zu Dialogflow CX migrieren, müssen Sie Ihren Webhook-Code ändern, da sich die Anfrage- und Antwortattribute unterscheiden.

Integrationen

Dialogflow ES-Integrationen und Dialogflow CX-Integrationen unterstützen unterschiedliche Plattformen. Bei Plattformen, die von beiden Agententypen unterstützt werden, kann es Unterschiede in der Konfiguration geben.

Wenn die von Ihnen verwendete Dialogflow ES-Integration nicht von Dialogflow CX unterstützt wird, müssen Sie möglicherweise die Plattform wechseln oder die Integration selbst implementieren.

Weitere Funktionen nur für Dialogflow CX

Es gibt viele weitere Funktionen, die nur in Dialogflow CX verfügbar sind. Sie sollten diese Funktionen bei der Migration in Betracht ziehen. Beispiel:

Best Practices

Bevor Sie migrieren, sollten Sie sich mit den Best Practices für das Design von Dialogflow CX-Agents vertraut machen. Viele dieser Best Practices für Dialogflow CX ähneln den Best Practices für Dialogflow ES, einige sind jedoch nur für Dialogflow CX relevant.

Informationen zum Migrationstool

Das Migrationstool kopiert den Großteil der Dialogflow ES-Daten in Ihren Dialogflow CX-Agent und schreibt in eine TODO-Datei mit einer Liste von Elementen, die manuell migriert werden müssen. Mit dem Tool werden nur benutzerdefinierte Entitätstypen und Trainingsformulierungen für Intents kopiert. Sie sollten dieses Tool an Ihre spezifischen Anforderungen anpassen.

Code des Migrationstools

Hier ist der Code für das Tool. Sie sollten sich den Code für dieses Tool ansehen, damit Sie wissen, was es bewirkt. Möglicherweise möchten Sie diesen Code ändern, um bestimmte Situationen in Ihrem Agent zu berücksichtigen. In den folgenden Schritten führen Sie dieses Tool aus.

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

Tool-Migration von Entitätstypen

Dialogflow ES-Entitätstypen und Dialogflow CX-Entitätstypen sind sehr ähnlich und lassen sich daher am einfachsten migrieren. Das Tool kopiert Entitätstypen einfach unverändert.

Tool-Migration von Intents

Dialogflow ES-Intents und Dialogflow CX-Intents unterscheiden sich erheblich.

Dialogflow ES-Intents werden als Bausteine des Agents verwendet. Sie enthalten Trainingsformulierungen, Antworten, Kontext für die Unterhaltungssteuerung, Webhook-Konfigurationen, Ereignisse, Aktionen und Parameter für das Ausfüllen von Slots.

Die meisten dieser Daten wurden in Dialogflow CX in andere Ressourcen verschoben. Dialogflow CX-Intents haben nur Trainingsformulierungen und Parameter. Dadurch können Intents im gesamten Agent wiederverwendet werden. Das Tool kopiert nur diese beiden Arten von Intent-Daten in Ihre Dialogflow CX-Intents.

Einschränkungen des Migrationstools

Das Migrationstool unterstützt Folgendes nicht:

  • Mega-Agents: Das Tool kann nicht aus mehreren Sub-Agents lesen, aber Sie können das Tool mehrmals für jeden Sub-Agent aufrufen.
  • Mehrsprachige Agents: Sie sollten das Tool so anpassen, dass mehrsprachige Trainingsformulierungen und Entitätseinträge erstellt werden.
  • Überprüfung von Systementitäten für nicht englische Sprachen: Das Tool erstellt TODO-Elemente, wenn es Systementitäten findet, die von Dialogflow CX nicht unterstützt werden. Dabei wird davon ausgegangen, dass Englisch die Standardsprache ist und eine US-Region verwendet wird. Die Unterstützung für Systementitäten variiert je nach Sprache und Region. Für andere Sprachen und Regionen müssen Sie das Tool entsprechend anpassen.

Wichtige Migrationsschritte

In den folgenden Unterabschnitten werden die erforderlichen Migrationsschritte beschrieben. Sie müssen diese manuellen Schritte nicht in der angegebenen Reihenfolge ausführen. Möglicherweise müssen Sie sie sogar gleichzeitig oder in einer anderen Reihenfolge ausführen. Lesen Sie sich die Schritte durch und beginnen Sie mit der Planung Ihrer Änderungen, bevor Sie sie tatsächlich vornehmen.

Nachdem Sie das Migrationstool ausgeführt haben, können Sie Ihren Dialogflow CX-Agent neu erstellen. Sie haben zwar immer noch einiges an Migrationsarbeit vor sich, aber der Großteil der manuell eingegebenen Daten ist in Ihrem Dialogflow CX-Agent und der TODO-Datei vorhanden.

Dialogflow CX-Agent erstellen

Erstellen Sie Ihren Dialogflow CX-Agent, falls noch nicht geschehen. Verwenden Sie dieselbe Standardsprache wie für Ihren Dialogflow ES-Agent.

Migrationstool ausführen

Führen Sie die folgenden Schritte aus, um das Tool auszuführen:

  1. Installieren Sie Go auf Ihrem Computer, falls noch nicht geschehen.
  2. Erstellen Sie ein Verzeichnis für den Toolcode mit dem Namen migrate.
  3. Kopieren Sie den Tool-Code oben in eine Datei mit dem Namen main.go in diesem Verzeichnis.
  4. Passen Sie den Code bei Bedarf an Ihren Fall an.
  5. Erstellen Sie in diesem Verzeichnis ein Go-Modul. Beispiel:

    go mod init migrate
    
  6. Installieren Sie die Go-Clientbibliotheken für Dialogflow ES V2 und Dialogflow CX V3:

    go get cloud.google.com/go/dialogflow/apiv2
    go get cloud.google.com/go/dialogflow/cx/apiv3
    
  7. Prüfen Sie, ob Sie die Authentifizierung der Clientbibliothek eingerichtet haben.

  8. Führen Sie das Tool aus und speichern Sie die Ausgabe in einer Datei:

    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
    

Fehlerbehebung beim Migrationstool

Wenn beim Ausführen des Tools Fehler auftreten, prüfen Sie Folgendes:

Fehler Lösung
RPC-Fehler, der angibt, dass in einem Teil einer Trainingsformulierung ein Parameter erwähnt wird, der nicht für den Intent definiert ist. Das kann passieren, wenn Sie die Dialogflow ES API zuvor verwendet haben, um Intent-Parameter auf eine Weise zu erstellen, die nicht mit den Trainingsformulierungen übereinstimmte. Um das Problem zu beheben, benennen Sie den Dialogflow ES-Parameter in der Console um, prüfen Sie, ob der Parameter in Ihren Trainingsformulierungen richtig verwendet wird, und klicken Sie dann auf „Speichern“. Das kann auch passieren, wenn in Ihren Trainingsformulierungen auf nicht vorhandene Parameter verwiesen wird.

Nachdem Sie die Fehler behoben haben, müssen Sie den Dialogflow CX-Agent von Intents und Entitäten bereinigen, bevor Sie das Migrationstool noch einmal ausführen.

Dialogflow ES-Intent-Daten zu Dialogflow CX migrieren

Mit dem Tool werden Trainingsformulierungen und Parameter für Intents zu Dialogflow CX-Intents migriert. Es gibt jedoch viele andere Dialogflow ES-Intent-Felder, die manuell migriert werden müssen.

Für einen Dialogflow ES-Intent ist möglicherweise eine entsprechende Dialogflow CX-Seite, ein entsprechender Dialogflow CX-Intent oder beides erforderlich.

Wenn ein Dialogflow ES-Intent-Abgleich verwendet wird, um die Unterhaltung von einem bestimmten Unterhaltungsknoten zu einem anderen zu übertragen, sollten Sie zwei Seiten in Ihrem Agent haben, die sich auf diesen Intent beziehen:

  • Die ursprüngliche Seite, die die Intent-Route enthält, über die zur nächsten Seite gewechselt wird: Die Intent-Route auf der ursprünglichen Seite kann Dialogflow CX-Fulfillment-Nachrichten enthalten, die den Intent-Antworten von Dialogflow ES ähneln. Auf dieser Seite sind möglicherweise viele Intent-Routen vorhanden. Während die ursprüngliche Seite aktiv ist, können diese Intent-Routen den Dialog in viele mögliche Richtungen lenken. Viele Dialogflow ES-Intents haben dieselbe entsprechende Originalseite in Dialogflow CX.
  • Die nächste Seite, die das Übergangsziel für die Intent-Route auf der ursprünglichen Seite ist: Die Dialogflow CX-Eintritts-Fulfillment-Nachricht für die nächste Seite kann Dialogflow CX-Fulfillment-Nachrichten enthalten, die den Dialogflow ES-Intent-Antworten ähneln.

Wenn ein Dialogflow ES-Intent erforderliche Parameter enthält, sollten Sie eine entsprechende Dialogflow CX-Seite mit denselben Parametern in einem Formular erstellen.

Häufig haben ein Dialogflow CX-Intent und eine Dialogflow CX-Seite dieselbe Parameterliste. Das bedeutet, dass ein einzelnes Dialogflow ES-Intent eine entsprechende Dialogflow CX-Seite und ein entsprechendes Dialogflow CX-Intent hat. Wenn ein Dialogflow CX-Intent mit Parametern in einer Intent-Route zugeordnet wird, wird die Unterhaltung häufig zu einer Seite mit denselben Parametern weitergeleitet. Die aus dem Intent-Abgleich extrahierten Parameter werden an Sitzungsparameter weitergegeben, die zum teilweisen oder vollständigen Ausfüllen von Seitenformularparametern verfügbar sind.

Fallback-Intents und vordefinierte Follow-up-Intents sind in Dialogflow CX nicht verfügbar. Weitere Informationen finden Sie unter Integrierte Intents.

In der folgenden Tabelle wird beschrieben, wie Sie bestimmte Intent-Daten aus Dialogflow ES Dialogflow CX-Ressourcen zuordnen:

Dialogflow ES-Intent-Daten Entsprechende Dialogflow CX-Daten Maßnahme erforderlich
Trainingssätze Trainingsformulierungen für Intents Mit dem Tool migriert. Das Tool prüft auf Unterstützung von Systementitäten und erstellt TODO-Elemente für nicht unterstützte Systementitäten.
Antworten des KI-Agenten Antwortnachrichten zur Auftragsausführung Weitere Informationen finden Sie unter Agent-Antworten.
Kontext für die Unterhaltungssteuerung Keine Weitere Informationen finden Sie unter Struktur und Konversationspfad steuern.
Webhook-Einstellung Konfiguration des Webhooks für die Auftragsausführung Weitere Informationen finden Sie unter Webhooks.
Ereignisse Event-Handler auf Ablauf- oder Seitenebene Weitere Informationen finden Sie unter Ereignisse.
Aktionen Tags für Webhooks zur Auftragsausführung Weitere Informationen finden Sie unter Webhooks.
Parameter Intent-Parameter und/oder Seitenformularparameter Migration zu Intent-Parametern nach Tool. Wenn die Parameter erforderlich sind, erstellt das Tool TODO-Elemente, um sie möglicherweise auf eine Seite zu migrieren. Parameter
Parameter-Prompts Aufforderungen für Seitenformularparameter Weitere Informationen finden Sie unter Formularausfüllung.

Flows erstellen

Erstellen Sie für jedes übergeordnete Gesprächsthema einen Flow. Die Themen in den einzelnen Abläufen sollten sich voneinander unterscheiden, damit die Unterhaltung nicht häufig zwischen den Abläufen hin- und herspringt.

Wenn Sie einen Mega-Agenten verwendet haben, sollte jeder Sub-Agent zu einem oder mehreren Abläufen werden.

Mit einfachen Konversationspfaden beginnen

Es empfiehlt sich, Ihren Agent mit dem Simulator zu testen, während Sie Änderungen vornehmen. Konzentrieren Sie sich daher zu Beginn der Unterhaltung auf die grundlegenden Konversationspfade und testen Sie, während Sie Änderungen vornehmen. Wenn diese funktionieren, können Sie sich detaillierteren Konversationspfaden zuwenden.

Zustands-Handler auf Ablaufebene und auf Seitenebene

Beim Erstellen von Status-Handlern sollten Sie überlegen, ob sie auf Flow- oder Seitenebene angewendet werden sollen. Ein Handler auf Ablaufebene ist immer dann im Bereich, wenn der Ablauf (und damit jede Seite im Ablauf) aktiv ist. Ein Handler auf Seitenebene ist nur im Bereich, wenn die entsprechende Seite aktiv ist. Handler auf Ablaufebene ähneln Dialogflow ES-Intents ohne Eingabekontext. Handler auf Seitenebene ähneln Dialogflow ES-Intents mit Eingabekontext.

Webhook-Code

Die Eigenschaften von Webhook-Anfragen und ‑Antworten sind für Dialogflow CX anders. Weitere Informationen finden Sie im Abschnitt zu Webhooks.

Wissensconnectors

Dialogflow CX unterstützt noch keine Knowledge-Connectors. Sie müssen diese als normale Intents implementieren oder warten, bis Dialogflow CX Knowledge Connectors unterstützt.

Agent-Einstellungen

Prüfen Sie die Einstellungen für Ihren Dialogflow ES-Agent und passen Sie die Einstellungen für Ihren Dialogflow CX-Agent bei Bedarf an.

TODO-Datei verwenden

Das Migrationstool gibt eine CSV-Datei aus. Die Elemente in dieser Liste beziehen sich auf bestimmte Daten, die möglicherweise Ihre Aufmerksamkeit erfordern. Importieren Sie diese Datei in eine Tabelle. Bearbeiten Sie jeden Eintrag in der Tabelle und verwenden Sie eine Spalte, um den Abschluss zu markieren.

Migration der API-Nutzung

Wenn in Ihrem System die Dialogflow ES API für Laufzeit- oder Designzeitaufrufe verwendet wird, müssen Sie diesen Code aktualisieren, damit die Dialogflow CX API verwendet wird. Wenn Sie die detect intent-Aufrufe nur zur Laufzeit verwenden, sollte diese Aktualisierung relativ einfach sein.

Integrationen

Wenn Ihr Agent Integrationen verwendet, lesen Sie den Abschnitt zu Integrationen und nehmen Sie gegebenenfalls Änderungen vor.

In den folgenden Unterabschnitten werden empfohlene Migrationsschritte beschrieben.

Validierung

Verwenden Sie die Agent-Validierung, um zu prüfen, ob Ihr Agent den Best Practices entspricht.

Test

Während Sie die oben beschriebenen manuellen Migrationsschritte ausführen, sollten Sie Ihren Agenten mit dem Simulator testen. Wenn Ihr Agent zu funktionieren scheint, sollten Sie Unterhaltungen zwischen Ihren Dialogflow ES- und Dialogflow CX-Agents vergleichen und prüfen, ob das Verhalten ähnlich oder besser ist.

Wenn Sie diese Unterhaltungen mit dem Simulator testen, sollten Sie Testfälle erstellen, um zukünftige Regressionen zu vermeiden.

Umgebungen

Überprüfen Sie Ihre Dialogflow ES-Umgebungen und aktualisieren Sie Ihre Dialogflow CX-Umgebungen nach Bedarf.