ذاكرة التلخيص والاقتطاع المراعي لعدد Tokens
استخدموا ConversationSummaryMemory لتلخيص الأدوار الأقدم تلقائيًا، مع إبقاء المحادثة موجزة والحفاظ على الحقائق الرئيسية التي ذكرها المستخدم سابقًا.
ذاكرة التلخيص والاقتطاع المراعي لعدد Tokens درس مجاني في AI Engineering Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في AI Engineering Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة AI Engineering Academy 4 دروس في المجموع.
تكلفة الرموز للسجل الكامل
تحتفظ Conversation Buffer Memory بكل رسالة جرى تبادلها، مما يستهلك نافذة السياق بسرعة. وقد تستهلك محادثة من 100 جولة 20,000 رمز للسجل وحده، فلا تترك مساحة كافية للاستجابة الفعلية. وتحل ذاكرة الملخص هذه المشكلة باستبدال الجولات القديمة بملخص مضغوط.
آلية عمل ذاكرة الملخص
عندما يتجاوز إجمالي الرموز حدًا معينًا، تمرّر ConversationSummaryMemory أقدم جولات المحادثة إلى LLM وتطلب منه تلخيص النقاط الأساسية. ثم تُحذف الجولات الكاملة ويُستعاض عنها بهذا الملخص الموجز. وتتراكم الجولات المستقبلية فوق الملخص.
- الجولات القديمة: تُستبدل بملخص
- الجولات الحديثة: تُحتفظ بها حرفيًا
- النتيجة النهائية: ضغط مفيد مع أقل قدر من فقدان المعلومات
ConversationSummaryMemory في LangChain
توفر LangChain المكوّن ConversationSummaryMemory الذي يلخّص السجل تلقائيًا كلما كبر أكثر من اللازم. وتمرّر LLM إلى كائن الذاكرة كي يتمكن من استدعاء النموذج لإنشاء الملخصات عند الطلب.
from langchain.memory import ConversationSummaryMemory
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model='gpt-4o-mini')
memory = ConversationSummaryMemory(
llm=llm,
return_messages=True
)
# Add messages manually
memory.save_context(
{'input': 'My name is Alice and I am building a RAG system.'},
{'output': 'Great, I can help you build a RAG system, Alice.'}
)
print(memory.load_memory_variables({}))ذاكرة مخزن الملخص: أفضل ما في النهجين
ConversationSummaryBufferMemory نهج هجين: يحتفظ بأحدث الجولات حرفيًا لضمان الدقة، ويلخّص الجولات الأقدم التي تتجاوز max_token_limit فقط. ويوفر ذلك استرجاعًا دقيقًا للسياق الحديث، إلى جانب استرجاع مضغوط للسياق الأقدم.
from langchain.memory import ConversationSummaryBufferMemory
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model='gpt-4o-mini')
memory = ConversationSummaryBufferMemory(
llm=llm,
max_token_limit=500, # Summarize when older turns exceed 500 tokens
return_messages=True
)
# As the conversation grows, old turns get summarized automatically
print('Moving summary:', memory.moving_summary_buffer)حساب الرموز قبل الاقتطاع
لاتخاذ قرارات ذكية بشأن الاقتطاع، تحتاج إلى معرفة عدد الرموز التي تستهلكها رسائلك. تتيح لك مكتبة tiktoken حساب الرموز لأي نموذج من نماذج OpenAI. وبذلك يمكنك تنفيذ اقتطاع واعٍ بالرموز يبقى بصرامة ضمن ميزانية محددة.
import tiktoken
def count_tokens(messages: list, model: str = 'gpt-4o') -> int:
encoding = tiktoken.encoding_for_model(model)
total = 0
for msg in messages:
# Each message has overhead tokens for role framing
total += 4
total += len(encoding.encode(msg.get('content', '')))
total += 2 # Reply primer
return total
messages = [
{'role': 'user', 'content': 'Explain RAG to me.'},
{'role': 'assistant', 'content': 'RAG stands for Retrieval-Augmented Generation...'}
]
print('Token count:', count_tokens(messages))الاقتطاع اليدوي الواعي بالرموز
قد تحتاج أحيانًا إلى تحكم كامل في الاقتطاع دون استخدام فئات الذاكرة في LangChain. ومن الأساليب البسيطة الاحتفاظ بكل الرسائل، ثم إزالة أقدم الرسائل غير التابعة للنظام واحدة تلو الأخرى حتى يتوافق إجمالي عدد الرموز مع ميزانيتك.
def truncate_to_budget(messages: list, budget: int, model: str = 'gpt-4o') -> list:
'''Remove oldest non-system messages until under budget.'''
import tiktoken
encoding = tiktoken.encoding_for_model(model)
def token_count(msgs):
total = 2
for m in msgs:
total += 4 + len(encoding.encode(m.get('content', '')))
return total
result = list(messages)
while token_count(result) > budget and len(result) > 1:
# Never remove the system prompt at index 0
if result[0]['role'] == 'system':
del result[1]
else:
del result[0]
return resultإنشاء مطالبة الملخص
عند إنشاء ذاكرة الملخص الخاصة بك، تصوغ مطالبة تطلب من LLM استخلاص الحقائق الأساسية. وينبغي أن توجّه المطالبة النموذج إلى تسجيل تفضيلات المستخدم، والكيانات المسماة، والأسئلة غير المحسومة، أي الحقائق التي يُرجح أن تهم في الجولات المستقبلية.
from openai import OpenAI
client = OpenAI()
def summarize_history(old_summary: str, new_turns: list) -> str:
turns_text = '\n'.join(
f'{m["role"].capitalize()}: {m["content"]}' for m in new_turns
)
prompt = f'''Current summary:\n{old_summary}\n\nNew conversation turns:\n{turns_text}\n\nWrite an updated summary that captures key facts, user preferences, and open questions.'''
resp = client.chat.completions.create(
model='gpt-4o-mini',
messages=[{'role': 'user', 'content': prompt}]
)
return resp.choices[0].message.contentدمج الملخص في مطالبة النظام
بعد إنشاء ملخص، أدرجه في مطالبة النظام كي يتوفر لدى LLM دائمًا سياق عن سجل المحادثة. أضف الملخص في البداية باعتباره كتلة سياق موجزة قبل تعليمات الشخصية الأساسية.
def build_messages_with_summary(summary: str, recent_turns: list, user_input: str) -> list:
system_content = (
'You are a helpful AI assistant.'
+ ('\n\n[Conversation summary]\n' + summary if summary else '')
)
messages = [{'role': 'system', 'content': system_content}]
messages.extend(recent_turns)
messages.append({'role': 'user', 'content': user_input})
return messagesتشغيل التلخيص تلقائيًا
من الأنماط الشائعة تشغيل التلخيص عندما تتجاوز المحادثة حدًا معينًا من الرموز، مثلًا عندما يتجاوز السجل المتراكم 2,000 رمز. عندها تلخّص كل الجولات باستثناء آخر جولتين، وتستبدلهما بالملخص.
class SummaryBufferChat:
def __init__(self, max_tokens=2000):
self.summary = ''
self.recent_turns = []
self.max_tokens = max_tokens
def chat(self, user_message: str) -> str:
from openai import OpenAI
client = OpenAI()
messages = build_messages_with_summary(self.summary, self.recent_turns, user_message)
resp = client.chat.completions.create(model='gpt-4o', messages=messages)
reply = resp.choices[0].message.content
self.recent_turns.append({'role': 'user', 'content': user_message})
self.recent_turns.append({'role': 'assistant', 'content': reply})
if count_tokens(self.recent_turns) > self.max_tokens:
to_summarize = self.recent_turns[:-2]
self.recent_turns = self.recent_turns[-2:]
self.summary = summarize_history(self.summary, to_summarize)
return replyالحفاظ على الكيانات المسماة في الملخصات
تعتمد جودة الملخص بدرجة كبيرة على مطالبة التلخيص. فإذا ذكر المستخدمون أسماءهم أو مواقعهم أو تفضيلاتهم أو مواعيدهم النهائية، فيجب أن توجّه مطالبتك النموذج صراحةً إلى تضمين هذه الحقائق. وغالبًا ما تُسقط الملخصات العامة أسماء العلم التي تهم التخصيص أكثر من غيرها.
- يجب تضمين: الأسماء والتواريخ والخيارات التقنية المتخذة والأسئلة المفتوحة
- يجب استبعاد: التبادلات الحشوّية والتأكيدات وعبارات المجاملة المتكررة
المفاضلة: ذاكرة الملخص مقابل ذاكرة النافذة
يعتمد الاختيار بين ذاكرة الملخص وذاكرة النافذة على حالة الاستخدام. تحافظ ذاكرة النافذة على الصياغة الدقيقة، وهو أمر مهم للاسترجاع الدقيق، لكنها تهدر الرموز على سياق غير ذي صلة. أما ذاكرة الملخص فتضغط المعلومات بقوة، لكنها تضيف استدعاءً آخر لـ LLM وقد تفقد تفاصيل الحالات الخاصة. وتستخدم معظم روبوتات المحادثة في بيئة الإنتاج نهجًا هجينًا: جولات حديثة دقيقة إلى جانب ملخص متجدد للجولات الأقدم.
تحقق سريع
اختبر مدى فهمك لمفاهيم ذاكرة الملخص والاقتطاع الواعي بالرموز.
مراجعة الدرس
في هذا الدرس تعلّمت أن: ذاكرة الملخص تضغط الجولات القديمة عبر استدعاء لـ LLM، وأن ConversationSummaryBufferMemory تدمج الجولات الحديثة الدقيقة مع الجولات الأقدم الملخصة، وأن tiktoken تتيح الاقتطاع الواعي بالرموز لإبقاء المحادثات ضمن الميزانية. بعد ذلك سنستكشف حفظ سجل المحادثة في Redis وPostgreSQL لتخزين دائم وقابل للتوسع.
الأسئلة الشائعة
هل درس «ذاكرة التلخيص والاقتطاع المراعي لعدد Tokens» مجاني؟
نعم — نص درس «ذاكرة التلخيص والاقتطاع المراعي لعدد Tokens» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة AI Engineering Academy، انتقل إلى CoddyKit PRO. تتضمن دورة AI Engineering Academy 4 دروس في المجموع.
ماذا ستتعلم في «ذاكرة التلخيص والاقتطاع المراعي لعدد Tokens»؟
استخدموا ConversationSummaryMemory لتلخيص الأدوار الأقدم تلقائيًا، مع إبقاء المحادثة موجزة والحفاظ على الحقائق الرئيسية التي ذكرها المستخدم سابقًا. تتمرن على AI Engineering Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ AI Engineering Academy؟
لا تُشترط خبرة سابقة. AI Engineering Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.
كم من الوقت يستغرق درس «ذاكرة التلخيص والاقتطاع المراعي لعدد Tokens»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس AI Engineering Academy هذا؟
نعم. كل درس في AI Engineering Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- لماذا تحتاج LLMs عديمة الحالة إلى ذاكرة خارجية
- ذاكرة المخزن وذاكرة النافذة
- ذاكرة التلخيص والاقتطاع المراعي لعدد Tokens
- حفظ سجل المحادثة في Redis وPostgreSQL