الضغط

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

Important

إطار عمل الضغط تجريبي حاليا. لاستخدامه، ستحتاج إلى إضافة #pragma warning disable MAAI001.

Important

إطار عمل الضغط تجريبي حاليا في Python. استيراد أنواع الضغط من agent_framework.

يدعم Go الضغط من خلال الحزمة agent/compaction . تسجيل استراتيجية ضغط ك حتى تتمكن من agent.ContextProvider ضغط محفوظات الجلسة قبل كل تشغيل.

لماذا الضغط مهم

تتضمن كل مكالمة إلى LLM محفوظات المحادثات الكاملة. بدون ضغط:

  • حدود الرمز المميز — تتجاوز المحادثات في النهاية نافذة سياق النموذج، مما يتسبب في حدوث أخطاء.
  • التكلفة - تستهلك المطالبات الأكبر المزيد من الرموز المميزة، مما يزيد من تكاليف واجهة برمجة التطبيقات.
  • زمن الانتقال — يعني المزيد من رموز الإدخال المميزة أوقات استجابة أبطأ.

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

المفاهيم الأساسية

القابلية للتطبيق: عوامل المحفوظات في الذاكرة فقط

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

  • Foundry Agents — تتم إدارة السياق من جانب الخادم بواسطة خدمة Microsoft Foundry.
  • واجهة برمجة تطبيقات الاستجابات مع تمكين المتجر (الافتراضي) — يتم تخزين حالة المحادثة وإدارتها بواسطة خدمة OpenAI.
  • Copilot Studio الوكلاء — يتم الاحتفاظ بسياق المحادثة بواسطة خدمة Copilot Studio.

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

يعمل الضغط على MessageIndex — طريقة عرض منظمة لقائمة الرسائل المسطحة التي تجمع الرسائل في وحدات ذرية تسمى MessageGroup المثيلات. تتعقب كل مجموعة عدد الرسائل وعدد البايت وعدد الرموز المميزة المقدرة.

مجموعات الرسائل

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

تحتوي كل مجموعة على MessageGroupKind:

لطيف Description
System رسالة نظام واحدة أو أكثر. يتم الاحتفاظ بها دائما أثناء الضغط.
User رسالة مستخدم واحدة تبدأ منعطفا جديدا.
AssistantText استجابة نص مساعد عادي (لا توجد استدعاءات أداة).
ToolCall رسالة مساعدة مع استدعاءات الأداة ورسائل نتائج الأداة المقابلة، تعامل كوحدة ذرية.
Summary رسالة مكثفة ينتجها ضغط التلخيص.

اًلمشغلات

A CompactionTrigger هو مفوض يقيم ما إذا كان يجب أن يستمر الضغط استنادا إلى المقاييس الحالية MessageIndex :

public delegate bool CompactionTrigger(MessageIndex index);

CompactionTriggers توفر الفئة أساليب مصنع شائعة:

المشغِّل الحرائق عندما
CompactionTriggers.Always في كل مرة (دون قيد أو شرط).
CompactionTriggers.Never أبدا (يعطل الضغط).
CompactionTriggers.TokensExceed(maxTokens) يتجاوز عدد الرموز المميزة المضمنة الحد.
CompactionTriggers.MessagesExceed(maxMessages) يتجاوز عدد الرسائل المضمنة الحد.
CompactionTriggers.TurnsExceed(maxTurns) يتجاوز عدد عمليات تحويل المستخدم المضمن الحد.
CompactionTriggers.GroupsExceed(maxGroups) يتجاوز عدد المجموعات المضمنة الحد.
CompactionTriggers.HasToolCalls() توجد مجموعة استدعاء أداة واحدة على الأقل غير مستبعدة.

دمج المشغلات مع CompactionTriggers.All(...) (LOGICAL AND) أو CompactionTriggers.Any(...) (logical OR):

// Compact only when there are tool calls AND tokens exceed 2000
CompactionTrigger trigger = CompactionTriggers.All(
    CompactionTriggers.HasToolCalls(),
    CompactionTriggers.TokensExceed(2000));

المشغل مقابل الهدف

