常见问题解答辅助

常见问题解答辅助会在与最终用户的对话过程中向人工客服建议相关的常见问题解答。在人工客服与最终用户对话过程中,您可以使用此功能来帮助人工客服回答最终用户的常见问题。

Agent Assist 会跟踪对话并解析存储在知识库中的常见问题解答文档,从而建议最终用户问题的解答。人工客服可以在对话进行时检查这些建议,并决定要与最终用户分享的建议。

本文档将引导您完成使用 API 实现常见问题解答辅助功能,并在运行时从此功能中获取建议的过程。您可以选择在设计过程中使用 Agent Assist 控制台来测试您的文章建议结果,但在运行时必须直接调用 API。如需详细了解如何使用 Agent Assist 控制台测试功能性能,请参阅教程部分

准备工作

在开始本指南之前,请先完成以下操作:

  1. 为您的 GCP 项目启用 Dialogflow API
  2. 为您的项目启用 Data Labeling API

配置对话配置文件

如需获取 Agent Assist 的建议,您必须创建一个包含您已上传的文档的知识库,并配置对话配置文件。如果您不希望直接调用 API,还可以使用 Agent Assist 控制台来执行这些操作。

创建知识库

在开始上传文档之前,您必须先创建一个知识库来放入文档。如需创建知识库,请对 KnowledgeBase 类型调用 create 方法。

REST 和命令行

在使用任何请求数据之前,请先进行以下替换:

  • project-id:您的 GCP 项目 ID
  • knowledge-base-display-name:所需的知识库名称

HTTP 方法和网址:

POST https://dialogflow.googleapis.com/v2/projects/project-id/knowledgeBases

请求 JSON 正文:

{
  "displayName": "knowledge-base-display-name"
}

如需发送您的请求,请展开以下选项之一:

您应该收到类似以下内容的 JSON 响应:

{
  "name": "projects/project-id/knowledgeBases/NDA4MTM4NzE2MjMwNDUxMjAwMA",
  "displayName": "knowledge-base-display-name"
}

knowledgeBases 后面的路径段包含新知识库 ID。

Python

def create_knowledge_base(project_id, display_name):
    """Creates a Knowledge base.

    Args:
        project_id: The GCP project linked with the agent.
        display_name: The display name of the Knowledge base."""
    from google.cloud import dialogflow_v2beta1 as dialogflow

    client = dialogflow.KnowledgeBasesClient()
    project_path = client.common_project_path(project_id)

    knowledge_base = dialogflow.KnowledgeBase(display_name=display_name)

    response = client.create_knowledge_base(
        parent=project_path, knowledge_base=knowledge_base
    )

    print("Knowledge Base created:\n")
    print("Display Name: {}\n".format(response.display_name))
    print("Knowledge ID: {}\n".format(response.name))

创建知识文档

您现在可以向知识库添加文档。如需在知识库中创建文档,请Document 类型调用 create 方法。将 KnowledgeType 设置为 FAQ。本示例使用已上传到公开共享的 Cloud Storage 存储桶的 Cloud Storage 常见问题解答文档。在您自己的系统中设置文章建议时,文档必须采用以下格式之一。如需详细了解文档最佳实践,请参阅“知识文档”文档

常见问题解答文档可以采用以下三种格式之一:

  • 公开网址。
  • .csv 文件的 Cloud Storage 路径。
  • .csv 文件(将添加到 API 请求中)。

如果您的文档采用 .csv 格式,则必须包含两列:“常见问题解答”问题必须在第一列中列出,每个问题的解答必须在第二列中列出。每个“常见问题解答”问题及其相关解答称为常见问题解答对。确保 .csv 文件不包含标题行。如果您的文档是公共网址,则它必须是列出了多个常见问题解答对的常见问题解答页面。

如需了解最佳做法,请参阅“知识文档”文档

REST 和命令行

在使用任何请求数据之前,请先进行以下替换:

  • project-id:您的 GCP 项目 ID
  • knowledge-base-id:上一项请求返回的您的知识库 ID
  • document-display-name:所需的知识文档名称

HTTP 方法和网址:

POST https://dialogflow.googleapis.com/v2/projects/project-id/knowledgeBases/knowledge-base-id/documents

请求 JSON 正文:

{
  "displayName": "document-display-name",
  "mimeType": "text/html",
  "knowledgeTypes": "FAQ",
  "contentUri": "https://cloud.google.com/storage/docs/faq"
}

如需发送您的请求,请展开以下选项之一:

您应该收到类似以下内容的 JSON 响应:

