الدرس 7 من 10

الذاكرة والسياق

الموديل بينسى كل حاجة بين كل request والتاني. انت المسؤول عن ذاكرته.

نوعين ذاكرة

قصيرة المدىالـ messages في المحادثة الحالية. بتضيع لما المحادثة تخلص، ومحدودة بالـ context window.
طويلة المدىمعلومات بتتحفظ برا (ملف، قاعدة بيانات) وترجعلها في محادثات جاية: تفضيلات العميل، ومشاكله القديمة.

المشكلة: الـ context بيتملي

كل خطوة في الـ agent بتضيف رسايل: طلبات أدوات، ونتايج (ممكن تبقى طويلة). بعد ٣٠ خطوة ممكن توصل لحد الـ context window، والتكلفة بتزيد مع كل طلب لأنك بتبعت كل حاجة كل مرة. الحلول: تقص الرسايل القديمة، أو تلخصها، أو تقصر نتايج الأدوات من الأول.

trim_context.py
def approx_tokens(text: str) -> int:
    return len(text) // 4 + 1            # rough rule: ~4 characters per token

def trim_history(messages: list[dict], budget: int = 300) -> list[dict]:
    """Keep the first message (the task) + as many recent messages as fit the budget."""
    first, rest = messages[0], messages[1:]
    kept, used = [], approx_tokens(str(first["content"]))
    for msg in reversed(rest):                         # newest first
        cost = approx_tokens(str(msg["content"]))
        if used + cost > budget:
            break
        kept.insert(0, msg)
        used += cost
    dropped = len(rest) - len(kept)
    note = {"role": "user", "content": f"[{dropped} earlier messages were removed to save space]"}
    return [first, note] + kept if dropped else [first] + kept

history = [{"role": "user", "content": "Help me track my 3 orders and fix the address."}]
for i in range(12):
    history.append({"role": "assistant", "content": f"Checking step {i}... " + "details " * 20})
    history.append({"role": "user", "content": f"result of step {i}"})

trimmed = trim_history(history)
print("before:", len(history), "messages,", sum(approx_tokens(str(m['content'])) for m in history), "tokens")
print("after: ", len(trimmed), "messages,", sum(approx_tokens(str(m['content'])) for m in trimmed), "tokens")
print(trimmed[1]["content"])
⚠ متقسمش زوج tool_use و tool_resultفي الـ agent الحقيقي، لو قصيت رسالة فيها tool_use وسبت الـ tool_result بتاعها (أو العكس)، الـ API هيرفض الطلب. قص عند حدود كاملة، أو لخّص الجزء القديم في رسالة نصية واحدة.

ذاكرة طويلة المدى كأداة

أبسط وأقوى طريقة: ادّي الـ agent أداتين، واحدة يحفظ بيها ملاحظة وواحدة يدور بيها. هو اللي يقرر إيه يستاهل يتحفظ:

memory_tools.py
import json
from datetime import date
from pathlib import Path

MEMORY_FILE = Path("customer_memory.json")
MEMORY_FILE.write_text("{}", encoding="utf-8")      # fresh start for this demo

def save_note(customer_id: str, note: str) -> str:
    """Save a short, useful fact about a customer for future conversations."""
    data = json.loads(MEMORY_FILE.read_text(encoding="utf-8"))
    data.setdefault(customer_id, []).append({"date": date(2026, 9, 22).isoformat(), "note": note})
    MEMORY_FILE.write_text(json.dumps(data, ensure_ascii=False, indent=1), encoding="utf-8")
    return "saved"

def recall_notes(customer_id: str) -> str:
    """Get saved notes about a customer. Use at the start of a conversation."""
    data = json.loads(MEMORY_FILE.read_text(encoding="utf-8"))
    notes = data.get(customer_id, [])
    return "\n".join(f"{n['date']}: {n['note']}" for n in notes) or "No notes yet."

# conversation 1
save_note("C-77", "Prefers delivery after 6 PM (works mornings).")
save_note("C-77", "Order 1031 arrived damaged; replacement sent.")

# conversation 2 (days later): the agent starts by recalling
print(recall_notes("C-77"))
print(recall_notes("C-99"))

في المحادثة التانية، الـ agent هيعرف إن العميل بيحب التوصيل بعد ٦، وإن آخر أوردر وصله مكسور، فيبدأ بالاعتذار ويتعامل بعناية أكتر. ده الفرق بين خدمة عملاء بتحسسك إنهم فاكرينك، وخدمة بتسألك نفس الأسئلة كل مرة.

🔎 والـ RAG كمان أداةبدل ما تحط المستندات في الـ prompt، اعمل أداة search_policies(query) بترجع أقرب فقرات (من المرحلة ٧). الـ agent يدور لما يحتاج بس، وممكن يدور كذا مرة بصيغ مختلفة لو أول بحث مجابش حاجة. ده اسمه Agentic RAG.
⚠ الذاكرة = بيانات شخصيةاللي بتحفظه عن العملاء بيانات شخصية. احفظ اللي محتاجه بس، ومتحفظش أرقام كروت أو باسوردات أبداً، وخلّي فيه طريقة تمسح بيها بيانات عميل لو طلب.
الدرس اللي فات