在 DialogFlow 中维护对话中的状态

Maintaining state within a conversation within DialogFlow

我试图了解如何在 fullfillment 中管理状态的某些方面(DialogFlow 的实现,您可以在 JavaScript 中编写代码并在 Google 云函数中执行)。首先,我会假设这个实现是无状态的,但必须有一种方法来维护一些状态,而不必将数据存储在数据库中,然后在下一次执行时检索它。

我只想维护聊天的完整历史记录——用户提出的问题,以及聊天机器人的回复。我可以看到我可以通过以下方式获取有关每个响应(并调用 fullfillment)的信息:

  console.log(JSON.stringify(request.body.queryResult.queryText));
  console.log(JSON.stringify(request.body.queryResult.fulfillmentText)); 

现在我有了这些信息,我只想将它附加到某个有状态的变量。我查看了 setContext、context.set、app.data 和其他 functions/variables,但我似乎无法让它工作,因为我不确定我是否理解它应该如何工作。

在我的代码中,我主要使用基本模板。我不认为我可以使用全局变量,所以我如何才能在意图执行之间仅针对该用户的对话存储此状态 (fullConversation)?

exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
  const agent = new WebhookClient({ request, response });
  console.log('Dialogflow Request headers: ' + JSON.stringify(request.headers));
  console.log('Dialogflow Request body: ' + JSON.stringify(request.body));
  let query = JSON.stringify(request.body.queryResult.queryText);
  let response = console.log(JSON.stringify(request.body.queryResult.fulfillmentText); 

  // here I want to retrieve the prior query/response and append it
  // i.e., let fullConversation = fullConversation + query + response
  }
  
  function welcome(agent) {
    agent.add(`Welcome to my agent!`);
  }
 
  function fallback(agent) {
    agent.add(`I didn't understand`);
    agent.add(`I'm sorry, can you try again?`);
  }

  function myNewHandler(agent) {
  }

  // Run the proper function handler based on the matched Dialogflow intent name
  let intentMap = new Map();
  intentMap.set('Default Welcome Intent', welcome);
  intentMap.set('Default Fallback Intent', fallback);
  intentMap.set('myIntent',myNewHandler);
  agent.handleRequest(intentMap);
});

更新: 如果我使用@Prisoner 的代码建议更新我的代码,我仍然无法获取上下文。我从来没有得到我的 console.log(2)。我需要将 agent.context.get 代码移到 onRequest 块之外吗??:

exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
  const agent = new WebhookClient({ request, response });
  console.log('Dialogflow Request headers: ' + JSON.stringify(request.headers));
  console.log('Dialogflow Request body: ' + JSON.stringify(request.body));
  console.log(JSON.stringify(request.body.queryResult.queryText));
  console.log(JSON.stringify(request.body.queryResult.fulfillmentText)); 

  console.log("1");
  // Get what was set before, or an empty array
  const historyContext = agent.context.get('history');
  console.log("2");

第二次更新: 该问题与已解决的已知问题有关 here

只需要更新 package.json 中的 dialogflow-fulfillment,一切正常。

你走在正确的轨道上。全局变量绝对不是的方法。状态 可以 作为上下文的一部分进行维护。

app.data 属性 仅在您使用 actions-on-google library, which it does not look like you're using. Several of the APIs have also changed over time, and can be confusing. See this older answer 检查某些选项时才可用。

由于您使用的是 dialogflow-fulfillment 库,因此您将使用 agent.context(注意单数)对象来添加新的上下文。对于上下文,您需要使用要存储的值设置上下文参数。值必须是字符串 - 所以如果你有类似数组的东西,你可能想使用 JSON.serialzie() 之类的东西将它转换为字符串并用 JSON.parse().

提取它

使用您存储的信息获取当前上下文,然后用最新值更新它的代码可能如下所示:

  // Get what was set before, or an empty array
  const historyContext = agent.context.get('history');
  const historyString = (historyContext && historyContext.params && historyContext.params.history) || '[]';
   const history = JSON.parse(historyString);

   // Add the messages as a single object
   history.push({
     requestMessage,
     responseMessage
   });

   // Save this as a context with a long lifespan
   agent.context.set('history', 99, JSON.stringify(history));

更新

我会把这段代码放在一个函数中,然后在你 return 从你所在的每个处理函数中调用这个函数。我有点惊讶 agent.context 会导致问题在处理程序之外 - 但由于您似乎没有任何特定错误,所以这是我最好的猜测。