{
  "name": "projects/project-id/operations/ks-add_document-MzA5NTY2MTc5Mzg2Mzc5NDY4OA"
}

该响应是一个长时间运行的操作,您可以轮询该操作以检查是否完成。

Python

def create_document(
    project_id, knowledge_base_id, display_name, mime_type, knowledge_type, content_uri
):
    """Creates a Document.

    Args:
        project_id: The GCP project linked with the agent.
        knowledge_base_id: Id of the Knowledge base.
        display_name: The display name of the Document.
        mime_type: The mime_type of the Document. e.g. text/csv, text/html,
            text/plain, text/pdf etc.
        knowledge_type: The Knowledge type of the Document. e.g. FAQ,
            EXTRACTIVE_QA.
        content_uri: Uri of the document, e.g. gs://path/mydoc.csv,
            http://mypage.com/faq.html."""
    from google.cloud import dialogflow_v2beta1 as dialogflow

    client = dialogflow.DocumentsClient()
    knowledge_base_path = dialogflow.KnowledgeBasesClient.knowledge_base_path(
        project_id, knowledge_base_id
    )

    document = dialogflow.Document(
        display_name=display_name, mime_type=mime_type, content_uri=content_uri
    )

    document.knowledge_types.append(
        getattr(dialogflow.Document.KnowledgeType, knowledge_type)
    )

    response = client.create_document(parent=knowledge_base_path, document=document)
    print("Waiting for results...")
    document = response.result(timeout=120)
    print("Created Document:")
    print(" - Display Name: {}".format(document.display_name))
    print(" - Knowledge ID: {}".format(document.name))
    print(" - MIME Type: {}".format(document.mime_type))
    print(" - Knowledge Types:")
    for knowledge_type in document.knowledge_types:
        print("    - {}".format(KNOWLEDGE_TYPES[knowledge_type]))
    print(" - Source: {}\n".format(document.content_uri))

创建对话配置文件

对话配置文件可配置一组参数,用于控制对话期间向客服人员提出的建议。以下步骤将使用 HumanAgentAssistantConfig 对象创建 ConversationProfile。如果您不希望直接调用 API,还可以使用 Agent Assist 控制台来执行这些操作。

REST 和命令行

如需创建对话配置文件,请对 ConversationProfile 资源调用 create 方法。

noSmallTalk:如果为 true,则在简短对话消息(例如“您好”、“您好吗”等)后不会触发建议。如果为 false,则在简短对话消息后会触发建议。

onlyEndUser:如果为 true,则只有在最终用户消息后才会触发建议。如果为 false,则在最终用户和人工客服消息后都会触发建议。

在使用任何请求数据之前,请先进行以下替换:

  • PROJECT_ID:您的 GCP 项目 ID
  • KNOWLEDGE_BASE_ID:您的知识库 ID

HTTP 方法和网址:

POST https://dialogflow.googleapis.com/v2/projects/PROJECT_ID/conversationProfiles

请求 JSON 正文:

{
  "displayName": "my-conversation-profile-display-name",
  "humanAgentAssistantConfig": {
    "humanAgentSuggestionConfig": {
      "featureConfigs": [
        {
          "suggestionFeature": {
            "type": "FAQ"
          },
          "queryConfig": {
            "knowledgeBaseQuerySource": {
              "knowledgeBases": ["projects/PROJECT_ID/knowledgeBases/KNOWLEDGE_BASE_ID"]
            }
          },
          "enableEventBasedSuggestion": false,
          "enableInlineSuggestion": true,
          "SuggestionTriggerSettings": {
             "noSmallTalk": true,
             "onlyEndUser": true,
           }
        }
      ]
    }
  }
}

如需发送您的请求,请展开以下选项之一:

您应该收到类似以下内容的 JSON 响应:

{
  "name": "projects/PROJECT_ID/conversationProfiles/CONVERSATION_PROFILE_ID",
  "displayName": "my-conversation-profile-display-name",
  "humanAgentAssistantConfig": {
    ...
  }
}

conversationProfiles 后面的路径段包含新对话配置文件 ID。

Python

