IBM Cloud Docs
访问上下文数据

经典 Watson Assistant 体验的 Documentation 已移动。 有关最新版本,请参阅 在对话框中访问上下文数据

访问上下文数据

上下文是一个包含变量的对象,这些变量在整个交谈中持久存储,并且可以由对话和客户机应用程序共享。 对话和客户机应用程序都可以读取和写入上下文变量。

您可以选择是希望由应用程序还是由 Watson Assistant 服务来维护上下文:

  • 如果使用的是有状态 V2 message API,那么助手将自动维护每个会话的上下文。 应用程序必须在每个交谈开始时显式创建会话;上下文由服务存储为会话的一部分,但不会在消息响应中返回,除非您请求这样做。 有关更多信息,请参阅 v2 API 参考

  • 如果使用无状态 V2 message API(或旧的 V1 message API),那么应用程序会负责在每轮交谈后存储上下文,并使用下一条消息将其发送回服务。 对于复杂应用程序或需要存储个人可标识信息的应用程序,您可以选择将上下文存储在数据库中。

    会话标识在交谈开始时自动生成,但服务不会存储会话数据。 对于无状态 message API,上下文始终包含在每条消息响应中。 有关更多信息,请参阅 v2 API 参考

**重要信息:**上下文的一个用途是指定与助手进行交互的每个最终用户的唯一用户标识。 对于基于用户的套餐,此标识用于计费。 (有关更多信息,请参阅基于用户的套餐。)

有两种类型的上下文:

  • 全局上下文:由助手使用的所有技能共享的上下文变量,包括用于管理交谈流的内部系统变量。 全局上下文包含用户标识,以及助手的时区和语言等其他全局值。

  • 特定于技能的上下文:特定于某种技能的上下文变量,包括应用程序所需的任何用户定义的变量。 目前,仅支持一种技能(名为 main skill)。

在对话节点中指定的用户定义的上下文变量是使用 API 访问该变量时,技能上下文中 user_defined 对象的一部分。 请注意,此结构与 Watson 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 API 参考

示例

以下示例显示了包含全局上下文变量和特定于技能的上下文变量的有状态 /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 的值作为全局上下文的一部分。 此外,应用程序还设置了一个用户定义的上下文变量 (account_number) 作为特定于技能的上下文的一部分。 此上下文变量可由对话节点作为 $account_number 进行访问。 (有关在对话中使用上下文的更多信息,请参阅如何处理对话。)

您可以指定要用于用户定义的上下文变量的任何变量名称。 如果指定的变量已存在,那么将使用新值覆盖该变量;如果不存在,就会将新变量添加到上下文中。

此请求的输出不仅包括通常的输出,还包括上下文,其中显示添加了指定值。 如果使用的是无状态 message 方法,那么此上下文数据必须存储在本地,并作为下一条消息的一部分发送回 Watson Assistant 服务。 如果使用的是有状态 message 方法,那么此上下文会自动存储,并将在会话生命期内持久存储。

{
  "output": {
    "generic": [
      {
        "response_type": "text",
        "text": "Welcome to the Watson 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 的其余部分一起)。 虽然无状态会话不会到期,但您仍可以使用此状态数据将交谈重置为先前状态。