IBM Cloud Docs
ダイアログでのコンテキスト・データへのアクセス

ダイアログでのコンテキスト・データへのアクセス

コンテキストとは、会話全体を通じて持続する変数を含むオブジェクトであり、ダイアログとクライアントアプリケーションで共有することができます。 ダイアログとクライアント・アプリケーションはどちらもコンテキスト変数を読み書きできます。

コンテキストをアプリケーションで維持するか watsonx Assistant サービスで維持するかを選択できます。

  • ステートフルな v2 の message API を使用する場合、コンテキストは自動的にアシスタントによってセッション単位で維持されます。 アプリケーションは、各会話の開始時にセッションを明示的に作成する必要があります。 コンテキストは、サービスによってセッションの一部として保管され、ユーザーが要求しない限り、メッセージ応答では返されません。 詳細については、 v2を参照してください。

  • ステートレスな v2 の message API (またはレガシーの v1 の message API) を使用する場合は、アプリケーションで、会話ターンが終わるたびにコンテキストを保管し、そのコンテキストを次のメッセージとともにサービスに送り返す必要があります。 複雑なアプリケーションや、個人情報を保管する必要があるアプリケーションの場合は、コンテキストをデータベースに保管することもできます。

    セッション ID は会話の開始時に自動的に生成されますが、セッションのデータがサービスに保管されることはありません。 ステートレスな message API では、コンテキストは必ず各メッセージ応答に含められます。 詳細については、 v2を参照してください。

重要: コンテキストの用途のひとつとして、アシスタントとやりとりする各ユーザーに固有のユーザーIDを指定することがあります。 ユーザー・ベース・プランの場合は、この ID が請求処理のために使用されます。 詳しくは、ユーザー・ベースのプランの説明を参照してください。

コンテキストには、次の 2 つのタイプがあります。

  • グローバルコンテキスト :会話の流れを管理するために使用される内部システム変数など、アシスタントが使用するすべてのスキルで共有されるコンテキスト変数。 グローバルコンテキストには、ユーザーIDや、タイムゾーン、アシスタントの言語などのグローバルな値が含まれます。

  • スキル固有のコンテキスト: アプリケーションに必要なユーザー定義変数など、特定のスキルに固有のコンテキスト変数。 現在、サポートされているスキルは 1 つ (main skill) だけです。

ダイアログノードで指定するユーザー定義のコンテキスト変数は、APIを使用してアクセスすると、スキルコンテキスト内の user_defined オブジェクトの一部となります。 この構造は、 watsonx Assistantの JSONエディタに表示される context 構造とは異なります。 例えば、JSONエディタに以下のコードを指定することができます

"context": {
  "my_context_var": "this is the value"
}

v2 API では、このユーザー定義変数に次のようにしてアクセスします。

"context": {
  "skills": {
    "main skill": {
      "user_defined": {
        "my_context_var": "this is the value"
      }
    }
  }
}

APIを使用してコンテキスト変数にアクセスする方法の詳細については、 v2を参照してください。

次の例は、グローバルおよびスキル固有のコンテキスト変数を含むステートフルな /message リクエストを示しています。また、 options.return_context プロパティを使用して、コンテキストがレスポンスとともに返されるようリクエストしています。 このオプションは、ステートフルな message メソッドを使用している場合にのみ適用されます。ステートレスな message メソッドは常にコンテキストを返すためです。

service
  .message({
    assistant_id: '{assistant_id}',
    session_id: '{session_id}',
    input: {
      message_type: 'text',
      text: 'Hello',
      options: {
        'return_context': true
      }
    },
    context: {
      'global': {
        'system': {
          'user_id': 'my_user_id'
        }
      },
      'skills': {
        'main skill': {
          'user_defined': {
            'account_number': '123456'
          }
        }
      }
    }
  })
  .then(res => {
    console.log(JSON.stringify(res, null, 2));
  })
  .catch(err => {
    console.log(err);
  });
