AWS Machine Learningتاريخ نشر المصدر

يوم مارموت للوكلاء الذكاء الاصطناعي: أنماط التخزين المؤقت للأوامر لاستخدام نماذج OpenAI على Amazon Bedrock

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

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

في فيلم Groundhog Day، يعيش شخصية بيل موراي يوم 2 فبراير نفسه كل يوم. يستيقظ على الأغنية نفسها على الراديو، في النُّزُل نفسه، والبلدة الصغيرة نفسها، مرة تلو الأخرى لمدة يقدّرها بعض محبي الفيلم بـ 34 عاماً.

لا شيء مما أنجزه في اليوم السابق يبقى إلا إذا أعدّه من الصفر. وكلاء الذكاء الاصطناعي يعيشون نسخة من يوم المارموت. في كل مرة يتخذ فيها الوكيل خطوة (يستدعي أداة، يقرأ النتيجة، يقرر ماذا يفعل بعد ذلك)، عليه أن يرسل إلى النموذج قصته بأكملها حتى الآن للحفاظ على الاستمرارية: تعريفات الأدوات، والتعليمات، وكل استدعاء أداة سابق، وكل نتيجة. النموذج لا يتنبأ إلا بالرمز (token) التالي بناءً على المدخلات التي تقدمها له. ليس لديه ذاكرة داخلية بين الطلبات، لذا يجب أن يقرأ كل شيء من جديد. عند الدورة 20 من جلسة برمجة، يعيد النموذج قراءة الدورات من 1 إلى 19، وأنت من يدفع ثمن كل واحد من تلك الرموز، مرة تلو الأخرى.

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

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

ما يرسله الوكيل إلى نموذجه اللغوي الكبير

قبل الحديث عن التخزين المؤقت، من المفيد النظر إلى ما تحتويه الاستدعاء الأول النموذجي لأحد الوكلاء إلى النموذج اللغوي الكبير (LLM):

  • قائمة الأدوات – تعريفات كل دالة يمكن للوكيل استدعاؤها. تتغير عند إصدار إصدار جديد.
  • التعليمات – موجّه المطور: القواعد، الشخصية، السياسات، الأمثلة. تتغير أيضاً مع كل إصدار.
  • السجل – كل ما حدث في هذه الجلسة حتى الآن: المهمة، استدعاءات النموذج للأدوات، ونتائج الأدوات (والتي تنمو كل دورة).
  • الدورة الجديدة – أحدث نتيجة أداة أو رسالة مستخدم (والتي قد تختلف كل مرة).

ما يرسله الوكيل إلى النموذج، دورة بعد دورة إذا لم تُعدّ التخزين المؤقت:

الشكل 1: ما يرسله الوكيل إلى النموذج في كل دورة

كيف يعمل التخزين المؤقت للأوامر تحت الغطاء

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

يحفظ التخزين المؤقت للأوامر تلك الحالة، التي تحتوي على موجه النظام، والأدوات، والمحتوى، والسجل، وما إلى ذلك. عندما يبدأ طلب لاحق بالرموز الإدخالية نفسها (أي النص نفسه)، تقوم خدمة التخزين المؤقت للأوامر بتحميل الحالة المحفوظة بدلاً من حسابها من جديد. ثم يعالج فقط ما هو جديد في الحمولة التالية المرسلة إلى النموذج. يمكن أن يكون التخزين المؤقت للأوامر ضمنياً، حيث تختار Amazon Bedrock أين ينتهي البادئة القابلة لإعادة الاستخدام، أو صريحاً، حيث يحدد كودك تلك النقطة باستخدام prompt_cache_breakpoint. يمكنك استخدام الطريقتين معاً، ونوصي بذلك.

الدورة 1 مقارنة بالدورة 2

الشكل 2: الدورة 1 تحفظ بادئة الأمر حتى نقطة الفصل، والدورة 2 تعيد استخدامها وتدفع السعر الكامل فقط للسؤال الجديد