كل استراتيجية لها دالتان أساسيتان:

  • المشغل — يتحكم عند بدء الضغط. إذا قام المشغل بإرجاع false، يتم تخطي الاستراتيجية بالكامل.
  • الهدف — يتحكم عند توقف الضغط. تستبعد الاستراتيجيات المجموعات بشكل متزايد وتعيد تقييم الهدف بعد كل خطوة، وتتوقف بمجرد إرجاع trueالهدف .

عندما لا يتم تحديد هدف، يتم تعيينه افتراضيا إلى عكس المشغل - يتوقف الضغط بمجرد أن يتوقف تشغيل شرط المشغل.

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

مجموعات الرسائل

يتم تجميع الرسائل في وحدات ذرية. يتم تعيين كل مجموعة إلى GroupKind:

لطيف Description
system رسائل النظام. يتم الاحتفاظ بها دائما أثناء الضغط.
user رسالة مستخدم واحدة.
assistant_text استجابة نص مساعد عادي (لا توجد استدعاءات دالة).
tool_call رسالة مساعد مع استدعاءات دالة بالإضافة إلى رسائل نتائج الأداة المقابلة، تعامل كوحدة ذرية.

استراتيجيات الضغط

CompactionStrategy هو بروتوكول — أي async قابل للاستدعاء يقبل list[Message] ويتحول في مكانه، ويعود True عندما يغير أي شيء:

class CompactionStrategy(Protocol):
    async def __call__(self, messages: list[Message]) -> bool: ...

الرمز المميز

تقبل الاستراتيجيات المدركة للرمز المميز تنفيذا TokenizerProtocol . يستخدم المضمن CharacterEstimatorTokenizer 4 أحرف لكل رمز تقديمي:

from agent_framework import CharacterEstimatorTokenizer

tokenizer = CharacterEstimatorTokenizer()

قم بتمرير رمز مميز مخصص عندما تحتاج إلى عدد دقيق من الرموز المميزة لترميز نموذج معين.

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

تتضمن حزمة Go أنواع استراتيجية مثل ToolResultStrategyو SlidingWindowStrategyو PipelineStrategyبالإضافة إلى مساعدي المشغل مثل MessagesExceed و TurnsExceed.

استراتيجيات الضغط

ترث جميع الاستراتيجيات من الفئة الأساسية المجردة CompactionStrategy . تحافظ كل استراتيجية على رسائل النظام وتحترم MinimumPreserved الكلمة التي تحمي المجموعات غير النظامية الأحدث من الإزالة.

يتم استيراد استراتيجيات الضغط من agent_framework.

يتم استيراد استراتيجيات الضغط من github.com/microsoft/agent-framework-go/agent/compaction.

TruncationCompactionStrategy

TruncationStrategy

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

  • يحترم حدود المجموعة الذرية (تتم إزالة رسائل استدعاء الأدوات والنتيجة معا).
  • الأفضل لخلفيات ميزانية الرمز المميز الثابت.
  • MinimumPreserved يقيم افتراضيا إلى 32.
// Drop oldest groups when tokens exceed 32K, keeping at least 10 recent groups
TruncationCompactionStrategy truncation = new(
    trigger: CompactionTriggers.TokensExceed(0x8000),
    minimumPreserved: 10);
  • tokenizer عند توفير، يكون المقياس هو عدد الرموز المميزة؛ وإلا يتم تضمينه في عدد الرسائل.
  • preserve_system يقيم افتراضيا إلى True.
from agent_framework import CharacterEstimatorTokenizer, TruncationStrategy

# Exclude oldest groups when tokens exceed 32 000, trimming to 16 000
truncation = TruncationStrategy(
    max_n=32_000,
    compact_to=16_000,
    tokenizer=CharacterEstimatorTokenizer(),
)

تمريرWindowCompactionStrategy

تمريرWindowStrategy

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

  • الأفضل لطول المحادثة المحيط بشكل متوقع.

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

  • يبدأ الدور برسالة مستخدم ويتضمن جميع مجموعات المكالمات المساعدة والأدوات اللاحقة حتى رسالة المستخدم التالية.
  • MinimumPreserved الإعدادات الافتراضية إلى 1 (تحافظ على أحدث مجموعة غير نظام على الأقل).
