الأدلة الإرشادية
الصور والصوت والفيديو
يقيّم Oloproof الأنظمة التي تأخذ الصور والصوت والفيديو أو تنتجها، ولا تغادر الملفات أبدًا المكان الذي يحفظها فيه نظامك. يسجّل التشغيل كل ملف بالإشارة؛ وتقيس الفحوص الحتمية البايتات؛ ويستطيع الحَكَم أن يرى الصور وإطارات الفيديو والصوت؛ وتعرضها منصة العمل بجانب كل حُكم. ويشرح الدرس التعليمي الصور على مثال قابل للتشغيل.
تسجيل الوسائط
يسجّل نظامك الملفات التي تلقّتها الحالة أو أنتجتها بـ current_case().media(...)، كمُخرَج فني واحد من نوع media/v1 لكل استدعاء:
from oloproof import current_case, media_file, system
@system(name="captioner", version="v2", records=("media/v1",))
def caption(case):
image = render(case["prompt"]) # your system writes its own file
current_case().media([
media_file(case["photo"], role="input"),
media_file(image), # role="output" by default
])
return {"caption": describe(image)}في oloproof.yaml، يعلن النظام القابل للاستدعاء records: [media/v1]. ويحمل كل عنصر:
| الحقل | المعنى |
|---|---|
| kind | image أو audio أو video، من نوع MIME |
| mime_type | image/png، audio/wav، video/mp4 وما إلى ذلك |
| uri | مكان الملف: مسار file://، أو URL من نوع https://، أو مسار نسبةً إلى المشروع |
| digest | بصمة sha256 للبايتات، sha256:... |
| size_bytes | الحجم بالبايتات |
| role | input أو output (الافتراضي) أو context |
| name | الاسم الذي يسمّيه به الموجِّه أو الصفحة؛ ويستخدم media_file اسم الملف |
| width، height، duration_s | اختيارية، كما يعلنها نظامك |
يملأ media_file(path) هذه الحقول من ملف محلي. ولا يُنسخ شيء إلى مخزن Oloproof. وكل ما يقرأ الملف لاحقًا، فحصًا كان أو حَكَمًا أو منصة العمل، يقرؤه عبر read_media، الذي يرفض البايتات التي يختلف حجمها أو بصمة sha256 لها عن السجل: فالمحتوى المتغيِّر يوقف التشغيل، والملف الذي اختفى يترك الحالة مفقودة. أبقِ ملفات التشغيل، دون تغيير، ما دمت تحتفظ بالتشغيل؛ واكتب مُخرَجات كل نسخة في مكانها الخاص. وفي @evaluator الخاص بك، يعيد read_media(item) البايتات المفحوصة.
فحوص دون نموذج
يقيس media_check كل عنصر مسجَّل من دورٍ ما، وينجح حين يستوفي كل عنصر كل شرط معلَن:
- type: media_check
criterion: thumbnail_fits
kind: image
formats: [png, jpeg, webp]
max_width: 256
max_height: 256
max_bytes: 50000تُقرأ الصيغة من البايتات الأولى للملف، فيفشل ملف JPEG محفوظ باسم .png؛ وتُقرأ أحجام الصور ومدد WAV من ترويساتها؛ ويُقاس حجم الفيديو أو طول ملف MP3 بـ ffprobe. وتنطبق حدود المدة على الصوت والفيديو، وحدود الأبعاد على الصور والفيديو.
ينجح image_matches_reference حين تشبه كل صورة مرجعًا: أي حين لا تختلف بصمتاهما الإدراكيتان ذواتا الـ 64 بتًا في أكثر من max_distance بتًا (8 افتراضيًا). فالنسخة المعاد تحجيمها أو ضغطها تبقى ضمن بضعة بتات؛ أما الصورة الفارغة أو الملف التالف أو المشهد المختلف فلا. والمرجع إما reference_file واحد لكل الحالات، وإما مسار يسمّيه expected لكل حالة عبر reference_field. والبصمة تقرأ التكوين والضوء، لا اللون، لذا لا تستطيع التمييز بين منتجين صُوِّرا بالطريقة نفسها، والرسوم المسطّحة ذات المساحات الفارغة الكبيرة تحرّكها أكثر مما تحرّكها الصور الفوتوغرافية. وهي تحتاج إلى Pillow: pip install 'oloproof[media]'.
كل حقل موجود في مرجع التهيئة. ويحسم كلا الفحصين من التشغيل الأول، لأنهما لا يستدعيان أي نموذج.
حُكّام يرون الوسائط
يُعرض على rubric_judge مع media ما سُجِّل للحالة من وسائط ذلك الدور (input أو output أو all)، كلٌّ منها مسمًّى في موجِّهه كي يميّز الحَكَم المُدخَل من المُخرَج:
- type: rubric_judge
criterion: caption_matches
provider: openai_compatible
base_url: http://localhost:11434/v1
model: qwen2.5vl
rubric_text: Pass only if the caption truthfully describes the attached image.
media: output
video_frames: 4
transcriber:
model: whisper-1- تُرفق الصور كما هي، حتى 5 MB لكل منها و20 لكل حُكم.
- يُرفق الفيديو إطاراتٍ ثابتة، تُلتقط بـ ffmpeg على الجهاز الذي يشغّل الحَكَم: يأخذ video_frames: 4 منتصف كل واحد من أربعة مقاطع متساوية، ويأخذ [0.5, 2.0] تلك اللحظات.
- يُفرِّغ transcriber الصوتَ نصًّا (نقطة نهاية /audio/transcriptions متوافقة مع OpenAI، وهي نقطة OpenAI حين يُترك base_url) ويدخل النص المفرَّغ في الموجِّه؛ أو، مع audio: native، يُرفق صوتًا لنموذج يسمع (wav وmp3؛ وليس نماذج Anthropic).
بصمات الوسائط جزء مما يُبنى عليه مفتاح الحُكم، فالوسائط المتغيِّرة تُحكَم من جديد والوسائط التي لم تتغير تأتي من التخزين المؤقت. والمُفرِّغ وأزمنة الإطارات جزء من إصدار الحَكَم، ويحتفظ كل حُكم بنصوصه المفرَّغة وبإصدار ffmpeg. والحَكَم المعلَن للصوت دون مُفرِّغ، أو للفيديو على جهاز ليس فيه ffmpeg، يوقف التشغيل بدلًا من أن يترك تلك الحالات مفقودة. والنموذج المستضاف يحاسب على كل صورة كما يحاسب على كل كلمة.
التحقق من حَكَم الوسائط
الحَكَم الذي يرى الوسائط لا يحسم شيئًا حتى تُظهر وسوم البشر أنه يتفق معهم، تمامًا كالحَكَم الذي يقرأ النص: ضع وسومًا على عيّنة عشوائية، ثم oloproof evaluators validate (الحُكّام). وفي مساحة عمل مستضافة، يعرض طابور المراجعة وسائط كل حالة على المراجع. وتغيير النموذج أو المعيار أو media أو الإطارات أو المُفرِّغ يصنع حَكَمًا جديدًا، يحتاج إلى تحقق خاص به.
الوسائط في منصة العمل
تظهر وسائط الحالة بجانب مُخرَجها وأحكامها، في صفحة الحالة وفي طابور المراجعة، مع نوع كل ملف وحجمه وبصمته.
- تقرأ منصة العمل المحلية كل ملف من حيث سجّله التشغيل، على جهازك، ولا تعرضه إلا ما دامت بصمة sha256 له مطابقة.
- لا تتلقى مساحة العمل المستضافة الوسائط أبدًا. فمتصفح المشاهد يجلب كل ملف من oloproof collect على شبكتك، بالتذكرة القصيرة الأجل نفسها التي يستخدمها طابور المراجعة لمحتوى الحالات (الحُكّام)، ويفحص بصمة sha256 له قبل عرضه. ودون مُجمِّع، تسرد الصفحة حقائق كل ملف وتقول لماذا لا يُعرض.
يحمل التشغيل المُرسَل سجلات media/v1، مع مكان حفظ كل ملف، تحت فئة الإخراج artifacts؛ والسياسة التي تحجب artifacts تُبقي تلك الأماكن على جانبك أيضًا.
غير مدعوم
- توليد الوسائط: نظامك يصنع ملفاته، وOloproof يقيّمها.
- رفع الوسائط إلى Oloproof: لا يوجد رفع، لا مستضاف ولا محلي.
- نموذج يشاهد فيديو كاملًا أو يسمع الصوت عبر API الخاص بـ Anthropic: هناك يُحكم على الفيديو من إطاراته، وعلى الصوت عبر نص مفرَّغ.
- الفحوص الحتمية لما يحتويه الصوت أو الفيديو (معدل خطأ الكلمات، اكتشاف المشاهد): اكتب واحدًا بـ @evaluator وread_media.
- البصمة الإدراكية للصوت أو الفيديو: لا يقرأ image_matches_reference إلا الصور.