إطار عمل لتطوير تطبيقات الشات بوت.
تأكد من تثبيت العقدة وnpm. اعتبارًا من الآن، تم اختبار هذه الوحدة مقابل إصدار العقدة 0.12 ضمن خط أنابيب Travis CI.
ما عليك سوى تشغيل أمر npm install
للتثبيت:
npm install --save talkify
تتطلب الوحدة الرئيسية والأنواع والتبعيات. يقوم الأمر التالي بتحميل كل ما تحتاجه من الوحدة.
// Core dependency
const talkify = require ( 'talkify' ) ;
const Bot = talkify . Bot ;
// Types dependencies
const BotTypes = talkify . BotTypes ;
const Message = BotTypes . Message ;
const SingleLineMessage = BotTypes . SingleLineMessage ;
const MultiLineMessage = BotTypes . MultiLineMessage ;
// Skills dependencies
const Skill = BotTypes . Skill ;
// Training dependencies
const TrainingDocument = BotTypes . TrainingDocument ;
بمجرد تحميل التبعيات، يمكنك تهيئة قلب الروبوت.
const bot = new Bot ( ) ;
يقبل منشئ Bot()
أيضًا المعلمات في شكل كائن التكوين. هنا يمكنك تمرير قيم تبديل التكوين أو التطبيقات البديلة لأشياء مثل ContextStore
و Classifier
وما إلى ذلك. وسنغطي ذلك لاحقًا في قسم خيارات التكوين.
بمجرد تهيئة الروبوت، أول شيء يجب عليك فعله هو تدريبه. لتدريبه على مستند واحد في كل مرة بشكل متزامن، يمكنك استخدام طريقة train
:
bot . trainAll ( [
new TrainingDocument ( 'how_are_you' , 'how are you' ) ,
new TrainingDocument ( 'how_are_you' , 'how are you going' ) ,
new TrainingDocument ( 'how_are_you' , 'how is it going' ) ,
new TrainingDocument ( 'help' , 'how can you help' ) ,
new TrainingDocument ( 'help' , 'i need some help' ) ,
new TrainingDocument ( 'help' , 'how could you assist me' )
] , function ( ) { } ) ;
يقوم الكود أعلاه بتدريب الروبوت على التعرف على الموضوع how_are_you
عندما يبدو النص مثل how are you
أو how are you doing
وكذلك how is it going
ولكن للتعرف على help
الموضوع عندما يبدو النص مثل how can you help
أو i need some help
وكذلك how can you assist me
. هذه هي الطريقة التي يمكنك بها تدريب الروبوت.
يقبل الأسلوب trainAll
مصفوفة من كائنات TrainingDocument
بالإضافة إلى وظيفة رد الاتصال. يقبل مُنشئ كائن TrainingDocument
معلمتين. هذه هي topicName
وبيانات trainingData
. المعلمة topicName
هي اسم الموضوع الذي تريد تدريب trainingData
عليه، trainingData
هي الجملة التي تقوم بتغذية الروبوت بها كبيانات تدريب خاصة به. سيتم لاحقًا تعيين topicName
للمهارات الفعلية التي يمكن للروبوت الاستجابة لها.
رد الاتصال لأسلوب trainAll
هو وظيفة يمكن للروبوت الاتصال بها عند اكتمال التدريب. إذا كان لديك الكثير من بيانات التدريب، فيجب عليك تنفيذ ذلك بشكل صحيح. في هذا المثال، نظرًا لعدم وجود الكثير من بيانات التدريب، فقد مررنا function
فارغة.
وغني عن القول أن الروبوت يتحسن مع المزيد من بيانات التدريب. في هذا البرنامج التعليمي، نستخدم المصنف الافتراضي، وهو حاليًا المصنف LogisticRegression
من مكتبة talkify-natural-classifier. يحتاج هذا المصنف عادةً إلى بيانات تدريب أكثر قليلًا للبدء به ولكنه أكثر دقة من المصنفات الأخرى في معظم الظروف.
بمجرد قيامك بتدريب الروبوت على بعض المواضيع، ستحتاج إلى إضافة بعض المهارات. المهارات هي الإجراءات التي سينفذها الروبوت عندما يتعرف على موضوع ما. لذلك يتم تعيين المواضيع والمهارات إلى 1:1.
لإضافة مهارة، عليك إنشائها أولاً. المهارة تتطلب ثلاثة أشياء. اسم المهارة الفريدة للبوت. يتم استخدام الاسم لربط المهارات لاحقًا ضمن السياق. موضوع يتم تعيينه إليه ووظيفة سيستدعيها الروبوت لتنفيذ المهارة. ستأخذ هذه الوظيفة أربعة معلمات، وهي: context, request, response, next
. يتم استخدام معلمة context
لتخزين أي معلومات سياقية مفيدة من تلك المهارة. تحتوي معلمة request
على معلومات حول الطلب، كما هو الحال بالنسبة response
. المعلمة next
هي وظيفة يمكنك الاتصال بها لإعلام الروبوت بأنك انتهيت من المعالجة. إليك ما تبدو عليه المهارة:
var howAction = function ( context , request , response , next ) {
response . message = new SingleLineMessage ( 'You asked: "' + request . message . content + '". I'm doing well. Thanks for asking.' ) ;
next ( ) ;
} ;
var helpAction = function ( context , request , response , next ) {
response . message = new SingleLineMessage ( 'You asked: "' + request . message . content + '". I can tell you how I'm doing if you ask nicely.' ) ;
next ( ) ;
} ;
var howSkill = new Skill ( 'how_skill' , 'how_are_you' , howAction ) ;
var helpSkill = new Skill ( 'help_skill' , 'help' , helpAction ) ;
ملاحظة: يمكن أن يكون اسم المهارة غير محدد. ومع ذلك، يرجى العلم أن القيام بذلك يعني أن الروبوت سينفذ هذه المهارة عندما يكون مستوى ثقته 0 للرد على استعلام معين.
بمجرد تحديد بعض المهارات، ستحتاج إلى إضافتها إلى الروبوت. أضف المهارة إلى الروبوت كما يلي:
bot . addSkill ( howSkill ) ;
bot . addSkill ( helpSkill ) ;
بمجرد الإضافة، يمكنك الآن أن تطلب من الروبوت حل مشكلة ما. هذا هو المكان الذي تقوم فيه بالاستعلام عن الروبوت بجملة وسوف يستجيب برسالة بشكل غير متزامن. تأخذ وظيفة الحل ثلاث معلمات: contextId, text, callback
. يساعد contextId
الروبوت في حل السياق من أي محادثة سابقة. text
هو السؤال أو جزء من سلسلة اللغة الطبيعية التي يحتاج الروبوت إلى تفسيرها والرد عليها. وأخيرًا، callback
هو وظيفة رد الاتصال التي سيتصل بها الروبوت عند err, messages
للإشارة إلى الخطأ (إن وجد) ورسائل الرد الخاصة به.
var resolved = function ( err , messages ) {
if ( err ) return console . error ( err ) ;
return console . log ( messages ) ;
} ;
bot . resolve ( 123 , 'Assistance required' , resolved ) ;
قم بتشغيله كملف عقدة بسيط ويجب أن يطبع ما يلي في وحدة التحكم.
[ { type: 'SingleLine',
content: 'You asked: "Assistance required". I can tell you how I'm doing if you ask nicely.' } ]
حاول تغيير bot.resolve
إلى هذا ولاحظ التغيير في الاستجابة.
bot . resolve ( 456 , 'How's it going?' , resolved ) ;
دعونا نسأل شيئين في وقت واحد. قم بتغيير bot.resolve
مرة أخرى إلى:
bot . resolve ( 456 , 'How's it going? Assistance required please.' , resolved ) ;
عند تشغيل التعليمات البرمجية الخاصة بك، يجب أن تحصل على رسالتين:
[ { type : 'SingleLine' ,
content : 'You asked: "How's it going? Assistance required please.". I'm doing well. Thanks for asking.' } ,
{ type : 'SingleLine' ,
content : 'You asked: "How's it going? Assistance required please.". I can tell you how I'm doing if you ask nicely.' } ]
حاليًا، أساليب train
addSkill
والحل قابلة resolve
. هذا يعني أنه يمكنك إنشاء كائن Bot وطرق تتالي كما هو مذكور أدناه.
new Bot ( ) . train ( topic , sentence ) . addSkill ( skill ) . resolve ( ... . )
يقبل الروبوت الأساسي أيضًا تطبيقًا بديلاً لمخزن السياق المدمج. يرجى الاطلاع على إدارة السياق لمزيد من التفاصيل.
يمكنك أيضًا توفير نسختك الخاصة من المصنف للروبوت. تم استخدام هذا الخيار بشكل أساسي لتسهيل الاختبار، ومع ذلك، لا يزال من الممكن استخدامه في الإنتاج إذا كان لديك إصدار أفضل من المصنف المدمج.
المصنف المدمج هو المصنف talkify الطبيعي. يوفر هذا المصنف تطبيقين:
LogisticRegressionClassifier
BayesClassifier
يعتبر LogisticRegressionClassifier
هو المصنف الافتراضي. إذا كنت تفضل تطبيق BayesClassifier
من talkify-natural-classifier
، فيمكنك القيام بما يلي:
var BayesClassifier = require ( 'talkify-natural-classifier' ) . BayesClassifier ;
var bot = new Bot ( { classifier : new BayesClassifier ( ) } ) ;
إذا كنت تفضل استخدام IBM Watson's Natural Language Processing Classifier بدلاً من ذلك، فيجب عليك استخدام مكتبة talkify-watson-classifier بدلاً من ذلك. يرجى الاطلاع على الدليل الموجود على صفحة مستودع Github لمزيد من التفاصيل حول كيفية استخدام هذا المصنف.
إذا كنت تعتقد أن عملك يعمل بشكل أفضل، صرخ لي! سأكون سعيدًا بمعرفة ذلك وربما العمل على تنفيذه ضمن الوحدة الأساسية.
لتوفير التنفيذ الخاص بك لاستراتيجية تحليل المهارة، ما عليك سوى تمرير تعريف الوظيفة في كائن التكوين على النحو التالي:
var mySkillResolutionStrategy = function ( ) {
this . addSkill = function ( skill , options ) { ... } ;
this . getSkills = function ( ) { ... } ;
this . resolve = function ( err , resolutionContext , callback ) {
...
} ;
return this ;
} ;
var bot = new Bot ( {
skillResolutionStrategy : mySkillResolutionStrategy
} ) ;
سيقوم الروبوت الأساسي بإنشاء مثيل لكائن استراتيجية تحليل المهارات الخاص بك على init وسيستخدمه كمثيل واحد عبر جميع القرارات.
لتوفير التنفيذ الخاص بك لاستراتيجية حل الموضوع، ما عليك سوى تمرير تعريف الوظيفة في كائن التكوين كما يلي:
var myTopicResolutionStrategy = function ( ) {
this . collect = function ( classification , classificationContext , callback ) { callback ( ) } ;
this . resolve = function ( callback ) { callback ( [ { name : "topic_name" , confidence : 0.5 ] ) } ;
return this ;
} ;
var bot = new Bot ( {
topicResolutionStrategy : myTopicResolutionStrategy
} ) ;
سيقوم الروبوت الأساسي بإنشاء مثيل جديد لاستراتيجية حل الموضوع لكل مكالمة يتلقاها في طريقة الحل.
بشكل افتراضي، يستخدم جوهر الروبوت إصداره المدمج من contextStore. إذا نظرت إلى lib/ContextStore.js، ستجد أنه تطبيق بسيط جدًا حيث يتم تخزين السياق في خريطة بسيطة في الذاكرة مع كون contextId
هو المفتاح وكائن السياق هو القيمة. بالطبع عندما تقوم بنشر هذا، سيكون مخزن السياق المدمج محدودًا للغاية.
يعد توسيع مخزن السياق أمرًا سهلاً للغاية. ضمن التكوين، يمكنك توفير التنفيذ الخاص بك لكائن contextStore. يوفر التعليمة البرمجية التالية تطبيقًا تافهًا للغاية يقوم ببساطة بتسجيل القيم إلى وحدة التحكم.
var myContextStore = {
put : function ( id , context , callback ) {
console . info ( 'put' ) ;
console . info ( id ) ;
console . info ( context ) ;
} ,
get : function ( id , callback ) {
console . info ( 'get' ) ;
console . info ( id ) ;
} ,
remove : function ( id , callback ) {
console . info ( 'remove' ) ;
console . info ( id ) ;
}
}
var bot = new Bot ( { contextStore : myContextStore } ) ;
تتطلب المواصفات الحالية لـ ContextStore
تنفيذ ثلاث وظائف. يتم put, get and remove
. طالما تم توفير هذه الأساليب، فإن الروبوت لا يهتم بالمصدر الذي تأتي منه قيمة حقل contextStore
في التكوين.
إذا كنت تريد تشغيل هذا الرمز مع بعض حلول الاستعلام، فستجد أنه لا يتم استدعاء وظيفة الإزالة أبدًا. هذا عمل مستمر لأنه لا يوجد حاليًا حد للمدة التي يجب أن نتذكر فيها السياق.
كما ذكرنا من قبل، فإن المصنف الافتراضي الذي يستخدمه الروبوت هو من مكتبة talkify-natural-classifier. أنت حر في كتابة المصنف الخاص بك واستخدامه في التطبيق الخاص بك. للقيام بذلك، تحتاج إلى توسيع واجهة المصنف المحددة في مكتبة talkify-classifier.
بمجرد نجاحك في توسيع هذا التنفيذ، يمكنك توفير المصنف الخاص بك إلى الروبوت كما يلي:
var myClassifier = new MyAwesomeClassifier ( ) ;
var bot = new Bot ( { classifier : myClassifier } ) ;
أود أن أرى تنفيذك لمصنف talkify. إذا قمت بتوسيع الواجهة ونفذت المصنف الخاص بك بنجاح، صرخ لي! سأكون سعيدًا بمعرفة تجربتك في استخدام هذه المكتبة.
منذ الإصدار 2.1.0، يمكنك تحديد مصنفات متعددة لروبوتك. راجع المستندات الموجودة على المصنف لمزيد من المعلومات.
تعد استراتيجية حل المهارات مكونًا قادرًا على إنتاج مهارة، في ظل سياق الحل. سياق الحل هو كائن يتكون من قائمة المواضيع والجملة الأصلية، والمكونات الأساسية اللازمة لحل المهارة.
+-------------+
| Topic | | |
+---------+ | +----> +--------------+
|-----------+ | | |
+-------------+ | Skill | +---------+
| Resolution +----> | Skill |
| Strategy | +---------+
+------------+ | |
| Sentence | +---> +--------------+
+------------+
تسمح لك إستراتيجية حل الموضوع بتوصيل منطق مخصص لحل موضوع ما، وفقًا لبيانات التصنيف. عند توصيل إستراتيجية مخصصة لحل الموضوع، يتوقع جوهر الروبوت أن يتم تمرير تعريف الوظيفة بدلاً من نتيجة تنفيذ الوظيفة. وذلك لأن كائن إستراتيجية حل الموضوع تم إنشاؤه باستخدام طريقة new
لكل استدعاء resolve
.
تتم عملية حل الموضوع في جزأين:
المرحلة الأولى من عملية حل الموضوع هي مرحلة التجميع. هنا، يرسل قلب الروبوت التصنيف لكل مجموعة تصنيف يتم إرجاعها من المصنف بالإضافة إلى أي سياق مطلوب. يمر نواة الروبوت أيضًا في وظيفة رد الاتصال المطلوبة ليتم استدعاؤها للسماح لنواة الروبوت بمعرفة أن الاستدعاء كان ناجحًا.
+------------------+ +
| Classification | |
+------------------+ |
| +-----------+
+--------> Collect |
| +-----------+
+-----------+ |
| Context | |
+-----------+ +
المرحلة الثانية هي مرحلة الحل. هنا، يتوقع قلب الروبوت إرجاع قائمة التصنيفات. يتم استدعاء الحل فقط بعد الانتهاء من تنفيذ كافة المجموعات.
+-----------+ +---------+-+-+
| Resolve +---->+ Topic | | |
+-----------+ +---------+ | |
|-----------+ |
+-------------+
يجب أن يعرض كائن إستراتيجية حل الموضوع طريقتين:
يتم استدعاء طريقة التجميع في كل مرة يقوم فيها المصنف بإرجاع التصنيف (التصنيفات). يتم استدعاؤه classification, context, callback
. يحتوي كائن classification
على التصنيف الذي تم إرجاعه من المصنف (أو مجموعة المصنفات في حالة استخدام النصاب القانوني). كائن context
هو الكائن الذي يحتوي على سياق الطلب. callback
المعلمة الأخير هو الوظيفة التي يجب استدعاؤها للسماح لنواة الروبوت بمعرفة أنك انتهيت من جمع المعلمات التي تم تمريرها.
يتم استدعاء طريقة الحل مرة واحدة بعد انتهاء جوهر الروبوت من خلال استدعاء collect
في إستراتيجية حل الموضوع الخاص بك. هذا هو النداء الأخير من bot core ويهدف إلى جمع معلومات حول حل الموضوع. يتم استدعاء أسلوب resolve
باستخدام معلمة callback
. هذه هي وظيفة رد الاتصال التي يجب استدعاؤها مع error, topics
. يجب تعريف معلمة الخطأ ككائن خطأ في حالة حدوث خطأ عند حل الموضوع. في أي حالة أخرى، يجب أن يكون هذا الكائن undefined
. يجب أن تكون معلمة topics
الثانية عبارة عن مجموعة من المواضيع التي تم حلها بواسطة إستراتيجية الحل.
يرجى الاطلاع على دليل المساهمة لمزيد من التفاصيل.