أهلاً بك مجدداً! في الدروس السابقة، قمنا ببناء "أيدي" و"عيون" وكيلنا الذكي. لقد أنشأنا أداة send_email التي تسمح له بالتصرف، وأداة read_recipients_from_file التي تمكنه من الإدراك وقراءة البيانات. الآن، حان الوقت لنمنحه "عقلاً" حقيقياً.
في هذا الدرس، سنقوم بالخطوة الأكثر أهمية وإثارة في مشروعنا حتى الآن: تطوير منطق الوكيل لاستخدام نموذج لغوي كبير (LLM) لتخصيص محتوى البريد الإلكتروني لكل مستلم. سنتعلم كيف "نوجه" هذا العقل الاصطناعي ليكتب رسالة فريدة ومخصصة لكل شخص في قائمتنا، بناءً على البيانات التي لدينا عنه. المهارة الأساسية التي سنكتسبها اليوم هي هندسة الأوامر (Prompt Engineering)، وهي جوهر التفاعل الفعال مع نماذج الذكاء الاصطناعي.
بحلول نهاية هذا الدرس، سيكون لديك وكيل متكامل يقرأ البيانات، و"يفكر" في كل مستلم على حدة، وينشئ محتوى مخصصاً، ثم يرسله. لنبدأ!
1. فن توجيه الذكاء الاصطناعي: مقدمة إلى هندسة الأوامر
قبل أن نجعل وكيلنا يكتب رسائل البريد الإلكتروني، يجب أن نتعلم كيف نطلب منه ذلك. هذا هو جوهر هندسة الأوامر (Prompt Engineering). ببساطة، هي فن وعلم صياغة التعليمات (الأوامر أو "Prompts") التي نقدمها لنموذج اللغة الكبير (LLM) للحصول على أفضل النتائج الممكنة. فكر في الأمر كأنك تعطي تعليمات لمساعد ذكي جداً ولكنه حرفي، كلما كانت تعليماتك أوضح وأكثر تحديداً، كانت النتيجة أفضل.

لفهم الأساسيات بشكل أعمق، لنبدأ بقراءة هذه المادة التي تقدم تعريفاً شاملاً لهندسة الأوامر والمفاهيم المرتبطة بها.
فهم أساسيات هندسة الأوامر وتطبيقاتها في اللغة العربية
يقدم هذا المقال من موقع أحمد بوشفرة شرحاً تأسيسياً ممتازاً باللغة العربية. سيرسخ فهمك للمفاهيم الأساسية التي سنبني عليها.
اقرأ قسم "1. مقدمة إلى هندسة الأوامر (Prompt Engineering)" لفهم ما هي هندسة الأوامر وأهميتها. ثم اقرأ قسم "2. المفاهيم الأساسية والمصطلحات" للتعرف على تعريفات الذكاء الاصطناعي، النماذج اللغوية، والموجه (Prompt).
مكونات الأمر الفعال
الأمر الجيد ليس مجرد سؤال، بل هو مجموعة من التعليمات المنظمة. تتكون الأوامر الفعالة عادةً من عدة مكونات رئيسية تساعد النموذج على فهم المطلوب بدقة.
هندسة الأوامر: الدليل العملي الكامل
يشرح هذا المقال من Kabshotech بالتفصيل المكونات التي تجعل الأمر احترافياً. فهم هذه المكونات سيغير طريقتك في التفاعل مع الذكاء الاصطناعي.
اقرأ القسم الذي يبدأ بعنوان "بنية إطار هندسة الأوامر التنفيذية (Executive Prompt Engineering)". ركز على فهم المكونات التالية: الدور (Role)، السياق (Context)، المدخلات (Inputs/Data)، المهمة (Task/Action)، والقيود (Constraints).
للتلخيص، هذه هي المكونات الأساسية لأمر فعال:
- الدور (Role): اطلب من النموذج أن يتقمص شخصية محددة. (مثال: "تصرف كخبير تسويق متخصص في كتابة الإعلانات").
- السياق (Context): قدم معلومات خلفية عن الموقف. (مثال: "أنا أرسل بريداً لعملاء محتملين لم يسمعوا بشركتنا من قبل").
- المهمة (Task): حدد ما يجب على النموذج فعله بوضوح. (مثال: "اكتب مسودة بريد إلكتروني قصيرة").
- المدخلات (Input Data): زوّد النموذج بالبيانات التي سيعمل عليها. (مثال: "اسم العميل هو 'خالد' وهو من مدينة 'جدة'").
- القيود (Constraints): ضع حدوداً للنتيجة. (مثال: "يجب ألا يتجاوز البريد 100 كلمة، واستخدم نبرة ودودة وغير رسمية").
اختبر فهمك!
لنفترض أنك تريد من النموذج اللغوي أن يكتب لك وصفًا لمنتج (قهوة مختصة جديدة) لعرضه على متجر إلكتروني. حاول صياغة أمر يستخدم على الأقل أربعة من المكونات الخمسة التي تعلمتها (الدور، السياق، المهمة، المدخلات، القيود).
Show answer
إليك مثال على أمر فعال:
- الدور: "تصرف ككاتب محتوى محترف متخصص في وصف المنتجات الغذائية الفاخرة."
- السياق: "نحن بصدد إطلاق منتج قهوة جديد في متجرنا الإلكتروني الذي يستهدف محبي القهوة المميزة."
- المهمة: "اكتب وصفاً جذاباً لهذا المنتج."
- المدخلات: "اسم المنتج: 'أرابيكا من مرتفعات إثيوبيا'. معلومات: حبوب بن أحادية المصدر، محمصة بدرجة متوسطة، بإيحاءات الفواكه الحمراء والشوكولاتة."
- القيود: "اجعل الوصف قصيراً (حوالي 50-70 كلمة)، واستخدم لغة عاطفية تثير حواس المتذوق، وتجنب المصطلحات المعقدة جداً."
2. من التعليمات الثابتة إلى التخصيص الديناميكي
الآن بعد أن فهمنا كيفية صياغة أمر جيد، كيف نجعله مخصصاً لكل مستلم في قائمتنا؟ هنا يأتي دور الأوامر الديناميكية (Dynamic Prompts). بدلاً من كتابة أمر ثابت، سنقوم بإنشاء "قالب أمر" يحتوي على عناصر نائبة (placeholders)، ثم نملأ هذه العناصر ببيانات كل مستلم بشكل آلي.

