{ "cells": [ { "cell_type": "markdown", "id": "e0f43254", "metadata": {}, "source": [ "# Memory Augmented Agents: Filesystems + Oracle AI Database for Context and Memory Engineering In AI Agents (LangChain)\n", "\n", "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/oracle-devrel/oracle-ai-developer-hub/blob/main/notebooks/fs_vs_dbs.ipynb) [![Read article here](https://img.shields.io/badge/Read%20article%20here-Oracle%20Blog-C74634?style=flat-square)](https://blogs.oracle.com/developers/comparing-file-systems-and-databases-for-effective-ai-agent-memory-management) [![Watch video here](https://img.shields.io/badge/Watch%20video%20here-YouTube-FF0000?style=flat-square&logo=youtube&logoColor=white)](https://youtu.be/At_7kscp7PI?si=d39r8hWmhrtE1Hpp)\n", "\n", "-----" ] }, { "cell_type": "markdown", "id": "4704ef0f", "metadata": {}, "source": [ "# Filesystem vs Database: Agent Memory Architectures\n", "\n", "This notebook explores different approaches to **agent memory** using LangChain and compares their performance.\n", "\n", "**What's covered:**\n", "\n", "- **Part 1: FSAgent** - Filesystem-based memory using markdown files. Fast local I/O, human-readable, git-friendly.\n", "\n", "- **Part 2: MemAgent** - Database-backed memory using Oracle SQL tables and vector embeddings. ACID guarantees, semantic search, production-ready.\n", "\n", "- **Part 3: Benchmarking** - End-to-end agent tests measuring latency and LLM-as-judge evaluation.\n", "\n", "- **Part 4: ACID Transactions & Concurrency** - Demonstrates database ACID guarantees vs filesystem concurrency limitations.\n", "\n", "**Requirements:** Python 3.10+, Oracle Database, OpenAI API key\n", "\n", "> **Tip:** Run the Docker section first if you don't have Oracle AI Database running locally." ] }, { "cell_type": "markdown", "id": "319a1644", "metadata": {}, "source": [ "# Use Case and Background\n", "\n", "-----" ] }, { "cell_type": "markdown", "id": "f3d3cfb7", "metadata": {}, "source": [ "### Use Case\n", "\n", "We're building a **Research Agent** that can fetch papers from arXiv, store them in memory, and answer questions about their content. The focus is on comparing **two memory architectures**:\n", "\n", "- **Filesystem memory** - Papers stored as markdown files, searched via keyword matching\n", "- **Database memory** - Papers chunked and embedded in a vector store for semantic search\n", "\n", "The agent demonstrates how memory architecture affects both **retrieval speed** and **answer quality**. We then combine both approaches into a **hybrid system** that writes to the filesystem for speed and queries the database for intelligence.\n", "\n", "This is a practical exploration of the trade-offs between simple file-based storage and production-grade database systems for agent memory." ] }, { "cell_type": "markdown", "id": "1143dade", "metadata": {}, "source": [ "### Workload Patterns (Filesystem vs Database)\n", "\n", "| Pattern | FSAgent (Filesystem) | MemAgent (Database) | MemFSAgent (Hybrid) |\n", "|---------|---------------------|---------------------|---------------------|\n", "| **Conversation history** | Append to markdown files per thread | SQL table with thread_id, role, content | Write to FS first, background sync to DB |\n", "| **Knowledge storage** | Full papers as `.md` files | Chunked + embedded in vector store | Store in both, query from DB |\n", "| **Search/retrieval** | Keyword matching (grep-style) | Semantic similarity search | DB-first with FS fallback |\n", "| **Write latency** | Fast (local I/O) | Slower (DB + embedding) | Fast (FS immediate) |\n", "| **Read quality** | Limited (exact match) | Better (understands meaning) | Best of both |\n", "| **Persistence** | File-based | ACID guarantees | Redundant (both) |\n", "| **Human readable** | Yes (markdown) | No (DB rows) | Yes (FS copy) |" ] }, { "cell_type": "markdown", "id": "5f8b0d3a", "metadata": {}, "source": [ "### Evaluation Metrics\n", "\n", "We benchmark each agent using two metrics:\n", "\n", "| Metric | Description |\n", "|--------|-------------|\n", "| **Latency** | Time to complete each agent query (paper retrieval, Q&A) |\n", "| **LLM-as-Judge** | An LLM scores each response for relevance and accuracy on a 0-100% scale |\n", "\n", "These metrics let us compare both **speed** (latency) and **quality** (LLM judgment) across filesystem and database approaches." ] }, { "cell_type": "markdown", "id": "e835b4d6", "metadata": {}, "source": [ "### Loading Libaries and Setting Environment Variables" ] }, { "cell_type": "markdown", "id": "9sf14jxvc8q", "metadata": {}, "source": [ "### Dependencies\n", "\n", "| Library | Purpose |\n", "|---------|---------|\n", "| `langchain` | Core framework for building LLM agents and chains |\n", "| `langchain-community` | Community integrations (ArxivLoader, etc.) |\n", "| `langchain_openai` | OpenAI LLM and embedding models |\n", "| `langchain_oracledb` | Oracle vector store integration |\n", "| `oracledb` | Python driver for Oracle Database |\n", "| `arxiv` | Fetching papers from arXiv API |\n", "| `pymupdf` | PDF parsing for paper content extraction |\n", "| `sentence-transformers` | Local embedding models (optional fallback) |\n", "| `matplotlib` | Visualization for benchmark charts |" ] }, { "cell_type": "code", "execution_count": 1, "id": "0564bf71", "metadata": {}, "outputs": [], "source": [ "! pip install -qU langchain langchain-community arxiv langchain_oracledb pymupdf langchain_openai oracledb sentence-transformers matplotlib" ] }, { "cell_type": "markdown", "id": "76wac84xgg5", "metadata": {}, "source": [ "### API Keys Required\n", "\n", "| Key | Required | Where to Get It |\n", "|-----|----------|-----------------|\n", "| `OPENAI_API_KEY` | Yes | [OpenAI Platform](https://platform.openai.com/api-keys) - Used for embeddings and LLM calls |\n", "| `LANGSMITH_API_KEY` | Optional | [LangSmith](https://smith.langchain.com/) - For tracing and debugging agent runs |\n", "\n", "**Setup options:**\n", "1. Set environment variables in your shell before running the notebook\n", "2. Use the `set_env_variable()` helper below to enter keys securely\n", "3. Create a `.env` file and load it with `python-dotenv`" ] }, { "cell_type": "code", "execution_count": 2, "id": "e5a40601", "metadata": {}, "outputs": [], "source": [ "import os\n", "import getpass\n", "\n", "def set_env_variable(key: str) -> str:\n", " \"\"\"\n", " Prompt for a value (hidden input) and set it as an environment variable.\n", " Returns the value that was set.\n", " \"\"\"\n", " value = getpass.getpass(f\"Enter value for {key}: \")\n", " os.environ[key] = value\n", " return value" ] }, { "cell_type": "code", "execution_count": 3, "id": "c2b096d4", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "''" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "set_env_variable(\"OPENAI_API_KEY\")\n", "set_env_variable(\"LANGSMITH_TRACING\")\n", "set_env_variable(\"LANGSMITH_ENDPOINT\")\n", "set_env_variable(\"LANGSMITH_API_KEY\")\n" ] }, { "cell_type": "markdown", "id": "00ab368d", "metadata": {}, "source": [ "# Part 1: FSAgent (Filesystem backed Agent)\n", "\n", "----" ] }, { "cell_type": "markdown", "id": "wrtba1z2ami", "metadata": {}, "source": [ "## What You Will Learn\n", "\n", "This section demonstrates how to build a **filesystem-backed research agent** that uses local markdown files as its memory system. By the end of Part 1, you will understand:\n", "\n", "### Architecture Overview\n", "\n", "The FSAgent organizes memory into two directories:\n", "- **`semantic/`** - Long-term knowledge storage (research papers, facts)\n", "- **`episodic/`** - Session-based memory (conversation transcripts, summaries)\n", "\n", "### Step-by-Step Implementation\n", "\n", "**1.1 ArXiv Search Tool**\n", "- Configure the `ArxivRetriever` from LangChain to search academic papers\n", "- Build `arxiv_search_candidates()` to return structured paper metadata (ID, title, authors, abstract)\n", "- Understand how to limit results and format output for LLM consumption\n", "\n", "**1.2 Paper Fetching and Storage**\n", "- Implement `fetch_and_save_paper()` to download PDFs and convert to text\n", "- Save papers directly to `semantic/knowledge_base/.md`\n", "- Learn the pattern of bypassing LLM context to prevent truncation of large documents\n", "\n", "**1.3 File Reading Tools (Progressive Disclosure)**\n", "- `read_file()` - Full file retrieval for small documents\n", "- `tail_file()` - Read last N lines to check recent content first\n", "- `read_file_range()` - Targeted line range extraction\n", "- `grep_files()` - Pattern-based search across the knowledge base\n", "- `list_papers()` - Directory listing for available papers\n", "\n", "**1.4 Episodic Memory Management**\n", "- `conversation_to_file()` - Append chat turns to `episodic/transcripts/.md`\n", "- `summarise_conversation_to_file()` - Generate and save conversation summaries\n", "- Understand the separation between raw transcripts and compressed summaries\n", "\n", "**1.5 Context Window Monitoring**\n", "- `monitor_context_window()` - Track token usage in real-time\n", "- Implement threshold-based warnings before hitting context limits\n", "- Learn how to trigger summarization when approaching capacity\n", "\n", "**1.6 Agent Assembly**\n", "- Combine all tools into `FS_TOOLS` list\n", "- Configure the LangChain agent with system prompts\n", "- Build the interactive chat loop with memory persistence\n", "\n", "### Key Patterns Demonstrated\n", "\n", "| Pattern | Description |\n", "|---------|-------------|\n", "| **Just-in-Time Retrieval** | Load files only when needed, not upfront |\n", "| **Progressive Disclosure** | Use `tail_file` before `read_file` to minimize token usage |\n", "| **Bypass LLM for Large Data** | Save papers directly to disk without passing through context |\n", "| **Structured File Layout** | Consistent directory structure for predictable retrieval |\n", "| **Token-Aware Operation** | Monitor and manage context window proactively |" ] }, { "cell_type": "markdown", "id": "04ba0f89", "metadata": {}, "source": [ "### FSAgent tools\n", "\n", "| Tool | What it does | Output |\n", "|---|---|---|\n", "| **arxiv_search_candidates(query, k=5)** | Searches arXiv and returns a JSON list of candidate papers with IDs, titles, authors, and abstracts. | JSON string of paper candidates |\n", "| **fetch_and_save_paper(arxiv_id)** | Fetches full paper text (PDF to text) and saves directly to `semantic/knowledge_base/.md`. Avoids routing full content through LLM. | File path |\n", "| **read_file(path)** | Reads a file from disk and returns its contents in full. Use to reload stored papers or transcripts just-in-time. | Full file contents |\n", "| **tail_file(path, n_lines=80)** | Reads the last N lines of a file. Use first when a file is large. | Last N lines of file |\n", "| **read_file_range(path, start_line, end_line)** | Reads a specific line range from a file (inclusive start, exclusive end). Use after tail_file to expand around relevant regions. | Selected line range |\n", "| **grep_files(pattern, root_dir, file_glob)** | Grep-like search across local files to find relevant passages by keyword/pattern. | Matches with file path and context |\n", "| **list_papers()** | Lists all locally saved paper files in `semantic/knowledge_base/`. | List of filenames |\n", "| **conversation_to_file(run_id, messages)** | Appends conversation entries to a single transcript file per run in `episodic/transcripts/`. | File path |\n", "| **summarise_conversation_to_file(run_id, messages)** | Saves full transcript to episodic memory, then writes a compact summary to `episodic/summaries/`. | Dict with transcript and summary paths |\n", "| **monitor_context_window(messages)** | Estimates current context usage (tokens used, remaining, percentage). | Dict with token stats |" ] }, { "cell_type": "markdown", "id": "c1f4e8e1", "metadata": {}, "source": [ "## 1.1 Create Arxiv search tool for papers\n", "\n", "The first step in building our research agent is enabling it to discover relevant academic papers. We use LangChain's `ArxivRetriever` to query the arXiv API, then wrap it in a custom tool that returns structured JSON with paper metadata. This approach gives the agent a curated list of candidates without overwhelming the context window with full paper content." ] }, { "cell_type": "code", "execution_count": 4, "id": "9d39cde6", "metadata": {}, "outputs": [], "source": [ "from langchain_community.retrievers import ArxivRetriever\n", "\n", "arxiv_retriever = ArxivRetriever(\n", " load_max_docs=8,\n", " get_full_documents=False,\n", " doc_content_chars_max=4000\n", ")" ] }, { "cell_type": "code", "execution_count": 5, "id": "af1d232c", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "/opt/homebrew/Caskroom/miniconda/base/envs/filesystemsvsdbs/lib/python3.12/site-packages/langsmith/client.py:498: LangSmithMissingAPIKeyWarning: API key must be provided when using hosted LangSmith API\n", " warnings.warn(\n", "Failed to multipart ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/multipart. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/multipart', '{\"error\":\"Unauthorized\"}\\n')trace=019c0bb2-6312-7850-bc6a-2b178b1f9db0,id=019c0bb2-6312-7850-bc6a-2b178b1f9db0\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "3\n", "{'Entry ID': 'http://arxiv.org/abs/2210.13383v1', 'Published': datetime.date(2022, 10, 24), 'Title': 'Evaluating Long-Term Memory in 3D Mazes', 'Authors': 'Jurgis Pasukonis, Timothy Lillicrap, Danijar Hafner'}\n", "Intelligent agents need to remember salient information to reason in partially-observed environments. For example, agents with a first-person view should remember the positions of relevant objects even if they go out of view. Similarly, to effectively navigate through rooms agents need to remember the floor plan of how rooms are connected. However, most benchmark tasks in reinforcement learning do not test long-term memory in agents, slowing down progress in this important research direction. In this paper, we introduce the Memory Maze, a 3D domain of randomized mazes specifically designed for evaluating long-term memory in agents. Unlike existing benchmarks, Memory Maze measures long-term memory separate from confounding agent abilities and requires the agent to localize itself by integra\n" ] } ], "source": [ "docs = arxiv_retriever.invoke(\"agent memory long-term evaluation benchmark\")\n", "print(len(docs))\n", "print(docs[0].metadata) # arxiv metadata (id, title, authors, etc.)\n", "print(docs[0].page_content[:800])" ] }, { "cell_type": "markdown", "id": "dj3a2kaau3", "metadata": {}, "source": [ "> 💡 **Key Takeaways**\n", "> - Return metadata (ID, title, abstract) instead of full content to preserve context space\n", "> - Use structured JSON output so the agent can programmatically select papers\n", "> - The retriever handles API rate limiting and pagination automatically" ] }, { "cell_type": "markdown", "id": "48706fb6", "metadata": {}, "source": [ "## 1.2 Paper Fetching and Storage\n", "\n", "Once the agent identifies papers of interest, it needs to retrieve and persist the full content. The `fetch_and_save_paper` tool downloads the PDF, converts it to plain text, and writes it directly to the filesystem at `semantic/knowledge_base/.md`. This bypasses the LLM entirely, preventing truncation of large documents and keeping the context window free for reasoning." ] }, { "cell_type": "code", "execution_count": 6, "id": "63eae7c9", "metadata": {}, "outputs": [], "source": [ "import json\n", "from urllib.parse import urlparse\n", "from langchain_core.tools import tool\n", "\n", "def _arxiv_id_from_entry_id(entry_id: str) -> str:\n", " \"\"\"\n", " Convert 'http://arxiv.org/abs/2310.08560v2' -> '2310.08560v2'\n", " \"\"\"\n", " if not entry_id:\n", " return \"\"\n", " path = urlparse(entry_id).path # e.g. '/abs/2310.08560v2'\n", " return path.split(\"/abs/\")[-1].strip(\"/\")\n", "\n", "@tool\n", "def arxiv_search_candidates(query: str, k: int = 5) -> str:\n", " \"\"\"\n", " Search arXiv and return a JSON list of candidate papers with IDs + metadata.\n", "\n", " Output schema (JSON string):\n", " [\n", " {\n", " \"arxiv_id\": \"2310.08560v2\",\n", " \"entry_id\": \"http://arxiv.org/abs/2310.08560v2\",\n", " \"title\": \"...\",\n", " \"authors\": \"...\",\n", " \"published\": \"2024-02-12\",\n", " \"abstract\": \"...\"\n", " },\n", " ...\n", " ]\n", " \"\"\"\n", " docs = arxiv_retriever.invoke(query) # uses your existing ArxivRetriever\n", " candidates = []\n", " for d in (docs or [])[:k]:\n", " meta = d.metadata or {}\n", " entry_id = meta.get(\"Entry ID\", \"\")\n", " candidates.append({\n", " \"arxiv_id\": _arxiv_id_from_entry_id(entry_id),\n", " \"entry_id\": entry_id,\n", " \"title\": meta.get(\"Title\", \"\"),\n", " \"authors\": meta.get(\"Authors\", \"\"),\n", " \"published\": str(meta.get(\"Published\", \"\")),\n", " \"abstract\": (d.page_content or \"\")[:2500], # keep lightweight\n", " })\n", " return json.dumps(candidates, ensure_ascii=False, indent=2)\n" ] }, { "cell_type": "code", "execution_count": 7, "id": "df5fb348", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "/opt/homebrew/Caskroom/miniconda/base/envs/filesystemsvsdbs/lib/python3.12/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", " from .autonotebook import tqdm as notebook_tqdm\n", "Failed to send compressed multipart ingest: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/multipart. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/multipart', '{\"error\":\"Unauthorized\"}\\n')trace=019c0bb2-6312-7850-bc6a-2b178b1f9db0,id=019c0bb2-6312-7850-bc6a-2b178b1f9db0\n" ] } ], "source": [ "from pathlib import Path\n", "from langchain_community.document_loaders import ArxivLoader\n", "\n", "@tool\n", "def fetch_and_save_paper(arxiv_id: str, semantic_dir: str = \"semantic\") -> str:\n", " \"\"\"\n", " Fetch full paper text (PDF->text) and save directly to semantic/knowledge_base/.md.\n", " Avoids routing full content through the LLM, preventing truncation.\n", " \"\"\"\n", " kb_dir = Path(semantic_dir) / \"knowledge_base\"\n", " kb_dir.mkdir(parents=True, exist_ok=True)\n", "\n", " loader = ArxivLoader(\n", " query=arxiv_id,\n", " load_max_docs=1,\n", " doc_content_chars_max=None, # no truncation\n", " )\n", " docs = loader.load()\n", " if not docs:\n", " return f\"No documents found for arXiv id: {arxiv_id}\"\n", "\n", " doc = docs[0]\n", " title = (\n", " doc.metadata.get(\"Title\")\n", " or doc.metadata.get(\"title\")\n", " or f\"arXiv {arxiv_id}\"\n", " )\n", " content = doc.page_content\n", "\n", " path = kb_dir / f\"{arxiv_id}.md\"\n", " path.write_text(f\"# {title}\\n\\n{content}\", encoding=\"utf-8\")\n", " return str(path)" ] }, { "cell_type": "markdown", "id": "18m8lwqckgf", "metadata": {}, "source": [ "> 💡 **Key Takeaways**\n", "> - Write large documents directly to disk—never route them through the LLM context\n", "> - Use consistent file naming (`.md`) for predictable retrieval later\n", "> - PDF-to-text conversion loses formatting but preserves the content that matters" ] }, { "cell_type": "markdown", "id": "7bf511c8", "metadata": {}, "source": [ "## 1.3 File Reading Tools (Progressive Disclosure)\n", "\n", "Reading entire files into the context window is wasteful when you only need a specific section. This section implements a suite of file reading tools that support progressive disclosure: start with `tail_file` to peek at recent content, use `grep_files` to locate specific passages, then retrieve targeted sections with `read_file_range`. Only fall back to `read_file` when you genuinely need the complete document." ] }, { "cell_type": "code", "execution_count": 8, "id": "407924e4", "metadata": {}, "outputs": [], "source": [ "@tool\n", "def read_file(path: str) -> str:\n", " \"\"\"\n", " Read a file from disk and return its contents in full.\n", " Use this to reload stored papers or conversation transcripts just-in-time.\n", " \"\"\"\n", " p = Path(path)\n", " if not p.exists():\n", " return f\"File not found: {path}\"\n", " return p.read_text(encoding=\"utf-8\")" ] }, { "cell_type": "code", "execution_count": 9, "id": "6004923c", "metadata": {}, "outputs": [], "source": [ "@tool\n", "def tail_file(path: str, n_lines: int = 80) -> str:\n", " \"\"\"\n", " Read the last N lines of a file.\n", "\n", " Use this first when a file is large. If you need more context,\n", " call read_file_range (or increase n_lines).\n", " \"\"\"\n", " p = Path(path)\n", " if not p.exists():\n", " return f\"File not found: {path}\"\n", " lines = p.read_text(encoding=\"utf-8\").splitlines()\n", " return \"\\n\".join(lines[-max(1, n_lines):])" ] }, { "cell_type": "code", "execution_count": 10, "id": "b5a25507", "metadata": {}, "outputs": [], "source": [ "@tool\n", "def read_file_range(path: str, start_line: int, end_line: int) -> str:\n", " \"\"\"\n", " Read a specific line range from a file (inclusive start, exclusive end).\n", "\n", " Use after tail_file to expand around relevant regions without loading\n", " the entire file into the context window.\n", " \"\"\"\n", " p = Path(path)\n", " if not p.exists():\n", " return f\"File not found: {path}\"\n", " lines = p.read_text(encoding=\"utf-8\").splitlines()\n", " start = max(0, start_line)\n", " end = min(len(lines), end_line)\n", " if start >= end:\n", " return f\"Empty range: {start_line}:{end_line} (file has {len(lines)} lines)\"\n", " return \"\\n\".join(lines[start:end])" ] }, { "cell_type": "code", "execution_count": 11, "id": "4c3c2068", "metadata": {}, "outputs": [], "source": [ "import re\n", "\n", "@tool\n", "def grep_files(\n", " pattern: str,\n", " root_dir: str = \"semantic\",\n", " file_glob: str = \"**/*.md\",\n", " max_matches: int = 200,\n", " ignore_case: bool = True,\n", ") -> str:\n", " \"\"\"\n", " Search files under a directory for a pattern (grep-like).\n", "\n", " Returns matching lines with file path + line number so the agent can\n", " jump to the right region using read_file_range.\n", "\n", " Args:\n", " pattern: Text or regex pattern to search for.\n", " root_dir: Directory to search under (default: \"semantic\").\n", " file_glob: Which files to include (default: markdown files recursively).\n", " max_matches: Safety cap on total returned matches.\n", " ignore_case: Case-insensitive matching (default True).\n", "\n", " Returns:\n", " A compact report of matches: :: \n", " \"\"\"\n", " root = Path(root_dir)\n", " if not root.exists():\n", " return f\"Directory not found: {root_dir}\"\n", "\n", " flags = re.IGNORECASE if ignore_case else 0\n", " try:\n", " rx = re.compile(pattern, flags)\n", " except re.error as e:\n", " return f\"Invalid regex pattern: {e}\"\n", "\n", " matches = []\n", " for fp in root.glob(file_glob):\n", " if not fp.is_file():\n", " continue\n", " try:\n", " lines = fp.read_text(encoding=\"utf-8\", errors=\"ignore\").splitlines()\n", " except Exception as e:\n", " continue\n", "\n", " for i, line in enumerate(lines, start=1):\n", " if rx.search(line):\n", " matches.append(f\"{fp.as_posix()}:{i}: {line.strip()}\")\n", " if len(matches) >= max_matches:\n", " return \"\\n\".join(matches) + \"\\n\\n[TRUNCATED: max_matches reached]\"\n", "\n", " if not matches:\n", " return \"No matches found.\"\n", " return \"\\n\".join(matches)\n" ] }, { "cell_type": "markdown", "id": "z28bcp3esma", "metadata": {}, "source": [ "> 💡 **Key Takeaways**\n", "> - Always try `tail_file` or `grep_files` before loading entire files\n", "> - Line-range retrieval (`read_file_range`) minimizes token usage for targeted lookups\n", "> - Pattern-based search scales better than loading all files into context" ] }, { "cell_type": "markdown", "id": "68380274", "metadata": {}, "source": [ "## 1.4 Episodic Memory Management\n", "\n", "While semantic memory stores facts and knowledge, episodic memory captures the agent's experiences—its conversation history. This section implements tools to persist chat transcripts to `episodic/transcripts/` and generate compressed summaries in `episodic/summaries/`. The LLM creates these summaries, extracting key decisions and insights while discarding redundant back-and-forth." ] }, { "cell_type": "code", "execution_count": 12, "id": "4a6632e3", "metadata": {}, "outputs": [], "source": [ "@tool\n", "def list_papers(semantic_dir: str = \"semantic\") -> list[str]:\n", " \"\"\"\n", " List locally saved paper files in the semantic knowledge base directory.\n", "\n", " Folder layout:\n", " semantic/knowledge_base/*.md\n", "\n", " Args:\n", " semantic_dir: Root directory for semantic memory (default: \"semantic\").\n", "\n", " Returns:\n", " A sorted list of file paths (e.g., [\"semantic/knowledge_base/2401.01234.md\", ...]).\n", " Returns an empty list if the directory does not exist or contains no .md files.\n", " \"\"\"\n", " kb_dir = Path(semantic_dir) / \"knowledge_base\"\n", " if not kb_dir.exists():\n", " return []\n", " return sorted(str(f) for f in kb_dir.glob(\"*.md\"))\n" ] }, { "cell_type": "code", "execution_count": 13, "id": "5e35df18", "metadata": {}, "outputs": [], "source": [ "from datetime import datetime, timezone\n", "from typing import List, Dict, Any\n", "\n", "\n", "def _ts_utc() -> str:\n", " return datetime.now(timezone.utc).strftime(\"%Y-%m-%dT%H:%M:%SZ\")\n", "\n", "def _format_blocks(messages: List[Dict[str, str]]) -> str:\n", " \"\"\"Format messages as appendable markdown blocks with timestamps.\"\"\"\n", " blocks = []\n", " for m in messages:\n", " role = (m.get(\"role\") or \"unknown\").lower()\n", " if role in {\"tool\", \"function\"}:\n", " continue # remove tool calls/tool outputs from conversation.md\n", " content = m.get(\"content\", \"\")\n", " ts = m.get(\"ts\") or _ts_utc()\n", " blocks.append(f\"### {ts} — {role.upper()}\\n\\n{content}\\n\")\n", " return \"\\n\".join(blocks) + (\"\\n\" if blocks else \"\")\n", "\n", "def _messages_to_markdown(messages: List[Dict[str, str]]) -> str:\n", " lines = []\n", " for m in messages:\n", " role = m.get(\"role\", \"unknown\").upper()\n", " content = m.get(\"content\", \"\")\n", " lines.append(f\"## {role}\\n\\n{content}\\n\")\n", " return \"\\n\".join(lines)\n", "\n", "\n", "@tool\n", "def conversation_to_file(\n", " run_id: str,\n", " messages: List[Dict[str, str]],\n", " episodic_dir: str = \"episodic\",\n", ") -> str:\n", " \"\"\"\n", " Append conversation entries to a single transcript file per run:\n", " episodic/conversations/.md\n", "\n", " Tool messages are ignored (tool output is logged separately via EpisodicToolLogger).\n", " Each entry is timestamped.\n", " \"\"\"\n", " conversations_dir = Path(episodic_dir) / \"conversations\"\n", " conversations_dir.mkdir(parents=True, exist_ok=True)\n", "\n", " path = conversations_dir / f\"{run_id}.md\"\n", "\n", " if not path.exists():\n", " header = f\"# Conversation Transcript\\n\\nRun: `{run_id}`\\nCreated: {_ts_utc()}\\n\\n---\\n\\n\"\n", " path.write_text(header, encoding=\"utf-8\")\n", "\n", " # Append new blocks\n", " path.write_text(path.read_text(encoding=\"utf-8\") + _format_blocks(messages), encoding=\"utf-8\")\n", " return str(path)" ] }, { "cell_type": "code", "execution_count": 14, "id": "9c16efbf", "metadata": {}, "outputs": [], "source": [ "from langchain_openai import ChatOpenAI\n", "\n", "\n", "@tool\n", "def summarise_conversation_to_file(\n", " run_id: str,\n", " messages: List[Dict[str, str]],\n", " episodic_dir: str = \"episodic\",\n", ") -> Dict[str, str]:\n", " \"\"\"\n", " Save the full transcript to episodic memory, then write a compact summary to episodic/summaries/.\n", "\n", " Returns:\n", " {\n", " \"transcript_path\": \"...\",\n", " \"summary_path\": \"...\",\n", " \"summary\": \"...\"\n", " }\n", " \"\"\"\n", " transcript_path = conversation_to_file.invoke(\n", " {\"run_id\": run_id, \"messages\": messages, \"episodic_dir\": episodic_dir}\n", " )\n", "\n", " model = ChatOpenAI(model=os.getenv(\"OPENAI_MODEL\", \"gpt-4o-mini\"), temperature=0)\n", "\n", " prompt = (\n", " \"Summarise this conversation for future continuity.\\n\\n\"\n", " \"Requirements:\\n\"\n", " \"- Capture key facts, decisions, and constraints.\\n\"\n", " \"- Capture open questions / next steps.\\n\"\n", " \"- Keep it concise (aim ~200-400 words).\\n\"\n", " \"- Do NOT invent details.\\n\\n\"\n", " f\"Transcript file reference: {transcript_path}\\n\\n\"\n", " \"Conversation:\\n\"\n", " + _messages_to_markdown(messages)\n", " )\n", " summary_text = model.invoke(prompt).content\n", "\n", " summaries_dir = Path(episodic_dir) / \"summaries\"\n", " summaries_dir.mkdir(parents=True, exist_ok=True)\n", "\n", " ts = datetime.now(timezone.utc).strftime(\"%Y%m%d_%H%M%S\")\n", " summary_path = summaries_dir / f\"{run_id}_{ts}_summary.md\"\n", " summary_path.write_text(\n", " f\"# Conversation Summary\\n\\nTranscript: {transcript_path}\\n\\n{summary_text}\",\n", " encoding=\"utf-8\",\n", " )\n", "\n", " return {\n", " \"transcript_path\": transcript_path,\n", " \"summary_path\": str(summary_path),\n", " \"summary\": summary_text,\n", " }" ] }, { "cell_type": "markdown", "id": "bd0ke94zika", "metadata": {}, "source": [ "> 💡 **Key Takeaways**\n", "> - Separate raw transcripts from summaries—keep both for different use cases\n", "> - LLM-generated summaries capture intent and decisions, not just text compression\n", "> - Episodic memory enables multi-session continuity without replaying full history" ] }, { "cell_type": "markdown", "id": "c36d7445", "metadata": {}, "source": [ "## 1.5 Context Window Monitoring\n", "\n", "LLMs have finite context windows, and exceeding them causes silent truncation or errors. The `monitor_context_window` tool uses tiktoken to count tokens in the current conversation and compare against the model's limit. When usage exceeds a configurable threshold, the agent can proactively trigger summarization to compress history before hitting the ceiling." ] }, { "cell_type": "code", "execution_count": 15, "id": "e70d44d2", "metadata": {}, "outputs": [], "source": [ "import tiktoken\n", "\n", "def _count_tokens_approx(messages: List[Dict[str, str]]) -> int:\n", " # Fallback: ~4 chars/token heuristic\n", " total_chars = sum(len(m.get(\"content\", \"\")) for m in messages)\n", " return max(1, total_chars // 4)\n", "\n", "def _count_tokens_tiktoken(messages: List[Dict[str, str]], model_name: str) -> int:\n", " # Best-effort token counting for OpenAI-like chat messages\n", " try:\n", " enc = tiktoken.encoding_for_model(model_name)\n", " except Exception:\n", " return _count_tokens_approx(messages)\n", "\n", " # Rough chat accounting (good enough for monitoring)\n", " tokens = 0\n", " for m in messages:\n", " tokens += 4 # role/message overhead (approx)\n", " tokens += len(enc.encode(m.get(\"content\", \"\")))\n", " tokens += 2\n", " return tokens\n", "\n", "@tool\n", "def monitor_context_window(\n", " messages: List[Dict[str, str]],\n", " model_name: str = \"gpt-4o-mini\",\n", " max_context_tokens: int = 128_000,\n", ") -> Dict[str, Any]:\n", " \"\"\"\n", " Estimate current context usage.\n", " Returns {tokens_used, max_context_tokens, utilization_ratio}.\n", " \"\"\"\n", " tokens_used = _count_tokens_tiktoken(messages, model_name)\n", " utilization = tokens_used / max_context_tokens\n", " return {\n", " \"tokens_used\": tokens_used,\n", " \"max_context_tokens\": max_context_tokens,\n", " \"utilization_ratio\": utilization,\n", " }" ] }, { "cell_type": "markdown", "id": "6iwxormfjfg", "metadata": {}, "source": [ "> 💡 **Key Takeaways**\n", "> - Monitor tokens proactively—don't wait for errors or silent truncation\n", "> - Set thresholds (e.g., 80%) to trigger summarization before hitting limits\n", "> - Token counting is cheap; context overflow recovery is expensive" ] }, { "cell_type": "markdown", "id": "cb21d286", "metadata": {}, "source": [ "## 1.6 Agent Assembly\n", "\n", "With all tools defined, we assemble the complete FSAgent. This involves registering tools in the `FS_TOOLS` list, configuring the LangChain agent with a system prompt that explains the memory architecture, and building the interactive chat loop. The loop persists each turn to the filesystem, monitors context usage, and maintains conversation continuity across sessions." ] }, { "cell_type": "code", "execution_count": 16, "id": "5f174dc1", "metadata": {}, "outputs": [], "source": [ "FS_TOOLS = [\n", " arxiv_search_candidates, # search arXiv for relevant research papers\n", " fetch_and_save_paper, # fetch full paper text (PDF->text) and save directly to semantic/knowledge_base/.md\n", " read_file, # read a file from disk and return its contents in full\n", " tail_file, # read the last N lines of a file\n", " read_file_range, # read a specific line range from a file (inclusive start, exclusive end)\n", " conversation_to_file, # append conversation entries to a single transcript file per run\n", " summarise_conversation_to_file, # save the full transcript to episodic memory, then write a compact summary to episodic/summaries/.\n", " monitor_context_window, # estimate current context usage\n", " list_papers, # list locally saved paper files in the semantic knowledge base directory\n", " grep_files\n", "]" ] }, { "cell_type": "code", "execution_count": 17, "id": "028bfa77", "metadata": {}, "outputs": [], "source": [ "from langchain.agents import create_agent\n", "\n", "fs_agent = create_agent(\n", " model=f\"openai:{os.getenv('OPENAI_MODEL', 'gpt-4o-mini')}\",\n", " tools=FS_TOOLS,\n", " system_prompt=(\n", " \"You are a conversational research ingestion agent.\\n\\n\"\n", " \"Core behavior:\\n\"\n", " \"- When asked to find a paper: use arxiv_search_candidates, pick the best arxiv_id, \"\n", " \"then call fetch_and_save_paper to store the full text in semantic/knowledge_base/.\\n\"\n", " \"- Stay grounded in retrieved and/or stored content. If you did not read it, say so.\\n\\n\"\n", " \"Filesystem-first reading (progressive disclosure):\\n\"\n", " \"- Prefer searching over reading: use grep_files to locate relevant passages, then use read_file_range \"\n", " \"to load only the needed lines.\\n\"\n", " \"- If you need the end of a file (logs/transcripts), use tail_file first, then read_file_range to expand.\\n\"\n", " \"- Use read_file only when you explicitly need the entire file and it is reasonably sized.\\n\\n\"\n", " \"Working pattern for answering questions about stored papers:\\n\"\n", " \"1) list_papers (if you need to see what's available)\\n\"\n", " \"2) grep_files to find where the answer likely is\\n\"\n", " \"3) read_file_range around the matching line numbers\\n\"\n", " \"4) answer with citations/quotes from the loaded spans (keep excerpts short)\\n\\n\"\n", " \"Memory taxonomy:\\n\"\n", " \"- Papers/knowledge base live in semantic/knowledge_base/.\\n\"\n", " \"- Conversations (transcripts) live in episodic/conversations/ (one file per run).\\n\"\n", " \"- Summaries live in episodic/summaries/.\\n\"\n", " \"- Conversation may be summarised externally; respect summary + transcript references.\\n\"\n", " ),\n", ")\n" ] }, { "cell_type": "code", "execution_count": 18, "id": "7abccb1f", "metadata": {}, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from IPython.display import Image, display\n", "\n", "png_bytes = fs_agent.get_graph().draw_mermaid_png()\n", "display(Image(png_bytes))" ] }, { "cell_type": "code", "execution_count": 19, "id": "3d9ff2f3", "metadata": {}, "outputs": [], "source": [ "def normalize_messages(messages: List[Any]) -> List[Dict[str, str]]:\n", " \"\"\"Convert LangChain message objects (or dicts) into [{'role','content'}] dicts.\"\"\"\n", " out = []\n", " for m in messages:\n", " # Already a dict?\n", " if isinstance(m, dict):\n", " out.append({\"role\": m.get(\"role\", \"unknown\"), \"content\": m.get(\"content\", \"\")})\n", " continue\n", "\n", " # LangChain BaseMessage-like objects\n", " role = getattr(m, \"type\", None) or m.__class__.__name__.lower()\n", " content = getattr(m, \"content\", \"\")\n", "\n", " # Normalize role names\n", " if role in (\"human\", \"user\", \"humanmessage\"):\n", " role = \"user\"\n", " elif role in (\"ai\", \"assistant\", \"aimessage\"):\n", " role = \"assistant\"\n", " elif role in (\"system\", \"systemmessage\"):\n", " role = \"system\"\n", "\n", " out.append({\"role\": role, \"content\": content})\n", " return out" ] }, { "cell_type": "code", "execution_count": 20, "id": "7a98480a", "metadata": {}, "outputs": [], "source": [ "from langchain_core.callbacks import BaseCallbackHandler\n", "from uuid import uuid4\n", "\n", "\n", "class EpisodicToolLogger(BaseCallbackHandler):\n", " \"\"\"Logs tool calls to episodic/tool_outputs//...json\"\"\"\n", "\n", " def __init__(self, run_id: str, episodic_dir: str = \"episodic\", max_chars: int = 50_000):\n", " self.run_id = run_id\n", " self.max_chars = max_chars\n", " self.out_dir = Path(episodic_dir) / \"tool_outputs\" / run_id\n", " self.out_dir.mkdir(parents=True, exist_ok=True)\n", " self._pending = {} # call_id -> dict\n", "\n", " def on_tool_start(self, serialized, input_str=None, **kwargs):\n", " tool_name = (serialized or {}).get(\"name\") or \"unknown_tool\"\n", " call_id = kwargs.get(\"run_id\") or str(uuid4())\n", "\n", " self._pending[call_id] = {\n", " \"ts_utc\": datetime.now(timezone.utc).isoformat(),\n", " \"tool\": tool_name,\n", " \"input\": input_str,\n", " }\n", "\n", " def on_tool_end(self, output, **kwargs):\n", " call_id = kwargs.get(\"run_id\")\n", " record = self._pending.pop(call_id, {\n", " \"ts_utc\": datetime.now(timezone.utc).isoformat(),\n", " \"tool\": \"unknown_tool\",\n", " \"input\": None,\n", " })\n", "\n", " # Make output JSON-safe + bounded\n", " try:\n", " out = output if isinstance(output, (dict, list, str, int, float, bool)) else str(output)\n", " except Exception:\n", " out = \"\"\n", "\n", " out_str = out if isinstance(out, str) else json.dumps(out, ensure_ascii=False)\n", " if len(out_str) > self.max_chars:\n", " out_str = out_str[: self.max_chars] + \"\\n\\n[TRUNCATED]\"\n", "\n", " record[\"output\"] = out_str\n", "\n", " ts = datetime.now(timezone.utc).strftime(\"%Y%m%d_%H%M%S\")\n", " fname = f\"{ts}_{record['tool']}.json\"\n", " (self.out_dir / fname).write_text(json.dumps(record, indent=2, ensure_ascii=False), encoding=\"utf-8\")\n" ] }, { "cell_type": "markdown", "id": "85980993", "metadata": {}, "source": [ "## 1.7 Run Agent" ] }, { "cell_type": "code", "execution_count": 21, "id": "536c1126", "metadata": {}, "outputs": [], "source": [ "from typing import Any, List\n", "\n", "def chat(run_id: str, max_context_tokens: int = 128_000, threshold: float = 0.80) -> None:\n", " \"\"\"\n", " Conversational chat loop with:\n", " - transcript persisted every turn (conversation_to_file)\n", " - tool outputs logged every turn (EpisodicToolLogger -> episodic/tool_outputs//)\n", " - context monitoring every turn (monitor_context_window)\n", " - auto-summarise at threshold (summarise_conversation_to_file)\n", " and rotate the working context to a compact summary + transcript reference.\n", " \"\"\"\n", " model_name = os.getenv(\"OPENAI_MODEL\", \"gpt-4o-mini\")\n", " tool_logger = EpisodicToolLogger(run_id=run_id, episodic_dir=\"episodic\")\n", "\n", " # Context for the agent (can be rotated after summarisation)\n", " messages: List[Any] = []\n", "\n", " print(\"FSAgent chat started. Type 'exit' to stop.\\n\")\n", "\n", " while True:\n", " user_text = input(\"You: \").strip()\n", " if user_text.lower() in {\"exit\", \"quit\"}:\n", " print(\"\\nSaved conversation transcript.\")\n", " break\n", "\n", " # 1) append user message to transcript (timestamped)\n", " conversation_to_file.invoke({\n", " \"run_id\": run_id,\n", " \"messages\": [{\"role\": \"user\", \"content\": user_text, \"ts\": _ts_utc()}],\n", " })\n", "\n", " # Add to agent context\n", " messages.append({\"role\": \"user\", \"content\": user_text})\n", "\n", " # Monitor context\n", " status = monitor_context_window.invoke(\n", " {\n", " \"messages\": normalize_messages(messages),\n", " \"model_name\": model_name,\n", " \"max_context_tokens\": max_context_tokens,\n", " }\n", " )\n", "\n", " # Summarise if needed (and rotate context)\n", " if status[\"utilization_ratio\"] >= threshold:\n", " pack = summarise_conversation_to_file.invoke(\n", " {\"run_id\": run_id, \"messages\": []} # summariser will read transcript file (see below)\n", " )\n", " summary = pack[\"summary\"]\n", " transcript_path = pack[\"transcript_path\"]\n", " summary_path = pack[\"summary_path\"]\n", "\n", " # record the summarisation event in transcript\n", " conversation_to_file.invoke({\n", " \"run_id\": run_id,\n", " \"messages\": [{\n", " \"role\": \"system\",\n", " \"content\": f\"Context summarised.\\nTranscript: {transcript_path}\\nSummary: {summary_path}\",\n", " \"ts\": _ts_utc()\n", " }],\n", " })\n", "\n", " # Rotate agent context to summary + pointer\n", " messages = [\n", " {\n", " \"role\": \"developer\",\n", " \"content\": (\n", " \"Conversation has been summarised to control context window usage.\\n\\n\"\n", " f\"Full transcript path: {transcript_path}\\n\"\n", " f\"Summary path: {summary_path}\\n\\n\"\n", " \"Summary:\\n\"\n", " f\"{summary}\\n\\n\"\n", " \"If you need details, use tail_file/read_file_range first, then read_file.\"\n", " ),\n", " },\n", " {\"role\": \"user\", \"content\": user_text},\n", " ]\n", "\n", " # Run agent (tool outputs logged by callback)\n", " state = fs_agent.invoke(\n", " {\"messages\": messages},\n", " config={\"callbacks\": [tool_logger]},\n", " )\n", "\n", " messages = state.get(\"messages\", messages)\n", "\n", " # append assistant message to transcript\n", " last = messages[-1]\n", " assistant_text = last.get(\"content\") if isinstance(last, dict) else getattr(last, \"content\", str(last))\n", " conversation_to_file.invoke({\n", " \"run_id\": run_id,\n", " \"messages\": [{\"role\": \"assistant\", \"content\": str(assistant_text), \"ts\": _ts_utc()}],\n", " })\n", "\n", " print(f\"\\nFSAgent: {assistant_text}\\n\")\n" ] }, { "cell_type": "code", "execution_count": 22, "id": "chat_benchmark_func_001", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[OK] chat_benchmark() defined\n" ] } ], "source": [ "# Benchmark version of chat() - non-interactive with auto-summarization\n", "import time\n", "from typing import Tuple\n", "\n", "def chat_benchmark(\n", " run_id: str,\n", " query: str,\n", " messages: List[Any] = None,\n", " max_context_tokens: int = 128_000,\n", " threshold: float = 0.80,\n", " auto_summarize: bool = True,\n", ") -> Tuple[str, float, bool, List[Any]]:\n", " \"\"\"\n", " Non-interactive benchmark version of chat() with auto-summarization.\n", " Returns: (response_text, latency_ms, success, updated_messages)\n", " \"\"\"\n", " start_time = time.perf_counter()\n", " model_name = os.getenv(\"OPENAI_MODEL\", \"gpt-4o-mini\")\n", " tool_logger = EpisodicToolLogger(run_id=run_id, episodic_dir=\"episodic\")\n", " \n", " if messages is None:\n", " messages = []\n", " \n", " try:\n", " conversation_to_file.invoke({\n", " \"run_id\": run_id,\n", " \"messages\": [{\"role\": \"user\", \"content\": query, \"ts\": _ts_utc()}],\n", " })\n", " messages.append({\"role\": \"user\", \"content\": query})\n", " \n", " status = monitor_context_window.invoke({\n", " \"messages\": normalize_messages(messages),\n", " \"model_name\": model_name,\n", " \"max_context_tokens\": max_context_tokens,\n", " })\n", " \n", " if auto_summarize and status[\"utilization_ratio\"] >= threshold:\n", " print(f\" [SUMMARIZING] Context at {status['utilization_ratio']:.1%}\")\n", " pack = summarise_conversation_to_file.invoke({\"run_id\": run_id, \"messages\": []})\n", " messages = [\n", " {\"role\": \"developer\", \"content\": f\"Summary: {pack['summary']}\"},\n", " {\"role\": \"user\", \"content\": query},\n", " ]\n", " \n", " state = fs_agent.invoke({\"messages\": messages}, config={\"callbacks\": [tool_logger]})\n", " messages = state.get(\"messages\", messages)\n", " \n", " last = messages[-1]\n", " assistant_text = last.get(\"content\") if isinstance(last, dict) else getattr(last, \"content\", str(last))\n", " \n", " conversation_to_file.invoke({\n", " \"run_id\": run_id,\n", " \"messages\": [{\"role\": \"assistant\", \"content\": str(assistant_text), \"ts\": _ts_utc()}],\n", " })\n", " \n", " latency_ms = (time.perf_counter() - start_time) * 1000\n", " return str(assistant_text), latency_ms, True, messages\n", " \n", " except Exception as e:\n", " latency_ms = (time.perf_counter() - start_time) * 1000\n", " return f\"Error: {str(e)}\", latency_ms, False, messages\n", "\n", "print(\"[OK] chat_benchmark() defined\")" ] }, { "cell_type": "code", "execution_count": 23, "id": "9133fe96", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "FSAgent chat started. Type 'exit' to stop.\n", "\n", "\n", "Saved conversation transcript.\n" ] } ], "source": [ "chat(run_id=\"fsagent_session_0010\", max_context_tokens=128_000, threshold=0.80)\n" ] }, { "cell_type": "markdown", "id": "zue8wp7wr8", "metadata": {}, "source": [ "> 💡 **Key Takeaways**\n", "> - The system prompt should explain the memory architecture so the agent uses tools appropriately\n", "> - Persist every turn immediately—don't batch writes that could be lost on crash\n", "> - Session IDs (`run_id`) enable resuming conversations across restarts" ] }, { "cell_type": "markdown", "id": "9ff1210e", "metadata": {}, "source": [ "# Part 2: MemAgent (Database backed Agent)" ] }, { "cell_type": "markdown", "id": "5sbh2ap9noi", "metadata": {}, "source": [ "## What You Will Learn\n", "\n", "This section demonstrates how to build a **database-backed research agent** using Oracle AI Database for persistent, queryable memory. By the end of Part 2, you will understand:\n", "\n", "### Architecture Overview\n", "\n", "The MemAgent uses two types of database storage:\n", "- **SQL Tables** - Structured storage for conversation history and tool logs\n", "- **Vector Stores** - Embedding-based storage for semantic search over the knowledge base\n", "\n", "### Step-by-Step Implementation\n", "\n", "**2.1 Setting Up Oracle AI Database**\n", "- Launch Oracle Database in a Docker container with vector search extensions\n", "- Establish a connection pool with retry logic for reliability\n", "- Configure the database user and permissions for vector operations\n", "\n", "**2.2 Creating Data Stores with LangChain and Oracle AI Database**\n", "\n", " **2.2.1 Conversational Memory Table**\n", " - Design a SQL schema for storing chat history (thread_id, role, content, timestamp)\n", " - Implement thread-based isolation for multi-user/multi-session support\n", " - Create a tool logging table to track agent actions for debugging\n", "\n", " **2.2.2 Vector Stores with Hybrid Search**\n", " - Initialize `OracleVS` vector store with HuggingFace embeddings\n", " - Configure HNSW indexes for fast approximate nearest neighbor search\n", " - Enable hybrid search combining vector similarity with keyword filtering\n", "\n", "**2.3 Memory Manager**\n", "- Build the `MemoryManager` class that abstracts all database operations\n", "- Implement `write_conversational_history()` for persisting chat turns\n", "- Implement `load_conversational_history()` for retrieving thread context\n", "- Implement `write_knowledge_base()` and `read_knowledge_base()` for semantic memory\n", "\n", "**2.4 Creating The Agent**\n", "- Create standalone tool wrappers that delegate to the MemoryManager\n", "- Build `fetch_and_save_paper_to_kb_db()` to chunk and embed papers\n", "- Configure the LangChain agent with database-aware tools\n", "- Implement the chat loop with automatic history loading and persistence\n", "\n", "### MemAgent Tools\n", "\n", "| Tool | What it does | Storage |\n", "|---|---|---|\n", "| **arxiv_search_candidates(query, k)** | Searches arXiv for candidate papers | None (API call) |\n", "| **fetch_and_save_paper_to_kb_db(arxiv_id)** | Fetches paper, chunks text, and stores embeddings in vector store | Vector store |\n", "| **search_knowledge_base(query, k)** | Semantic search over stored papers using vector similarity | Vector store |\n", "| **store_to_knowledge_base(text, metadata)** | Manually store text with metadata in the knowledge base | Vector store |\n", "\n", "### Key Differences from FSAgent\n", "\n", "| Aspect | FSAgent (Filesystem) | MemAgent (Database) |\n", "|--------|---------------------|---------------------|\n", "| **Search** | Keyword/grep-based | Vector similarity (semantic) |\n", "| **Persistence** | Markdown files | SQL tables + vector indexes |\n", "| **Scalability** | Directory traversal | Indexed queries |\n", "| **Query Language** | File paths + regex | SQL + vector similarity |\n", "| **Setup Complexity** | None (filesystem) | Requires database server |" ] }, { "cell_type": "markdown", "id": "42b2ed0b", "metadata": {}, "source": [ "## 2.1 Setting Up Oracle AI Database\n", "\n", "Before running the setup code, ensure you have Docker installed and pull the Oracle Free container image with vector search capabilities. This image includes Oracle AI Database Free with built-in vector operations.\n", "\n", "```bash\n", "docker pull ghcr.io/gvenzl/oracle-free:23.26.0\n", "docker run -d --name oracle-free -p 1521:1521 -p 5500:5500 -e ORACLE_PASSWORD='YourStrongPassword' ghcr.io/gvenzl/oracle-free:23.26.0\n", "docker logs -f oracle-free\n", "```\n", "\n", "First-time startup may take a few minutes as Oracle initializes the database files. Once ready, the code below will establish a connection to the running container." ] }, { "cell_type": "code", "execution_count": 24, "id": "5295913c", "metadata": {}, "outputs": [], "source": [ "import subprocess, time\n", "import oracledb\n", "\n", "IMAGE = \"ghcr.io/gvenzl/oracle-free:23.26.0\"\n", "CONTAINER = \"oracle-free\"\n", "PDB = \"FREEPDB1\"\n", "PORT = 1521\n", "\n", "def sh(*cmd, check=True, capture=True, text=True):\n", " return subprocess.run(cmd, check=check, capture_output=capture, text=text)\n", "\n", "def ensure_running(container=CONTAINER, image=IMAGE, oracle_pwd=None):\n", " # Docker reachable?\n", " sh(\"docker\", \"info\")\n", "\n", " # Container exists?\n", " r = sh(\"docker\", \"ps\", \"-a\", \"--filter\", f\"name=^{container}$\", \"--format\", \"{{.Names}}\", check=False)\n", " if r.stdout.strip() == container:\n", " r2 = sh(\"docker\", \"inspect\", \"-f\", \"{{.State.Running}}\", container, check=False)\n", " if r2.stdout.strip().lower() != \"true\":\n", " sh(\"docker\", \"start\", container)\n", " return\n", "\n", " # Otherwise create it (minimal, safe defaults)\n", " if not oracle_pwd:\n", " raise ValueError(\"Set oracle_pwd (SYS/SYSTEM password) to create a fresh container.\")\n", " sh(\n", " \"docker\", \"run\", \"-d\",\n", " \"--name\", container,\n", " \"-p\", f\"{PORT}:1521\",\n", " \"-p\", \"5500:5500\",\n", " \"--shm-size=1g\",\n", " \"-e\", f\"ORACLE_PASSWORD={oracle_pwd}\",\n", " image\n", " )\n", "\n", "def wait_ready(container=CONTAINER, pdb=PDB, timeout_s=600):\n", " \"\"\"Deterministic readiness check: instance OPEN + PDB READ WRITE.\"\"\"\n", " deadline = time.time() + timeout_s\n", " cmd = (\n", " \"export ORACLE_SID=FREE; \"\n", " \"sqlplus -s / as sysdba <<'SQL'\\n\"\n", " \"set heading off feedback off pages 0 verify off echo off\\n\"\n", " \"select status from v$instance;\\n\"\n", " f\"select open_mode from v$pdbs where name='{pdb}';\\n\"\n", " \"exit\\n\"\n", " \"SQL\"\n", " )\n", " while time.time() < deadline:\n", " r = sh(\"docker\", \"exec\", container, \"bash\", \"-lc\", cmd, check=False)\n", " out = (r.stdout or \"\").upper()\n", " if \"OPEN\" in out and \"READ WRITE\" in out:\n", " return\n", " time.sleep(3)\n", " raise TimeoutError(f\"DB not ready after {timeout_s}s. Try: docker logs -f {container}\")\n", "\n", "def get_vector_memory_size(container=CONTAINER) -> int:\n", " \"\"\"Return vector_memory_size in bytes (0 if unset).\"\"\"\n", " cmd = (\n", " \"export ORACLE_SID=FREE; \"\n", " \"sqlplus -s / as sysdba <<'SQL'\\n\"\n", " \"set heading off feedback off pages 0 verify off echo off\\n\"\n", " \"select value from v$parameter where name='vector_memory_size';\\n\"\n", " \"exit\\n\"\n", " \"SQL\"\n", " )\n", " r = sh(\"docker\", \"exec\", container, \"bash\", \"-lc\", cmd, check=False)\n", " raw = (r.stdout or \"\").strip()\n", " # sqlplus output can include blank lines; grab the last numeric token\n", " tokens = [t for t in raw.split() if t.isdigit()]\n", " return int(tokens[-1]) if tokens else 0\n", "\n", "def configure_vector_memory(container=CONTAINER, size=\"1G\", timeout_s=600):\n", " \"\"\"\n", " Ensure Vector Pool is enabled for HNSW/ANN operations by setting VECTOR_MEMORY_SIZE\n", " (SPFILE) and restarting the DB if needed.\n", "\n", " size: e.g. \"512M\", \"1G\"\n", " \"\"\"\n", " current = get_vector_memory_size(container)\n", " if current and current > 0:\n", " return False # no restart needed\n", "\n", " sql = f\"\"\"\n", "alter system set vector_memory_size={size} scope=spfile sid='*';\n", "shutdown immediate;\n", "startup;\n", "\"\"\"\n", " sh(\"docker\", \"exec\", container, \"bash\", \"-lc\", f\"export ORACLE_SID=FREE; sqlplus -s / as sysdba <<'SQL'\\n{sql}\\nSQL\")\n", " wait_ready(container=container, pdb=PDB, timeout_s=timeout_s)\n", " return True # restart happened\n", "\n", "def create_vector_user(container=CONTAINER, vector_pwd=\"VectorPwd_2025\"):\n", " sql = f\"\"\"\n", "ALTER SESSION SET CONTAINER = {PDB};\n", "BEGIN\n", " EXECUTE IMMEDIATE 'CREATE USER VECTOR IDENTIFIED BY \"{vector_pwd}\"';\n", "EXCEPTION\n", " WHEN OTHERS THEN\n", " IF SQLCODE != -01920 AND SQLCODE != -01921 AND SQLCODE != -01918 AND SQLCODE != -00955 THEN\n", " RAISE;\n", " END IF;\n", "END;\n", "/\n", "GRANT CREATE SESSION, CREATE TABLE, CREATE SEQUENCE, CREATE VIEW TO VECTOR;\n", "GRANT UNLIMITED TABLESPACE TO VECTOR;\n", "\"\"\"\n", " sh(\"docker\", \"exec\", container, \"bash\", \"-lc\",\n", " f'export ORACLE_SID=FREE; echo \"{sql}\" | sqlplus -s / as sysdba')\n", "\n", "def test_connection(vector_pwd=\"VectorPwd_2025\"):\n", " conn = oracledb.connect(user=\"VECTOR\", password=vector_pwd, dsn=f\"127.0.0.1:{PORT}/{PDB}\")\n", " with conn.cursor() as cur:\n", " cur.execute(\"select sys_context('userenv','con_name') from dual\")\n", " con_name = cur.fetchone()[0]\n", " conn.close()\n", " return con_name\n", "\n", "def setup(oracle_pwd=None, vector_pwd=\"VectorPwd_2025\", vector_memory_size=\"1G\"):\n", " ensure_running(oracle_pwd=oracle_pwd)\n", " wait_ready()\n", "\n", " restarted = configure_vector_memory(size=vector_memory_size)\n", " if restarted:\n", " print(f\"🧠 Enabled Vector Pool (VECTOR_MEMORY_SIZE={vector_memory_size}) and restarted DB\")\n", "\n", " create_vector_user(vector_pwd=vector_pwd)\n", " con_name = test_connection(vector_pwd=vector_pwd)\n", " print(f\"✅ Ready. Connected as VECTOR to container: {con_name}\")\n", " print(f\"DSN: 127.0.0.1:{PORT}/{PDB}\")\n" ] }, { "cell_type": "code", "execution_count": 25, "id": "2545ab7d", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "✅ Ready. Connected as VECTOR to container: FREEPDB1\n", "DSN: 127.0.0.1:1521/FREEPDB1\n" ] } ], "source": [ "setup(oracle_pwd=\"YourStrongPassword\", vector_pwd=\"VectorPwd_2025\", vector_memory_size=\"1G\")" ] }, { "cell_type": "code", "execution_count": null, "id": "a0309392", "metadata": {}, "outputs": [], "source": [ "def connect_oracle(user, password, dsn=\"127.0.0.1:1521/FREEPDB1\", program=\"devrel.content.filesystem_vs_dbs):\n", " return oracledb.connect(user=user, password=password, dsn=dsn, program=program)" ] }, { "cell_type": "code", "execution_count": 27, "id": "2878113f", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Using user: VECTOR\n" ] } ], "source": [ "database_connection = connect_oracle(\n", " user=\"VECTOR\",\n", " password=\"VectorPwd_2025\",\n", " dsn=\"127.0.0.1:1521/FREEPDB1\",\n", " program=\"devrel.content.filesystem_vs_dbs\",\n", ")\n", "\n", "print(\"Using user:\", database_connection.username)" ] }, { "cell_type": "markdown", "id": "8usa2j2vxzb", "metadata": {}, "source": [ "> 💡 **Key Takeaways**\n", "> - Use Docker for reproducible Oracle setup—no local installation required\n", "> - Connection pooling with retry logic handles transient startup delays\n", "> - Oracle 23ai Free includes vector operations at no cost for development" ] }, { "cell_type": "markdown", "id": "c50d241e", "metadata": {}, "source": [ "## 2.2 Creating Data Stores with LangChain and Oracle AI Database\n", "\n", "With the database running, we now create the storage infrastructure. Oracle AI Database supports both traditional SQL tables and vector stores, allowing us to use the right tool for each memory type. We'll initialize the embedding model first, then set up structured tables for conversation history and a vector store for semantic knowledge retrieval." ] }, { "cell_type": "code", "execution_count": 28, "id": "f3bfcd4e", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "/var/folders/8r/qvgk1jk97zdc9z1jjtdhm_440000gn/T/ipykernel_76924/2603100073.py:4: LangChainDeprecationWarning: The class `HuggingFaceEmbeddings` was deprecated in LangChain 0.2.2 and will be removed in 1.0. An updated version of the class exists in the `langchain-huggingface package and should be used instead. To use it run `pip install -U `langchain-huggingface` and import as `from `langchain_huggingface import HuggingFaceEmbeddings``.\n", " embedding_model = HuggingFaceEmbeddings(\n" ] } ], "source": [ "from langchain_community.embeddings import HuggingFaceEmbeddings\n", "\n", "# Initialize the embedding model\n", "embedding_model = HuggingFaceEmbeddings(\n", " model_name=\"sentence-transformers/paraphrase-mpnet-base-v2\"\n", ")" ] }, { "cell_type": "code", "execution_count": 29, "id": "a7839ae1", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " - LOGS_MEMORY (not exists)\n" ] } ], "source": [ "from langchain_oracledb.vectorstores import OracleVS\n", "from langchain_oracledb.vectorstores.oraclevs import create_index\n", "from langchain_community.vectorstores.utils import DistanceStrategy\n", "\n", "# Table names for each memory type\n", "CONVERSATIONAL_TABLE = \"CONVERSATIONAL_MEMORY\" # Episodic memory\n", "KNOWLEDGE_BASE_TABLE = \"SEMANTIC_MEMORY\" # Semantic memory\n", "LOGS_TABLE = \"LOGS_MEMORY\" # Episodic memory\n", "SUMMARY_TABLE = \"SUMMARY_MEMORY\" # Episodic memory\n", "\n", "ALL_TABLES = [\n", " CONVERSATIONAL_TABLE, \n", " KNOWLEDGE_BASE_TABLE, \n", " LOGS_TABLE, \n", " SUMMARY_TABLE]\n", "\n", "# Drop existing tables to start fresh\n", "for table in ALL_TABLES:\n", " try:\n", " with database_connection.cursor() as cur:\n", " cur.execute(f\"DROP TABLE {table} PURGE\")\n", " except Exception as e:\n", " if \"ORA-00942\" in str(e):\n", " print(f\" - {table} (not exists)\")\n", " else:\n", " print(f\" [FAIL] {table}: {e}\")\n", " \n", "database_connection.commit()" ] }, { "cell_type": "markdown", "id": "dydh6b6y5ac", "metadata": {}, "source": [ "> 💡 **Key Takeaways**\n", "> - Choose storage type based on query pattern: SQL for exact lookups, vectors for semantic search\n", "> - Initialize embeddings once and reuse—model loading is expensive\n", "> - LangChain's Oracle integration handles connection and transaction management" ] }, { "cell_type": "markdown", "id": "60cf2215", "metadata": {}, "source": [ "### 2.2.1 Create conversational memory table\n", "\n", "Conversation history requires structured storage with fast lookups by thread ID. We create a SQL table with columns for thread identification, role (user/assistant), message content, and timestamps. A separate tool logging table tracks every tool invocation, enabling debugging and analysis of agent behavior." ] }, { "cell_type": "code", "execution_count": 30, "id": "db8f67c4", "metadata": {}, "outputs": [], "source": [ "from typing import Sequence, Tuple, Optional\n", "\n", "ColumnSpec = Tuple[str, str]\n", "IndexSpec = Tuple[str, Sequence[str]]\n", "\n", "def create_table(\n", " conn,\n", " table_name: str,\n", " columns: Sequence[ColumnSpec],\n", " indexes: Optional[Sequence[IndexSpec]] = None,\n", " drop_if_exists: bool = True,\n", ") -> str:\n", " \"\"\"\n", " Generic Oracle table creator with optional indexes.\n", "\n", " Args:\n", " conn: Oracle DB connection (python-oracledb)\n", " table_name: Table name (optionally schema-qualified)\n", " columns: List of (column_name, sql_type_and_constraints)\n", " e.g. (\"id\", \"VARCHAR2(32) DEFAULT SYS_GUID() PRIMARY KEY\")\n", " indexes: List of (index_suffix, [columns...])\n", " Index name will be: idx__\n", " drop_if_exists: Drop table first (best-effort)\n", "\n", " Returns:\n", " table_name\n", " \"\"\"\n", " if not columns:\n", " raise ValueError(\"columns must be non-empty\")\n", "\n", " with conn.cursor() as cur:\n", " if drop_if_exists:\n", " try:\n", " cur.execute(f\"DROP TABLE {table_name} PURGE\")\n", " except Exception:\n", " pass\n", "\n", " ddl_cols = \",\\n \".join(\n", " f\"{col_name} {col_def}\" for col_name, col_def in columns\n", " )\n", "\n", " cur.execute(f\"\"\"\n", " CREATE TABLE {table_name} (\n", " {ddl_cols}\n", " )\n", " \"\"\")\n", "\n", " if indexes:\n", " for suffix, cols in indexes:\n", " if not cols:\n", " continue\n", " idx_name = f\"idx_{table_name.lower()}_{suffix}\".replace(\".\", \"_\")\n", " col_list = \", \".join(cols)\n", " cur.execute(f\"CREATE INDEX {idx_name} ON {table_name}({col_list})\")\n", "\n", " conn.commit()\n", " print(f\"Table {table_name} created successfully\" + (f\" with {len(indexes)} indexes\" if indexes else \"\"))\n", " return table_name\n" ] }, { "cell_type": "code", "execution_count": 31, "id": "754a62c1", "metadata": {}, "outputs": [], "source": [ "def create_conversational_history_table(conn, table_name: str = \"CONVERSATIONAL_MEMORY\"):\n", " columns = [\n", " (\"id\", \"VARCHAR2(32) DEFAULT RAWTOHEX(SYS_GUID()) PRIMARY KEY\"),\n", " (\"thread_id\", \"VARCHAR2(100) NOT NULL\"),\n", " (\"role\", \"VARCHAR2(50) NOT NULL\"),\n", " (\"content\", \"CLOB NOT NULL\"),\n", " (\"timestamp\", \"TIMESTAMP DEFAULT CURRENT_TIMESTAMP\"),\n", " (\"metadata\", \"CLOB\"),\n", " (\"created_at\", \"TIMESTAMP DEFAULT CURRENT_TIMESTAMP\"),\n", " (\"summary_id\", \"VARCHAR2(100) DEFAULT NULL\"),\n", " ]\n", " indexes = [\n", " (\"thread_id\", [\"thread_id\"]),\n", " (\"timestamp\", [\"timestamp\"]),\n", " ]\n", " return create_table(conn, table_name, columns, indexes)\n" ] }, { "cell_type": "code", "execution_count": 32, "id": "82c96fd7", "metadata": {}, "outputs": [], "source": [ "def create_tool_log_table(conn, table_name: str = \"TOOL_LOGS\"):\n", " columns = [\n", " (\"id\", \"VARCHAR2(32) DEFAULT RAWTOHEX(SYS_GUID()) PRIMARY KEY\"),\n", " (\"run_id\", \"VARCHAR2(100) NOT NULL\"),\n", " (\"tool_name\", \"VARCHAR2(200) NOT NULL\"),\n", " (\"input\", \"CLOB\"),\n", " (\"output\", \"CLOB\"),\n", " (\"status\", \"VARCHAR2(30)\"),\n", " (\"error\", \"CLOB\"),\n", " (\"ts_utc\", \"TIMESTAMP DEFAULT CURRENT_TIMESTAMP\"),\n", " (\"metadata\", \"CLOB\"),\n", " ]\n", " indexes = [\n", " (\"run_id\", [\"run_id\"]),\n", " (\"tool_name\", [\"tool_name\"]),\n", " (\"ts_utc\", [\"ts_utc\"]),\n", " ]\n", " return create_table(conn, table_name, columns, indexes)\n" ] }, { "cell_type": "code", "execution_count": 33, "id": "19df1abe", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Table CONVERSATIONAL_MEMORY created successfully with 2 indexes\n", "Table TOOL_LOGS created successfully with 3 indexes\n" ] } ], "source": [ "CONVERSATION_HISTORY_TABLE = create_conversational_history_table(database_connection)\n", "TOOL_LOG_TABLE = create_tool_log_table(database_connection)" ] }, { "cell_type": "markdown", "id": "8v93qkozp4", "metadata": {}, "source": [ "> 💡 **Key Takeaways**\n", "> - Thread-based isolation (`thread_id`) enables multi-user and multi-session support\n", "> - Tool logging creates an audit trail for debugging agent behavior\n", "> - Use CLOB type for content columns—VARCHAR2 has a 4000-byte limit" ] }, { "cell_type": "markdown", "id": "81ff7a8e", "metadata": {}, "source": [ "### 2.2.2 Create Vector Stores with Hybrid Search Capabilities\n", "\n", "Unlike conversation history, the knowledge base benefits from semantic search—finding relevant content based on meaning rather than exact keywords. We use LangChain's `OracleVS` to create a vector store backed by Oracle's native vector operations. HNSW (Hierarchical Navigable Small World) indexes enable fast approximate nearest neighbor search at scale." ] }, { "cell_type": "code", "execution_count": 34, "id": "9c941b36", "metadata": {}, "outputs": [], "source": [ "knowledge_base_vs = OracleVS(\n", " client=database_connection,\n", " embedding_function=embedding_model,\n", " table_name=KNOWLEDGE_BASE_TABLE,\n", " distance_strategy=DistanceStrategy.COSINE,\n", ")\n", "\n", "summary_vs = OracleVS(\n", " client=database_connection,\n", " embedding_function=embedding_model,\n", " table_name=SUMMARY_TABLE,\n", " distance_strategy=DistanceStrategy.COSINE,\n", ")" ] }, { "cell_type": "code", "execution_count": 35, "id": "b1daa7f1", "metadata": {}, "outputs": [], "source": [ "def safe_create_index(conn, vs, idx_name):\n", " \"\"\"Create index, skipping if it already exists.\"\"\"\n", " try:\n", " create_index(\n", " client=conn,\n", " vector_store=vs,\n", " params={\"idx_name\": idx_name, \"idx_type\": \"HNSW\"}\n", " )\n", " print(f\" Created index: {idx_name}\")\n", " except Exception as e:\n", " if \"ORA-00955\" in str(e):\n", " print(f\" [SKIP] Index already exists: {idx_name}\")\n", " else:\n", " raise" ] }, { "cell_type": "code", "execution_count": 36, "id": "7906f6fb", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Creating vector indexes...\n", " Created index: kb_hnsw_cosine_idx\n", " Created index: summary_hnsw_cosine_idx\n", "All indexes created!\n" ] } ], "source": [ "print(\"Creating vector indexes...\")\n", "safe_create_index(database_connection, knowledge_base_vs, \"kb_hnsw_cosine_idx\")\n", "safe_create_index(database_connection, summary_vs, \"summary_hnsw_cosine_idx\")\n", "print(\"All indexes created!\")" ] }, { "cell_type": "markdown", "id": "gvfsy0sszar", "metadata": {}, "source": [ "> 💡 **Key Takeaways**\n", "> - HNSW indexes trade perfect accuracy for dramatically faster search at scale\n", "> - Create indexes after bulk loading data—index maintenance slows inserts\n", "> - Vector similarity finds semantically related content even with different wording" ] }, { "cell_type": "markdown", "id": "ba8efed7", "metadata": {}, "source": [ "## 2.3 Memory Manager\n", "\n", "The `MemoryManager` class encapsulates all database operations behind a clean interface. It handles the complexity of SQL queries, vector similarity search, and connection management so the agent tools can remain simple. This abstraction also makes it easy to swap storage backends without changing tool implementations." ] }, { "cell_type": "code", "execution_count": 37, "id": "20bef4ef", "metadata": {}, "outputs": [], "source": [ "from langchain.tools import tool\n", "from typing import List, Dict\n", "\n", "class MemoryManager:\n", " \"\"\"\n", " A simplified memory manager for AI agents using Oracle AI Database.\n", " \n", " Manages 5 types of memory:\n", " - Conversational: Chat history per thread (SQL table)\n", " - Knowledge Base: Searchable documents (Vector store)\n", " - Workflow: Execution patterns (Vector store)\n", " - Toolbox: Available tools (Vector store)\n", " - Entity: People, places, systems (Vector store)\n", " - Summary: Storing compressed context window\n", " \"\"\"\n", "\n", " def __init__(self, conn, conversation_table: str, knowledge_base_vs, summary_vs, tool_log_table):\n", " self.conn = conn\n", " self.conversation_table = conversation_table\n", " self.knowledge_base_vs = knowledge_base_vs\n", " self.summary_vs = summary_vs\n", " self.tool_log_table = tool_log_table\n", " \n", " # ==================== CONVERSATIONAL MEMORY (SQL) ====================\n", " \n", " def write_conversational_memory(self, content: str, role: str, thread_id: str) -> str:\n", " \"\"\"Store a message in conversation history.\"\"\"\n", " thread_id = str(thread_id)\n", " with self.conn.cursor() as cur:\n", " id_var = cur.var(str)\n", " cur.execute(f\"\"\"\n", " INSERT INTO {self.conversation_table} (thread_id, role, content, metadata, timestamp)\n", " VALUES (:thread_id, :role, :content, :metadata, CURRENT_TIMESTAMP)\n", " RETURNING id INTO :id\n", " \"\"\", {\"thread_id\": thread_id, \"role\": role, \"content\": content, \"metadata\": \"{}\", \"id\": id_var})\n", " record_id = id_var.getvalue()[0] if id_var.getvalue() else None\n", " self.conn.commit()\n", " return record_id\n", " \n", " def load_conversational_history(self, thread_id: str, limit: int = 50) -> List[Dict[str, str]]:\n", " \"\"\"Load conversation history for a thread as a list of message dicts.\"\"\"\n", " thread_id = str(thread_id)\n", " with self.conn.cursor() as cur:\n", " cur.execute(f\"\"\"\n", " SELECT role, content FROM {self.conversation_table}\n", " WHERE thread_id = :thread_id AND summary_id IS NULL\n", " ORDER BY timestamp ASC\n", " FETCH FIRST :limit ROWS ONLY\n", " \"\"\", {\"thread_id\": thread_id, \"limit\": limit})\n", " results = cur.fetchall()\n", " \n", " return [{\"role\": str(role), \"content\": content.read() if hasattr(content, 'read') else str(content)} for role, content in results]\n", " \n", " def mark_as_summarized(self, thread_id: str, summary_id: str):\n", " \"\"\"Mark all unsummarized messages in a thread as summarized.\"\"\"\n", " thread_id = str(thread_id)\n", " with self.conn.cursor() as cur:\n", " cur.execute(f\"\"\"\n", " UPDATE {self.conversation_table}\n", " SET summary_id = :summary_id\n", " WHERE thread_id = :thread_id AND summary_id IS NULL\n", " \"\"\", {\"summary_id\": summary_id, \"thread_id\": thread_id})\n", " self.conn.commit()\n", " print(f\" Marked messages as summarized (summary_id: {summary_id})\")\n", " \n", " # ==================== KNOWLEDGE BASE (Vector Store) ====================\n", " \n", " def write_knowledge_base(self, text: str, metadata_json: str = \"{}\"):\n", " \"\"\"Store text in knowledge base with metadata (metadata_json should be a JSON string).\"\"\"\n", " metadata = json.loads(metadata_json)\n", " self.knowledge_base_vs.add_texts([text], [metadata])\n", "\n", " \n", " def read_knowledge_base(self, query: str, k: int = 5) -> str:\n", " \"\"\"Search knowledge base for relevant content.\"\"\"\n", " results = self.knowledge_base_vs.similarity_search(query, k=k)\n", " content = \"\\n\".join([doc.page_content for doc in results])\n", " return f\"\"\"## Knowledge Base Memory: This are general information that is relevant to the question\n", "### How to use: Use the knowledge base as background information that can help answer the question\n", "\n", "{content}\"\"\"\n", "\n", " #==================== TOOL LOG ====================\n", "\n", " @tool\n", " def write_tool_log(self, tool_name: str, input: str, output: str, status: str, error: str, metadata: dict):\n", " \"\"\"Store a tool call in the tool log.\"\"\"\n", " thread_id = str(thread_id)\n", " with self.conn.cursor() as cur:\n", " id_var = cur.var(str)\n", " cur.execute(f\"\"\"\n", " INSERT INTO {self.tool_log_table}\n", " VALUES (:tool_name, :input, :output, :status, :error, :metadata)\n", " RETURNING id INTO :id\n", " \"\"\", {\"tool_name\": tool_name, \"input\": input, \"output\": output, \"status\": status, \"error\": error, \"metadata\": \"{}\", \"id\": id_var})\n", " record_id = id_var.getvalue()[0] if id_var.getvalue() else None\n", " self.conn.commit()\n", " return record_id\n", " \n", " \n", " # ==================== SUMMARY (Vector Store) ====================\n", " \n", " def write_summary(self, summary_id: str, full_content: str, summary: str, description: str):\n", " \"\"\"Store a summary with its original content.\"\"\"\n", " self.summary_vs.add_texts(\n", " [f\"{summary_id}: {description}\"],\n", " [{\"id\": summary_id, \"full_content\": full_content, \"summary\": summary, \"description\": description}]\n", " )\n", " return summary_id\n", " \n", " def read_summary_memory(self, summary_id: str) -> str:\n", " \"\"\"Retrieve a specific summary by ID (just-in-time retrieval).\"\"\"\n", " results = self.summary_vs.similarity_search(\n", " summary_id, \n", " k=5, \n", " filter={\"id\": summary_id}\n", " )\n", " if not results:\n", " return f\"Summary {summary_id} not found.\"\n", " doc = results[0]\n", " return doc.metadata.get('summary', 'No summary content.')\n", " \n", " def read_summary_context(self, query: str = \"\", k: int = 5) -> str:\n", " \"\"\"Get available summaries for context window (IDs + descriptions only).\"\"\"\n", " results = self.summary_vs.similarity_search(query or \"summary\", k=k)\n", " if not results:\n", " return \"## Summary Memory\\nNo summaries available.\"\n", " \n", " lines = [\"## Summary Memory\", \"Use expand_summary(id) to get full content:\"]\n", " for doc in results:\n", " sid = doc.metadata.get('id', '?')\n", " desc = doc.metadata.get('description', 'No description')\n", " lines.append(f\" - [ID: {sid}] {desc}\")\n", " return \"\\n\".join(lines)" ] }, { "cell_type": "code", "execution_count": 38, "id": "b9a90b59", "metadata": {}, "outputs": [], "source": [ "memory_manager = MemoryManager(\n", " conn=database_connection,\n", " conversation_table=CONVERSATION_HISTORY_TABLE, \n", " knowledge_base_vs=knowledge_base_vs,\n", " tool_log_table=TOOL_LOG_TABLE,\n", " summary_vs=summary_vs\n", ")" ] }, { "cell_type": "code", "execution_count": 39, "id": "clear_tables_util_001", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[OK] clear_all_tables() defined\n" ] } ], "source": [ "# Utility: Clear all tables\n", "def clear_all_tables(conn, confirm: bool = True) -> dict:\n", " \"\"\"Clear all MemAgent tables without dropping them.\"\"\"\n", " tables = [CONVERSATION_HISTORY_TABLE, TOOL_LOG_TABLE, KNOWLEDGE_BASE_TABLE, SUMMARY_TABLE]\n", " results = {}\n", " if confirm:\n", " print(\"Tables to clear:\")\n", " for t in tables:\n", " try:\n", " with conn.cursor() as cur:\n", " cur.execute(f\"SELECT COUNT(*) FROM {t}\")\n", " print(f\" - {t}: {cur.fetchone()[0]} rows\")\n", " except: pass\n", " for t in tables:\n", " try:\n", " with conn.cursor() as cur:\n", " cur.execute(f\"SELECT COUNT(*) FROM {t}\")\n", " count = cur.fetchone()[0]\n", " cur.execute(f\"DELETE FROM {t}\")\n", " conn.commit()\n", " results[t] = count\n", " print(f\"[OK] Cleared {t}: {count} rows\")\n", " except Exception as e:\n", " results[t] = f\"ERROR: {e}\"\n", " return results\n", "\n", "print(\"[OK] clear_all_tables() defined\")" ] }, { "cell_type": "code", "execution_count": 40, "id": "6560e630", "metadata": {}, "outputs": [], "source": [ "from datetime import datetime, timezone\n", "from langchain_core.tools import tool\n", "from langchain_community.document_loaders import ArxivLoader\n", "from langchain_text_splitters import RecursiveCharacterTextSplitter\n", "\n", "@tool\n", "def fetch_and_save_paper_to_kb_db(\n", " arxiv_id: str,\n", " chunk_size: int = 1500,\n", " chunk_overlap: int = 200,\n", ") -> str:\n", " \"\"\"\n", " Fetch full arXiv paper text (PDF -> text) and store it into the OracleVS\n", " knowledge base table as chunked records (avoids routing full content via the LLM).\n", "\n", " Writes to: KNOWLEDGE_BASE_TABLE (via knowledge_base_vs.add_texts)\n", " \"\"\"\n", "\n", " # 1) Load full paper text from arXiv (PDF -> text)\n", " loader = ArxivLoader(\n", " query=arxiv_id,\n", " load_max_docs=1,\n", " doc_content_chars_max=None, # \"no truncation\" in current LangChain docs :contentReference[oaicite:1]{index=1}\n", " )\n", " docs = loader.load()\n", " if not docs:\n", " return f\"No documents found for arXiv id: {arxiv_id}\"\n", "\n", " doc = docs[0]\n", "\n", " title = (\n", " doc.metadata.get(\"Title\")\n", " or doc.metadata.get(\"title\")\n", " or f\"arXiv {arxiv_id}\"\n", " )\n", "\n", " # Normalize common arxiv metadata keys\n", " entry_id = doc.metadata.get(\"Entry ID\") or doc.metadata.get(\"entry_id\") or \"\"\n", " published = doc.metadata.get(\"Published\") or doc.metadata.get(\"published\") or \"\"\n", " authors = doc.metadata.get(\"Authors\") or doc.metadata.get(\"authors\") or \"\"\n", "\n", " full_text = doc.page_content or \"\"\n", " if not full_text.strip():\n", " return f\"Loaded arXiv {arxiv_id} but extracted empty text (PDF parsing issue).\"\n", "\n", " # 2) Chunk (important: embeddings have input limits; chunking prevents failures/truncation)\n", " splitter = RecursiveCharacterTextSplitter(\n", " chunk_size=chunk_size,\n", " chunk_overlap=chunk_overlap,\n", " )\n", " chunks = splitter.split_text(full_text)\n", "\n", " # 3) Store chunks into OracleVS (vector store table)\n", " ts_utc = datetime.now(timezone.utc).isoformat()\n", " metadatas = []\n", " for i in range(len(chunks)):\n", " metadatas.append(\n", " {\n", " \"source\": \"arxiv\",\n", " \"arxiv_id\": arxiv_id,\n", " \"title\": title,\n", " \"entry_id\": entry_id,\n", " \"published\": str(published),\n", " \"authors\": str(authors),\n", " \"chunk_id\": i,\n", " \"num_chunks\": len(chunks),\n", " \"ingested_ts_utc\": ts_utc,\n", " }\n", " )\n", "\n", " # OracleVS typically supports add_texts(texts, metadatas)\n", " knowledge_base_vs.add_texts(chunks, metadatas)\n", "\n", " return (\n", " f\"Saved arXiv {arxiv_id} to {KNOWLEDGE_BASE_TABLE}: \"\n", " f\"{len(chunks)} chunks (title: {title}).\"\n", " )\n" ] }, { "cell_type": "markdown", "id": "fstfats02", "metadata": {}, "source": [ "> 💡 **Key Takeaways**\n", "> - Encapsulate database logic in a manager class—tools should be thin wrappers\n", "> - Handle Oracle LOB objects with `.read()` before returning content as strings\n", "> - The manager pattern makes it easy to mock storage for testing" ] }, { "cell_type": "markdown", "id": "58d7861d", "metadata": {}, "source": [ "## 2.4 Creating The Agent\n", "\n", "With the memory infrastructure in place, we assemble the MemAgent. This involves creating standalone tool wrapper functions (since `@tool` cannot decorate class methods), building a paper ingestion tool that chunks and embeds documents, and configuring the chat loop to automatically load conversation history at startup." ] }, { "cell_type": "code", "execution_count": 41, "id": "32be09a1", "metadata": {}, "outputs": [], "source": [ "# Initialize the agent\n", "\n", "import os\n", "from langchain.agents import create_agent\n", "from langchain.tools import tool\n", "\n", "@tool\n", "def search_knowledge_base(query: str, k: int = 5) -> str:\n", " \"\"\"Search knowledge base for relevant content.\"\"\"\n", " return memory_manager.read_knowledge_base(query, k)\n", "\n", "@tool \n", "def store_to_knowledge_base(text: str, metadata_json: str = \"{}\") -> str:\n", " \"\"\"Store text in knowledge base with metadata (metadata_json should be a JSON string).\"\"\"\n", " memory_manager.write_knowledge_base(text, metadata_json)\n", " return f\"Successfully stored text to knowledge base.\"\n", "\n", "MEM_AGENT = create_agent(\n", " model=f\"openai:{os.getenv('OPENAI_MODEL', 'gpt-4o-mini')}\",\n", " tools=[search_knowledge_base, store_to_knowledge_base, arxiv_search_candidates, fetch_and_save_paper_to_kb_db],\n", ")" ] }, { "cell_type": "code", "execution_count": 42, "id": "2e1d72d5", "metadata": {}, "outputs": [], "source": [ "\n", "import os\n", "import json\n", "import uuid\n", "from datetime import datetime, timezone\n", "from typing import Any, Dict, List, Optional\n", "from langchain_openai import ChatOpenAI\n", "from langchain_core.callbacks import BaseCallbackHandler\n", "\n", "\n", "def _ts_utc() -> str:\n", " return datetime.now(timezone.utc).isoformat()\n", "\n", "\n", "def normalize_messages_any(messages: List[Any]) -> List[Dict[str, str]]:\n", " \"\"\"\n", " Convert LangChain message objects (or dicts) into [{'role','content'}] dicts.\n", " Includes tool messages too (role='tool') so context monitoring is accurate.\n", " \"\"\"\n", " out: List[Dict[str, str]] = []\n", " for m in messages:\n", " if isinstance(m, dict):\n", " out.append({\"role\": m.get(\"role\", \"unknown\"), \"content\": m.get(\"content\", \"\")})\n", " continue\n", "\n", " # LangChain BaseMessage-like\n", " msg_type = getattr(m, \"type\", None) or m.__class__.__name__.lower()\n", " content = getattr(m, \"content\", \"\")\n", "\n", " if msg_type in (\"human\", \"user\", \"humanmessage\"):\n", " role = \"user\"\n", " elif msg_type in (\"ai\", \"assistant\", \"aimessage\"):\n", " role = \"assistant\"\n", " elif msg_type in (\"system\", \"systemmessage\"):\n", " role = \"system\"\n", " elif msg_type in (\"tool\", \"toolmessage\"):\n", " role = \"tool\"\n", " else:\n", " role = msg_type # best effort\n", "\n", " out.append({\"role\": role, \"content\": content})\n", " return out\n", "\n", "\n", "def _extract_last_assistant_text(messages: List[Any]) -> str:\n", " \"\"\"Find the last assistant/AI message in a mixed message list.\"\"\"\n", " for m in reversed(messages):\n", " if isinstance(m, dict):\n", " if m.get(\"role\") in {\"assistant\", \"ai\"}:\n", " return str(m.get(\"content\", \"\"))\n", " continue\n", "\n", " msg_type = getattr(m, \"type\", None) or m.__class__.__name__.lower()\n", " if msg_type in {\"ai\", \"assistant\", \"aimessage\"}:\n", " return str(getattr(m, \"content\", \"\"))\n", " # fallback\n", " last = messages[-1] if messages else \"\"\n", " return str(last.get(\"content\")) if isinstance(last, dict) else str(getattr(last, \"content\", last))\n", "\n", "\n", "class DBToolLogger(BaseCallbackHandler):\n", " \"\"\"\n", " Logs tool calls to an Oracle table (TOOL_LOG_TABLE).\n", "\n", " Schema expected (matches your create_tool_log_table):\n", " (id, run_id, tool_name, input, output, status, error, ts_utc, metadata)\n", " \"\"\"\n", "\n", " def __init__(\n", " self,\n", " conn,\n", " tool_log_table: str,\n", " run_id: str,\n", " max_chars: int = 50_000,\n", " ):\n", " self.conn = conn\n", " self.table = tool_log_table\n", " self.run_id = run_id\n", " self.max_chars = max_chars\n", " self._pending: Dict[str, Dict[str, Any]] = {} # tool_run_id -> record\n", "\n", " def on_tool_start(self, serialized, input_str=None, **kwargs):\n", " tool_name = (serialized or {}).get(\"name\") or \"unknown_tool\"\n", " tool_run_id = kwargs.get(\"run_id\") or kwargs.get(\"tool_call_id\") or uuid.uuid4().hex\n", "\n", " self._pending[tool_run_id] = {\n", " \"tool_run_id\": tool_run_id,\n", " \"tool_name\": tool_name,\n", " \"input\": input_str,\n", " \"ts_utc\": _ts_utc(),\n", " }\n", "\n", " def on_tool_end(self, output, **kwargs):\n", " tool_run_id = kwargs.get(\"run_id\") or kwargs.get(\"tool_call_id\")\n", " rec = self._pending.pop(tool_run_id, None) or {\n", " \"tool_run_id\": tool_run_id or uuid.uuid4().hex,\n", " \"tool_name\": \"unknown_tool\",\n", " \"input\": None,\n", " \"ts_utc\": _ts_utc(),\n", " }\n", "\n", " # JSON-safe output + truncation\n", " try:\n", " out_obj = output if isinstance(output, (dict, list, str, int, float, bool)) else str(output)\n", " except Exception:\n", " out_obj = \"\"\n", "\n", " out_str = out_obj if isinstance(out_obj, str) else json.dumps(out_obj, ensure_ascii=False)\n", " if len(out_str) > self.max_chars:\n", " out_str = out_str[: self.max_chars] + \"\\n\\n[TRUNCATED]\"\n", "\n", " self._insert_tool_log(\n", " tool_name=rec[\"tool_name\"],\n", " input_text=rec.get(\"input\"),\n", " output_text=out_str,\n", " status=\"OK\",\n", " error_text=None,\n", " ts_utc=rec[\"ts_utc\"],\n", " metadata={\"tool_run_id\": str(rec[\"tool_run_id\"])},\n", " )\n", "\n", " def on_tool_error(self, error, **kwargs):\n", " tool_run_id = kwargs.get(\"run_id\") or kwargs.get(\"tool_call_id\")\n", " rec = self._pending.pop(tool_run_id, None) or {\n", " \"tool_run_id\": tool_run_id or uuid.uuid4().hex,\n", " \"tool_name\": \"unknown_tool\",\n", " \"input\": None,\n", " \"ts_utc\": _ts_utc(),\n", " }\n", "\n", " err_str = str(error)\n", " if len(err_str) > self.max_chars:\n", " err_str = err_str[: self.max_chars] + \"\\n\\n[TRUNCATED]\"\n", "\n", " self._insert_tool_log(\n", " tool_name=rec[\"tool_name\"],\n", " input_text=rec.get(\"input\"),\n", " output_text=None,\n", " status=\"ERROR\",\n", " error_text=err_str,\n", " ts_utc=rec[\"ts_utc\"],\n", " metadata={\"tool_run_id\": str(rec[\"tool_run_id\"])},\n", " )\n", "\n", " def _insert_tool_log(\n", " self,\n", " tool_name: str,\n", " input_text: Optional[str],\n", " output_text: Optional[str],\n", " status: str,\n", " error_text: Optional[str],\n", " ts_utc: str,\n", " metadata: Optional[dict] = None,\n", " ):\n", " meta_str = json.dumps(metadata or {}, ensure_ascii=False)\n", "\n", " with self.conn.cursor() as cur:\n", " cur.execute(\n", " f\"\"\"\n", " INSERT INTO {self.table}\n", " (run_id, tool_name, input, output, status, error, ts_utc, metadata)\n", " VALUES\n", " (:run_id, :tool_name, :input, :output, :status, :error, CURRENT_TIMESTAMP, :metadata)\n", " \"\"\",\n", " {\n", " \"run_id\": self.run_id,\n", " \"tool_name\": tool_name,\n", " \"input\": input_text,\n", " \"output\": output_text,\n", " \"status\": status,\n", " \"error\": error_text,\n", " \"metadata\": meta_str,\n", " },\n", " )\n", " self.conn.commit()\n", "\n", "\n", "def _summarise_working_context_to_db(\n", " thread_id: str,\n", " working_messages: List[Any],\n", " model_name: str,\n", ") -> Dict[str, str]:\n", " \"\"\"\n", " Summarise what the model has been seeing (working context),\n", " store the summary in SUMMARY_TABLE (via summary_vs), and mark\n", " unsummarised conversational rows with summary_id.\n", "\n", " Returns: {summary_id, summary}\n", " \"\"\"\n", " llm = ChatOpenAI(model=model_name, temperature=0)\n", "\n", " # Build a clean transcript view of the working context\n", " norm = normalize_messages_any(working_messages)\n", " transcript = \"\\n\".join(\n", " [f\"[{_ts_utc()}] {m['role'].upper()}: {m['content']}\" for m in norm if m.get(\"content\")]\n", " )\n", "\n", " prompt = (\n", " \"Summarise this conversation for future continuity.\\n\\n\"\n", " \"Requirements:\\n\"\n", " \"- Capture key facts, decisions, constraints.\\n\"\n", " \"- Capture open questions / next steps.\\n\"\n", " \"- Keep it concise (~200-400 words).\\n\"\n", " \"- Do NOT invent details.\\n\\n\"\n", " f\"Thread: {thread_id}\\n\\n\"\n", " \"Conversation:\\n\"\n", " f\"{transcript}\"\n", " )\n", "\n", " summary_text = llm.invoke(prompt).content\n", " summary_id = uuid.uuid4().hex\n", " description = f\"[thread:{thread_id}] conversation summary @ {_ts_utc()}\"\n", "\n", " # Store summary in vector store-backed summary memory\n", " memory_manager.write_summary(\n", " summary_id=summary_id,\n", " full_content=\"\", # full transcript already lives in CONVERSATIONAL_MEMORY\n", " summary=summary_text,\n", " description=description,\n", " )\n", "\n", " # Mark DB conversation rows as summarised (so load_conversational_history ignores them)\n", " memory_manager.mark_as_summarized(thread_id=thread_id, summary_id=summary_id)\n", "\n", " # Optional: record an explicit system event in conversation history\n", " memory_manager.write_conversational_memory(\n", " content=f\"Context summarised into summary_id={summary_id}.\",\n", " role=\"system\",\n", " thread_id=thread_id,\n", " )\n", "\n", " return {\"summary_id\": summary_id, \"summary\": summary_text}" ] }, { "cell_type": "markdown", "id": "46b92752", "metadata": {}, "source": [ "## 2.5 Run Agent" ] }, { "cell_type": "code", "execution_count": 43, "id": "3e9c08ef", "metadata": {}, "outputs": [], "source": [ "def chat_memagent(\n", " thread_id: str,\n", " max_context_tokens: int = 128_000,\n", " threshold: float = 0.80,\n", ") -> None:\n", " \"\"\"\n", " Conversational chat loop for MemAgent (DB-backed memory):\n", " - user + assistant messages persisted to CONVERSATIONAL_MEMORY\n", " - tool outputs logged to TOOL_LOG_TABLE via DBToolLogger\n", " - context monitoring every turn\n", " - auto-summarise at threshold, store summary to SUMMARY_TABLE and mark rows summarised\n", " - rotate working context to (summary + pointer) to keep token usage stable\n", " \"\"\"\n", " model_name = os.getenv(\"OPENAI_MODEL\", \"gpt-4o-mini\")\n", "\n", " tool_logger = DBToolLogger(\n", " conn=database_connection,\n", " tool_log_table=TOOL_LOG_TABLE,\n", " run_id=thread_id, # group tool logs by thread/run\n", " )\n", "\n", " # Working context that gets passed to the agent (may contain tool messages)\n", " # Load existing conversation history if any\n", " existing_history = memory_manager.load_conversational_history(thread_id, limit=50)\n", " messages: List[Any] = existing_history\n", "\n", " if messages:\n", " print(f\"Loaded {len(messages)} previous messages from thread '{thread_id}'.\\n\")\n", " \n", " print(\"MemAgent chat started. Type 'exit' to stop.\\n\")\n", "\n", " while True:\n", " user_text = input(\"You: \").strip()\n", " if user_text.lower() in {\"exit\", \"quit\"}:\n", " print(\"\\nDone (conversation is stored in the database).\")\n", " break\n", "\n", " # 1) Persist user message (DB transcript)\n", " memory_manager.write_conversational_memory(\n", " content=user_text,\n", " role=\"user\",\n", " thread_id=thread_id,\n", " )\n", "\n", " # 2) Add to working context\n", " messages.append({\"role\": \"user\", \"content\": user_text})\n", "\n", " # 3) Monitor context usage (includes tool messages if present)\n", " status = monitor_context_window.invoke(\n", " {\n", " \"messages\": normalize_messages_any(messages),\n", " \"model_name\": model_name,\n", " \"max_context_tokens\": max_context_tokens,\n", " }\n", " )\n", "\n", " # 4) Summarise + rotate at threshold\n", " if status[\"utilization_ratio\"] >= threshold:\n", " pack = _summarise_working_context_to_db(\n", " thread_id=thread_id,\n", " working_messages=messages,\n", " model_name=model_name,\n", " )\n", " summary_id = pack[\"summary_id\"]\n", " summary = pack[\"summary\"]\n", "\n", " # Rotate working context:\n", " # NOTE: this adds an extra system message AFTER the agent’s own system_prompt.\n", " # Keep it short + purely informational to avoid \"overriding\" behavior.\n", " messages = [\n", " {\n", " \"role\": \"system\",\n", " \"content\": (\n", " \"Working context was summarised to control context window usage.\\n\"\n", " f\"summary_id: {summary_id}\\n\\n\"\n", " \"Summary:\\n\"\n", " f\"{summary}\\n\\n\"\n", " \"If details are needed, ask to retrieve them from database memory.\"\n", " ),\n", " },\n", " {\"role\": \"user\", \"content\": user_text},\n", " ]\n", "\n", " # 5) Invoke agent (tools logged to DB via callback)\n", " state = MEM_AGENT.invoke(\n", " {\"messages\": messages},\n", " config={\"callbacks\": [tool_logger]},\n", " )\n", "\n", " # Keep returned messages (includes tool call/result messages if any)\n", " messages = state.get(\"messages\", messages)\n", "\n", " # 6) Persist assistant message (DB transcript)\n", " assistant_text = _extract_last_assistant_text(messages)\n", " memory_manager.write_conversational_memory(\n", " content=str(assistant_text),\n", " role=\"assistant\",\n", " thread_id=thread_id,\n", " )\n", "\n", " print(f\"\\nMemAgent: {assistant_text}\\n\")" ] }, { "cell_type": "code", "execution_count": 44, "id": "chat_memagent_benchmark_func_001", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[OK] chat_memagent_benchmark() defined\n" ] } ], "source": [ "# Benchmark version of chat_memagent() - non-interactive\n", "\n", "def chat_memagent_benchmark(\n", " thread_id: str,\n", " query: str,\n", " messages: List[Any] = None,\n", " max_context_tokens: int = 128_000,\n", " threshold: float = 0.80,\n", " auto_summarize: bool = True,\n", ") -> Tuple[str, float, bool, List[Any]]:\n", " \"\"\"\n", " Non-interactive benchmark version of chat_memagent().\n", " Returns: (response_text, latency_ms, success, updated_messages)\n", " \"\"\"\n", " start_time = time.perf_counter()\n", " model_name = os.getenv(\"OPENAI_MODEL\", \"gpt-4o-mini\")\n", " tool_logger = DBToolLogger(conn=database_connection, tool_log_table=TOOL_LOG_TABLE, run_id=thread_id)\n", " \n", " if messages is None:\n", " messages = memory_manager.load_conversational_history(thread_id, limit=50)\n", " \n", " try:\n", " memory_manager.write_conversational_memory(content=query, role=\"user\", thread_id=thread_id)\n", " messages.append({\"role\": \"user\", \"content\": query})\n", " \n", " status = monitor_context_window.invoke({\n", " \"messages\": normalize_messages_any(messages),\n", " \"model_name\": model_name,\n", " \"max_context_tokens\": max_context_tokens,\n", " })\n", " \n", " if auto_summarize and status[\"utilization_ratio\"] >= threshold:\n", " print(f\" [SUMMARIZING] Context at {status['utilization_ratio']:.1%}\")\n", " pack = _summarise_working_context_to_db(thread_id=thread_id, working_messages=messages, model_name=model_name)\n", " messages = [\n", " {\"role\": \"system\", \"content\": f\"Summary: {pack['summary']}\"},\n", " {\"role\": \"user\", \"content\": query},\n", " ]\n", " \n", " state = MEM_AGENT.invoke({\"messages\": messages}, config={\"callbacks\": [tool_logger]})\n", " messages = state.get(\"messages\", messages)\n", " \n", " assistant_text = _extract_last_assistant_text(messages)\n", " memory_manager.write_conversational_memory(content=str(assistant_text), role=\"assistant\", thread_id=thread_id)\n", " \n", " latency_ms = (time.perf_counter() - start_time) * 1000\n", " return str(assistant_text), latency_ms, True, messages\n", " \n", " except Exception as e:\n", " latency_ms = (time.perf_counter() - start_time) * 1000\n", " return f\"Error: {str(e)}\", latency_ms, False, messages\n", "\n", "print(\"[OK] chat_memagent_benchmark() defined\")" ] }, { "cell_type": "code", "execution_count": 45, "id": "92ff0603", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "MemAgent chat started. Type 'exit' to stop.\n", "\n", "\n", "Done (conversation is stored in the database).\n" ] } ], "source": [ "chat_memagent(thread_id=\"memagent_thread_0010\", max_context_tokens=128_000, threshold=0.80)\n" ] }, { "cell_type": "markdown", "id": "jwivgzie6tf", "metadata": {}, "source": [ "> 💡 **Key Takeaways**\n", "> - Never use `@tool` on class methods—create standalone wrapper functions instead\n", "> - Load conversation history at chat startup for seamless multi-session continuity\n", "> - Chunk large documents before embedding—embedding models have token limits" ] }, { "cell_type": "markdown", "id": "benchmark_header_001", "metadata": {}, "source": [ "# Part 3: Benchmarking FSAgent vs MemAgent\n", "\n", "This section compares the filesystem-based agent (FSAgent) against the database-backed agent (MemAgent) with **end-to-end agent execution tests**:\n", "\n", "1. **Search & Retrieve** - Agent searches for a paper and retrieves it\n", "2. **Question Answering** - Agent answers questions about retrieved content\n", "3. **Latency** - Time to complete full agent interactions\n", "4. **Accuracy** - Quality of retrieved information\n", "\n" ] }, { "cell_type": "markdown", "id": "1aff74e1", "metadata": {}, "source": [ "## 3.1 Benchmark Setup" ] }, { "cell_type": "code", "execution_count": 46, "id": "benchmark_setup_002", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[OK] Agent benchmark utilities loaded\n" ] } ], "source": [ "# Benchmark Setup for End-to-End Agent Testing\n", "import time\n", "import statistics\n", "import uuid\n", "from dataclasses import dataclass, field\n", "from typing import List, Dict, Any, Optional\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "\n", "@dataclass\n", "class AgentBenchmarkResult:\n", " \"\"\"Store results from an agent benchmark run.\"\"\"\n", " agent_type: str # \"fs\" or \"db\"\n", " task: str # \"search_paper\", \"ask_question\", etc.\n", " query: str\n", " response: str\n", " latency_ms: float\n", " success: bool\n", " expected_content: Optional[str] = None\n", " \n", " @property\n", " def contains_expected(self) -> bool:\n", " if not self.expected_content:\n", " return True\n", " return self.expected_content.lower() in self.response.lower()\n", "\n", "def run_agent_query(agent, query: str, thread_id: str, timeout: int = 120) -> tuple:\n", " \"\"\"\n", " Run a single query through an agent and measure latency.\n", " Returns: (response_text, latency_ms, success)\n", " \"\"\"\n", " start = time.perf_counter()\n", " try:\n", " state = agent.invoke(\n", " {\"messages\": [{\"role\": \"user\", \"content\": query}]},\n", " config={\"configurable\": {\"thread_id\": thread_id}}\n", " )\n", " messages = state.get(\"messages\", [])\n", " # Extract last assistant message\n", " response = \"\"\n", " for msg in reversed(messages):\n", " if hasattr(msg, 'content'):\n", " response = str(msg.content)\n", " break\n", " elif isinstance(msg, dict) and msg.get(\"role\") == \"assistant\":\n", " response = str(msg.get(\"content\", \"\"))\n", " break\n", " latency = (time.perf_counter() - start) * 1000\n", " return response, latency, True\n", " except Exception as e:\n", " latency = (time.perf_counter() - start) * 1000\n", " return f\"Error: {str(e)}\", latency, False\n", "\n", "benchmark_results: List[AgentBenchmarkResult] = []\n", "print(\"[OK] Agent benchmark utilities loaded\")" ] }, { "cell_type": "markdown", "id": "test_scenarios_header_003", "metadata": {}, "source": [ "## 3.2 Test Scenarios\n", "\n", "Define realistic test scenarios that exercise both agents:\n", "1. **Paper Search** - Find a specific paper by topic\n", "2. **Content Retrieval** - Get specific sections (abstract, conclusion)\n", "3. **Follow-up Questions** - Multi-turn conversation about the paper" ] }, { "cell_type": "code", "execution_count": 47, "id": "test_scenarios_004", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[OK] Test scenarios configured\n", " - Questions: 10\n", " - FS Thread: fs_benchmark_a84c312e\n", " - DB Thread: db_benchmark_cdf748fe\n" ] } ], "source": [ "# Test Scenarios for Benchmarking\n", "\n", "# Questions for testing agent knowledge retrieval\n", "TEST_QUESTIONS = [\n", " \"What is MemGPT and what problem does it solve?\",\n", " \"How does MemGPT handle the limited context window problem?\",\n", " \"Explain the memory hierarchy in MemGPT.\",\n", " \"What is virtual context management in MemGPT?\",\n", " \"How does MemGPT use function calls for memory operations?\",\n", " \"What are the main memory tiers in MemGPT's architecture?\",\n", " \"How does MemGPT compare to traditional operating system memory management?\",\n", " \"What use cases does MemGPT support, like document analysis or chat?\",\n", " \"How does MemGPT achieve the illusion of infinite context?\",\n", " \"What is the role of archival storage in MemGPT?\",\n", "]\n", "\n", "# Build TEST_SCENARIOS\n", "TEST_SCENARIOS = [\n", " {\n", " \"name\": \"Content Questions\",\n", " \"queries\": [\n", " {\n", " \"query\": query,\n", " \"task\": \"ask_question\",\n", " \"description\": f\"Q{i+1}\"\n", " }\n", " for i, query in enumerate(TEST_QUESTIONS)\n", " ]\n", " },\n", "]\n", "\n", "# Thread IDs for benchmarking\n", "FS_BENCHMARK_THREAD = f\"fs_benchmark_{uuid.uuid4().hex[:8]}\"\n", "DB_BENCHMARK_THREAD = f\"db_benchmark_{uuid.uuid4().hex[:8]}\"\n", "\n", "print(\"[OK] Test scenarios configured\")\n", "print(f\" - Questions: {len(TEST_QUESTIONS)}\")\n", "print(f\" - FS Thread: {FS_BENCHMARK_THREAD}\")\n", "print(f\" - DB Thread: {DB_BENCHMARK_THREAD}\")" ] }, { "cell_type": "code", "execution_count": 48, "id": "benchmark_data_setup_code", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "======================================================================\n", "LOADING TEST DATA: MemGPT Paper\n", "======================================================================\n", "\n", "[1/2] Loading for FSAgent...\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Failed to send compressed multipart ingest: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/multipart. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/multipart', '{\"error\":\"Unauthorized\"}\\n')trace=019c0bb2-b5ec-7b93-a29b-007fc87ef849,id=019c0bb2-b5ec-7b93-a29b-007fc87ef849\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " [OK] semantic/knowledge_base/2310.08560.md...\n", "\n", "[2/2] Loading for MemAgent...\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Failed to send compressed multipart ingest: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/multipart. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/multipart', '{\"error\":\"Unauthorized\"}\\n')trace=019c0bb2-b5ec-7b93-a29b-007fc87ef849,id=019c0bb2-b5ec-7b93-a29b-007fc87ef849; trace=019c0bb2-b877-7063-8d24-79d2921dcb51,id=019c0bb2-b877-7063-8d24-79d2921dcb51\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " [OK] Saved arXiv 2310.08560 to SEMANTIC_MEMORY: 42 chunks (title: MemGPT: Towards LLM...\n", "\n", "[OK] Test data loaded for both agents\n" ] } ], "source": [ "# Load MemGPT paper into both agents before benchmarking\n", "print(\"=\" * 70)\n", "print(\"LOADING TEST DATA: MemGPT Paper\")\n", "print(\"=\" * 70)\n", "\n", "MEMGPT_ARXIV_ID = \"2310.08560\"\n", "\n", "print(\"\\n[1/2] Loading for FSAgent...\")\n", "try:\n", " fs_load = fetch_and_save_paper.invoke({\"arxiv_id\": MEMGPT_ARXIV_ID})\n", " print(f\" [OK] {fs_load[:80]}...\")\n", "except Exception as e:\n", " print(f\" [ERROR] {e}\")\n", "\n", "print(\"\\n[2/2] Loading for MemAgent...\")\n", "try:\n", " db_load = fetch_and_save_paper_to_kb_db.invoke({\"arxiv_id\": MEMGPT_ARXIV_ID})\n", " print(f\" [OK] {db_load[:80]}...\")\n", "except Exception as e:\n", " print(f\" [ERROR] {e}\")\n", "\n", "print(\"\\n[OK] Test data loaded for both agents\")" ] }, { "cell_type": "markdown", "id": "fsagent_benchmark_header_005", "metadata": {}, "source": [ "## 3.3 Run FSAgent Benchmark\n", "\n", "Execute all test scenarios using the filesystem-based agent." ] }, { "cell_type": "code", "execution_count": null, "id": "fsagent_benchmark_006", "metadata": {}, "outputs": [], "source": [ "# Run FSAgent Benchmark\n", "print(\"=\" * 70)\n", "print(\"FSAGENT BENCHMARK\")\n", "print(\"=\" * 70)\n", "\n", "fs_results = []\n", "\n", "for scenario in TEST_SCENARIOS:\n", " print(f\"\\n[FS] Scenario: {scenario['name']}\")\n", " print(\"-\" * 50)\n", " \n", " for q in scenario[\"queries\"]:\n", " print(f\" Query: {q['query'][:60]}...\")\n", " \n", " response, latency, success = run_agent_query(\n", " agent=fs_agent,\n", " query=q[\"query\"],\n", " thread_id=FS_BENCHMARK_THREAD\n", " )\n", " \n", " result = AgentBenchmarkResult(\n", " agent_type=\"fs\",\n", " task=q[\"task\"],\n", " query=q[\"query\"],\n", " response=response[:500],\n", " latency_ms=latency,\n", " success=success,\n", " expected_content=None\n", " )\n", " fs_results.append(result)\n", " benchmark_results.append(result)\n", " \n", " status = \"[OK]\" if success else \"[FAIL]\"\n", " print(f\" {status} Latency: {latency:.0f}ms\")\n", "\n", "print(f\"\\n[OK] FSAgent benchmark complete: {len(fs_results)} queries\")" ] }, { "cell_type": "markdown", "id": "memagent_benchmark_header_007", "metadata": {}, "source": [ "## 3.4 Run MemAgent Benchmark\n", "\n", "Execute all test scenarios using the database-backed agent." ] }, { "cell_type": "code", "execution_count": null, "id": "memagent_benchmark_008", "metadata": {}, "outputs": [], "source": [ "# Run MemAgent Benchmark\n", "print(\"=\" * 70)\n", "print(\"MEMAGENT BENCHMARK\")\n", "print(\"=\" * 70)\n", "\n", "db_results = []\n", "\n", "for scenario in TEST_SCENARIOS:\n", " print(f\"\\n[DB] Scenario: {scenario['name']}\")\n", " print(\"-\" * 50)\n", " \n", " for q in scenario[\"queries\"]:\n", " print(f\" Query: {q['query'][:60]}...\")\n", " \n", " response, latency, success = run_agent_query(\n", " agent=MEM_AGENT,\n", " query=q[\"query\"],\n", " thread_id=DB_BENCHMARK_THREAD\n", " )\n", " \n", " result = AgentBenchmarkResult(\n", " agent_type=\"db\",\n", " task=q[\"task\"],\n", " query=q[\"query\"],\n", " response=response[:500],\n", " latency_ms=latency,\n", " success=success,\n", " expected_content=None\n", " )\n", " db_results.append(result)\n", " benchmark_results.append(result)\n", " \n", " status = \"[OK]\" if success else \"[FAIL]\"\n", " print(f\" {status} Latency: {latency:.0f}ms\")\n", "\n", "print(f\"\\n[OK] MemAgent benchmark complete: {len(db_results)} queries\")" ] }, { "cell_type": "markdown", "id": "results_analysis_header_009", "metadata": {}, "source": [ "## 3.5 Results Analysis\n", "\n", "Compare latency between both agents." ] }, { "cell_type": "code", "execution_count": 51, "id": "results_analysis_010", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "======================================================================\n", "BENCHMARK RESULTS ANALYSIS\n", "======================================================================\n", "\n", "[DEBUG] fs_results: 10, db_results: 10\n", "\n", "Task Agent Latency \n", "----------------------------------------\n", "Q&A FS 12980ms\n", " DB 8232ms\n", "\n", "TOTAL: FS=129799ms DB=82320ms\n" ] } ], "source": [ "# Results Analysis\n", "print(\"=\" * 70)\n", "print(\"BENCHMARK RESULTS ANALYSIS\")\n", "print(\"=\" * 70)\n", "\n", "print(f\"\\n[DEBUG] fs_results: {len(fs_results)}, db_results: {len(db_results)}\")\n", "\n", "tasks = [\"ask_question\"]\n", "task_labels = [\"Q&A\"]\n", "\n", "fs_latencies_by_task = {t: [] for t in tasks}\n", "db_latencies_by_task = {t: [] for t in tasks}\n", "\n", "for r in benchmark_results:\n", " if r.task not in tasks: continue\n", " if r.agent_type == \"fs\":\n", " fs_latencies_by_task[r.task].append(r.latency_ms)\n", " else:\n", " db_latencies_by_task[r.task].append(r.latency_ms)\n", "\n", "print(f\"\\n{'Task':<15} {'Agent':<10} {'Latency':<12}\")\n", "print(\"-\" * 40)\n", "for task, label in zip(tasks, task_labels):\n", " if fs_latencies_by_task[task]:\n", " lat = statistics.mean(fs_latencies_by_task[task])\n", " print(f\"{label:<15} {'FS':<10} {lat:>8.0f}ms\")\n", " if db_latencies_by_task[task]:\n", " lat = statistics.mean(db_latencies_by_task[task])\n", " print(f\"{'':<15} {'DB':<10} {lat:>8.0f}ms\")\n", "\n", "fs_total_latency = sum(r.latency_ms for r in benchmark_results if r.agent_type == 'fs' and r.task in tasks)\n", "db_total_latency = sum(r.latency_ms for r in benchmark_results if r.agent_type == 'db' and r.task in tasks)\n", "\n", "print(f\"\\nTOTAL: FS={fs_total_latency:.0f}ms DB={db_total_latency:.0f}ms\")" ] }, { "cell_type": "markdown", "id": "llm_judge_header_011", "metadata": {}, "source": [ "## 3.6 LLM-as-Judge Evaluation\n", "\n", "Use an LLM to evaluate the quality and relevance of each agent's responses on a scale of 0-100%." ] }, { "cell_type": "code", "execution_count": 52, "id": "llm_judge_function_012", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[OK] LLM Judge initialized\n" ] } ], "source": [ "# LLM-as-Judge with robust parsing\n", "from langchain_openai import ChatOpenAI\n", "import re\n", "\n", "judge_llm = ChatOpenAI(model=os.getenv(\"OPENAI_MODEL\", \"gpt-4o-mini\"), temperature=0)\n", "\n", "def llm_judge_response(query: str, response: str) -> dict:\n", " if not response or response.startswith(\"Error:\"):\n", " return {\"score\": 0, \"reasoning\": \"Empty/error response\"}\n", " \n", " prompt = f\"\"\"Score this AI response 0-100.\n", "\n", " Score criteria (use both):\n", " 1) Answer quality (0-60): how directly and completely the RESPONSE answers the QUERY, follows any constraints, and stays on-topic.\n", " 2) Accuracy (0-40): factual correctness, internal consistency, and no invented claims. Penalize confident speculation.\n", "\n", " Scoring guidance:\n", " - 90-100: fully answers + accurate + clear.\n", " - 70-89: mostly answers, minor gaps or minor inaccuracies.\n", " - 40-69: partially answers, significant gaps and/or questionable claims.\n", " - 0-39: largely wrong, irrelevant, or heavily hallucinated.\n", "\n", " QUERY: {query}\n", " RESPONSE: {response[:1500]}\n", "\n", " Reply exactly in this format (no extra text):\n", " SCORE: <0-100> REASONING: \"\"\"\n", "\n", " \n", " try:\n", " result = judge_llm.invoke(prompt)\n", " content = result.content\n", " match = re.search(r'SCORE[:\\s]*(\\d+)', content, re.IGNORECASE)\n", " score = float(match.group(1)) if match else 50\n", " score = max(0, min(100, score))\n", " r_match = re.search(r'REASONING[:\\s]*(.+)', content, re.IGNORECASE)\n", " reasoning = r_match.group(1).strip() if r_match else \"N/A\"\n", " return {\"score\": score, \"reasoning\": reasoning}\n", " except Exception as e:\n", " print(f\" [Judge Error] {e}\")\n", " return {\"score\": 50, \"reasoning\": str(e)}\n", "\n", "print(\"[OK] LLM Judge initialized\")" ] }, { "cell_type": "code", "execution_count": null, "id": "llm_judge_run_013", "metadata": {}, "outputs": [], "source": [ "# Run LLM Judge on all results (filtered to tasks we're analyzing)\n", "print(\"=\" * 70)\n", "print(\"LLM-AS-JUDGE EVALUATION\")\n", "print(\"=\" * 70)\n", "\n", "llm_judge_results = []\n", "\n", "# Filter to only tasks we're analyzing\n", "fs_to_judge = [r for r in fs_results if r.task in tasks]\n", "db_to_judge = [r for r in db_results if r.task in tasks]\n", "\n", "print(f\"\\n[LLM Judge] Evaluating {len(fs_to_judge)} FSAgent responses...\")\n", "for i, r in enumerate(fs_to_judge):\n", " print(f\" [{i+1}/{len(fs_to_judge)}] {r.query[:50]}...\")\n", " j = llm_judge_response(r.query, r.response)\n", " llm_judge_results.append({\"agent\": \"fs\", \"task\": r.task, \"query\": r.query, \"score\": j[\"score\"], \"reasoning\": j[\"reasoning\"]})\n", " print(f\" Score: {j['score']:.0f}%\")\n", "\n", "print(f\"\\n[LLM Judge] Evaluating {len(db_to_judge)} MemAgent responses...\")\n", "for i, r in enumerate(db_to_judge):\n", " print(f\" [{i+1}/{len(db_to_judge)}] {r.query[:50]}...\")\n", " j = llm_judge_response(r.query, r.response)\n", " llm_judge_results.append({\"agent\": \"db\", \"task\": r.task, \"query\": r.query, \"score\": j[\"score\"], \"reasoning\": j[\"reasoning\"]})\n", " print(f\" Score: {j['score']:.0f}%\")\n", "\n", "# Calculate averages\n", "fs_llm_scores = [r[\"score\"] for r in llm_judge_results if r[\"agent\"] == \"fs\"]\n", "db_llm_scores = [r[\"score\"] for r in llm_judge_results if r[\"agent\"] == \"db\"]\n", "\n", "fs_avg_llm = statistics.mean(fs_llm_scores) if fs_llm_scores else 0\n", "db_avg_llm = statistics.mean(db_llm_scores) if db_llm_scores else 0\n", "\n", "print(f\"\\n{'='*70}\")\n", "print(f\"LLM JUDGE SUMMARY: FSAgent={fs_avg_llm:.1f}% | MemAgent={db_avg_llm:.1f}%\")\n", "print(f\"Winner: {'FSAgent' if fs_avg_llm > db_avg_llm else 'MemAgent'}\")" ] }, { "cell_type": "markdown", "id": "visualization_header_014", "metadata": {}, "source": [ "## 3.7 Visualization" ] }, { "cell_type": "code", "execution_count": 54, "id": "visualization_015", "metadata": {}, "outputs": [ { "data": { "image/png": "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pWObHfu1WqKsU6dOJiHAE6PV3PVrtbyY61wXrs9F+67FihUzj9VSZI40KeHDDz+Up556yiQ7fPXVV/fdTgC+R8YtALjQIfbuhs737NnTlBrQQF/z5s1NVqkON5s+fbrpQGlHznEiLV2nkxdoJoBmgOqwfV20k6hDnLT+qn5jr1m4WitLg786+YDWH4sPrWGlNbK0Q64BSP12XbMg9DjXr183NXktGmTVIKoGXLXDqNkXcaXf6Ot10Y6gDrnTTrTW9n3zzTdNTS5Hem20hIF2QLXzqwHr+6XX/pNPPjETRei11euldcb0PI50mwbHy5UrZ6771q1bTVaD48RqjvS10lq/Wu5C26oB7bvVCwYAAPBFX9SyZs2aaF/YK500y10/RjNfdfSRp2h/Uuuvap9YJx7TPue0adNMv9dxci3N7tX+5tSpU02gt0qVKqbt7jJrtX1aCqtq1arSuXNn8+W89ln1+ezYscMpaKzZw5pxqvVo9TlrEoP2yzVwrBP7almyu9H9n3zySWnQoIHpV2rJAu1Hly5d2mk/HaGmbdB+rWYsawkuT/RrdV4GHR2m12T37t1mJJjrfBKaoKGlGfSaaMkGreGr10T72vqcXWmNXn0eek20vJhOtKZ9XACJmA0AYMyePVu/9o5xOX78uC0qKso2cuRIW/78+W1BQUG2smXL2lauXGlr06aNWedo48aNtnLlytlSp05tHj948GD7tr/++svWunVrW1hYmC1VqlS23Llz2xo3bmz74osvorVny5YtTsddt26dWa+3jr766itblSpVbGnSpLGFhITYHn30UdvChQujvbqbN282j69Xr16cX3l9funSpTPt1selTZvWliNHDvOcIiMj3T6mS5cu5jwLFiyI9zvs7Nmz0a7ZxYsXbW3btrVlzZrVlj59elv9+vVt+/fvN9dd22cZPny4ee6hoaHmWhQpUsQ2YsQI261bt6I9H0fnzp2zFStWzLwmBw8ejHebAQAAEroveuTIkVj3+eSTT8yxtH/UqFGjOJ3Pta/pau3atWa/pUuXOq3//vvvbSVKlDB93Ycfftj26aefmr6ba5jhxo0bth49etiyZMli+l9NmjQxz8W1r6fWrFlj+td6zAcffNA2c+ZM22uvvWYLDg6O1q4lS5bYqlWrZo6pi/b5unbtajtw4ECsz8dq4969e21PPfWULUOGDLZM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Xr16Jmt427Zt8t5778k777wjH374oUefDwAAABIHnYz37bffltSpUzutL1CggPz7778+axcAAACSj3gHbvv27WsCnWr37t3y2muvmUnJjhw5In369PFo4zZu3ChNmzaVRo0amU7yU089ZQKsmzdvtmfbTpgwwXSqdb9SpUrJvHnzTO2x5cuXm3004KvB5pkzZ0rFihWlWrVqJvC7aNEis5+aP3++3Lp1Sz7++GMpXry4qdPbo0cPGTdunEefDwAAABKHqKgoM/rL1T///GNKJgAAAAB+UePWkQZoixUrZn5esmSJNG7cWEaOHCnbt283AVxPqlKlisl6/fPPP80EaTt37jTZvlZAVdty6tQpUx7BkjFjRhOg3bRpkwnA6q2WR9ChbhbdPzAw0GTo6nA33ad69epOGRWatasZvppFnClTpmht09pmulisYLZ28nXxhgD5/5IRAOAptoAALiYAj/JW38iT59JkAU0QsEZgBQQEmFJbgwcP9nifFwAAAPBI4FaDm9evXzc///DDD9K6dWvzc+bMme3BS0954403zDGLFCkiKVKkMFkPI0aMMKUPlAZtVY4cOZwep/etbXqbPXt2p+0pU6Y07XXcR+vouh7D2uYucDtq1CgZMmRItPVnz551KtOQkAoFOdfpBQBPCM/r/HkIAPcr4MwZr13EK1eueOQ477//vpmcTBMWtG+nZcF0HoWsWbPKwoULPXIOAAAAwKOBWy01oCURqlatakoWfPbZZ2a9ZsXmyZNHPOnzzz83ZQwWLFhgShjs2LFDevXqJbly5ZI2bdqILw0YMMCpNIQGmHVSs2zZsplJ0LzhUIRn/jABAEehx49wQQB4lOuX6AlJJ5r1BO3X6Wgv7evqrWbb6gS3mkDgOFkZAAAA4DeBW50orEuXLvLFF1+YicNy585t1n/77bcmK8GTtJ6uZt1qyQNVsmRJOXr0qMl21cBtWFiYWX/69GnJmTOn/XF6XydMU7rPGZcsjzt37siFCxfsj9dbfYwj6761j6ugoCCzuNISDLp4g00YzgzA8wJslGEB4Fne6ht56ly3b982I750UlsN1FqjvQAAAAC/Dtzmy5fPdGJdjR8/XjxNSzK4dr61ZIJVu0zLG2hgdc2aNfZArWa+au3azp07m/uVK1eW8PBw2bZtm5QrV86sW7t2rTmG1sK19nnrrbdMJz1VqlRm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0KC6uyWalbQpsHvKxNgIA/7Nul19IRQh0cy6JSIiIiIiovyNgVsiIsrQrZA4/HktXE1/0tAZRkYFM9tWq3kpG1RysUBUvAZLz4boe3OIiIiIiIiInomBWyIiytCs44FI0kBl2tbwsCrwe0kCzx/Vd1bTv10Kg19Egr43iYiIiIiIiChTDNwSEVE6fz+OxqG7UZCStlLbtrBoUMwKtTwtEZeowc9ngvW9OURERERERESZYuCWiIh0aDQazDgWqKZfrWiPkkXMC80eUlm39ZID0ZuuhuN+WJy+N4mIiIiIiIgoQwzcEhGRjr23I3HRPxZWpkZ4/9+GXoVJTU8rvORtjUQNsOAUs26JiIiIiIgof2LgloiIUiQkajD7eJCafqu6I1ysTQvl3hn4b9btjpsRuBkUq+/NISIiIiIiIkqHgVsiIkqx4UoY7ofHw8nKBG/XKFJo90wFFwu0Km0LDYB5zLolIiIiIiKifIiBWyIiUiLjkrDodIia7l/HCTbmhfu/iA/rOsHYCDhwJxIX/WL0vTlEREREREREOgr3p3IiIsqy5edCEBKTCG8HM7xW0b7Q7zlputaxvJ2annsyuTwEERERERERUX7BwC0RESEwMgErz4eqPTGovjNMTYwMYq9IZrGpMXDiYTROPozS9+YQERERERERpWDgloiIsOB0MGISNKjmZoHmpWwMZo942ZmhayUHNT33RBA0Gql6S0RERERERKR/DNwSERm4OyFx2HQ1XE0PbugCIyPDyLbVerd2EViYGuGCfywO3WXWLREREREREeUPDNwSERm42SeCkKgBmpSwQS1PKxgaF2tT9KyanHU772QQkph1S0RERERERPkAA7dERAbsnG809t+JhLER8HEDZxiq3jWKwMbcGDeC47D7nwh9bw4RERERERERA7dERIZK6rlOPxakpl+pYI9SRcxhqBwsTdC7hqOann8qGAlJrHVLRERERERE+sWMWyIiA7XvdiQu+MXA0tQIH9R1gqHrWdURRSxNcC8sHluuP9H35hAREREREZGBY+CWiMgAJSRqVG1b0au6I1xtTGHopFTCO7WKqOmFp4MRm5Ck700iIiIiIiIiA8bALRGRAfr9arjKLHW0NFb1XSlZt8r2cLMxhV9EAjZcCeduISIiIiIiIr1h4JaIyMBExSepjFLxfh0n2JrzvwItC1Nj9K+THMhe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22zZssHPz0/+HKXdlz+FQiHHmYFb28fjbV94vO0Lj7f9SO9jbWkn+4mIiIiIbDJwW7t2bZw9e9bkuc6dO8s6tl999ZUMlDo6OmLnzp1o0aKFXH/58mXcunULFStWlI/F/ffffy8DwP7+/vI5kcErgquFChVKafPnn3+a7Ee0MW7jRdRqtbw9S3whYUAxbYkvfxxn+8HjbV94vO0Lj7f9SM9jzc9hRERERGQrLDpw6+bmhiJFipg85+LiAh8fn5Tnu3btKjNfvb29ZTD2iy++kAHXChUqyPV169aVAdr27dtj4sSJsp7t8OHD5YRnxsBrz549ZQbvkCFD0KVLF+zatQtr167FH3/8YYZXTURERERERERERPbOogO3b2Lq1Kkys0Jk3IrJwurVq4c5c+akrFepVNi8eTN69eolA7oi8NuxY0eMHj06pU2uXLlkkHbAgAGYPn06smbNioULF8ptEREREREREREREaU3hUHMFEHvTdS49fDwkJNvsMZt2tbJM5a94KWQto/H277weNsXHm/7kd7Hmp/JiIiIiMhWpP2nZyIiIiIiIiIiIiJ6KwzcEhEREREREREREVkYBm6JiIiIiIiIiIiILAwDt0REREREREREREQWhoFbIiIiIiIiIiIiIgvDwC0RERERERERERGRhXEwdwdshcFgkPcRERHm7opN0+v1iIyMhEajgVLJ8w62jsfbvvB42xceb/uR3sfa+FnM+NmMiIiIiMhaMXCbSsQXEiFbtmyptUkiIiIieo/PZh4eHhw/IiIiIrJaCgPTEVItm+TevXtwc3ODQqFInY3SC7NoRHD89u3bcHd35wjZOB5v+8LjbV94vO1Heh9r8dFWBG0zZ87Mq3OIiIiIyKox4zaViEv/smbNmlqbo9cQX/wYuLUfPN72hcfbvvB424/0PNbMtCUiIiIiW8AioUREREREREREREQWhoFbIiIiIiIiIiIiIgvDwC1ZFbVajW+//Vbek+3j8bYvPN72hcfbfvBYExERERG9G05ORkRERERERERERGRhmHFLREREREREREREZGEYuCUiIiIiIiIiIiKyMAzcEhEREREREREREVkYBm7JKowfPx5ly5aFm5sb/P390axZM1y+fNnc3aJ0MGHCBCgUCvTv35/jbaPu3r2LTz/9FD4+PtBqtShatCiOHz9u7m5RGkhKSsKIESOQK1cueazz5MmDMWPGwGAwcLxtwL59+9C4cWNkzpxZ/t3esGGDyXpxnEeOHIlMmTLJ4x8QEICrV6+arb9ERERERJaOgVuyCnv37kWfPn1w+PBhbN++HQkJCahbty6io6PN3TVKQ8eOHcOPP/6IYsWKcZxtVGhoKCpXrgxHR0f89ddfuHDhAiZPngwvLy9zd43SwA8//IC5c+di1qxZuHjxonw8ceJEzJw5k+NtA8T/5OLFi2P27NkvXC+O9YwZMzBv3jwcOXIELi4uqFevHmJjY9O9r0RERERE1kBhYJoLWaHg4GCZeSsCutWqVTN3dygNREVFoVSpUpgzZw7Gjh2LEiVKYNq0aRxrGzN06FAcOHAA+/fvN3dXKB18+OGHyJAhA3766aeU51q0aCGzL1esWMFjYENExu369evlFTKC+LgpMnEHDRqEwYMHy+fCw8Pl+2HJkiVo06aNmXtMRERERGR5mHFLVkl82RO8vb3N3RVKIyLDulGjRvJSWrJdmzZtQpkyZdCqVSt5MqZkyZJYsGCBubtFaaRSpUrYuXMnrly5Ih+fPn0af//9Nxo0aMAxt3E3btxAYGCgyd90Dw8PlC9fHocOHTJr34iIiIiILJWDuTtA9Lb0er2sdyoury5SpAgH0AatWbMGJ0+elKUSyLZdv35dXjo/cOBAfPPNN/KY9+3bF05OTujYsaO5u0dpkGEdERGBAgUKQKVSyZq333//Pdq1a8extnEiaCuIDNunicfGdUREREREZIqBW7LKTMxz587JLC2yPbdv30a/fv1kLWONRmPu7lA6nIgRGbfjxo2Tj0XGrfj9FjUwGbi1PWvXrsXKlSuxatUqFC5cGKdOnZIn4sQl9DzeREREREREplgqgazK559/js2bN2P37t3ImjWrubtDaeDEiRMICgqS9W0dHBzkTdQyFhPaiGWRoUe2Q8wuX6hQIZPnChYsiFu3bpmtT5R2vvzyS5l1K+qZFi1aFO3bt8eAAQMwfvx4DruNy5gxo7x/8OCByfPisXEdERERERGZYuCWrIKY1EQEbcVEJ7t27UKuXLnM3SVKI7Vr18bZs2dlJp7xJjIyxaXUYllcXk22Q5Q8uXz5sslzov5pjhw5zNYnSjsxMTFQKk0/eojfaZF5TbZN/N8WAVpR49hIlM04cuQIKlasaNa+ERERERFZKpZKIKspjyAurd24cSPc3NxS6uGJiU3EbORkO8TxfbZ2sYuLC3x8fFjT2AaJbEsxYZUoldC6dWscPXoU8+fPlzeyPY0bN5Y1bbNnzy5LJfzzzz+YMmUKunTpYu6uUSqIiorCtWvXTCYkEyfcxESi4piLshhjx47FBx98IAO5I0aMkGUymjVrxvEnIiIiInoBhUGkMhJZOIVC8cLnFy9ejE6dOqV7fyh91ahRAyVKlMC0adM49DZIlD/5+uuvcfXqVRnMEROVde/e3dzdojQQGRkpg3Xi6glREkUE7T755BOMHDlSTkhH1m3Pnj2oWbPmc8+L+sVLliyRV898++238sRMWFgYqlSpgjlz5iBfvnxm6S8RERERkaVj4JaIiIiIiIiIiIjIwrDGLREREREREREREZGFYeCWiIiIiIiIiIiIyMIwcEtERERERERERERkYRi4JSIiIiIiIiIiIrIwDNwSERERERERERERWRgGbomIiIiIiIiIiIgsDAO3RERERERERERERBaGgVsiIiIiIiIiIiIiC8PALREREREREREREZGFYeCWiMgK3L59G126dEHmzJnh5OSEHDlyoF+/fnj06BGsRZ8+ffDNN9/I5XHjxsnXQ0REREREREQvxsAtEZGFu379OsqUKYOrV69i9erVuHbtGubNm4edO3eiYsWKCAkJSdP9x8fHp8p2Dh06hMqVK8vl/fv3pywTERERERER0fMYuCUisoJMVZFlu23bNlSvXh3Zs2dHgwYNsGPHDty9exfDhg1LaatQKLBhwwaTn/f09MSSJUtMsndbt24tn/f29kbTpk1x8+bNlPWdOnVCs2bN8P3338sM3/z582P06NEoUqTIc30rUaIERowY8drXEB0djXPnzqFSpUrQ6/UmQVwiIiIiIiIieh4Dt0REFkxk027duhW9e/eGVqs1WZcxY0a0a9cOP//8MwwGwxttLyEhAfXq1YObm5vMej1w4ABcXV1Rv359k8xakc17+fJlbN++HZs3b5ZlDS5evIhjx46ltPnnn39w5swZdO7c+aX7E/0WAeJMmTLJfefKlQteXl4IDw9HhQoV5Lpbt26909gQERERERER2TIHc3eAiIheTpRHEEHZggULvnC9eD40NBTBwcHw9/d/7VCKIK/IeF24cKHMzhUWL14sA6h79uxB3bp15XMuLi6yjcj0NRIBX9G2bNmyKT8nMoBz58790v2JTN0hQ4Zg7Nix8vHw4cMxf/58XLp0CVOmTJHPiaxeIiIiIiIiIjLFjFsiIivwuozapwOsr3L69GlZI1dk3IpMW3ET5RJiY2Px77//prQrWrToc9vs3r27rLEr2ors3FWrVr12gjFfX1/kzJkTBw8exMcffyyXRdZu8+bN5bK4OTjwHCIRERERERHRs/htmYjIguXNm1dmxooyBR999NFz68Xzfn5+MmNWEG2fDfKKEgVGUVFRKF26NFauXPnctsR2jETG7bMaN24MtVqN9evXy6Cu2G7Lli1f2nexj88++yylxq2omyv6FxMTI0s09OzZEz/++KMs90BEREREREREphi4JSKyYD4+PqhTpw7mzJmDAQMGmNS5DQwMlMFRMXnZ08HX+/fvm5RaEIFSo1KlSslyCaKsgru7+1v1RWTGduzYUZZIEIHbNm3aPFd392lNmjRB+fLlsXHjRvz2229YunSpzLwVZRP+/PNP2SZDhgxv1QciIiIiIiIie8FSCUREFm7WrFmIi4uTNWb37duH27dvY8uWLTKgmy9fPowcOTKlba1atWR7MXHY8ePHZVaro6NjynqR3SrKFzRt2lROTnbjxg1Z27Zv3764c+fOa/vSrVs37Nq1S+7/dWUSRDkGkTEsgscBAQFy+ebNm6hZs6ZcFjfRhoiIiIiIiIiex8AtEZGF++CDD2RdWDEJWOvWrZEjRw40aNBABm1FyQFRp9Zo8uTJyJYtG6pWrYq2bdti8ODBcHZ2TlkvlkXwN3v27LLOrJjcrGvXrrJu7Ztk4Iq+VKpUCQUKFJDZtG9CBIarVasml/fu3ZuyTEREREREREQvpzC8bsYbIiKyON9++y2mTJmC7du3o0KFCum2X/EvQwRve/fujYEDB6bbfomIiIiIiIjsDWvcEhFZoVGjRiFnzpw4fPgwypUrB6Uy7S+gCA4Oxpo1a2Rt3c6dO6f5/oiIiIiIiIjsGTNuiYjozf5hKBSyPu706dNlGQYiIiIiIiIiSjvMuCUiojfCyjpERERERERE6YeTkxERERERERERERFZGAZuiYiIiIiIiIiIiCwMA7dEREREREREREREFoaBWyIiIiIiIiIiIiILw8AtERERERERERERkYVh4JaIiIiIiIiIiIjIwjBwS0RERERERERERGRhGLglIiIiIiIiIiIisjAM3BIRERERERERERHBsvwfuPHuEmWEZ6YAAAAASUVORK5CYII=", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "[OK] Chart saved\n" ] } ], "source": [ "# Visualization\n", "fig, axes = plt.subplots(2, 2, figsize=(14, 10))\n", "fig.suptitle(\"FSAgent vs MemAgent: End-to-End Benchmark\", fontsize=14, fontweight='bold')\n", "FS_COLOR, DB_COLOR = \"#3498db\", \"#e74c3c\"\n", "\n", "# 1. Latency by Task\n", "ax1 = axes[0, 0]\n", "x = np.arange(len(tasks))\n", "width = 0.35\n", "fs_lat = [statistics.mean(fs_latencies_by_task[t]) if fs_latencies_by_task[t] else 0 for t in tasks]\n", "db_lat = [statistics.mean(db_latencies_by_task[t]) if db_latencies_by_task[t] else 0 for t in tasks]\n", "bars1 = ax1.bar(x - width/2, fs_lat, width, label='FSAgent', color=FS_COLOR)\n", "bars2 = ax1.bar(x + width/2, db_lat, width, label='MemAgent', color=DB_COLOR)\n", "ax1.set_ylabel('Latency (ms)')\n", "ax1.set_title('Latency by Task')\n", "ax1.set_xticks(x)\n", "ax1.set_xticklabels(task_labels)\n", "ax1.legend()\n", "ax1.grid(axis='y', alpha=0.3)\n", "\n", "# 2. LLM Judge by Task (with value labels)\n", "ax2 = axes[0, 1]\n", "fs_llm_task = {t: [] for t in tasks}\n", "db_llm_task = {t: [] for t in tasks}\n", "if 'llm_judge_results' in dir():\n", " for r in llm_judge_results:\n", " if r[\"task\"] not in tasks: continue\n", " if r[\"agent\"] == \"fs\": fs_llm_task[r[\"task\"]].append(r[\"score\"])\n", " else: db_llm_task[r[\"task\"]].append(r[\"score\"])\n", "fs_llm_means = [statistics.mean(fs_llm_task[t]) if fs_llm_task[t] else 0 for t in tasks]\n", "db_llm_means = [statistics.mean(db_llm_task[t]) if db_llm_task[t] else 0 for t in tasks]\n", "bars1 = ax2.bar(x - width/2, fs_llm_means, width, label='FSAgent', color=FS_COLOR)\n", "bars2 = ax2.bar(x + width/2, db_llm_means, width, label='MemAgent', color=DB_COLOR)\n", "# Add value labels\n", "for bar, val in zip(bars1, fs_llm_means):\n", " ax2.annotate(f'{val:.0f}%', xy=(bar.get_x() + bar.get_width()/2, max(val, 5)),\n", " ha='center', va='bottom', fontsize=10, color=FS_COLOR)\n", "for bar, val in zip(bars2, db_llm_means):\n", " ax2.annotate(f'{val:.0f}%', xy=(bar.get_x() + bar.get_width()/2, max(val, 5)),\n", " ha='center', va='bottom', fontsize=10, color=DB_COLOR)\n", "ax2.set_ylabel('LLM Judge Score (%)')\n", "ax2.set_title('LLM Judge by Task')\n", "ax2.set_xticks(x)\n", "ax2.set_xticklabels(task_labels)\n", "ax2.set_ylim(0, 110)\n", "ax2.legend()\n", "ax2.grid(axis='y', alpha=0.3)\n", "\n", "# 3. Latency Timeline\n", "ax3 = axes[1, 0]\n", "fs_filtered = [r for r in fs_results if r.task in tasks]\n", "db_filtered = [r for r in db_results if r.task in tasks]\n", "if fs_filtered:\n", " ax3.plot(range(1, len(fs_filtered)+1), [r.latency_ms for r in fs_filtered], 'o-', color=FS_COLOR, label='FSAgent')\n", "if db_filtered:\n", " ax3.plot(range(1, len(db_filtered)+1), [r.latency_ms for r in db_filtered], 's-', color=DB_COLOR, label='MemAgent')\n", "ax3.set_xlabel('Query #')\n", "ax3.set_ylabel('Latency (ms)')\n", "ax3.set_title('Latency per Query')\n", "ax3.legend()\n", "ax3.grid(alpha=0.3)\n", "\n", "# 4. Overall Summary\n", "ax4 = axes[1, 1]\n", "ax4.axis('off')\n", "fs_llm = statistics.mean([r['score'] for r in llm_judge_results if r['agent']=='fs']) if 'llm_judge_results' in dir() and llm_judge_results else 0\n", "db_llm = statistics.mean([r['score'] for r in llm_judge_results if r['agent']=='db']) if 'llm_judge_results' in dir() and llm_judge_results else 0\n", "summary = f'''SUMMARY\n", "{'='*40}\n", "LATENCY (lower=better):\n", " FSAgent: {fs_total_latency:.0f}ms\n", " MemAgent: {db_total_latency:.0f}ms\n", "\n", "LLM JUDGE (higher=better):\n", " FSAgent: {fs_llm:.1f}%\n", " MemAgent: {db_llm:.1f}%\n", "{'='*40}'''\n", "ax4.text(0.1, 0.5, summary, transform=ax4.transAxes, fontsize=11,\n", " verticalalignment='center', fontfamily='monospace',\n", " bbox=dict(boxstyle='round', facecolor='wheat', alpha=0.5))\n", "ax4.set_title('Overall Summary')\n", "\n", "plt.tight_layout()\n", "plt.savefig('agent_benchmark_results.png', dpi=150)\n", "plt.show()\n", "print(\"[OK] Chart saved\")" ] }, { "cell_type": "markdown", "id": "conclusions_header_016", "metadata": {}, "source": [ "## 3.8 Conclusions" ] }, { "cell_type": "code", "execution_count": null, "id": "conclusions_017", "metadata": {}, "outputs": [], "source": [ "# Final Conclusions with LLM Judge\n", "print(\"=\" * 70)\n", "print(\"BENCHMARK CONCLUSIONS\")\n", "print(\"=\" * 70)\n", "\n", "latency_winner = \"FSAgent\" if fs_total_latency < db_total_latency else \"MemAgent\"\n", "llm_winner = \"FSAgent\" if fs_avg_llm > db_avg_llm else \"MemAgent\"\n", "fs_wins = [latency_winner, llm_winner].count(\"FSAgent\")\n", "overall = \"FSAgent\" if fs_wins >= 1 else \"MemAgent\"\n", "\n", "print(f\"\"\"\n", "RESULTS SUMMARY\n", "{'='*60}\n", "LATENCY: FSAgent={fs_total_latency:.0f}ms | MemAgent={db_total_latency:.0f}ms -> {latency_winner} (fast)\n", "LLM JUDGE: FSAgent={fs_avg_llm:.1f}% | MemAgent={db_avg_llm:.1f}% -> {llm_winner} [LLM Judge]\n", "{'='*60}\n", "OVERALL WINNER: {overall} (won {max(fs_wins, 2-fs_wins)}/2 categories)\n", "\n", "RECOMMENDATIONS:\n", "• FSAgent: Fast prototyping, simple search, local single-user\n", "• MemAgent: Semantic search, production use, better response quality\n", "\"\"\")" ] }, { "cell_type": "markdown", "id": "0ma2g1y7rfxk", "metadata": {}, "source": [ "## 3.9 Large Corpus Benchmark: Concatenated vs Chunked\n", "\n", "This benchmark tests how each agent handles a large corpus of research papers. We compare two approaches:\n", "\n", "- **FSAgent**: All 10 papers concatenated into a single large markdown file. The agent must use `grep_files` and `read_file_range` to find relevant sections.\n", "- **MemAgent**: Papers chunked and embedded into the vector store. The agent uses semantic similarity search to retrieve relevant chunks.\n", "\n", "This tests the trade-off between keyword-based search over large files vs. semantic search over chunked embeddings." ] }, { "cell_type": "code", "execution_count": null, "id": "r303sfa154b", "metadata": {}, "outputs": [], "source": [ "# 3.9.1 Prepare Large Corpus from ArXiv Papers (Full PDF Content)\n", "import time\n", "from pathlib import Path\n", "from langchain_community.document_loaders import ArxivLoader\n", "from langchain_text_splitters import RecursiveCharacterTextSplitter\n", "\n", "# 10 valid papers from the curated list (all confirmed to exist)\n", "CORPUS_ARXIV_IDS = [\n", " \"2310.08560\", # MemGPT: Towards LLMs as Operating Systems\n", " \"2303.11366\", # Reflexion: Language Agents with Verbal Reinforcement Learning\n", " \"2304.03442\", # Generative Agents: Interactive Simulacra of Human Behavior\n", " \"2404.13501\", # A Survey on the Memory Mechanism of LLM-Based Agents\n", " \"2410.10813\", # LongMemEval: Benchmarking Chat Assistants on Long-Term Memory\n", " \"2402.17753\", # LoCoMo: Evaluating Very Long-Term Conversational Memory\n", " \"2404.02039\", # A Survey on Large Language Model-Based Game Agents\n", " \"2411.08432\", # One STEP at a time: Language Agents are Stepwise Planners\n", " \"2309.02427\", # Cognitive Architectures for Language Agents (CoALA)\n", " \"2308.11432\", # AgentBench: Evaluating LLMs as Agents\n", " \"2505.16067\", # How Memory Management Impacts LLM Agents: An Empirical Study of Experience-Following Behavior\n", " \"2504.19413\", # Mem0: Building Production-Ready AI Agents with Scalable Long-Term Memory \n", "]\n", "\n", "# Fetch FULL papers (PDF -> text, not just abstracts)\n", "print(\"=\" * 70)\n", "print(\"FETCHING FULL PAPERS FOR LARGE CORPUS BENCHMARK\")\n", "print(\"=\" * 70)\n", "print(\"Note: Each paper downloads PDF and extracts text (~30-80K chars each)\")\n", "print()\n", "\n", "corpus_papers = []\n", "\n", "for arxiv_id in CORPUS_ARXIV_IDS:\n", " try:\n", " print(f\"[FETCH] {arxiv_id}...\", end=\" \", flush=True)\n", " \n", " # Use ArxivLoader with explicit settings to get full PDF content\n", " loader = ArxivLoader(\n", " query=arxiv_id,\n", " load_max_docs=1,\n", " load_all_available_meta=True,\n", " )\n", " docs = loader.load()\n", " \n", " if docs:\n", " content = docs[0].page_content\n", " char_count = len(content)\n", " \n", " # Check if we got full content (abstracts are typically <3000 chars)\n", " if char_count > 5000:\n", " corpus_papers.append({\n", " \"id\": arxiv_id,\n", " \"title\": docs[0].metadata.get(\"Title\", arxiv_id),\n", " \"content\": content\n", " })\n", " print(f\"[OK] {char_count:,} chars (full paper)\")\n", " else:\n", " print(f\"[WARN] Only {char_count:,} chars - may be abstract only\")\n", " # Still add it but warn\n", " corpus_papers.append({\n", " \"id\": arxiv_id,\n", " \"title\": docs[0].metadata.get(\"Title\", arxiv_id),\n", " \"content\": content\n", " })\n", " else:\n", " print(\"[SKIP] No documents returned\")\n", " \n", " time.sleep(3) # Rate limiting for PDF downloads\n", " \n", " except Exception as e:\n", " print(f\"[ERROR] {str(e)[:60]}\")\n", "\n", "total_chars = sum(len(p[\"content\"]) for p in corpus_papers)\n", "print(f\"\\n{'=' * 70}\")\n", "print(f\"Fetched {len(corpus_papers)} papers\")\n", "print(f\"Total corpus size: {total_chars:,} characters ({total_chars // 1000}K)\")\n", "if corpus_papers:\n", " print(f\"Average paper size: {total_chars // len(corpus_papers):,} chars\")\n", " if total_chars // len(corpus_papers) < 10000:\n", " print(\"[WARN] Average size is low - may only have abstracts. Check pymupdf installation.\")" ] }, { "cell_type": "code", "execution_count": 57, "id": "skd7m9xhyci", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[FS] Created concatenated corpus: semantic/knowledge_base/agent_memory_corpus.md\n", "[FS] Total size: 1,201,752 characters (1201K)\n", "\n", "[DB] Total chunks to embed: 928\n", "[DB] Adding to vector store... [OK]\n", "\n", "Corpus prepared for both agents:\n", " - FSAgent: 1 file with 12 papers (1,201,752 chars)\n", " - MemAgent: 928 chunks in vector store\n" ] } ], "source": [ "# 3.9.2 Prepare Corpus for Both Agents\n", "\n", "# === FSAgent: Concatenate all papers into one large markdown file ===\n", "corpus_dir = Path(\"semantic/knowledge_base\")\n", "corpus_dir.mkdir(parents=True, exist_ok=True)\n", "corpus_file = corpus_dir / \"agent_memory_corpus.md\"\n", "\n", "concatenated_content = []\n", "for paper in corpus_papers:\n", " concatenated_content.append(f\"\"\"\n", "{'='*80}\n", "# {paper['title']}\n", "ArXiv ID: {paper['id']}\n", "{'='*80}\n", "\n", "{paper['content']}\n", "\"\"\")\n", "\n", "corpus_file.write_text(\"\\n\\n\".join(concatenated_content), encoding=\"utf-8\")\n", "total_chars = len(corpus_file.read_text())\n", "print(f\"[FS] Created concatenated corpus: {corpus_file}\")\n", "print(f\"[FS] Total size: {total_chars:,} characters ({total_chars // 1000}K)\")\n", "\n", "# === MemAgent: Chunk and embed into vector store ===\n", "text_splitter = RecursiveCharacterTextSplitter(\n", " chunk_size=1500,\n", " chunk_overlap=200,\n", " separators=[\"\\n\\n\", \"\\n\", \". \", \" \", \"\"]\n", ")\n", "\n", "all_chunks = []\n", "all_metadatas = []\n", "\n", "for paper in corpus_papers:\n", " chunks = text_splitter.split_text(paper['content'])\n", " for i, chunk in enumerate(chunks):\n", " all_chunks.append(chunk)\n", " all_metadatas.append({\n", " \"arxiv_id\": paper['id'],\n", " \"title\": paper['title'],\n", " \"chunk_index\": i,\n", " \"source\": \"corpus_benchmark\"\n", " })\n", "\n", "print(f\"\\n[DB] Total chunks to embed: {len(all_chunks)}\")\n", "print(f\"[DB] Adding to vector store...\", end=\" \")\n", "\n", "# Add to knowledge base vector store\n", "knowledge_base_vs.add_texts(all_chunks, all_metadatas)\n", "print(\"[OK]\")\n", "\n", "print(f\"\\nCorpus prepared for both agents:\")\n", "print(f\" - FSAgent: 1 file with {len(corpus_papers)} papers ({total_chars:,} chars)\")\n", "print(f\" - MemAgent: {len(all_chunks)} chunks in vector store\")" ] }, { "cell_type": "code", "execution_count": 58, "id": "67wc7yiwhpg", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Defined 46 corpus benchmark queries\n" ] } ], "source": [ "# 3.9.3 Define Corpus Benchmark Queries\n", "\n", "CORPUS_QUERIES = [\n", " \"What is MemGPT and how does it manage context like an operating system?\",\n", " \"Explain the Reflexion framework and how verbal reinforcement learning works.\",\n", " \"How do generative agents simulate human behavior in sandbox environments?\",\n", " \"What are the different types of memory in LLM-based agents according to surveys?\",\n", " \"How is long-term conversational memory evaluated in benchmarks like LongMemEval?\",\n", " \"What techniques are used for memory compression in conversational agents?\",\n", " \"How do game-playing agents use memory to improve performance?\",\n", " \"What is stepwise planning and how does it relate to agent memory?\",\n", " \"Compare episodic and semantic memory in the context of LLM agents.\",\n", " \"What are the main challenges in building agents with persistent memory?\",\n", "\n", " # Added from the provided corpus (capability acquisition + applications)\n", " \"What are the trade-offs between fine-tuning and prompting/mechanism engineering for improving LLM-agent capabilities?\",\n", " \"Why is fine-tuning often only suitable for open-source LLMs, and what alternatives exist for closed-source models?\",\n", " \"How do LLM context window limitations constrain non–fine-tuned agent capability acquisition methods?\",\n", " \"What practical methods can teams use to search the large design space of prompts and agent mechanisms?\",\n", " \"In CLMTWA, how does a teacher LLM use theory of mind to generate explanations that improve a student model’s reasoning?\",\n", " \"What does it mean to personalize explanations for a student model, and what signals indicate personalization is needed?\",\n", " \"How can 'expected utility of intervention' be operationalized to decide when a teacher agent should intervene?\",\n", " \"What failure modes occur if a teacher agent intervenes too frequently or too rarely?\",\n", " \"In NLSOM-style systems, how do agents collaborate in natural language to solve problems beyond a single agent’s scope?\",\n", " \"What feedback signals should trigger dynamic adjustment of roles, tasks, and relationships in multi-agent collaboration?\",\n", " \"Operationally, what does an inter-agent 'relationship' represent (authority, trust, specialization, dependencies), and why does it matter?\",\n", " \"What risks arise from dynamic role assignment in multi-agent systems (oscillation, coordination overhead, accountability issues)?\",\n", " \"How would you compare teacher–student orchestration (CLMTWA) vs peer collaboration (NLSOM) in terms of reliability and scalability?\",\n", "\n", " # Social science applications\n", " \"Why are LLM-based agents useful for psychology simulation experiments, and what are the limitations compared to human studies?\",\n", " \"What is 'hyper-accuracy distortion' in psychology simulations, and how can it bias downstream applications?\",\n", " \"How would you design an evaluation to detect hyper-accuracy distortion in an LLM agent running psychology tasks?\",\n", " \"What are the benefits and risks of LLM conversation agents for mental well-being support, and what guardrails are required?\",\n", " \"In political science/economy applications (ideology detection, voting prediction, persuasion analysis), what are key ethical and methodological risks?\",\n", "\n", " # Social simulation\n", " \"Why are some social experiments expensive, unethical, or infeasible with humans, and how do LLM-based simulations change that?\",\n", " \"In multi-agent social simulations (e.g., virtual towns), what memory and identity mechanisms are needed for believable long-term behavior?\",\n", " \"Which social phenomena are easiest vs hardest to simulate with LLM agents (misinformation spread, emotion contagion, norm formation), and why?\",\n", " \"How would you validate that an LLM-agent social simulation reflects meaningful dynamics rather than prompt artifacts?\",\n", "\n", " # Jurisprudence\n", " \"How does a multi-judge voting mechanism (e.g., Blind Judgement) reduce decision risk, and what new risks can it introduce?\",\n", " \"How do database + keyword search strategies (e.g., ChatLaw) mitigate hallucination in legal agents, and what failure modes remain?\",\n", " \"What are 'reference inaccuracies' in legal reasoning, and why are they especially dangerous for LLM-based agents?\",\n", "\n", " # Natural science: documentation + experiments\n", " \"Why are documentation and data management tasks well-suited for tool-using LLM agents that query the internet and databases?\",\n", " \"What’s the difference between agents focused on information extraction (e.g., ChatMOF) versus agents that plan and execute workflows (e.g., experiment assistants)?\",\n", " \"How do safety-oriented chemistry tools (e.g., identifying dangerous substances) change the risk profile of LLM scientific assistants?\",\n", " \"What are the risks of agents that autonomously design and execute experiments, and how should sandboxing and permissions be enforced?\",\n", "\n", " # Education agents\n", " \"What capabilities make LLM-based education agents effective (personalization, explanation, feedback), and where do they fail?\",\n", " \"How can an education agent monitor student queries responsibly while preserving privacy and avoiding surveillance creep?\",\n", " \"What is the difference between an agent that can solve math problems and one that can teach mathematical reasoning effectively?\",\n", " \"How would you evaluate whether an education agent improves critical thinking rather than just answer correctness?\",\n", "\n", " # Engineering: software engineering + analysis\n", " \"What advantages do multi-role software engineering agent frameworks (e.g., ChatDev, MetaGPT) have over a single coding agent?\",\n", " \"How does self-collaboration among multiple LLM 'experts' affect code quality, cost, and reliability compared to single-agent generation?\",\n", " \"How does tree-of-thought with backtracking (e.g., D-Bot) improve diagnostic accuracy in debugging and anomaly analysis?\",\n", "]\n", "\n", "\n", "print(f\"Defined {len(CORPUS_QUERIES)} corpus benchmark queries\")" ] }, { "cell_type": "code", "execution_count": null, "id": "72w2pno88qt", "metadata": {}, "outputs": [], "source": [ "# 3.9.4 Run Corpus Benchmark\n", "import time\n", "\n", "corpus_results = {\"fsagent\": [], \"memagent\": []}\n", "\n", "print(\"=\" * 70)\n", "print(\"CORPUS BENCHMARK: FSAgent (grep) vs MemAgent (vector search)\")\n", "print(\"=\" * 70)\n", "\n", "for i, query in enumerate(CORPUS_QUERIES, 1):\n", " print(f\"\\n[Query {i}/{len(CORPUS_QUERIES)}] {query[:60]}...\")\n", " \n", " # === FSAgent ===\n", " print(\" [FS] Running FSAgent...\", end=\" \")\n", " fs_start = time.time()\n", " try:\n", " fs_response = fs_agent.invoke(\n", " {\"messages\": [{\"role\": \"user\", \"content\": f\"Using the agent_memory_corpus.md file, answer: {query}\"}]}\n", " )\n", " fs_answer = fs_response[\"messages\"][-1].content if fs_response.get(\"messages\") else \"\"\n", " fs_latency = time.time() - fs_start\n", " print(f\"[OK] {fs_latency:.2f}s\")\n", " except Exception as e:\n", " fs_answer = f\"Error: {e}\"\n", " fs_latency = time.time() - fs_start\n", " print(f\"[ERROR] {e}\")\n", " \n", " corpus_results[\"fsagent\"].append({\n", " \"query\": query,\n", " \"response\": fs_answer,\n", " \"latency\": fs_latency\n", " })\n", " \n", " # === MemAgent ===\n", " print(\" [DB] Running MemAgent...\", end=\" \")\n", " mem_start = time.time()\n", " try:\n", " mem_response = MEM_AGENT.invoke(\n", " {\"messages\": [{\"role\": \"user\", \"content\": query}]}\n", " )\n", " mem_answer = mem_response[\"messages\"][-1].content if mem_response.get(\"messages\") else \"\"\n", " mem_latency = time.time() - mem_start\n", " print(f\"[OK] {mem_latency:.2f}s\")\n", " except Exception as e:\n", " mem_answer = f\"Error: {e}\"\n", " mem_latency = time.time() - mem_start\n", " print(f\"[ERROR] {e}\")\n", " \n", " corpus_results[\"memagent\"].append({\n", " \"query\": query,\n", " \"response\": mem_answer,\n", " \"latency\": mem_latency\n", " })\n", "\n", "print(\"\\n\" + \"=\" * 70)\n", "print(\"CORPUS BENCHMARK COMPLETE\")\n", "print(\"=\" * 70)" ] }, { "cell_type": "code", "execution_count": 60, "id": "p4cvc9y1ta", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "======================================================================\n", "CORPUS BENCHMARK RESULTS\n", "======================================================================\n", "\n", "## Latency Comparison\n", "Metric FSAgent MemAgent \n", "--------------------------------------------------\n", "Mean Latency 5.85s 34.24s\n", "Median Latency 4.85s 10.20s\n", "Min Latency 3.59s 3.07s\n", "Max Latency 15.76s 1032.60s\n", "\n", "## Response Length Comparison\n", "Metric FSAgent MemAgent \n", "--------------------------------------------------\n", "Mean Length 542 chars 2474 chars\n", "Total Chars 24,918 113,803\n", "\n", "## Per-Query Winners (by latency)\n", " FSAgent faster: 40/46 queries\n", " MemAgent faster: 6/46 queries\n" ] } ], "source": [ "# 3.9.5 Corpus Benchmark Analysis\n", "\n", "import statistics\n", "\n", "# Calculate latency statistics\n", "fs_latencies = [r[\"latency\"] for r in corpus_results[\"fsagent\"]]\n", "mem_latencies = [r[\"latency\"] for r in corpus_results[\"memagent\"]]\n", "\n", "print(\"=\" * 70)\n", "print(\"CORPUS BENCHMARK RESULTS\")\n", "print(\"=\" * 70)\n", "\n", "print(\"\\n## Latency Comparison\")\n", "print(f\"{'Metric':<20} {'FSAgent':<15} {'MemAgent':<15}\")\n", "print(\"-\" * 50)\n", "print(f\"{'Mean Latency':<20} {statistics.mean(fs_latencies):.2f}s{'':<10} {statistics.mean(mem_latencies):.2f}s\")\n", "print(f\"{'Median Latency':<20} {statistics.median(fs_latencies):.2f}s{'':<10} {statistics.median(mem_latencies):.2f}s\")\n", "print(f\"{'Min Latency':<20} {min(fs_latencies):.2f}s{'':<10} {min(mem_latencies):.2f}s\")\n", "print(f\"{'Max Latency':<20} {max(fs_latencies):.2f}s{'':<10} {max(mem_latencies):.2f}s\")\n", "\n", "# Calculate response lengths\n", "fs_lengths = [len(r[\"response\"]) for r in corpus_results[\"fsagent\"]]\n", "mem_lengths = [len(r[\"response\"]) for r in corpus_results[\"memagent\"]]\n", "\n", "print(\"\\n## Response Length Comparison\")\n", "print(f\"{'Metric':<20} {'FSAgent':<15} {'MemAgent':<15}\")\n", "print(\"-\" * 50)\n", "print(f\"{'Mean Length':<20} {statistics.mean(fs_lengths):.0f} chars{'':<5} {statistics.mean(mem_lengths):.0f} chars\")\n", "print(f\"{'Total Chars':<20} {sum(fs_lengths):,}{'':<10} {sum(mem_lengths):,}\")\n", "\n", "# Winner summary\n", "fs_wins = sum(1 for f, m in zip(fs_latencies, mem_latencies) if f < m)\n", "mem_wins = len(fs_latencies) - fs_wins\n", "\n", "print(\"\\n## Per-Query Winners (by latency)\")\n", "print(f\" FSAgent faster: {fs_wins}/{len(CORPUS_QUERIES)} queries\")\n", "print(f\" MemAgent faster: {mem_wins}/{len(CORPUS_QUERIES)} queries\")" ] }, { "cell_type": "code", "execution_count": null, "id": "m5tn7250iki", "metadata": {}, "outputs": [], "source": [ "# 3.9.6 LLM-as-Judge for Corpus Benchmark\n", "print(\"=\" * 70)\n", "print(\"LLM-AS-JUDGE: CORPUS BENCHMARK\")\n", "print(\"=\" * 70)\n", "\n", "corpus_llm_scores = {\"fsagent\": [], \"memagent\": []}\n", "\n", "print(\"\\n[LLM Judge] Evaluating FSAgent responses...\")\n", "for i, r in enumerate(corpus_results[\"fsagent\"]):\n", " print(f\" [{i+1}/{len(corpus_results['fsagent'])}] {r['query'][:50]}...\", end=\" \")\n", " j = llm_judge_response(r[\"query\"], r[\"response\"])\n", " corpus_llm_scores[\"fsagent\"].append(j[\"score\"])\n", " print(f\"Score: {j['score']:.0f}%\")\n", "\n", "print(\"\\n[LLM Judge] Evaluating MemAgent responses...\")\n", "for i, r in enumerate(corpus_results[\"memagent\"]):\n", " print(f\" [{i+1}/{len(corpus_results['memagent'])}] {r['query'][:50]}...\", end=\" \")\n", " j = llm_judge_response(r[\"query\"], r[\"response\"])\n", " corpus_llm_scores[\"memagent\"].append(j[\"score\"])\n", " print(f\"Score: {j['score']:.0f}%\")\n", "\n", "fs_avg_corpus = statistics.mean(corpus_llm_scores[\"fsagent\"]) if corpus_llm_scores[\"fsagent\"] else 0\n", "mem_avg_corpus = statistics.mean(corpus_llm_scores[\"memagent\"]) if corpus_llm_scores[\"memagent\"] else 0\n", "\n", "print(f\"\\n{'=' * 70}\")\n", "print(f\"CORPUS LLM JUDGE SUMMARY\")\n", "print(f\"{'=' * 70}\")\n", "print(f\"FSAgent Average: {fs_avg_corpus:.1f}%\")\n", "print(f\"MemAgent Average: {mem_avg_corpus:.1f}%\")\n", "print(f\"Winner: {'FSAgent' if fs_avg_corpus > mem_avg_corpus else 'MemAgent'}\")" ] }, { "cell_type": "code", "execution_count": 62, "id": "o1uojzhuw9b", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "/var/folders/8r/qvgk1jk97zdc9z1jjtdhm_440000gn/T/ipykernel_76924/1074112835.py:34: MatplotlibDeprecationWarning: The 'labels' parameter of boxplot() has been renamed 'tick_labels' since Matplotlib 3.9; support for the old name will be dropped in 3.11.\n", " bp = ax3.boxplot([fs_latencies, mem_latencies], labels=['FSAgent', 'MemAgent'], patch_artist=True)\n" ] }, { "data": { "image/png": "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WG3169OnT3i6jtEnn3wy5mvrOMkt//Gd2wofra/3nDvvvDPmPAsXLsyyguull14KPz8jI8NtQ+++tn1WVOF7/vnnu2NE2+y4444LzZ49O8fqZFXFPfroo25+tV3Hl/b9f/7zn9DcuXMzzR/9enq+9qnaWaxYMfcZccMNN7jpsbZjrFtut+2ll14afs6tt96a6fGZM2dGvO6BBx7otnUs+kxTBWt267Z582a3nHr16rljWMdYorbb1q1bQwMHDnRt1HbTMgYPHhzavn17zPa2bt06/Nznnnsux221fv169/71v6einXPOOeHHO3TokKefs3pPen+ritLz999/u2V4lZc5VTm+8cYbrnpO21rP02fRCSec4LbJnj17sv2u0fthxIgRoYMPPth9Zjdq1Cj07LPPunn1mdS3b1+3zvq8bNq0abbV8PqM815Xn4V6nndfx39Wvvvuu9Bpp50WKlu2rLtpm6piPPo7N9b+HDZsWOjoo492369a91q1arnvk++//z7T/NGvp32mGKB27druuTre7r777ohtllMFZ6wq6Vh0LHnPUTwSTd+b3uP67oumOMK/3EceeSSikv6ZZ55xcYa+07Qu++23n6t6fvPNN7Ns048//uhiGH1P63guWbKk2wbnnntuaP78+Xu1/optVPlat25dd8zodXVM9evXL7R8+fIc4wB9d+p7Up/ZWV054Kfj03t+/fr1Q7t27Yp5nHz88ccxn6/3tdZXx40+c3T8HXPMMS6OUOwYTd+hutpI+0uxij4D9RzFFDfffHPMWCc6Jvzoo49C7du3d8espq1duzaufRKr0lbLveqqq0I1atRw66H2xTrOZOPGjW4e7zNo2bJl2W5jAMD/kLQFgDhceeWVET8e4rnMa86cORGJpOibAtkHH3wwyx98+kHk/5GlW6yk7bHHHhv+8e2/KRBX4L6vSdt3330304/66Jt+BOxL0lYJTSU2s2ufkon+ZEj0TUmr6ESRf3lHHHGE++ET/Twl6LSOfkqS+pN20Tf9eMoqaauEaqznKNmbXTJJl/dGP0cJjtdffz3849J/0485/+WvomnZ7Sdd4q4fU37+x5UI89/PKWl70003hafpGJk0aVKWr53XSVv/vlVi3p+8zI3OnTuHn69EnRIW3n39+FSyMZreU0pixXpvn3rqqTG3mWi/KTmV3WeDklx+0ftA7/tY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AAAQICRtAQAAAAAAACBASNoCAAAAAAAAQICQtAUAAAAAAACAACFpCwAAAAAAAAABQtIWAAAAAAAAAAKEpC0AAAAAAAAABAhJWwAAAAAAAAAIkEAnbXfv3m133HGH1atXz0qWLGkHHXSQ3XXXXRYKhcLz6O+BAwdajRo13DwdOnSwxYsXR7zOmjVr7MILL7Ry5cpZhQoVrFevXrZp06YkrBEAAAAAAAAApHDS9t5777UxY8bYqFGj7Mcff3T377vvPnv00UfD8+j+yJEjbezYsfbZZ59Z6dKlrWPHjrZt27bwPErY/vDDDzZr1iybPn26ffjhh3b55Zcnaa0AAAAAAAAAIGtFLMDmzp1rZ5xxhp166qnuft26dW3y5Mn2+eefh6tsR4wYYbfffrubT5555hmrVq2avfbaa3beeee5ZO+MGTNs/vz51rx5czePkr6nnHKKPfDAA1azZs0kriEAAAAAAAAApFDStnXr1vb444/bzz//bAcffLB9++239vHHH9tDDz3kHl+6dKmtWLHCdYngKV++vLVs2dLmzZvnkrb6X10ieAlb0fyFChVylbldu3bNtNzt27e7m2fDhg3u/z179rgbgMQLZWRkmsb7DQCQE74rAAAAUBAFOmnbv39/lzBt2LChFS5c2PVxe/fdd7vuDkQJW1FlrZ/ue4/p/6pVq0Y8XqRIEatUqVJ4nmjDhw+3wYMHZ5q+evXqiG4XACTOulr1Mk3LWLWKTQwAyNbGjRtTbgsppr3zzjvtueeec/Gorvzq0aOHu3os4/+fxNQVZYMGDbInnnjC1q1bZ23atHHdhjVo0CDZzQcAAEC6J21feuklmzRpkj3//PPWqFEj++abb+z66693gW337t3zbLkDBgywfv36he8rcVyrVi2rUqWKG8wMQOKFli/NNC36hAsAANFKlCiRchvFG7fh6aefdjHuF198YT179nRXjF133XUR4zZoHg3Kq8F5NW7DwoULU3KdAQAAUICStjfddJOrtlU3B9K4cWP7/fffXSWskrbVq1d301euXGk1atQIP0/3mzZt6v7WPKuiqvV27dpla9asCT8/WvHixd0tmrpU0A1A4mWEQjHfcwAAZCcVvysSMW4DAAAACrZAR7lbtmzJFIirmwSv7zJVHSjxOnv27IiqWPVV26pVK3df/+uSsi+//DI8z3vvvedeQ33fAgAAAPk9boPiV43bIN64DZ07d87VuA0AAAAo+AJdadulSxfXh23t2rXdpWNff/21G4TskksucY+rzy91lzB06FDXv5d36Zi6TzjzzDPdPIceeqh16tTJLrvsMhs7dqzt3LnTrr32WlehoPkAAACAVBu3IZYgDKabYaG4BhqNnj83z8nv+WM9Jz/XIRGvH+s58c4f9P2QjDal2vGdV8fSvrQpGfMHsU3JXodkHKv5tYx4BHEdCsJ+KAif94mW22UFOmn76KOPuiTs1Vdf7bo4UJL1iiuusIEDB4bnufnmm23z5s12+eWXu4raY4891mbMmBHR15f6xVWitn379q5y96yzznJ9hAEAAAAFZdyGIAymW7/4prgGGo2ePzfPye/5Yz0nP9chEa8f6znxzh/0/ZCMNqXa8Z1Xx9K+tCk/5u834+9Mj9+RYuuQ18tIxrGaX8vITvSxEe9xsTdtCtr8qdKmjIAfS3k1kG6gk7Zly5Z1/XnplhVV2w4ZMsTdslKpUiUXFAMAAAAFYdyGoA6mu2R75I+QCjkMNBo9f26es6+Dme7N4KfRz8nPdUjE68daRrzzB30/JKNNoRQ7vvPqWNqXNqXjfkjE/IleRjK20d48J9GDV8f7nZWINgVt/lRpU9WAH0vxyu2gsoFO2gIAAAAFTTzjNnhJWm/chquuuirL1w3CYLohy4hroNHo+XPznPyeP9Zz8nMdEvH6sZ4T7/xB3w/JaFOqHd95dSztS5vScT8kYv5ELyMZ2yi/lpHI76xEtClo86dKmwoF/FiKV26XRdIWAAAASLFxGwAAAFCwkbQFAAAAUnDcBgAAABRcJG0BAACAFBy3AQAAAAVX/nXYAAAAAAAAAADIEUlbAAAAAAAAAAgQkrYAAAAAAAAAECAkbQEAAAAAAAAgQEjaAgAAAAAAAECAkLQFAAAAAAAAgAAhaQsAAAAAAAAAAULSFgAAAAAAAAAChKQtAAAAAAAAAAQISVsAAAAAAAAACBCStgAAAAAAAAAQICRtAQAAAAAAACBASNoCAAAAAAAAQICQtAUAAAAAAACAACFpCwAAAAAAAAABQtIWAAAAAAAAAAKkSLIbAAAAAATBsmXL7Pfff7ctW7ZYlSpVrFGjRla8ePFkNwsAAABpiKQtAAAA0tZvv/1mY8aMsRdeeMH++OMPC4VC4ceKFStmxx13nF1++eV21llnWaFCXKQGAACA/EHkCQAAgLR03XXXWZMmTWzp0qU2dOhQW7hwoa1fv9527NhhK1assLfeesuOPfZYGzhwoB1xxBE2f/78ZDcZAAAAaYJKWwAAAKSl0qVL26+//mqVK1fO9FjVqlXtxBNPdLdBgwbZjBkzbPny5daiRYuktBUAAADphaQtAAAA0tLw4cNzPW+nTp3ytC0AAACAH0lbAAAAwOeff/6xzz77zHbv3u0qa2vUqMH2AQAAQL4iaQsAAAD8f6+88or16tXLDj74YNu5c6ctWrTIHnvsMevZsyfbCAAAAPmGgcgAAACQtjZt2hRxf/Dgwfb555+729dff21Tpkyx2267LWntAwAAQHqKu9JWo+t+9NFH9vvvv9uWLVusSpUqduSRR1qrVq2sRIkSedNKAAAAIA80a9bM7rvvPjvjjDPc/SJFitiqVatcpa2sXLnSihUrxrYHAABAMJO2kyZNskceecS++OILq1atmtWsWdNKlixpa9assV9++cUlbC+88EK75ZZbrE6dOnnbagAAACABZs6caddcc41NnDjRdYOgePfcc891/dnu2rXLChUq5B4DAAAAApe0VSWtKgx69Ojh+vmqVatWxOPbt2+3efPm2QsvvGDNmze30aNH29lnn51XbQYAAAASom7duvbmm2/a5MmTrV27dnbdddfZkiVL3E2J24YNG3I1GQAAAILZp+0999zjRtC9+uqrMyVspXjx4nb88cfb2LFj7aeffrIDDzwwL9oKAAAA5Inzzz/f5s+fb99++62La/fs2WNNmzYlYQsAAIDgVtp27Ngx1y9YuXJldwMAAABSwVtvvWU//vijNWnSxMaPH29z5sxx3X517tzZhgwZ4roEAwAAAAJXaev31Vdf2YIFC8L3X3/9dTvzzDPt1ltvtR07diS6fQAAAECeueGGG6xnz56uyvaKK66wu+66y3WToJhXYzaom7C3336bPQAAAIBgJ20VzP7888/u719//dXOO+88K1WqlE2ZMsVuvvnmvGgjAAAAkCc0yJgqbTU2gxK3zz77rJuu8RyUwH311Vdt2LBhbH0AAAAEO2mrhK369xIlatu2bWvPP/+8C3g1SBkAAACQKkqXLm1Lly51fy9fvjxTH7aHHXaYffTRR0lqHQAAANJV3EnbUCjkBmaQd99910455RT3twYo++effxLfQgAAACCPDB8+3C6++GKrWbOm6xZB1bUAAABASgxE5te8eXMbOnSodejQwQ3SMGbMGDddFQrVqlXLizYCAAAAeUIDjnXq1Ml1+9WgQQOrUKECWxoAAACpl7QdMWKEC25fe+01u+2226x+/fpu+ssvv2ytW7fOizYCAAAAeaZy5cruBgAAAKRs0vaII46wBQsWZJp+//33W+HChRPVLgAAACBPXXnllXb77bfbAQcckOO8L774ou3atcsVLwAAAACBS9pmJXrQBgAAACDIqlSpYo0aNbI2bdpYly5dXDdg6ttWce3atWtt4cKF9vHHH9sLL7zgpj/++OPJbjIAAADSRK6SthUrVrSMjIxcveCaNWv2tU0AAABAntOgY9dee62NHz/eRo8e7ZK0fmXLlnXjOChZq35vAQAAgEAlbdWPrefff/91A5F17NjRWrVq5abNmzfPZs6caXfccUfetRQAAABIMA2kq3EadFN17bJly2zr1q2233772UEHHZTrwgUAAAAg35O23bt3D/991lln2ZAhQ1xVgue6666zUaNG2bvvvmt9+/ZNaAMBAACA/KCry3QDAAAAkq1QvE9QRW2sy8M0TUlbAAAAAAAAAEA+Jm0rV65sr7/+eqbpmqbHAAAAAAAAAAB53D2C3+DBg+3SSy+1Dz74wFq2bOmmffbZZzZjxgx74okn9qEpAAAAAAAAAIC4k7Y9evSwQw891EaOHGmvvvqqm6b7H3/8cTiJCwAAAAAAAADIp6StKDk7adKkvVwkAAAAEDy7du1yV5P98ssvdsEFF1jZsmXtr7/+snLlylmZMmWS3TwAAACkkb1K2u7Zs8eWLFliq1atcn/7tW3bNlFtAwAAAPLF77//7gbWXbZsmW3fvt1OOukkl7S999573f2xY8eyJwAAABDcpO2nn37qKg8U2IZCoYjHMjIybPfu3YlsHwAAAJDn+vTpY82bN7dvv/02YnDdrl272mWXXcYeAAAAQLCTtldeeaULaN98802rUaOGS9QCAAAAqeyjjz6yuXPnWrFixSKm161b1/7888+ktQsAAADpKe6k7eLFi+3ll1+2+vXr502LAAAAgHymLr9iXTH2xx9/uG4SAAAAgPxUaG8GIVN/tgAAAEBBcfLJJ9uIESPC93U12aZNm2zQoEF2yimnJLVtAAAASD9xV9r27t3bbrjhBluxYoU1btzYihYtGvH4EUcckcj2AQAAAHnugQcecAORHXbYYbZt2zY3hoOuMNtvv/1s8uTJ7AEAAAAEO2l71llnuf8vueSSiEoEDUrGQGQAAABIRbVq1XKDkL344ovuf1XZ9urVyy688EIrWbJkspsHAACANBN30nbp0qV50xIAAAAgCXbu3GkNGza06dOnuyStbgAAAEBKJW3r1KmTNy0BAAAAkkDdfalLBAAAACBlByKTX375xfVt26FDB3e77rrr3DQAAAAgFV1zzTV277332q5du5LdFAAAACD+StuZM2fa6aefbk2bNrU2bdq4aZ988ok1atTIpk2bZieddBKbFQAAACll/vz5Nnv2bHvnnXfcYLulS5eOePzVV19NWtsAAACQfuJO2vbv39/69u1r99xzT6bpt9xyC0lbAAAApJwKFSqEB9wFAAAAUi5p++OPP9pLL72Uafoll1xiI0aMSFS7AAAAgHwzYcIEtjYAAABSN2lbpUoV++abb6xBgwYR0zWtatWqiWwbAAAAkK9Wr15tixYtcn8fcsghLvYFAAAAAp+0veyyy+zyyy+3X3/91Vq3bh3u01YDN/Tr1y8v2ggAAADkqc2bN7uBdp955hnbs2ePm1a4cGG7+OKL7dFHH7VSpUqxBwAAAJBvCsX7hDvuuMMGDhzogtd27dq526hRo+zOO++022+/PeEN/PPPP+2///2vVa5c2UqWLOkGhvjiiy/Cj4dCIdeeGjVquMc7dOhgixcvjniNNWvW2IUXXmjlypVz/ZX16tXLNm3alPC2AgAAIDWp+GDOnDluYN1169a52+uvv+6m3XDDDcluHgAAANJM3EnbjIwMNxDZH3/8YevXr3c3/d2nTx/3WCKtXbvW2rRpY0WLFrW3337bFi5caA8++KBVrFgxPM99991nI0eOtLFjx9pnn33mRvrt2LGjbdu2LTyPErY//PCDzZo1y6ZPn24ffvihqxYGAAAA5JVXXrEnn3zSOnfu7E7063bKKafYE088YS+//DIbCQAAAMHuHmHp0qW2a9cu16dt2bJlw9NV3arkat26dRPWOHW5UKtWrYiBIerVqxdRZavBz1The8YZZ7hpuqStWrVq9tprr9l5553nBk6bMWOGzZ8/35o3b+7mUZWwgvAHHnjAatasmbD2AgAAIDVt2bLFxZDRNGaDHgMAAAACnbTt0aOHXXLJJZkGIlOV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l7tcDAAAAEh1GzZsiHnbuHGj7dixI9nNAwAAQJqJO2n7559/2tNPP23//POPHX/88dawYUO79957bcWKFXnTQgAAACCPVahQwSpWrJjppuklS5a0OnXq2KBBg2zPnj3sCwAAAAQvaVukSBHr2rWrvf7667Z8+XK77LLLbNKkSVa7dm07/fTT3XSCWQAAAKSSiRMnWs2aNe3WW2+11157zd309/77729jxoyxyy+/3EaOHGn33HNPspsKAACANBB3n7Z+1apVc4M2/Pzzz+62YMEC6969u6tKUN+3qsQFAAAAgk5Xkj344IN2zjnnhKd16dLFDUo2btw4mz17titSuPvuu10yFwAAAAhUpa2sXLnSHnjgAWvUqJFLzKq/r+nTp9vSpUtd9wkKdpW8BQAAAFKBxmo48sgjM03XtHnz5rm/VaywbNmyJLQOAAAA6SbupK0qDmrVquUuIVPXCErSTp482Tp06OAeL126tN1www2u6wQAAAAgFSi+ffLJJzNN1zQ9Jv/++6+7ogwAAAAIXPcIVatWtTlz5lirVq2ynKdKlSqu6hYAAABIBbqK7Oyzz7a3337bWrRo4aZ98cUX9tNPP9nLL7/s7s+fP9/OPffcJLcUAAAA6SDupG2sCoRoGRkZboRdAAAAIBVoQF0laB9//HFbtGiRm9a5c2c3IFndunXd/auuuirJrQQAAEC6iDtpe91111n9+vXd/36jRo2yJUuW2IgRIxLZPgAAACBf1KtXz4YPH87WBoA01mLckkzTpiWlJQDSXdxJ21deecXeeOONTNNbt25t99xzD0lbAAAApITvvvsu1/MeccQRedoWAAAAYJ+SthqAoXz58pmmlytXzv755594Xw4AAABIiqZNm7puvUKhkPvfo/vin7Z79+6ktBEAAADpqVC8T1DXCDNmzMg0XYM2HHjggYlqFwAAAJCnNHDur7/+6v7X1WTqHmH06NH2zTffuJv+Puigg9xjAAAAQKArbfv162fXXnutrV692k488UQ3bfbs2fbggw/SNQIAAABShn/g3LPPPttGjhxpp5xySkSXCLVq1bI77rjDzjzzzCS1EgAAAOko7qTtJZdcYtu3b7e7777b7rrrLjdNI+qOGTPGLr744rxoIwAAAJCnFixY4Cpto2nawoUL2foAAAAIdvcIctVVV9kff/xhK1eutA0bNrjLykjYAgAAIFUdeuihNnz4cNuxY0d4mv7WND0GAAAABLrS1q9KlSqJawkAAACQJGPHjrUuXbrYAQcc4LpFkO+++84NRjZt2jT2CwAAAIKdtFV17Y033uj6sV21alV4dF0PI+sCAAAg1Rx99NHu6rFJkybZTz/95Kade+65dsEFF1jp0qWT3TwAAACkmbiTtj169LBly5a5ARlq1Kjhqg8AAACAVKfk7OWXX57sZgAAAADxJ20//vhj++ijj6xp06ZsPgAAABQIzzzzTLaPM34DAAAAAp20rVWrVqYuEQAAAIBU1qdPn4j7O3futC1btlixYsWsVKlSJG0BAACQrwrF+4QRI0ZY//797bfffsubFgEAAAD5bO3atRG3TZs22aJFi+zYY4+1yZMnsz8AAAAQ7EpbDcigqoODDjrIVR0ULVo04vE1a9Yksn0AAABAUjRo0MDuuece++9//xsenAwAAAAIZNJWlbYAAABAOihSpIj99ddfyW4GAAAA0kzcSdvu3bvnTUsAAACAJHnjjTci7msMh7///ttGjRplbdq0Yb8AAAAg2Elb+eWXX2zChAnu/0ceecSqVq1qb7/9ttWuXdsaNWqU+FYCAAAAeejMM8+MuJ+RkWFVqlSxE0880R588EG2PQAAAII9ENmcOXOscePG9tlnn9mrr77qBmmQb7/91gYNGpQXbQQAAADy1J49eyJuu3fvthUrVtjzzz9vNWrUYOsDAAAg2Enb/v3729ChQ23WrFlWrFix8HRVIXz66aeJbh8AAAAAAAAApJW4u0dYsGCBqziIpi4S/vnnn0S1CwAAAMhz/fr1y9VgZNWrV7f27dtbkyZN2CsAAAAIXtK2QoUKblCGevXqRUz/+uuvbf/9909k2wAAAIA8pRg2J+ouYdWqVXbTTTfZo48+aldffTV7BQAAAMFK2p533nl2yy232JQpU9wADQpiP/nkE7vxxhvt4osvzptWAgAAAHng/fffz/W8Tz/9tA0ZMoSkLQAAAILXp+2wYcOsYcOGVqtWLTcI2WGHHWZt27a11q1b2+233543rQQAAACS7JRTTnFXnQEAAACBq7TV4GNPPPGEDRw40PVvq8TtkUceaQ0aNMibFgIAAAABUKVKFfvyyy+T3QwAAACkgbgrbXVJ2JYtW1ylraoNzjnnHJew3bp1q3sMAAAAAAAAAJCPSdvBgwe76tpoSuTqMQAAAAAAAABAPiZtQ6GQG4As2rfffmuVKlXah6YAAAAAAAAAAHLdp23FihVdsla3gw8+OCJxu3v3bld9e+WVV7JFAQAAkDKWLVuWq/lq166d520BAAAA4k7ajhgxwlXZXnLJJa4bhPLly0cMTla3bl1r1apVbl8OAAAASLp69eqF/1asK/7iBO8qMxUpAAAAAIFL2nbv3j0c2LZu3dqKFi2al+0CAAAA8pwSsgcccID16NHDunTpYkWK5Do8BgAAAILTp227du3CCdtt27bZhg0bIm556Z577nGB9fXXXx+epjZcc801VrlyZStTpoydddZZtnLlykyXvZ166qlWqlQpq1q1qt100022a9euPG0rAAAAgu+PP/6wq666yl544QUXLz777LPuKrImTZpE3AAAAIBAJ223bNli1157rUt+li5d2vV167/llfnz59u4cePsiCOOiJjet29fmzZtmk2ZMsXmzJljf/31l3Xr1i38uC5lUwC+Y8cOmzt3rj399NM2ceJEGzhwYJ61FQAAAKmhevXqdsstt9hPP/1kL7/8sq1du9ZatmxpxxxzjD3xxBO2Z8+eZDcRAAAAaSjupK2qVN977z0bM2aMFS9e3MaPH+/6uK1Zs6Y988wzedJIDXJ24YUXusDZnxhev369Pfnkk/bQQw/ZiSeeaM2aNbMJEya45Oynn37q5nnnnXds4cKF9txzz1nTpk2tc+fOdtddd9ljjz3mErkAAACAHHvssS62XLx4sbtCS4Psrlu3Ls83zt5eTQYAAICCK+6krapaR48e7QJH9fl13HHH2e23327Dhg2zSZMm5UkjFbCqWrZDhw4R07/88kvbuXNnxPSGDRu60X3nzZvn7uv/xo0bW7Vq1cLzdOzY0XXl8MMPP+RJewEAAJB6dOL/0ksvtYMPPtgVDegkf4UKFfJ0mXt7NRkAAAAKtrhHWlizZo0deOCB7u9y5cq5+15lgvoDSzT1L/bVV1+5gDbaihUrXJ9j0cG0ErR6zJvHn7D1Hvcei2X79u3u5vH66tXlcVwiB+SNkG+kbg/vNwBATvb1u+Lvv/92V4vpai11jaCruz755BM7/PDD83zj+68mGzp0aKaryZ5//nl3NZmofYceeqi7mkxdNwAAAKBgiztpq4Tt0qVLXTWrqlpfeuklO/roo10lQKIrEZYvX259+vSxWbNm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dLEJEybY9u3bE7KchQsXumX99ttvFjRBbhsAAEA8fvjhB/vvf/9r+++/vxUvXtxq1qxpF154oZte0O3Zs8eeeeYZa9mypVWqVMnKli1rBx98sF188cX26aefJrt5AJBviuTfogAgOJS0HTx4sPu7IFVgjhkzxsqUKeOStH/++afNnDnTLrnkEhsxYoRNnz7datWqFZ73iSeecEFxvIlRbTdts3gqJRYtWmSFCuXtecLs2vbOO+/k6bIBAAAS5dVXX7Xzzz/fJSx79epl9erVcyeln3zySXv55ZfthRdesK5duxbYDX7dddfZY489ZmeccYZLVBcpUsTFkm+//bYdeOCBdswxxyS7iQCQL0jaAkAB8p///Mf222+/8P2BAwfapEmTXGXC2WefHVGdULRo0TxtSygUsm3btlnJkiVdhUgyFStWLKnLBwAAyI1ffvnFLrroIpec/PDDD61KlSrhx/r06WPHHXece/y7775z8+SXzZs3W+nSpfN8OStXrrTRo0fbZZddZo8//njEYypCWL16taUbxdOKZfO6AAJA8PCuB1Cg7NixwyUqmzVrZuXLl3fBpYLb999/PzyPKhW8AFiVmV6XArq03vPTTz+5BKgqHEqUKGHNmze3N954I2Z3DZ988on169fPvaaWp8qHWAGlqgPatWvnLvEqV66ctWjRwp5//nn32KBBg1wSNdbzLr/8cqtQoYIL2PaGKhQuvfRS++yzz2zWrFnZ9iumyg1tO6+NjRs3tkceeSS8vkr8ygknnBDebl4XE3qt0047zVX3anspWTtu3LiYfdr6K56vuOIKq1y5sluekstr166NmCd633j8r5lT22L1abtq1SpXvVKtWjW3j5s0aWJPP/10xDw6VvQ6DzzwgPvhcNBBB7kEtPbd/Pnz49gLAAAAObv//vtdfKS4w5+wFZ2YV2ylBOp9993npqnyVrHKnDlzMr2W5tVj33///V7FuHrNq6++2qpWrWoHHHCAe+z333930w455BAX6ymGUwyWqO6pli5d6k78t2nTJtNjapPaEt09WDSv/f42eXGqYkMvTlWc68WKqm7WfW0TxcJff/11xGsq5tTVbMuWLXOvo7/VdYUqgmXBggV24oknut8CderUCcf4njVr1tiNN97olqHnKu7t3LmzffvttzH7AlZMfvvtt7tlqNuzb775xk1/+OGHM63v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oig0NFT9uK45XyMiIiIiSggYtI0CTUkECdgyaEtERERkeljCioiIiIgSEhb+IiIiIiIiIiIiIjIhDNoSERERERERERERmRAGbYmIiIiIiIiIiIhMCIO2RERERERERERERCaEQVsiIiIiIiIiIiIiE8KgLREREREREREREZEJYdCWiIiIiIiIiIiIyIQwaEtERERERERERERkQhi0JSIiIiIiIiIiIjIhDNoSERERERERERERmRDz+B4AERERJTzv3r3DgQMHcPv2bdjY2KB8+fJImjRpfA+LiIiIiIjom8BMWyIiIopVmzZtQp48eVC5cmW0atVK3cpjaSciIiIiIqIvY9CWiIiIYo0EZr/77jsUKVIE/v7+ePLkibqVx9LOwC0REREREdGXmX348OFDFPolaqGhobCyskJISAgsLS3jezhEREQmWxJBMmolQOvu7o4kST7/Nvz+/Xs0atQI//zzDy5dusRSCRRreJ5GRERERAkRM22JiIgoVkgN22vXrmHYsGF6AVt1wpEkCYYOHYrAwEDVj4iIiIiIiCLGoC0RERHFCll0TBQuXDjc5zXtmn5EREREREQUPgZtiYiIKFbY2NioWymBEB5Nu6YfERERERERhY9BWyIiIooV5cuXR44cOTBhwgRVw1aXPJ44cSJy5syp+hEREREREVHEGLQlIiKiWJE0aVJMnz4d27ZtU4uO+fv748mTJ+pWHkv7tGnTuAgZERERERHRF5h/qQMRERFRVDVp0gQbNmzAgAED4Orqqm2XDFtpl+eJiIiIiIgocmYfPnz48IU+iV5oaCisrKwQEhICS0vLRD8fREREX/Lu3TscOHBALTomNWylJIJk4hLFNp6nEREREVFCxExbIiIiinUSoK1UqRJnloiIiIiI6Furaevr64v69evD1tYWZmZmcHd313tekoBHjRqlMnRSpkyJatWq4dKlS3p9Hj16hNatW6sM2HTp0qFjx454+vSpXp/Tp0+rDB8LCwvY2dlhypQpX+X9EREREREREREREX1TQdtnz56hWLFimDNnTrjPS3B15syZmD9/Pg4fPozUqVOjZs2aePnypbaPBGzPnj2L3bt3qwVOJBDcpUsXvUvmatSoAQcHBxw7dgxTp07FL7/8goULF36V90hERERERERERET0Tda0lUzbzZs3q9WlhQxLMnBlIZOBAweqNqkpmyVLFvz1119o2bIl/v33XxQsWBBHjhyBs7Oz6uPp6Yk6deogKChIvX7evHkYPnw47ty5g+TJk6s+Q4YMUVm958+fj9LYWCuNiIiIyDTxPI2IiIiIEqJ4zbSNTGBgoAq0SkkEDVkMrEyZMvD391eP5VZKImgCtkL6J0mSRGXmavpUqFBBG7AVkq174cIF/Pfff1/1PRERERERERERERF9swuRScBWSGatLnmseU5uM2fOrPe8ubk5MmTIoNcnZ86cBvvQPJc+fXqDY7969Uptuhkc4v3792ojIiIiItPAczMiIiIiSohMNmgbnyZOnIgxY8YYtN+/f1+vni4RERERxa8nT57wIyAiIiKiBMdkg7ZZs2ZVt3fv3oWNjY22XR4XL15c2+fevXt6r3v79i0ePXqkfb3cymt0aR5r+oQ1dOhQ9O/fXy/T1s7ODtbW1rC0tIy190hEREREMWNhYcEpTORkLQz5m0AWJ759+zZev/58xRwREVFUSanNNGnSIm/evMiXLx/PMSjemWzQVkoaSFB1z5492iCtBE+lVm337t3VYxcXFzx+/BjHjh1DyZIlVdvevXvVZXJS+1bTRxYie/PmDZIlS6badu/ejfz584dbGkGkSJFCbeH9BywbEREREZkGnpslbhKw3bp1K44dOQSLZGbIbmuNVMmTqUWOiYiIjPHu3XvcD7qFU8f8YZHaCm3atkf27Nk5iZQ4g7ZPnz7F5cuX9RYfO3nypKpJa29vj759+2LcuHHqVw4J4o4cORK2trZo1KiR6l+gQAHUqlULnTt3xvz581VgtmfPnmjZsqXqJ1q1aqVKHXTs2BGDBw/GP//8gz/++AO///57vL1vIiIiIiKKOW9vbxwP8EOtKmXgVKwgkiZNymklIqIYCQl9AneP3Vi+bAm6de+pYlRE8SFe00aPHj0KJycntQkpSSD3R40apR4PGjQIvXr1QpcuXVCqVCkV5PX09NRLUV+1ahUcHR1RtWpV1KlTB25ubli4cKH2eSsrK+zatUsFhCUbd8CAAWr/sk8iIiIiIvo2vXv3DkeP/I0yJQvAuUQRBmyJiChWWFmmRcvv6gFvn+PUqVOcVYo3Zh/kmiKKlJRlkOBvSEgIa9oSERERmRCepyVeV65cwbIl89G5TSNkyZwpvodDREQJzJZt3rgf+gE9fuoZ30OhRIoFWomIiIiI6Jsja1uY4T0yW2eM76EQEVEClNk6Ax7/9zC+h0GJGIO2RERERET0TZZHSJokCRcdIyKiOGFubq7+X0MUXxi0JSIiIiIiIiIiIjIhDNoSERERERERERERmRAGbYmIiIiIiIiIiIhMCIO2RERERERERERERCaEQVsiIiIiIiIiIiIiE8KgLREREREREREREZEJYdCWiIiIiIiIiIiIyIQwaEtERERERERERERkQhi0JSIiIiIiIiIiIjIhDNoSERERERERERERmRAGbYmIiIiIiIiIiIhMCIO2RERERERERERERCaEQVsiIiIiIiIiIiIiE8KgLREREREREREREZEJYdCWiIiIiIiIiIiIyIQwaEtERERERERERERkQhi0JSIiIiIiIiIiIjIhDNoSERERERERERERmRAGbYmIiIiIiIiIiIhMCIO2RERERERERERERCaEQVsiIiIiIiKiBGbD5p3ImqsMnjx5ioSoXdefkSKDo3bz8TsMU2Lq4xNv3rxB7sKVMH/x6vgeChGFg0FbIiIiIiJKcG4F30XrDv2QOUcpZLQvgXrfdcK/F65on1+8bJ0KpOzac8DgtV7eB9RzC5asUY+Xr96kF3zR3SrXbqV9Xb5iVbTtqTMXRoGSNdCt9wg1lvAEXg/S9r989brB8xLkkec2bfGM9L1GtZ+xZG5qNGiDTPYl1TzKe926Y49R86wZm2wXLl3VtoeGPkXarEVUu8xvePMs+yvp1gDTZy7Gq1evjZ6/qH4ekX2+mrFpHD5yEnWbdlRzksGuBJxc62PgsIl4HBJq1Lzojm/J8vV67Y1adlXPxcS7d+8wdtIsdOvYCmnTpgm3z5fmz1hbtntj5rxl+Fq6dvgeS+dPweD+XWO8L2P+PYiP8cWVZMmSoXePdpj823y8fPkqvodDRGGYh20gIiIiIiL6lknwoVbjdrh37yF+7tsZKVKkwIzZS1QA8uiBLciSOROqVnZVfQ8cOoIaVcvrvf7AoQB1W61yOb320UN7I4dDdr0260wZ9B4XK1IAfX9qrzLYTv9zAYv+WgtPbx8c89uKjBnS6/X18vZFxgzp1H0JFuXJ5QBTIcHKLr2Go0TxQhgzoi/Mzc2xe68fVq51R4M6VaM8zxopU1rAY8ce5O+TSz323O2DpEmTSq6fwbE18xwS+gTuHrsw7JepOHHqLFYu/s3o+YvK5+HmWkoF18TPwycim21W9RpRtrSTdl9Hj59B9QZt4GCfDUMH9kCG9FY4ffY8Vq/bgvY/NEU6K0uj50UsW7URHdo0Q2za5rkPFy8HomPb5hH2ie3vn8cOb/j6BaB397b4GlzKlFCb/DAw+bcFMdpXdP49+Jrji0vtfmiKEWOnY+2Gbeo+EZkOBm2JiIiIiChBkcDixUuBWLX4d3zXuLZqK1WiCCrVboXZC5bj15H9kcM+O/LkdsCBg0cMXi9tOXPYIXdOe732mtXKo6RTkUiPbWuTGa2aN9A+zp3LHv0Gj8OKNe7aQKBu0KyiWxl8+PBBZfP16PwDTMHdew/Qb8g4lC1VHN7bVqiArSZzMOjWHaPmWaNKRRds3e6NgX06q8eSsVu1kiu27dxrcHzdeZZjulVvjvWbd2DKuMGwtcli1PxF5fPIlcNObeKX8TMMXqMx+fcFsEybBgd2/U8boBVjhvWFmRmiNS8SwP37yEmcv3gVjvk+BrRjK+hexrkY7LLbRNjHVL9/8SE6/x4kFFaWadV/iyvWbGbQlsjEsDwCERERERElKNu99iF58mRoUPdjRqiQjLfstlmxw2u/tk0y546e+AfPn7/Qtsn9YyfPGp1VF5FKbmXU7aUr1/Ta5XJ/H78AVK7oojbJxjOVy5NXr9uKp0+fY8iA7tqArUb2bFmNnmdRp0YlHD91Dnfu3sfr169VwLB+7c+vi0iSJElQoVxpdf/6jVsxnr+IPo+o+PfCZRQqkFcvYCssLdPolSAwZl4kk9kxX26VbRtbZB4kc7ZKxY/Zo+ExZv4k+7ROkw6wdnBWW/X6P6qsaw1NiQUJhF+/GRxheQlNGYprN4L09i+lIDr9NET7+NF/jzF45GRVGkNKS0gpilqN28P/8HHEpaj+exDb44vqvIj7Dx6he9+RsHd0g6VNUZSp1AQ7d/sY7FNKcTRt3QPZ87kifXYnVcbj10mzIhxD1UrlcPDvY+q9EZHpYNCWiIiIiIgSlHPnL6tL2JMnT67Xnj9fLly4FKjqfYpqld3UZfOS6ajhH3BCtVUPJ2gbEvoUDx7+p7fpBnjCc+v2x/qpmsvQNXwPBuDZs+eoXKGs2l68eKnaTIGf/1GYmZmhQrlSsTLPQkoJuJZxUpm1+w8cRoYM6VCkUL4ojefqtZsf96Ezh9Gdv4g+j6iwyWKNE6fOGQTXYjIvok2rJipQ/vbtW8SG4yfP4vXrNyjhVDjCPlGdv22ee1GzYTvcvHUbA3p3wqSxg1S2s9SA1ZDSErK5uTgjU8b02seqzTXy71B4Aq/dxF8rN6J8uVKYOm4ohg/6CbeC76jAqGQkx5Wo/nsQX+OTOtBV6rZWJUM6t2uBKeOGIF06SzRt1UNvkTP5UaRh8844duIM+vRoh6njhqB6lXKqZEZE5McDybiW90tEpoPlEYiIiIiIKEGRy/uLFXY0aJdAnQRgHv0XomrRVnIrrRbikcuf5fJ9Ifclu7RShbIGr6/dWL+8gRgyoBvGDO+rffzmzVsVzJXA3PmLVzBoxGRVu7VFk7p6r5PL0e2y2SBv7hzqsWRhSlvYeprx4dr1IBV8S5UqZYznWVe92lVVWQR7O9tIs2w1wXGpaSuLq0lZBclwzZ83l9HzF9XPIyqkfEDLdn1U1mLt6hVRvYobGtarhgzp00Xr+6fxQ8uGGDXud+zcLdnHMVuATGgWfMsVpv6yrqjMn8xZv0HjkCunHfz3bECaNKlVu9TJvX3nnrafppTEXp9DuBkUHG5pCWPky5MTl0/v1ctebtqoFvIVq6oykieO+RlxIar/HsTX+H6btRiB14JweN9GFCr48QePLu1bolSFRhg/ZY4qdSEkcCwZz/Nm/KpXKzmyHwU05UEkQ7duzcpxMn4iMh6DtkRERERElKDIpd/Jkhn+qSMBGaG5DFyCLlL3U7PQkOZScKk/KnUew/pj6ihtkEsj7MJk3vsOIlvejwEfUbpkMXisX6QNsmh47fFFpQofgyxC7kvbdAxDfHv2/AUsUqSItXnWqF+nqlrwSMoLrPhzeoT7DRscl8v8Z00fHa35i+rnERWNG9TE1nWLMHXGAmz22IWNWzzR++cxqjbuL8P6fFpYzfh5kbq2tapXUAG/2AjaPvx0iXu6dFYR9onK/EnG7o2gYPw+eYQ2YKthkzUz4opuMFQCjRK8T5UypfohQX5QiMvjRuXfg/gan/u23XB2KowsWazVDxEaslielFiQILt8BzU/tki5BvlBQJPxHbbUia70n74rD3X2S0Txj0FbIiIiIiJKUFKkSK4yLMOSLEdhYfE5ICkL8Ez6bb42kHbk+Gn8/GmxrLAkePOlhcgkKPjL8D548fIl1qzzUJctSzBHV+D1ILVQVcc2zbULexUumB8r125RpQA0WW/xJXWqlCpbNDbnWeR0yK6C3sG376pL6U+ePhfufjXB8bRpUqsyAxLUjO78ReXzMIYskiab1Bbds/8g5ixYiSm/L1QlA7p3ah2teRFtWzfF9+364N79h4gtcrl7eKI6f5oApNTc/Zrev3+POQtXYt6fq9QYdMtJvHwVt3Wfo/LvQXyN7+q1G+oHAd0fIXSFPnmqgq95cjmobGgpYSGBXqmnLCUw2v3QVBucjei7ImVRiMh0MGhLREREREQJSmbrjNpsQ10PHz1W2Wbp031eSEoWGBozcSYCjp1SgQsJisRkEbKMGdOpwI9m8a0KNVqiQ/fBOOLrrhbVEp6fFg6SxYxk0yULdGmCf/FFyhec/feSqtcbWYkEY+ZZY/b0X1QmryYrNTrBcWPmLyqfR3RIeYOW39VH4/o14ViiGja679QeNzrzUqdGRVU+YeVad8RUxk/lGh6HhOgtHKdhat+/d+/e6z2e9scijPz1d3zfrD7GDOujrWXcpvOACAPRsSUq/x58rfGFnRcJqEpJjn49O4TbP03qVNr7c38fq+reyoJ0u/b4YcioKViyYj2O+LiH+6PBf49DDOpGE1H8Y9CWiIiIiIgSlIKOebBn/yG1II/uYlCSXZg/b069y4SdSxRR2WdSu1ICLnIZdGnnYrEyDgkKDh/8Exq16IqN7p5o1qSONjCWJ7eDWkhI16ARk0wiaFvOxRk7vPbD9+ARddl+bMyzhmT9xVR05y+izyMmJKtWsoJv370fo3mRNqkFu3z1ZuRwyBajMWlq/169FqQyaKM7f5rSH/9euKyt8RoZM0SepZk8+cfyEC+ev9TLWr33QD+7eP3mnSjv6oy/FkzVy1J+HPIk/P1+Kjvx9q3+Am/REZV/D2J7fFGdl5wOdnj58qX2R4gvcSpWSG2D+3fDjDlLVYB+r6+/+vEiosX+HPN9rhtNRPEv+j8tEhERERERmaDaNSrh9es32Lp9j7bt8JGTuHnrNurUrGQQyJNLh30PHVH1K2XBociyQI1Vq1oFFSCbNvNP9Vgy93z8AlSdVlnwR3eTNnlO+sSnVs3qqwzbSdPnGSxepLmc3th5ji0xnb+wn4cx/PyP6l0KL6S26Ol/LqiAWkznRUokSID0xKnwy0ZEVUmnwioQeOLk2RjNX4nihdRiZbMXrMCTJ0/19hNeGYc0aVPjwaPHES54JSUkxPFTn8flsXOvmitdSZMmgfmnQKfGkhUbItxvtk/ZxFcCbyCmovLvQWyPL6rzIove+fkfU7Vqw7oZdFt7PzT0qcFYpDSJMI/g3zapXyyZvC6lncJ9nojiBzNtiYiIiIgoQfmxZSP8Mfcv/NR/NAKv34SFhQVmzF6iLmnv2bWNQX+5/HnAsAnqftjsQ11e3gdw4VKgXptFiuRo0rBWhK+RQEi3jq0xcNgE7N7rp9qk7EC5soYZp24uJbFwyRr4HgxQl0FryKJXYY8rZGV43XqvUe33JRJEmjpuiJq/irW+R+sWDVUmqCzqJdYtnxWteY4NMjfGzl9kn4f0kyzDvwNOqOeldEPw7XtYvW6rdpEnTY3XSdPn4/LV62jepA5y5bDHvfsPsHTlRlVLVBYj04juvBTIn1sthHX46Ck42NnGKPu3RtXy6vMaPax3tOdPgpUzpo5E8x97waXqd+p9WWfKiEOHj+HZsxdY89cfeq93KeWEuQtXokffUahft5rKMC1cMB+y2X4MSpZxLq7qCUtGb9Ct23j+4qXKWpWyELrq1aqCXyfPVvPnVLQgTp75F9t27omwFrF9dluUKlEUE6fNVRmqlmnToETxwtHOGv3SvwexPb6ozsuAXp2waasXajfpgE5tW6jX3wq+i32+/mpxNFlgT+w78Df6Dx6HJg1rIl/enHj06DHmLlqlxhFRUFa+K65lSiBjhujXeyai2MegLRERERERJSiSJerl/hd+Hj5RLRL17v17FayQQGTWLNYG/atVKYcXLz5emhxZPVupdRmWBFYiC9qKtq2a4JcJMzB91mIULpBPtbmWLWnQz82llDY4rBt0XLdpR7j7laxN3WBsVPtFRad2LWBrmwXT//gTI8b+pjL05LJ/3Xqaxs5zbJC5MXb+Ivs8pJ/foSPo3HOYXvZs+26D1P1Fsydog7b9e3XEXys34H8bt+PO3fuqNm3RwgWwdN5kFdyNjXmRbFsJ2saU7KfZDz/hRlCwCtZFd/4kQOnpvhQTp83H1Bkfg4LFixbAoH5dDV7/XePaOHbyH6xZ74Hlazar8gIyf21aNdEGkzetnodeA8dg4vT5KFIwP1Yt/g0t2vTS28+gfl1U8HztBg+s+t8WVePYY/2faB6mn65li6ahW+/hKvApmcJTxw+NftD2C/8exPb4ojovlpZpsH/naoydNAubt3qp8glZrDOp8g2y8JhG0cKOqpzFlu3en76nVihXtqRakE+Cu2E9DgnFXh9/zJo2OlrzRURxx+xDXFfyTgBCQ0NhZWWFkJAQWFoaFo0nIiIiovjB87TEKyAgAJ4e6zGkf6f4HgqRyZEyDk6u9dG4QQ2MGd43vodDJkzq3f4xdynOHd2FlCkt4ns4JuXIsdPYe/AMRo4eG99DoUSKNW2JiIiIiIiIEhApbTBqSC8sWLzGoB4tke4CarPmLVOLlTFgS2R6WB6BiIiIiIiIKIGRcgWyEUUkWbJkuPLPfk4QkYlipi0RERERERERERGRCWHQloiIiIiIiIiIiMiEMGhLREREREREREREZEIYtCUiIiIiIiIiIiIyIQzaEhEREREREREREZkQBm2JiIiIiIiIiIiITAiDtkREREREREREREQmhEFbIiIiIiIiIiIiIhPCoC0RERERERERERGRCTGP7wEQERERERHFpjdv3iAk9GmkfdKmSY0nT599sU+SJGZR2hf7cV74PeB/H/z34Nv+dzJFiuSR9iH62hi0JSIiIiKiBOXQ4eOo0aBtpH0WzZ6Azj2HfbGPg322KO2L/Tgv/B7wvw/+e/Bt/zvZplWTSPsQfW1mHz58+PDVj/qNCQ0NhZWVFUJCQmBpaRnfwyEiIiKiT3ielngFBATA02M9hvTvZPDcf49DcPzk2UhfX9AxD86dv/zFPhYWKaK0L/bjvPB7wP8++O/Bt/3vpE3WzHptR46dxt6DZzBy9NhIX0sUVxi0jQL+MUBERERkmnielnhFFrQlIiKKKQZtKb6xPAIRERERESUor1+/xqP/QiLtkzKlBV68eBlpHyvLtEiaNMkX98V+nBd+D/jfB/89+Pb/nZT/LxCZEgZtiYiIiIgoQfEPOMGatt9YLUn247zwe8D/PuL73wPWtCVTw/IIUcDL7oiIiIhME8/TEi/WtP02akSyH+eF3wP+9/Gt/HvAmrZkahi0jQL+MUBERERkmnielnixpi0REcUl1rSl+JYkvgdARERERERERERERJ8xaEtERERERERERERkQhi0JSIiIiIiIiIiIjIhDNoSERERERERERERmRAGbYmIiIiIiIiIiIhMiEkHbd+9e4eRI0ciZ86cSJkyJXLnzo1ff/0VHz580PaR+6NGjYKNjY3qU61aNVy6dElvP48ePULr1q1haWmJdOnSoWPHjnj69Gk8vCMiIiIiIiIiIiKibzhoO3nyZMybNw+zZ8/Gv//+qx5PmTIFs2bN0vaRxzNnzsT8+fNx+PBhpE6dGjVr1sTLly+1fSRge/bsWezevRvbtm2Dr68vunTpEk/vioiIiIiIiIiIiChi5jBhhw4dQsOGDVG3bl31OEeOHFizZg0CAgK0WbYzZszAiBEjVD+xfPlyZMmSBe7u7mjZsqUK9np6euLIkSNwdnZWfSToW6dOHUybNg22trbx+A6JiIiIiIiIiIiIvqGgraurKxYuXIiLFy8iX758OHXqFPz8/PDbb7+p5wMDA3Hnzh1VEkHDysoKZcqUgb+/vwrayq2URNAEbIX0T5IkicrMbdy4scFxX716pTaN0NBQdfv+/Xu1EREREZFp4LkZERERESVEJh20HTJkiAqYOjo6ImnSpKrG7fjx41W5AyEBWyGZtbrkseY5uc2cObPe8+bm5siQIYO2T1gTJ07EmDFjDNrv37+vV3aBiIiIiOLXkydP+BEQERERUYJj0kHbdevWYdWqVVi9ejUKFSqEkydPom/fvqqkQdu2bePsuEOHDkX//v21jyVwbGdnB2tra7WYGRERERGZBgsLi/geAhERERFR4gra/vzzzyrbVsociCJFiuD69esqE1aCtlmzZlXtd+/ehY2NjfZ18rh48eLqvvS5d++e3n7fvn2LR48eaV8fVooUKdQWlpRUkI2IiIiITAPPzYiIiIgoITLpCOTz588NTsSlTIKmdlnOnDlV4HXPnj16WbFSq9bFxUU9ltvHjx/j2LFj2j579+5V+5Dat0RERERERERERESmxKQzbevXr69q2Nrb26vyCCdOnFCLkHXo0EE9b2ZmpsoljBs3Dnnz5lVB3JEjR6ryCY0aNVJ9ChQogFq1aqFz586YP38+3rx5g549e6rsXelHREREREREREREZEpMOmg7a9YsFYTt0aOHKnEgQdauXbti1KhR2j6DBg3Cs2fP0KVLF5VR6+bmBk9PT736ZlIXVwK1VatWVZm7TZs2xcyZM+PpXRERERERERERERFFzOzDhw8fInmePpVcsLKyQkhICBciIyIiIjIhPE9LvAICAuDpsR5D+neK76EQEVECdOTYaew9eAYjR4+N76FQImXSNW2JiIiIiIiIiIiIEhsGbYmIiIiIiIiIiIhMCIO2RERERERERERERCaEQVsiIiIiIiIiIiIiE8Kg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QdfOXT7qtnTJopxiIiKixF4eQVfGjBmxZcsWDBgwQK9d2uQ5IiIiIiIiih15i1VB00a1VS3Zm0HBmDV/uVqwzKlYIU4xERFRAmZ00HbMmDHo1KkT9u/fjzJlyqi2w4cPw9PTE4sWRa/APRERERERERmqV6sKPHf7YOmK9bCyTItWzRtg0phBnCoiIqIEzuigbbt27VCgQAHMnDkTmzZtUm3y2M/PTxvEJSIiIiIiophbMGs8p5GIiCgRMjpoKyQ4u2rVqtgfDREREREREREREVEiF62g7fv373H58mXcu3dP3ddVoUKF2BobERERERERERERUaJjdND277//RqtWrXD9+nV8+PBB7zkzMzO8e/cuNsdHRERERERERERElKgkMfYF3bp1g7OzM/755x88evQI//33n3aTx0RERERERAmFj99hpMjgqLYLl65q20NDnyJt1iKqffnqj2t9xJXA60HaMVy+eh2mZst2b8yct+yrHW/XngNo2KIrchaqAEubonAsUR19B/+Kh4/+i/R1g0dOVnPYZ9DYaB336PEz6NJzGAqUrIF02YqjUKmaGDJqCp48eRqnxyUiosTJ6EzbS5cuYcOGDciTJ0/cjIiIiIiIiMjEpExpAY8de5C/Ty712HO3D5ImTQrgTZwf28vbFxkzpNMGLPPkcoAp8djhDV+/APTu3varHO/02QtIlswc3Tq2QmbrTAi6dRvzF6/GPp+/cXj/JlhYpDB4zdVrN7F42boYHXfGnKX4O+AEmjWpg7y5c+D8xSuYu2gl9h/4G36718Hc3DxOjktERImTeXQWIZN6tgzaEhERERFRYlGlogu2bvfGwD6d1eOtO/agaiVXbNu596sEbSu6lVHl6by8D6BH5x+QmA3s3cmgzal4ITRt1QM7vPahScNaBs8PGz0VbVo1wZyFK6J9XAlK/7Vgil5w1i67LQYOm6C+B43q14iT4xIRUeJkdHmEXr16YcCAAfjrr79w7NgxnD59Wm8jIiIiIiJKaOrUqITjp87hzt37eP36tQqk1q9d1aDf/QeP0L3vSNg7uqlL98tUaoKdu320z1+78bHUwchff4NtnrIoVrYu/A8fR6kKjWCTuwwWLFmjt79Xr17Dxy8AlSu6qE3KNbx8+crguL4HA1C6YmN1TOfyDVVGqBzn10mzjBqfkHIP8tojx06j2Y89kdG+hCpB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iIiIiIiIiIiIKBExOmhrbm6Oxo0bY8uWLbh58yY6d+6MVatWwd7eHg0aNFDt79+/j5vREhERERERERERESVwMVqILEuWLHBzc4OLiwuSJEmCM2fOoG3btsidOzf2798fe6MkIiIiIiIiIiIiSiSiFbS9e/cupk2bhkKFCqkSCaGhodi2bRsCAwNV+YTmzZur4C0RERERERERERERxXHQtn79+rCzs8Nff/2lSiNIkHbNmjWoVq2aej516tQYMGCAKp1ARERERERERERERMYxN7I/MmfODB8fH1USISLW1tYq65aIiIiIiIiIiIiI4jhou3jx4i/2MTMzg4ODg7G7JiIiIiIiIiIiIkr0jC6P0Lt3b8ycOdOgffbs2ejbt2+in1AiIiIiIiIiIiKirxq03bhxI8qVK2fQ7urqig0bNsRoMERERERERERERESJndFB24cPH8LKysqg3dLSEg8ePIitcRERERERERERERElSkYHbfPkyQNPT0+D9p07dyJXrlyxNS4iIiIiIiIiIiKiRMnooG3//v0xaNAgjB49Gj4+PmobNWoUhgwZgn79+sXNKImIiIiIiIi+QRs270TWXGXw5MlTvfblqzchRQZHXLsRFOV9/TpplnpNTETnuPElNt5vQpyX2PLmzRvkLlwJ8xevju+hEFFsBG07dOiA6dOnY/HixahcubLaVq5ciXnz5qFz587G7o6IiIiIiChW+fgdVsGXTVs8Y9xP00e2C5euattDQ58ibdYiql2CPdFhaVNUu2/ZGrXsqvd89fo/wsm1vsHrwrbnK1ZFvd4iYwHY5C6DWo3bq0BheN6/f68CNKUqNIKVbTHkLVoFnX4agktXrhkEr8LbKtduFa33evjISdRt2hGZ7Esig10JNf6BwybicUioQd9dew6gRoM2qm/mHKXUMbfu2KPX51bwXbTu0E89n9G+BOp91wn/Xrii10czL7KlzlwYBUrWQLfeI9RrdcXF+9V49+4dxk6ahW4dWyFt2jQx2hd9m7Zs98bMectirV9sSpYsGXr3aIfJv83Hy5evvuqxiejLzBEN3bt3V9v9+/eRMmVKpEnD//kQEREREVHClTKlBTx27EH+Ph9Lwnnu9kHSpEklVy3a+1w0ewLevXuv7v88fGKMxlesSAH07t4Wd+89xLade9C6Yz8cOX4ak38drNfvp36jsWTFejSs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WPphfPjR6vhSuw5x6oBTok2bNjXdLeoxoS0AAFBrHXroobHvvvvG66+/nhc/XLVqVU13CYBaegVH15YtY+edd47OnTtb5JIaJ7QFAABqtZYtW0b37t1ruhsAANVGaAsAVLs0023cuHHx1ltvxY477hhnn312NGnSxJkGAACoAqEtAFCtLrzwwrj++uvjk08+Kd93wQUXxHnnnRejR492tgEAADai4cYaAJvHmjVrYsaMGXHXXXfl+7QNUBsD2zFjxkS7du3illtuyfUl033aTvvTcQAAADasQaFQKGykTb23dOnSKCkpidLSUisHsklMmTIlBg8eHPPnzy/ft8MOO8S1114bxx57rLMO1JqSCKmuZApo33777Wjc+D8X9KRZtx07dox//etfsXz5cqUSqDbepwEAUBeZaQtFENj2798/dtttt+jXr18cfvjh+T5tp/3pOEBtkGrYpnD2yiuvrBTYJml7xIgR+XhqBwAAwGdT0xZqUCqBkGbYtm/fPh566KF1jnfo0CHOP//86NOnTzRq1KhG+ghQ5qOPPorXX3/9M0/IrFmz8n3nzp3j+eefjxUrVuQrCNKVA82bN48uXbqUtzvkkEPW+xy77rprtGjRwkkHAADqNeURqsBld2wqqXbtYYcdlr9Oq6oPGjQoTj/99JgwYUJcd911+VLj5IknnohevXr5QQA1KgWx3bt336SvMWfOnNhnn3026WtQt3ifBgBAXWSmLdSgf/zjH+WB7bJly8prPI4aNSqGDx8erVu3zsFtWTuAmpRmwaZQ9bOk8erggw/OdeAffvjheOONN+Kkk06KO+64I3beeef41re+levDP/30059Z0za9BgAAQH1Xr0Lbm266Ka9cvXjx4thrr73ihhtuiP3337+mu0U9dv/99+f7448/fp0AI20fd9xxceedd+Z2AwYMqKFeAnXZ26/PiWXvvFHl9s03cuySU4+OqVOnxkXfPypfIfC1bRrGm0/9LiaMnBFdmpTGMaceEyUfzY/4aP3P8Y8//63KfWm93c7RcddNO/MXAACgJtSb0Paee+7Jl57ffPPNccABB8TYsWOjd+/eMXfu3FxPFGqi/uOiRYvyfWrz3HPPxccff1xe/7Fp06b597OsXboseX3UfwS+qAULFsRvzj00Lj24+mpmj9g+YsQZrVLV7oh4PC7PXz8el383HU1fz4h4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+e1vf5s/WNpll13yc6bXrzhOzps3L/r37x99+/bNZWbOOOOMPHZV9NZbb+WrHPr16xcvvfRSDoFTiHvuuedWanfttdfGvvvuGy+88EKcffbZOSieO3duPjZ79ux8P3369DzmVQyyAQAAiloB2KABAwYUGjVqVGjZsmX5rX///vnYJZdcUmjcuHGhbdu2haOOOqowevTowuLFiys9vrS0tNC8efPCiy++mLdfeOGFQqtWrQrLli0rb3PAAQcUzjnnnEqP+/rXv17Ya6+9yrd33HHHwqRJkyq1GTlyZOHAAw/MX8+bNy8lIoUJEyaUH3/llVfyvtdeey1vT5w4sVBSUuInDnV4vOrTp09hyZIlhaZNmxbmz5+fb82aNSu89957+Vhqs3LlykKLFi0KzzzzTKXHn3baaYUTTjghf/3EE0/k8WP69Onlx0eNGpX3vfXWW+X7zjjjjELv3r0rPc9BBx1UGDt2bP569erVha222io/X5mLLrqosPvuu1d6zKWXXpqf+/333y/vy49+9KNKbZ566qlCw4YNCytWrMjbXbp0KZx00knlx9euXVto3759Yfz48ZXGxTTuAgAA1CZm2kIVpEt308zVstvPf/7zvD/Nel28eHGeqfbVr34136fZZX/961/LH3vXXXfFjjvumC89TlLJgy5duuRZY2XSrLD999+/0mtW3E6XA6dZZ6eddlq0atWq/JZKKqT9Fe25557lX2+77bb5fn0LowF119Zbb11eliDNuE1fb7XVVuXH00KKqaTBN7/5zUpjSpp5u6ExpUOHDrn0ype//OVK+yqOMWk8SzNc0yz/pHHjxnmBxopXGKQ2++23X6XX+fQYmGbgpv5X7F/v3r1zWYc0U3d9/UslENJVEMY8AACgtmtc0x2A2qBly5ax0047rfdYu3bt4rjjjsu3VLIg1U685ppryssWpKAiXXqcgosyKXRIlwunELYqUn3I5JZbbokDDjig0rG0OntFqQRDxQCj7PWA+lcioayUwE033bTeMSWVN9h+++3XqeG9oTGl4nbZvopjTBrzUkmWtChjmVQaIT1vKrNQUlJSpf6nPqayCamO7adVXFBtY/0BAACojYS2UI2aNGmSZ9WWLZSTZtw+99xzeUGftm3blrf797//nRfEef3118vrPj777LPx/e9/v7xN2q44ky0FIH//+9/je9/73n/VvzVr1nzhxwO1R6oHu2rVqhxiphmqFe222245RF2wYEEceuih1faaKaxNs3VTndkjjzyy0rFUvzZdeXDmmWfmMe+hhx6qdLzimFe2oNqrr776mR+YVXXMS4x7AABAbSO0hS9o6tSpcffdd8d3v/vdvOBXmkn24IMP5iCibAGgNOMsXfJ7yCGHrPP4dGlwOj5mzJgYOHBg/PCHP8yL6aQFw1LphLTwTsVLkIcPH55nnKVZaimM+fjjj3Mg/P7778egQYOq1Oe00nqavfb444/ncg3pMud0A+qeNAs/LVpY9nVFrVu3zgsRpsXH0qzUgw8+OEpLS+NPf/pTXqxwwIABX3hcTGNSuorg0zNq04JiacxLoW2aQXvdddfFRRddlNumsjOpFELFKwTSsR49euTZwqeffnq+4iGFuI899liesVsV7du3j+bNm8e0adOiY8eO0axZsyrP9AUAAKhJatrCF5RmqqXAc/DgwblObQoX0orpEyZMiJNPPjnPcLvjjjtyULE+aX+akbZ69eo8e3bIkCE5REmzy1K9xlNOOSUHDGVSaJGeOwXCe+yxR54dl0KOrl27VrnPKRBOgUmqL5lqXo4ePdrPH+qwFMCm2/qMHDkyhg4dGqNGjYpu3brlD4NSuYTPM6Z8WgpljzjiiPUGo2nMSx80pQ+k0mtMnjw5pkyZkmvSjh8/Pi699NJK5RnS/pkzZ8bf/va36NmzZy49M2zYsEplFzYmlaVJNch/8Ytf5Mf16dPnC39vAAAAm1ODtBrZZn1FoErSAkFpQZ3f/OY3zhhQ56WFHdNijgsXLqzprgAAANQ45RGgCKRV3FNYkepOpsuYU93H6dOn58uAAeqicePG5TIxaTHHVJYhlYopWzgNAACgvhPaQhFINRxTLdw002zlypV5kZ7f/e53+TJjgLrojTfeiCuvvDIvzNi5c+dcaiaViQEAAEB5BAAAAACAomIhMgAAAACAIiK0BQAAAAAoIkJbAAAAAIAiIrQFAAAAACgiQlsAAAAAgCIitAUAAAAAKCJCWwAAAACAIiK0BQAAAAAoIkJbAAAAAIAoHv8feQUgGgacMGcAAAAASUVORK5CYII=", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "[OK] Saved: corpus_benchmark_results.png\n" ] } ], "source": [ "# 3.9.7 Corpus Benchmark Visualization\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "\n", "fig, axes = plt.subplots(2, 2, figsize=(14, 10))\n", "fig.suptitle(\"Corpus Benchmark: FSAgent (Grep) vs MemAgent (Vector Search)\", fontsize=14, fontweight='bold')\n", "\n", "FS_COLOR, MEM_COLOR = \"#3498db\", \"#e74c3c\"\n", "\n", "# 1. Latency per Query\n", "ax1 = axes[0, 0]\n", "query_nums = range(1, len(CORPUS_QUERIES) + 1)\n", "ax1.bar([x - 0.2 for x in query_nums], fs_latencies, 0.4, label='FSAgent', color=FS_COLOR)\n", "ax1.bar([x + 0.2 for x in query_nums], mem_latencies, 0.4, label='MemAgent', color=MEM_COLOR)\n", "ax1.set_xlabel('Query #')\n", "ax1.set_ylabel('Latency (seconds)')\n", "ax1.set_title('Latency per Query')\n", "ax1.legend()\n", "ax1.grid(axis='y', alpha=0.3)\n", "\n", "# 2. LLM Judge Scores per Query\n", "ax2 = axes[0, 1]\n", "ax2.bar([x - 0.2 for x in query_nums], corpus_llm_scores[\"fsagent\"], 0.4, label='FSAgent', color=FS_COLOR)\n", "ax2.bar([x + 0.2 for x in query_nums], corpus_llm_scores[\"memagent\"], 0.4, label='MemAgent', color=MEM_COLOR)\n", "ax2.set_xlabel('Query #')\n", "ax2.set_ylabel('LLM Judge Score (%)')\n", "ax2.set_title('LLM Judge Score per Query')\n", "ax2.set_ylim(0, 110)\n", "ax2.legend()\n", "ax2.grid(axis='y', alpha=0.3)\n", "\n", "# 3. Latency Comparison (Box Plot)\n", "ax3 = axes[1, 0]\n", "bp = ax3.boxplot([fs_latencies, mem_latencies], labels=['FSAgent', 'MemAgent'], patch_artist=True)\n", "bp['boxes'][0].set_facecolor(FS_COLOR)\n", "bp['boxes'][1].set_facecolor(MEM_COLOR)\n", "ax3.set_ylabel('Latency (seconds)')\n", "ax3.set_title('Latency Distribution')\n", "ax3.grid(axis='y', alpha=0.3)\n", "\n", "# 4. Overall Summary - Show actual values\n", "ax4 = axes[1, 1]\n", "ax4.axis('off') # Turn off axis for text-based summary\n", "\n", "fs_avg_lat = statistics.mean(fs_latencies)\n", "mem_avg_lat = statistics.mean(mem_latencies)\n", "latency_winner = 'FSAgent' if fs_avg_lat < mem_avg_lat else 'MemAgent'\n", "llm_winner = 'FSAgent' if fs_avg_corpus > mem_avg_corpus else 'MemAgent'\n", "\n", "summary_text = f\"\"\"\n", "OVERALL COMPARISON (Actual Values)\n", "{'='*40}\n", "\n", "AVERAGE LATENCY (lower is better):\n", " FSAgent: {fs_avg_lat:.2f}s\n", " MemAgent: {mem_avg_lat:.2f}s\n", " Winner: {latency_winner}\n", "\n", "LLM JUDGE SCORE (higher is better):\n", " FSAgent: {fs_avg_corpus:.1f}%\n", " MemAgent: {mem_avg_corpus:.1f}%\n", " Winner: {llm_winner}\n", "\n", "{'='*40}\n", "\"\"\"\n", "\n", "ax4.text(0.1, 0.5, summary_text, transform=ax4.transAxes, fontsize=12,\n", " verticalalignment='center', fontfamily='monospace',\n", " bbox=dict(boxstyle='round', facecolor='wheat', alpha=0.5))\n", "ax4.set_title('Overall Summary')\n", "\n", "plt.tight_layout()\n", "plt.savefig(\"corpus_benchmark_results.png\", dpi=150, bbox_inches='tight')\n", "plt.show()\n", "print(\"\\n[OK] Saved: corpus_benchmark_results.png\")" ] }, { "cell_type": "markdown", "id": "ws58ni0gq1i", "metadata": {}, "source": [ "> 💡 **Key Takeaways**\n", "> - **Large corpus handling**: FSAgent requires multiple grep/read operations; MemAgent retrieves directly via vector similarity\n", "> - **Latency trade-off**: FSAgent may be slower on large files due to sequential search; MemAgent benefits from indexed retrieval\n", "> - **Response quality**: LLM Judge scores reveal which approach produces more relevant, comprehensive answers\n", "> - **Scalability**: Chunked embeddings scale better for growing corpora; concatenated files hit practical limits" ] }, { "cell_type": "markdown", "id": "part5_intro_acid_001", "metadata": {}, "source": [ "# Part 4: ACID Transactions & Concurrency\n", "\n", "----\n", "\n", "A critical difference between filesystem and database storage that's often overlooked: **how they handle concurrent access**.\n", "\n", "When multiple processes or threads try to write to the same resource simultaneously:\n", "\n", "| Property | Filesystem | Database (ACID) |\n", "|----------|------------|------------------|\n", "| **Atomicity** | No - partial writes can corrupt files | Yes - all or nothing |\n", "| **Consistency** | No constraint enforcement | Yes - constraints, foreign keys |\n", "| **Isolation** | No - concurrent reads see incomplete writes | Yes - transaction isolation |\n", "| **Durability** | Depends on fsync | Yes - WAL, redo logs |\n", "\n", "This matters for agents because:\n", "- Multiple users might query the same knowledge base\n", "- Background processes might be indexing while users are querying\n", "- A crash during write could corrupt the memory store\n", "\n", "Let's demonstrate this with a practical test." ] }, { "cell_type": "markdown", "id": "part5_setup_header_002", "metadata": {}, "source": [ "## 4.1 Concurrency Test Setup\n", "\n", "We'll simulate multiple concurrent writers trying to append entries to:\n", "1. A shared file (FSAgent pattern)\n", "2. A database table (MemAgent pattern)\n", "\n", "Each writer will append 50 entries. With 10 concurrent writers, we expect **500 total entries** if everything works correctly." ] }, { "cell_type": "code", "execution_count": 63, "id": "part5_test_setup_003", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[OK] Test configured: 10 writers × 50 writes = 500 expected entries\n" ] } ], "source": [ "# Concurrency Test Configuration\n", "import threading\n", "import time\n", "from pathlib import Path\n", "from concurrent.futures import ThreadPoolExecutor, as_completed\n", "\n", "NUM_WRITERS = 10 # Number of concurrent threads\n", "WRITES_PER_THREAD = 50 # Entries each thread writes\n", "EXPECTED_TOTAL = NUM_WRITERS * WRITES_PER_THREAD # 500\n", "\n", "# Test file path (reuses episodic directory from FSAgent)\n", "CONCURRENCY_TEST_FILE = Path(\"episodic\") / \"concurrency_test.md\"\n", "\n", "# Test table (reuses database_connection from MemAgent)\n", "CONCURRENCY_TEST_TABLE = \"CONCURRENCY_TEST\"\n", "\n", "print(f\"[OK] Test configured: {NUM_WRITERS} writers × {WRITES_PER_THREAD} writes = {EXPECTED_TOTAL} expected entries\")" ] }, { "cell_type": "markdown", "id": "part5_file_test_header_004", "metadata": {}, "source": [ "## 4.2 Filesystem Concurrency Test (Naive - No Locking)\n", "\n", "Multiple threads will append to the same file simultaneously using a **read-modify-write** pattern without any locking. This is a common anti-pattern known as [TOCTOU (Time-of-check to time-of-use)](https://en.wikipedia.org/wiki/Time-of-check_to_time-of-use) that causes **race conditions**:\n", "\n", "- Lost writes (one thread's write overwrites another's)\n", "- Corrupted content (interleaved partial writes)\n", "- Missing entries\n", "\n", "> **Note:** This demonstrates what happens when filesystem code is written naively. We'll show a properly locked version next." ] }, { "cell_type": "code", "execution_count": 64, "id": "part5_file_test_005", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[OK] File concurrency test ready\n" ] } ], "source": [ "def file_writer(writer_id: int, num_writes: int, filepath: Path) -> int:\n", " \"\"\"\n", " Simulate FSAgent-style file append without locking.\n", " Returns the number of writes attempted.\n", " \"\"\"\n", " for i in range(num_writes):\n", " entry = f\"[Writer-{writer_id}] Entry {i+1} @ {_ts_utc()}\\n\"\n", " \n", " # FSAgent pattern: read existing + append + write back\n", " # This is NOT atomic and creates a race condition\n", " try:\n", " existing = filepath.read_text() if filepath.exists() else \"\"\n", " filepath.write_text(existing + entry)\n", " except Exception as e:\n", " pass # Silently fail (simulates real-world issues)\n", " \n", " return num_writes\n", "\n", "\n", "def run_file_concurrency_test() -> dict:\n", " \"\"\"Run concurrent file writers and count results.\"\"\"\n", " \n", " # Clean start\n", " if CONCURRENCY_TEST_FILE.exists():\n", " CONCURRENCY_TEST_FILE.unlink()\n", " CONCURRENCY_TEST_FILE.parent.mkdir(parents=True, exist_ok=True)\n", " CONCURRENCY_TEST_FILE.write_text(\"# Concurrency Test\\n\\n\")\n", " \n", " print(f\"Starting {NUM_WRITERS} concurrent file writers...\")\n", " start_time = time.perf_counter()\n", " \n", " # Launch concurrent writers\n", " with ThreadPoolExecutor(max_workers=NUM_WRITERS) as executor:\n", " futures = [\n", " executor.submit(file_writer, i, WRITES_PER_THREAD, CONCURRENCY_TEST_FILE)\n", " for i in range(NUM_WRITERS)\n", " ]\n", " for f in as_completed(futures):\n", " f.result() # Wait for all to complete\n", " \n", " elapsed = time.perf_counter() - start_time\n", " \n", " # Count actual entries written\n", " content = CONCURRENCY_TEST_FILE.read_text()\n", " actual_entries = content.count(\"[Writer-\")\n", " \n", " # Count entries per writer\n", " writer_counts = {}\n", " for i in range(NUM_WRITERS):\n", " writer_counts[f\"Writer-{i}\"] = content.count(f\"[Writer-{i}]\")\n", " \n", " return {\n", " \"expected\": EXPECTED_TOTAL,\n", " \"actual\": actual_entries,\n", " \"lost\": EXPECTED_TOTAL - actual_entries,\n", " \"loss_rate\": (EXPECTED_TOTAL - actual_entries) / EXPECTED_TOTAL * 100,\n", " \"elapsed_ms\": elapsed * 1000,\n", " \"writer_counts\": writer_counts,\n", " }\n", "\n", "print(\"[OK] File concurrency test ready\")" ] }, { "cell_type": "code", "execution_count": 65, "id": "part5_run_file_test_006", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "============================================================\n", "FILESYSTEM CONCURRENCY TEST (No Locking)\n", "============================================================\n", "Starting 10 concurrent file writers...\n", "\n", "Results:\n", " Expected entries: 500\n", " Actual entries: 14\n", " Lost entries: 486 (97.2% loss)\n", " Time elapsed: 33ms\n", "\n", "Entries per writer:\n", " Writer-0: 1/50 [LOST 49]\n", " Writer-1: 2/50 [LOST 48]\n", " Writer-2: 1/50 [LOST 49]\n", " Writer-3: 0/50 [LOST 50]\n", " Writer-4: 1/50 [LOST 49]\n", " Writer-5: 1/50 [LOST 49]\n", " Writer-6: 3/50 [LOST 47]\n", " Writer-7: 3/50 [LOST 47]\n", " Writer-8: 0/50 [LOST 50]\n", " Writer-9: 2/50 [LOST 48]\n", "\n", "[WARNING] Race condition detected! 486 writes were lost.\n" ] } ], "source": [ "# Run Filesystem Concurrency Test\n", "print(\"=\" * 60)\n", "print(\"FILESYSTEM CONCURRENCY TEST (No Locking)\")\n", "print(\"=\" * 60)\n", "\n", "file_results = run_file_concurrency_test()\n", "\n", "print(f\"\\nResults:\")\n", "print(f\" Expected entries: {file_results['expected']}\")\n", "print(f\" Actual entries: {file_results['actual']}\")\n", "print(f\" Lost entries: {file_results['lost']} ({file_results['loss_rate']:.1f}% loss)\")\n", "print(f\" Time elapsed: {file_results['elapsed_ms']:.0f}ms\")\n", "\n", "print(f\"\\nEntries per writer:\")\n", "for writer, count in file_results['writer_counts'].items():\n", " expected = WRITES_PER_THREAD\n", " status = '[OK]' if count == expected else f'[LOST {expected - count}]'\n", " print(f\" {writer}: {count}/{expected} {status}\")\n", "\n", "if file_results['lost'] > 0:\n", " print(f\"\\n[WARNING] Race condition detected! {file_results['lost']} writes were lost.\")\n", "else:\n", " print(f\"\\n[OK] No data loss (may vary between runs)\")" ] }, { "cell_type": "markdown", "id": "zjkh6lk3bee", "metadata": {}, "source": [ "## 4.2b Filesystem Concurrency Test (With Locking)\n", "\n", "Now let's run the same test but with **proper file locking** using `fcntl.flock()`. This demonstrates that filesystems CAN handle concurrency safely when implemented correctly:\n", "\n", "- **Exclusive lock (LOCK_EX)** ensures only one writer at a time\n", "- **Append mode** is more atomic than read-modify-write\n", "- Trade-off: Slower due to lock contention, but guarantees data integrity\n", "\n", "> **Note:** `flock()` works on local filesystems but has limitations on NFS and network shares." ] }, { "cell_type": "code", "execution_count": 66, "id": "e9dlm71sty9", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[OK] Locked file concurrency test ready\n" ] } ], "source": [ "import fcntl\n", "\n", "# Test file for locked writes\n", "CONCURRENCY_TEST_FILE_LOCKED = Path(\"episodic\") / \"concurrency_test_locked.md\"\n", "\n", "def file_writer_with_lock(writer_id: int, num_writes: int, filepath: Path) -> int:\n", " \"\"\"\n", " Filesystem append with proper locking using fcntl.flock().\n", " This is the CORRECT way to handle concurrent file writes.\n", " \"\"\"\n", " for i in range(num_writes):\n", " entry = f\"[Writer-{writer_id}] Entry {i+1} @ {_ts_utc()}\\n\"\n", " \n", " # Proper pattern: open in append mode with exclusive lock\n", " with open(filepath, 'a') as f:\n", " fcntl.flock(f.fileno(), fcntl.LOCK_EX) # Acquire exclusive lock\n", " f.write(entry)\n", " f.flush() # Ensure write is complete\n", " fcntl.flock(f.fileno(), fcntl.LOCK_UN) # Release lock\n", " \n", " return num_writes\n", "\n", "\n", "def run_file_concurrency_test_locked() -> dict:\n", " \"\"\"Run concurrent file writers WITH locking and count results.\"\"\"\n", " \n", " # Clean start\n", " if CONCURRENCY_TEST_FILE_LOCKED.exists():\n", " CONCURRENCY_TEST_FILE_LOCKED.unlink()\n", " CONCURRENCY_TEST_FILE_LOCKED.parent.mkdir(parents=True, exist_ok=True)\n", " CONCURRENCY_TEST_FILE_LOCKED.write_text(\"# Concurrency Test (Locked)\\n\\n\")\n", " \n", " print(f\"Starting {NUM_WRITERS} concurrent file writers WITH locking...\")\n", " start_time = time.perf_counter()\n", " \n", " # Launch concurrent writers\n", " with ThreadPoolExecutor(max_workers=NUM_WRITERS) as executor:\n", " futures = [\n", " executor.submit(file_writer_with_lock, i, WRITES_PER_THREAD, CONCURRENCY_TEST_FILE_LOCKED)\n", " for i in range(NUM_WRITERS)\n", " ]\n", " for f in as_completed(futures):\n", " f.result()\n", " \n", " elapsed = time.perf_counter() - start_time\n", " \n", " # Count actual entries written\n", " content = CONCURRENCY_TEST_FILE_LOCKED.read_text()\n", " actual_entries = content.count(\"[Writer-\")\n", " \n", " # Count entries per writer\n", " writer_counts = {}\n", " for i in range(NUM_WRITERS):\n", " writer_counts[f\"Writer-{i}\"] = content.count(f\"[Writer-{i}]\")\n", " \n", " return {\n", " \"expected\": EXPECTED_TOTAL,\n", " \"actual\": actual_entries,\n", " \"lost\": EXPECTED_TOTAL - actual_entries,\n", " \"loss_rate\": (EXPECTED_TOTAL - actual_entries) / EXPECTED_TOTAL * 100,\n", " \"elapsed_ms\": elapsed * 1000,\n", " \"writer_counts\": writer_counts,\n", " }\n", "\n", "print(\"[OK] Locked file concurrency test ready\")" ] }, { "cell_type": "code", "execution_count": 67, "id": "7s9glw77qlr", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "============================================================\n", "FILESYSTEM CONCURRENCY TEST (With flock Locking)\n", "============================================================\n", "Starting 10 concurrent file writers WITH locking...\n", "\n", "Results:\n", " Expected entries: 500\n", " Actual entries: 500\n", " Lost entries: 0 (0.0% loss)\n", " Time elapsed: 15ms\n", "\n", "Entries per writer:\n", " Writer-0: 50/50 [OK]\n", " Writer-1: 50/50 [OK]\n", " Writer-2: 50/50 [OK]\n", " Writer-3: 50/50 [OK]\n", " Writer-4: 50/50 [OK]\n", " Writer-5: 50/50 [OK]\n", " Writer-6: 50/50 [OK]\n", " Writer-7: 50/50 [OK]\n", " Writer-8: 50/50 [OK]\n", " Writer-9: 50/50 [OK]\n", "\n", "[OK] Zero data loss - File locking ensures consistency!\n" ] } ], "source": [ "# Run Locked Filesystem Concurrency Test\n", "print(\"=\" * 60)\n", "print(\"FILESYSTEM CONCURRENCY TEST (With flock Locking)\")\n", "print(\"=\" * 60)\n", "\n", "file_locked_results = run_file_concurrency_test_locked()\n", "\n", "print(f\"\\nResults:\")\n", "print(f\" Expected entries: {file_locked_results['expected']}\")\n", "print(f\" Actual entries: {file_locked_results['actual']}\")\n", "print(f\" Lost entries: {file_locked_results['lost']} ({file_locked_results['loss_rate']:.1f}% loss)\")\n", "print(f\" Time elapsed: {file_locked_results['elapsed_ms']:.0f}ms\")\n", "\n", "print(f\"\\nEntries per writer:\")\n", "for writer, count in file_locked_results['writer_counts'].items():\n", " expected = WRITES_PER_THREAD\n", " status = '[OK]' if count == expected else f'[LOST {expected - count}]'\n", " print(f\" {writer}: {count}/{expected} {status}\")\n", "\n", "if file_locked_results['lost'] > 0:\n", " print(f\"\\n[WARNING] Data loss detected: {file_locked_results['lost']} writes were lost.\")\n", "else:\n", " print(f\"\\n[OK] Zero data loss - File locking ensures consistency!\")" ] }, { "cell_type": "markdown", "id": "part5_db_test_header_007", "metadata": {}, "source": [ "## 4.3 Database Concurrency Test\n", "\n", "Now the same test using database INSERT operations. The database handles concurrency through:\n", "- **Row-level locking** - Writers don't block each other\n", "- **ACID transactions** - Each INSERT is atomic\n", "- **Isolation** - No interference between concurrent writes\n", "\n", "We expect **zero data loss**." ] }, { "cell_type": "code", "execution_count": 68, "id": "part5_db_test_008", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[OK] Database concurrency test ready\n" ] } ], "source": [ "def setup_concurrency_test_table(conn) -> str:\n", " \"\"\"Create a simple test table for concurrency testing.\"\"\"\n", " columns = [\n", " (\"id\", \"VARCHAR2(32) DEFAULT RAWTOHEX(SYS_GUID()) PRIMARY KEY\"),\n", " (\"writer_id\", \"NUMBER NOT NULL\"),\n", " (\"entry_num\", \"NUMBER NOT NULL\"),\n", " (\"content\", \"VARCHAR2(500)\"),\n", " (\"created_at\", \"TIMESTAMP DEFAULT CURRENT_TIMESTAMP\"),\n", " ]\n", " return create_table(conn, CONCURRENCY_TEST_TABLE, columns, drop_if_exists=True)\n", "\n", "\n", "def db_writer(writer_id: int, num_writes: int, conn) -> int:\n", " \"\"\"\n", " Simulate MemAgent-style database insert.\n", " Each INSERT is atomic and isolated.\n", " \"\"\"\n", " for i in range(num_writes):\n", " content = f\"[Writer-{writer_id}] Entry {i+1} @ {_ts_utc()}\"\n", " \n", " with conn.cursor() as cur:\n", " cur.execute(\n", " f\"INSERT INTO {CONCURRENCY_TEST_TABLE} (writer_id, entry_num, content) \"\n", " f\"VALUES (:writer_id, :entry_num, :content)\",\n", " {\"writer_id\": writer_id, \"entry_num\": i + 1, \"content\": content}\n", " )\n", " conn.commit()\n", " \n", " return num_writes\n", "\n", "\n", "def run_db_concurrency_test(conn) -> dict:\n", " \"\"\"Run concurrent database writers and count results.\"\"\"\n", " \n", " # Create fresh table\n", " setup_concurrency_test_table(conn)\n", " \n", " print(f\"Starting {NUM_WRITERS} concurrent database writers...\")\n", " start_time = time.perf_counter()\n", " \n", " # Launch concurrent writers\n", " with ThreadPoolExecutor(max_workers=NUM_WRITERS) as executor:\n", " futures = [\n", " executor.submit(db_writer, i, WRITES_PER_THREAD, conn)\n", " for i in range(NUM_WRITERS)\n", " ]\n", " for f in as_completed(futures):\n", " f.result() # Wait for all to complete\n", " \n", " elapsed = time.perf_counter() - start_time\n", " \n", " # Count actual entries\n", " with conn.cursor() as cur:\n", " cur.execute(f\"SELECT COUNT(*) FROM {CONCURRENCY_TEST_TABLE}\")\n", " actual_entries = cur.fetchone()[0]\n", " \n", " # Count per writer\n", " cur.execute(\n", " f\"SELECT writer_id, COUNT(*) FROM {CONCURRENCY_TEST_TABLE} \"\n", " f\"GROUP BY writer_id ORDER BY writer_id\"\n", " )\n", " writer_counts = {f\"Writer-{row[0]}\": row[1] for row in cur.fetchall()}\n", " \n", " return {\n", " \"expected\": EXPECTED_TOTAL,\n", " \"actual\": actual_entries,\n", " \"lost\": EXPECTED_TOTAL - actual_entries,\n", " \"loss_rate\": (EXPECTED_TOTAL - actual_entries) / EXPECTED_TOTAL * 100,\n", " \"elapsed_ms\": elapsed * 1000,\n", " \"writer_counts\": writer_counts,\n", " }\n", "\n", "print(\"[OK] Database concurrency test ready\")" ] }, { "cell_type": "code", "execution_count": 69, "id": "part5_run_db_test_009", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "============================================================\n", "DATABASE CONCURRENCY TEST (ACID Transactions)\n", "============================================================\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Failed to send compressed multipart ingest: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/multipart. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/multipart', '{\"error\":\"Unauthorized\"}\\n')trace=019c0bd5-6007-72a1-be26-92a669549599,id=019c0bd5-6007-72a1-be26-92a669549599\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Table CONCURRENCY_TEST created successfully\n", "Starting 10 concurrent database writers...\n", "\n", "Results:\n", " Expected entries: 500\n", " Actual entries: 500\n", " Lost entries: 0 (0.0% loss)\n", " Time elapsed: 656ms\n", "\n", "Entries per writer:\n", " Writer-0: 50/50 [OK]\n", " Writer-1: 50/50 [OK]\n", " Writer-2: 50/50 [OK]\n", " Writer-3: 50/50 [OK]\n", " Writer-4: 50/50 [OK]\n", " Writer-5: 50/50 [OK]\n", " Writer-6: 50/50 [OK]\n", " Writer-7: 50/50 [OK]\n", " Writer-8: 50/50 [OK]\n", " Writer-9: 50/50 [OK]\n", "\n", "[OK] Zero data loss - ACID transactions guarantee consistency\n" ] } ], "source": [ "# Run Database Concurrency Test\n", "print(\"=\" * 60)\n", "print(\"DATABASE CONCURRENCY TEST (ACID Transactions)\")\n", "print(\"=\" * 60)\n", "\n", "db_results = run_db_concurrency_test(database_connection)\n", "\n", "print(f\"\\nResults:\")\n", "print(f\" Expected entries: {db_results['expected']}\")\n", "print(f\" Actual entries: {db_results['actual']}\")\n", "print(f\" Lost entries: {db_results['lost']} ({db_results['loss_rate']:.1f}% loss)\")\n", "print(f\" Time elapsed: {db_results['elapsed_ms']:.0f}ms\")\n", "\n", "print(f\"\\nEntries per writer:\")\n", "for writer, count in db_results['writer_counts'].items():\n", " expected = WRITES_PER_THREAD\n", " status = '[OK]' if count == expected else f'[LOST {expected - count}]'\n", " print(f\" {writer}: {count}/{expected} {status}\")\n", "\n", "if db_results['lost'] > 0:\n", " print(f\"\\n[ERROR] Unexpected data loss: {db_results['lost']} writes\")\n", "else:\n", " print(f\"\\n[OK] Zero data loss - ACID transactions guarantee consistency\")" ] }, { "cell_type": "markdown", "id": "part5_comparison_header_010", "metadata": {}, "source": [ "## 4.4 Results Comparison" ] }, { "cell_type": "code", "execution_count": 70, "id": "part5_comparison_viz_011", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "=====================================================================================\n", "CONCURRENCY TEST COMPARISON: Three Approaches\n", "=====================================================================================\n", "\n", "Metric FS (No Lock) FS (With Lock) Database \n", "-------------------------------------------------------------------------------------\n", "Expected Entries 500 500 500 \n", "Actual Entries 14 500 500 \n", "Lost Entries 486 0 0 \n", "Data Loss Rate 97.2% 0.0% 0.0%\n", "Time Elapsed 33ms 15ms 656ms\n", "\n", "=====================================================================================\n", "\n", "VERDICT:\n", " • Filesystem (No Lock): ❌ UNSAFE - 97.2% data loss, fastest (33ms)\n", " • Filesystem (With Lock): ✓ Safe - 0.0% data loss, slower (15ms)\n", " • Database (ACID): ✓ Safe - 0.0% data loss, slowest (656ms)\n", "\n", "KEY INSIGHT:\n", " Filesystems CAN be safe with proper locking, but require explicit implementation.\n", " Databases provide safety by DEFAULT through ACID transactions.\n" ] } ], "source": [ "# Side-by-side Comparison of All Three Approaches\n", "print(\"=\" * 85)\n", "print(\"CONCURRENCY TEST COMPARISON: Three Approaches\")\n", "print(\"=\" * 85)\n", "\n", "print(f\"\\n{'Metric':<20} {'FS (No Lock)':<18} {'FS (With Lock)':<18} {'Database':<18}\")\n", "print(\"-\" * 85)\n", "print(f\"{'Expected Entries':<20} {file_results['expected']:<18} {file_locked_results['expected']:<18} {db_results['expected']:<18}\")\n", "print(f\"{'Actual Entries':<20} {file_results['actual']:<18} {file_locked_results['actual']:<18} {db_results['actual']:<18}\")\n", "print(f\"{'Lost Entries':<20} {file_results['lost']:<18} {file_locked_results['lost']:<18} {db_results['lost']:<18}\")\n", "print(f\"{'Data Loss Rate':<20} {file_results['loss_rate']:.1f}%{'':<15} {file_locked_results['loss_rate']:.1f}%{'':<15} {db_results['loss_rate']:.1f}%\")\n", "print(f\"{'Time Elapsed':<20} {file_results['elapsed_ms']:.0f}ms{'':<14} {file_locked_results['elapsed_ms']:.0f}ms{'':<14} {db_results['elapsed_ms']:.0f}ms\")\n", "\n", "print(\"\\n\" + \"=\" * 85)\n", "\n", "# Verdict\n", "print(\"\\nVERDICT:\")\n", "print(f\" • Filesystem (No Lock): {'❌ UNSAFE' if file_results['lost'] > 0 else '✓ Safe'} - {file_results['loss_rate']:.1f}% data loss, fastest ({file_results['elapsed_ms']:.0f}ms)\")\n", "print(f\" • Filesystem (With Lock): {'❌ UNSAFE' if file_locked_results['lost'] > 0 else '✓ Safe'} - {file_locked_results['loss_rate']:.1f}% data loss, slower ({file_locked_results['elapsed_ms']:.0f}ms)\")\n", "print(f\" • Database (ACID): {'❌ UNSAFE' if db_results['lost'] > 0 else '✓ Safe'} - {db_results['loss_rate']:.1f}% data loss, slowest ({db_results['elapsed_ms']:.0f}ms)\")\n", "\n", "print(\"\\nKEY INSIGHT:\")\n", "print(\" Filesystems CAN be safe with proper locking, but require explicit implementation.\")\n", "print(\" Databases provide safety by DEFAULT through ACID transactions.\")" ] }, { "cell_type": "code", "execution_count": 71, "id": "part5_chart_012", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "/var/folders/8r/qvgk1jk97zdc9z1jjtdhm_440000gn/T/ipykernel_76924/4134488372.py:72: UserWarning: Glyph 10060 (\\N{CROSS MARK}) missing from font(s) DejaVu Sans Mono.\n", " plt.tight_layout()\n", "/var/folders/8r/qvgk1jk97zdc9z1jjtdhm_440000gn/T/ipykernel_76924/4134488372.py:73: UserWarning: Glyph 10060 (\\N{CROSS MARK}) missing from font(s) DejaVu Sans Mono.\n", " plt.savefig(\"concurrency_test_results.png\", dpi=150, bbox_inches='tight')\n", "/opt/homebrew/Caskroom/miniconda/base/envs/filesystemsvsdbs/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 10060 (\\N{CROSS MARK}) missing from font(s) DejaVu Sans Mono.\n", " fig.canvas.print_figure(bytes_io, **kw)\n" ] }, { "data": { "image/png": "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ERGFTsz0JiIisgKoW4lam1omGoUeqGOLsiaoK8qAN1HwB75R23ny5MkMeBMRERGFYsz0JiIiIiIiIiIiIiKrwUxvIiIiIiIiIiIiIrIaDHoTERERERERERERkdVg0JuIiIiIiIiIiIiIrAaD3kRERERERERERERkNRj0JiIiIiIiIiIiIiKrwaA3EREREREREREREVkNBr2JiIiIiIiIiIiIyGow6E1EREREREREREREVoNBbyIiIiIiIiIiIiKyGgx6ExEREREREREREZHVYNCbiIiIiIiIiIiIiKwGg95EREREREREREREZDUY9CYiIiIiIiIiIiIiq8GgNxERERERERERERFZDQa9iYiIiIiIiIiIiMhqMOhNRERERERERERERFaDQW8iIiIiIiIiIiIishoMehMRERERERERERGR1WDQm4iIiIiIiIiIiIisBoPeRGTVwoULJ4MGDQru2SAiIgo0+/fvV9c7/A2peD0mIiIioqDEoDdREFi0aJH6sae9IkeOLIkTJxYHBweZMmWKfPjwwc/TPnr0qArquri4BOg8Y5qY11evXlk87pMnT9T458+fl5AmsNYXERGFnuuwx9fx48clNJgxY4ZaltCwTrVXypQpg3tWiYiIiCgMihDcM0AUlgwZMkRSpUolP378kGfPnqmMrK5du8qECRNk06ZNkj17dj8FcQcPHix//PGHxIwZU0ICBL0xT/ihmzNnzmCdly9fvkiECBFC9PoiIqKgvQ57lDZt2lAT9I4bN666hhkVL15cXe8iRYoUZPOCz1y6dKlJt1atWkn+/PmlTZs2erfo0aN7eT0mIiIiIgpM/OZJFIQqVqwoefPm1f/v06eP7N27V6pUqSLVqlWTa9euSZQoUbhN/MnNzU2+f/+uMurxIiIi8uo6bC1sbGyC/HqXOnVq9TL6888/VbfGjRt7Gp7XYyIiIiIKSixvQhTMSpcuLf3795f79+/LsmXL9O4XL15UmVz48YgfigkTJpQWLVrI69ev9WFQpqNXr17qPTLXtEeJ7927p7otXLhQTT9+/Phia2srmTNnlpkzZ/p5XkuWLClZs2aVq1evSqlSpSRq1KiSJEkSGTNmjD4Mstfz5cun3jdv3lyfJ+Pj2CdOnJAKFSqIvb29mkaJEiXkyJEjnj4P00JwAsufJk0amT17tl52xQj/d+zYUZYvXy5Z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6dG+ofrr3XjPrm6ThJkrcVyuK+4bPBas/rxBpsK5u7u7SxiHR7Lt7e1V/VA+Sk2BJUuWLOLmckNODbHnSg4l8g14JzYxM8iVK1eCZP+4/eGJpJr8K0uWQjbnLhskrV3iANk3eA3iuiGikIvX59CH1+jQYevWrTKgb2/Zv2GqRIzIXDwioqBUp0VfqVjNUTp06GDVK541vYmIiIiIiIiIiIjIavCWKhEREREREREFuzFTl8qYqcssGuevTo3/P67X4726uVPipnfguFxX3Dd4LFj9eYNMsbwJHy2nIMLyJqEPy5uQd/jodNBg6RciCm4sbxL68BodOrC8CRFR8KnD8iZERERERERERERERKELa3oTERERERERERERkdVg0JuIiIiIiIiIiIiIrAaD3kRERERERERERERkNRj0JiIiIiIiIiIiIiKrwaA3EREREREREREREVkNBr2JiIiIiIiIiIiIyGow6E1EREREREREREREVoNBbyIiIiIiIiIiIiKyGgx6ExEREREREREREZHVYNCbiIiIiIiIiIiIiKwGg95EREREREREREREZDUY9CYiIiIiIiIiIiIiq8GgNxERERERERERERFZDQa9iYiIiIiIiIiIiMhqMOhNRERERERERERERFaDQW8iIiIiIiIiIiIishoMehMRERERERERERGR1WDQm4iIiIiIiIiIiIisBoPeRERERERERERERGQ1GPQmIiIiIiIiIiIiIqvBoDcRERERERERERERWQ0GvYmIiIiIiIgoRLjj/EiiJC0uDdsOMOl+8Og51T1uegeJl8FBshVrKDMX/qv3L1+ns9inLqP6J81WVeo0/1vuPXii+rXuNkJipCqtxkueo5o4tuorD58818d98eqtGh7jpspdQ8bPWOFpvpp3Gqo+/+oNZ0/9lq7ZLtmLN5LYactJ5iL1ZfWG3frn9hw4xWRYTOPClVsBsKYoKNy6+1CqN+4libNUVvtVRceucv/hU7P2DW2/w36lvZp2GOxpfza+njx7pfqfOndVfVaSrFXUPjl22rIQscEnzV4lmQo76seg8Vjx6Rj0bXmN42qvrn0nmqxHHF85SjSWcdOXi5ubmwQ3n+YZ+4hXy3v52h1f9w3tnJK+QF21zPgc5/tPPE03fsYKan0sWL5Z9Tt84oI+rZhpykq05CX1/7EPh0URgnsGiIiIiIiI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zEzvQURERERERBRRrOlNREREevz9/XH79m29ySvPnz+vanJnz54dPXv2xJgxY5A3b14VBB86dCgsLS3h4uKiti9YsCCcnJzQsWNHzJs3D58+fUK3bt3QpEkTtR0RERERERFRTGLQm4iIiPScOXMGVatW1b3u3bu3+tm6dWssWbIE/fv3R0BAADp16qQyuitWrIhdu3YhZcqUun1WrFihAt3Vq1dH0qRJ4erqihkzZrCniYiIiIiIKMYx6E1ERER6qlSpAo1GE2qvJEmSBKNGjVKP0EhW+MqVK9mzRERERERE9MOxpjcRERERERERERERJRgMehMRERERERERERFRgsGgNxERERERERERERElGAx6ExEREREREREREVGCwaA3ERERERERERERESUYDHoTERERERER0Q+TIkUKIAnw4eNH9joR0Q/24eOnr3+HEzgGvYmIiIiIiIjoh8mTJw+QJBnOX7rJXici+oE8Hz+Dt48/8ubNm+D7nUFvIiIiIiIiIvphcuXKhQIFCmHa/LW4cv0uNBoNe5+IKIY9eOSFsVOWwNwiHSpUqJDg+zt5bDeAiIiIiIiIiBKXP6dMxS9dOqNT38kwTWOCVCmNkSRJkthuFhFRgi1p8trXXwW8Z82eC2NjYyR0DHqTzpEjRzBhwgS4u7vj5cuXatncuXPRpUuXYL305s0bFC9eHHfv3g1zOyIiIiIiIqLvZcmSBevWb4CHhwcuX76M9+/fs5OIiGKIkZGRKi1la2ubKALegkFv0jl79iz27t2rvmqmDXqHplu3brqANxEREREREVFEJUuWDGXLllUPIiKi6MSa3qTTsmVL+Pn5Yffu3WH2ypo1a7Bs2TI0btyYvUdERERERERERERxCoPepJM+fXqYmJiE2SMPHz5E586dUapUKYwZM4a9R0RERERERERERHEKg95ksMDAQJUN/unTJ6xcuRIpUqRg7xEREREREREREVGcwqA3GWz69Ok4fPiw+pkvXz72HBEREREREREREcU5DHqTwS5cuKB+9ujRA2nSpIGNjY1uXc+ePVGhQgX2JhEREREREREREcWq5LF7eoqPAgICgi378OED3r59GyvtISIiIiIiIiIiItJipjfpbNiwAXny5EGVKlV0y4YNG6aWNW/eHEuWLIFGo9E97t27p9tu7ty5OH/+PHuTiIjIANOmTUOxYsVgYWEBY2NjZMuWDY0aNcLFixfV+nfv3qFBgwbImTOnmmTazMwMBQsWxODBg/H+/Xv2MRERERERURgY9CYdPz8/3LlzBw8ePNAte/HihVr2+PFj9hQREVE0kTky5D02V65cyJ07N54+fYp169ahatWq6htV8g2qbdu2qUmjpZxY6tSpcf36dYwbN06VFCMiIiIiIqLQMehNOm3atNHL5A76OHToULCekuwz7fouXbqwJ4mIiAz077//4smTJzh79iyuXr2KQYMGqeXe3t4quG1ubg5/f3/cunULZ86cwcOHD2Ftba22OXbsmN57d5IkSdR78tKlS2FlZaWywiUwLtni8lOOlT17dsybN0+335cvXzBw4EAVdE+ZMiXSpUuH0qVL448//uA9JCIiIiKieI81vYmIiIh+MAk0b9y4ERMnTlTftLpx44ZanjFjRuTLl08Fso2MjNChQwdV8uTRo0cqG1xUrFgx2PFk3a+//oqsWbPizZs3mD59Ovbs2aO+qSVBbwmad+3aFZUrV1ZlUmbPno0JEyYgWbJkKpNc5uW4dOmSmqi6X79+HA9ERERERBSvMehNREREFAuePXuGU6dO6V5LJvfWrVthamqqW3b58mW4u7vrXsscGzNmzAh2rI8fP+LAgQOwtbVVWd8S5L59+zZu3ryJDBkyqGC61AKXsioS9JYMctG2bVssWLBAPZfM8mvXrsXwVRMREREREcU8ljchIiIiigVSGiwwMFDNpeHm5qYmiJafkqmtdfLkSRWs/u+//2BpaYkVK1Zg9OjRwY6VNm1a2NnZIWnSpKqUiShcuLAKgEv2dqZMmXSBdlGnTh2VTf7333/jp59+UrXEx4wZo8qcEBERERERxXcMehMRERHFEgk8S5BaW9P7ypUrqt53UMbGxqqkiQTEhUxmKeVIgpI63lrJkycPtkzOI2QeDuHo6Kjqict5S5QooTLCpdSKBM4l45uIiIiIiCg+Y9CbiIiI6Ad69eoVli9frkqSaO3YsUP3PCAgAPv371dBaS0JRB85ckQ3CaVkf0eF1AmXkidjx47Ftm3b4OHhocsE19YXJyIiIiIiiq8Y9E5k/8iWrC95+Pr6xvj5WrdurTLL5s+fH+PnIiIiii+kfEmrVq1gYWGBIkWKqEzvgQMHqnVSz7tBgwaqnEmpUqVUWZLixYur0ibawHTdunWjXIZkzZo1sLKyUueW80g7RKpUqZA7d+5ouEoiIiIiIqLYw6B3IvLHH3+of2i3b98e5ubmuHDhAuzt7ZElSxYYGRkhffr0KFeuHBYtWqS33/jx45EtWzYVLHd2doaXl5du3efPn1GsWDF06tQp2Pn69OmjfkqN0E+fPv2AKyQiIor7JNjdpEkTZM2aFXfu3MHTp09VALpFixZqYsscOXKgfPnyqFKlivrwWEqeSO1veb8dNWqUClhHVaVKleDk5KSOK5NlStmTatWqYefOnap9RERERERE8dnXoo+U4MlXqGWyKiH/qBYyYZb841r+oS2TWN26dQunT59WD8n0kn+Q7927V9X7HDZsmHotmWASzJaJtMSkSZPw4sULFVD/XtGiRdUkWvKPafnqdP369X/wVRMREcU9ElT+vm739yQgLY/wLFmyRD2COnToULDt7t+/r/fawcFBPSjukTI2EyZMgLu7O16+fKmWzZ07V018qiUfiBw+fDjYvlKT/ejRoz+0vUREREREcREzvRMJCV5LeRPJKpOvMYtatWrBz88PV69eVV+ZPnfunG77Y8eOqZ/nz59XP2UCrYIFC6qvWUuGuJAg+ejRozFr1iyVOR6SOnXqqJ/h/eOeiIiIiKBqucv/txlSwiZXrlzqW3rah42NDbuQiIiIiIiZ3omHNuunTJkyumVS0kQywOUrzlJ+5Pbt27p1EuQWUkdUu7+UOHn+/DmqVq2qvgYtJU1q1qypao+GpmzZsuqn1CYlIiKKLfXq1VOlRCj+kNriW7ZsQWLTsmVLdO7cWU0qam1tHea2Q4cORZs2bUJcJ98AaNu2rXouJXHGjRuH69evqyzxZcuWYdOmTapcztu3b+Hm5obp06cjRYoUantZP2XKFN3vjPw/YOnSpdUErERERERE8QHLmyQSkpUtcubMqbdcanlKiROt5MmT488//1T/+BE1atRQ/0iSbO6pU6eq7HBZv3DhQpUZLqVQ5B9UUr5Esr2lDIpMzqUldUmF1AEPCAhA6tSpf9AVExERfSPBu9vXryFnKhN2Szxw/+07JFYyx4qhevXqpQLkUqZO5mmRb+Blzpw5xMnF5f/JPnz4gF27dqFy5coq2UGC6o8ePVLlU6RmvBxLvtEngXRJcMiTJw9SpkypyuNIwJxBbyIiIiKKLxj0TiR8fX3VT1NTU73l8g8Z+UeNTHC5YcMGNcll//791T9yJMAtBg4cqB5aEsDu16+fquctwW/JJJLJLyXwLQFwKZ+i/XqtTH4ZtA0MehMRUWyRgPfhKiV5A+KByofOxnYT4jwTExMV7Pbx8VHztCxYsAD79u3DpUuXgv3/1uDBg9VD5nWReVmuXbuGf/75B82bN8fPP/+svtF38OBBFfSWYLj8v2G+fPnUdkmTJsWXL190pe+IiIiIiOID1vROJLTBZ39//xDXSzBcsoBk8knJAhozZkyox+rWrZvarmPHjuofV1JzUoLdkhUkmeMHDhzQbSs1w79vAxERERFFnnz77vXr12qy8IcPH+qSEyT4vXHjxmDb161bN9g3/rTLpC64kHIq2skw06ZNi5s3b6qsc6kV/uuvv/J2EREREVG8wqB3IpE3b17188GDB7plkunz+PFj3Wv5x422rreUIgnJ5s2bsX37dpVNlCRJEpUJJLXBhbYOZFDa82XJkgVp0qSJ5qsiIiIiSnxKlCgBY2Nj9Vz+f6xZs2a6dZ6ensG21yYeSBm775fJ/kL+n077/2xXrlzBxIkT4eDgoL4NOH/+fDWnS9CSeEREREREcRmD3omEfHVVeHh46JZJ4NrKykpl/RQpUkSVJJF/2AjJ+v6eZG137dpVTZokX3kVUj9Syp3IcXfs2KG+Aiv/KNKSmt9Bz09EREREkSeTisskk9r/ZxOrV6/WPf9+/paIevLkCV68eKHK3clxr169igIFCqhv82knRiciIiIiiutY0zuRkAkp5Suq8hXY8+fPo3jx4nB2dlblTmRyL5nESEqcaMuWSM3H7/3+++/qGPKPIC0JgMs/jqpXrw4LCwsVSC9cuLBuvdT5Fk2bNv1BV0pEREQUf8kcK/L/Wp8/f9Ytk4nCJ0+erEqNjB07Fn369MGAAQPUHCzy7Tz5/ztRsGBBNGjQIErnlyC3/H9jxowZYWlpqZIepGyKkCQJIiIiIqL4gEHvREJKkHTo0EF9VXX58uUq6N2rVy/1MNScOXOCLZNAuUyEFJKLFy+qWpOSTV6nTp0otZ+IiIgoMZAgsyQkBCWZ1/LIli2bCkbLpJR79uxR2717905lYru4uKhguUxSHhVS47tJkyZwd3dXpe+SJUuGYsWKqW/7SbkTIiIiIqL4IIlGW8Avkf/jwtzcHL6+vgl6ssVXr17B2tpa1W6Ueo9yzTGpVatWKsAudSAlezyxk/IxgT434D4qZvudok+ZYb5IapFf1Tb9EePj9psnsJ7uEuPnoqi712MT8phaRsvYSCzvQbHdN/I79tnzPg5XKRlt7aOYU/nQWSTPnvOH/P0lCgvfn+MfvkcTERGRYKZ3NKtXr16w7Jy4RLKuRYUKFX7I+QoVKoRp06apR1yVO3dubNmyJbabQURERERERERERNGAQe9oJgHv29evIWcqk+g+NMWA+2/fsV+JiIgSsbiesEAhY9ICEREREYWFQe8YIAFvfn06/nx9moiIiBJ5wsLNq8iVKVlsN4UMdPf5F/YVEREREYWJQW8iIiIiStQk4M05N+LXnBtERERERGFJGuZaIiIiIiIiIiIiIqJ4hEFvIiIiIiIiIiIiIkowEkzQe/bs2ciZMydSpkyJcuXK4fTp07HdJCIiokSP789ERERERET0oyWIoPfq1avRu3dvDB8+HGfPnkWxYsXg6OiI58+fx3bTiIiIEi2+PxMREREREVFsSBBB7ylTpqBjx45o27YtChUqhHnz5iFVqlRYtGhRbDeNiIgo0eL7MxEREREREcWG5IjnPn78CA8PDwwcOFC3LGnSpLC3t8eJEydC3OfDhw/qoeXr+3UGeD8/vyi358uXL7gX8BYVD3pE+VgU8zzfvkOuL1+i5d4bMjbuPvuCkkN8YvxcFD3uvwhELtMfNz4+PvHF3e4bY/xcFHWfvPzwJU/maBkb2mNoNBokJHx/pqjg+zOFhe/PFBa+RxMREVGCCHq/fPlSBYsyZ86st1xeX79+PcR9xo8fj5EjRwZbbmVlFW3tuhPwLtqORTHrxo0bMDc3/2HdfMsr8Iedi+Lf+Pj0+OuHcJT4xsabN29+6FiLaXx/pqji+zPFpfHB9+f4he/RREREFO+D3pEhWeFSA1wrMDAQ3t7eSJ8+PZIkSRKrbYurJBNRPhR4+PAhzMzMYrs5FIdwbBDHR9RIhrcEvC0tLRP9YOL7M/8GU/TiezRxbEQN36OJiIjir3gf9M6QIQOSJUuGZ8+e6S2X11myZAlxH2NjY/UIysLCIkbbmVBIwJtBb+LYIP7tiF4JKcNbi+/PPxbfn4njg/i3I2YkxPdoIiKixCDeT2RpZGSEUqVKYf/+/XqZ2/La1tY2VttGRESUWPH9mYiIiIiIiGJLvM/0FlKqpHXr1ihdujTKli2LadOmISAgAG3bto3tphERESVafH8mIiIiIiKi2JAggt5ubm548eIFhg0bBi8vLxQvXhy7du0KNrklRZ6Ugxk+fHiwsjBEHBvEvx3E9+fYw7/BxPFB/NtBREREFFwSjczOQURERERERERERESUAMT7mt5ERERERERERERERFoMehMRERERERERERFRgsGgNxERERERERERERElGAx6ExFRjDp06BCSJEkCHx8f9jQREVEcwfdnIiIiSsgY9CY9bdq0UcGp7x+3b9/GhQsXUK9ePWTKlAkpU6ZEzpw54ebmhufPn7MXEwmOj/h/31KkSIHMmTOjRo0aWLRoEQIDAw0+zpIlS2BhYRGjbSWikPHvL4WF4yN+4vszERERUcxh0JuCcXJywtOnT/UepqamqF69OtKlS4fdu3fj2rVrWLx4MSwtLREQEMBeTEQ4PuL3fbt//z527tyJqlWrokePHqhTpw4+f/4c280jIgPw7y9xfCQ8fH8mIiIiihkMelMwxsbGyJIli97jxIkT8PX1xd9//40SJUrA2tpaBc2mTp2qnlPiwfERv+/bTz/9hJIlS2LQoEHYvHmzCoBLBreYMmUKihQpgtSpU8PKygq//vor/P39dV+Bbtu2rfo7oM0aHzFihFq3fPlylC5dWn04Judo1qxZiN8AOXbsGIoWLaq+KVK+fHlcvnxZt+7Vq1do2rSpal+qVKlUO/7991+9/detW6eWm5iYIH369LC3t9f70E3+PhUsWFAdv0CBApgzZ06M9SdRbODfX+L4SHj4/kxEREQUMxj0JoNIIEuyQTdu3AiNRsNeI46PBKBatWooVqwYNmzYoF4nTZoUM2bMwJUrV7B06VIcOHAA/fv3V+sqVKiAadOmwczMTPcNkL59+6p1nz59wujRo1UJpE2bNqlscvnK9vf69euHP//8E+7u7siYMSPq1q2r9hXv379HqVKlsH37dhUM79SpE1q2bInTp0+r9XI+CYq3a9dOfdNEgvANGjTQ/T1asWIFhg0bhrFjx6r148aNw9ChQ9V1ECVkfH8mjo+Eh+/PRERERNFAQxRE69atNcmSJdOkTp1a92jYsKFaN2jQIE3y5Mk16dKl0zg5OWkmTZqk8fLyYv8lIhwf8fe+OTs7h7jOzc1NU7BgwRDXrV27VpM+fXrd68WLF2vMzc3DPZ+7u7tEojVv3rxRrw8ePKher1q1SrfNq1evNCYmJprVq1eHepzatWtr+vTpo557eHioY9y/fz/EbXPnzq1ZuXKl3rLRo0drbG1tw20vUXzAv7/E8ZHw8P2ZiIiIKOYw05uCkbIl58+f1z0k81NIBqWXlxfmzZsHGxsb9VNKCFy6dIm9mIhwfCQskiktpUrEvn37VO1+KTEipUok01rKjrx9+zbMY3h4eKis7ezZs6v9KleurJZ7enrqbWdra6t7LvMD5M+fX2Vliy9fvqhscSlfIuvSpEmj5g/QHkMy0qVtsr5Ro0ZYsGABXr9+rdZJiZM7d+6gffv2aj/tY8yYMWo5UULBv7/E8ZF48P2ZiIiIKGoY9KZgpJ5vnjx5dI+sWbPq1kkdXQk4TZ48WQWrZCJLeU6JB8dHwiK/x1KXX0qSyKSWUnN7/fr1KpA9e/Zstc3Hjx9D3V8Czo6OjqrsiZQYkdIlUgYpvP2+98cff2D69OkYMGAADh48qD5wk+Nqj5EsWTLs3btX1SAvVKgQZs6cqYLm9+7d09Udl0B40A/spEzKyZMno9hDRHEH//4Sx0fiwfdnIiIioqhJHsX9KREzMjJC7ty59SaSI+L4iD+kZrd8U6NXr14qyB0YGKhqbkttb7FmzZpgv/OSkR3U9evXVTb4hAkT1OSX4syZMyGeTwLQkg0uJEv75s2bauJJ7SSXzs7OaNGihXotbZH1EuDWkox0Ozs79ZD63Tly5FAB9t69e6sP4O7evYvmzZtHax8RxUd8fyaOj/iN789EREREUcegNxlk27ZtWLVqFZo0aYJ8+fKpr1xu3boVO3bswOLFi9mLiRzHR9z34cMHVZ5IgtbPnj3Drl27MH78eJXd3apVK5UVLZNKSga1lCqRILSUMAoqZ86cKqt6//79qtxIqlSpVBBbAmyyX5cuXdRxpExJSEaNGqW+LZI5c2YMHjwYGTJkgIuLi1qXN29erFu3DsePH0fatGkxZcoU1U5t0PvUqVPqvA4ODsiUKZN6/eLFC13QfOTIkfjtt99gbm4OJycndb0SfJfgugTFiRIq/v0ljo/4je/PRERERDEkBuuFUwKaUOfOnTuajh07avLly6cmn7OwsNCUKVNGTWxHiQfHR/y9b/LnXh4yGW3GjBk19vb2mkWLFmm+fPmi227KlCmarFmzqt9xR0dHzbJly9Q+r1+/1m3TpUsXNbmlLB8+fLhaJhNI5syZU2NsbKwmjtyyZYtaf+7cOb2JLLdu3aqxsbHRGBkZacqWLau5cOGC3sSW8rcnTZo0mkyZMmmGDBmiadWqle7v0dWrV1WbpO1yHvlbNHPmTL3rXLFihaZ48eLq+GnTptVUqlRJs2HDhhjvX6IfgX9/ieMj4eH7MxEREVHMSSL/iamAOhERERERERERERHRj8SJLImIiIiIiIiIiIgowWDQm4iIiIiIiIiIiIgSDAa9iYiIiIiIiIiIiCjBYNCbiIiIiIiIiIiIiBIMBr2JiIiIiIiIiIiIKMFg0DueefXqFTJlyoT79+8jvluyZAksLCxCXX/16lVky5YNAQEBP7RdCcWPHCtt2rSBi4tLtB5zxIgRKF68uO7177//ju7du0frOYiIogvfnykujhW+PxMRERFRYsWgdzwzduxYODs7I2fOnOq1/IMpSZIk6h9Pb9680dtWAoYSOIwKOc+0adMQGwoVKoTy5ctjypQpsXL+hDRWtOPk/PnziK/69u2LpUuX4u7du7HdFCKiYPj+TIbi+zMRERERUcxj0Dseefv2LRYuXIj27dsHWycB78mTJyOhadu2LebOnYvPnz/HdlMSzFiJrzJkyABHR0c1HoiI4hK+P1N0jJX4iu/PRERERBQXMegdj+zYsQPGxsYq+/l7UvZBMqKfP38e6v6vX79Gq1atkDZtWqRKlQo1a9bErVu3otQmCUDmzp0bRkZGyJ8/P5YvX6633sfHB507d0bmzJmRMmVKFC5cGNu2bQvxWC9evEDp0qVRv359fPjwQS2rUaMGvL29cfjw4Si1M7EJa6yERPr7t99+U98YkPtUsWJFuLu7621z5coV1KlTB2ZmZjA1NcXPP/+MO3fuhHg82TdjxoyYOHGibhx06NBBLZP9q1WrhgsXLujtM2HCBDVO5NgSDHj//n2w49atWxerVq2KQE8QEcU8vj9TdIyVkPD9mYiIiIgochj0jkf+++8/lCpVKsR1TZs2RZ48eTBq1Kgw6zqeOXMGW7ZswYkTJ6DRaFCrVi18+vQpUu3ZuHEjevTogT59+uDy5csquC2Z2QcPHlTrAwMDVWD92LFj+Oeff1SNbglsJkuWLNixHj58qIKoEhRft26d+gehkGC6lGmRa6foGSsh6d+/P9avX6/Kh5w9e1aNJcmqlg8cxOPHj1GpUiV1Xw4cOAAPDw+0a9cuxAx8WS8fVsjXtwcMGKCWNWrUSH0gs3PnTrVvyZIlUb16dd3x16xZo0rxjBs3To3RrFmzYs6cOcGOXbZsWTx69ChB1LQnooSD788UHWMlJHx/JiIiIiKKJA3FG87Ozpp27drpLbt3755GbuO5c+c0u3bt0qRIkUJz+/Ztta5YsWKa4cOHq+c3b95U2x07dky378uXLzUmJiaaNWvWhHrOHDlyaKZOnRriugoVKmg6duyot6xRo0aaWrVqqee7d+/WJE2aVHPjxo0Q91+8eLHG3Nxcc/36dY2VlZXmt99+0wQGBgbbrn79+po2bdqE0TMU3lgJOk6+5+/vr8bNihUrdMs+fvyosbS01EyaNEm9HjhwoMba2lotD0nr1q3VOTds2KBJkyaNZtWqVbp1//33n8bMzEzz/v17vX1y586t+euvv9RzW1tbza+//qq3vly5cmoMB+Xr66uu49ChQ7zpRBRn8P2ZIjtW+P5MRERERBQzmOkdj7x7906VngiNZOZKWYqhQ4cGW3ft2jUkT54c5cqV0y1Lnz69Kkki6yJD9rOzs9NbJq+1x5NJE7Nly4Z8+fKFeU2S4d2gQQNMnz5dTbb4PRMTE1UDk6JvrAQlJUok2z/ovUyRIoXKqg56L+U+yfLQnDp1SmV0S4kbNzc33XIpY+Lv76/GW5o0aXSPe/fu6cqjyHmCjk1ha2sb4lgQHA9EFJfw/Zmia6wExfdnIiIiIqLISx6FfSkWJgqSutxhkfIhEizs168fYps2QBkWKZdhb2+v6nxLm3/66adg20gJDKkbTtE7VqL7Xso9ksD2okWLULt2bV2AXALeUq7k0KFDwfaxsLCIUDu05VCkNjgRUVzB92eKzrESEXx/JiIiIiIKGTO945ESJUqouthhkexcyZr+/fff9ZYXLFhQ1V+WbFytV69e4caNGyhUqFCk2iPHlHrdQclr7fGKFi2q6i/fvHkz1GMkTZpUZQZLfcuqVaviyZMnwbaReuFy7RS9Y0VLOxFp0Hspmd8yGWXQeyl1SMOq/y7/kJd63rdv30bjxo1120r9bi8vL/VNA6kVHvQh+2jHUtCxKU6ePBniWJBguo2NjYE9QUQU8/j+TNE5VrT4/kxEREREFHkMescjUr7kypUr4WYIyQSCEnyUgLZW3rx54ezsjI4dO+Lo0aOq5ESLFi1UZrUsD4tMYijlLYI+pA2Smb1kyRLMnTsXt27dwpQpU7Bhwwb07dtX7Ve5cmU1+aGrqyv27t2rylnIRIa7du3SO75MbLlixQoUK1YM1apVUwFSLZmwUM4v2eAU9bEiY+L7eykB719++UXdT7k38o9xGSdSQqR9+/Zqv27dusHPzw9NmjRRE03K/ZYPK4KOMZEpUyY19q5fv64mV5UPWuTeybcPXFxcsGfPHnVPjx8/jsGDB6tjCZkQVTLEFy9erD4kGT58uGr/9yTwLmVWDMlsIyL6Ufj+TFEdK3x/JiIiIiKKZjFUK5xiSNmyZTXz5s0LdwKkTp06qeXaiSyFt7e3pmXLlmrySJnA0tHRUU1wGRaZyFKO8/1j+fLlav2cOXM0uXLlUhMh5suXT7Ns2TK9/V+9eqVp27atJn369JqUKVNqChcurNm2bZveRJZanz590jRo0EBTsGBBzbNnz9SycePGqXZS1MaKdpyE9Hj48KHm3bt3mu7du2syZMigMTY21tjZ2WlOnz6td7wLFy5oHBwcNKlSpdKYmppqfv75Z82dO3f0JrLUevLkiRoPjRs31nz+/Fnj5+enji+TY8pYkYlLmzdvrvH09NTtM3bsWHV+mQhTjte/f/9gE1nmz59f8++//3I4EFGcw/dnisxY4fszEREREVHMSCL/ie5AOsWc7du3q4xcKfMgpUESso8fP6oM9ZUrVwabMJMS31iRbwn06dMHFy9eVKVSiIjikoT2NzcsfH+OmoQ2Vvj+TERERERxESNH8YxMECilJaTkh5WVFRIyT09PDBo0iAHvSEpoYyUgIECVP2HAm4jiooT2NzcsfH+OmoQ2Vvj+TERERERxETO9iYiIiIiIiIiIiCjBiP/fqSQiIiIiIiIiIiIi+j8GvYmIiIiIiIiIiIgowWDQm4iIiIiIiIiIiIgSDAa9iYiIiIiIiIiIiCjBYNCbiIiIiIiIiIiIiBIMBr2JiIiIiIiIiIiIKMFg0JuIiIiIiIiIiIiIEgwGvYmIiIiIiIiIiIgowWDQm4iIiIiIiIiIiIiQUPwPH6jGf+HvqQYAAAAASUVORK5CYII=", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "[OK] Saved: concurrency_test_results.png\n" ] } ], "source": [ "# Visualization - Three Approaches\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "\n", "fig, axes = plt.subplots(1, 3, figsize=(15, 5))\n", "fig.suptitle(\"Concurrency Test: Filesystem (No Lock) vs Filesystem (Locked) vs Database\", fontsize=12, fontweight='bold')\n", "\n", "FS_NOLOCK_COLOR = \"#e74c3c\" # Red - unsafe\n", "FS_LOCKED_COLOR = \"#f39c12\" # Orange - safe but requires effort\n", "DB_COLOR = \"#27ae60\" # Green - safe by default\n", "\n", "# Chart 1: Data Integrity Comparison\n", "ax1 = axes[0]\n", "approaches = ['FS\\n(No Lock)', 'FS\\n(Locked)', 'Database']\n", "actual_values = [file_results['actual'], file_locked_results['actual'], db_results['actual']]\n", "colors = [FS_NOLOCK_COLOR, FS_LOCKED_COLOR, DB_COLOR]\n", "\n", "bars = ax1.bar(approaches, actual_values, color=colors, edgecolor='black', linewidth=1.2)\n", "ax1.axhline(y=EXPECTED_TOTAL, color='black', linestyle='--', linewidth=2, label=f'Expected ({EXPECTED_TOTAL})')\n", "ax1.set_ylabel('Entries Written')\n", "ax1.set_title('Data Integrity')\n", "ax1.set_ylim(0, EXPECTED_TOTAL * 1.1)\n", "ax1.legend()\n", "\n", "# Add value labels\n", "for bar, val in zip(bars, actual_values):\n", " pct = val / EXPECTED_TOTAL * 100\n", " ax1.annotate(f'{val}\\n({pct:.0f}%)', xy=(bar.get_x() + bar.get_width()/2, val),\n", " ha='center', va='bottom', fontsize=10, fontweight='bold')\n", "\n", "# Chart 2: Time Comparison\n", "ax2 = axes[1]\n", "times = [file_results['elapsed_ms'], file_locked_results['elapsed_ms'], db_results['elapsed_ms']]\n", "bars = ax2.bar(approaches, times, color=colors, edgecolor='black', linewidth=1.2)\n", "ax2.set_ylabel('Time (ms)')\n", "ax2.set_title('Execution Time')\n", "\n", "# Add value labels\n", "for bar, val in zip(bars, times):\n", " ax2.annotate(f'{val:.0f}ms', xy=(bar.get_x() + bar.get_width()/2, val),\n", " ha='center', va='bottom', fontsize=10, fontweight='bold')\n", "\n", "# Chart 3: Safety vs Speed Trade-off\n", "ax3 = axes[2]\n", "ax3.axis('off')\n", "\n", "summary = f\"\"\"\n", "SUMMARY\n", "{'='*45}\n", "\n", "APPROACH SAFE? SPEED EFFORT\n", "{'─'*45}\n", "FS (No Lock) ❌ No Fast None\n", "FS (With Lock) ✓ Yes Medium Manual\n", "Database (ACID) ✓ Yes Slow None\n", "{'='*45}\n", "\n", "TRADE-OFFS:\n", "• Speed vs Safety: Naive FS is fast but unsafe\n", "• Locked FS: Safe but requires manual locking\n", "• Database: Safe by default, slower due to\n", " network/transaction overhead\n", "\n", "RECOMMENDATION:\n", "• Development/Prototyping: FS with locking\n", "• Production/Multi-user: Database (ACID)\n", "\"\"\"\n", "ax3.text(0.05, 0.95, summary, transform=ax3.transAxes, fontsize=9,\n", " verticalalignment='top', fontfamily='monospace',\n", " bbox=dict(boxstyle='round', facecolor='wheat', alpha=0.8))\n", "\n", "plt.tight_layout()\n", "plt.savefig(\"concurrency_test_results.png\", dpi=150, bbox_inches='tight')\n", "plt.show()\n", "print(\"\\n[OK] Saved: concurrency_test_results.png\")" ] }, { "cell_type": "markdown", "id": "part5_takeaways_013", "metadata": {}, "source": [ "## 4.5 Key Takeaways\n", "\n", "### The Real Story: It's About Default Safety vs Explicit Implementation\n", "\n", "| Approach | Safe? | Speed | Effort Required |\n", "|----------|-------|-------|-----------------|\n", "| **Filesystem (No Lock)** | ❌ No | Fast | None |\n", "| **Filesystem (With Lock)** | ✓ Yes | Medium | Manual implementation |\n", "| **Database (ACID)** | ✓ Yes | Slower | None - built-in |\n", "\n", "> **Key Insight:** Filesystems are not inherently broken for concurrency - they just require **explicit locking**. Databases provide safety **by default** through ACID transactions.\n", "\n", "### When to Use Each Approach\n", "\n", "> **Filesystem WITHOUT Locking (FSAgent default)**\n", "> - Single-user CLI tools\n", "> - Development and quick prototyping\n", "> - When you control all access to the files\n", "> - ⚠️ Never use for multi-user or concurrent scenarios\n", "\n", "> **Filesystem WITH Locking (`fcntl.flock()`)**\n", "> - Multi-process scenarios on local filesystems\n", "> - When you need human-readable files AND concurrency\n", "> - Development teams with shared file access\n", "> - ⚠️ Does NOT work reliably on NFS or network shares\n", "\n", "> **Database (MemAgent with ACID)**\n", "> - Production deployments\n", "> - Multi-user applications\n", "> - When data integrity is non-negotiable\n", "> - Network/distributed scenarios\n", "> - Background processes alongside user queries\n", "\n", "### The ACID Guarantee\n", "\n", "| Property | What It Means | Why It Matters for Agents |\n", "|----------|---------------|---------------------------|\n", "| **Atomicity** | All or nothing | Partial memory writes won't corrupt state |\n", "| **Consistency** | Rules enforced | Can't store invalid data (e.g., missing thread_id) |\n", "| **Isolation** | No interference | Concurrent users don't see each other's incomplete work |\n", "| **Durability** | Survives crashes | Memory persists even if agent crashes mid-operation |\n", "\n", "### Bottom Line\n", "\n", "**For production agent deployments**, the database's ACID guarantees provide reliability without requiring you to implement locking correctly. The performance overhead is usually worth the peace of mind.\n", "\n", "**For development/prototyping**, filesystem with proper locking (`fcntl.flock()`) can work well, but remember it won't work on all filesystem types (NFS, SMB network shares)." ] } ], "metadata": { "kernelspec": { "display_name": "filesystemsvsdbs", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.12" } }, "nbformat": 4, "nbformat_minor": 5 }