ضمني أم صريح، ولماذا نحتاج إلى كليهما؟

بالنسبة لأعباء العمل الوكيلة، يتيح التخزين المؤقت الضمني لـ Bedrock اختيار ما يُخزَّن مؤقتاً مع نمو المحادثة. أما مع التخزين المؤقت الصريح، فيمكنك تحديد المحتوى المشترك، مثل الأدوات والتعليمات، لإعادة استخدامه عبر الجلسات وعند إنشاء وكلاء مساعدين. لا تحتاج دائماً إلى كلا شكلَي التخزين المؤقت، لكن الجمع بينهما يمنحك نقطة انطلاق قابلة لإعادة الاستخدام بينما يدير Bedrock المحادثة المتنامية تلقائياً.

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

مرحبًا يا عالم التخزين المؤقت

الربح الأول هو تخزين الجزء الثابت من المطالبة مؤقتًا: الأدوات والتعليمات التي تظل كما هي عبر الطلبات. تستخدم هذه الأمثلة عميل Amazon Bedrock الحالي لديك، TOOLS، و task. استبدل النص المختصر INSTRUCTIONS بسياساتك وأمثلتك الحقيقية. يجب أن تصل البادئة القابلة لإعادة الاستخدام إلى 1,024 رمزًا حتى تكون مؤهلة.

عند تخزين المحتوى الثابت مؤقتًا، استخدم الوضع الصريح: اختر أين تنتهي البادئة المحفوظة.

KEY = "support-agent:v7:gpt-6-astra"
INSTRUCTIONS = "Your full support policies and examples..."

# Rendered context: [provider context][TOOLS][INSTRUCTIONS] | [task]
# Cache starts at the beginning; the marker below chooses its end.
resp = client.responses.create(
    model="us.openai.gpt-6-astra",
    store=False,  # Response storage; prompt caching still works.
    include=["reasoning.encrypted_content"],
    prompt_cache_key=KEY,
    prompt_cache_options={"mode": "explicit", "ttl": "30m"},
    tools=TOOLS,  # Rendered before instructions; keep order stable.
    input=[
        {
            "role": "developer",
            "content": [{
                "type": "input_text",
                "text": INSTRUCTIONS,
                # Save through this whole block, including TOOLS.
                "prompt_cache_breakpoint": {"mode": "explicit"},
            }],
        },
        # User message is processed but not cached.
        {"role": "user", "content": task},
    ],
)

يُخبر prompt_cache_key الخدمة بالطلبات المخصصة لمشاركة ذاكرة تخزين مؤقت. نعود إلى كيفية استخدامه عندما نصل إلى قراءة ذاكرة التخزين المؤقت في الجلسات الجديدة. في أحد اختباراتنا باستخدام التخزين المؤقت الصريح، كتبت بادئة الأدوات والتعليمات التي تبلغ نحو 4,000 رمز 4,120 رمزًا في الطلب الأول، وقرأت تلك الـ 4,120 رمزًا في الطلبات اللاحقة. يأتي task (أو طلب المستخدم) بعد حد ذاكرة التخزين المؤقت، لذا لا يؤدي هذا إلى تفعيل الكتابة إلى ذاكرة التخزين المؤقت.

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

مع نمو المحتوى وتنوعه (أدوات ومحتوى مختلفة)، استخدم الوضع الضمني ليتبع service المحادثة. هنا، الطلب الأول ليس يحتوي على أي علامة صريحة، وأحدث رسالة مؤهلة لديه هي مهمة المستخدم، لذا يأتي نقطة الفصل التلقائية بعد تلك المهمة وتغطي الأدوات والتعليمات والمهمة معًا. يُعرض الوضع صراحةً في المثال التالي للتوضيح، رغم أن الوضع الضمني هو الافتراضي. الإعداد store=False يترك سجل المحادثة في تطبيقك. إنه لا يعطّل التخزين المؤقت.