في بايثون، أفضل طريقة لإنشاء هذه القوالب هي باستخدام f-strings. تسمح لنا f-strings بدمج المتغيرات والتعبيرات مباشرة داخل النصوص بكل سهولة.
لنفترض أن لدينا قاموسًا يمثل مستلماً واحداً من قائمتنا:
recipient = {
"name": "سارة",
"email": "sarah@example.com",
"city": "دبي"
}
يمكننا إنشاء قالب أمر ديناميكي بهذا الشكل:
prompt_template = f"""
تصرف كخبير تسويق ودود.
مهمتك هي كتابة نص بريد إلكتروني قصير وجذاب.
العميل المستهدف هو {recipient['name']} الذي يعيش في مدينة {recipient['city']}.
الهدف من البريد هو دعوته لتجربة خدمتنا الجديدة لتوصيل الوجبات الصحية.
اكتب نص البريد الإلكتروني. اجعله شخصياً وودوداً، واذكر اسمه ومدينته.
لا تتجاوز 100 كلمة.
"""
print(prompt_template)
إذا قمت بتشغيل هذا الكود، سترى أن قيم recipient['name'] و recipient['city'] قد تم إدراجها مباشرة في النص، مما ينتج عنه أمر مخصص بالكامل لسارة! سنستخدم هذه التقنية داخل حلقة تكرارية لمعالجة كل مستلم.
3. بناء عقل الوكيل ومنطقه البرمجي
حان الوقت لتجميع كل شيء معًا في ملف main.py الذي سيكون نقطة انطلاق وتشغيل وكيلنا. سيقوم هذا البرنامج النصي بتنسيق العملية بأكملها: قراءة البيانات، التفكير باستخدام LLM، والتصرف عبر إرسال البريد الإلكتروني.
الفيديو التالي، على الرغم من أنه يستخدم أداة بدون كود (no-code)، إلا أنه يوضح بشكل مرئي ممتاز نفس المنطق الذي سنبنيه: تحديد طلب مخصص (قالب أمر) يحتوي على متغيرات ديناميكية، وإرساله إلى الذكاء الاصطناعي للحصول على مخرجات.
دليل n8n للمبتدئين 2026: أنشئ وكلاء ذكاء اصطناعي خطوة بخطوة
شاهد هذا المقطع من قناة Metics Media | عربى لترى تمثيلاً مرئياً للعملية التي سنقوم ببرمجتها. ركز على كيفية إنشاء "طلب مخصص" وإدخال متغيرات ديناميكية فيه لتوجيه الذكاء الاصطناعي.
شاهد المقطع من الدقيقة 8:58 إلى 11:14. لاحظ كيف يتم كتابة قالب الطلب (Prompt Template) ثم إدراج متغير ديناميكي (الطابع الزمني) فيه. هذا يمثل تماماً ما سنفعله باستخدام f-strings وبيانات المستلمين.
الآن، لنحول هذا المفهوم إلى كود بايثون. سنحتاج إلى:
- إعداد OpenAI: التأكد من أن مفتاح API الخاص بـ OpenAI مُعد كمتغير بيئة (كما تعلمنا في الوحدة 2).
- ملف
main.py: إنشاء ملف جديد سيكون هو البرنامج الرئيسي. - دالة للتفكير: إنشاء دالة مساعدة
generate_personalized_contentتأخذ بيانات المستلم، وتصيغ الأمر، وتتواصل مع OpenAI API. - الحلقة الرئيسية: كتابة الحلقة التي تقرأ المستلمين واحداً تلو الآخر وتطبق عليهم منطق التفكير والفعل.
الخطوة 1: تحديث ملف tools.py
قبل أن نبدأ، لنجعل دالة send_email أكثر أمانًا للاختبار. سنضيف معامل dry_run الذي يمنع إرسال البريد الفعلي ويقوم بطباعة المحتوى فقط.
افتح ملف tools.py وعدّل دالة send_email لتبدو هكذا:
# في ملف tools.py
import os
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
# ... (باقي دوال الاستيراد مثل csv و json) ...
def send_email(recipient_email, subject, body, dry_run=False):
"""
ترسل بريدًا إلكترونيًا.
:param recipient_email: بريد المستلم.
:param subject: عنوان البريد.
:param body: محتوى البريد.
:param dry_run: إذا كانت True، تطبع البريد بدلاً من إرساله.
"""
sender_email = os.environ.get("SENDER_EMAIL")
password = os.environ.get("SENDER_PASSWORD")
smtp_server = os.environ.get("SMTP_SERVER")
smtp_port = int(os.environ.get("SMTP_PORT", 587))
if not all([sender_email, password, smtp_server]):
print("خطأ: متغيرات بيئة البريد الإلكتروني غير مكتملة.")
return
message = MIMEMultipart()
message["From"] = sender_email
message["To"] = recipient_email
message["Subject"] = subject
message.attach(MIMEText(body, "plain"))
if dry_run:
print("--- وضع الاختبار (Dry Run) ---")
print(f"إلى: {recipient_email}")
print(f"الموضوع: {subject}")
print(f"النص:\n{body}")
print("----------------------------")
return
try:
with smtplib.SMTP(smtp_server, smtp_port) as server:
server.starttls()
server.login(sender_email, password)
server.send_message(message)
print(f"تم إرسال البريد بنجاح إلى {recipient_email}")
except Exception as e:
print(f"فشل إرسال البريد إلى {recipient_email}. الخطأ: {e}")
# ... (باقي الكود في tools.py) ...
الخطوة 2: إنشاء ملف main.py
أنشئ ملفًا جديدًا باسم main.py في نفس المجلد. هذا هو الكود الكامل الذي ستحتاجه. اقرأ التعليقات بعناية لفهم كل جزء.
import os
import openai
from tools import read_recipients_from_file, send_email
# --- الإعداد ---
# تأكد من أنك قمت بتعيين مفتاح OpenAI API كمتغير بيئة باسم OPENAI_API_KEY
# يمكنك الحصول على المفتاح من: https://platform.openai.com/api-keys
try:
openai.api_key = os.environ["OPENAI_API_KEY"]
except KeyError:
print("خطأ: لم يتم العثور على متغير البيئة OPENAI_API_KEY.")
print("يرجى تعيينه قبل تشغيل البرنامج.")
exit()
def generate_personalized_content(recipient):
"""
ينشئ محتوى بريد إلكتروني مخصص باستخدام LLM.
هذه هي وظيفة 'التفكير' في وكيلنا.
:param recipient: قاموس يحتوي على بيانات المستلم (مثل name, city).
:return: سلسلة نصية تحتوي على جسم البريد الإلكتروني المخصص.
"""
# صياغة الأمر الديناميكي باستخدام f-string
prompt = f"""
تصرف كخبير تسويق عبر البريد الإلكتروني متخصص في التواصل الشخصي.
مهمتك هي كتابة نص بريد إلكتروني قصير جداً وودود.
سياق الرسالة: نحن شركة ناشئة تقدم خدمة توصيل طعام صحي.
المستلم هو {recipient.get('name', 'عميلنا العزيز')}، وهو يعيش في مدينة {recipient.get('city', 'مدينتك')}.
الهدف: إثارة اهتمامه لتجربة خدمتنا.
اكتب نص البريد الإلكتروني. يجب أن:
1. يبدأ بتحية شخصية (مرحباً [اسم الشخص]).
2. يذكر بشكل طبيعي أنه من سكان مدينة [اسم المدينة].
3. يكون قصيراً ومباشراً (لا يتجاوز 3-4 جمل).
4. ينتهي بدعوة لتجربة الخدمة.
"""
try:
print(f"يتم التفكير في رسالة مخصصة لـ {recipient.get('name')}...")
response = openai.chat.completions.create(
model="gpt-3.5-turbo", # يمكنك استخدام "gpt-4" إذا كان متاحاً لديك
messages=[
{"role": "system", "content": "أنت مساعد تسويقي خبير."},
{"role": "user", "content": prompt}
],
temperature=0.7, # قيمة بين 0 و 1 للتحكم في إبداع النموذج
max_tokens=150 # الحد الأقصى لطول الرد
)
# استخراج النص من الاستجابة
content = response.choices[0].message.content.strip()
return content
except Exception as e:
print(f"حدث خطأ أثناء التواصل مع OpenAI: {e}")
return None
# --- حلقة العمل الرئيسية للوكيل ---
if __name__ == "__main__":
# 1. الإدراك (Perceive): قراءة قائمة المستلمين
# تأكد من وجود ملف `recipients.csv` في نفس المجلد
recipients_list = read_recipients_from_file('recipients.csv')
if not recipients_list:
print("لم يتم العثور على مستلمين. سيتم إنهاء البرنامج.")
else:
# 2. التفكير والتصرف (Think & Act) لكل مستلم
for person in recipients_list:
# التفكير (Think): إنشاء محتوى مخصص
email_body = generate_personalized_content(person)
if email_body:
# التصرف (Act): إرسال البريد الإلكتروني
subject = f"عرض خاص لسكان {person.get('city', 'مدينتكم')}!"
# استخدم dry_run=True للاختبار دون إرسال رسائل فعلية
send_email(person['email'], subject, email_body, dry_run=True)
else:
print(f"تم تخطي إرسال البريد إلى {person.get('name')} بسبب خطأ في إنشاء المحتوى.")
print("\n" + "="*30 + "\n") # فاصل بين كل عملية
للتشغيل:
- تأكد من وجود ملف
recipients.csvالذي أنشأته في الدرس السابق. - تأكد من إعداد متغيرات البيئة الخاصة بالبريد (
SENDER_EMAIL،SENDER_PASSWORD...) ومتغير البيئةOPENAI_API_KEY. - قم بتشغيل الملف من الطرفية:
python main.py
ستلاحظ أن البرنامج الآن يقرأ كل مستلم، ويتوقف للحظة (أثناء "التفكير" والتواصل مع OpenAI)، ثم يطبع بريداً إلكترونياً مخصصاً بالكامل لكل شخص!
خلاصة الدرس
لقد حققنا قفزة نوعية اليوم! وكيلنا لم يعد مجرد مجموعة من الأدوات المنفصلة، بل أصبح نظاماً متكاملاً يتبع دورة عمل منطقية:
- الإدراك: يقرأ قائمة المستلمين من ملف.
- التفكير: يستخدم نموذج لغة كبير (LLM) لإنشاء محتوى بريد إلكتروني مخصص لكل فرد بناءً على بياناته.
- التصرف: يرسل البريد المخصص (أو يطبعه في وضع الاختبار).
المفاهيم الأساسية التي غطيناها:
- هندسة الأوامر (Prompt Engineering): تعلمنا كيفية صياغة تعليمات واضحة ومفصلة للحصول على المخرجات المطلوبة من الذكاء الاصطناعي.
- الأوامر الديناميكية: استخدمنا f-strings في بايثون لإنشاء قوالب أوامر يتم ملؤها ببيانات فريدة لكل مستلم.
- تنسيق منطق الوكيل: قمنا ببناء حلقة عمل رئيسية في
main.pyتنسق بين الإدراك (قراءة الملفات) والتفكير (استدعاء LLM) والتصرف (إرسال البريد).
ماذا بعد؟
لقد قمنا ببناء وتطوير منطق الوكيل. في الدرس القادم، سنقوم بتجميع كل شيء معاً لتنفيذ حلقة عمل الوكيل الكاملة. سنتعلم كيف نقرأ قائمة المستلمين، نخصص البريد لكل واحد منهم، ونرسله بالفعل كجزء من حملة مصغرة. سنركز على التأكد من أن كل الأجزاء التي بنيناها تعمل معًا بسلاسة.