প্রয়োগ সংক্রান্ত পরামর্শ (Dialogflow)

আপনার অ্যাকশনে ভাল কথোপকথন ডিজাইন সংক্রান্ত প্র্যাক্টিস প্রয়োগ করতে নিম্নলিখিত পরামর্শগুলি পর্যালোচনা করুন।

ভেরিয়েশন আশা করুন

Dialogflow-এ "ব্যবহারকারী যা বলেন" ইনপুটে এটি ম্যানেজ করুন। এছাড়াও, একই অ্যাকশনে ম্যাপ করা যেতে পারে এমন একাধিক ইনটেন্ট ব্যবহার করুন, যেখানে প্রতিটি ইনটেন্ট "ব্যবহারকারী বলেন" বাক্যাংশের বিভিন্ন সেট দিয়ে ট্রিগার করা যেতে পারে।

সহায়ক রিপ্রম্পট প্রদান করা এবং কোনও সমস্যা হলে তা আরও ভালোভাবে ম্যানেজ করা

কখনও কখনও আপনার অ্যাকশন কোনও ইনপুট না পাওয়ার কারণে (ইনপুট না পাওয়া হিসেবে পরিচিত) অথবা ব্যবহারকারীর ইনপুট বুঝতে না পারার কারণে (মিল না পাওয়া হিসেবে পরিচিত) এগোতে পারে না। এটি ঘটলে, Assistant প্রথমে বোঝার চেষ্টা করে যে ব্যবহারকারী অন্য কোনও অ্যাকশন ট্রিগার করতে চান কিনা। Assistant যদি ব্যবহারকারীর ইনপুট অন্য কোনও অ্যাকশনের সাথে ম্যাচ না করে, তাহলে ব্যবহারকারী আপনার অ্যাকশনের প্রসঙ্গে চালিয়ে যান। এই পরিস্থিতি যেকোনও সময় হতে পারে, তাই কথোপকথনের প্রতিটি ধাপে কোনও ইনপুট না পাওয়া এবং কোনও মিল না পাওয়ার পরিস্থিতিকে ফলব্যাক দিয়ে অনন্যভাবে ম্যানেজ করা হল সবচেয়ে ভালো পদ্ধতি। ফলব্যাক ব্যবহার করে, আপনি ব্যবহারকারীদের ট্র্যাকে ফিরে আসতে সাহায্য করতে পারেন।

এটি করতে, আপনার conv.data অবজেক্টে একটি fallbackCount ভেরিয়েবল ইনিশিয়ালাইজ করুন, এবং এটি 0-তে সেট করুন। দুটি ফলব্যাক প্রম্পটের (স্পষ্টতা বাড়ানো) একটি অ্যারে প্রস্তুত করুন, এবং একটি চূড়ান্ত ফলব্যাক প্রম্পট যা কথোপকথন শেষ করে।

তারপর, একটি ফলব্যাক ইনটেন্ট তৈরি করুন (আদর্শভাবে এজেন্টের প্রতিটি অ্যাকশনযোগ্য ইনটেন্টের জন্য একটি)। ইনটেন্ট হ্যান্ডলারে, conv.data অবজেক্ট থেকে ফলব্যাক কাউন্ট পুল করুন, এটি বাড়ান এবং এটি ৩-এর কম হলে, ৩-এর অ্যারে থেকে প্রম্পট পুল করুন। যদি সংখ্যাটি ৪ বা তার বেশি হয়, তাহলে চূড়ান্ত প্রম্পট ব্যবহার করে কথোপকথনটি বন্ধ করুন। ফলব্যাক নয় এমন সব ইনটেন্টের ক্ষেত্রে, ফলব্যাক কাউন্ট রিসেট করে 0 করুন। নির্দিষ্ট ইনটেন্টের জন্য ফলব্যাক টেমপ্লেট তৈরি করুন যাতে সেগুলি নির্দিষ্টভাবে কাজ করে।

Node.js

const GENERAL_FALLBACK = [
   'Sorry, what was that?',
   'I didn\'t quite get that. I can help you find good local restaurants, what do you want to know about?',
];

const LIST_FALLBACK = [
   'Sorry, what was that?',
   'I didn\'t catch that. Could you tell me which one you prefer?',
];

const FINAL_FALLBACK = 'I\'m sorry I\'m having trouble here. Let\'s talk again later.';

