العودة إلى المدونة

النماذج والمقارناتدليل

قارن بين نموذجين لغويين كبيرين بعدل على مهمتك: تبديل الجانبين وسجل التكلفة

أجرِ مواجهة مباشرة بين نموذجين على تذاكرك الخاصة: إعدادات متساوية، وتقييم كل زوج في كلا الترتيبين، وسجل calls.jsonl يعطي تكلفة التشغيل.

بواسطة CheapTokens Teamنُشر في 7 دقيقة قراءة

الغلاف: قارن بين نموذجين بعدل، مع تدفق من ثلاث خطوات: نفس الموجه، بدّل الجانبين، سجّل كل استدعاء
في هذه الصفحة
  1. ما تفعله بطولة عامة يمكنك استعارته
  2. المهمة: صياغة ردود على 30 تذكرة دعم
  3. بدّل الجانبين: قيّم كل زوج مرتين
  4. سجّل كل استدعاء، ثم سعّر التشغيل
  5. قبل إطلاق التشغيل الكامل
  6. قراءة النتيجة دون خداع نفسك

لقد شغّلت ثلاثة أوامر توجيهية عبر نموذجين، وفاز الثاني. قبل أن تثق بذلك، تحقق من أيّهما كان مُدرجًا في المرتبة الثانية. المقارنة العادلة تحتاج إلى ثلاثة أشياء: إعدادات متطابقة لكلا النموذجين، وتقييم كل زوج في كلا الترتيبين، وسجل للرموز المميزة لكل استدعاء، حتى تعرف تكلفة التشغيل بأكمله. فيما يلي سكربت Python صغير يقوم بالأمور الثلاثة على مهمتك الخاصة.

ما تفعله بطولة عامة يمكنك استعارته#

Clocktower Bench من Dwarkesh Patel هو مشروع بحثي غير رسمي حيث تلعب نماذج اللغة لعبة الاستنتاج الاجتماعي Blood on the Clocktower ضد بعضها البعض. اللعبة ليست المقصود هنا؛ بل أداة الاختبار. وفقًا لـ صفحة About الخاصة بالمشروع (تم التحقق في 8 نوفمبر 2026)، فإنها تفعل بضعة أشياء يجب أن تفعلها أي مواجهة مباشرة:

  • يلعب نموذج واحد جميع المقاعد الجيدة وآخر جميع المقاعد الشريرة، وتُلعب كل توزيعة مرتين مع تبديل الجانبين، حتى لا يقرر مقعد محظوظ النتيجة؛
  • تحصل جميع النماذج على نفس الإعدادات: نفس جهد الاستدلال، وسقف 8,000 رمز مميز لكل دور، وحد 150 كلمة على الكلام؛
  • الراوي مبرمج، فلا يحكم أي نموذج على اللعبة؛
  • يُكتب كل استدعاء API إلى calls.jsonl مع رموزه المميزة وتكلفته. تقول الصفحة إن اللعبة الواحدة تكلف من حوالي 2 دولار إلى 50 دولارًا، اعتمادًا على النماذج (على واجهات OpenAI وAnthropic).

أداة الاختبار مبنية لنماذج OpenAI وAnthropic، ومهمتك على الأرجح ليست لعبة لوحية. لكن العادات الثلاث تنتقل: إعدادات متساوية، وجوانب متبادلة، وسجل تكلفة. يطبق باقي هذا الدليل هذه العادات على شيء عادي.

كل تذكرة تذهب إلى كلا النموذجين؛ يرى الحكم الزوج مرتين، بترتيبين متعاكسين
حلقة تبديل الجانبين لتذكرة واحدة

المهمة: صياغة ردود على 30 تذكرة دعم#

لنفترض أنك تدير مكتب دعم صغير وتريد معرفة ما إذا كان DeepSeek-V4-Flash أو GLM-5.3-Flash يكتب مسودات أولى أفضل. لديك ملف tickets.jsonl يحتوي على 30 تذكرة حقيقية، كائن JSON واحد لكل سطر: {"id": 1, "text": "..."}.

