IBM Cloud Docs
在对话中访问上下文数据

在对话中访问上下文数据

上下文是一个包含变量对象的上下文,这些变量在对话中始终存在,并且可以被对话和客户端应用程序共享。 对话和客户机应用程序都可以读取和写入上下文变量。

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

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

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

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

重要提示: 上下文的一个用途是为与助手交互的每个用户指定一个唯一的ID。 对于基于用户的套餐,此标识用于计费。 有关更多信息,请参阅基于用户的套餐说明

有两种类型的上下文:

  • 全局上下文:助理使用的所有技能所共有的上下文变量,包括用于管理对话流程的内部系统变量。 全局环境包括用户ID和其他全局值,例如助手的时区和语言。

  • 特定于技能的上下文:特定于某种技能的上下文变量,包括应用程序所需的任何用户定义的变量。 目前,仅支持一种技能(名为 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 的值作为全局上下文的一部分。 此外,应用程序还设置了一个用户定义的上下文变量 (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 的其余部分一起)。 虽然无状态会话不会到期,但您仍可以使用此状态数据将交谈重置为先前状态。