// Keep only the last 4 user turns
SlidingWindowCompactionStrategy slidingWindow = new(
    trigger: CompactionTriggers.TurnsExceed(4));

يحتفظ فقط بأحدث keep_last_groups المجموعات غير النظامية، باستثناء كل شيء أقدم.

  • preserve_system يقيم افتراضيا إلى True.
from agent_framework import SlidingWindowStrategy

# Keep only the last 20 non-system groups
sliding_window = SlidingWindowStrategy(keep_last_groups=20)

ToolResultCompactionStrategy

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

  • لا تلمس رسائل المستخدم أو استجابات المساعد العادي.
  • الأفضل كاستراتيجية تمرير أولى لاستعادة المساحة من نتائج الأداة المطولة.
  • يستبدل مجموعات استدعاء الأدوات متعددة الرسائل (مساعد مكالمة + نتائج الأداة) بملخص قصير مثل [Tool calls: get_weather, search_docs].
  • MinimumPreserved افتراضيات إلى 2، مما يضمن بقاء تفاعلات أداة الدور الحالي مرئية.
// Collapse old tool results when tokens exceed 512
ToolResultCompactionStrategy toolCompaction = new(
    trigger: CompactionTriggers.TokensExceed(0x200));
  • ينهار إلى رسائل ملخص مضغوطة مثل [Tool results: get_weather: sunny, 18°C].
  • يتم ترك أحدث keep_last_tool_call_groups مجموعات استدعاء الأدوات دون تغيير.
from agent_framework import ToolResultCompactionStrategy

# Collapse all but the newest tool-call group
tool_result = ToolResultCompactionStrategy(keep_last_tool_call_groups=1)

SummarizationCompactionStrategy

SummarizationStrategy

يستخدم LLM لتلخيص الأجزاء القديمة من المحادثة، واستبدالها برسالة ملخص واحدة.

  • تحتفظ المطالبة الافتراضية بالحقائق الرئيسية والقرارات وتفضيلات المستخدم ونتائج استدعاء الأدوات.
  • يتطلب عميل LLM منفصلا للتلخيص — يوصى بنموذج أصغر وأسرع.
  • الأفضل للحفاظ على سياق المحادثة مع تقليل عدد الرموز المميزة بشكل كبير.
  • يمكنك توفير مطالبة تلخيص مخصصة.
  • يحمي رسائل النظام وأحدث MinimumPreserved المجموعات غير التابعة للنظام (الافتراضي: 4).
  • إرسال الرسائل القديمة إلى منفصل IChatClient مع مطالبة تلخيص، ثم إدراج الملخص كمجموعة MessageGroupKind.Summary .
// Summarize older messages when tokens exceed 1280, keeping the last 4 groups
SummarizationCompactionStrategy summarization = new(
    chatClient: summarizerChatClient,
    trigger: CompactionTriggers.TokensExceed(0x500),
    minimumPreserved: 4);

يمكنك توفير مطالبة تلخيص مخصصة:

SummarizationCompactionStrategy summarization = new(
    chatClient: summarizerChatClient,
    trigger: CompactionTriggers.TokensExceed(0x500),
    summarizationPrompt: "Summarize the key decisions and user preferences only.");
  • تتجاوز المشغلات عند تضمين عدد الرسائل غير التابعة target_count + thresholdللنظام .
  • يحتفظ بالرسائل الأخيرة بالقرب من target_count، وتخضع لحدود مجموعة الرسائل؛ ويلخص أقدم المجموعات الكاملة التي تناسب ميزانية إدخال الملخص.
  • يتطلب عميلا SupportsChatGetResponse .
  • ربط موجه التلخيص والنسخة إلى 8000 رمز مميز مقدر بشكل افتراضي. يحدد مجموعات الرسائل الكاملة، لذلك لا يتم تقسيم المجموعة أبدا لتناسب الميزانية.
  • قم بتعيين max_summary_input_tokens=None لتعطيل حد إدخال الملخص، أو مرر tokenizer= عندما تحتاج إلى عد الرمز المميز الخاص بالنموذج. إذا لم يتم احتواء مجموعة كاملة، يتم تخطي التلخيص وتبقى المحفوظات الموجودة دون تغيير.
