1. مقدمة
نظرة عامة
أنت مطوِّر في شركة تسويق سفر. قرّر قسم المبيعات أنّه بحاجة إلى تطبيق دردشة جديد لمواكبة شركات الحجز والبحث الأكبر. سمعوا أيضًا عن الذكاء الاصطناعي التوليدي، ولكنّهم لا يعرفون الكثير عنه. سمعت الأقسام الأخرى عن هذه المبادرة، وهي مهتمة بمعرفة كيف يمكن أن تساعد أيضًا في تحسين تجربة العملاء.
الإجراءات التي ستنفذّها
في هذا الدرس التطبيقي، ستنشئ برنامج دردشة آليًا لمساعدة المسافرين باستخدام نموذج Gemini 2.5 Flash على Vertex AI.
يجب أن يلتزم التطبيق بما يلي:
- تساعد المستخدمين في طرح أسئلة حول السفر وحجز رحلات والتعرّف على الأماكن التي يخططون للذهاب إليها
- توفّر للمستخدمين طرقًا للحصول على مساعدة بشأن خطط سفرهم المحدّدة
- أن يكون بإمكانها استرداد بيانات في الوقت الفعلي، مثل الطقس، باستخدام الأدوات
ستعمل في بيئة Google Cloud تم إعدادها مسبقًا، وتحديدًا في "محرّر Cloud Shell". تمّ إعداد واجهة أمامية أساسية لتطبيق الويب لك مسبقًا، بالإضافة إلى الأذونات اللازمة للوصول إلى Vertex AI. تم إنشاء هذا التطبيق باستخدام Streamlit.
أهداف الدورة التعليمية
في هذه الميزة الاختبارية، ستتعرّف على كيفية تنفيذ المهام التالية:
- استكشِف منصة Vertex AI لتحديد نماذج الذكاء الاصطناعي التوليدي المتاحة.
- التطوير في محرِّر Cloud Shell والوحدة الطرفية
- استخدام Gemini Code Assist لفهم الرمز البرمجي
- استخدِم حزمة تطوير البرامج (SDK) الخاصة بـ Vertex AI في Python لإرسال الطلبات إلى نموذج لغوي كبير من Gemini وتلقّي الردود منه.
- تطبيق هندسة الطلبات الأساسية (تعليمات النظام ومَعلمات النموذج) لتخصيص ناتج نموذج لغوي كبير من Gemini
- اختبِر تطبيق محادثة يستند إلى LLM وحسِّنه بشكل متكرّر من خلال تعديل الطلبات والمعلَمات لتحسين الردود.
- تحديد الأدوات واستخدامها مع نموذج Gemini لتفعيل استدعاء الدوال
- إعادة تصميم الرمز البرمجي لاستخدام جلسة محادثة ذات حالة، وهي أفضل ممارسة للتطبيقات الحوارية
2. إعداد المشروع
حساب Google
إذا لم يكن لديك حساب شخصي على Google، عليك إنشاء حساب على Google.
استخدام حساب شخصي بدلاً من حساب تابع للعمل أو تديره مؤسسة تعليمية
تسجيل الدخول إلى Google Cloud Console
سجِّل الدخول إلى Google Cloud Console باستخدام حساب Google شخصي.
تفعيل الفوترة
تحصيل قيمة رصيد Google Cloud بقيمة 5 دولار أمريكي (اختياري)
لإجراء ورشة العمل هذه، تحتاج إلى حساب فوترة يتضمّن بعض الرصيد. إذا كنت تخطّط لاستخدام نظام الفوترة الخاص بك، يمكنك تخطّي هذه الخطوة.
- انقر على هذا الرابط وسجِّل الدخول باستخدام حساب Google شخصي.سيظهر لك ما يلي:

- انقر على الزر انقر هنا للوصول إلى رصيدك.سينقلك هذا الزر إلى صفحة لإعداد ملف الفوترة

- انقر على تأكيد.
أنت مرتبط الآن بحساب فوترة تجريبي على Google Cloud Platform.

إعداد حساب فوترة شخصي
إذا أعددت الفوترة باستخدام أرصدة Google Cloud، يمكنك تخطّي هذه الخطوة.
لإعداد حساب فوترة شخصي، يُرجى الانتقال إلى هنا لتفعيل الفوترة في Cloud Console.
ملاحظات:
- يجب أن تكلّف إكمال هذا المختبر أقل من دولار أمريكي واحد من موارد السحابة الإلكترونية.
- يمكنك اتّباع الخطوات في نهاية هذا المختبر لحذف الموارد وتجنُّب المزيد من الرسوم.
- يمكن للمستخدمين الجدد الاستفادة من الفترة التجريبية المجانية بقيمة 300 دولار أمريكي.
إنشاء مشروع (اختياري)
إذا لم يكن لديك مشروع حالي تريد استخدامه لهذا التصنيف، يمكنك إنشاء مشروع جديد هنا.
3- فتح Cloud Shell Editor
- انقر على هذا الرابط للانتقال مباشرةً إلى محرّر Cloud Shell
- إذا طُلب منك منح الإذن في أي وقت اليوم، انقر على منح الإذن للمتابعة.

- إذا لم تظهر المحطة الطرفية في أسفل الشاشة، افتحها باتّباع الخطوات التالية:
- انقر على عرض.
- انقر على Terminal

