{
  "source_file": "0930",
  "source_platform": "Ghost",
  "author": "Peng Qian / Data Leads Future",
  "title_listed": "Advanced RedisVL Long-term Memory Tutorial: Using an LLM to Extract Memories",
  "keywords": "",
  "domain": "大模型算法",
  "content_type": "工程实践",
  "is_paid_flag": "否",
  "url": "https://www.dataleadsfuture.com/advanced-redisvl-long-term-memory-tutorial-using-an-llm-to-extract-memories/",
  "publish_date": "2026-02",
  "corpus_stage": "",
  "notes": "",
  "id": "2233559a8999",
  "collected_at": "2026-10-02T12:26:59",
  "title": "Advanced RedisVL Long-term Memory Tutorial: Using an LLM to Extract Memories",
  "body_markdown": "Agentic AI\nAdvanced RedisVL Long-term Memory Tutorial: Using an LLM to Extract Memories\nBuilding an intelligent, context-aware memory system\nPeng Qian\n05 Feb 2026\n—\n11 min read\nShare\nAdvanced RedisVL Long-term Memory Tutorial: Using an LLM to Extract Memories. Image by DALL-E-3\nIntroduction\nIn this weekend note, we keep talking about how to build long-term memory for an agent with RedisVL.\nWhen we build a long-term memory module for an agent, we need to care about two points most:\nAfter long running, will the saved memories grow too large and cause context explosion?\nHow do we recall the memories that matter most to the current context?\nWe will solve these two problems today.\nTLDR\n: In this hands-on tutorial, we first use an LLM to extract information from user messages that has value for later chats. Then we store that as long-term memory in RedisVL. When needed, we search related memories with semantic search. With this setup, the agent understands the past context of the user and gives more accurate answers.\nAfter using an LLM to extract memories, how my long‑term memory module runs. Image by Author\nWith this kind of long-term memory, we do not worry about memory explosion after long running. We also do not worry that unrelated memories will hurt LLM responses.\nYou can get all the source code at the end of this post.\nWhy do we do this?\nIn the last hands-on post, I shared how to build short-term and long-term memory for an agent with RedisVL:\nBuild Long-Term and Short-Term Memory for Agents Using RedisVL\nPros and cons analysis based on real-world practice\nData Leads Future\nPeng Qian\nThe short-term part works very well. RedisVL API feels much simpler than the raw Redis API. I can write that code with little effort.\nThe long-term part does not work. We follow the official example and store user queries and LLM responses in RedisVL. When chat continues, RedisVL keeps pulling repeated queries or unrelated answers via semantic search. This troubles the LLM a lot and blocks the chat from going on.\nCan we avoid RedisVL?\nYour boss will not agree. There is already Redis in your stack. Why do you still want to install mem0 or other open source tools? How about extra cost? This is real life.\nSo we still need to make RedisVL work. But I do not want to run around like a headless fly. Before that I want to see how humans handle memory.\nHow Humans Handle Memory\nWhat deserves memory\nFirst, we need to know one thing. Only information that centers on me and links to me tightly deserves a sticky note.\nSo what information about me do I want to write down?\nPreference settings such as tools I like, languages I use, my schedule, and my tone when I talk\nStable personal info such as my role, my time zone, and my daily habits\nGoals and decisions, such as chosen options, plans, and sentences that start with “I decide to...”\nKey milestones such as job change, moving, deadlines, and product launches\nWork and project context, such as project names, stakeholders, needs, and status like “done/next” step.\nRepeated pain points or strong views that will change LLM advice later\nThings I say with “remember this ...” or “do not forget ...”\nWhat does not deserve memory\nI do not plan to store any LLM answer. LLM answers to the same question will change with context. So LLM answers in long-term memory do not help much.\nBesides LLM answers, I also do not want to keep these:\nOne-time small things that likely will not matter later\nVery sensitive personal data such as health diagnosis, exact address, government IDs, passwords, bank accounts\nThings I clearly ask not to remember\nThings I already wrote down on the sticky note\nDesign a Prompt for LLM Memory Extraction\nNow we know how humans handle memory. Next, I want to build an agent that follows the same rules and extracts memories from my daily chats.\nThe key lives in the\nsystem prompt\n. I need to describe all rules in the system prompt. Then I ask the agent to follow these rules with very high consistency.\nIn the past, I might have tried some “write 1000-line prompt” challenge. Now I do not need that. I just open any LLM client, paste these rules, then ask the LLM to help me write a\nsystem prompt\n. This takes less than one minute.\nAfter a few tries, I pick one I like. Here is that\nsystem prompt\n:\nYour job:\nBased only on the user’s current input and the existing related memories, decide whether you need to add a new “long-term memory,” and if needed, **extract just one fact**. You do not talk to the user. You only handle memory extraction and deduplication.\n\n---\n\n### 1. Core principles\n\n1. Only save information that **will likely be useful in the future**.\n2. **At most one fact per turn**, and it must clearly appear in the current input.\n3. **Never invent or infer anything**. You can only restate or lightly rephrase what the user has explicitly said.\n4. If the current input has nothing worth keeping, or the information is already in the related memories, then do not add a new memory.\n\n---\n\n### 2. What counts as “long-term memory”\n\nOnly consider the categories below, and decide whether the information has long-term value:\n\n...\nDue to space, I only show part of the prompt here. You can get the full prompt from the source code at the end.\nBuild a ContextProvider for Long-term Memory\nAfter we finish the memory extraction rules, we start to build the long-term memory module for the agent.\nFor future use, I still pick Microsoft Agent Framework MAF. It gives a\nContextProvider\nfeature that lets us plug long-term memory into the agent in a simple way.\nOf course the principle of long-term memory stays the same. You can use any agent framework you like and build your own memory module. Or you can ignore frameworks and first build storage and retrieval of memories, and then call them through function calls. That is fine.\nRun memory extraction in sequence\nIn the last post, I already built a long-term memory module with\nContextProvider\n. The new version looks similar. But this time, we use an LLM to extract memories. So after we set up\nContextProvider\n, we first use the\nsystem prompt\nto build a memory extraction agent.\nIf you do not know how to use\nContextProvider\nyet, I suggest you read my last post again. That post explains\nChatMessageStore\nand\nContextProvider\nin Microsoft Agent Framework in detail:\nBuild Long-Term and Short-Term Memory for Agents Using RedisVL\nPros and cons analysis based on real-world practice\nData Leads Future\nPeng Qian\nTo avoid too much unrelated data from Redis, I set the\ndistance_threshold\nvalue pretty small. But not too small. If too small, then it loses meaning. You can pick the value you like.\nclass LongTermMemory(ContextProvider):\n    def __init__(\n        self,\n        thread_id: str | None = None,\n        session_tag: str | None = None,\n        distance_threshold: float = 0.3,\n        context_prompt: str = ContextProvider.DEFAULT_CONTEXT_PROMPT,\n        redis_url: str = \"redis://localhost:6379\",\n        embedding_model: str = \"BAAI/bge-m3\",\n        llm_model: str = Qwen3.NEXT,\n        llm_api_key: str | None = None,\n        llm_base_url: str | None = None,\n    ):\n        ...\n        self._init_extractor()\n\n    def _init_extractor(self):\n        with open(\"prompt.md\", \"r\", encoding=\"utf-8\") as f:\n                system_prompt = f.read()\n\n        self._extractor = OpenAILikeChatClient(\n            model_id=self._llm_model,\n        ).as_agent(\n            name=\"extractor\",\n            instructions=system_prompt,\n            default_options={\n                \"response_format\": ExtractResult,\n                \"extra_body\": {\"enable_thinking\": False}\n            },\n        )\nNext we implement the\ninvoking\nmethod. This method runs before the user agent calls the LLM. In this method, we extract and store long-term memory\nTo make the logic clear, I first implement the\ninvoking\nmethod in order, as in this diagram:\nRun the memory extraction logic step by step in order. Image by Author\nWhen a new user request comes into\nContextProvider\n, we first search RedisVL with semantic search for the most similar memories.\nclass LongTermMemory(ContextProvider):\n    ...\n\n    async def invoking(\n        self,\n        messages: ChatMessage | MutableSequence[ChatMessage],\n        **kwargs: Any\n    ) -> Context:\n        if isinstance(messages, ChatMessage):\n            messages = [messages]\n        prompt = \"\\n\".join([m.text for m in messages])\n\n        line_sep_memories = self._get_line_sep_memories(prompt)\n        ...\n\n    def _get_line_sep_memories(self, prompt: str) -> str:\n        context = self._semantic_store.get_relevant(prompt, role=\"user\", session_tag=self._session_tag)\n        line_sep_memories = \"\\n\".join([f\"* {str(m.get(\"content\", \"\"))}\" for m in context])\n      \n        return line_sep_memories\nNext, we send these existing memories plus the user request to the memory extraction agent. That agent first checks if anything is worth saving according to the rules. Then it extracts a new helpful memory from the user request and saves it into RedisVL.\nclass LongTermMemory(ContextProvider):\n    ...\n\n    async def invoking(\n        self,\n        messages: ChatMessage | MutableSequence[ChatMessage],\n        **kwargs: Any\n    ) -> Context:\n        ...\n        await self._save_memory(messages, line_sep_memories)\n        ...\n\n    async def _save_memory(\n        self,\n        messages: ChatMessage | MutableSequence[ChatMessage],\n        relevant_memory: str | None = None,\n    ) -> None:\n        detect_messages = (\n            [\n            ChatMessage(role=Role.USER, text=f\"Existing related memories：\\n\\n{relevant_memory}\"),\n            ] + list(messages)\n            if relevant_memory.strip()\n            else list(messages)\n        )\n        response = await self._extractor.run(detect_messages)\n\n        extract_result: ExtractResult = cast(ExtractResult, response.value)\n        if extract_result.should_write_memory:\n            self._semantic_store.add_messages(\n                messages=[\n                    {\"role\": \"user\", \"content\": extract_result.memory_to_write}\n                ],\n                session_tag=self._session_tag,\n            )\nLast, we put the memories from RedisVL into\nContext\nas extra context. These memory messages get merged into the history of the real chat agent. They give the chat agent extra background to produce answers.\nclass LongTermMemory(ContextProvider):\n    ...\n\n    async def invoking(\n        self,\n        messages: ChatMessage | MutableSequence[ChatMessage],\n        **kwargs: Any\n    ) -> Context:\n        ...\n\n        return Context(messages=[\n            ChatMessage(role=\"user\", text=f\"{self._context_prompt}\\n{line_sep_memories}\")\n        ] if len(line_sep_memories)>0 else None)\nNow we build a simple chat agent to test the new long-term memory module\nagent = OpenAILikeChatClient(\n    model_id=Qwen3.MAX\n).as_agent(\n    name=\"assistant\",\n    instructions=\"You are a helpful assistant.\",\n    context_provider=LongTermMemory(),\n)\n\nasync def main():\n    thread = agent.get_new_thread()\n\n    while True:\n        user_input = input(\"\\nUser: \")\n        if user_input.startswith(\"exit\"):\n            break\n        stream = agent.run_stream(user_input, thread=thread)\n        print(\"Assistant: \\n\")\n        async for event in stream:\n            print(event.text, end=\"\", flush=True)\n        print(\"\\n\")\n\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\nNow we chat with the agent and see how it works:\nThe yellow parts are memories fetched from RedisVL, and the green parts are memories extracted by the LLM. Image by Author\nFrom MLFlow we see that the retrieved memories go in as a separate message in the chat history:\nThe retrieved memory will be added to the chat history as a separate message. Image by Author\nThen we check Redis and see what memories we saved:\nThe info that the LLM pulls out from the user’s past conversations will be saved into Redis as valuable memories. Image by Author\nWe can see that as the chat goes on, the new long-term memory module no longer stores and retrieves all chat history without filter. It keeps and retrieves only memories that matter to the user, and these memories give strong help in later chats.\nUse concurrency to speed up\nEverything looks fine except for the part where we use an LLM to extract memories that deserve saving.\nThe largest delay in an agent often comes from LLM calls. Now we add one more LLM call. We also need to wait for the LLM to decide whether to save memory before we go on with the real chat.\nWe can add some logs and see how much delay we add:\nEvery time we use the LLM to pull out memories, it takes a bit more than one second. Image by Author\nWe add more than one second per chat turn.\nOne way to optimize is to use a smaller model like\nqwen3-8b\n. But the gain stays small. We save little time and hurt memory quality due to the smaller model.\nToday I use a different way. I use concurrent programming so that the LLM call for memory extraction and the LLM call for user reply run at the same time.\nLet us see the result after that change:\nThe memory retrieval step basically doesn’t take any time at all, so how did I pull that off? Image by Author\nThe time cost for extraction and storage of memory becomes almost nothing while the effect stays the same. How do we reach that?\nIf you built multi-agent workflows with LangGraph or LlamaIndex, you have likely seen the fan-out idea. It lets many nodes run at the same time, and then you take the final result.\nThe base idea uses the\nasyncio\nmodule in Python. You often see\nasync\nand\nawait\nwhen you write agent code. I wrote many posts in the past about\nasyncio\nand concurrency:\nUse These Methods to Make Your Python Concurrent Tasks Perform Better\nBest practices for asyncio.gather, asyncio.as_completed, and asyncio.wait\nData Leads Future\nPeng Qian\nIn short, when you face delays because of long IO calls, you can use concurrent programming.\nNote:\nIf you use\nmlflow.openai.autolog()\nto trace LLM calls, you may see that concurrent runs stop working. I still do not know why. I suggest you comment out MLFlow parts before you go on.\nBy running the memory retrieval process with concurrent programming. Image by Author\nBack to our current case. We see that\n_save_memory\nis an\nasync\nmethod. That means we can run it with concurrency.\nHow do we do that? Very simple. When we call\n_save_memory\n, we use\nasyncio.create_task\nto build a new concurrent task. That is all.\nclass LongTermMemory(ContextProvider):\n    ...\n\n    async def invoking(\n        self,\n        messages: ChatMessage | MutableSequence[ChatMessage],\n        **kwargs: Any\n    ) -> Context:\n        ...\n        asyncio.create_task(self._save_memory(messages, line_sep_memories))\n        ...\nSince real user chat often takes more time than memory extraction, we do not need to wait for that task in code. We only need to create the task.\nWith that, we add a memory extraction module that does not bring much extra delay to the agent system.\nConslusion\nRedis now serves as standard infra for many companies. With RedisVL, it can cache and search information by semantics. This makes it easier to build short-term and long-term memory on top of Redis.\nBut if you build long-term memory with RedisVL API directly, you may not see good results. The system has no “brain” to judge which information deserves long-term storage and keeps value over time.\nSo in this tutorial, I first use an agent to extract useful memories and then write them into RedisVL. This improves the value of saved information. Long-term memory works much better now and fills the gap in my last post.\nI also share a short guide on how to use concurrent programming so that many LLM calls run at the same time. This cuts system delay by a lot. If you like concurrency, you can read my old posts.\nThanks for reading. If you have any questions or ideas, leave me a note. I will reply as soon as I can.\nDo not forget to subscribe to my blog and follow my new work in AI applications.\nAlso share this post with your friends. It may help more people.\nFollow Data Leads Future\nOne practical story every month, sharing my hard-learned experiences in the enterprise AI space.\nSubscribe\nEmail sent! Check your inbox to complete your signup.\nNo spam, No ads, you can unsubscribe anytime.\nGet the source code for this article.\nStart using it right away and save yourself a ton of trial and error time.\nGrab the Source Code",
  "metadata": {
    "title": "Advanced RedisVL Long-term Memory Tutorial: Using an LLM to Extract Memories",
    "description": "Learn how to build robust long-term memory for AI agents with RedisVL and LLMs, from human-like memory rules and semantic search to async optimization that cuts latency.",
    "keywords": null,
    "author": null,
    "og:site_name": "Data Leads Future",
    "og:type": "article",
    "og:title": "Advanced RedisVL Long-term Memory Tutorial: Using an LLM to Extract Memories",
    "og:description": "Building an intelligent, context-aware memory system",
    "og:url": "https://www.dataleadsfuture.com/advanced-redisvl-long-term-memory-tutorial-using-an-llm-to-extract-memories/",
    "og:image": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/size/w1200/2026/02/cover.webp",
    "og:image:width": "1200",
    "og:image:height": "686",
    "twitter:card": "summary_large_image",
    "twitter:title": "Advanced RedisVL Long-term Memory Tutorial: Using an LLM to Extract Memories",
    "twitter:description": "Building an intelligent, context-aware memory system",
    "twitter:url": "https://www.dataleadsfuture.com/advanced-redisvl-long-term-memory-tutorial-using-an-llm-to-extract-memories/",
    "twitter:image": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/size/w1200/2026/02/cover.webp",
    "twitter:label1": "Written by",
    "twitter:data1": "Peng Qian",
    "twitter:label2": "Filed under",
    "twitter:data2": "Agentic AI, Generative AI, Microsoft Agent Framework",
    "twitter:site": "@qtalen",
    "twitter:creator": "@qtalen",
    "article:published_time": "2026-02-05T11:44:14.000Z",
    "article:modified_time": "2026-09-07T09:17:48.000Z",
    "article:tag": "Microsoft Agent Framework"
  },
  "paywall": {
    "listed_paid": false,
    "detected": false,
    "marker": "",
    "public_only": false,
    "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
  },
  "crawl": {
    "success": true,
    "status_code": 200,
    "error": ""
  },
  "code_blocks": [
    {
      "file": "attachments/2233559a8999/code/body-000.txt",
      "chars": 844,
      "language": "text"
    },
    {
      "file": "attachments/2233559a8999/code/body-001.txt",
      "chars": 996,
      "language": "text"
    },
    {
      "file": "attachments/2233559a8999/code/body-002.txt",
      "chars": 693,
      "language": "text"
    },
    {
      "file": "attachments/2233559a8999/code/body-003.txt",
      "chars": 1108,
      "language": "text"
    },
    {
      "file": "attachments/2233559a8999/code/body-004.txt",
      "chars": 373,
      "language": "text"
    },
    {
      "file": "attachments/2233559a8999/code/body-005.txt",
      "chars": 597,
      "language": "text"
    },
    {
      "file": "attachments/2233559a8999/code/body-006.txt",
      "chars": 287,
      "language": "text"
    }
  ],
  "images": [
    {
      "status": "ok",
      "url": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/size/w1200/2026/02/cover.webp",
      "bytes": 60672,
      "reused": true,
      "local_path": "attachments/2233559a8999/images/000.webp",
      "src": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/size/w1200/2026/02/cover.webp",
      "alt": "Advanced RedisVL Long-term Memory Tutorial: Using an LLM to Extract Memories.",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/2026/02/image.png",
      "bytes": 16202,
      "reused": true,
      "local_path": "attachments/2233559a8999/images/005.png",
      "src": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/2026/02/image.png",
      "alt": "After using an LLM to extract memories, how my long‑term memory module runs.",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/icon/color_192_192-62.png",
      "bytes": 17721,
      "reused": false,
      "local_path": "attachments/2233559a8999/images/body-0289e115ecc61f634dfe.png",
      "src": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/icon/color_192_192-62.png",
      "alt": "",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/thumbnail/cover-11.webp",
      "bytes": 113826,
      "reused": true,
      "local_path": "attachments/2233559a8999/images/008.webp",
      "src": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/thumbnail/cover-11.webp",
      "alt": "",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/icon/color_192_192-63.png",
      "bytes": 17721,
      "reused": false,
      "local_path": "attachments/2233559a8999/images/body-dd39495348089b1b6262.png",
      "src": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/icon/color_192_192-63.png",
      "alt": "",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/thumbnail/cover-12.webp",
      "bytes": 113826,
      "reused": true,
      "local_path": "attachments/2233559a8999/images/009.webp",
      "src": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/thumbnail/cover-12.webp",
      "alt": "",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/2026/02/image-1.png",
      "bytes": 16202,
      "reused": true,
      "local_path": "attachments/2233559a8999/images/010.png",
      "src": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/2026/02/image-1.png",
      "alt": "Run the memory extraction logic step by step in order.",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/2026/02/image-2.png",
      "bytes": 23525,
      "reused": true,
      "local_path": "attachments/2233559a8999/images/013.png",
      "src": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/2026/02/image-2.png",
      "alt": "The yellow parts are memories fetched from RedisVL, and the green parts are memories extracted by the LLM.",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/2026/02/image-3.png",
      "bytes": 28355,
      "reused": true,
      "local_path": "attachments/2233559a8999/images/015.png",
      "src": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/2026/02/image-3.png",
      "alt": "The retrieved memory will be added to the chat history as a separate message.",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/2026/02/image-4.png",
      "bytes": 22038,
      "reused": true,
      "local_path": "attachments/2233559a8999/images/017.png",
      "src": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/2026/02/image-4.png",
      "alt": "The info that the LLM pulls out from the user’s past conversations will be saved into Redis as valuable memories.",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/2026/02/image-5.png",
      "bytes": 20080,
      "reused": true,
      "local_path": "attachments/2233559a8999/images/019.png",
      "src": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/2026/02/image-5.png",
      "alt": "Every time we use the LLM to pull out memories, it takes a bit more than one second.",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/2026/02/image-6.png",
      "bytes": 23617,
      "reused": true,
      "local_path": "attachments/2233559a8999/images/021.png",
      "src": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/2026/02/image-6.png",
      "alt": "The memory retrieval step basically doesn’t take any time at all, so how did I pull that off?",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/icon/color_192_192-64.png",
      "bytes": 17721,
      "reused": false,
      "local_path": "attachments/2233559a8999/images/body-802070452982c4744212.png",
      "src": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/icon/color_192_192-64.png",
      "alt": "",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/thumbnail/0_Eel1JPfhnioG71TL.jpg",
      "bytes": 78319,
      "reused": true,
      "local_path": "attachments/2233559a8999/images/023.jpg",
      "src": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/thumbnail/0_Eel1JPfhnioG71TL.jpg",
      "alt": "",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/2026/02/image-7.png",
      "bytes": 20981,
      "reused": true,
      "local_path": "attachments/2233559a8999/images/024.png",
      "src": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/2026/02/image-7.png",
      "alt": "By running the memory retrieval process with concurrent programming.",
      "downloaded": true
    }
  ],
  "audio": [],
  "videos": [],
  "links": [
    {
      "href": "https://www.dataleadsfuture.com/tag/agentic-ai/",
      "label": "Agentic AI",
      "type": "a"
    },
    {
      "href": "https://www.dataleadsfuture.com/author/peng/",
      "label": "",
      "type": "a"
    },
    {
      "href": "https://www.dataleadsfuture.com/build-long-term-and-short-term-memory-for-agents-using-redisvl/",
      "label": "Build Long-Term and Short-Term Memory for Agents Using RedisVL Pros and cons analysis based on real-world practice Data ",
      "type": "a"
    },
    {
      "href": "https://www.dataleadsfuture.com/use-these-methods-to-make-your-python-concurrent-tasks-perform-better/",
      "label": "Use These Methods to Make Your Python Concurrent Tasks Perform Better Best practices for asyncio.gather, asyncio.as_comp",
      "type": "a"
    }
  ],
  "repair_version": 2,
  "repaired_at": "2026-10-14T10:47:46Z",
  "source_url": "https://www.dataleadsfuture.com/advanced-redisvl-long-term-memory-tutorial-using-an-llm-to-extract-memories/",
  "papers": [],
  "actual_video_files": [],
  "body_chars": 16399,
  "expected_body_images": 15,
  "discovery_status": "ok",
  "delivery_status": "ok",
  "missing_reason": "",
  "raw_html": "attachments/2233559a8999/pages/source.html",
  "local_html": "attachments/2233559a8999/pages/article.html",
  "body_base_path": "attachments/2233559a8999/pages/",
  "body_markdown_path": "attachments/2233559a8999/pages/article.md"
}