واجهة API متوافقة مع OpenAI، لذا تعمل حزمة openai الرسمية مع CheapTokens على https://api.cheaptokens.dev/v1. استخدم معرّفات النماذج الكاملة من الوثائق: deepseek-ai/DeepSeek-V4-Flash-0731 وzai-org/GLM-5.3-Flash. يحصل كلا النموذجين أيضًا على نموذج ثالث كحكم، MiniMaxAI/MiniMax-M2.7، حتى لا يقيّم أي من المتنافسين عمله بنفسه.

ابدأ بالجزء الذي يجعل السجل ممكنًا: دالة واحدة تمر عبرها كل استدعاء.

python
import json, os, re
from openai import OpenAI

client = OpenAI(base_url="https://api.cheaptokens.dev/v1",
                api_key=os.environ["CHEAPTOKENS_API_KEY"])

CONTESTANTS = {"deepseek": "deepseek-ai/DeepSeek-V4-Flash-0731",
               "glm": "zai-org/GLM-5.3-Flash"}
JUDGE = "MiniMaxAI/MiniMax-M2.7"
SETTINGS = {"temperature": 0.2, "max_tokens": 800}   # same for both

def call(model, messages, role, ticket_id, **settings):
    r = client.chat.completions.create(model=model, messages=messages, **settings)
    with open("calls.jsonl", "a", encoding="utf-8") as f:
        f.write(json.dumps({
            "role": role, "ticket": ticket_id, "model": model,
            "input_tokens": r.usage.prompt_tokens,
            "output_tokens": r.usage.completion_tokens,
            "finish": r.choices[0].finish_reason}) + "\n")
    return r.choices[0].message.content or ""

def draft(model, ticket):
    msgs = [{"role": "system", "content": "You answer support tickets. "
             "Reply in under 80 words, politely, with no promises about refunds."},
            {"role": "user", "content": ticket["text"]}]
    return call(model, msgs, "draft", ticket["id"], **SETTINGS)

الحقول في calls.jsonl هي التي يختارها هذا السكربت؛ أرقام الاستخدام تأتي من كائن usage في استجابة API. يحصل كلا النموذجين على نفس موجه النظام، ونفس temperature ونفس max_tokens. غيّر واحدًا منها لنموذج واحد وستكون تقارن إعدادات، لا نماذج.

بدّل الجانبين: قيّم كل زوج مرتين#

الآن الحكم. قد يميل نموذج الحكم نحو الإجابة في خانة معينة، لذا يخلط حكم واحد بين الجودة والموضع. تناسب حيلة Clocktower هنا تمامًا: اعرض كل زوج في كلا الدورين. تفوز إجابة بتذكرة فقط إذا اختارها الحكم في كلا الترتيبين. إذا تبع الحكم الخانة بدلاً من الإجابة، فالتذكرة تعادل.

python
def judge(ticket, first, second):
    prompt = (f"Ticket:\n{ticket['text']}\n\nReply A:\n{first}\n\nReply B:\n{second}\n\n"
              "Which reply is better for the customer? Finish with a last line: Verdict: A or Verdict: B.")
    out = call(JUDGE, [{"role": "user", "content": prompt}], "judge",
               ticket["id"], temperature=0, max_tokens=1000)
    letters = re.findall(r"Verdict:\s*([AB])\b", out)
    return letters[-1] if letters else None

tickets = [json.loads(l) for l in open("tickets.jsonl", encoding="utf-8")]
wins = {"deepseek": 0, "glm": 0, "tie": 0}

for t in tickets:
    a = draft(CONTESTANTS["deepseek"], t)
    b = draft(CONTESTANTS["glm"], t)
    v1 = judge(t, a, b)   # DeepSeek's reply shown as A
    v2 = judge(t, b, a)   # GLM's reply shown as A
    pick1 = {"A": "deepseek", "B": "glm"}.get(v1)
    pick2 = {"A": "glm", "B": "deepseek"}.get(v2)
    wins[pick1 if pick1 and pick1 == pick2 else "tie"] += 1

