رموز API للنماذج الكبيرة: التقدير، القراءة، الميزانية والأمثلة
استخدام API للنماذج الكبيرة يشبه استخدام الكهرباء: عدم مراقبة العداد قد يفاجئك بالفاتورة في نهاية الشهر؛ بينما مراقبته يمنحك وضوحاً لكل وحدة. هنا، العداد هو عداد الرموز. نبدأ بشرح ماهية الرمز وكيفية تقديره للصينية والإنجليزية، ثم نعلمك قراءة حقل usage في الاستجابة، وإضافة صمامات الميزانية لبرامجك، وأخيراً نعرض ثلاث أمثلة توضيحية تطبق أسعار الإدخال $0.25 والإخراج $1.00 (لكل مليون رمز) على سيناريوهات محددة.
تم التحديث في
نقاط رئيسية
- معادلة الفوترة: (رموز الإدخال × $0.25) + (رموز الإخراج × $1.00) ÷ 1,000,000.
- التقدير يستخدم للتنبؤ المسبق فقط؛ الاستخدام الفعلي يعتمد على حقل usage في الاستجابة، وتحتوي الاستجابة المتدفقة على usage في الكتلة الأخيرة فقط.
- التكلفة الرئيسية لتطبيقات المحادثة هي إرسال التاريخ المتكرر، لذا يعد تقصير التاريخ الخيار الأكثر توفيراً.
- ثلاث أدوات للتحكم في الميزانية: تحديد max_tokens، تحديد طول التاريخ، وتراكم التكاليف في البرنامج مع تحديد حد يومي.
ما هي الرموز، وكيف تُحسب التكاليف
الرمز هو أصغر وحدة معالجة للنص في النموذج، وهو ليس حرفاً ولا كلمة، بل "شظية" بينهما. يمكنك تخيله كعلامة على عداد الماء: كلما استخدمت أكثر، تحركت العلامة أسرع. تتكون التكلفة من جزأين:
| البند | الوحدة (لكل مليون رمز) | ما الذي يتضمنه |
|---|---|---|
| الإدخال | $0.25 | كل محتوى في messages: system، التاريخ، سؤالك الحالي |
| الإخراج | $1.00 | رد النموذج المُولّد |
ملاحظة: سعر الإخراج أربعة أضعاف سعر الإدخال، لذا فإن جعل النموذج "يقلل من الكلام الزائد" يوفر المال أكثر من "إرسال سياق أقل"، لكن في سيناريوهات المحادثة، يتضخم الإدخال بسبب تراكم التاريخ، لذا يجب إدارة الجانبين. طريقة الدفع هي رصيد مسبق الدفع، وليس اشتراكاً، والرصيد لا ينتهي؛ الحسابات الجديدة تحصل على رصيد تجريبي بقيمة $0.50 صالح لمدة 7 أيام.
ملاحظة إضافية قد تسبب لبساً: رموز الإخراج هي الكمية التي يولدها النموذج فعلياً، وليست max_tokens التي تحددها. max_tokens هو الحد الأقصى فقط؛ إذا أجاب النموذج بـ 200 كلمة فقط، فسيتم احتساب الرسوم بناءً على الرموز المقابلة لـ 200 كلمة فقط. لكن عند التنبؤ بالميزانية، يجب حساب السيناريو الأسوأ بناءً على الحد الأقصى لتجنب المفاجآت من الإطالات غير المتوقعة.
التقدير المسبق: كيفية تقدير الرموز الصينية والإنجليزية
قبل إرسال الطلب، لا يمكن إلا التقدير. القيم أدناه تقريبية وقد تختلف حسب المحتوى:
| النص | قاعدة التقدير | مثال (افتراضي) |
|---|---|---|
| الصينية | كل حرف يقارب 1 إلى 1.5 رمز | 3000 حرف تقارب 3000 إلى 4500 رمز |
| الإنجليزية | كل 4 أحرف تقارب 1 رمز، أو كل كلمة تقارب 1.3 رمز | 1000 كلمة تساوي تقريباً 1300 رمز |
| نص مختلط (صيني/إنجليزي) ورموز | التقدير بناءً على القيم الأعلى | محتوى JSON والرموز يستهلك أكثر |
الاستخدام الصحيح للتقدير هو "تحديد الحجم": هل هذا المقال يحتوي على 10,000 أو 100,000 رمز؟ هل سيملأ نافذة السياق البالغة 100,000 رمز؟ كم ستكلف الاستدعاءة الواحدة؟ للدقة، اقرأ usage. عادة جيدة هي تشغيل عشرات العينات لكل سيناريو عملي، وحساب متوسط usage، واستخدامه بدلاً من القيم التجريبية.
مثال يجمع بين التقدير والقياس الفعلي. افترض أنك تعالج مجموعة من ملاحظات العملاء الصينية بحجم 2000 حرف، بتقدير 1.3 رمز للحرف، يكون الطلب الواحد حوالي 2600 رمز، مضافاً إليه 200 رمز للأوامر، فيصبح الإدخال حوالي 2800. اختر 30 طلباً وشغلها، واقرأ متوسط usage. إذا كان المتوسط الفعلي 2500، فقم بتعديل معاملك إلى حوالي 1.15. بعد ذلك احسب ميزانية الدفعة الكاملة باستخدام المعامل المعدل، وستقل الخطأ بشكل كبير. هذا الرقم الفعلي هو مجرد افتراض لتوضيح الطريقة، وستكون لديك بياناتك الخاصة.
قراءة usage: "قراءة العداد" الحقيقية
كل استجابة ناجحة تحتوي على usage، والذي يتضمن prompt_tokens، completion_tokens، و total_tokens. الاستجابة المتدفقة لا تحتاج معلمات إضافية، وتضيف تلقائياً كتلة بيانات تحتوي على usage في النهاية. يوضح الكود أدناه طريقتي القراءة ويحول القراءة إلى دولارات:
import os
from openai import OpenAI
client = OpenAI(base_url="https://api.apidamoxing.com/v1", api_key=os.environ["API_KEY"])
PRICE_IN, PRICE_OUT = 0.25, 1.00 # 美元 / 百万 token
def cost(u):
return (u.prompt_tokens * PRICE_IN + u.completion_tokens * PRICE_OUT) / 1_000_000
# 非流式:usage 在响应对象上
r = client.chat.completions.create(
model="uncensored", max_tokens=200,
messages=[{"role": "user", "content": "用三句话解释什么是通货膨胀。"}],
)
print(r.usage.prompt_tokens, r.usage.completion_tokens, f"${cost(r.usage):.6f}")
# 流式:最后一个数据块带 usage,其余块的 usage 为空
usage_last = None
stream = client.chat.completions.create(
model="uncensored", max_tokens=200, stream=True,
messages=[{"role": "user", "content": "再用三句话解释什么是通货紧缩。"}],
)
for chunk in stream:
if chunk.usage:
usage_last = chunk.usage
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)
print()
if usage_last:
print(usage_last.prompt_tokens, usage_last.completion_tokens, f"${cost(usage_last):.6f}")أثناء التدفق: انتبه إلى أن usage موجود فقط في الكتلة الأخيرة، وهو فارغ في الكتل الأخرى، لذا استخدم if chunk.usage للتحقق. سجل قراءة كل طلب في السجلات أو قاعدة البيانات، وستعتمد عليها في نهاية الشهر للمطابقة، وفحص الشذوذ، وحساب تكلفة المستخدم الواحد.
عادة أخرى تستحق التكوين: وضع علامات لكل وظيفة عمل، وتسجيل التكاليف معاً. على سبيل المثال، سجل "الملخص" و"خدمة العملاء" و"الترجمة" بشكل منفصل، وعند المطابقة في نهاية الشهر، ستعرف أي وظيفة هي الأكثر تكلفة، وما إذا كان يجب تحسين الموجّه، أو تقصير التاريخ، أو تقليل max_tokens. بدون علامات، سيكون لديك رقم إجمالي واحد فقط، مما يجعل التحسين صعباً.
ثلاثة أمثلة (تم توضيح الافتراضات)
المثال الأول: خدمة العملاء
افتراض: كل طلب يحتوي على 800 رمز (نص النظام وشظايا المعرفة)، و200 رمز للإخراج؛ 10,000 طلب يومياً.
تكلفة الطلب الواحد: 800 × 0.25 ÷ 1,000,000 = $0.0002، والإخراج 200 × 1.00 ÷ 1,000,000 = $0.0002، المجمل $0.0004. يومياً $4.00، خلال 30 يوماً $120. بهذه السرعة، يمكن لرصيد التجربة بقيمة $0.50 أن يدعم حوالي 1250 استدعاءً من هذا النوع.
المثال الثاني: تلخيص المقالات الطويلة
الافتراض: كل مقال يحتوي على 20,000 رمز للإدخال، و600 رمز للإخراج (التلخيص)؛ 500 مقال في المجموع.
لكل مقال: 20,000 × 0.25 ÷ 1,000,000 = $0.005، مضافاً إليها 600 × 1.00 ÷ 1,000,000 = $0.0006، المجمل $0.0056. 500 مقال تكلف $2.80. يتضح أن المهام ذات الإدخال الطويل والإخراج القصير رخيصة التكلفة.
المثال الثالث: الدردشة متعددة الجولات وقص التاريخ
الافتراض: نظام 100 رمز؛ كل جولة تحتوي على إدخال المستخدم 60 رمز، ورد 150 رمز؛ محادثة واحدة مكونة من 20 جولة.
| الحلول | إجمالي رموز الإدخال | إجمالي رموز الإخراج | التكلفة الإجمالية |
|---|---|---|---|
| كل الجولات مع التاريخ الكامل | 43,100 | 3,000 | حوالي $0.0138 |
| آخر 3 جولات فقط | 14,540 | 3,000 | حوالي $0.0066 |
إدخال الحل الذي يعتمد على التاريخ الكامل هو: 20 × (100 + 60) + 210 × (0 + 1 + … + 19) = 3,200 + 39,900 = 43,100. الحل الذي يقتصر على ثلاث جولات الأولى يحتوي على 160، والثانية 370، والثالثة 580، بينما الجولات من 4 إلى 20 تحتوي كل منها على 790 رمز، ليصبح المجمل 14,540. الفرق في التكلفة يبلغ حوالي النصف، ويصبح أكبر كلما زادت عدد الجولات، لأن إدخال الحل الذي يعتمد على التاريخ الكامل ينمو بشكل تربيعي مع عدد الجولات.
من هذه الأمثلة الثلاثة، يمكن استخلاص معادلة تجريبية: التكلفة تتحدد بشكل أساسي بـ "عدد الطلبات × حجم الإدخال والإخراج لكل طلب"، وحجم الإدخال لكل طلب يتأثر بشكل كبير بالتاريخ والمواد المرفقة. في سيناريو خدمة العملاء، تقليل طول المقاطع المعرفية، وفي سيناريو الدردشة، اقتطاع التاريخ، وفي سيناريو التلخيص، التوازي عبر التقسيم، كلها تتبع نفس المنطق: لا تدفع مقابل رموز غير ضرورية. تجدر الإشارة إلى أن أرقام هذه الأمثلة مستمدة بالكامل من الافتراضات المذكورة أعلاه، ويجب أن تعتمد على بيانات الاستخدام الفعلية.
لنعد إلى عملية حسابية عكسية: إذا كان ميزانيتك الشهرية $30، وتريد معرفة عدد محادثات الـ 20 جولة التي يمكن أن تدعمها منتج الدردشة شهرياً. باستخدام حل "آخر 3 جولات فقط" من المثال الثالث، كل محادثة تكلف حوالي $0.0066، $30 ÷ 0.0066 تعطي حوالي 4545 محادثة. بنفس الميزانية، باستخدام حل التاريخ الكامل، كل محادثة تكلف $0.0138، مما يكفي لحوالي 2174 محادثة فقط. هذا هو الفرق العملي الذي يترتب على اقتطاع التاريخ.
التحكم في الميزانية: تركيب صمامات في البرنامج
التقدير مجرد توقع، والصمام هو التأمين. فيما يلي صنف ميزانية يومي يسجل بالدولار: قبل الطلب، افترض "أسوأ حالة" (الإخراج يملأ max_tokens)؛ بعد الطلب، سجل الاستخدام الفعلي.
class Budget:
"""按美元计的日预算。超出时拒绝新请求。"""
def __init__(self, daily_usd):
self.limit = daily_usd
self.spent = 0.0
def check(self, est_prompt_tokens, max_tokens):
# 最坏情况:输出用满 max_tokens
worst = (est_prompt_tokens * 0.25 + max_tokens * 1.00) / 1_000_000
if self.spent + worst > self.limit:
raise RuntimeError(f"预算不足:已用 ${self.spent:.4f},本次最坏 ${worst:.4f},上限 ${self.limit}")
def record(self, usage):
self.spent += (usage.prompt_tokens * 0.25 + usage.completion_tokens * 1.00) / 1_000_000
budget = Budget(daily_usd=5.0)
budget.check(est_prompt_tokens=1200, max_tokens=500) # 请求前
# ……发请求……
# budget.record(response.usage) # 请求后بالإضافة إلى الصمامات داخل البرنامج، هناك ثلاث أدوات على مستوى التكوين:
- يتم ضبط max_tokens حسب المهمة، لا ترفعها دائماً للحد الأقصى؛ الافتراضي 2048، والحد الأقصى 32,000؛
- تعيين حد أقصى لطول تاريخ المحادثة، انظر الممارسات فيبناء روبوت الدردشة؛
- شحن رصيد الحساب فقط بالقيمة التي تخطط لاستخدامها، وأضف رصيداً عند النفاد، فوضع الدفع المسبق يشكل بحد ذاته حداً أقصى صارماً.
تعتمد الأسعار وقواعد الرصيد علىصفحة الأسعار، وتفاصيل الواجهة فيتفاصيل المعاملات.
لنلخص ذلك في قائمة مراجعة: قبل البدء، تقدير الحجم، تعيين max_tokens، فحص طول التاريخ؛ أثناء التنفيذ، الانتباه إلى استخدام آخر كتلة عند الإخراج المتدفق؛ بعد الانتهاء، تسجيل الاستخدام وتصنيفه حسب الوظيفة ومقارنته بالميزانية. بعد إكمال الخطوات الثلاث، تصبح الحسابات واضحة.
الأسئلة الشائعة
هل يتم دفع رسوم عن رموز الإدخال والإخراج على حد سواء؟
نعم. كل مليون رمز إدخال يكلف $0.25، وكل مليون رمز إخراج يكلف $1.00، ويتم الحساب بناءً على prompt_tokens و completion_tokens في بيانات الاستخدام.
هل يمكنني حساب التكلفة الدقيقة مسبقاً؟
يمكن تقدير الحجم التقريبي فقط. للأرقام الدقيقة، راجع حقل usage في الاستجابة. يُنصح بأخذ عينات إحصائية لكل سيناريو للحصول على متوسطات للتنبؤ.
هل الرصيد ينتهي؟
رصيد الدفع المسبق المضاف لا ينتهي. رصيد التجربة بقيمة $0.50 للحسابات الجديدة صالح لمدة 7 أيام.
كيف أتجنب أن تصبح المحادثة أغلى مع مرور الوقت؟
حدد طول التاريخ المرفق، احتفظ بآخر بضع جولات فقط، أو قم بضغط المحتوى الأقدم في تلخيص، وقم بتعيين max_tokens المناسب حسب المهمة.
املأ النموذج فقط للحصول على المفتاح
أنشئ حساباً، انسخ المفتاح، عدل Base URL. التكوين بهذه السهولة.