Amazon Q in Connectでコンテンツにタグ付けし、コンテンツセグメンテーションを実装してみた

Amazon Q in Connectでコンテンツにタグ付けし、コンテンツセグメンテーションを実装してみた

Clock Icon2025.05.15

はじめに

Amazon Q in Connect は、コンタクトセンター業務を AI で支援するマネージドサービスです。
本サービスには、データソースにタグを付与し、問い合わせに関連するドキュメントだけを絞り込める「コンテンツセグメンテーション」という機能があります。これにより次のメリットが得られます。

  • 回答精度の向上 : 関連性の高い情報だけを検索対象にするため、より正確な回答が可能
  • 応答時間の短縮 : 検索対象が減ることで、必要な情報へ迅速にアクセス
  • 顧客満足度の向上 : 的確でスピーディーな回答により、顧客の課題を早期に解決

利用シーンを具体的にイメージしてみましょう。
金融機関のコンタクトセンターで「クレジットカードの利用限度額を上げたい」という問い合わせが来た場合、通常は「口座開設」「ローン」「投資商品」などを含むナレッジベース全体が検索対象になります。
しかしコンテンツセグメンテーションを用いて「お問い合わせ種別 : クレジットカード関連」というタグが付いたドキュメントのみに絞れば、エージェントは関連度の高い情報だけを即座に参照でき、顧客へ迅速かつ的確に回答できます。

本記事では、この機能を実際に試した手順と結果を紹介します。具体的には次の 2 点を解説します。

  1. S3 に保存したドキュメントへのタグ付け方法
  2. Amazon Connect フローから Lambda を呼び出し、セッション単位でタグフィルターを適用する方法

なお「コンテンツセグメンテーション」という呼称は公式ドキュメントには登場せず、以下の AWS 公式ワークショップで使われている用語です。

Content segmentation filters articles by applied tags, reducing the content considered to just what matches the supplied tag
日本語訳:コンテンツセグメンテーションは適用されたタグによって記事をフィルタリングし、提供されたタグに一致するものだけにコンテンツを絞り込みます

https://catalog.workshops.aws/amazon-q-in-connect/en-US/content-segmentation/configuring-content-tagging

事前準備

  • Amazon Q in Connect のセットアップが完了していること
    (インスタンス作成、ナレッジベースと S3 連携済み)

検証用に、以下 3 つのファイルを S3 バケットへ配置しました。

s3://<bucket-name>/
├── test1/
│   └── classmethod.html   … クラスメソッド公式サイトのトップページ
├── test2/
│   └── tokyo.txt          … 本社所在地を「東京」と記載
└── test3/
    └── sapporo.txt        … 本社所在地を「札幌」と記載

classmethod.htmlはクラスメソッドのトップページです。

tokyo.txtは、クラスメソッド本社が東京にあると記載しています。

tokyo.txt
クラスメソッドの本社
日比谷本社オフィス
〒105-0003 東京都港区西新橋1-1-1 日比谷フォートタワー26階

sapporo.txtは、クラスメソッド本社が札幌にあると記載しています。(実際の本社ではありません。検証のため、本社と記載しました。)

sapporo.txt
クラスメソッドの本社
札幌オフィス
〒060-0003 北海道札幌市中央区北3条西1-1-1 札幌ブリックキューブ10階

コンテンツのタグ付け手順

まず、Connectインスタンスと紐づいている対象のナレッジベースのknowledgeBaseIdを取得します。

AWS CloudShellで以下のコマンドを実行します。

aws qconnect list-knowledge-bases