def ask_with_implicit_cache(history):
    return client.responses.create(
        model="us.openai.gpt-6-astra",
        store=False,
        include=["reasoning.encrypted_content"],
        prompt_cache_key=KEY,
        prompt_cache_options={"mode": "implicit", "ttl": "30m"},
        tools=TOOLS,
        input=history,  # Everything gets cached
    )

history = [
    {"role": "developer", "content": INSTRUCTIONS},
    {"role": "user", "content": task},
]
# Automatic endpoint: the end of the user message.
resp = ask_with_implicit_cache(history)

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

استخدم كليهما عندما يحتاج الوكيل إلى نقطة انطلاق مشتركة وسجل متزايد. ابدأ بالكتلة البرمجية للمطور المُعلَّمة في مثال الكود التالي واستدعِ الدالة ask_with_implicit_cache. يبقى الوضع على مستوى الطلب ضمنياً. تضيف العلامة على مستوى الكتلة نقطة حفظ صريحة بعد التعليمات. ويمكن للخدمة أيضاً الحفظ عبر أحدث رسالة مؤهلة. يحافظ هذا على توفر البادئة المشتركة مع نمو المحادثة.

history = [
    {
        "role": "developer",
        "content": [{
            "type": "input_text",
            "text": INSTRUCTIONS,
            "prompt_cache_breakpoint": {"mode": "explicit"}, 
        }],
    },
    {"role": "user", "content": task},
]
# Still implicit mode, now with an explicit startup save point in the history.
resp = ask_with_implicit_cache(history)

تخزين سجل المحادثة ونتائج الأدوات مؤقتًا

يطلب النموذج الأدوات بالاسم ويقدّم وسائطها. وعلى تطبيقك أن ينفّذها. execute_function هو مساعد تبنيه لتوجيه تلك الطلبات إلى دوال بايثون المطابقة وإرجاع نتائجها. تستخدم الحلقة التالية هذا المساعد لتشغيل كل أداة مطلوبة. وتضيف مخرجات النموذج وجميع نتائج الأدوات إلى history قائمة، ثم يرسل تلك القائمة مرة أخرى حتى يُعيد النموذج إجابة نهائية. في الوضع الضمني، يمكن لـ Amazon Bedrock إعادة استخدام البادئة غير المتغيرة وتخزين المحتوى المُضاف مؤقتًا حتى نتيجة الأداة الأخيرة. احتفظ بالرسائل السابقة والأولية TOOLS بدون تغيير.

import json

# Map tool names to their Python implementations.
TOOL_HANDLERS = {
    "get_owner": get_owner,
    # Register your other initial tools here.
}

def execute_function(name, arguments):
    """Run the requested tool and return its result."""
    handler = TOOL_HANDLERS.get(name)
    if handler is None:
        return {"error": f"Unknown tool: {name}"}
    return handler(**arguments)

while True:
    # Preserve all output items, including encrypted reasoning.
    history.extend(resp.output)
    calls = [x for x in resp.output if x.type == "function_call"]
    if not calls:
        break
    for call in calls:
        result = execute_function(call.name, json.loads(call.arguments))
        history.append({
            "type": "function_call_output",
            "call_id": call.call_id,
            "output": json.dumps(result),
        })
    # The last result in this group supplies the automatic endpoint.
    resp = ask_with_implicit_cache(history)

للمتابعة، أضف رسالة مستخدم جديدة واستدعِ الدالة المساعدة مرة أخرى. حافظ على الرسائل السابقة دون تغيير حتى تظل نقاط النهاية المخزّنة مؤقتًا متاحة.

نقاط التوقف المتدرجة: كل دور يقرأ كل ما قبله

الشكل 3: نقاط التوقف المتدرجة، حيث يقرأ كل دور كل ما قبله ويكتب نتيجة أداته الخاصة فقط