def create_conversation_profile_article_faq(
    project_id,
    display_name,
    article_suggestion_knowledge_base_id=None,
    faq_knowledge_base_id=None,
):
    """Creates a conversation profile with given values

    Args: project_id:  The GCP project linked with the conversation profile.
        display_name: The display name for the conversation profile to be
        created.
        article_suggestion_knowledge_base_id: knowledge base id for article
        suggestion.
        faq_knowledge_base_id: knowledge base id for faq."""

    client = dialogflow.ConversationProfilesClient()
    project_path = client.common_project_path(project_id)

    conversation_profile = {
        "display_name": display_name,
        "human_agent_assistant_config": {
            "human_agent_suggestion_config": {"feature_configs": []}
        },
        "language_code": "en-US",
    }

    if article_suggestion_knowledge_base_id is not None:
        as_kb_path = dialogflow.KnowledgeBasesClient.knowledge_base_path(
            project_id, article_suggestion_knowledge_base_id
        )
        feature_config = {
            "suggestion_feature": {"type_": "ARTICLE_SUGGESTION"},
            "suggestion_trigger_settings": {
                "no_small_talk": True,
                "only_end_user": True,
            },
            "query_config": {
                "knowledge_base_query_source": {"knowledge_bases": [as_kb_path]},
                "max_results": 3,
            },
        }
        conversation_profile["human_agent_assistant_config"][
            "human_agent_suggestion_config"
        ]["feature_configs"].append(feature_config)
    if faq_knowledge_base_id is not None:
        faq_kb_path = dialogflow.KnowledgeBasesClient.knowledge_base_path(
            project_id, faq_knowledge_base_id
        )
        feature_config = {
            "suggestion_feature": {"type_": "FAQ"},
            "suggestion_trigger_settings": {
                "no_small_talk": True,
                "only_end_user": True,
            },
            "query_config": {
                "knowledge_base_query_source": {"knowledge_bases": [faq_kb_path]},
                "max_results": 3,
            },
        }
        conversation_profile["human_agent_assistant_config"][
            "human_agent_suggestion_config"
        ]["feature_configs"].append(feature_config)

    response = client.create_conversation_profile(
        parent=project_path, conversation_profile=conversation_profile
    )

    print("Conversation Profile created:")
    print("Display Name: {}".format(response.display_name))
    # Put Name is the last to make it easier to retrieve.
    print("Name: {}".format(response.name))
    return response

(可选)设置安全设置

您可以选择设置安全参数以解决数据隐去和数据保留等问题。为此,您必须创建一个 SecuritySettings 资源,然后使用 securitySettings 字段 将其关联到某个对话配置文件。

添加到对话配置文件中的安全设置只会影响 Agent Assist 短信的行为。Dialogflow 互动历史记录的行为由 Dialogflow 的安全设置控制,您可以使用 Dialogflow CX 控制台进行设置。

在运行时处理对话

创建对话

当最终用户与人工或虚拟客服之间开始对话时,您需要创建对话如需查看建议,您还必须创建最终用户参与者和人工客服参与者,并将其添加到对话中。以下部分将引导您完成此过程。

首先,您必须创建一个对话:

REST 和命令行

如需创建对话,请对 Conversation 资源调用 create 方法。

在使用任何请求数据之前,请先进行以下替换:

  • PROJECT_ID:您的 GCP 项目 ID
  • CONVERSATION_PROFILE_ID:您在创建对话配置文件时收到的 ID

HTTP 方法和网址:

POST https://dialogflow.googleapis.com/v2/projects/PROJECT_ID/conversations

请求 JSON 正文:

{
  "conversationProfile": "projects/PROJECT_ID/conversationProfiles/CONVERSATION_PROFILE_ID",
}

如需发送您的请求,请展开以下选项之一:

您应该收到类似以下内容的 JSON 响应:

{
  "name": "projects/PROJECT_ID/conversations/CONVERSATION_ID",
  "lifecycleState": "IN_PROGRESS",
  "conversationProfile": "projects/PROJECT_ID/conversationProfiles/CONVERSATION_PROFILE_ID",
  "startTime": "2018-11-05T21:05:45.622Z"
}

conversations 后面的路径段包含新对话 ID。

Python

def create_conversation(project_id, conversation_profile_id):
    """Creates a conversation with given values

    Args:
        project_id:  The GCP project linked with the conversation.
        conversation_profile_id: The conversation profile id used to create
        conversation."""

    client = dialogflow.ConversationsClient()
    conversation_profile_client = dialogflow.ConversationProfilesClient()
    project_path = client.common_project_path(project_id)
    conversation_profile_path = conversation_profile_client.conversation_profile_path(
        project_id, conversation_profile_id
    )
    conversation = {"conversation_profile": conversation_profile_path}
    response = client.create_conversation(
        parent=project_path, conversation=conversation
    )

    print("Life Cycle State: {}".format(response.lifecycle_state))
    print("Conversation Profile Name: {}".format(response.conversation_profile))
    print("Name: {}".format(response.name))
    return response

创建最终用户参与者

您必须将最终用户参与者和人工客服参与者添加到对话中才能查看建议。首先,将最终用户参与者添加到对话中:

REST 和命令行

如需创建最终用户参与者,请对 Participant 资源调用 create 方法。

在使用任何请求数据之前,请先进行以下替换:

  • PROJECT_ID:您的 GCP 项目 ID
  • CONVERSATION_ID:您的对话 ID

HTTP 方法和网址:

POST https://dialogflow.googleapis.com/v2/projects/PROJECT_ID/conversations/CONVERSATION_ID/participants

请求 JSON 正文:

{
  "role": "END_USER",
}

如需发送您的请求,请展开以下选项之一:

您应该收到类似以下内容的 JSON 响应:

{
  "name": "projects/PROJECT_ID/conversations/CONVERSATION_ID/participants/PARTICIPANT_ID",
  "role": "END_USER"
}

participants 后面的路径段包含新的最终用户参与者 ID。

Python

def create_participant(project_id, conversation_id, role):
    """Creates a participant in a given conversation.

    Args:
        project_id: The GCP project linked with the conversation profile.
        conversation_id: Id of the conversation.
        participant: participant to be created."""

    client = dialogflow.ParticipantsClient()
    conversation_path = dialogflow.ConversationsClient.conversation_path(
        project_id, conversation_id
    )
    if role in ROLES:
        response = client.create_participant(
            parent=conversation_path, participant={"role": role}, timeout=600
        )
        print("Participant Created.")
        print("Role: {}".format(response.role))
        print("Name: {}".format(response.name))

        return response

创建人工客服参与者

将人工客服参与者添加到对话中:

REST 和命令行

如需创建人工客服参与者,请对 Participant 资源调用 create 方法。

在使用任何请求数据之前,请先进行以下替换:

  • PROJECT_ID:您的 GCP 项目 ID
  • CONVERSATION_ID:您的对话 ID

HTTP 方法和网址:

POST https://dialogflow.googleapis.com/v2/projects/PROJECT_ID/conversations/CONVERSATION_ID/participants

请求 JSON 正文:

{
  "role": "HUMAN_AGENT",
}

如需发送您的请求,请展开以下选项之一:

您应该收到类似以下内容的 JSON 响应:

{
  "name": "projects/PROJECT_ID/conversations/CONVERSATION_ID/participants/PARTICIPANT_ID",
  "role": "HUMAN_AGENT"
}

participants 后面的路径段包含新的人工客服参与者 ID。

Python

def create_participant(project_id, conversation_id, role):
    """Creates a participant in a given conversation.

    Args:
        project_id: The GCP project linked with the conversation profile.
        conversation_id: Id of the conversation.
        participant: participant to be created."""

    client = dialogflow.ParticipantsClient()
    conversation_path = dialogflow.ConversationsClient.conversation_path(
        project_id, conversation_id
    )
    if role in ROLES:
        response = client.create_participant(
            parent=conversation_path, participant={"role": role}, timeout=600
        )
        print("Participant Created.")
        print("Role: {}".format(response.role))
        print("Name: {}".format(response.name))

        return response

添加和分析人工客服的消息

每次任一参与者在对话中输入消息时,您都需要向 API 发送该消息以进行处理。Agent Assist 的建议基于对人工客服和最终用户消息的分析。在以下示例中,人工客服通过询问“您需要什么帮助?”来开始对话。响应中尚未返回任何建议。

REST 和命令行

如需为对话添加和分析人工客服消息,请对 Participant 资源调用 analyzeContent 方法。

在使用任何请求数据之前,请先进行以下替换:

  • PROJECT_ID:您的 GCP 项目 ID
  • CONVERSATION_ID:您的对话 ID
  • PARTICIPANT_ID:您的人工客服参与者 ID

HTTP 方法和网址:

POST https://dialogflow.googleapis.com/v2/projects/PROJECT_ID/conversations/CONVERSATION_ID/participants/PARTICIPANT_ID:analyzeContent

请求 JSON 正文:

{
  "textInput": {
    "text": "How may I help you?",
    "languageCode": "en-US"
  }
}

如需发送您的请求,请展开以下选项之一:

您应该收到类似以下内容的 JSON 响应:

      {
        "message": {
          "name": "projects/PROJECT_ID/conversations/CONVERSATION_ID/messages/MESSAGE_ID",
          "content": "How may I help you?",
          "languageCode": "en-US",
          "participant": "PARTICIPANT_ID",
          "participantRole": "HUMAN_AGENT",
          "createTime": "2020-02-13T00:01:30.683Z"
        },
        "humanAgentSuggestionResults": [
          {
            "suggestArticlesResponse": {
              "latestMessage": "projects/PROJECT_ID/conversations/CONVERSATION_ID/messages/MESSAGE_ID",
              "contextSize": 1
            }
          }
        ]
      }
    }
  ]
}