{
    "knowledgeBaseSummaries": [
        {
            "knowledgeBaseArn": "arn:aws:wisdom:ap-northeast-1:111111111111:knowledge-base/a772458c-e30c-4507-86ba-7e1575bea3cb",
            "knowledgeBaseId": "a772458c-e30c-4507-86ba-7e1575bea3cb",
            "knowledgeBaseType": "EXTERNAL",
            "name": "S3",
            "serverSideEncryptionConfiguration": {
                "kmsKeyId": "arn:aws:kms:ap-northeast-1:111111111111:key/b829c99d-232c-4c8c-9a92-516b5a52a319"
            },
            "sourceConfiguration": {
                "appIntegrations": {
                    "appIntegrationArn": "arn:aws:app-integrations:ap-northeast-1:111111111111:data-integration/5518196f-61a2-44e4-8b72-628761d3ca0c",
                    "objectFields": []
                }
            },
            "status": "ACTIVE",
            "tags": {
                "AmazonConnectEnabled": "True"
            }
        },

対象のナレッジベース名前は、マネジメントコンソール上の[統合名]から確認できます。今回は、S3という名前です。

cm-hirai-screenshot 2025-04-11 11.11.57

次に、ListContents APIにて、対象ナレッジベースのコンテンツリストを取得します。ここで言うコンテンツとは、S3に保存されている各ファイルのことです。

各コンテンツのcontentArnをコピーしておきます。

$ aws qconnect list-contents --knowledge-base-id a772458c-e30c-4507-86ba-7e1575bea3cb
{
    "contentSummaries": [
        {
            "contentArn": "arn:aws:wisdom:ap-northeast-1:111111111111:content/a772458c-e30c-4507-86ba-7e1575bea3cb/764465e0-ee2d-4610-8cd1-f01b2aba296a",
            "contentId": "764465e0-ee2d-4610-8cd1-f01b2aba296a",
            "contentType": "text/html",
            "knowledgeBaseArn": "arn:aws:wisdom:ap-northeast-1:111111111111:knowledge-base/a772458c-e30c-4507-86ba-7e1575bea3cb",
            "knowledgeBaseId": "a772458c-e30c-4507-86ba-7e1575bea3cb",
            "metadata": {
                "aws:wisdom:externalVersion": "0067F76422127CC553",
                "eventName": "CopyObject",
                "s3.bucket.name": "cm-hirai-amazon-connect-q",
                "s3.object.eTag": "19e0aedd52d05800f19355538b53e3d2",
                "s3.object.key": "test1/classmethod.html",
                "s3.object.sequencer": "0067F76422127CC553",
                "s3.object.size": "168896",
                "size": "168896"
            },
            "name": "ff57688378c0cb4135f854fb18bdc524",
            "revisionId": "MTA5NTg5MzhiYmVmMmRlOWM1OTRlMGVjMjliNzRkMWVjZWZkMTYzMjE2YzA2N2ViMzlkYWE1ZjlkMDJkYjU2Nw==",
            "status": "ACTIVE",
            "tags": {},
            "title": "classmethod"
        },
        {
            "contentArn": "arn:aws:wisdom:ap-northeast-1:111111111111:content/a772458c-e30c-4507-86ba-7e1575bea3cb/ad5a8de0-685f-41ec-90b4-3790720c02ce",
            "contentId": "ad5a8de0-685f-41ec-90b4-3790720c02ce",
            "contentType": "text/plain",
            "knowledgeBaseArn": "arn:aws:wisdom:ap-northeast-1:111111111111:knowledge-base/a772458c-e30c-4507-86ba-7e1575bea3cb",
            "knowledgeBaseId": "a772458c-e30c-4507-86ba-7e1575bea3cb",
            "metadata": {
                "aws:wisdom:externalVersion": "0067F7643652742D5B",
                "eventName": "CopyObject",
                "s3.bucket.name": "cm-hirai-amazon-connect-q",
                "s3.object.eTag": "e0b0a19a0d7f15884376b35574ab2a8a",
                "s3.object.key": "test2/tokyo.txt",
                "s3.object.sequencer": "0067F7643652742D5B",
                "s3.object.size": "136",
                "size": "136"
            },
            "name": "56ac0e2048051cc238797934fa9a61c5",
            "revisionId": "YzE3NTgwZjBkZWUyNWRiMmU2Y2I5OTA1ZDM1MWEyYmYxM2FiODc5NDNmZTdlYjVkNjY1ZmZjMTlhYzAwMzI2YQ==",
            "status": "ACTIVE",
            "tags": {},
            "title": "tokyo"
        },
        {
            "contentArn": "arn:aws:wisdom:ap-northeast-1:111111111111:content/a772458c-e30c-4507-86ba-7e1575bea3cb/1f72748a-b558-4008-9507-bd44f13582c7",
            "contentId": "1f72748a-b558-4008-9507-bd44f13582c7",
            "contentType": "text/plain",
            "knowledgeBaseArn": "arn:aws:wisdom:ap-northeast-1:111111111111:knowledge-base/a772458c-e30c-4507-86ba-7e1575bea3cb",
            "knowledgeBaseId": "a772458c-e30c-4507-86ba-7e1575bea3cb",
            "metadata": {
                "aws:wisdom:externalVersion": "0067F7644404F77644",
                "eventName": "CopyObject",
                "s3.bucket.name": "cm-hirai-amazon-connect-q",
                "s3.object.eTag": "2673c95ad06a01ad0276a5c0e0c1c6d4",
                "s3.object.key": "test3/sapporo.txt",
                "s3.object.sequencer": "0067F7644404F77644",
                "s3.object.size": "142",
                "size": "142"
            },
            "name": "54a9dec77aaf8d802d3b6104af14b590",
            "revisionId": "NTJlZTg4ZTlkMzM0ZDkzYWI4MWU2NzY4MDAzNjY3MjMyZGZiMDM1NzNlNzljYTljZDU2Njk5MTYzMjI3ZjU2Mw==",
            "status": "ACTIVE",
            "tags": {},
            "title": "sapporo"
        }
    ]
}

TagResource APIにて、先程取得したリストのコンテンツそれぞれにタグ付けを実行します。

なお、TagResource APIのリクエストパラメータresourceArnは、先ほど取得した各コンテンツのcontentArnです。

ここでは 3 ファイルに categorycontent_type の 2 種類のタグを付けます。

# test1フォルダのコンテンツに「category」と「content_type」タイプのタグを付ける
aws qconnect tag-resource \
  --resource-arn "arn:aws:wisdom:ap-northeast-1:111111111111:content/a772458c-e30c-4507-86ba-7e1575bea3cb/764465e0-ee2d-4610-8cd1-f01b2aba296a" \
  --tags '{"category":"product_info","content_type":"homepage"}'

# test2フォルダのコンテンツに「category」と「content_type」タイプのタグを付ける
aws qconnect tag-resource \
  --resource-arn "arn:aws:wisdom:ap-northeast-1:111111111111:content/a772458c-e30c-4507-86ba-7e1575bea3cb/ad5a8de0-685f-41ec-90b4-3790720c02ce" \
  --tags '{"category":"product_info","content_type":"address_tokyo"}'

# test3フォルダのコンテンツに「category」と「content_type」タイプのタグを付ける
aws qconnect tag-resource \
  --resource-arn "arn:aws:wisdom:ap-northeast-1:111111111111:content/a772458c-e30c-4507-86ba-7e1575bea3cb/1f72748a-b558-4008-9507-bd44f13582c7" \
  --tags '{"category":"product_info","content_type":"address_sapporo"}'

コンテンツがタグ付けされているかも確認できます。

aws qconnect list-tags-for-resource \
--resource-arn "arn:aws:wisdom:ap-northeast-1:111111111111:content/a772458c-e30c-4507-86ba-7e1575bea3cb/1f72748a-b558-4008-9507-bd44f13582c7"

{
    "tags": {
        "content_type": "address_sapporo",
        "category": "product_info"
    }
}

https://awscli.amazonaws.com/v2/documentation/api/latest/reference/qconnect/list-contents.html
https://awscli.amazonaws.com/v2/documentation/api/latest/reference/qconnect/tag-resource.html
https://awscli.amazonaws.com/v2/documentation/api/latest/reference/qconnect/list-tags-for-resource.html

Lambdaを作成する

コンタクトフローから呼び出し、Amazon Q in Connect の「セッション」にタグフィルターを設定する Lambda 関数を作成します。

  • 名前 : cm-hirai-q-in-connect-session-tag-filter-updater
  • ランタイム : Python 3.13
  • 付与するロール : AWSLambdaBasicExecutionRole + 下記インラインポリシー
インラインポリシー
{
    "Version": "2012-10-17",
    "Statement":[
        {
            "Effect": "Allow",
            "Action": [
                "connect:DescribeContact",
                "wisdom:UpdateSession"
            ],
            "Resource": "*"
        }
    ]
}
import json
import boto3
from botocore.exceptions import ClientError

connect_client = boto3.client('connect')
qconnect_client = boto3.client('qconnect')

def lambda_handler(event, context):
    print('Event Received: ' + json.dumps(event, ensure_ascii=False))

    # Connectコンタクトデータとパラメータの取得
    contact_data = event.get('Details', {}).get('ContactData', {})
    tag_filter = event.get('Details', {}).get('Parameters', {}).get('tagFilter')
    print("Tag Filter: ", json.dumps(tag_filter))

    # Amazon Connect Contactの情報を取得
    try:
        contact_response = connect_client.describe_contact(
            InstanceId=contact_data.get('InstanceARN'),
            ContactId=contact_data.get('ContactId')
        ).get("Contact", {})

        print(f"Describe ContactId: {contact_data.get('ContactId')}: {json.dumps(contact_response, default=str)}")
    except ClientError as e:
        error_message = f"ClientError - DescribeContact for ContactId: {contact_data.get('ContactId')} - {e}"
        print(error_message)
        return {"success": False}

    # Amazon Q in Connect セッション情報の抽出
    wisdom_info = contact_response.get("WisdomInfo", {})
    session_arn = wisdom_info.get("SessionArn")

    if not session_arn:
        error_message = f"No Amazon Q in Connect session found for ContactId: {contact_data.get('ContactId')}"
        print(error_message)
        return {"success": False}

    # セッションARNからアシスタントIDとセッションIDを抽出
    try:
        arn_parts = session_arn.split('/')
        assistant_id = arn_parts[1]
        session_id = arn_parts[2]
    except (IndexError, AttributeError) as e:
        error_message = f"Error parsing session ARN: {session_arn} - {e}"
        print(error_message)
        return {"success": False}

    # タグフィルターの処理とセッションの更新
    try:
        # タグフィルターが文字列の場合、JSONオブジェクトに変換
        if isinstance(tag_filter, str):
            try:
                tag_filter_json = json.loads(tag_filter)
            except json.JSONDecodeError:
                error_message = f"Invalid JSON in tagFilter parameter: {tag_filter}"
                print(error_message)
                return {
                    "statusCode": 400,
                    "body": error_message
                }
        else:
            tag_filter_json = tag_filter

        # セッションにタグフィルターを適用
        update_session_response = qconnect_client.update_session(
            assistantId=assistant_id,
            sessionId=session_id,
            tagFilter=tag_filter_json
        ).get("session", {})

        print("Update Session Response: ", json.dumps(update_session_response))
        return {"success": True}
    except Exception as e:
        print(f"Error: {str(e)}")
        return {"success": False}

この関数は以下の処理を行います

  1. コンタクトフローから渡された Contact情報とtagFilter パラメータを受け取る
  2. DescribeContact で Wisdom セッション ARN を取得
  3. ARN から assistantId と sessionId を分解
  4. UpdateSession API に tagFilter を渡してセッションを更新
    → 以降の検索対象が、指定タグを持つコンテンツだけに絞られる

Connectフロー

検証用のフローは下図のとおりです。

cm-hirai-screenshot 2025-04-10 17.29.16

(クリックで展開)
{
  "Version": "2019-10-30",
  "StartAction": "62416ee0-7b7d-406f-8df5-4888d812fa9a",
  "Metadata": {
    "entryPointPosition": {
      "x": 290.4,
      "y": 53.6
    },
    "ActionMetadata": {
      "fba2c05b-c6a2-4795-acaf-200e9f6c39da": {
        "position": {
          "x": 631.2,
          "y": 52.8
        }
      },
      "62416ee0-7b7d-406f-8df5-4888d812fa9a": {
        "position": {
          "x": 404.8,
          "y": 52
        }
      },
      "10d508f7-76b0-4ff6-b084-59ed78c9e1a0": {
        "position": {
          "x": 176.8,
          "y": 238.4
        },
        "children": [
          "b3ab6dc2-902c-411a-b211-7c3128e8abfa"
        ],
        "parameters": {
          "WisdomAssistantArn": {
            "displayName": "arn:aws:wisdom:ap-northeast-1:111111111111:assistant/a1793008-f4de-481b-a9ed-3697ef373ff2"
          }
        },
        "fragments": {
          "SetContactData": "b3ab6dc2-902c-411a-b211-7c3128e8abfa"
        }
      },
      "b3ab6dc2-902c-411a-b211-7c3128e8abfa": {
        "position": {
          "x": 176.8,
          "y": 238.4
        },
        "dynamicParams": []
      },
      "90537ffa-b186-47ec-938f-cca6dc4286db": {
        "position": {
          "x": 404,
          "y": 236.8
        },
        "parameters": {
          "LambdaFunctionARN": {
            "displayName": "cm-hirai-q-in-connect-session-tag-filter-updater"
          },
          "LambdaInvocationAttributes": {
            "tagFilter": {
              "useJson": true
            }
          }
        },
        "dynamicMetadata": {
          "tagFilter": false
        }
      },
      "433d0be0-48cb-44da-a24f-6aa745e3f242": {
        "position": {
          "x": 853.6,
          "y": 224.8
        }
      },
      "d7f03407-1f71-4852-9ca0-1a8e00d17409": {
        "position": {
          "x": 630.4,
          "y": 234.4
        },
        "parameters": {
          "QueueId": {
            "displayName": "cm-hirai"
          }
        },
        "queue": {
          "text": "cm-hirai"
        }
      },
      "8e1110a3-e055-4bf4-9c5a-2b5c2b48f6bc": {
        "position": {
          "x": 863.2,
          "y": 454.4
        }
      }
    },
    "Annotations": [],
    "name": "cm-hirai-q-in-connect-session-tag-filter-updater",
    "description": "",
    "type": "contactFlow",
    "status": "published",
    "hash": {}
  },
  "Actions": [
    {
      "Parameters": {
        "RecordingBehavior": {
          "RecordedParticipants": [
            "Agent",
            "Customer"
          ],
          "ScreenRecordedParticipants": [
            "Agent"
          ],
          "IVRRecordingBehavior": "Disabled"
        },
        "AnalyticsBehavior": {
          "Enabled": "True",
          "AnalyticsLanguage": "ja-JP",
          "AnalyticsRedactionBehavior": "Disabled",
          "AnalyticsRedactionResults": "None",
          "ChannelConfiguration": {
            "Chat": {
              "AnalyticsModes": []
            },
            "Voice": {
              "AnalyticsModes": [
                "PostContact"
              ]
            }
          }
        }
      },
      "Identifier": "fba2c05b-c6a2-4795-acaf-200e9f6c39da",
      "Type": "UpdateContactRecordingBehavior",
      "Transitions": {
        "NextAction": "10d508f7-76b0-4ff6-b084-59ed78c9e1a0"
      }
    },
    {
      "Parameters": {
        "FlowLoggingBehavior": "Enabled"
      },
      "Identifier": "62416ee0-7b7d-406f-8df5-4888d812fa9a",
      "Type": "UpdateFlowLoggingBehavior",
      "Transitions": {
        "NextAction": "fba2c05b-c6a2-4795-acaf-200e9f6c39da"
      }
    },
    {
      "Parameters": {
        "WisdomAssistantArn": "arn:aws:wisdom:ap-northeast-1:111111111111:assistant/a1793008-f4de-481b-a9ed-3697ef373ff2"
      },
      "Identifier": "10d508f7-76b0-4ff6-b084-59ed78c9e1a0",
      "Type": "CreateWisdomSession",
      "Transitions": {
        "NextAction": "b3ab6dc2-902c-411a-b211-7c3128e8abfa",
        "Errors": [
          {
            "NextAction": "90537ffa-b186-47ec-938f-cca6dc4286db",
            "ErrorType": "NoMatchingError"
          }
        ]
      }
    },
    {
      "Parameters": {
        "WisdomSessionArn": "$.Wisdom.SessionArn"
      },
      "Identifier": "b3ab6dc2-902c-411a-b211-7c3128e8abfa",
      "Type": "UpdateContactData",
      "Transitions": {
        "NextAction": "90537ffa-b186-47ec-938f-cca6dc4286db",
        "Errors": [
          {
            "NextAction": "90537ffa-b186-47ec-938f-cca6dc4286db",
            "ErrorType": "NoMatchingError"
          }
        ]
      }
    },
    {
      "Parameters": {
        "LambdaFunctionARN": "arn:aws:lambda:ap-northeast-1:111111111111:function:cm-hirai-q-in-connect-session-tag-filter-updater",
        "InvocationTimeLimitSeconds": "8",
        "LambdaInvocationAttributes": {
          "tagFilter": {
            "tagCondition": {
              "key": "content_type",
              "value": "address_sapporo"
            }
          }
        },
        "ResponseValidation": {
          "ResponseType": "STRING_MAP"
        }
      },
      "Identifier": "90537ffa-b186-47ec-938f-cca6dc4286db",
      "Type": "InvokeLambdaFunction",
      "Transitions": {
        "NextAction": "d7f03407-1f71-4852-9ca0-1a8e00d17409",
        "Errors": [
          {
            "NextAction": "d7f03407-1f71-4852-9ca0-1a8e00d17409",
            "ErrorType": "NoMatchingError"
          }
        ]
      }
    },
    {
      "Parameters": {},
      "Identifier": "433d0be0-48cb-44da-a24f-6aa745e3f242",
      "Type": "TransferContactToQueue",
      "Transitions": {
        "NextAction": "8e1110a3-e055-4bf4-9c5a-2b5c2b48f6bc",
        "Errors": [
          {
            "NextAction": "8e1110a3-e055-4bf4-9c5a-2b5c2b48f6bc",
            "ErrorType": "QueueAtCapacity"
          },
          {
            "NextAction": "8e1110a3-e055-4bf4-9c5a-2b5c2b48f6bc",
            "ErrorType": "NoMatchingError"
          }
        ]
      }
    },
    {
      "Parameters": {
        "QueueId": "arn:aws:connect:ap-northeast-1:111111111111:instance/3ff2093d-af96-43fd-b038-3c07cdd7609c/queue/ba8d05d9-27b3-406e-b089-f5707174697e"
      },
      "Identifier": "d7f03407-1f71-4852-9ca0-1a8e00d17409",
      "Type": "UpdateContactTargetQueue",
      "Transitions": {
        "NextAction": "433d0be0-48cb-44da-a24f-6aa745e3f242",
        "Errors": [
          {
            "NextAction": "8e1110a3-e055-4bf4-9c5a-2b5c2b48f6bc",
            "ErrorType": "NoMatchingError"
          }
        ]
      }
    },
    {
      "Parameters": {},
      "Identifier": "8e1110a3-e055-4bf4-9c5a-2b5c2b48f6bc",
      "Type": "DisconnectParticipant",
      "Transitions": {}
    }
  ]
}

Lambda ブロックの設定

[AWS Lambda 関数を呼び出す] ブロックに、前項で作成した Lambda を指定し、パラメータ tagFilter に次の JSON を渡します。
この設定により、content_type=address_sapporo のタグを持つコンテンツだけが検索対象になります。
(実際に利用する場合は、前段でIVRなどでお客様のお問い合わせ内容に応じて動的にフィルタリングしますが、今回は検証なので、シンプルなフローで検証します。)

{
	"tagCondition": {
		"key": "content_type",
		"value": "address_sapporo"
	}
}

cm-hirai-screenshot 2025-04-11 11.36.52

UpdateSession API の TagFilter 仕様

UpdateSessiontagFilter は「Tagged Union」形式で、トップレベルには次の 3 つのいずれか 1 つしか指定できません。

  1. andConditions
  2. orConditions
  3. tagCondition(単一条件)

ドキュメントには明確に記載されています。

This is a Tagged Union structure. Only one of the following top level keys can be set: andConditions, orConditions, tagCondition.

つまり、これらの条件を同時に使用することはできません。1つのリクエストで指定できるのは、これらのうちの1つだけです。

ただし、それぞれの条件内で複雑な条件を構築することは可能です。

  • andConditionsでは複数のタグ条件をAND条件で結合できます
  • orConditionsでは複数の条件をOR条件で結合でき、その中にandConditionstagConditionを含めることができます
  • tagConditionは単一のタグキーと値のペアを指定します

これにより、複雑なタグフィルタリング条件を構築できますが、トップレベルでは3つのうち1つだけを選択する必要があります。

以下のように複数条件フィルタリングすることが可能です。

複数の条件をANDで結合する例
{
  "andConditions": [
    {
      "key": "content_type",
      "value": "address_sapporo"
    },
    {
      "key": "category",
      "value": "product_info"
    }
  ]
}
複数の条件をORで結合する例
{
  "orConditions": [
    {
      "tagCondition": {
        "key": "content_type",
        "value": "address_sapporo"
      }
    },
    {
      "tagCondition": {
        "key": "content_type",
        "value": "address_tokyo"
      }
    }
  ]
}
複雑な条件の例
{
  "orConditions": [
    {
      "andConditions": [
        {
          "key": "content_type",
          "value": "address"
        },
        {
          "key": "region",
          "value": "hokkaido"
        }
      ]
    },
    {
      "tagCondition": {
        "key": "priority",
        "value": "high"
      }
    }
  ]
}

https://docs.aws.amazon.com/ja_jp/connect/latest/APIReference/API_amazon-q-connect_TagFilter.html

https://awscli.amazonaws.com/v2/documentation/api/latest/reference/qconnect/update-session.html

動作検証

Amazon Q in Connectで以下の2点をコンテンツ検索して、タグフィルタリングの効果を検証します。

  1. クラスメソッドの本社を教えてください
    • sapporo.txtには「札幌」と記載
    • tokyo.txtには「東京」と記載
  2. クラスメソッドメンバーズについて教えてください
    • classmethod.htmlに説明文がある

Lambda関数によるタグフィルタリングが適用されると、電話対応中やアフターコールワーク(ACW)中は、content_type: address_sapporoのタグを持つsapporo.txtのみを利用して回答するはずです。

電話対応前

エージェントワークスペースの[Amazon Q]から質問を行うと、S3に保存されているすべてのファイルを参照して回答されています。

cm-hirai-screenshot 2025-04-11 11.31.59

電話対応中

電話対応すると、Amazon Qが再ロードされます。

cm-hirai-screenshot 2025-04-11 11.34.01

  • 「クラスメソッドの本社を教えてください」: sapporo.txt に基づき「札幌」と回答
  • 「クラスメソッドメンバーズについて教えてください」: classmethod.html が検索対象外のため誤回答

cm-hirai-screenshot 2025-04-11 11.39.30

ACW中

ACW中も同様に、タグフィルターが継続して適用されています。

  • 「クラスメソッドの本社を教えてください」: sapporo.txt に基づき「札幌」と回答
  • 「クラスメソッドメンバーズについて教えてください」: 引き続き誤った回答

cm-hirai-screenshot 2025-04-11 11.39.55

ACW終了後

電話対応前のコンテンツ検索結果が表示されていました。

cm-hirai-screenshot 2025-04-11 11.39.30

ACW終了すると、タグフィルターが解除され、エージェントワークスペースの[Amazon Q]では再び全コンテンツが参照されました。

cm-hirai-screenshot 2025-04-11 11.47.11

この検証により、以下のことが確認できました。

  1. Lambda で設定したタグフィルターが通話開始時に正しく適用された
  2. 通話中~ACW 中はフィルターが維持された
  3. ACW 終了と同時にフィルターが解除された
  4. フィルター中は content_type=address_sapporo を持つ sapporo.txt だけが検索対象となった

これにより、通話対応時、ナレッジベースを絞り込めることを確認できました。

まとめ

本記事では、Amazon Q in Connect の「コンテンツセグメンテーション」機能を使い、特定タグを持つドキュメントだけをナレッジ検索の対象にする方法を検証しました。ポイントは次の 3 つです。

  1. S3 上のファイルに TagResource API でタグを付与する
  2. UpdateSession API の tagFilter パラメータを使う Lambda 関数を実装する
  3. Connect フローでコンタクト開始時にその Lambda を呼び出し、セッションにタグフィルターを設定する

検証の結果、 以下を確認できました。これにより、問い合わせ内容に最も関連する情報だけをエージェントへ提示できます。

  • 通話中と ACW 中はフィルターが有効で、content_type=address_sapporo を持つ sapporo.txt だけが参照された
  • ACW 終了と同時にフィルターが解除され、再び全コンテンツが検索対象になった

課題として、現在はファイル単位でタグを付ける必要があり、フォルダー単位で一括付与したい場合はスクリプトなどの自動化が不可欠です。タグ付け作業の効率化が今後の改善ポイントとなるでしょう。

コンテンツセグメンテーションを活用すれば、エージェントは適切な情報に素早くアクセスできるため、回答精度の向上と応答時間の短縮、ひいては顧客満足度の向上が期待できます。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.