لتشغيل منفصل بالوضع الصريح فقط، أعد إنشاء سجل الرسالتين من مثال Hello cached world المدمج. تحيط هذه الحلقة نتائج الأدوات بـ input_text وتميّز النتيجة النهائية في كل دفعة. تبقى العلامات السابقة في history. انظر قواعد البحث الحالية للمحادثات الطويلة.

import json

while True:
    resp = client.responses.create(
        model="us.openai.gpt-6-astra", store=False,
        include=["reasoning.encrypted_content"],
        tools=TOOLS, prompt_cache_key=KEY, input=history,
        prompt_cache_options={"mode": "explicit", "ttl": "30m"},
    )
    d = resp.usage.input_tokens_details
    print("read", d.cached_tokens, "write", d.cache_write_tokens)
    history.extend(resp.output)  # Includes encrypted reasoning.
    calls = [x for x in resp.output if x.type == "function_call"]
    if not calls:
        break
    batch = []
    for call in calls:
        result = execute_function(call.name, json.loads(call.arguments))
        batch.append({
            "type": "function_call_output", "call_id": call.call_id,
            "output": [{"type": "input_text", "text": json.dumps(result)}],
        })
    # Add the newest boundary; retain every earlier marker.
    batch[-1]["output"][-1]["prompt_cache_breakpoint"] = {"mode": "explicit"}
    history.extend(batch)

حقق GPT-6 Astra أفضل نتيجة ضمنية بالتعادل في عبء العمل المكوّن من ستة أدوار هذه: انخفاض تكلفة الإدخال بنحو 62 بالمئة مقارنة بالتشغيل دون تخزين مؤقت. ووفّرت نقاط التوقف المتدرجة الصريحة نحو 61 بالمئة على النموذج نفسه. أعاد كلاهما استخدام مزيد من السجل كلما نماconte المحادثة. هذه نتائج عبء عمل. قِس وفورات وكيلك بنفسك.

الشكل 4: تكلفة الإدخال لكل إعداد تخزين مؤقت على GPT-6 Astra، نسبةً إلى عدم التخزين المؤقت

احذر من:

  • نقطة توقف ثابتة فقط في الوضع الصريح فقط – تُخزَّن الأدوات والتعليمات مؤقتًا، لكن تُعالَج السجلات المتزايدة من جديد في كل دور (0.61). لا ينطبق هذا القيد على المثال المدمج، الذي يوفّر أيضًا من خلال نهايات المحادثة المؤهلة.
  • تحريك نقطة توقف واحدة يمكن أن يمنع إعادة استخدام ذاكرة التخزين المؤقت ويسبب كتابات متكررة في الوضع الصريح فقط. احتفظ بنقطة توقف الدور السابق أيضًا.
  • كتابة ضمنية فقط من خلال مهمة متغيرة – قد تتشارك المهمة الجديدة الأدوات والتعليمات لكنها لا تشارك نقطة النهاية المحفوظة سابقًا. أضف علامة صريحة بعد التعليمات المشتركة إذا احتاجت مهام مختلفة إلى إعادة استخدام تلك البادئة الأقصر.

عندما تتغير الأدوات

أحيانًا تتغير قائمة أدوات الوكيل، أو تُضاف أدوات جديدة. حافظ على استقرار القائمة الأولية: إضافة التعريفات أو إزالتها أو إعادة ترتيبها يمكن أن يُبطل البادئة المخزَّنة مؤقتًا. اختر النهج المناسب لكيفية إتاحة الأداة.

عندما تُستدعى الأدوات المعروفة في خطوات مختلفة من تدفق الوكيل: أرسل نفس TOOLS مرتبةً واستخدم allowed_tools لتقييد ما يمكن للنموذج استدعاؤه. مع allowed_tools, "mode": "auto" يسمح للنموذج بتحديد ما إذا كان سينادٍ أداة مسموح بها، و "mode": "required" يتطلب استدعاء أداة مسموح بها واحدة على الأقل. مرّر هذا كـ tool_choiceلا يغير هذا التقييد الكتالوج المخزن مؤقتًا:

tool_choice={"type": "allowed_tools", "mode": "auto",
             "tools": [{"type": "function", "name": "get_owner"}]}

أدوات جديدة أثناء الجلسة. تقبل كل من نقاط نهاية Amazon Bedrock Runtime و Amazon Bedrock Mantle نوع عنصر إدخال يسمى additional_tools لـ GPT-6 Astra و GPT-6.1 Sol و GPT-5.6 Luna. للتعرّف على توافر النماذج حسب منطقة AWS، راجع النماذج المدعومة حسب منطقة AWS في Amazon Bedrock. سجّل الأداة الجديدة get_due_date في دالة المساعدة execute_function، ثم أضف مخططها إلى السجل المكتمل من حلقة الوكيل. حافظ على TOOLS الأولي دون تغيير:

TOOL_HANDLERS["get_due_date"] = get_due_date
NEW_TOOL = {
    "type": "function", "name": "get_due_date",
    "description": "Return the due date for a support case.",
    "strict": True,
    "parameters": {
        "type": "object",
        "properties": {"case_id": {"type": "string"}},
        "required": ["case_id"], "additionalProperties": False,
    },
}
history.append({
    "type": "additional_tools", "role": "developer",
    "tools": [NEW_TOOL],
})
history.append({
    "role": "user", "content": "Find the due date for case C-123.",
})
# Implicit mode saves through this new user message, including NEW_TOOL.
resp = ask_with_implicit_cache(history)
d = resp.usage.input_tokens_details
print("old prefix read", d.cached_tokens, "new write", d.cache_write_tokens)

# Example output:
# old prefix read 2048 new write 256

تصل أداة جديدة في منتصف الجلسة

الشكل 5: إضافة أداة تحافظ على إعادة استخدام البادئة السابقة، مع أعداد أمثلة من GPT-6 Astra على Amazon Bedrock Runtime

تابع حلقة تنفيذ الأداة مع الاستجابة الجديدة. تضيف الحلقة مخرجات النموذج إلى history، يشغّل أي أدوات مطلوبة، وينضم نتائجها. أبقِ additional_tools العنصر في الطلبات اللاحقة حتى تظل الأداة الجديدة متاحة. في الوضع الضمني (implicit mode)، يمكن لـ Amazon Bedrock إجراء التخزين المؤقت عبر رسالة المستخدم الجديدة، بما في ذلك تعريفات الأدوات التي تسبقها. في وضع الصريح فقط (explicit-only mode)، احتفظ بنقاط الفصل السابقة وأضف واحدة إلى input_text كتلة في رسالة المستخدم تلك. أما additional_tools العنصر نفسه فلا يمكنه احتواء نقطة توقف.

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

ملفات الأدوات المخزنة مؤقتًا

الشكل 6: لكل ملف أدوات بادئة مخزنة مؤقتًا خاصة به، قابلة لإعادة الاستخدام من خلال مطابقة الجلسات

الوكلاء الفرعيون والمكالمات الجانبية

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

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

shared = {"role": "developer", "content": [{
    "type": "input_text", "text": INSTRUCTIONS,
    "prompt_cache_breakpoint": {"mode": "explicit"},
}]}
warm = client.responses.create(
    model="us.openai.gpt-6-astra", store=False,
    tools=TOOLS, prompt_cache_key=KEY,
    prompt_cache_options={"mode": "implicit", "ttl": "30m"},
    max_output_tokens=16,
    input=[shared, {"role": "user", "content": "Reply READY."}],
)
d = warm.usage.input_tokens_details
if not (d.cache_write_tokens or d.cached_tokens):
    raise RuntimeError("Shared prefix was not cached.")
from concurrent.futures import ThreadPoolExecutor

# helper_tasks contains the task text for each helper.
helper_inputs = [
    [shared, {"role": "user", "content": task}]
    for task in helper_tasks
]
with ThreadPoolExecutor(max_workers=4) as pool:
    helpers = list(pool.map(ask_with_implicit_cache, helper_inputs))