from agent_framework import SummarizationStrategy

# Summarize when non-system message count exceeds 6, retaining the 4 newest
summarization = SummarizationStrategy(
    client=summarizer_client,
    target_count=4,
    threshold=2,
)

قم بتوفير مطالبة تلخيص مخصصة:

summarization = SummarizationStrategy(
    client=summarizer_client,
    target_count=4,
    prompt="Summarize the key decisions and user preferences only.",
)

التحكم في موازنة طلب الملخص بشكل مستقل عن هدف المحفوظات المحتفظ بها:

from agent_framework import CharacterEstimatorTokenizer, SummarizationStrategy

summarization = SummarizationStrategy(
    client=summarizer_client,
    target_count=4,
    threshold=2,
    max_summary_input_tokens=16_000,
    tokenizer=CharacterEstimatorTokenizer(),
)

PipelineCompactionStrategy

إنشاء استراتيجيات متعددة في مسار تسلسلي. تعمل كل استراتيجية على نتيجة السابقة، ما يتيح الضغط متعدد الطبقات من لطيف إلى عدواني.

  • المشغل الخاص بالبنية الأساسية لبرنامج ربط العمليات التجارية هو CompactionTriggers.Always — تقوم كل استراتيجية تابعة بتقييم مشغلها الخاص بشكل مستقل.
  • يتم تنفيذ الاستراتيجيات بالترتيب، لذا ضع الاستراتيجيات اللطيفة أولا.
PipelineCompactionStrategy pipeline = new(
    new ToolResultCompactionStrategy(CompactionTriggers.TokensExceed(0x200)),
    new SummarizationCompactionStrategy(summarizerChatClient, CompactionTriggers.TokensExceed(0x500)),
    new SlidingWindowCompactionStrategy(CompactionTriggers.TurnsExceed(4)),
    new TruncationCompactionStrategy(CompactionTriggers.TokensExceed(0x8000)));

هذا المسار:

  1. طي نتائج الأدوات القديمة (لطيف).
  2. تلخيص امتدادات المحادثات القديمة (متوسطة).
  3. يحتفظ فقط بآخر 4 مستخدم يتحول (عدواني).
  4. يسقط أقدم المجموعات إذا كانت لا تزال تتجاوز الميزانية (في حالات الطوارئ).

SelectiveToolCallCompactionStrategy

يستبعد تماما مجموعات استدعاء الأدوات القديمة، مع الاحتفاظ بآخر keep_last_tool_call_groupsفقط .

  • لا تلمس رسائل المستخدم أو المساعد العادي.
  • الأفضل عندما يهيمن أداة الدردشة على استخدام الرمز المميز ولا يلزم محفوظات الأدوات الكاملة.
from agent_framework import SelectiveToolCallCompactionStrategy

# Keep only the most recent tool-call group
selective_tool = SelectiveToolCallCompactionStrategy(keep_last_tool_call_groups=1)

TokenBudgetComposedStrategy

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

  • تنفيذ الاستراتيجيات بالترتيب؛ ضع الاستراتيجيات اللطيفة أولا.
  • early_stop=True يتوقف (الافتراضي) بمجرد استيفاء موازنة الرمز المميز.
from agent_framework import (
    CharacterEstimatorTokenizer,
    SelectiveToolCallCompactionStrategy,
    SlidingWindowStrategy,
    SummarizationStrategy,
    TokenBudgetComposedStrategy,
    ToolResultCompactionStrategy,
)

tokenizer = CharacterEstimatorTokenizer()

pipeline = TokenBudgetComposedStrategy(
    token_budget=16_000,
    tokenizer=tokenizer,
    strategies=[
        ToolResultCompactionStrategy(keep_last_tool_call_groups=1),
        SummarizationStrategy(client=summarizer_client, target_count=4, threshold=2),
        SlidingWindowStrategy(keep_last_groups=20),
    ],
)