response=service.message(
    assistant_id='{assistant_id}',
    session_id='{session_id}',
    input={
        'message_type': 'text',
        'text': 'Hello',
        'options': {
            'return_context': True
        }
    },
    context={
        'global': {
            'system': {
                'user_id': 'my_user_id'
            }
        },
        'skills': {
            'main skill': {
                'user_defined': {
                    'account_number': '123456'
                }
            }
        }
    }
).get_result()

print(json.dumps(response, indent=2))
MessageInputOptions inputOptions = new MessageInputOptions.Builder()
  .returnContext(true)
  .build();

MessageInput input = new MessageInput.Builder()
  .messageType("text")
  .text("Hello")
  .options(inputOptions)
  .build();

// create global context with user ID
MessageContextGlobalSystem system = new MessageContextGlobalSystem.Builder()
  .userId("my_user_id")
  .build();
MessageContextGlobal globalContext = new MessageContextGlobal.Builder()
  .system(system)
  .build();

// build user-defined context variables, put in skill-specific context for main skill
Map<String, Object> userDefinedContext = new HashMap<>();
userDefinedContext.put("account_number","123456");
MessageContextSkill mainSkillContext = new MessageContextSkill.Builder()
  .userDefined(userDefinedContext)
  .build();
Map<String, MessageContextSkill> skillsContext = new HashMap<>();
skillsContext.put("main skill", mainSkillContext);

MessageContext context = new MessageContext.Builder()
  .global(globalContext)
  .skills(skillsContext)
  .build();

MessageOptions options = new MessageOptions.Builder()
  .assistantId("{assistant_id}")
  .sessionId("{session_id}")
  .input(input)
  .context(context)
  .build();

MessageResponse response = service.message(options).execute().getResult();

System.out.println(response);

この要求例のアプリケーションでは、グローバル・コンテキストの一部として user_id の値を指定しています。 さらに、スキル固有のコンテキストの一部として、1 つのユーザー定義のコンテキスト変数 (account_number) を設定しています。 このコンテキスト変数は、$account_number としてダイアログ・ノードからアクセスできます。

ユーザー定義のコンテキスト変数として使用したい任意の変数名を指定できます。 指定された変数が存在する場合は、新しい値で上書きされます。存在しない場合は、新しい変数がコンテキストに追加されます。

この要求からの出力には、通常の出力だけでなく、指定された値が追加されたことを示すコンテキストも含まれています。 ステートレスな message メソッドを使用する場合は、このコンテキスト・データをローカルに保管し、次のメッセージの一部として watsonx Assistant サービスに送り返す必要があります。 ステートフルな message メソッドを使用している場合、このコンテキストは自動的に保存され、セッションが続く限り維持されます。

{
  "output": {
    "generic": [
      {
        "response_type": "text",
        "text": "Welcome to the watsonx Assistant example!"
      }
    ],
    "intents": [
      {
        "intent": "hello",
        "confidence": 1
      }
    ],
    "entities": []
  },
  "user_id": "my_user_id",
  "context": {
    "global": {
      "system": {
        "turn_count": 1,
        "user_id": "my_user_id"
      }
    },
    "skills": {
      "main skill": {
        "user_defined": {
          "account_number": "123456"
        }
      }
    }
  }
}

会話状態の復元

一部の状況では、会話を以前の状態に復元する機能が必要になることがあります。

ステートフルな export 要求では、message オプションを使用することで、応答のコンテキスト・オブジェクトに完全なセッション状態データを含めるように指定できます。 このオプションに true を指定すると、現在の会話状態を表す state プロパティーをエンコードしたものが、返されるスキル・コンテキストに含められます。

ステートフルな message API を使用する場合に、サービスが会話の状態データを保管するのは、セッションが持続している間だけです。 しかし、このコンテキストデータ( state を含む)を保存し、その後のメッセージリクエストでサービスに送り返せば、元のセッションが期限切れまたは削除された場合でも、同じ状態の会話を復元することができます。

ステートレスな message API を使用する場合は、必ず state プロパティーが (context の他の部分とともに) 応答に含められます。 ステートレスなセッションには期限がありませんが、この状態データを使用すれば会話を前の状態にリセットすることができます。