يستخدم المساعدون نفس TOOLSوالموديل و KEY كما في التسخين. يمكن للتسخين الذي ينتهي عند حد المخرجات أن يملأ ذاكرة التخزين المؤقت مع ذلك. يؤكد فحص الاستخدام نشاط التخزين المؤقت قبل بدء المساعدين.

الوكلاء الفرعيون: سخّن البادئة المشتركة مرة واحدة، ثم وزّع

الشكل 7: سخّن البادئة المشتركة قبل إطلاق المساعدين، ثم يضيف كل مساعد مهمته الخاصة

امنح المكالمات الجانبية البداية نفسها. يبني حلقة الوكيل history عن طريق إلحاق كل resp.output ونتائج الأدوات المطابقة له، بما في ذلك الاستدلال المشفر. بعد انتهاء العنصر الأب، انسخ تلك القائمة الكاملة لأداة تلخيص أو حَكَم. يحافظ المساعد نفسه على الأدوات والموديل والمفتاح دون تغيير:

from copy import deepcopy

# history is the completed history built by the agent loop above.
# Copy it so the helper can add instructions without changing the parent.
helper_history = deepcopy(history)
helper_history.append({
    "role": "developer",
    "content": "Summarize this conversation in one sentence. Do not call tools.",
})
summary = ask_with_implicit_cache(helper_history)
d = summary.usage.input_tokens_details
print("history read", d.cached_tokens, "write", d.cache_write_tokens)
print(summary.output_text)

# Example output (assumed values and conversation):
# history read 4096 write 32
# Case C-123 is due on October 31, 2026.

يمكن للمساعد إعادة استخدام الجزء المخزن مؤقتًا من history، لكن رسالة المطور الملحقة لا توسّع ذاكرة التخزين المؤقت تلقائيًا لتشمل تعليمة التلخيص. إذا أعادت الطلبات اللاحقة استخدام نفس السجل والتعليمة، فضع التعليمة في كتلة input_text مع prompt_cache_breakpoint. وبالنسبة لملخص ل لمرة واحدة، لا حاجة إلى علامة إضافية.

التوقفات وإعادة التشغيل ومفتاح التخزين المؤقت

التوقفات. البادئات المخزنة مؤقتًا لها مدة بقاء (TTL) دنيا تبلغ 30 دقيقة، تُجدد بإعادة الاستخدام الناجحة، وقد تبقى لمدة أطول. إذا استؤافت جلسة قريبًا، فيمكن لتسخين عادي أن يجدد البادئة قبل انتهاء صلاحيتها. قارن تكلفة ذلك الطلب بترك ذاكرة التخزين المؤقت تنتهي. للاطلاع على قواعد TTL، راجع وثائق Amazon Bedrock.

الجلسات الجديدة. حافظ على ثبات prompt_cache_key للطلبات المفترض أن تتشارك بادئة. يعزل المفتاح الخاص بالجلسة الجلسات حتى عندما تتطابق مطالباتها. في المثال التالي، أدى التحويل إلى مفتاح مشترك إلى تمكين الجلسات من إعادة استخدام البادئة.

لا تعيد الجلسات الجديدة استخدام ذاكرة التخزين المؤقت إلا إذا كانت تشترك في المفتاح نفسه

الشكل 8: المفتاح الخاص بالجلسة يفصل إدخالات ذاكرة التخزين المؤقت، والمفتاح المشترك يتيح للجلسات المتطابقة إعادة استخدامها

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

import hashlib

def cache_key(app, model, prompt_version, instructions):
    digest = hashlib.sha256(instructions.encode()).hexdigest()[:12]
    return f"{app}:{prompt_version}:{model}:{digest}"