Python

def analyze_content_text(project_id, conversation_id, participant_id, text):
    """Analyze text message content from a participant.

    Args:
        project_id: The GCP project linked with the conversation profile.
        conversation_id: Id of the conversation.
        participant_id: Id of the participant.
        text: the text message that participant typed."""

    client = dialogflow.ParticipantsClient()
    participant_path = client.participant_path(
        project_id, conversation_id, participant_id
    )
    text_input = {"text": text, "language_code": "en-US"}
    response = client.analyze_content(
        participant=participant_path, text_input=text_input
    )
    print("AnalyzeContent Response:")
    print("Reply Text: {}".format(response.reply_text))

    for suggestion_result in response.human_agent_suggestion_results:
        if suggestion_result.error is not None:
            print("Error: {}".format(suggestion_result.error.message))
        if suggestion_result.suggest_articles_response:
            for answer in suggestion_result.suggest_articles_response.article_answers:
                print("Article Suggestion Answer: {}".format(answer.title))
                print("Answer Record: {}".format(answer.answer_record))
        if suggestion_result.suggest_faq_answers_response:
            for answer in suggestion_result.suggest_faq_answers_response.faq_answers:
                print("Faq Answer: {}".format(answer.answer))
                print("Answer Record: {}".format(answer.answer_record))
        if suggestion_result.suggest_smart_replies_response:
            for (
                answer
            ) in suggestion_result.suggest_smart_replies_response.smart_reply_answers:
                print("Smart Reply: {}".format(answer.reply))
                print("Answer Record: {}".format(answer.answer_record))

    for suggestion_result in response.end_user_suggestion_results:
        if suggestion_result.error:
            print("Error: {}".format(suggestion_result.error.message))
        if suggestion_result.suggest_articles_response:
            for answer in suggestion_result.suggest_articles_response.article_answers:
                print("Article Suggestion Answer: {}".format(answer.title))
                print("Answer Record: {}".format(answer.answer_record))
        if suggestion_result.suggest_faq_answers_response:
            for answer in suggestion_result.suggest_faq_answers_response.faq_answers:
                print("Faq Answer: {}".format(answer.answer))
                print("Answer Record: {}".format(answer.answer_record))
        if suggestion_result.suggest_smart_replies_response:
            for (
                answer
            ) in suggestion_result.suggest_smart_replies_response.smart_reply_answers:
                print("Smart Reply: {}".format(answer.reply))
                print("Answer Record: {}".format(answer.answer_record))

    return response

添加最终用户的消息并获取建议

响应客服人员时,最终用户询问“如何注册?”。响应包含建议的最终用户问题解答列表以及每个解答的置信度分数。所有解答都来自本教程前面添加的单个常见问题解答知识文档。置信度阈值是指模型的每个常见问题解答建议与客服人员的请求相关的置信度水平。置信度值越高,相关响应返回的可能性就越高;但是,如果没有可用的选项达到高阈值,则可能会导致返回的响应较少或无响应返回。我们建议起始置信度分数值为 0.4。如果需要,您可以稍后调整此值以改善结果。

响应还包含解答的 source,即解答来自的知识文档。您应该向人工客服提供建议的解答,他们可能会选择向最终用户提供此信息。

REST 和命令行

如需为对话添加和分析最终用户消息,请对 Participant 资源调用 analyzeContent 方法。

在使用任何请求数据之前,请先进行以下替换:

  • PROJECT_ID:您的 GCP 项目 ID
  • CONVERSATION_ID:您的对话 ID
  • PARTICIPANT_ID:最终用户参与者 ID

HTTP 方法和网址:

POST https://dialogflow.googleapis.com/v2/projects/PROJECT_ID/conversations/CONVERSATION_ID/participants/PARTICIPANT_ID:analyzeContent

请求 JSON 正文:

{
  "textInput": {
    "text": "How do I sign up?",
    "languageCode": "en-US"
  }
}

如需发送您的请求,请展开以下选项之一:

您应该收到类似以下内容的 JSON 响应:

{
  "message": {
    "name": "projects/PROJECT_ID/conversations/fiiJBeHnQIa6Zx_DUKNlEg/messages/Rjv8ErKYS_yIqVR9SW4CpA",
    "content": "How may I help you?",
    "languageCode": "en-US",
    "participant": "PaZQyeiTQgCOyliHkZjs0Q",
    "participantRole": "HUMAN_AGENT",
    "createTime": "1970-01-01T00:00:00Z"
  },
  "humanAgentSuggestionResults": [
    {
      "suggestFaqAnswersResponse": {
        "faqAnswers": [
          {
            "answer": "Sign up for Cloud Storage by turning on the Cloud Storage service in the Google Cloud Platform Console.",
            "confidence": 0.07266401,
            "question": "How do I sign up?",
            "source": "projects/PROJECT_ID/knowledgeBases/NjQ2MzI1MDQwNTQ2MjYzODU5Mg/documents/NTMxOTA4MTAxMzQxMjg4ODU3Ng",
            "metadata": {
              "document_display_name": "my-document-display-name"
            },
            "answerRecord": "projects/PROJECT_ID/answerRecords/MTU0MzE0NDQwOTAwNzEyODU3NjA"
          },
          {
            "answer": "Consider storing your data in a multi-regional or dual-regional bucket location if high availability is a top requirement. This ensures that your data is stored in at least two geographically separated regions, providing continued availability even in the rare event of a region-wide outage, including ones caused by natural disasters. All data, regardless of storage class, is stored geo-redundantly in these types of locations, which allows you to use storage lifecycle management without giving up high availability.",
            "confidence": 0.06937904,
            "question": "How can I maximize the availability of my data?",
            "source": "projects/PROJECT_ID/knowledgeBases/NjQ2MzI1MDQwNTQ2MjYzODU5Mg/documents/NTMxOTA4MTAxMzQxMjg4ODU3Ng",
            "metadata": {
              "document_display_name": "my-document-display-name"
            },
            "answerRecord": "projects/PROJECT_ID/answerRecords/MzkwMjIyOTA0NDAwMjgxNjAwMA"
          },
          {
            "answer": "From the Cloud Storage documentation click \"Send feedback\" near the top right of the page. This will open a feedback form. Your comments will be reviewed by the Cloud Storage team.",
            "confidence": 0.069021806,
            "question": "How do I give product feedback?",
            "source": "projects/PROJECT_ID/knowledgeBases/NjQ2MzI1MDQwNTQ2MjYzODU5Mg/documents/NTMxOTA4MTAxMzQxMjg4ODU3Ng",
            "metadata": {
              "document_display_name": "my-document-display-name"
            },
            "answerRecord": "projects/PROJECT_ID/answerRecords/MTMxMjU2MDEwODA4NTc1OTE4MDg"
          },
          {
            "answer": "Read the Pricing page for detailed information on pricing, including how Cloud Storage calculates bandwidth and storage usage.",
            "confidence": 0.06681696,
            "question": "Where can I find pricing information?",
            "source": "projects/PROJECT_ID/knowledgeBases/NjQ2MzI1MDQwNTQ2MjYzODU5Mg/documents/NTMxOTA4MTAxMzQxMjg4ODU3Ng",
            "metadata": {
              "document_display_name": "my-document-display-name"
            },
            "answerRecord": "projects/PROJECT_ID/answerRecords/ODUxMzkxNTA2MjQzMDIwMzkwNA"
          },
          {
            "answer": "Use Object Versioning. The Object Versioning feature keeps an archived version of an object whenever you overwrite or delete the live version. If you accidentally delete an object, you can copy an archived version of it back to the live version. It's recommended that you use Object Versioning in conjunction with Object Lifecycle Management. Doing so ensures that you don't have multiple, unnecessary copies of an object, which are each subject to storage costs. Caution: Object Versioning does not protect your data if you delete the entire bucket. As an alternative, use object holds. When you place an object hold on an object, it cannot be deleted or overwritten.",
            "confidence": 0.06453417,
            "question": "How do I protect myself from accidental data deletion?",
            "source": "projects/PROJECT_ID/knowledgeBases/NjQ2MzI1MDQwNTQ2MjYzODU5Mg/documents/NTMxOTA4MTAxMzQxMjg4ODU3Ng",
            "metadata": {
              "document_display_name": "my-document-display-name"
            },
            "answerRecord": "projects/PROJECT_ID/answerRecords/MTc3MzcyODcwOTkyODQ5Nzk3MTI"
          },
          {
            "answer": "You can share an individual object with a user or group by adding an entry to that object's access control list (ACL) that grants the user or group READ permission. For step-by-step instructions, see Changing ACLs.",
            "confidence": 0.06336816,
            "question": "I want to let someone download an individual object. How do I do that?",
            "source": "projects/PROJECT_ID/knowledgeBases/NjQ2MzI1MDQwNTQ2MjYzODU5Mg/documents/NTMxOTA4MTAxMzQxMjg4ODU3Ng",
            "metadata": {
              "document_display_name": "my-document-display-name"
            },
            "answerRecord": "projects/PROJECT_ID/answerRecords/MTAxOTkyNTI4MjQ4NTY5ODU2MA"
          },
          {
            "answer": "You can simply use the gsutil tool to download the data, even without a Google account. You do not need to activate Cloud Storage or turn on billing for this purpose. You also do not need to create credentials or authenticate to Cloud Storage. The gsutil tool is best installed as part of the Google Cloud SDK package, but may also be downloaded and installed as a stand-alone product.",
            "confidence": 0.061990723,
            "question": "I am just trying to download or access some data that is freely available to the public. How can I do that?",
            "source": "projects/PROJECT_ID/knowledgeBases/NjQ2MzI1MDQwNTQ2MjYzODU5Mg/documents/NTMxOTA4MTAxMzQxMjg4ODU3Ng",
            "metadata": {
              "document_display_name": "my-document-display-name"
            },
            "answerRecord": "projects/PROJECT_ID/answerRecords/MTAyNDMyOTczMTkzNDA0NzQzNjg"
          },
          {
            "answer": "Certain types of content are not allowed on this service; please refer to the Terms of Services and Platform Policies for details. If you believe a piece of content is in violation of our policies, report it here (select See more products, then Google Cloud Storage & Cloud Bigtable).",
            "confidence": 0.060459033,
            "question": "I believe some content hosted on your service is inappropriate, how do I report it?",
            "source": "projects/PROJECT_ID/knowledgeBases/NjQ2MzI1MDQwNTQ2MjYzODU5Mg/documents/NTMxOTA4MTAxMzQxMjg4ODU3Ng",
            "metadata": {
              "document_display_name": "my-document-display-name"
            },
            "answerRecord": "projects/PROJECT_ID/answerRecords/NTYzMTYxMTMwMDkxMzA4NjQ2NA"
          },
          {
            "answer": "For most common Cloud Storage operations, you only need to specify the relevant bucket's name, not the project associated with the bucket. In general, you only need to specify a project identifier when creating a bucket or listing buckets in a project. For more information, see When to specify a project. To find which project contains a specific bucket: If you are searching over a moderate number of projects and buckets, use the Google Cloud Platform Console, select each project, and view the buckets it contains. Otherwise, go to the storage.bucket.get page in the API Explorer and enter the bucket's name in the bucket field. When you click Authorize and Execute, the associated project number appears as part of the response. To get the project name, use the project number in the following terminal command: gcloud projects list | grep [PROJECT_NUMBER]",
            "confidence": 0.05914715,
            "question": "I created a bucket, but don't remember which project I created it in. How can I find it?",
            "source": "projects/PROJECT_ID/knowledgeBases/NjQ2MzI1MDQwNTQ2MjYzODU5Mg/documents/NTMxOTA4MTAxMzQxMjg4ODU3Ng",
            "metadata": {
              "document_display_name": "my-document-display-name"
            },
            "answerRecord": "projects/PROJECT_ID/answerRecords/MTQ4NTQ5ODMzMzc3Njc4NjIyNzI"
          },
          {
            "answer": "Cloud Storage is designed for 99.999999999% (11 9's) annual durability, which is appropriate for even primary storage and business-critical applications. This high durability level is achieved through erasure coding that stores data pieces redundantly across multiple devices located in multiple availability zones. Objects written to Cloud Storage must be redundantly stored in at least two different availability zones before the write is acknowledged as successful. Checksums are stored and regularly revalidated to proactively verify that the data integrity of all data at rest as well as to detect corruption of data in transit. If required, corrections are automatically made using redundant data. Customers can optionally enable object versioning to add protection against accidental deletion.",
            "confidence": 0.05035359,
            "question": "How durable is my data in Cloud Storage?",
            "source": "projects/PROJECT_ID/knowledgeBases/NjQ2MzI1MDQwNTQ2MjYzODU5Mg/documents/NTMxOTA4MTAxMzQxMjg4ODU3Ng",
            "metadata": {
              "document_display_name": "my-document-display-name"
            },
            "answerRecord": "projects/PROJECT_ID/answerRecords/MzMyNTc2ODI5MTY5OTM5MjUxMg"
          }
        ],
        "latestMessage": "projects/PROJECT_ID/conversations/fiiJBeHnQIa6Zx_DUKNlEg/messages/Rjv8ErKYS_yIqVR9SW4CpA",
        "contextSize": 1
      }
    }
  ]
}