const handleFallback = (conv, promptFetch, callback) => {
 conv.data.fallbackCount = parseInt(conv.data.fallbackCount, 10);
 conv.data.fallbackCount++;
 if (conv.data.fallbackCount > 2) {
   conv.close(promptFetch.getFinalFallbackPrompt());
 } else {
   callback();
 }
}
// Intent handlers below
const generalFallback = (conv) => {
  handleFallback = (conv, promptFetch, () => {
    conv.ask(GENERAL_FALLBACK[conv.data.fallbackCount],
      getGeneralNoInputPrompts());
 });
}

const listFallback = (conv) => {
  handleFallback = (conv, promptFetch, () => {
   conv.ask(LIST_FALLBACK[conv.data.fallbackCount],
       getGeneralNoInputPrompts());
 });
}

const nonFallback = (conv) => {
  conv.data.fallbackCount = 0;
  conv.ask('A non-fallback message here');
}

Java

private static final List<String> GENERAL_FALLBACK =
    Arrays.asList(
        "Sorry, what was that?",
        "I didn\'t quite get that. I can tell you all about IO, like date or location, or about the sessions. What do you want to know about?");
private static final List<String> LIST_FALLBACK =
    Arrays.asList(
        "Sorry, what was that?",
        "I didn\'t catch that. Could you tell me which one you liked?");
private static final List<String> FINAL_FALLBACK =
    Arrays.asList("I\'m sorry I\'m having trouble here. Maybe we should try this again later.");

@ForIntent("General Fallback")
public ActionResponse generalFallback(ActionRequest request) {
  ResponseBuilder responseBuilder = getResponseBuilder(request);
  int fallbackCount = (Integer) request.getConversationData().get("fallbackCount");
  fallbackCount++;
  request.getConversationData().put("fallbackCount", fallbackCount);
  if (fallbackCount > 2) {
    responseBuilder.add(getRandomPromptFromList(FINAL_FALLBACK)).endConversation();
  } else {
    responseBuilder.add(getRandomPromptFromList(GENERAL_FALLBACK));
  }
  return responseBuilder.build();
}

private String getRandomPromptFromList(List<String> prompts) {
  Random rand = new Random();
  int i = rand.nextInt(prompts.size());
  return prompts.get(i);
}

@ForIntent("List Fallback")
public ActionResponse listFallback(ActionRequest request) {
  ResponseBuilder responseBuilder = getResponseBuilder(request);
  int fallbackCount = (Integer) request.getConversationData().get("fallbackCount");
  fallbackCount++;
  request.getConversationData().put("fallbackCount", fallbackCount);
  if (fallbackCount > 2) {
    responseBuilder.add(getRandomPromptFromList(FINAL_FALLBACK)).endConversation();
  } else {
    responseBuilder.add(getRandomPromptFromList(LIST_FALLBACK));
  }
  return responseBuilder.build();
}

@ForIntent("Non Fallback")
public ActionResponse nonFallback(ActionRequest request) {
  ResponseBuilder responseBuilder = getResponseBuilder(request);
  request.getConversationData().put("fallbackCount", 0);
  responseBuilder.add("Non Fallback message");
  return responseBuilder.build();
}

যেকোনও সময় সাহায্য করার জন্য প্রস্তুত থাকুন

"আমি কী করতে পারি?"-এর মতো সাহায্যকারী বাক্যাংশ শোনার জন্য একটি ইনটেন্ট তৈরি করুন, "তুমি আমাকে কী বলতে পারো" অথবা "সাহায্য করো"। এই ইনটেন্টে, কিছু (ঘূর্ণায়মান) উত্তর অফার করুন যা এজেন্ট কী করতে পারে তার একটি ওভারভিউ অফার করে এবং ব্যবহারকারীদের একটি সম্ভাব্য অ্যাকশনে নির্দেশ করে। এছাড়াও, বিভিন্ন অ্যাকশনযোগ্য ইনটেন্টের জন্য বিভিন্ন সাহায্যকারী পরিস্থিতি তৈরি করতে Dialogflow-তে ফলো-আপ সাহায্যকারী ইনটেন্ট ব্যবহার করুন।

Node.js

const HELP_PROMPTS = [
   'There\'s a lot you might want to know about the local restaurants, and I can tell you all about it, like where it is and what kind of food they have. What do you want to know?',
   'I\'m here to help, so let me know if you need any help figuring out where or what to eat. What do you want to know?',
];