- في الوحدة الطرفية، اضبط مشروعك باستخدام الأمر التالي:
gcloud config set project [PROJECT_ID]- مثال:
gcloud config set project lab-project-id-example - إذا تعذّر عليك تذكُّر معرّف مشروعك، يمكنك إدراج جميع معرّفات المشاريع باستخدام:
gcloud projects list | awk '/PROJECT_ID/{print $2}'
- مثال:
- من المفترض أن تظهر لك هذه الرسالة:
>aside negative إذا ظهرت لك رسالة `WARNING` وطُلب منك الإجابة عن السؤال `Do you want to continue (Y/n)?`، فمن المحتمل أنّك أدخلت معرّف المشروع بشكل غير صحيح. اضغط على `n`، ثم اضغط على `Enter`، وحاوِل تشغيل الأمر `gcloud config set project` مرة أخرى. >Updated property [core/project].
4. تفعيل واجهات برمجة التطبيقات
لاستخدام Vertex AI SDK والتفاعل مع نموذج Gemini، عليك تفعيل Vertex AI API في مشروعك على Google Cloud.
- في الوحدة الطرفية، فعِّل واجهات برمجة التطبيقات:
gcloud services enable \ aiplatform.googleapis.com
مقدمة عن حزمة تطوير البرامج (SDK) لخدمة Vertex AI في Python
للتفاعل مع النماذج المستضافة على Vertex AI من تطبيق Python، عليك استخدام حزمة تطوير البرامج (SDK) الخاصة بـ Vertex AI للغة Python. تُبسّط حزمة تطوير البرامج هذه عملية إرسال الطلبات وتحديد مَعلمات النموذج وتلقّي الردود بدون الحاجة إلى التعامل مع تعقيدات طلبات واجهة برمجة التطبيقات الأساسية مباشرةً.
يمكنك العثور على مستندات شاملة حول حزمة تطوير البرامج (SDK) الخاصة بـ Vertex AI في Python هنا: مقدمة عن حزمة تطوير البرامج (SDK) الخاصة بـ Vertex AI في Python | Google Cloud.
5- إنشاء بيئة افتراضية وتثبيت التبعيات
قبل بدء أي مشروع Python، من الممارسات الجيدة إنشاء بيئة افتراضية. يؤدي ذلك إلى عزل التبعيات الخاصة بالمشروع، ما يمنع حدوث تعارضات مع المشاريع الأخرى أو حِزم Python العامة في النظام.
- أنشئ مجلدًا باسم
wanderbotلتخزين الرمز الخاص بتطبيق مساعد السفر. شغِّل الرمز التالي في الوحدة الطرفية:mkdir wanderbot && cd wanderbot - أنشئ بيئة افتراضية وفعِّلها:
سيظهر لك البادئة (uv venv --python 3.12 source .venv/bin/activatewanderbot) قبل طلب المحطة الطرفية، ما يشير إلى أنّ البيئة الافتراضية نشطة. سيبدو على النحو التالي:
6. إنشاء ملفات أولية لتطبيق wanderbot
- أنشئ ملف
app.pyجديدًا وافتحه للتطبيق. نفِّذ الرمز التالي في الوحدة الطرفية: سيفتح الأمرcloudshell edit app.pycloudshell editالملفapp.pyفي المحرِّر أعلى الوحدة الطرفية. - ألصِق رمز تشغيل التطبيق التالي في
app.py:import streamlit as st from google import genai from google.genai import types import requests import logging # --- Defining variables and parameters --- REGION = "global" PROJECT_ID = None # TO DO: Insert Project ID GEMINI_MODEL_NAME = "gemini-2.5-flash" temperature = .2 top_p = 0.95 system_instructions = None # --- Tooling --- # TODO: Define the weather tool function declaration # TODO: Define the get_current_temperature function # --- Initialize the Vertex AI Client --- try: # TODO: Initialize the Vertex AI client print(f"VertexAI Client initialized successfully with model {GEMINI_MODEL_NAME}") except Exception as e: st.error(f"Error initializing VertexAI client: {e}") st.stop() # TODO: Add the get_chat function here in Task 15. # --- Call the Model --- def call_model(prompt: str, model_name: str) -> str: """ This function interacts with a large language model (LLM) to generate text based on a given prompt and system instructions. It will be replaced in a later step with a more advanced version that handles tooling. """ try: # TODO: Prepare the content for the model # TODO: Define generate_content configuration (needed for system instructions and parameters) # TODO: Define response logging.info(f"[call_model_response] LLM Response: \"{response.text}\"") # TODO: Uncomment the below "return response.text" line # return response.text except Exception as e: return f"Error: {e}" # --- Presentation Tier (Streamlit) --- # Set the title of the Streamlit application st.title("Travel Chat Bot") # Initialize session state variables if they don't exist if "messages" not in st.session_state: # Initialize the chat history with a welcome message st.session_state["messages"] = [ {"role": "assistant", "content": "How can I help you today?"} ] # Display the chat history for msg in st.session_state.messages: st.chat_message(msg["role"]).write(msg["content"]) # Get user input if prompt := st.chat_input(): # Add the user's message to the chat history st.session_state.messages.append({"role": "user", "content": prompt}) # Display the user's message st.chat_message("user").write(prompt) # Show a spinner while waiting for the model's response with st.spinner("Thinking..."): # Get the model's response using the call_model function model_response = call_model(prompt, GEMINI_MODEL_NAME) # Add the model's response to the chat history st.session_state.messages.append( {"role": "assistant", "content": model_response} ) # Display the model's response st.chat_message("assistant").write(model_response) - أنشئ ملف
requirements.txtجديدًا وافتحه لرمز التطبيق. نفِّذ الرمز التالي في الوحدة الطرفية: سيفتح الأمرcloudshell edit requirements.txtcloudshell editالملفrequirements.txtفي المحرِّر أعلى الوحدة الطرفية. - ألصِق رمز تشغيل التطبيق التالي في
requirements.txt.google-genai streamlit requests - ثبِّت تبعيات Python المطلوبة لهذا المشروع. نفِّذ الرمز التالي في الوحدة الطرفية:
uv pip install -r requirements.txt
7. استكشاف الرمز
تتضمّن الملفات التي أنشأتها واجهة أمامية أساسية لتطبيق محادثة. وتشمل:
app.py: هذا هو الملف الذي سنعمل فيه. يتضمّن حاليًا ما يلي:- عمليات الاستيراد الضرورية
- متغيّرات البيئة والمَعلمات (بعضها عناصر نائبة)
- دالة
call_modelفارغة سنملأها - رمز Streamlit لتطبيق المحادثات على الواجهة الأمامية
requirements.txt:- تتضمّن متطلبات التثبيت لتشغيل
app.py
- تتضمّن متطلبات التثبيت لتشغيل
حان الوقت الآن لاستكشاف التعليمات البرمجية.
فتح محادثة Gemini Code Assist
يجب أن يكون Gemini Code Assist Chat مفتوحًا في لوحة على يسار الشاشة في "محرِّر Cloud Shell". إذا لم تكن نافذة Gemini Code Assist Chat مفتوحة، يمكنك فتحها باتّباع الخطوات التالية:
- النقر على زر Gemini Code Assist (
) بالقرب من أعلى الشاشة - انقر على فتح محادثة Gemini Code Assist.