KEY = cache_key("support-agent", "us.openai.gpt-6-astra", "v7", INSTRUCTIONS)
prefix = {"role": "developer", "content": [{
    "type": "input_text", "text": INSTRUCTIONS,
    "prompt_cache_breakpoint": {"mode": "explicit"},
}]}
for label, question in [
    ("session A", "Explain the refund policy without calling tools."),
    ("session B", "Explain the escalation policy without calling tools."),
]:
    # A fresh conversation for each session; the startup prefix matches.
    session_history = [prefix, {"role": "user", "content": question}]
    result = ask_with_implicit_cache(session_history)
    d = result.usage.input_tokens_details
    print(label, "read", d.cached_tokens, "write", d.cache_write_tokens)

عند البدء البارد، تكتب الجلسة 1 البادئة المشتركة. ويمكن للجلسة 2 قراءتها حتى لو كانت مهمتها مختلفة. ويمكن أيضًا تخزين كل مهمة ضمنيًا. تحقق من عدادات الاستخدام: المفاتيح والعلامات المتطابقة تجعل إعادة الاستخدام ممكنة، ولكن لا يزال يتعين أن يكون إدخال ذاكرة التخزين المؤقت متاحًا.

ما الذي يوفره تخزين المطالبات المؤقت

التكلفة. بالنسبة إلى وكيل مدعوم بـ GPT-6 Astra له بادئة بدء تشغيل من 8,000 رمز وستة أدوار يضيف كل منها 2,000 رمز، خفضت التخزين المؤقت الثابت لمرة واحدة التكلفة إلى 0.50 دولار، وخفضت نقاط التوقف المتجددة تكلفة المدخلات النموذجية بنسبة 64 بالمئة: من 0.87 دولار إلى 0.32 دولار لكل جلسة.

الشكل 9: تكلفة المدخلات التراكمية لكل جلسة لمثال وكيل الدعم، باستخدام أسعار Amazon Bedrock حسب الطلب لـ GPT-6 Astra

كيف تعرف أن التخزين المؤقت يعمل

ابدأ باستخدام الاستجابة. cached_tokens تُبلغ عن المدخلات المقروءة من ذاكرة التخزين المؤقت، و cache_write_tokens تُبلغ عن المدخلات المكتوبة إليها. مع نمو المحادثة، تحقق من أن الأدوار اللاحقة تعيد استخدام السجل السابق وأن عمليات الكتابة الجديدة تعكس المحتوى الذي يُضاف.

للمراقبة في بيئة الإنتاج على نقطة نهاية Amazon Bedrock Runtime، استخدم مقياسي CacheReadInputTokenCount و CacheWriteInputTokenCount في Amazon CloudWatch. فعّل تسجيل استدعاء النموذج عندما تحتاج إلى سجلات الطلبات الفردية، ثم استعلم عنها باستخدام Amazon CloudWatch Logs Insights. بالنسبة إلى نقطة نهاية Amazon Bedrock Mantle، سجّل حقول استخدام الاستجابة في سجلات تطبيقك. فئة Amazon CloudWatch الخاصة بها لا تحتوي حاليًا على عدادات ذاكرة تخزين مؤقت منفصلة.

للتحقق من التكاليف، قم بتصفية AWS Cost Explorer على Amazon Bedrock والتجميع حسب Usage type. تظهر قراءات ذاكرة التخزين المؤقت وعمليات كتابتها والمدخلات غير المخزنة مؤقتًا كإدخالات منفصلة لكل نموذج. استبعد إدخالات رموز المخرجات عند حساب حصتها من تكلفة المدخلات.