// Intent handler
const help = (conv) => {
 reply(conv, promptFetch.getHelpPrompt(), // fetches random entry from HELP_PROMPTS
     promptFetch.getGeneralNoInputPrompts());
}

Java

private static final List<String> HELP_PROMPTS =
    Arrays.asList(
        "There's a lot you might want to know about IO, and I can tell you all about it, like where it is and what the sessions are. What do you want to know?",
        "IO can be a little overwhelming, so I\'m here to help. Let me know if you need any help figuring out the event, like when it is, or what the sessions are. What do you want to know?");

@ForIntent("Help")
public ActionResponse help(ActionRequest request) {
  return getResponseBuilder(request).add(getRandomPromptFromList(HELP_PROMPTS)).build();
}

ব্যবহারকারীদের তথ্য রিপ্লে করার অনুমতি দিন

আপনার সব app.ask(output) পদ্ধতিকে একটি প্রক্সি ফাংশন দিয়ে র‍্যাপ করুন যা conv.data.lastPrompt-এ আউটপুট যোগ করে। এমন একটি রিপিট ইনটেন্ট তৈরি করুন যা ব্যবহারকারীর কাছ থেকে "কী?"-এর মতো রিপিট করার প্রম্পট শোনে, "আবার বলো" অথবা "তুমি কি আবার বলতে পারবে?"। ব্যবহারকারী কোনও কিছু রিপিট করার জন্য অনুরোধ করেছেন তা স্বীকার করার জন্য ব্যবহার করা যেতে পারে এমন রিপিট প্রিফিক্সের একটি অ্যারে তৈরি করুন। রিপিট ইনটেন্ট হ্যান্ডলারে, রিপিট প্রিফিক্স ও conv.data.lastPrompt-এর ভ্যালু কনক্যাটিনেট করা স্ট্রিং সহ ask() কল করুন। মনে রাখবেন যে, শেষ প্রম্পটে ব্যবহার করা হলে, আপনাকে যেকোনও SSML ওপেনিং ট্যাগ শিফ্ট করতে হবে।

Node.js

const REPEAT_PREFIX = [
    'Sorry, I said ',
    'Let me repeat that. ',
];

const reply = (conv, inputPrompt, noInputPrompts) => {
  conv.data.lastPrompt = inputPrompt;
  conv.data.lastNoInputPrompts = noInputPrompts;
  conv.ask(inputPrompt, noInputPrompts);
}
// Intent handlers
const normalIntent = (conv) => {
  reply(conv, 'Hey this is a question', SOME_NO_INPUT_PROMPTS);
}

const repeat = (conv) => {
  let repeatPrefix = promptFetch.getRepeatPrefix(); // randomly chooses from REPEAT_PREFIX
  // Move SSML start tags over
  if (conv.data.lastPrompt.startsWith(promptFetch.getSSMLPrefix())) {
    conv.data.lastPrompt =
        conv.data.lastPrompt.slice(promptFetch.getSSMLPrefix().length);
    repeatPrefix = promptFetch.getSSMLPrefix() + repeatPrefix;
  }
  conv.ask(repeatPrefix + conv.data.lastPrompt,
      conv.data.lastNoInputPrompts);
}

Java

private final List<String> REPEAT_PREFIX = Arrays.asList("Sorry, I said ", "Let me repeat that.");

private final String SsmlPrefix = "<speak>";

@ForIntent("Normal Intent")
public ActionResponse normalIntent(ActionRequest request) {
  ResponseBuilder responseBuilder = getResponseBuilder(request);
  responseBuilder.getConversationData().put("lastPrompt", "Hey this is a question");
  return responseBuilder.build();
}

@ForIntent("repeat")
public ActionResponse repeat(ActionRequest request) {
  ResponseBuilder responseBuilder = getResponseBuilder(request);
  String repeatPrefix = getRandomPromptFromList(REPEAT_PREFIX);
  // Move SSML start tags over
  String lastPrompt = (String) responseBuilder.getConversationData().get("lastPrompt");
  if (lastPrompt.startsWith(SsmlPrefix)) {
    String newLastPrompt = lastPrompt.substring(SsmlPrefix.length());
    responseBuilder.getConversationData().put("lastPrompt", newLastPrompt);
    repeatPrefix = SsmlPrefix + repeatPrefix;
  }
  responseBuilder.add(repeatPrefix + lastPrompt);
  return responseBuilder.build();
}