هذا المسار:

  1. طي نتائج الأدوات القديمة (لطيف).
  2. تلخيص امتدادات المحادثات القديمة (متوسطة).
  3. يحافظ فقط على آخر 20 مجموعة (عدوانية).
  4. الرجوع إلى أقدم استثناء أولا إذا كان لا يزال فوق الميزانية (في حالات الطوارئ).

استخدام الضغط مع عامل

التفاف استراتيجية الضغط في CompactionProvider وتسجيلها ك AIContextProvider. تمرير إما استراتيجية واحدة أو PipelineCompactionStrategy إلى الدالة الإنشائية.

التسجيل مع واجهة برمجة تطبيقات المنشئ

تسجيل الموفر على ChatClientBuilder باستخدام UseAIContextProviders. يعمل الموفر داخل حلقة استدعاء الأدوات، وضغط الرسائل قبل كل مكالمة LLM.

IChatClient agentChatClient = openAIClient.GetChatClient(deploymentName).AsIChatClient();
IChatClient summarizerChatClient = openAIClient.GetChatClient(deploymentName).AsIChatClient();

PipelineCompactionStrategy compactionPipeline =
    new(
        new ToolResultCompactionStrategy(CompactionTriggers.TokensExceed(0x200)),
        new SummarizationCompactionStrategy(summarizerChatClient, CompactionTriggers.TokensExceed(0x500)),
        new SlidingWindowCompactionStrategy(CompactionTriggers.TurnsExceed(4)),
        new TruncationCompactionStrategy(CompactionTriggers.TokensExceed(0x8000)));

AIAgent agent =
    agentChatClient
        .AsBuilder()
        .UseAIContextProviders(new CompactionProvider(compactionPipeline))
        .BuildAIAgent(
            new ChatClientAgentOptions
            {
                Name = "ShoppingAssistant",
                ChatOptions = new()
                {
                    Instructions = "You are a helpful shopping assistant.",
                    Tools = [AIFunctionFactory.Create(LookupPrice)],
                },
            });

AgentSession session = await agent.CreateSessionAsync();
Console.WriteLine(await agent.RunAsync("What's the price of a laptop?", session));

Tip

استخدم نموذجا أصغر وأرخص (مثل gpt-4o-mini) لعميل دردشة التلخيص لتقليل التكاليف مع الحفاظ على جودة الملخص.

إذا كانت هناك حاجة إلى استراتيجية واحدة فقط، فمررها مباشرة إلى CompactionProvider دون تضمينها في PipelineCompactionStrategy:

agentChatClient
    .AsBuilder()
    .UseAIContextProviders(new CompactionProvider(
        new SlidingWindowCompactionStrategy(CompactionTriggers.TurnsExceed(20))))
    .BuildAIAgent(...);

التسجيل من خلال ChatClientAgentOptions

يمكن أيضا تحديد الموفر مباشرة في ChatClientAgentOptions.AIContextProviders:

AIAgent agent = agentChatClient
    .AsBuilder()
    .BuildAIAgent(new ChatClientAgentOptions
    {
        AIContextProviders = [new CompactionProvider(compactionPipeline)]
    });

Note

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

الضغط المخصص

CompactionProvider.CompactAsync يطبق استراتيجية على قائمة رسائل عشوائية دون جلسة عمل عامل نشط:

IEnumerable<ChatMessage> compacted = await CompactionProvider.CompactAsync(
    new TruncationCompactionStrategy(CompactionTriggers.TokensExceed(8000)),
    existingMessages);

قم بتكوين استراتيجية الضغط المحددة و tokenizer مباشرة على Agent. تتجاوز القيم على مستوى العامل الإعدادات الافتراضية التي تم تكوينها على عميل الدردشة الأساسي، ويمكن لمكالمة واحدة agent.run(...) تجاوز كليهما مرة أخرى.

التسجيل مع وكيل

from agent_framework import (
    Agent,
    CharacterEstimatorTokenizer,
    SlidingWindowStrategy,
    SummarizationStrategy,
    TokenBudgetComposedStrategy,
    ToolResultCompactionStrategy,
    TruncationStrategy,
)

tokenizer = CharacterEstimatorTokenizer()