استخدام Gemini Code Assist لفهم الرمز البرمجي
يمكنك استخدام Gemini Code Assist Chat لفهم الرمز البرمجي بشكل أفضل.
- ميِّز قسم الرمز المطلوب أو اختَره.
- اكتب "اشرح هذا الرمز البرمجي" في محادثة Gemini.
- اضغط على مفتاح Enter لإرسال الطلب

8. تشغيل تطبيق الويب
قبل ربط هذا التطبيق بنموذج لغوي كبير، شغِّله لمعرفة سلوكه في البداية.
- ضِمن دليل
wanderbot، شغِّل الأمر التالي في الوحدة الطرفية لبدء تطبيق Streamlit وإتاحة الوصول إليه محليًا ضمن بيئة Cloud Shell: يُرجى إبقاء نافذة Terminal هذه مفتوحة، لأنّ تطبيق Streamlit سيستمر في العمل. يمكنك فتح نافذة طرفية جديدة في Cloud Shell لتنفيذ أوامر أخرى.streamlit run app.py --browser.serverAddress=localhost --server.enableCORS=false --server.enableXsrfProtection=false --server.port 8080 - بعد تنفيذ الأمر، انقر على الزر معاينة الويب في أعلى محرّر Cloud Shell واختَر معاينة على المنفذ 8080.