ব্যবহারকারীর পছন্দ অনুযায়ী কথোপকথন পছন্দমতো সাজিয়ে নিন

আপনার অ্যাকশন ব্যবহারকারীর পছন্দ সম্পর্কে জিজ্ঞাসা করতে পারে এবং পরে ব্যবহারের জন্য তা মনে রাখতে পারে, যার ফলে আপনি সেই ব্যবহারকারীর সাথে ভবিষ্যতে কথোপকথন পছন্দমতো করে তুলতে পারবেন।

এই উদাহরণ অ্যাকশন ব্যবহারকারীদের একটি পিন কোডের জন্য আবহাওয়ার রিপোর্ট দেয়। নিম্নলিখিত উদাহরণ কোড ব্যবহারকারীকে জিজ্ঞাসা করে যে তিনি পরবর্তী কথোপকথনের জন্য অ্যাকশনকে তার পিন কোড মনে রাখতে বলতে চান কিনা।

Node.js

app.intent('weather_report', (conv) => {
  let zip = conv.arguments.get('zipcode');
  conv.data.zip = zip;
  conv.ask(getWeatherReport(zip));
  conv.ask(new Confirmation(`Should I remember ${zip} for next time?`));
});

app.intent('remember_zip', (conv, params, confirmation) => {
  if (confirmation) {
    conv.user.storage.zip = conv.data.zip;
    conv.close('Great! See you next time.');
  } else conv.close('Ok, no problem.');
});

Java

@ForIntent("weather_report")
public ActionResponse weatherReport(ActionRequest request) {
  ResponseBuilder responseBuilder = getResponseBuilder(request);
  String zip = (String) request.getArgument("location").getStructuredValue().get("zipCode");
  responseBuilder.getConversationData().put("zip", zip);
  responseBuilder.add(getWeatherReport(zip));
  responseBuilder.add(
      new Confirmation().setConfirmationText("Should I remember " + zip + " for next time?"));
  return responseBuilder.build();
}

@ForIntent("remember_zip")
public ActionResponse rememberZip(ActionRequest request) {
  ResponseBuilder responseBuilder = getResponseBuilder(request);
  if (request.getUserConfirmation()) {
    responseBuilder.getUserStorage().put("zip", responseBuilder.getConversationData().get("zip"));
    responseBuilder.add("Great! See you next time.").endConversation();
  } else {
    responseBuilder.add("Ok, no problem.").endConversation();
  }
  return responseBuilder.build();
}

প্রথমবার কথোপকথনের সময় ব্যবহারকারীকে তার পিন কোড জিজ্ঞাসা করার পরে, পরের বার কথোপকথনের সময় আপনি সেই প্রম্পটটি এড়িয়ে যেতে এবং একই পিন কোড ব্যবহার করতে পারবেন। আপনাকে এখনও একটি এস্কেপ রুট প্রদান করতে হবে (যেমন একটি সাজেশন চিপ যা তাদের একটি ভিন্ন পিন কোড বেছে নিতে দেয়) তবে সাধারণ ক্ষেত্রে কথোপকথনের একটি টার্ন কমিয়ে, আপনি অনেক বেশি নির্বিঘ্ন অভিজ্ঞতা তৈরি করেন।

Node.js

app.intent('weather_report', (conv) => {
  let zip = conv.arguments.get('zipcode');
  if (zip) {
    conv.close(getWeatherReport(zip));
  } else if (conv.user.storage.zip) {
    conv.ask(new SimpleResponse(getWeatherReport(conv.user.storage.zip)));
    conv.ask(new Suggestions('Try another zipcode'));
  } else {
    conv.ask('What\'s your zip code?');
  }
});

app.intent('provide_zip_df', (conv) => {
  conv.user.storage.zip = conv.arguments.get('zipcode');
  conv.close(getWeatherReport(conv.user.storage.zip));
});

Java

