后端模块提供了一个基础架构,用于处理大量与功能相关的消息并与代理桌面界面进行交互。本教程将引导您完成将后端模块与代理系统集成的过程。
如需详细了解后端模块的概念和结构,请参阅后端模块基础知识文档。
前提条件
- 安装 Google Cloud CLI(如果您尚未安装)。
- 为 Dialogflow 中所需的每种事件通知创建一个 Cloud Pub/Sub 主题。记下主题 ID 和主题名称,以供日后进行后端部署。
- 使用对话配置文件使用 Agent Assist 控制台和 Pub/Sub 主题配置对话配置文件。
自动部署
您可以使用自动化脚本或 Terraform 自动执行部署。 Google Cloud
自动化脚本
如需了解详情,请查看 ./deploy.sh。
应用 Terraform 更改
您可以使用 gcloud CLI 自动化脚本或 Terraform 自动执行部署。在应用 Terraform 更改之前,请完成以下步骤。
- 向您的账号授予以下 IAM 角色:
Project IAM Admin(roles/resourcemanager.projectIamAdmin)Service Usage Admin(roles/serviceusage.serviceUsageAdmin)Service Account Admin(roles/iam.serviceAccountAdmin)Service Account User(roles/iam.serviceAccountUser)Pub/Sub Admin(roles/pubsub.admin)Secret Manager Admin(roles/secretmanager.admin)Cloud Build Editor(roles/cloudbuild.builds.editor)Artifact Registry Administrator(roles/artifactregistry.admin)Storage Admin(roles/storage.admin)Cloud Run Admin(roles/run.admin)Cloud Memorystore Redis Admin(roles/redis.admin)Serverless VPC Access Admin(roles/vpcaccess.admin)
- 为界面连接器和 Cloud Pub/Sub 拦截器构建映像,并记下映像名称。
- 对于界面连接器,请在
./ui-connector文件夹下运行以下命令。$ gcloud builds submit --tag gcr.io/$GCP_PROJECT_ID/aa-integration-backend/ui-connector
- 对于 Cloud Pub/Sub 拦截器,请在
./cloud-pubsub-interceptor文件夹下运行以下命令。$ gcloud builds submit --tag gcr.io/$GCP_PROJECT_ID/aa-integration-backend/cloud-pubsub-interceptor
- 对于界面连接器,请在
- 创建一个 Cloud Storage 存储桶来存储 Terraform 状态,并使用以下命令更新
/terraform/backend.tf中的后端存储桶值。GCP_PROJECT_ID=$(gcloud config get-value project) # Create the Cloud storage bucket gcloud storage buckets create gs://${GCP_PROJECT_ID}-tfstate # Enable Object Versioning to keep the history of your deployments gcloud storage buckets update gs://${GCP_PROJECT_ID}-tfstate --versioning
- 导出所需的 Terraform 变量
gcp_project_id、ui_connector_docker_image和cloud_pubsub_interceptor_docker_image的值。示例:export TF_VAR_gcp_project_id='you-gcp-project-id'。或者,您也可以直接在/terraform/variables.tf中填写这些变量的值。 - 通过修改
/ui-connector/auth.py中的auth.check_auth()方法来自定义身份验证方法。
如果您想使用 Cloud Build 自动执行这些步骤,请按照此 说明 操作,并使用 build 配置文件 ./terraform_cloudbuild.yaml。如需允许 Cloud Build 部署服务,您需要向 Cloud Build 服务账号授予第 1 步中列出的 IAM 角色。
手动部署
以下步骤介绍了如何手动部署后端模块。
设置环境变量
为了简化部署命令,我们建议您在 Shell 中设置以下有用的环境变量。您可以使用以下示例命令设置变量:
$ export GCP_PROJECT_ID='aa-integration-service'
设置以下环境变量:
GCP_PROJECT_ID:托管相关资源的 Cloud Platform 项目的项目 ID。示例:my-project。SERVICE_REGION:服务和相关 Google Cloud 资源的位置或区域。 平台资源。示例:us-central1。
设置管理员账号
我们建议您使用单独的 Google Cloud 账号进行服务 管理和运行时身份验证。服务管理主要由拥有 Google 账号的人员执行 ,而 运行时身份验证则使用 服务账号向 Cloud Run 服务授予权限,以允许其访问 必要的资源。
准备人员管理员账号
如果您打算使用在 项目中已拥有 Editor 或 Owner 权限的账号,则可以跳到 下一部分。
如需管理后端基础架构,请设置一个管理员账号并向其授予以下 Identity and Access Management (IAM) 角色。这些角色的权限都包含在 Editor 和 Owner 基本角色中。
roles/secretmanager.admin(Secret Manager Admin):管理存储在 Secret Manager 中用于生成和验证 JWT 的密钥。roles/run.admin(Cloud Run Admin):部署和管理 Cloud Run 服务。roles/iam.serviceAccountUser(Service Account User):向 Cloud Run 运行时服务账号授予iam.serviceAccounts.actAs权限。roles/cloudbuild.builds.editor(Cloud Build Editor):使用 Cloud Build 为集成服务构建 Docker 映像。- Artifact Registry Administrator:存储和管理为集成服务构建的 Docker 映像。
roles/pubsub.editor(Cloud Pub/Sub Editor):创建和管理 Cloud Pub/Sub 主题和订阅。roles/redis.admin(Redis Admin):创建和管理 Memorystore for Redis 的资源。
如需向人员账号授予 IAM 角色,请使用
add-iam-policy-binding
Google Cloud CLI 命令。以下是命令示例:
$ gcloud projects add-iam-policy-binding $GCP_PROJECT_ID \ --member='user:test-user@gmail.com' \ --role='roles/pubsub.editor'
在 gcloud 中设置人员管理员账号
在以下示例中,将 $ADMIN_ACCOUNT 替换为您要使用的管理员账号(例如:myaccount@gmail.com):
$ gcloud config set account $ADMIN_ACCOUNT
设置服务账号
默认情况下,Cloud Run 服务或作业以 默认 Compute Engine 服务账号的身份运行。 我们建议您为每个 Cloud Run 服务分配一个用户代管式服务账号,并为其授予最低必需权限集,而不是使用默认服务账号,从而为该服务提供专用身份。如果您打算保留默认服务账号,则可以跳到设置环境变量。
为每个 Cloud Run 运行时创建两个服务账号
如需创建服务账号,请替换
$CONNECTOR_SERVICE_ACCOUNT_ID和$INTERCEPTOR_SERVICE_ACCOUNT_ID的值(如果存在),然后运行以下命令:$ export CONNECTOR_SERVICE_ACCOUNT_ID='aa-ui-connector' && gcloud iam service-accounts create $CONNECTOR_SERVICE_ACCOUNT_ID \ --description='Agent Assist integration - UI connector service account' \ --display-name='Agent Assist integration - UI connector' $ export INTERCEPTOR_SERVICE_ACCOUNT_ID='aa-pubsub-interceptor' && gcloud iam service-accounts create $INTERCEPTOR_SERVICE_ACCOUNT_ID \ --description='Agent Assist integration - Pubsub interceptor service account' \ --display-name='Agent Assist integration - Pubsub interceptor'
使用以下示例命令向界面连接器和 Cloud Pub/Sub 连接器服务账号分配以下角色:
$ gcloud projects add-iam-policy-binding $GCP_PROJECT_ID \ --member='serviceAccount:$CONNECTOR_SERVICE_ACCOUNT_ID@$GCP_PROJECT_ID.iam.gserviceaccount.com' \ --role='roles/pubsub.editor'
向界面连接器服务帐号授予以下 IAM 角色:
roles/redis.editorroles/vpcaccess.userroles/compute.viewerroles/secretmanager.secretAccessorroles/dialogflow.agentAssistClient
向 Cloud Pub/Sub 连接器服务帐号授予以下角色:
roles/redis.editorroles/vpcaccess.userroles/compute.viewer
设置环境变量
将以下环境变量的值设置为您刚刚创建的服务账号或 项目中的默认 Compute Engine 服务账号 。
CONNECTOR_SERVICE_ACCOUNT:界面连接器运行时的服务帐号。 示例:aa-ui-connector@my-project-id.iam.gserviceaccount.com。INTERCEPTOR_SERVICE_ACCOUNT:Cloud Pub/Sub 拦截器运行时的服务帐号。示例:aa-pubsub-interceptor@my-project-id.iam.gserviceaccount.com。
自定义用户身份验证方法
代码库同时支持后端用户以及 Genesys Cloud 和 Twilio 的前端模块用户。
- 在代码库中,打开
ui_connector/auth.py文件。 通过设置环境变量
AUTH_OPTION指定受支持的身份提供方,或使用auth.check_auth实现您的身份验证方法。默认情况下,
AUTH_OPTION为空,并且不允许任何用户向界面连接器服务注册 JWT。 支持的值:Salesforce:使用 Salesforce OpenID Connect 验证身份验证令牌。所需环境变量:SALESFORCE_ORGANIZATION_ID。SalesforceLWC:使用oauth2/userinfoREST 端点验证 Salesforce OAuth 客户端凭据身份验证令牌。所需环境变量:SALESFORCE_ORGANIZATION_ID、SALESFORCE_DOMAIN。GenesysCloud:使用 Genesys SDK UsersAPI 验证身份验证令牌。Twilio:验证 Twilio 的身份验证令牌。所需环境变量:TWILIO_FLEX_ENVIRONMENT。Skip:跳过身份验证令牌验证。不得在正式版中使用。
示例:
$ export AUTH_OPTION='Salesforce'
每种令牌类型可能具有不同的验证方式。您可以决定如何验证令牌。如果不进行任何更改,
auth.check_auth会为每个请求返回false。
自定义允许的来源(推荐)
如需限制可以访问您的服务的来源,请更改 config.CORS_ALLOWED_ORIGINS 变量的值。默认值 * 将允许任何来源访问您的服务。
生成并存储 JWT 密钥
为了让界面连接器服务将安全身份验证令牌发送回客户端,它必须使用 JWT 密钥对其进行加密。密钥的值可以是任何任意字符串,但它应该是唯一的且难以猜测。
此密钥将存储在 Secret Manager 中。
设置环境变量
JWT_SECRET_NAME:Secret Manager 中密钥的名称。它可以是任何任意名称。推荐值:aa-integration-jwt-secret。
生成密钥
我们建议您生成随机哈希作为 JWT 密钥,这样攻击者就无法猜测到该密钥。为此,您可以使用 Python 密钥为其生成 安全的随机数。
# generate_secret_key.py import secrets jwt_secret_key = secrets.token_bytes(16) print(jwt_secret_key) # Output example: b'L\x9b\xd6i4\xc3\x1d\x95\xe3\xf78z\xdda\x97\xec'
将密钥存储在 Secret Manager 中
在以下示例命令中,将 my_key 替换为您计划使用的密钥。
$ python generate_secret_key.py | gcloud secrets create $JWT_SECRET_NAME --data-file=- \ --replication-policy=user-managed --locations=$SERVICE_REGION
设置 Memorystore for Redis
如需设置 Redis,您需要以下环境变量:
VPC_CONNECTOR_NAME:您的 无服务器 VPC 访问通道连接器 的名称,用于将 Cloud Run 服务连接到 Memorystore for Redis。推荐值:aa-integration-vpc。VPC_NETWORK:要将无服务器 VPC 访问通道连接器连接到的 VPC 网络。如果您没有为您的 Google Cloud 项目设置 VPC,则该值应为default。VPC_SUBNET:Redis 实例连接到的授权 VPC 网络的名称。如果您没有自定义 VPC 网络设置,则该值应为default。REDIS_IP_RANGE:无服务器 VPC 访问通道连接器的未保留内部 IP 网络。需要/28的未分配空间。推荐值:10.8.0.0/28(此值应适用于大多数新项目)。REDIS_INSTANCE_ID:Redis 实例的名称。推荐值:aa-integration-redis。
在 Cloud Run 服务所在的区域中创建 Redis 实例
运行以下命令:
$ gcloud redis instances create $REDIS_INSTANCE_ID --size=5 --region=$SERVICE_REGION
您可以使用直接出站流量或无服务器 VPC 访问通道从 Cloud Run 连接到 Redis 实例。
创建无服务器 VPC 访问通道连接器 {:#create-svpca-connector}(可选)
如果客户选择直接出站流量,则此步骤现在是可选的。如果您选择无服务器 VPC 访问通道,则需要创建一个无服务器 VPC 访问通道连接器。如需详细了解此步骤,请参阅 Cloud Run 教程。
验证是否已为您的项目启用无服务器 VPC 访问通道 API:
$ gcloud services enable vpcaccess.googleapis.com
使用自定义 IP 范围创建无服务器 VPC 访问通道连接器:
$ gcloud compute networks vpc-access connectors create $VPC_CONNECTOR_NAME \ --network $VPC_NETWORK \ --region $SERVICE_REGION \ --range $REDIS_IP_RANGE
将 Redis 主机和 Redis 端口另存为环境变量
- 将 Redis 实例的 IP 地址设置为环境变量
REDIS_HOST。 - 将 Redis 实例的端口号设置为环境变量
REDIS_PORT。
部署界面连接器服务
对于界面连接器服务,您需要以下环境变量:
CONNECTOR_SERVICE_NAME:界面连接器的 Cloud Run 服务名称。 推荐值:ui-connector。CONNECTOR_IMAGE_NAME:界面连接器服务的映像名称。它可以与CONNECTOR_SERVICE_NAME相同。推荐值:ui-connector。
构建 Docker 映像
在 /ui-connector 文件夹下,运行以下命令:
$ gcloud builds submit --tag gcr.io/$GCP_PROJECT_ID/$CONNECTOR_IMAGE_NAME
将界面连接器部署到 Cloud Run
在 /ui-connector 文件夹下,
运行以下命令:
- 如果使用直接出站流量连接 Redis 连接。
$ gcloud run deploy $CONNECTOR_IMAGE_NAME \ --image gcr.io/$GCP_PROJECT_ID/$CONNECTOR_IMAGE_NAME \ --platform managed \ --service-account=$CONNECTOR_SERVICE_ACCOUNT_NAME \ --allow-unauthenticated \ --timeout 3600 \ --region $SERVICE_REGION \ --network $VPC_NETWORK \ --subnet $VPC_SUBNET \ --clear-vpc-connector \ --min-instances=1 \ --set-env-vars REDISHOST=$REDIS_HOST,REDISPORT=$REDIS_PORT,GCP_PROJECT_ID=$GCP_PROJECT_ID,AUTH_OPTION=$AUTH_OPTION \ --update-secrets=/secret/jwt_secret_key=${JWT_SECRET_NAME}:latest
- 如果使用创建的无服务器 VPC 访问通道连接器连接 Redis。
$ gcloud run deploy $CONNECTOR_IMAGE_NAME \ --image gcr.io/$GCP_PROJECT_ID/$CONNECTOR_IMAGE_NAME \ --platform managed \ --service-account=$CONNECTOR_SERVICE_ACCOUNT_NAME \ --allow-unauthenticated \ --timeout 3600 \ --region $SERVICE_REGION \ --vpc-connector $VPC_CONNECTOR_NAME \ --clear-network \ --min-instances=1 \ --no-cpu-throttling \ --set-env-vars REDISHOST=$REDIS_HOST,REDISPORT=$REDIS_PORT,GCP_PROJECT_ID=$GCP_PROJECT_ID,AUTH_OPTION=$AUTH_OPTION \ --update-secrets=/secret/jwt_secret_key=${JWT_SECRET_NAME}:latest
记下已部署的界面连接器的服务网址,客户端(代理桌面)将使用该网址。
部署 Cloud Pub/Sub 拦截器服务
对于 Pub/Sub 拦截器服务,您需要以下环境变量:
INTERCEPTOR_SERVICE_NAME:Cloud Pub/Sub 拦截器的 Cloud Run 服务名称。推荐值:cloud-pubsub-interceptor。INTERCEPTOR_IMAGE_NAME:Cloud Pub/Sub 拦截器服务的映像名称。它可以与INTERCEPTOR_SERVICE_NAME相同。推荐值:cloud-pubsub-interceptor。INTERCEPTOR_SERVICE_ACCOUNT_NAME:Cloud Pub/Sub 拦截器运行时的服务帐号。
构建 Docker 映像
在 /cloud-pubsub-interceptor 文件夹下,运行以下命令:
$ gcloud builds submit --tag gcr.io/$GCP_PROJECT_ID/$INTERCEPTOR_IMAGE_NAME
将 Pub/Sub 拦截器部署到 Cloud Run
在 /cloud-pubsub-interceptor 文件夹下,运行以下命令:
- 如果使用直接出站流量连接 Redis 连接。
$ gcloud run deploy $INTERCEPTOR_SERVICE_NAME \ --image gcr.io/$GCP_PROJECT_ID/$INTERCEPTOR_IMAGE_NAME \ --platform managed \ --service-account=$INTERCEPTOR_SERVICE_ACCOUNT_NAME \ --region $SERVICE_REGION \ --network $VPC_NETWORK \ --subnet $VPC_SUBNET \ --clear-vpc-connector \ --ingress=internal \ --min-instances=1 \ --no-cpu-throttling \ # You can also add LOGGING_FILE here to specify the logging file path on Cloud Run. --set-env-vars REDISHOST=$REDIS_HOST,REDISPORT=$REDIS_PORT
- 如果使用创建的无服务器 VPC 访问通道连接器连接 Redis。
$ gcloud run deploy $INTERCEPTOR_SERVICE_NAME \ --image gcr.io/$GCP_PROJECT_ID/$INTERCEPTOR_IMAGE_NAME \ --platform managed \ --service-account=$INTERCEPTOR_SERVICE_ACCOUNT_NAME \ --region $SERVICE_REGION \ --vpc-connector $VPC_CONNECTOR_NAME \ --clear-network \ --ingress=internal \ --min-instances=1 \ # You can also add LOGGING_FILE here to specify the logging file path on Cloud Run. --set-env-vars REDISHOST=$REDIS_HOST,REDISPORT=$REDIS_PORT
保存已部署的网址
将已部署的网址设置为 INTERCEPTOR_SERVICE_URL 环境变量。
配置 Cloud Pub/Sub 订阅
Cloud Pub/Sub 订阅使用以下内容:
- 主题
- 对话配置文件
- 服务账号
- 拦截器服务的服务账号权限
创建 Cloud Pub/Sub 主题
为 Dialogflow 中所需的每种事件通知创建一个 Cloud Pub/Sub 主题。可用的事件通知类型包括:
- 新建议事件:当有新的 Agent Assist 建议可用时发送的事件(例如,针对客户话语的新智能回复建议)。
- 新消息事件:每当从代理或客户处识别出新话语时发送的事件(例如,客户说
Hi)。 - 新对话生命周期事件:针对某些对话生命周期更改发送的事件(例如,当对话开始或完成时)。
- 新识别结果通知事件:当从代理或客户处识别出中间脚本时发送的事件(例如,客户说
Hi, how can I help you?, 中间脚本为Hi how can,而客户正在说话)。
记下主题 ID 和主题名称,以供日后进行后端部署。
配置对话配置文件
使用您在上一步中创建的 Cloud Pub/Sub 主题配置对话配置文件。
- 创建新的对话配置文件时,依次选择 Pub/Sub 通知 和 启用 Pub/Sub 通知 。启用后,您可以勾选要启用的通知类型旁边的复选框,然后输入通知关联的 Cloud Pub/Sub 主题的主题 ID。
- 为每个主题选择
JSON作为消息格式。
为 Pub/Sub 订阅身份创建服务帐号
使用以下命令创建一个代表 Pub/Sub 订阅身份的服务帐号:
$ gcloud iam service-accounts create cloud-run-pubsub-invoker \ --display-name "Cloud Run Pub/Sub Invoker"
授予服务帐号调用拦截器服务的权限
运行以下命令:
$ gcloud run services add-iam-policy-binding $INTERCEPTOR_SERVICE_NAME \ --member=serviceAccount:cloud-run-pubsub-invoker@$GCP_PROJECT_ID.iam.gserviceaccount.com \ --role=roles/run.invoker
为主题创建 Cloud Pub/Sub 订阅
对于您创建的每个主题,您都必须创建一个对应的 Cloud Pub/Sub 订阅。
新建议事件
将 your-new-suggestion-topic-id 替换为您为新建议配置的 Cloud Pub/Sub 主题:
$ export TOPIC_ID='your-new-suggestion-topic-id' && gcloud pubsub subscriptions create $SUBSCRIPTION_NAME --topic $TOPIC_ID \ --push-endpoint=$INTERCEPTOR_SERVICE_URL/human-agent-assistant-event \ --push-auth-service-account=cloud-run-pubsub-invoker@$GCP_PROJECT_ID.iam.gserviceaccount.com
新消息事件
将 your-new-message-event-topic-id 替换为您为新消息事件配置的 Cloud Pub/Sub 主题:
$ export TOPIC_ID='your-new-message-event-topic-id' && gcloud pubsub subscriptions create $SUBSCRIPTION_NAME --topic $TOPIC_ID \ --push-endpoint=$INTERCEPTOR_SERVICE_URL/new-message-event \ --push-auth-service-account=cloud-run-pubsub-invoker@$GCP_PROJECT_ID.iam.gserviceaccount.com
对话生命周期事件
将 your-conversation-lifecycle-event-topic 替换为您为新对话生命周期事件配置的 Cloud Pub/Sub 主题:
$ export TOPIC_ID='your-conversation-lifecycle-event-topic' && gcloud pubsub subscriptions create $SUBSCRIPTION_NAME --topic $TOPIC_ID \ --push-endpoint=$INTERCEPTOR_SERVICE_URL/conversation-lifecycle-event \ --push-auth-service-account=cloud-run-pubsub-invoker@$GCP_PROJECT_ID.iam.gserviceaccount.com
新识别结果通知事件
$ export TOPIC_ID='your-new-recognition-result-notification-event-topic' && gcloud pubsub subscriptions create $SUBSCRIPTION_NAME --topic $TOPIC_ID \ --push-endpoint=$INTERCEPTOR_SERVICE_URL/new-recognition-result-notification-event \ --push-auth-service-account=cloud-run-pubsub-invoker@$GCP_PROJECT_ID.iam.gserviceaccount.com