strategy = TokenBudgetComposedStrategy(
    token_budget=16_000,
    tokenizer=tokenizer,
    strategies=[
        ToolResultCompactionStrategy(keep_last_tool_call_groups=1),
        SummarizationStrategy(client=summarizer_client, target_count=4, threshold=2),
        SlidingWindowStrategy(keep_last_groups=20),
    ],
)

agent = Agent(
    client=client,
    name="ShoppingAssistant",
    instructions="You are a helpful shopping assistant.",
    compaction_strategy=strategy,
    tokenizer=tokenizer,
)

session = agent.create_session()
print(await agent.run("What's the price of a laptop?", session=session))

Tip

استخدم نموذجا أصغر وأرخص (مثل gpt-4o-mini) لعميل التلخيص لتقليل التكاليف مع الحفاظ على جودة الملخص.

إذا كانت هناك حاجة إلى استراتيجية واحدة فقط، فمررها مباشرة:

agent = Agent(
    client=client,
    compaction_strategy=SlidingWindowStrategy(keep_last_groups=20),
    tokenizer=CharacterEstimatorTokenizer(),
)

تجاوز الضغط لتشغيل واحد

تمرير compaction_strategy وإلى tokenizeragent.run(...) عندما يحتاج طلب واحد إلى نهج مختلف:

response = await agent.run(
    "Summarize the rollout risks.",
    compaction_strategy=TruncationStrategy(max_n=8_000, compact_to=4_000),
    tokenizer=tokenizer,
)

الضغط المخصص

apply_compaction يطبق استراتيجية على قائمة رسائل عشوائية خارج جلسة عمل عامل نشط:

from agent_framework import apply_compaction, TruncationStrategy, CharacterEstimatorTokenizer

tokenizer = CharacterEstimatorTokenizer()

compacted = await apply_compaction(
    messages,
    strategy=TruncationStrategy(
        max_n=8_000,
        compact_to=4_000,
        tokenizer=tokenizer,
    ),
    tokenizer=tokenizer,
)

إنشاء موفر سياق ضغط وإضافته إلى موفري سياق العامل:

import (
    "github.com/microsoft/agent-framework-go/agent"
    "github.com/microsoft/agent-framework-go/agent/compaction"
    "github.com/microsoft/agent-framework-go/provider/foundryprovider"
)

compactionProvider := compaction.NewContextProvider(compaction.ContextProviderConfig{
    Strategy: &compaction.PipelineStrategy{
        Strategies: []compaction.Strategy{
            &compaction.ToolResultStrategy{
                Trigger:                compaction.MessagesExceed(7),
                MinimumPreservedGroups: 4,
            },
            &compaction.SlidingWindowStrategy{
                Trigger:               compaction.TurnsExceed(4),
                MinimumPreservedTurns: 4,
            },
        },
    },
})

a := foundryprovider.NewAgent(endpoint, token, foundryprovider.ModelDeployment(model), foundryprovider.AgentConfig{
    Config: agent.Config{
        ContextProviders: []agent.ContextProvider{compactionProvider},
    },
})

Tip

راجع نموذج مسار الضغط للحصول على مثال كامل قابل للتشغيل.

استخدام الضغط مع Harness Agent

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

يكون الضغط متوقفا عن التشغيل بشكل افتراضي. قم بتعيين كل من HarnessAgentOptions.MaxContextWindowTokens و لإنشاء افتراضي ContextWindowCompactionStrategy، أو تعيين CompactionStrategy لتوفير الاستراتيجية MaxOutputTokens الخاصة بك.

HarnessAgent agent = chatClient.AsHarnessAgent(new HarnessAgentOptions
{
    MaxContextWindowTokens = 128_000,
    MaxOutputTokens = 16_384,
});

يعمل التسخير على تشغيل الاستراتيجية التي تم حلها قبل كل استدعاء نموذج في حلقة استدعاء الوظيفة. عندما يقوم أيضا بإنشاء الافتراضي InMemoryChatHistoryProvider، فإنه يقوم بتكوين هذا الموفر مع مخفض الدردشة الخاص بالاستراتيجية. يتم استخدام مخصص ChatHistoryProvider كما هو متوفر. DisableCompaction = true يتجاوز إعدادات الرمز المميز و CompactionStrategy؛ MaxOutputTokens لا يزال يتم تعيينه ChatOptions.MaxOutputTokens عند تمكين الضغط أو تعطيله.