public ActionResponse weatherReport2(ActionRequest request) {
  ResponseBuilder responseBuilder = getResponseBuilder(request);
  String zip = (String) request.getArgument("location").getStructuredValue().get("zipCode");
  if (zip != null) {
    responseBuilder.add(getWeatherReport(zip)).endConversation();
  } else if ((zip = (String) responseBuilder.getUserStorage().get("zip")) != null) {
    responseBuilder.add(new SimpleResponse().setTextToSpeech(getWeatherReport(zip)));
    responseBuilder.add(new Suggestion().setTitle("Try another zipcode"));
  } else {
    responseBuilder.add("What's your zip code?");
  }
  return responseBuilder.build();
}

ফিরে আসা ব্যবহারকারীদের জন্য কাস্টমাইজ করুন

কথোপকথনের মধ্যে কিছু স্টেট বজায় রাখলে, ফিরে আসা ব্যবহারকারীদের জন্য অনেক বেশি স্বাভাবিক অভিজ্ঞতা নিশ্চিত করা যায়। এই অভিজ্ঞতা তৈরি করার প্রথম ধাপ হল ফিরে আসা ব্যবহারকারীদের আলাদাভাবে স্বাগত জানানো। যেমন, আপনি শুভেচ্ছার মেসেজটি ছোট করতে পারেন অথবা পুরনো কথোপকথনের ভিত্তিতে প্রয়োজনীয় তথ্য দেখাতে পারেন। এটি করতে, ব্যবহারকারী আগে আপনার অ্যাকশনের সাথে ইন্টার‍্যাক্ট করেছেন কিনা তা নির্ধারণ করতে ইনকামিং AppRequest.User lastSeen প্রপার্টি ব্যবহার করুন। অনুরোধের পেলোডে lastSeen প্রপার্টি অন্তর্ভুক্ত থাকলে, আপনি স্বাভাবিকের থেকে আলাদা অভিবাদন ব্যবহার করতে পারবেন।

নিচে দেওয়া কোড Node.js ক্লায়েন্ট লাইব্রেরি ব্যবহার করে last.seen-এর ভ্যালু নিয়ে আসে।

Node.js

// This function is used to handle the welcome intent
// In Dialogflow, the Default Welcome Intent ('input.welcome' action)
// In Actions SDK, the 'actions.intent.MAIN' intent
const welcome = (conv) => {
  if (conv.user.last.seen) {
    conv.ask(`Hey you're back...`);
  } else {
    conv.ask('Welcome to World Cities Trivia!...');
  }
}

Java

// This function is used to handle the welcome intent
// In Dialogflow, the Default Welcome Intent ('input.welcome' action)
// In Actions SDK, the 'actions.intent.MAIN' intent
public ActionResponse welcome(ActionRequest request) {
  ResponseBuilder responseBuilder = getResponseBuilder(request);
  if (request.getUser().getLastSeen() != null) {
    responseBuilder.add("Hey you're back...");
  } else {
    responseBuilder.add("Welcome to Number Genie!...");
  }
  return responseBuilder.build();
}

lastSeen-এর আসল ভ্যালু অনুযায়ী উত্তর কাস্টমাইজ করে আপনি এই অভিবাদন আরও উন্নত করতে পারেন। যেমন, বর্তমান ইন্টার‍্যাকশনের আগে অনেক মাস আগে ইন্টার‍্যাক্ট করেছেন এমন ব্যবহারকারীকে এমনভাবে স্বাগত জানানো হতে পারে যা আগের দিন অ্যাকশন ব্যবহার করেছেন এমন ব্যবহারকারীর থেকে আলাদা।

কথোপকথন চলাকালীন ভলিউম কন্ট্রোল

কাজ করে এমন ডিভাইসে, Assistant ব্যবহারকারীদের আপনার কনভারসেশনাল অ্যাকশনের মধ্যে ডিভাইসের ভলিউম কন্ট্রোল করতে দেয়। এর জন্য "ভলিউম বাড়াও" বা "ভলিউম ৫০ শতাংশে সেট করো"-এর মতো কথা বলতে হয়। আপনার কাছে একই ধরনের ট্রেনিং ফ্রেজ ম্যানেজ করার ইনটেন্ট থাকলে, আপনার ইনটেন্টকে অগ্রাধিকার দেওয়া হয়। আপনার অ্যাকশনের কোনও নির্দিষ্ট কারণ না থাকলে, আমরা সাজেস্ট করি যে Assistant-কে এইসব ব্যবহারকারীর অনুরোধ ম্যানেজ করতে দিন।