استراتيجيات التسجيل والتوثيق
تسجيل إصدارات المطالبات والمدخلات والمخرجات لتصحيح الأخطاء بصورة قابلة لإعادة الإنتاج
استراتيجيات التسجيل والتوثيق درس مجاني في AI Prompt Engineering على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في AI Prompt Engineering، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة AI Prompt Engineering 4 دروس في المجموع.
أهمية تسجيل المطالبات
من دون تسجيل، تظل حالات فشل المطالبات غير مرئية حتى يبلغ عنها أحد المستخدمين. أما مع التسجيل، فيمكنك:
- اكتشاف حالات التراجع فور حدوثها
- إعادة إنتاج أي فشل سابق تمامًا كما حدث
- قياس التحسن بمرور الوقت مع تطور المطالبات
- مراجعة سلوك النموذج للتحقق من الامتثال أو السلامة
لا يُعد التسجيل اختياريًا في أنظمة المطالبات الإنتاجية؛ بل هو أساس تطبيقات LLM الموثوقة.
الحد الأدنى من إدخال السجل القابل للتطبيق
ينبغي أن يسجّل كل تفاعل مع المطالبة هذه الحقول كحد أدنى:
timestamp: توقيت UTC وفق ISO 8601prompt_id: قالب المطالبة المستخدمmodel: اسم النموذج وإصداره بدقةtemperature: مَعلمة أخذ العيناتinput: رسالة المستخدم (أو تجزئة لها إذا احتوت على PII)output: استجابة النموذجlatency_ms: زمن الاستجابةtokens_used: رموز الإدخال + الإخراج
import time, json
from datetime import datetime, timezone
def logged_call(prompt_id, system_prompt, user_message, model='gpt-4o', temperature=0.7):
start = time.time()
resp = client.chat.completions.create(
model=model,
messages=[
{'role': 'system', 'content': system_prompt},
{'role': 'user', 'content': user_message}
],
temperature=temperature
)
latency = int((time.time() - start) * 1000)
output = resp.choices[0].message.content
log_entry = {
'timestamp': datetime.now(timezone.utc).isoformat(),
'prompt_id': prompt_id,
'model': model,
'temperature': temperature,
'input': user_message,
'output': output,
'latency_ms': latency,
'input_tokens': resp.usage.prompt_tokens,
'output_tokens': resp.usage.completion_tokens
}
append_log(log_entry)
return outputتنسيق التسجيل المهيكل
استخدم JSON مفصولًا بأسطر جديدة (JSONL) لملفات السجل. كل سطر عبارة عن كائن JSON كامل وصالح. ويتميز هذا التنسيق بأنه:
- يسهل الإلحاق به من دون أقفال
- يمكن لـ jq وpandas وجميع مجمّعات السجلات قراءته
- ملائم للبث — إذ يمكن معالجة كل سطر عند وصوله
import json
LOG_FILE = 'prompt_logs.jsonl'
def append_log(entry):
with open(LOG_FILE, 'a') as f:
f.write(json.dumps(entry) + '\n')
def read_logs():
with open(LOG_FILE) as f:
return [json.loads(line) for line in f if line.strip()]
# Query: all entries for prompt_id 'summarize_v3'
logs = read_logs()
summarize_logs = [e for e in logs if e['prompt_id'] == 'summarize_v3']
print(f'Total calls to summarize_v3: {len(summarize_logs)}')إصدارات المطالبات
تتغير المطالبات بمرور الوقت. ومن دون إدارة الإصدارات، لن تتمكن من إعادة إنتاج السلوك السابق أو مقارنة مخرجات النموذج عبر إصدارات المطالبة. استخدم معرّف إصدار في كل إدخال سجل.
إدارة الإصدارات البسيطة: سلسلة إصدار دلالية (مثل v1.2.3) أو تجزئة تثبيت git. خزّن إصدارات المطالبات في ملف مخصص حتى يمكن استرداد أي إصدار لإعادة التشغيل.
PROMPTS = {
'summarize': {
'v1': 'Summarize the following text.',
'v2': 'Summarize the following text in 3 sentences.',
'v3': 'Summarize the following text in exactly 3 sentences. '
'Start each sentence on a new line. No bullet points.'
}
}
CURRENT_VERSIONS = {'summarize': 'v3'}
def get_prompt(prompt_id):
version = CURRENT_VERSIONS[prompt_id]
return version, PROMPTS[prompt_id][version]
version, prompt = get_prompt('summarize')
log_entry['prompt_version'] = versionمعالجة PII في السجلات
قد تحتوي مدخلات المستخدم على معلومات تعريف شخصية (PII). وقد يؤدي تسجيل المدخلات الخام إلى انتهاك GDPR أو CCPA. وتشمل الخيارات:
- التجزئة: خزّن SHA-256 للمدخل — يمكن إعادة إنتاجه لإزالة التكرارات، لكن لا يمكن استخدامه لإعادة التشغيل
- الحجب: استخدم تعبيرًا نمطيًا أو نموذج NER لاستبدال PII قبل التسجيل
- التخزين المنفصل: سجّل PII في مخزن مشفّر مع ضوابط وصول؛ وسجّل معرّفًا مرجعيًا فقط في السجل الرئيسي
import hashlib, re
def redact_pii(text):
# Redact email addresses
text = re.sub(r'[\w.-]+@[\w.-]+\.\w+', '[EMAIL]', text)
# Redact phone numbers (US format)
text = re.sub(r'\b\d{3}[-.]\d{3}[-.]\d{4}\b', '[PHONE]', text)
return text
def hash_input(text):
return hashlib.sha256(text.encode()).hexdigest()[:16]
log_entry['input'] = redact_pii(user_message)
log_entry['input_hash'] = hash_input(user_message)تتبّع زمن الاستجابة والتكلفة
تتيح السجلات إنشاء لوحات معلومات للتكلفة وزمن الاستجابة. تتبّع المقاييس لكل إصدار من إصدارات المطالبة لاكتشاف حالات التراجع في الأداء أو التكلفة بعد تغيير المطالبة:
def compute_cost(entry, price_per_1m_input=5.0, price_per_1m_output=15.0):
input_cost = entry['input_tokens'] / 1_000_000 * price_per_1m_input
output_cost = entry['output_tokens'] / 1_000_000 * price_per_1m_output
return input_cost + output_cost
def prompt_stats(prompt_id, version):
logs = [e for e in read_logs()
if e['prompt_id'] == prompt_id and e.get('prompt_version') == version]
if not logs:
return
avg_latency = sum(e['latency_ms'] for e in logs) / len(logs)
total_cost = sum(compute_cost(e) for e in logs)
print(f'{prompt_id} {version}: {len(logs)} calls, avg {avg_latency:.0f}ms, total ${total_cost:.4f}')تسجيل تقييم المخرجات
بالإضافة إلى السجلات الخام، خزّن درجات التقييم إلى جانب كل إدخال سجل. يتيح ذلك تحليل الاتجاهات: هل تتحسن جودة المخرجات عبر إصدارات المطالبة؟
def evaluated_call(prompt_id, system_prompt, user_message, evaluator_fn):
output = logged_call(prompt_id, system_prompt, user_message)
score = evaluator_fn(user_message, output)
# Update the last log entry with the evaluation score
logs = read_logs()
last = logs[-1]
last['eval_score'] = score
last['eval_pass'] = score >= 0.8
# Rewrite the last line
with open(LOG_FILE, 'a') as f:
# In practice, use a DB or separate eval log
pass
return output, scoreتوثيق المطالبة
ينبغي أن يكون لكل قالب مطالبة إدخال توثيقي مرافق يتناول ما يلي:
- الغرض: المهمة التي تنفذها هذه المطالبة
- المتغيرات: العناصر النائبة الموجودة وما هو متوقع منها
- القيود المعروفة: المدخلات التي يُعرف أن المطالبة تفشل معها
- سجل الإصدارات: ما الذي تغيّر في كل إصدار ولماذا
- حالات الاختبار: رابط إلى مجموعة الاختبارات الخاصة بهذه المطالبة
PROMPT_DOCS = {
'summarize': {
'purpose': 'Summarize a single text passage into 3 sentences.',
'variables': {'text': 'The passage to summarize (max 2000 tokens)'},
'known_limitations': [
'Fails to preserve numbers accurately for texts with many statistics',
'May not summarize correctly for non-English text'
],
'versions': {
'v1': 'Initial version — vague length instruction',
'v2': 'Added 3-sentence limit',
'v3': 'Added line-break and no-bullet formatting fix'
},
'test_suite': 'tests/test_summarize.py'
}
}استخدام خدمات التسجيل المركزية
بالنسبة إلى أنظمة الإنتاج، اكتب السجلات في خدمة مركزية بدلًا من الملفات المحلية:
- LangSmith: منصة التتبّع والتقييم الأصلية لـ LangChain
- Weights and Biases Prompts: تتبّع التجارب الخاصة بالمطالبات
- Datadog / Grafana: لوحات عمليات قياسية مع مقاييس مخصصة
- Supabase / PostgreSQL: الاستعلام عن السجلات باستخدام SQL للتحليل المخصص
يبقى المخطط نفسه؛ الذي يتغير هو الوجهة فقط.
# Example: writing to Supabase
from supabase import create_client
supabase = create_client('https://xxx.supabase.co', 'your-anon-key')
def log_to_supabase(entry):
supabase.table('prompt_logs').insert(entry).execute()
# Now query with SQL:
# SELECT prompt_id, prompt_version, AVG(latency_ms), COUNT(*)
# FROM prompt_logs
# WHERE timestamp > NOW() - INTERVAL '7 days'
# GROUP BY prompt_id, prompt_version
# ORDER BY COUNT(*) DESC;التنبيه عند ارتفاع معدلات الفشل
اضبط التنبيهات عند ارتفاع معدلات الفشل متجاوزةً حدًا معينًا. مثال: إذا أعاد أكثر من 10% من الاستدعاءات إلى prompt ما JSON غير صالح خلال نافذة مدتها 5 دقائق، فأرسل تنبيهًا.
from collections import deque
from datetime import datetime, timezone, timedelta
recent_results = deque(maxlen=100) # sliding window
def track_and_alert(prompt_id, success, alert_fn, threshold=0.10):
recent_results.append({'success': success, 'time': datetime.now(timezone.utc)})
window = [
r for r in recent_results
if r['time'] > datetime.now(timezone.utc) - timedelta(minutes=5)
]
if not window:
return
fail_rate = sum(1 for r in window if not r['success']) / len(window)
if fail_rate > threshold:
alert_fn(f'ALERT: {prompt_id} failure rate {fail_rate:.0%} in last 5 min')الاحتفاظ بالسجلات وأرشفتها
حدّد سياسة للاحتفاظ بالسجلات:
- سجلات الاستدعاءات الخام: 30 يومًا (على أساس متجدد) — حجمها كبير، ونحتاج إليها لتصحيح المشكلات الحديثة
- المقاييس المجمعة: سنة واحدة — نحتاج إليها لتحليل الاتجاهات والتنبؤ بالتكاليف
- سجلات الفشل: إلى أجل غير مسمى — نحتاج إليها لاكتشاف أنماط الأسباب الجذرية
اضغط السجلات الخام وأرشفها بعد 30 يومًا. لا تحذف سجلات الفشل أبدًا — فهي ذاكرتك المؤسسية لهندسة الـprompt.
اختبار المعرفة
ما الميزة الأساسية لاستخدام تنسيق JSON المفصول بأسطر جديدة (JSONL) لسجلات الـprompt مقارنةً بمصفوفة JSON واحدة كبيرة؟
خلاصة: تسجيل الـprompt وتوثيقه
الممارسات الأساسية لتسجيل الـprompt وتوثيقه:
- سجّل كل استدعاء: الطابع الزمني، prompt_id، version، model، temperature، input، output، latency، tokens
- استخدم تنسيق JSONL: يسهّل الإضافة في نهاية الملف، وقابل للاستعلام باستخدام الأدوات القياسية
- أصدِر نسخًا من الـprompt: يحصل كل تغيير على نسخة جديدة، وتشير السجلات إلى النسخة
- تعامل مع PII: احجب المدخلات الحساسة أو أنشئ لها قيم hash قبل تسجيلها
- تتبّع التكلفة وزمن الاستجابة: لاكتشاف التراجعات بعد تحديثات الـprompt
- أطلق تنبيهًا عند ارتفاع معدلات الفشل: مراقبة معدل الفشل ضمن نافذة منزلقة
بهذا تختتم الدورة التدريبية 17 حول تصحيح أخطاء فشل الـprompt. التالي: حقن الـprompt والدفاع ضده.
تعلم AI Prompt Engineering مع معلم ذكاء اصطناعي — مجانًا
اكتب وقم بتشغيل أكوادك الفعلية في المتصفح، واحصل على مساعدة فورية من معلم ذكاء اصطناعي متاح 24/7، واستمر من حيث توقفت على الويب أو في التطبيق.
- الدورات
- 53
- الدروس
- 199
الأسئلة الشائعة
هل درس «استراتيجيات التسجيل والتوثيق» مجاني؟
نعم — نص درس «استراتيجيات التسجيل والتوثيق» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة AI Prompt Engineering، انتقل إلى CoddyKit PRO. تتضمن دورة AI Prompt Engineering 4 دروس في المجموع.
ماذا ستتعلم في «استراتيجيات التسجيل والتوثيق»؟
تسجيل إصدارات المطالبات والمدخلات والمخرجات لتصحيح الأخطاء بصورة قابلة لإعادة الإنتاج تتمرن على AI Prompt Engineering مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ AI Prompt Engineering؟
لا تُشترط خبرة سابقة. AI Prompt Engineering على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.
كم من الوقت يستغرق درس «استراتيجيات التسجيل والتوثيق»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس AI Prompt Engineering هذا؟
نعم. كل درس في AI Prompt Engineering يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- تشخيص المخرجات غير المتوقعة
- تحليل السبب الجذري للمطالبات
- نهج منهجي لتصحيح الأخطاء
- استراتيجيات التسجيل والتوثيق