print(wins)

هناك تفصيلان يسهل تفويتهما. يعمل الحكم عند temperature=0 للحفاظ على ثبات أحكامه؛ لا تحترم كل النماذج هذا الإعداد، لذا أعد تشغيل بضعة أزواج وقارن الأحكام قبل أن تثق بها. يُقرأ الحكم فقط من سطر Verdict: نهائي، والحدود سخية (800 للمسودات، 1000 للحكم) حتى لا يُقطع نموذج يفكر قبل الإجابة في منتصف تفكيره؛ يستخدم التقدير أدناه الأحجام النموذجية، لا الحدود. الإجابة غير القابلة للتحليل تعطي None، والتي تقع في تعادل بدلاً من تعطيل التشغيل.

جرّب بنفسكجرّب: قال الحكم "A" في كلا الترتيبين للتذكرة 7. من يفوز بتلك التذكرة؟إظهار الإجابة

لا أحد. في الترتيب الأول كانت A إجابة DeepSeek، وفي الترتيب الثاني كانت A إجابة GLM، لذا فضّل الحكم الخانة، لا نموذجًا. يحسبها الكود كتعادل. كومة من هذه التعادلات هي بحد ذاتها نتيجة: النموذجان متقاربان في مهمتك، أو موجه الحكم غامض جدًا.

الترتيب هو طريقة واحدة فقط لإمالة اختبار. الإعدادات والموجهات والتسجيل يمكنها إمالته أيضًا، لذا تحقق من الإعداد بأكمله، لا فقط من يذهب أولاً. إليك نفس التجربة قبل وبعد.

قارن

ما الذي يتغير عندما تتوقف عن المقارنة بشكل عابر

عابر

موجه واحد لكل نموذج، والإعدادات الافتراضية متروكة، والزوج معروض بترتيب واحد، والفاتورة تُقرأ من لوحة التحكم في نهاية الشهر. قد يكون الفائز هو النموذج الذي صادف أنه مُدرج أولاً.

عادل

موجه نظام مشترك واحد ونفس temperature وmax_tokens، ويُقيّم كل زوج في كلا الترتيبين، وسطر في calls.jsonl لكل استدعاء. الفائز هو من يفوز من كلا المقعدين.

سجّل كل استدعاء، ثم سعّر التشغيل#

السجل هو ما يحول المقارنة إلى ميزانية. بعد التشغيل، اجمع الرموز المميزة لكل نموذج:

python
from collections import defaultdict

totals = defaultdict(lambda: [0, 0, 0])
for line in open("calls.jsonl", encoding="utf-8"):
    c = json.loads(line)
    s = totals[c["model"]]
    s[0] += c["input_tokens"]; s[1] += c["output_tokens"]; s[2] += 1

for model, (tin, tout, n) in totals.items():
    print(model, n, "calls", tin, "input", tout, "output")

ستحصل على سطر واحد لكل نموذج مع عدد الاستدعاءات ورموز الإدخال ورموز الإخراج. اضرب في سعري النموذج (يُفوتر الإدخال والإخراج بشكل منفصل) أو، الأسهل، الصق الإجماليات في علامة تكلفة حية.

يمكنك أيضًا التقدير قبل التشغيل. افترض أن كل تذكرة بالإضافة إلى موجه النظام تبلغ حوالي 300 رمز إدخال، والمسودة حوالي 250 رمز إخراج، ويرى الحكم حوالي 800 رمز إدخال (التذكرة بالإضافة إلى كلا الردين بالإضافة إلى السؤال) ويجيب بحوالي 200 رمز (سطر الحكم مع مساحة صغيرة للتفكير):

  • المسودات: 30 تذكرة × 2 نموذج = 60 استدعاء، 30 × 300 = 9000 إدخال و30 × 250 = 7500 رمز إخراج لكل متنافس؛
  • الأحكام: 30 تذكرة × 2 ترتيب = 60 استدعاء، 60 × 800 = 48000 إدخال و60 × 200 = 12000 رمز إخراج على الحكم.

