أعلنت شركة أخيرًا عن تطبيق الذكاء الاصطناعي Gemini AI الذي سينافس ChatGPT، وعلى إثره فقد أجرت تغييرات كثيرة كان أهمها كان تعويض Bard باسم Gemini وكذلك Google Assistant. فأصبح بشكل رسمي الذكاء الاصطناعي والمودل الأساسي الذي سيتعامل مع كافة خدمات الذكاء الاصطناعي التابعة لجوجل.
برمجيًا، أتاحت كذلك جوجل Gemini AI SDK، بيئة عمل متكاملة للمطورين من أجل بناء تطبيقات باستخدام الذكاء الاصطناعي للمطورين. وهو ما سنستغله في مقالنا هذا من أكاديمية أكوا التعليمية.
ما الذي ستتعلمه بنهاية هذا المقال ( وما ستصنع ) ؟
بحلول نهاية هذا المقال ستكون قادرًا على استخدام Gemini AI API من أجل بناء وتطوير تطبيقات تعتمد على الذكاء الاصطناعي من كافة الأصناف. بالطبع التقنية التي سنعتمد عليها في الشرح هي تقنية Flutter. نحن سنقدم الأساسيات فقط، والتي ستكون عبارة عن تطبيق للأسئلة والأجوبة باستخدام الذكاء الاصطناعي والتجاوب معه. يمكنك تطوير قدراتك أكثر لو أحببت ذلك.
تجهيز منصة العمل والبدء في المشروع
تهيئة مشروع Flutter
سنعتمد على منصة VSCode كمنصة أساسية للتطوير والبرمجة، فتأكد من تحميلك لمحرر الأكواد هذا أولًا.
ثانيًا عليك تجهيز مشروع على Flutter، إن كانت هذه أول مرة لك في استخدام Flutter فرجاءًا اتبع مقالنا بعنوان ( خطوة بخطوة لتهيئة مشروع Flutter وتشغيله على أندرويد ستوديو و VsCode ) . بعد انتهائك من قراءة المقال سيمكنك إنشاء مشروع على VSCode باستخدام Flutter بالشكل التالي:
الحصول على API Key من خدمة Google Gemini AI
بالطبع من أجل استخدام Gemini AI في مشروعنا نحن بحاجة للـ API Key الخاص بنا، الذي من خلاله سيمكننا استدعاء كل خدمات Gemini AI.
لفعل ذلك توجه إلى موقع Google Ai Dev ثم صوب خيار (Get API Key In Google Studio). بالطبع إن كانت لديك الخبرة الكافية يمكنك التوجه مباشرة لـ Google Studio والبحث عن خيارات Gemini AI ثم الحصول على الـ API Key.
الخطوة 1: إدراج مكتبة Google Generative AI
إن كل ما تحتاجه للبدء في هذا المشروع هو مكتبة Google Generative AI، المكتبة التي أدرتها جوجل في خزينة Flutter و Dart من أجل البدء في التطوير باستخدام Gemini AI.
لتنصيب المكتبة في المشروع:
- توجه إلى VSCode ( رابط المشروع الخاص )
- افتح الـ Terminal (عبر خيار View من القائمة العلوية، ثم Terminal )
- واكتب أمر: flutter pub add google_generative_ai
انتظر قليلًا إلى حين تنصيب المكتبة في المشروع.
الخطوة 2: تهيئة Gemini AI في المشروع
يوجد مقاربات كثيرة ويعتمد الأمر على أهدافك واستخداماتك. لأن استخدامنا في هذا المقال لغرض الشرح فقط فسنبقي الأمور بسيطة للغاية.
لننشئ صفحة جديدة في المشروع وهي الصفحة الرئيسية والتي ستحتوي على كل المعطيات والعناصر. يمكن إبقاء الأمور في صفحة Main.dart لكن قد يحمل هذا الملف خصائص كثيرة أخرى ولتجنب الخلط ننشئ صفحة جديدة من صنف StatefulWidget (لأنها ستضم عناصر متغيرة). ونقوم في ملف main.dart بتوجيه بداية التطبيق إلى الصفحة الجديدة:
دعنا ننشئ Method داخل المشروع والتي ستقوم بالوظيفة بأكملها (التحقق من الـ API ثم أخذ الأمر الذي يكتبه المستخدم ثم إرجاع نتيجة). لأن الغرض من هذا المحتوى تعليمي فسنبقي كل الأمور في نفس الصفحة. بالطبع لو كان مشروع أكبر فسيكون هناك جزء خاص بالتحقق من الـ API وحده، وجزء آخر للتعامل مع الـ Logic خلفه، وكذلك طريقة وضع API مختلفة وأكثر أمانًا عبر الـ Platform Environment. الشرح التالي للمبتدئين وعملي فقط.
يجب على الـ Method أن تكون على شكل Future والتعامل مع الـ Promis عن طريق الـ Async / Await لأننا نتعامل مع إرسال بيانات عبر الإنترنت ثم انتظار رد من الخادم، وكتابتها تكون بهذا الشكل:
لنملأ الـ Parameters بحيث يحمل الـ API Key كود الـ API الذي ولدناه سابقًا، ويحمل الـ model نوع المودل الذي نستخدمه (وهو 'gemini-pro' في هذه الحالة):
بات لدينا الآن Instance جاهز للتعامل. يستطيع هذا الـ Instance إرسال بيانات واستقبالها والبيانات هي أسئلة المستخدم. في نفس الـ Future لنقم بتجربة بسيطة للتأكد من وظيفته وذلك عبر إرسال رسالة ثم إنتظار الجواب، وذلك باستخدام الكود التالي:
قمنا بصناعة Variable ويجب أن يكون من نوع List لأن الـ Generative Model يقبل فقط الـ List لإرسالها (ويمكن للـ List أن تحمل نصوصًا وصور والكثير ...). نحن وفرنا له نص بسيط أطلب فيه Gemini AI أن يقول لي: السلام عليكم 😅.
في السطر الثاني أرسل البيانات للـ Gemini ولأن الـ Future من نوع Async فالعملية تتطلب انتظار Await.
بعد أن يرسل البيانات سيرجعها على شكل response، وهو المتغير الذي يحفظ لي البيانات مباشرة بعد إرسالها.
أما لإظهار النتيجة أوليًا فسأطبعها على شكل print في الكونسول.
بقي لنا الآن تشغيل هذه الـ Future، لفعل ذلك سأنشئ زر بسيط في واجهة التطبيق عند النقر عليه ينادي على هذه الـ Future، سأقوم بذلك بالشكل التالي:
الخطوة الثالثة: لنجعل الأمور ديناميكية أكثر
الأمور حتى الآن ليست ديناميكية فنحن من نطرح السؤال من الكود البرمجي ونحصل على الجواب في الكونسول.
المطلوب هو وضع Textfield يكتب من خلاله المستخدم سؤاله، ثم ينقر على زر OK عند النقر عليه تشتغل الـ Future ثم تُرجع لنا بيانات، عند إرجاعها تظهر كذلك في الشاشة على شكل Text.
دعنا نطبق هذا الكلام برمجيًا، لنبدأ بصناعة الواجهة (بشكل بسيط) :
ما سنفعله الآن هو أخذ المحتوى الذي يكتبه المستخدم في الـ Textfield ولفعل ذلك نستخدم Controller ونسحب منه النص بالشكل التالي:
لنسحب الآن النص الذي سيكتبه المستخدم، ونقوم بإدراجه في الـ WorkerAI() التي أنشأناها. أفضل مقاربة بالنسبة لنا هو جهل الـ Future تأخذ الـ Prompt على شكل متغير وهذا المتغير سيكون الـ Controller Text، بالشكل التالي:
لنقم بإدراج الـ WorkerAI() في الزر مع إدخال prompt كمتغير:
الكود الآن جاهز، لكن يوجد شيء أخير علينا فعله. حين تشغيل الكود سيشتغل لكن النتائج لن تظهر إلا بعد إعادة تحميل التطبيق. لحل هذا المشكل نقوم بإعادة تحديث الـ State الخاصة بالمتغير results لإظهار النتائج بشكل حي، وذلك عبر الكود:
والنتيجة النهائية كالتالي:
الكود يشتغل وتطبيقي للذكاء الاصطناعي يقوم بوظيفته. لكنه بدائي، سآخذ بعض الوقت لتصميم واجهة مناسبة قليلًا، لنحصل على نتيجة نهائية كالتالي:
الكود المستخدم تجده في رابط الـ Gist التالي: من هنا