Python

def analyze_content_text(project_id, conversation_id, participant_id, text):
    """Analyze text message content from a participant.

    Args:
        project_id: The GCP project linked with the conversation profile.
        conversation_id: Id of the conversation.
        participant_id: Id of the participant.
        text: the text message that participant typed."""

    client = dialogflow.ParticipantsClient()
    participant_path = client.participant_path(
        project_id, conversation_id, participant_id
    )
    text_input = {"text": text, "language_code": "en-US"}
    response = client.analyze_content(
        participant=participant_path, text_input=text_input
    )
    print("AnalyzeContent Response:")
    print("Reply Text: {}".format(response.reply_text))

    for suggestion_result in response.human_agent_suggestion_results:
        if suggestion_result.error is not None:
            print("Error: {}".format(suggestion_result.error.message))
        if suggestion_result.suggest_articles_response:
            for answer in suggestion_result.suggest_articles_response.article_answers:
                print("Article Suggestion Answer: {}".format(answer.title))
                print("Answer Record: {}".format(answer.answer_record))
        if suggestion_result.suggest_faq_answers_response:
            for answer in suggestion_result.suggest_faq_answers_response.faq_answers:
                print("Faq Answer: {}".format(answer.answer))
                print("Answer Record: {}".format(answer.answer_record))
        if suggestion_result.suggest_smart_replies_response:
            for (
                answer
            ) in suggestion_result.suggest_smart_replies_response.smart_reply_answers:
                print("Smart Reply: {}".format(answer.reply))
                print("Answer Record: {}".format(answer.answer_record))

    for suggestion_result in response.end_user_suggestion_results:
        if suggestion_result.error:
            print("Error: {}".format(suggestion_result.error.message))
        if suggestion_result.suggest_articles_response:
            for answer in suggestion_result.suggest_articles_response.article_answers:
                print("Article Suggestion Answer: {}".format(answer.title))
                print("Answer Record: {}".format(answer.answer_record))
        if suggestion_result.suggest_faq_answers_response:
            for answer in suggestion_result.suggest_faq_answers_response.faq_answers:
                print("Faq Answer: {}".format(answer.answer))
                print("Answer Record: {}".format(answer.answer_record))
        if suggestion_result.suggest_smart_replies_response:
            for (
                answer
            ) in suggestion_result.suggest_smart_replies_response.smart_reply_answers:
                print("Smart Reply: {}".format(answer.reply))
                print("Answer Record: {}".format(answer.answer_record))

    return response