chatClient.AsHarnessAgent(options) واستخدم new HarnessAgent(chatClient, options) نفس HarnessAgentOptions.

يكون الضغط متوقفا عن التشغيل بشكل افتراضي ما لم يتم تعيين كل من max_context_window_tokens و max_output_tokens ، أو توفير استراتيجية مرحلة مخصصة.

agent = create_harness_agent(
    client,
    max_context_window_tokens=128_000,
    max_output_tokens=16_384,
)

مع إعدادات الرمز المميز، يعيد التسخير استخدام واحد ContextWindowCompactionStrategy لكلا المرحلتين: يتم تشغيل المرحلة السابقة قبل كل استدعاء نموذج داخل حلقة الأدوات، بينما استمرت ضغطات المرحلة بعد المحفوظات بعد التشغيل. تجاوز إما مرحلة بشكل مستقل مع before_compaction_strategy أو after_compaction_strategy؛ تعيين tokenizer= لرمز مميز مخصص، history_provider= لمخزن محفوظات آخر، أو disable_compaction=True لتعطيل المرحلتين. max_output_tokens يوفر أيضا خيار الدردشة الافتراضي max_tokens .

Harness Agent غير متوفر حاليا في Go SDK. تسجيل موفر سياق ضغط يدويا كما هو موضح أعلاه.

اختيار استراتيجية

الاستراتيجية العدوانية يحافظ على السياق يتطلب LLM الأفضل ل
ToolResultCompactionStrategy منخفض عالي — يطوي نتائج الأداة فقط No استعادة المساحة من إخراج الأداة المطولة
SummarizationCompactionStrategy Medium متوسط — يستبدل المحفوظات بملخص Yes محادثات طويلة حيث يكون السياق مهما
SlidingWindowCompactionStrategy مستوى مرتفع منخفض — يسقط المنعطفات بأكملها No حدود عدد الأدوار الصعبة
TruncationCompactionStrategy مستوى مرتفع منخفض — يسقط أقدم المجموعات No ميزانيات الرمز المميز للطوارئ
PipelineCompactionStrategy Configurable يعتمد على استراتيجيات الطفل يعتمد ضغط الطبقات مع احتياطيات متعددة
الاستراتيجية العدوانية يحافظ على السياق يتطلب LLM الأفضل ل
ToolResultCompactionStrategy منخفض عالي — يطوي نتائج الأدوات إلى رسائل ملخصة No استعادة المساحة من إخراج الأداة المطولة
SelectiveToolCallCompactionStrategy منخفض–متوسط متوسط — يستبعد مجموعات المكالمات القديمة بالكامل No إزالة محفوظات الأدوات عندما لا تكون هناك حاجة إلى النتائج
SummarizationStrategy Medium متوسط — يستبدل المحفوظات بملخص Yes محادثات طويلة حيث يكون السياق مهما
SlidingWindowStrategy مستوى مرتفع منخفض — يسقط أقدم المجموعات No حدود عدد المجموعات الصعبة
TruncationStrategy مستوى مرتفع منخفض — يسقط أقدم المجموعات No الرسائل الطارئة - أو الرسائل الاحتياطية لموازنة الرمز المميز
TokenBudgetComposedStrategy Configurable يعتمد على استراتيجيات الطفل يعتمد الضغط متعدد الطبقات مع هدف موازنة الرمز المميز والارجاعات المتعددة
الاستراتيجية العدوانية يحافظ على السياق يتطلب LLM الأفضل ل
ToolResultStrategy منخفض عالي - يطوي نتائج الأداة المطولة No استعادة المساحة من إخراج الأداة المطولة
SlidingWindowStrategy مستوى مرتفع منخفض - يحافظ على أحدث المنعطفات No حدود عدد الأدوار الصعبة
PipelineStrategy Configurable يعتمد على استراتيجيات الطفل يعتمد ضغط الطبقات مع احتياطيات متعددة

الخطوات التالية