بالأسعار الحالية، تكلف 30 مسودة لمتنافس واحد $0.00089 على DeepSeek-V4-Flash و$0.00048 على GLM-5.3-Flash. تكلف الأحكام الستون على MiniMax-M2.7 $0.0042. اجمع الثلاثة وستحصل على سعر المقارنة بأكملها قبل إرسال طلب واحد. نفس عبء الصياغة عبر النماذج الثلاثة، مع حساب الإدخال والإخراج معًا:

النموذج التكلفة OpenRouter
GLM-5.3-Flash $0.00048 $0.00092
DeepSeek-V4-Flash $0.00089 $0.0017
MiniMax-M2.7 $0.0016 $0.0189

9,000 رمز إدخال و7,500 رمز إخراج إجمالًا. الأسعار لكل مليون رمز حالية وتتغير مع تعريفاتنا؛ يعرض عمود OpenRouter أسعارًا مرجعية لنفس حجم العمل.

يعرض الجدول أيضًا مرجع OpenRouter، حتى ترى كيف يقارن الإجمالي. افتراضات الرموز المميزة لك لتغييرها: إذا كانت تذاكرك طويلة، ينمو إدخال الحكم بأسرع وتيرة، لأنه يحمل كلا الردين مرتين. إذا كان حكمك يفكر بصوت عالٍ قبل الإجابة، ينمو رقم إخراجه أيضًا، وسيظهر ذلك في سجلك. لعادة حساب الرموز المميزة قبل الطلب، راجع count tokens before you send a request.

نفس الحد الذي يستخدمه Clocktower يستحق الاستعارة. يحدد 8,000 رمز مميز لكل دور، ولديك بالفعل max_tokens. ضعه في SETTINGS ولا يمكن لإجابة جامحة أن تضاعف تقديرك بهدوء.

قبل إطلاق التشغيل الكامل#

قائمة التحقق

فحص ما قبل الإقلاع لمقارنة عادلة

العنصر الأخير مهم. شغّل ثلاث تذاكر، وافتح calls.jsonl واقرأه. تحقق من أن finish يقول stop بدلاً من length؛ إذا قُطعت مسودة بواسطة max_tokens، فقد يخسر نموذج فقط لأن إجابته قُطعت. الأمر نفسه ينطبق على استدعاءات الحكم: length هناك يتحول إلى تعادل صامت، لذا احسب أحكام None أيضًا. إذا كانت مهمتك لها إجابة صحيحة واحدة، فقد لا تحتاج إلى حكم على الإطلاق: test your prompt on 20 cases with exact-match grading.

قراءة النتيجة دون خداع نفسك#

انظر إلى الأرقام الثلاثة في wins. ثلاثون تذكرة عينة صغيرة: انقسام مثل 12 إلى 9 مع 9 تعادلات يخبرك أن النماذج متقاربة، لا أن أحدها أفضل. يساعد السجل هنا. إذا فاز نموذج قليلاً لكنه يستخدم إخراجًا أكثر بكثير، فالسؤال الحقيقي هو سعر المهمة، لا عدد الانتصارات؛ price per 1M tokens versus cost per task يتناول تلك المقارنة.

إذا كانت النتيجة متقاربة، اختر النموذج الأرخص للمهمة، أو أضف المزيد من التذاكر وأعد التشغيل. كلاهما رخيص التجربة لأن الآلية بأكملها هي بالفعل حلقة. عندما تريد تكرار التمرين على نموذج آخر، تقف النماذج الثلاثة أعلاه خلف API واحد ومفتاح واحد: الإعداد في docs هو نفسه لكل منها، وصفحة التسعير تسرد تكلفة كل منها الآن. اكتشاف Dwarkesh Patel نفسه حول نماذج OpenAI مقابل Anthropic (الكشف مقابل الخداع) هو نتيجته للعبته؛ ستأتي نتيجتك من تذاكرك.