完成对话

对话结束后,请使用 API 完成对话。

REST 和命令行

如需完成对话,请对 conversations 资源调用 complete 方法。

在使用任何请求数据之前,请先进行以下替换:

  • PROJECT_ID:您的 GCP 项目 ID
  • CONVERSATION_ID:您在创建对话时收到的 ID

HTTP 方法和网址:

POST https://dialogflow.googleapis.com/v2/projects/PROJECT_ID/conversations/CONVERSATION_ID:complete

如需发送您的请求,请展开以下选项之一:

您应会收到如下所示的 JSON 响应:

{
  "name": "projects/PROJECT_ID/conversations/CONVERSATION_ID",
  "lifecycleState": "COMPLETED",
  "conversationProfile": "projects/PROJECT_ID/conversationProfiles/CONVERSATION_PROFILE_ID",
  "startTime": "2018-11-05T21:05:45.622Z",
  "endTime": "2018-11-06T03:50:26.930Z"
}

Python

def complete_conversation(project_id, conversation_id):
    """Completes the specified conversation. Finished conversations are purged from the database after 30 days.

    Args:
        project_id: The GCP project linked with the conversation.
        conversation_id: Id of the conversation."""

    client = dialogflow.ConversationsClient()
    conversation_path = client.conversation_path(project_id, conversation_id)
    conversation = client.complete_conversation(name=conversation_path)
    print("Completed Conversation.")
    print("Life Cycle State: {}".format(conversation.lifecycle_state))
    print("Conversation Profile Name: {}".format(conversation.conversation_profile))
    print("Name: {}".format(conversation.name))
    return conversation

API 请求选项

以上部分展示了如何创建简单的 ConversationProfile,以便接收建议。以下部分概述了您可以在对话期间实现的一些可选功能。

Pub/Sub 建议通知

在上述部分中,ConversationProfile 是仅通过人工客服助理创建的。在对话期间,您需要调用 API,以便在每个消息添加到对话后接收建议。如果您希望收到建议的通知事件,则可以在创建对话配置文件时设置 notificationConfig 字段。在对话进行且有新建议可用时,此选项会使用 Cloud Pub/Sub 向应用发送建议通知。