قائمة تحقق موجزة

  • حافظ على استقرار البادئة القابلة لإعادة الاستخدام. ضع الأدوات والتعليمات المشتركة أولًا، ثم أضف سجل المحادثة والأدوار الجديدة. تغيير طابع زمني أو رسالة أو تعريف أداة يمنع إعادة الاستخدام بعد نقطة ذلك التغيير. ويمكن مع ذلك إعادة استخدام بادئة أقصر إذا كان لها نقطة نهاية محفوظة خاصة بها.
  • اختر حدودًا حول المحتوى الذي تريد إعادة استخدامه. استخدم التخزين المؤقت الضمني للسجل المتنامي، أو العلامات الصريحة للبادئات المشتركة، أو كليهما. وضع الصريح فقط يتجنب كتابة اللواحق أحادية الاستخدام. عند توسيع محادثة تعتمد على الوضع الصريح فقط، احتفظ بالعلامات السابقة حتى يتمكن الطلبات اللاحقة من العثور على البادئات المحفوظة.
  • احتفظ بكتالوج الأدوات الأولي دون تغيير. استخدم allowed_tools لتقييد الأدوات القابلة للاستدعاء. أضِف التعريفات المعروفة باستخدام additional_tools، أو اكتشفها من خلال tool_searchعلى جانب العميل ذات النطاقات المسماة. اختر ملف أدوات ثابتًا عندما تحتاج الأدوار الوكيلة المختلفة إلى كتالوجات مختلفة.
  • تحقق من حجم البادئة وعمرها. يجب أن تحتوي البادئة القابلة للتخزين المؤقت على 1,024 رمزًا على الأقل. تبقى البادئات المخزنة مؤقتًا مؤهلة لإعادة الاستخدام لمدة 30 دقيقة على الأقل بعد أحدث عملية كتابة أو إعادة استخدام ناجحة لها.
  • قم بتسخين المحتوى المشترك قبل تشغيل المساعدين. ضع علامة على البادئة المشتركة في كل من طلب التسخين المسبق وطلبات المساعد، بما في ذلك عند استخدام الوضع الضمني. أكمل طلب التسخين المسبق قبل بدء الطلبات المتوازية.
  • احتفظ بمفاتيح التخزين المؤقت مستقرة داخل كل مجموعة مشاركة. يجب أن تستخدم الطلبات المقصودة لإعادة استخدام بادئة نفس المفتاح. يمكن للمفاتيح المنفصلة أن تحافظ على حسابات التخزين المؤقت منفصلة بين العملاء أو المستخدمين.
  • قِس التوفير عبر سير العمل بالكامل. تكلفة عمليات الكتابة إلى ذاكرة التخزين المؤقت 1.25 ضعف معدل الإدخال العادي. تعتمد أسعار القراءة على النموذج. تتبع تكاليف الكتابة جنبًا إلى جنب مع وفورات القراءة، باستخدام usage في الاستجابة أثناء التطوير، وبيانات المراقبة والفوترة في الإنتاج.

الاستيقاظ في 3 فبراير

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

في هذه التدوينة، تناولنا كيفية تخزين الأدوات والتعليمات المشتركة مؤقتًا، وتنمية ذاكرة التخزين المؤقت عبر محادثات الوكيل، والحفاظ على إعادة الاستخدام عند إضافة أدوات أو تشغيل مساعدين أو بدء جلسات جديدة. حافظ على استقرار البادئة المشتركة وأضف المعلومات الجديدة مع تقدم سير العمل. استخدم التخزين المؤقت الضمني للمحادثات المتنامية والفواصل الصريحة للمحتوى المشترك. اجمع بينهما عندما تحتاج إلى الاثنين معًا، أو اختر الوضع الصريح فقط عندما يُستبعد إعادة استخدام لاحقة متغيرة. قارن بين قراءات وكتابات التخزين المؤقت وإجمالي تكلفة الإدخال وزمن الاستجابة لمعرفة ما يناسب وكيلك على أفضل وجه. لتطبيق هذه الأنماط، اتبع وثائق التخزين المؤقت للمطالبات في Amazon Bedrock لنماذج OpenAI وتحقق من توافر النماذج حسب منطقة AWS ونقطة النهاية. ابدأ بسير عمل واحد وقِس التوفير مع نمو محادثاتك.

 


نبذة عن المؤلف

المصدر الأصلي

AWS Machine Learning

ملاحظات المحتوى

النشر الأصلي والحقوق تعود إلى المصدر.

ترجمة آلية · يُرجى الرجوع إلى الأصل