よくある質問のアシスト

よくある質問のアシストは、エンドユーザーとの会話中に、人間のエージェントに対するよくある質問の回答を提案します。この機能を使用すると、人間のエージェントが会話中にエンドユーザーのよくある質問に回答できるようになります。

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 メソッドと URL:

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 メソッドを呼び出しますKnowledgeTypeFAQ に設定する。この例では、一般公開されている Cloud Storage バケットにアップロードされた Cloud Storage のよくある質問のドキュメントを使用します。独自のシステムで記事の候補を設定する場合、ドキュメントは次のいずれかの形式にする必要があります。ドキュメントのベストプラクティスについて詳しくは、ナレッジ ドキュメントのドキュメントをご覧ください。

よくある質問のドキュメントは、次の 3 つの形式のいずれかで作成できます。

  • 公開 URL。
  • .csv ファイルへの GCS パス。
  • .csv ファイル(API リクエストに含める)。

ドキュメントを .csv 形式で作成する場合は 2 列以上が必要です。よくある質問は最初の列にリストし、各質問に対する回答を 2 番目の列にリストする必要があります。よくある質問のそれぞれの質問とそれに関連する回答は FAQ ペアと呼ばれます。.csv ファイルにヘッダー行が含まれていないことを確認します。ドキュメントが公開 URL の場合は、複数の FAQ ペアをリストした FAQ ページでなければなりません。

ベスト プラクティスの詳細については、ナレッジ ドキュメントのドキュメントをご覧ください。

REST とコマンドライン

後述のリクエストのデータを使用する前に、次のように置き換えます。

  • project-id: GCP プロジェクト ID
  • knowledge-base-id: 前回のリクエストから返されたナレッジベース ID
  • document-display-name: 目的のナレッジ ドキュメント名

HTTP メソッドと URL:

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 メソッドと URL:

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

ランタイムに会話を処理する

会話を作成する

エンドユーザーと人間または仮想エージェントとのダイアログが開始されると、会話が作成されます。候補を表示するには、エンドユーザーの参加者と人間のエージェントの参加者を両方とも作成して、会話に加える必要があります。以下のセクションでは、このプロセスについて詳しく説明します。

まず、会話を作成する必要があります。

REST とコマンドライン

会話を作成するには、Conversation リソースの create メソッドを呼び出します。

後述のリクエストのデータを使用する前に、次のように置き換えます。

  • PROJECT_ID: GCP プロジェクト ID
  • CONVERSATION_PROFILE_ID: 会話プロファイルの作成時に受け取った ID

HTTP メソッドと URL:

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 メソッドと URL:

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})
        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 メソッドと URL:

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})
        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 メソッドと URL:

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 メソッドと URL:

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 メソッドと URL:

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 を使用し、会話が進行して新しい候補が利用可能になったときに、候補の通知をアプリケーションに送信します。