ستظهر لك واجهة محادثة بسيطة لتطبيق السفر. - اكتب أي رسالة (مثل
Hi!) واضغط على ENTER.
ستلاحظ أنّ الرسالة ستظهر في سجلّ المحادثات، ولكن ستتلقّى رسالة خطأ بدلاً من ردّ من المساعد. ويرجع ذلك إلى أنّ التطبيق لم يتم ربطه بعد بنموذج لغوي كبير. راقِب هذا السلوك لفهم نقطة بداية المختبر.
9- إعداد برنامج Vertex AI
استكشاف النماذج المتاحة في Vertex AI
تتيح منصة Vertex AI من Google Cloud الوصول إلى مجموعة متنوّعة من نماذج الذكاء الاصطناعي التوليدي. قبل دمج إحدى هذه الخدمات، يمكنك استكشاف الخيارات المتاحة في Google Cloud Console.
- من Google Cloud Console، انتقِل إلى Model Garden. يمكنك إجراء ذلك من خلال البحث عن "Model Garden" في شريط البحث أعلى الشاشة واختيار Vertex AI.(
) - تصفَّح النماذج المتاحة. يمكنك الفلترة حسب عناصر مثل طرق العرض وأنواع المهام والميزات.
لأغراض هذا المختبر، ستستخدم نموذج Gemini 2.5 Flash، وهو خيار جيد لإنشاء تطبيقات دردشة سريعة الاستجابة بسبب سرعته.
إعداد برنامج Vertex AI
ستعدّل الآن القسم --- Initialize the Vertex AI Client --- في app.py لإعداد برنامج Vertex AI. سيتم استخدام عنصر العميل هذا لإرسال الطلبات إلى النموذج.
- افتح
app.pyفي "محرِّر Cloud Shell". - في
app.py، ابحث عن السطرPROJECT_ID = None. - استبدِل
Noneبرقم تعريف مشروعك على Google Cloud بين علامتَي اقتباس. (مثلاًPROJECT_ID = "google-cloud-labs")
إذا لم تتمكّن من تذكُّر معرّف مشروعك، يمكنك إدراج جميع معرّفات المشاريع باستخدام:gcloud projects list | awk '/PROJECT_ID/{print $2}' - تحديد العميل: داخل الحزمة
try، ابدأ عملية إعداد عميل Vertex AI.client = genai.Client( vertexai=True, project=PROJECT_ID, location=REGION, )
تعديل عملية تهيئة عميل Vertex AI
في هذه المرحلة، سيظهر قسم "إعداد برنامج Vertex AI" على النحو التالي:
# --- Initialize the Vertex AI Client ---
try:
client = genai.Client(
vertexai=True,
project=PROJECT_ID,
location=REGION,
)
print(f"VertexAI Client initialized successfully with model {GEMINI_MODEL_NAME}")
except Exception as e:
st.error(f"Error initializing VertexAI client: {e}")
st.stop()
10. إعداد البيانات واستدعاء النموذج
عليك الآن إعداد المحتوى لإرساله إلى النموذج، وإجراء عملية إلى نموذج Gemini.
- ابحث عن القسم
--- Call the Model ---حيث يتم تعريف الدالةcall_model. - تحديد المحتوى: ضمن
# TODO: Prepare the content for the model، حدِّد المحتوى الذي سيتم إرساله إلى النموذج. بالنسبة إلى الطلب الأساسي، ستكون هذه هي رسالة الإدخال الخاصة بالمستخدم.contents = [prompt] - تحديد الردّ: الصِق هذا الرمز تحت
# TODO: Define response.response = client.models.generate_content( model=model_name, contents=contents, ) - إرجاع الردّ: أزِل التعليق من السطر التالي:
return response.text - افحص السطر الذي يتم فيه استدعاء الدالة
call_model، بالقرب من أسفل الملف في الحظرwith. إذا لم تفهم ما يحدث هنا، حدِّد السطر واطلب من Gemini Code Assist شرحه.
طريقة أكثر وضوحًا لتحديد contents
تعمل طريقة تحديد contents الموضّحة أعلاه لأنّ حزمة تطوير البرامج (SDK) ذكية بما يكفي لفهم أنّ القائمة التي تحتوي على سلاسل تمثّل إدخال نص المستخدم. ويتم تنسيقه تلقائيًا بشكل صحيح لواجهة برمجة التطبيقات الخاصة بالنموذج.
ومع ذلك، فإنّ الطريقة الأكثر وضوحًا وأساسية لتنظيم الإدخال تتضمّن استخدام الكائنَين types.Part وtypes.Content، كما يلي:
user_message_parts = [types.Part.from_text(text=prompt)]
contents = [
types.Content(
role="user", # Indicates the content is from the user
parts=user_message_parts, # A list, allowing multiple types of content
),
]
تم تعديل الدالة call_model
في هذه المرحلة، من المفترض أن تبدو الدالة call_model على النحو التالي:
def call_model(prompt: str, model_name: str) -> str:
"""
This function interacts with a large language model (LLM) to generate text based on a given prompt and system instructions.
It will be replaced in a later step with a more advanced version that handles tooling.
"""
try:
contents = [prompt]
# TODO: Define generate_content configuration (needed later for system instructions and parameters)
response = client.models.generate_content(
model=model_name,
contents=contents,
)
logging.info(f"[call_model_response] LLM Response: \"{response.text}\"")
return response.text
except Exception as e:
return f"Error: {e}"
11. اختبار التطبيق المرتبط
- في الوحدة الطرفية، أوقِف العملية الجارية حاليًا (CTRL+C).
- أعِد تشغيل الأمر لبدء تطبيق Streamlit مرة أخرى.
streamlit run app.py --browser.serverAddress=localhost --server.enableCORS=false --server.enableXsrfProtection=false --server.port 8080 - أعِد تحميل تطبيق Streamlit. إذا كان تطبيق Streamlit لا يزال قيد التشغيل، يمكنك ببساطة إعادة تحميل صفحة معاينة الويب في المتصفّح.
- الآن، اكتب سؤالاً في مربّع إدخال الدردشة، مثل ما يلي:
What is the best time of year to go to Iceland? - اضغط على مفتاح ENTER.
من المفترض أن يعرض التطبيق رسالتك، ورمزًا متحركًا "جارٍ التفكير..."، ثم ردًا من إنشاء نموذج Gemini. إذا كان الأمر كذلك، تكون قد ربطت تطبيق الويب بنجاح بنموذج لغوي كبير على Vertex AI. 🙌 🥳
12. تحديد تعليمات النظام
على الرغم من أنّ الاتصال الأساسي يعمل، تتأثر جودة وأسلوب ردود النموذج اللغوي الكبير بشكل كبير بالمدخلات التي يتلقّاها. هندسة الطلبات هي عملية تصميم هذه المدخلات (الطلبات) وتحسينها لتوجيه النموذج نحو إنشاء النتائج المطلوبة.
لتحقيق ذلك، ستبدأ بإنشاء بعض تعليمات النظام وتمريرها إلى النموذج.
ستستخدم ميزة اسأل Gemini لمساعدتك في وضع تعليمات مفيدة للنظام.
- في
app.py، ابحث عن المتغيّرsystem_instructions، الذي تم ضبطه حاليًا علىNone. ستستبدلsystem_instructions = NoneNoneبسلسلة متعددة الأسطر تقدّم تعليمات لروبوت مساعد السفر. - طرح سؤال على Gemini Code Assist: أدخِل الطلب التالي إلى Gemini Code Assist (أو يمكنك إنشاء طلب خاص بك):
I am a developer at a travel marketing company, and my sales department has decided that they need a new chat application to keep up with the bigger booking and search companies. I'm building a simple travel assistant chatbot using the Gemini 2.5 Flash model on Vertex AI. The application should: - Helps users ask questions about travel, book travel, and learn about places they are going to go - Provides users ways to get help about their specific travel plans - Provides all this in a production quality way (multiple environments, logging and monitoring, etc.) Please create system instructions appropriate for that chat app. Be thorough. Do not alter the code in any way beyond providing me with system instructions. - تحديد
system_instructions: اضبط قيمةsystem_instructionsلتساوي تعليمات النظام التي أنشأتها باستخدام Gemini Code Assist. يمكنك بدلاً من ذلك استخدام تعليمات النظام هذه التي أنشأها Gemini باستخدام طلب مشابه.system_instructions = """ You are a sophisticated travel assistant chatbot designed to provide comprehensive support to users throughout their travel journey. Your capabilities include answering travel-related questions, assisting with booking travel arrangements, offering detailed information about destinations, and providing support for existing travel plans. **Core Functionalities:** 1. **Travel Information and Recommendations:** * Answer user inquiries about travel destinations, including popular attractions, local customs, visa requirements, weather conditions, and safety advice. * Provide personalized recommendations for destinations, activities, and accommodations based on user preferences, interests, and budget. * Offer insights into the best times to visit specific locations, considering factors like weather, crowds, and pricing. * Suggest alternative destinations or activities if the user's initial choices are unavailable or unsuitable. 2. **Booking Assistance:** * Facilitate the booking of flights, hotels, rental cars, tours, and activities. * Search for available options based on user-specified criteria such as dates, destinations, budget, and preferences. * Present clear and concise information about available options, including pricing, amenities, and booking terms. * Guide users through the booking process, ensuring accurate information and secure transactions. * Provide booking confirmations and relevant details, such as booking references and contact information. 3. **Travel Planning and Itinerary Management:** * Assist users in creating detailed travel itineraries, including flights, accommodations, activities, and transportation. * Offer suggestions for optimizing travel plans, such as minimizing travel time or maximizing sightseeing opportunities. * Provide tools for managing and modifying existing itineraries, including adding or removing activities, changing booking dates, or upgrading accommodations. * Offer reminders and notifications for upcoming travel events, such as flight check-in or tour departure times. 4. **Customer Support and Troubleshooting:** * Provide prompt and helpful support to users with questions or issues related to their travel plans. * Assist with resolving booking discrepancies, cancellations, or modifications. * Offer guidance on travel-related emergencies, such as lost luggage or travel delays. * Provide access to relevant contact information for airlines, hotels, and other travel providers. **Interaction Guidelines:** * **Professionalism:** Maintain a polite, respectful, and professional tone in all interactions. * **Clarity and Conciseness:** Provide clear, concise, and easy-to-understand information. Avoid jargon or technical terms unless necessary and always explain them. * **Accuracy:** Ensure all information provided is accurate and up-to-date. Double-check details before sharing them with users. If unsure about something, admit that you don't know and offer to find the information. * **Personalization:** Tailor your responses and recommendations to the specific needs and preferences of each user. * **Proactive Assistance:** Anticipate user needs and offer relevant information or suggestions proactively. * **Error Handling:** Gracefully handle user errors or misunderstandings. Provide helpful guidance and alternative options when necessary. * **Confidentiality:** Respect user privacy and handle personal information with the utmost confidentiality and in compliance with data protection regulations. **Example Interactions:** **User:** "I want to go on a beach vacation in the Caribbean. I have a budget of $2000 per person for a week." **Chatbot:** "Certainly! The Caribbean offers many beautiful beach destinations within your budget. Some popular options include Punta Cana in the Dominican Republic, Cancun in Mexico, and Montego Bay in Jamaica. These destinations offer stunning beaches, all-inclusive resorts, and various activities. Would you like me to search for flights and accommodations for these locations based on your travel dates?" **User:** "My flight is delayed. What should I do?" **Chatbot:** "I'm sorry to hear about the delay. Please check with the airline for the updated departure time and any assistance they can offer. You may be entitled to compensation or rebooking options depending on the length of the delay and the airline's policy. Do you have your flight number handy so I can look up the current status for you?" **User:** "Tell me about the best time to visit Japan." **Chatbot:** "Japan is a fantastic destination with distinct seasons offering unique experiences. Spring (March-May) is famous for the beautiful cherry blossoms, while autumn (September-November) boasts stunning fall foliage. Both seasons have pleasant temperatures, making them ideal for sightseeing. Summer (June-August) can be hot and humid, but it's a great time for festivals and outdoor activities in the mountains. Winter (December-February) offers opportunities for skiing and snowboarding in the Japanese Alps, though some areas may experience heavy snowfall. To recommend the best time for you, could you tell me what you'd like to experience in Japan?" By following these instructions, you will be able to provide exceptional travel assistance and create a positive experience for every user. """ - تحديد إعدادات generate_content: ابدأ بكائن إعدادات ستمرّر إليه تعليمات النظام هذه. بما أنّ
system_instructionsمعرَّف على مستوى العالم في النص البرمجي، يمكن للدالة الوصول إليه مباشرةً.generate_content_config = types.GenerateContentConfig( system_instruction=[ types.Part.from_text(text=system_instructions) ], ) logging.info(f"[generate_config_details] System Instruction: {generate_content_config.system_instruction[0].text}") - لإضافة تعليمات النظام إلى الردّ، أضِف المَعلمة
configإلى الطريقةgenerate content، واضبطها على قيمة مساوية للكائنgenerate_content_configالذي تم إنشاؤه أعلاه.response = client.models.generate_content( model=model_name, contents=contents, config=generate_content_config, # This is the new line )
تم تعديل الدالة call_model
تبدو الدالة call_model الكاملة الآن على النحو التالي:
def call_model(prompt: str, model_name: str) -> str:
"""
This function interacts with a large language model (LLM) to generate text based on a given prompt and system instructions.
It will be replaced in a later step with a more advanced version that handles tooling.
"""
try:
contents = [prompt]
generate_content_config = types.GenerateContentConfig(
system_instruction=[
types.Part.from_text(text=system_instructions)
],
)
logging.info(f"[generate_config_details] System Instruction: {generate_content_config.system_instruction[0].text}")
response = client.models.generate_content(
model=model_name,
contents=contents,
config=generate_content_config,
)
logging.info(f"[call_model_response] LLM Response: \"{response.text}\"")
return response.text
except Exception as e:
return f"Error: {e}"
13. اختبار التطبيق باستخدام "تعليمات النظام"
- في الوحدة الطرفية، أوقِف العملية الجارية حاليًا (CTRL+C).
- أعِد تشغيل الأمر لبدء تطبيق Streamlit مرة أخرى.
streamlit run app.py --browser.serverAddress=localhost --server.enableCORS=false --server.enableXsrfProtection=false --server.port 8080 - أعِد تحميل تطبيق Streamlit. إذا كان تطبيق Streamlit لا يزال قيد التشغيل، يمكنك ببساطة إعادة تحميل صفحة معاينة الويب في المتصفّح.
- جرِّب طرح السؤال نفسه كما كان من قبل:
What is the best time of year to go to Iceland? - اضغط على مفتاح ENTER.
قارِن بين طريقة استجابته هذه المرة وطريقة استجابته في المرة السابقة.
14. تحديد أداة الطقس
حتى الآن، يتمتّع روبوت الدردشة الخاص بنا بمعرفة جيدة، ولكنها تقتصر على البيانات التي تم تدريبه عليها. لا يمكنه الوصول إلى المعلومات في الوقت الفعلي. بالنسبة إلى روبوت محادثة خاص بالسفر، تشكّل القدرة على استرداد بيانات مباشرة، مثل توقعات الطقس، ميزة كبيرة.
هنا يأتي دور الأدوات، المعروفة أيضًا باسم استدعاء الدوال. يمكننا تحديد مجموعة من الأدوات (دوال Python) التي يمكن للنموذج اللغوي الكبير اختيار استدعائها للحصول على معلومات خارجية.
طريقة عمل الأدوات
- نقدّم وصفًا لأدواتنا إلى النموذج، بما في ذلك وظائفها والمعلَمات التي تستخدمها.
- يرسل المستخدم طلبًا (مثلاً ما حالة الطقس في لندن؟
- يتلقّى النموذج الطلب ويرى أنّ المستخدم يسأل عن شيء يمكنه العثور عليه باستخدام إحدى أدواته.
- بدلاً من الرد بنص، يردّ النموذج بكائن
function_callخاص يشير إلى الأداة التي يريد استخدامها والحجج التي يريد تقديمها. - يتلقّى رمز Python هذا
function_call، وينفّذ دالةget_current_temperatureالفعلية باستخدام الوسيطات المقدَّمة، ويحصل على النتيجة (مثل 15 درجة مئوية). - ونرسل هذه النتيجة مرة أخرى إلى النموذج.
- يتلقّى النموذج النتيجة وينشئ ردًا بلغة طبيعية للمستخدم (مثلاً تبلغ درجة الحرارة الحالية في لندن 15 درجة مئوية").
تتيح هذه العملية للنموذج الإجابة عن أسئلة تتجاوز بكثير بيانات التدريب، ما يجعله مساعدًا أكثر فعالية وفائدة.
تحديد أداة الطقس
إذا كان المسافر يبحث عن نصائح بشأن الأنشطة التي يمكنه ممارستها ويحتار بين أنشطة تتأثر بالطقس، يمكن أن تكون أداة الطقس مفيدة. لننشئ أداة لنموذجنا للحصول على أحوال الطقس الحالية. نحتاج إلى جزأين: تعريف دالة يصف الأداة للنموذج، ودالة Python الفعلية التي تنفّذها.
- في
app.py، ابحث عن التعليق# TODO: Define the weather tool function declaration. - أضِف المتغيّر
weather_functionتحت هذا التعليق. هذه عبارة عن قاموس يقدّم للنموذج كل ما يحتاج إلى معرفته عن غرض الدالة ومعلَماتها ووسيطاتها المطلوبة.weather_function = { "name": "get_current_temperature", "description": "Gets the current temperature for a given location.", "parameters": { "type": "object", "properties": { "location": { "type": "string", "description": "The city name, e.g. San Francisco", }, }, "required": ["location"], }, } - بعد ذلك، ابحث عن التعليق
# TODO: Define the get_current_temperature function. أضِف رمز Python التالي أدناه. ستنفّذ هذه الدالة ما يلي:- استدعِ واجهة برمجة تطبيقات ترميز جغرافي للحصول على إحداثيات الموقع الجغرافي.
- استخدِم هذه الإحداثيات لطلب واجهة برمجة تطبيقات خاصة بالطقس.
- عرض سلسلة بسيطة تتضمّن درجة الحرارة ووحدتها
def get_current_temperature(location: str) -> str: """Gets the current temperature for a given location.""" try: # --- Get Latitude and Longitude for the location --- geocode_url = f"https://geocoding-api.open-meteo.com/v1/search?name={location}&count=1&language=en&format=json" geocode_response = requests.get(geocode_url) geocode_data = geocode_response.json() if not geocode_data.get("results"): return f"Could not find coordinates for {location}." lat = geocode_data["results"][0]["latitude"] lon = geocode_data["results"][0]["longitude"] # --- Get Weather for the coordinates --- weather_url = f"https://api.open-meteo.com/v1/forecast?latitude={lat}&longitude={lon}¤t_weather=true" weather_response = requests.get(weather_url) weather_data = weather_response.json() temperature = weather_data["current_weather"]["temperature"] unit = "°C" return f"{temperature}{unit}" except Exception as e: return f"Error fetching weather: {e}"
15. إعادة تصميم Chat والأدوات
تستخدم دالة call_model الحالية طلب generate_content بسيطًا لمرة واحدة. هذا الخيار رائع للأسئلة الفردية، ولكنّه ليس مثاليًا للمحادثات المتعددة، خاصةً تلك التي تتضمّن تبادلاً للرسائل بشأن الأدوات.
من الأفضل استخدام جلسة محادثة، التي تحتفظ بسياق المحادثة. سنعيد الآن تصميم الرمز البرمجي لاستخدام جلسة محادثة، وهو أمر ضروري لتنفيذ الأدوات بشكل صحيح.
- احذف الدالة
call_modelالحالية. سنستبدلها بنسخة أكثر تقدّمًا. - أضِف بدلاً منها الدالة الجديدة
call_modelمن مقطع الرمز البرمجي أدناه. تحتوي هذه الدالة الجديدة على منطق للتعامل مع حلقة استدعاء الأدوات التي ناقشناها سابقًا. لاحظ أنّها تتضمّن العديد من تعليقات TODO التي سنكملها في الخطوات التالية.# --- Call the Model --- def call_model(prompt: str, model_name: str) -> str: """ This function interacts with a large language model (LLM) to generate text based on a given prompt. It maintains a chat session and handles function calls from the model to external tools. """ try: # TODO: Get the existing chat session or create a new one. message_content = prompt # Start the tool-calling loop while True: # TODO: Send the message to the model. # Check if the model wants to call a tool has_tool_calls = False for part in response.candidates[0].content.parts: if part.function_call: has_tool_calls = True function_call = part.function_call logging.info(f"Function to call: {function_call.name}") logging.info(f"Arguments: {function_call.args}") # TODO: Call the appropriate function if the model requests it. # If no tool call was made, break the loop if not has_tool_calls: break # TODO: Return the model's final text response. except Exception as e: return f"Error: {e}" - الآن، لنضِف دالة مساعدة لإدارة جلسة الدردشة. أضِف الدالة
get_chatفوق الدالة الجديدةcall_model. ستنشئ هذه الدالة جلسة محادثة جديدة تتضمّن تعليمات النظام وتعريفات الأدوات، أو ستسترد الجلسة الحالية. هذه ممارسة جيدة لتنظيم الرموز البرمجية.def get_chat(model_name: str): if f"chat-{model_name}" not in st.session_state: # TODO: Define the tools configuration for the model # TODO: Define the generate_content configuration, including tools # TODO: Create a new chat session st.session_state[f"chat-{model_name}"] = chat return st.session_state[f"chat-{model_name}"]
لقد أعددت الآن البنية الأساسية لمنطق المحادثة المتقدّم الذي يتيح استخدام الأدوات.
16. تنفيذ منطق استدعاء الأدوات
لنملأ الآن TODOs لجعل منطق استدعاء الأدوات يعمل بشكل كامل.
تنفيذ get_chat
- في الدالة
get_chatضمن التعليق# TODO: Define the tools configuration...، حدِّد العنصرtoolsمن خلال إنشاء مثيلtypes.Toolمن تعريفweather_function.tools = types.Tool(function_declarations=[weather_function]) - ضمن
# TODO: Define the generate_content configuration...، حدِّدgenerate_content_config، مع الحرص على تمرير العنصرtoolsإلى النموذج. هذه هي الطريقة التي يتعرّف بها النموذج على الأدوات التي يمكنه استخدامها.generate_content_config = types.GenerateContentConfig( system_instruction=[types.Part.from_text(text=system_instructions)], tools=[tools] # Pass the tool definition here ) - ضمن
# TODO: Create a new chat session، أنشئ عنصر المحادثة باستخدامclient.chats.create()، مع إدخال اسم النموذج والإعداد.chat = client.chats.create( model=model_name, config=generate_content_config, )
تنفيذ call_model
- ضمن
# TODO: Get the existing chat session...في الدالةcall_model، استدعِ دالة المساعدة الجديدةget_chat.chat = get_chat(model_name) - بعد ذلك، ابحث عن
# TODO: Send the message to the model. أرسِل رسالة المستخدم باستخدام طريقةchat.send_message().response = chat.send_message(message_content) - ابحث عن
# TODO: Call the appropriate function.... هذا هو المكان الذي نتحقّق فيه من الوظيفة التي يريدها النموذج وننفّذها.
if function_call.name == "get_current_temperature":
result = get_current_temperature(**function_call.args)
function_response_part = types.Part.from_function_response(
name=function_call.name,
response={"result": result},
)
message_content = [function_response_part]
- أخيرًا، ابحث عن
# TODO: Return the model's final text responseوأضِف عبارة الإرجاع.return response.text
تم تعديل الدالة get_chat
من المفترض أن تبدو دالة get_chat المعدَّلة الآن على النحو التالي:
def get_chat(model_name: str):
if f"chat-{model_name}" not in st.session_state:
#Tools
tools = types.Tool(function_declarations=[weather_function])
# Initialize a confiburation object
generate_content_config = types.GenerateContentConfig(
system_instruction=[types.Part.from_text(text=system_instructions)],
tools=[tools]
)
chat = client.chats.create(
model=model_name,
config=generate_content_config,
)
st.session_state[f"chat-{model_name}"] = chat
return st.session_state[f"chat-{model_name}"]
تم تعديل الدالة call_model
من المفترض أن تبدو دالة call_model المعدَّلة الآن على النحو التالي:
def call_model(prompt: str, model_name: str) -> str:
try:
chat = get_chat(model_name)
message_content = prompt
while True:
response = chat.send_message(message_content)
has_tool_calls = False
for part in response.candidates[0].content.parts:
if part.function_call:
has_tool_calls = True
function_call = part.function_call
logging.info(f"Function to call: {function_call.name}")
logging.info(f"Arguments: {function_call.args}")
if function_call.name == "get_current_temperature":
result = get_current_temperature(**function_call.args)
function_response_part = types.Part.from_function_response(
name=function_call.name,
response={"result": result},
)
message_content = [function_response_part]
elif part.text:
logging.info("No function call found in the response.")
logging.info(response.text)
if not has_tool_calls:
break
return response.text
except Exception as e:
return f"Error: {e}"
17. اختبار التطبيق الذي تم تفعيل الأداة فيه
لنطّلِع على ميزتك الجديدة عمليًا.
- في الوحدة الطرفية، أوقِف العملية الجارية حاليًا (CTRL+C).
- أعِد تشغيل الأمر لبدء تطبيق Streamlit مرة أخرى.
streamlit run app.py --browser.serverAddress=localhost --server.enableCORS=false --server.enableXsrfProtection=false --server.port 8080 - أعِد تحميل تطبيق Streamlit. إذا كان تطبيق Streamlit لا يزال قيد التشغيل، يمكنك ببساطة إعادة تحميل صفحة معاينة الويب في المتصفّح.
- الآن، اطرح سؤالاً من المفترض أن يؤدي إلى تشغيل أداتك الجديدة، مثل ما يلي:
I'm looking for something to do in New York today. What do you recommend? Would it be a good day to go to Ellis Island? - اضغط على ENTER
لمقارنة هذا الرد بالردود السابقة. ما هي الاختلافات؟
من المفترض أن يظهر لك ردّ يتضمّن درجة الحرارة من الدالة. تحقَّق أيضًا من نافذة Cloud Shell، من المفترض أن تظهر لك عبارات الطباعة التي تؤكّد تنفيذ دالة Python.
18 تحسين إخراج النموذج باستخدام المَعلمات
أحسنت. يمكن لمساعد السفر الآن استخدام أدوات لجلب بيانات خارجية مباشرة، ما يجعله أكثر فعالية.
بعد أن حسّنّا إمكانات نموذجنا، لنركّز الآن على تحسين طريقة استجابته. تتيح لك مَعلمات النموذج التحكّم في أسلوب النص الذي تنشئه النماذج اللغوية الكبيرة ودرجة عشوائيته. من خلال تعديل هذه الإعدادات، يمكنك جعل ناتج البوت أكثر تركيزًا وتحديدًا أو أكثر إبداعًا وتنوّعًا.
في هذا التمرين العملي، سنركّز على temperature وtop_p. (يُرجى الرجوع إلى GenerateContentConfig في مرجع واجهة برمجة التطبيقات للاطّلاع على قائمة كاملة بالمعلّمات القابلة للإعداد وأوصافها).
temperature: تتحكّم في عشوائية الناتج. تؤدي القيمة المنخفضة (الأقرب إلى 0) إلى أن يكون الردّ أكثر حتمية وتركيزًا، بينما تؤدي القيمة المرتفعة (الأقرب إلى 2) إلى زيادة العشوائية والإبداع. بالنسبة إلى روبوتات الدردشة المخصّصة للأسئلة والأجوبة أو المساعدة، يُفضّل عادةً استخدام درجة عشوائية منخفضة للحصول على ردود أكثر اتساقًا وواقعية.top_p: الحدّ الأقصى للاحتمال التراكمي للرموز المميّزة التي يجب أخذها في الاعتبار عند أخذ العيّنات. يتم ترتيب الرموز المميزة استنادًا إلى الاحتمالات المحدّدة لها، وبالتالي لا يتم أخذ سوى الرموز المميزة الأكثر ترجيحًا في الاعتبار. يأخذ النموذج في الاعتبار الرموز المميّزة الأكثر ترجيحًا التي يصل مجموع احتمالاتها إلى قيمةtop_p. تؤدي القيمة المنخفضة إلى تقييد خيارات الرموز المميزة، ما يؤدي إلى إنتاج محتوى أقل تنوعًا.
مَعلمات المكالمة
- ابحث عن المتغيّرين
temperatureوtop_pالمحدّدين في أعلىapp.py. لاحظ أنّه لم يتم استدعاؤها بعد في أي مكان. - أضِف
temperatureوtop_pإلى المَعلمات المحدّدة ضمنGenerateContentConfigفي الدالةcall_model.generate_content_config = types.GenerateContentConfig( temperature=temperature, top_p=top_p, system_instruction=[types.Part.from_text(text=system_instructions)], tools=[tools] # Pass the tool definition here )
تم تعديل الدالة get_chat
يظهر تطبيق get_chat الآن على النحو التالي:
def get_chat(model_name: str):
if f"chat-{model_name}" not in st.session_state:
#Tools
tools = types.Tool(function_declarations=[weather_function])
# Initialize a confiburation object
generate_content_config = types.GenerateContentConfig(
temperature=temperature,
top_p=top_p,
system_instruction=[types.Part.from_text(text=system_instructions)],
tools=[tools]
)
chat = client.chats.create(
model=model_name,
config=generate_content_config,
)
st.session_state[f"chat-{model_name}"] = chat
return st.session_state[f"chat-{model_name}"]
19. الاختبار باستخدام مَعلمات النموذج
- في الوحدة الطرفية، أوقِف العملية الجارية حاليًا (CTRL+C).
- أعِد تشغيل الأمر لبدء تطبيق Streamlit مرة أخرى.
streamlit run app.py --browser.serverAddress=localhost --server.enableCORS=false --server.enableXsrfProtection=false --server.port 8080 - أعِد تحميل تطبيق Streamlit. إذا كان تطبيق Streamlit لا يزال قيد التشغيل، يمكنك ببساطة إعادة تحميل صفحة معاينة الويب في المتصفّح.
- جرِّب طرح السؤال نفسه كما كان من قبل،
I'm looking for something to do in New York today. What do you recommend? Would it be a good day to go to Ellis Island? - اضغط على ENTER
لمقارنة هذا الرد بالردود السابقة.
20. تهانينا!
لقد نجحت في ترقية تطبيق الأسئلة والأجوبة باستخدام الأدوات، وهي ميزة فعّالة تتيح لتطبيقك المستند إلى Gemini التفاعل مع الأنظمة الخارجية والوصول إلى المعلومات في الوقت الفعلي.
مواصلة التجربة
تتوفّر العديد من الخيارات لمواصلة تحسين طلبك. في ما يلي بعض الأمور التي يجب مراعاتها:
- اضبط
temperatureوtop_pواطّلِع على كيفية تغييرهما للردّ الذي تقدّمه نماذج اللغات الكبيرة. - راجِع
GenerateContentConfigفي مرجع واجهة برمجة التطبيقات للاطّلاع على قائمة كاملة بالمعلّمات القابلة للإعداد وأوصافها. جرِّب تحديد المزيد من المَعلمات وتعديلها لمعرفة ما سيحدث.
ملخّص
في هذا الدرس التطبيقي، نفّذت ما يلي:
- استخدام محرّر Cloud Shell ووحدة التحكّم الطرفية للتطوير
- استخدام حزمة تطوير البرامج (SDK) الخاصة بلغة Python في Vertex AI لربط تطبيقك بنموذج Gemini
- تطبيق تعليمات النظام ومَعلمات النموذج لتوجيه ردود النموذج اللغوي الكبير
- تعرّفت على مفهوم الأدوات (استدعاء الدوال) وفوائده.
- أعدنا تصميم الرمز البرمجي لاستخدام جلسة محادثة ذات حالة، وهي من أفضل الممارسات المتعلّقة بالذكاء الاصطناعي الحواري.
- تم تحديد أداة للنموذج باستخدام تعريف دالة.
- تم تنفيذ دالة Python لتوفير منطق الأداة.
- كتابة الرمز البرمجي للتعامل مع طلبات استدعاء الدوال في النموذج وعرض النتائج