{
  "source_file": "0930",
  "source_platform": "Ghost",
  "author": "Peng Qian / Data Leads Future",
  "title_listed": "Build Long-Term and Short-Term Memory for Agents Using RedisVL",
  "keywords": "",
  "domain": "大模型算法",
  "content_type": "工程实践",
  "is_paid_flag": "否",
  "url": "https://www.dataleadsfuture.com/build-long-term-and-short-term-memory-for-agents-using-redisvl/",
  "publish_date": "2026-01",
  "corpus_stage": "",
  "notes": "",
  "id": "a2f040236c41",
  "collected_at": "2026-10-02T12:27:07",
  "title": "Build Long-Term and Short-Term Memory for Agents Using RedisVL",
  "body_markdown": "Agentic AI\nBuild Long-Term and Short-Term Memory for Agents Using RedisVL\nPros and cons analysis based on real-world practice\nPeng Qian\n23 Jan 2026\n—\n10 min read\nShare\nBuild Long-Term and Short-Term Memory for Agents Using RedisVL. Image by DALL-E-3\nIntroduction\nFor this weekend note, I want to share some tries I made using RedisVL to add short-term and long-term memory to my agent system.\nTLDR: RedisVL works pretty well for short-term memory. It feels a bit simpler than using the traditional Redis API. For long-term memory with semantic search, the experience is not good. I do not recommend it.\nWhy RedisVL?\nBig companies like to use mature infrastructure to build new features.\nWe know mem0 and Graphiti are good open source software for long-term agent memory. But companies want to stay safe. Building new infrastructure costs money. It is unstable. It needs people who know how to run it.\nSo when Redis launched RedisVL with vector search, we naturally wanted to try it first. You can connect it to existing Redis clusters and start using it. That sounds nice. But is it really nice? We need to try it for real.\nToday I will cover how to use\nMessageHistory\nand\nSemanticMessageHistory\nfrom RedisVL to add short-term and long-term memory to agents built on the Microsoft Agent Framework.\nYou can find the source code at the end of this article.\nPreparation\nInstall Redis\nIf you want to try it locally, you can install a Redis instance with Docker.\ndocker run -d --name redis -p 6379:6379 -p 8001:8001 redis/redis-stack:latest\nCannot use Docker Desktop? See my other article.\nA Quick Guide to Containerizing Agent Applications with Podman\nAlternative solutions compatible with Docker SDK\nData Leads Future\nPeng Qian\nThe Redis instance will listen on ports 6379 and 8001. Your RedisVL client should connect to\nredis://localhost:6379\n. You can visit\nhttp://localhost:8001\nin the browser to open the Redis console.\nInstall RedisVL\nInstall RedisVL with pip.\npip install redisvl\nAfter installation, you can use the RedisVL CLI to manage your indexes and keep your testing neat.\nrvl index listall\nImplement Short-Term Memory Using MessageHistory\nThere are lots of “How to” RedisVL articles online, so let’s start straight from Microsoft Agent Framework and see how to use\nMessageHistory\nfor short-term memory.\nAs in the official tutorial, you should implement a\nRedisVLMessageStore\nbased on\nChatMessageStoreProtocol\n.\nclass RedisVLMessageStore(ChatMessageStoreProtocol):\n    def __init__(\n        self,\n        thread_id: str = \"common_thread\",\n        top_k: int = 6,\n        session_tag: str | None = None,\n        redis_url: str | None = \"redis://localhost:6379\",\n    ):\n        self._thread_id = thread_id\n        self._top_k = top_k\n        self._session_tag = session_tag or f\"session_{uuid4()}\"\n        self._redis_url = redis_url\n        self._init_message_history()\nIn\n__init__\nyou should note two parameters.\nthread_id\nis used for the\nname\nparameter when creating\nMessageHistory\n. I like to bind it to the agent. Each agent gets a unique\nthread_id\n.\nsession_tag\nlets you set a tag for each user so different sessions do not mix.\nThe protocol asks us to implement two methods\nlist_messages\nand\nadd_messages\n.\nlist_messages\nruns before the agent calls the LLM. It gets all available chat messages from the message store. It takes no parameters, so it cannot support long-term memory. More on that later.\nadd_messages\nruns after the agent gets the LLM’s reply. It stores new messages into the message store.\nHere is how the message store works.\nThe calling order of message store in the agent. Image by Author\nSo in\nlist_messages\nand\nadd_messages\nwe just use RedisVL’s\nMessageHistory\nto do the job.\nlist_messages\nbelow uses\nget_recent\nto get\ntop_k\nrecent messages and turns them into\nChatMessage\n.\nclass RedisVLMessageStore(ChatMessageStoreProtocol):\n    ...\n    \n    async def list_messages(self) -> list[ChatMessage]:\n        messages: list[dict[str, str]] = self._message_history.get_recent(\n            top_k=self._top_k,\n            session_tag=self._session_tag,\n        )\n        return [self._back_to_chat_message(message)\n                for message in messages]\nadd_messages\nturns the\nChatMessage\ninto Redis messages and calls\nadd_messages\nto store them.\nclass RedisVLMessageStore(ChatMessageStoreProtocol):\n    ...\n    \n    async def add_messages(self, messages: Sequence[ChatMessage]):\n        messages = [self._to_redis_message(message)\n                    for message in messages]\n        self._message_history.add_messages(\n            messages,\n            session_tag=self._session_tag\n        )\nThat is short-term memory done with RedisVL. You may also implement\ndeserialize\n,\nserialize\nand\nupdate_from_state\nfor saving and loading the memory, but it is not important now. See the full code at the end.\nTest RedisVLMessageStore\nLet’s build an agent and test the message store.\nagent = OpenAILikeChatClient(\n    model_id=Qwen3.NEXT\n).create_agent(\n    name=\"assistant\",\n    instructions=\"You're a little helper who answers my questions in one sentence.\",\n    chat_message_store_factory=lambda: RedisVLMessageStore(\n        session_tag=\"user_abc\"\n    )\n)\nNow a console loop for multi-turn dialog. Remember, Microsoft Agent Framework does not support short-term memory unless you use an\nAgentThread\nand pass it to\nrun\n.\nasync def main():\n    thread = agent.get_new_thread()\n    while True:\n        user_input = input(\"User: \")\n        if user_input.startswith(\"exit\"):\n            break\n        response = await agent.run(user_input, thread=thread)\n        print(f\"\\nAssistant: {response.text}\")\n    thread.message_store.clear()\nAgentThread\nwhen created calls the factory method to build the\nRedisVLMessageStore\n.\nTo check if the store works, we can use\nmlflow.openai.autolog()\nto see if messages sent to the LLM contain historical messages.\nimport mlflow\nmlflow.set_tracking_uri(os.environ.get(\"MLFLOW_TRACKING_URI\"))\nmlflow.set_experiment(\"Default\")\nmlflow.openai.autolog()\nYou can see that the conversation comes with a complete history of messages. Image by Author\nSee my other article for using MLFlow to track LLM calls.\nMonitoring Qwen 3 Agents with MLflow 3.x: End-to-End Tracing Tutorial\nEnhance your multi-agent application’s observability, explainability and Traceability\nData Leads Future\nPeng Qian\nLet’s open the Redis console to see the cache.\nHow the cache is stored in Redis. Image by Author\nAs you can see, after using\nMessageHistory\nas MAF's message store, we can implement multi-turn conversations with historical messages.\nWith\nthread_id\nand\nsession_tag\nparameters, we can also implement the feature that lets users switch between multiple conversation sessions, like in popular LLM chat applications.\nFeels simpler than the official\nRedisMessageStore\nsolution right?\nImplement Long-Term Memory Using SemanticMessageHistory\nSemanticMessageHistory\nis a subclass of\nMessageHistory\n. It adds a\nget_relevant\nmethod for vector search.\nExample:\nprompt = \"what have I learned about the size of England?\"\nsemantic_history.set_distance_threshold(0.35)\ncontext = semantic_history.get_relevant(prompt)\nfor message in context:\n    print(message)\nBatches: 100%|██████████| 1/1 [00:00<00:00, 56.30it/s]\n{'role': 'user', 'content': 'what is the size of England compared to Portugal?'}\nCompared to\nMessageHistory\nthe big thing here is that we can get the most relevant historical messages based on the user request.\nYou might think that if\nMessageStore\nshort-term memory is nice, then\nSemanticMessageHistory\nwith semantic search must be even better.\nFrom my experience, this is not the case.\nFrom my test results, it is not like that. Let’s now make a long-term memory adapter for Microsoft Agent Framework using\nSemanticMessageHistory\nand see the result.\nIn my latest research, I’m going to bring in an LLM to handle memory retrieval so long‑term memory can become more interconnected：\nAdvanced RedisVL Long-term Memory Tutorial: Using an LLM to Extract Memories\nBuilding an intelligent, context-aware memory system\nData Leads Future\nPeng Qian\nUse SemanticMessageHistory in Microsoft Agent Framework\nEarlier I said\nlist_messages\nin\nChatMessageStoreProtocol\nhas no parameters, so we cannot search history. Thus, we cannot use\nMessageStore\nfor long-term memory.\nMicrosoft Agent Framework has a\nContextProvider\nclass. From its name, it is for context engineering.\nSo we should build long-term memory on this class.\nclass RedisVLSemanticMemory(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        redis_url: str = \"redis://localhost:6379\",\n        embedding_model: str = \"BAAI/bge-m3\",\n        embedding_api_key: str | None = None,\n        embedding_endpoint: str | None = None,\n    ):\n        self._thread_id = thread_id or \"semantic_thread\"\n        self._session_tag = session_tag or f\"session_{uuid4()}\"\n        self._distance_threshold = distance_threshold\n        self._redis_url = redis_url\n        self._embedding_model = embedding_model\n        self._embedding_api_key = embedding_api_key or os.getenv(\"EMBEDDING_API_KEY\")\n        self._embedding_endpoint = embedding_endpoint or os.getenv(\"EMBEDDING_ENDPOINT\")\n        self._init_semantic_store()\nContextProvider\nhas two methods\ninvoked\nand\ninvoking\n.\ninvoked\nruns after LLM call. It stores the latest messages in RedisVL. It has both\nrequest_message\nand\nresponse_messages\nparameters but stores them separately.\ninvoking\nruns before LLM call. It uses the user’s current input to search for relevant history in RedisVL and returns a\nContext\nobject.\nThe\nContext\nobject has three variables.\ninstructions\nstring. The agent adds this to the system prompt.\nmessages\nlist. Put history messages found in long-term memory here.\ntools\nlist for functions. The agent adds these tools to its\nChatOptions\n.\nThe purpose of the three types of messages retrieved. Image by Author\nSince we want to use vector search to get relevant history, we put those messages in\nmessages\n. The order between\nMessageStore\nmessages and\nContextProvider\nmessages matters. Here is the order of their calls.\nThe calling order of long-term and short-term memory in the agent. Image by Author\nSetting up a TextVectorizer\nSemantic vector search needs embeddings. We must set up a vectorizer.\nIn\n__init__\nbesides\nthread_id\nand\nsession_tag\nwe set the embedding model info.\nclass RedisVLSemanticMemory(ContextProvider):\n    ...\n    def _init_semantic_store(self) -> None:\n        if not self._embedding_api_key:\n            vectorizer = HFTextVectorizer(\n                model=self._embedding_model,\n            )\n        else:\n            vectorizer = OpenAITextVectorizer(\n                model=self._embedding_model,\n                api_config={\n                    \"api_key\": self._embedding_api_key,\n                    \"base_url\": self._embedding_endpoint\n                }\n            )\n    \n        self._semantic_store = SemanticMessageHistory(\n            name=self._thread_id,\n            session_tag=self._session_tag,\n            distance_threshold=self._distance_threshold,\n            redis_url=self._redis_url,\n            vectorizer=vectorizer,\n        )\nI can choose a server-hosted embedding model with OpenAI API or a local HuggingFace model, depending on whether\nembedding_api_key\nis set.\nImplement invoked and invoking methods\ninvoked\nis easy. As said\nSemanticMessageHistory\nstores request and response separately. I merge them into one list, then call\nadd_messages\n.\nclass RedisVLSemanticMemory(ContextProvider):\n    ...\n    async def invoked(\n        self,\n        request_messages: ChatMessage | Sequence[ChatMessage],\n        response_messages: ChatMessage | Sequence[ChatMessage] | None = None,\n        invoke_exception: Exception | None = None,\n        **kwargs: Any,\n    ) -> None:\n        if isinstance(request_messages, ChatMessage):\n            request_messages = [request_messages]\n        if isinstance(response_messages, ChatMessage):\n            response_messages = [response_messages]\n        chat_messages = request_messages + response_messages\n        messages = [self._to_redis_message(message)\n                    for message in chat_messages]\n        self._semantic_store.add_messages(\n            messages=messages,\n            session_tag=self._session_tag,\n        )\ninvoking\nbelow:\nclass RedisVLSemanticMemory(ContextProvider):\n    ...\n    async def invoking(\n        self,\n        messages: ChatMessage | MutableSequence[ChatMessage],\n        **kwargs: Any\n    ) -> Context:\n        if isinstance(messages, ChatMessage): # 1\n            messages = [messages]\n        prompt = \"\\n\".join([message.text\n                            for message in messages])\n        context = self._semantic_store.get_relevant(\n            prompt=prompt,\n            raw=True,\n            session_tag=self._session_tag,\n        )\n        context = sorted(context, key=lambda m: m['timestamp']) # 2\n        relevant_messages = [self._back_to_chat_message(message)\n                             for message in context]\n        print([m.text for m in relevant_messages])\n        return Context(messages=relevant_messages) # 3\nPoints to note.\nThe\nmessages\nparameter may be a list for multi-modal input. Merge all text.\nSince messages are stored separately, I need to sort them by timestamp to keep order.\nPut the retrieved messages into\nContext.messages\nso they go to the end of the current chat messages.\nTest semantic memory\nUnlike message store, we can set\nContextProvider\ndirectly in the agent.\nmemory_provider = RedisVLSemanticMemory(\n    session_tag=\"user_abc\",\n    distance_threshold=0.3,\n)\nagent = OpenAILikeChatClient(\n    model_id=Qwen3.NEXT\n).create_agent(\n    name=\"assistant\",\n    instructions=\"You're a little helper who answers my questions in one sentence.\",\n    context_providers=memory_provider,\n)\nNow a\nmain\nwith a\nthread\ninstance to keep short-term memory while testing multi turn dialog.\nasync def main():\n    thread = agent.get_new_thread()\n    while True:\n        user_input = input(\"User: \")\n        if user_input.startswith(\"exit\"):\n            break\n        response = await agent.run(user_input, thread=thread)\n        print(response.text)\n    memory_provider.clear()\nTest result:\nThe\ndistance_threshold\nis too high, causing irrelevant messages to be retrieved. Image by Author\nIt seems the default value of\ndistance_threshold\n0.3 is too high. Let's set it lower:\nmemory_provider = RedisVLSemanticMemory(\n    session_tag=\"user_abc\",\n    distance_threshold=0.2,\n)\nTest again:\nOnly request messages were retrieved, not response messages. Image by Author\nLower threshold stops unrelated messages. But since requests and responses are stored separately, only requests are found. ContextProvider puts retrieved messages at the end of the message list. The LLM may think the user asked two questions. MLFlow shows it.\nTwo similar questions were both added to the message list, but without attaching the already provided answers. Image by Author\nThis is bad. We care more about the LLM’s answers than the requests. But vector search often finds the questions, not the answers. This just adds useless questions and does not help the LLM answer.\nHard to say if the fault is Microsoft Agent Framework or RedisVL.\nWhen\nContextProvider\nlong-term finds related chat messages, they go after the ones from message store. If long-term and short-term messages repeat, they can confuse the LLM.\nAlso, RedisVL not storing requests and responses together is a choice I do not like. LLM responses cost more. In production, a response may involve web search, RAG retrieval, or running code. But vector search finds just the request, not the answer. That is a waste.\nConclusion\nToday, we tried using RedisVL for short-term and long-term memory in Microsoft Agent Framework and checked the results.\nRedisVL is very handy for short-term agent memory. It is simpler than using the Redis API.\nBut\nSemanticMessageHistory\nfor semantic search of the user history did not perform well. I explained why.\nThanks to the solid Redis infrastructure, semantic caches with RedisVL are simpler than other vector solutions.\nNext time, I will show you a semantic cache with RedisVL to save big costs for your company.\nShare your thoughts in the comments.\nSubscribe to my blog to follow my latest agent app work.\nAnd share this article with friends. Maybe it will help more people.😁\nHere's the source code of this article:\nagentic-ai-playground/12_RedisVL_Long_Short_Memory at main · qtalen/agentic-ai-playground\nContribute to qtalen/agentic-ai-playground development by creating an account on GitHub.\nGitHub\nqtalen\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.\nYou can unsubscribe anytime.",
  "metadata": {
    "title": "Build Long-Term and Short-Term Memory for Agents Using RedisVL",
    "description": "Discover how to use RedisVL to build short and long-term memory in Microsoft Agent Framework agents, with setup steps, code examples, and real-world test insights.",
    "keywords": null,
    "author": null,
    "og:site_name": "Data Leads Future",
    "og:type": "article",
    "og:title": "Build Long-Term and Short-Term Memory for Agents Using RedisVL",
    "og:description": "Pros and cons analysis based on real-world practice",
    "og:url": "https://www.dataleadsfuture.com/build-long-term-and-short-term-memory-for-agents-using-redisvl/",
    "og:image": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/size/w1200/2026/01/cover.webp",
    "og:image:width": "1200",
    "og:image:height": "686",
    "twitter:card": "summary_large_image",
    "twitter:title": "Build Long-Term and Short-Term Memory for Agents Using RedisVL",
    "twitter:description": "Pros and cons analysis based on real-world practice",
    "twitter:url": "https://www.dataleadsfuture.com/build-long-term-and-short-term-memory-for-agents-using-redisvl/",
    "twitter:image": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/size/w1200/2026/01/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-01-23T04:20:56.000Z",
    "article:modified_time": "2026-04-22T08:18:47.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/a2f040236c41/code/body-000.txt",
      "chars": 77,
      "language": "text"
    },
    {
      "file": "attachments/a2f040236c41/code/body-001.txt",
      "chars": 19,
      "language": "text"
    },
    {
      "file": "attachments/a2f040236c41/code/body-002.txt",
      "chars": 17,
      "language": "text"
    },
    {
      "file": "attachments/a2f040236c41/code/body-003.txt",
      "chars": 456,
      "language": "text"
    },
    {
      "file": "attachments/a2f040236c41/code/body-004.txt",
      "chars": 373,
      "language": "text"
    },
    {
      "file": "attachments/a2f040236c41/code/body-005.txt",
      "chars": 347,
      "language": "text"
    },
    {
      "file": "attachments/a2f040236c41/code/body-006.txt",
      "chars": 275,
      "language": "text"
    },
    {
      "file": "attachments/a2f040236c41/code/body-007.txt",
      "chars": 308,
      "language": "text"
    },
    {
      "file": "attachments/a2f040236c41/code/body-008.txt",
      "chars": 133,
      "language": "text"
    },
    {
      "file": "attachments/a2f040236c41/code/body-009.txt",
      "chars": 194,
      "language": "text"
    },
    {
      "file": "attachments/a2f040236c41/code/body-010.txt",
      "chars": 135,
      "language": "text"
    },
    {
      "file": "attachments/a2f040236c41/code/body-011.txt",
      "chars": 863,
      "language": "text"
    },
    {
      "file": "attachments/a2f040236c41/code/body-012.txt",
      "chars": 797,
      "language": "text"
    },
    {
      "file": "attachments/a2f040236c41/code/body-013.txt",
      "chars": 821,
      "language": "text"
    },
    {
      "file": "attachments/a2f040236c41/code/body-014.txt",
      "chars": 819,
      "language": "text"
    },
    {
      "file": "attachments/a2f040236c41/code/body-015.txt",
      "chars": 316,
      "language": "text"
    },
    {
      "file": "attachments/a2f040236c41/code/body-016.txt",
      "chars": 285,
      "language": "text"
    },
    {
      "file": "attachments/a2f040236c41/code/body-017.txt",
      "chars": 98,
      "language": "text"
    }
  ],
  "images": [
    {
      "status": "ok",
      "url": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/size/w1200/2026/01/cover.webp",
      "bytes": 109966,
      "reused": true,
      "local_path": "attachments/a2f040236c41/images/000.webp",
      "src": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/size/w1200/2026/01/cover.webp",
      "alt": "Build Long-Term and Short-Term Memory for Agents Using RedisVL.",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/icon/color_192_192-60.png",
      "bytes": 17721,
      "reused": false,
      "local_path": "attachments/a2f040236c41/images/body-1790c6b7b2d776af715b.png",
      "src": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/icon/color_192_192-60.png",
      "alt": "",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/thumbnail/podman.webp",
      "bytes": 106536,
      "reused": true,
      "local_path": "attachments/a2f040236c41/images/005.webp",
      "src": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/thumbnail/podman.webp",
      "alt": "",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/2026/01/image-5.png",
      "bytes": 18767,
      "reused": true,
      "local_path": "attachments/a2f040236c41/images/006.png",
      "src": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/2026/01/image-5.png",
      "alt": "The calling order of message store in the agent.",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/2026/01/image-6.png",
      "bytes": 28186,
      "reused": true,
      "local_path": "attachments/a2f040236c41/images/008.png",
      "src": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/2026/01/image-6.png",
      "alt": "You can see that the conversation comes with a complete history of messages.",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/icon/color_192_192-61.png",
      "bytes": 17721,
      "reused": false,
      "local_path": "attachments/a2f040236c41/images/body-af7686aa08f7ce4ad4c6.png",
      "src": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/icon/color_192_192-61.png",
      "alt": "",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/thumbnail/Tracing-with-MLflow-3.x-1-1.webp",
      "bytes": 99038,
      "reused": true,
      "local_path": "attachments/a2f040236c41/images/010.webp",
      "src": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/thumbnail/Tracing-with-MLflow-3.x-1-1.webp",
      "alt": "",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/2026/01/image-7.png",
      "bytes": 44178,
      "reused": true,
      "local_path": "attachments/a2f040236c41/images/011.png",
      "src": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/2026/01/image-7.png",
      "alt": "How the cache is stored in Redis.",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/icon/color_192_192-65.png",
      "bytes": 17721,
      "reused": false,
      "local_path": "attachments/a2f040236c41/images/body-d02cfb51a2c426fee7ff.png",
      "src": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/icon/color_192_192-65.png",
      "alt": "",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/thumbnail/cover-13.webp",
      "bytes": 63136,
      "reused": true,
      "local_path": "attachments/a2f040236c41/images/015.webp",
      "src": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/thumbnail/cover-13.webp",
      "alt": "",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/2026/01/image-8.png",
      "bytes": 10577,
      "reused": true,
      "local_path": "attachments/a2f040236c41/images/016.png",
      "src": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/2026/01/image-8.png",
      "alt": "The purpose of the three types of messages retrieved.",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/2026/01/image-9.png",
      "bytes": 16050,
      "reused": true,
      "local_path": "attachments/a2f040236c41/images/018.png",
      "src": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/2026/01/image-9.png",
      "alt": "The calling order of long-term and short-term memory in the agent.",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/2026/01/image-10.png",
      "bytes": 49404,
      "reused": true,
      "local_path": "attachments/a2f040236c41/images/020.png",
      "src": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/2026/01/image-10.png",
      "alt": "The distance_threshold is too high, causing irrelevant messages to be retrieved.",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/2026/01/image-11.png",
      "bytes": 12505,
      "reused": true,
      "local_path": "attachments/a2f040236c41/images/022.png",
      "src": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/2026/01/image-11.png",
      "alt": "Only request messages were retrieved, not response messages.",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/2026/01/image-12.png",
      "bytes": 16677,
      "reused": true,
      "local_path": "attachments/a2f040236c41/images/024.png",
      "src": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/2026/01/image-12.png",
      "alt": "Two similar questions were both added to the message list, but without attaching the already provided answers.",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/icon/pinned-octocat-093da3e6fa40-30.svg",
      "bytes": 1009,
      "reused": false,
      "local_path": "attachments/a2f040236c41/images/body-aec1b855bc382c80ece1.svg",
      "src": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/icon/pinned-octocat-093da3e6fa40-30.svg",
      "alt": "",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/thumbnail/agentic-ai-playground-28",
      "bytes": 100100,
      "reused": false,
      "local_path": "attachments/a2f040236c41/images/body-e57a03af955e7443ac2f.img",
      "src": "https://storage.ghost.io/c/33/67/33678c00-2c15-4961-93e9-497b427e2006/content/images/thumbnail/agentic-ai-playground-28",
      "alt": "",
      "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/a-quick-guide-to-containerizing-agent-applications-with-podman/",
      "label": "A Quick Guide to Containerizing Agent Applications with Podman Alternative solutions compatible with Docker SDK Data Lea",
      "type": "a"
    },
    {
      "href": "https://www.dataleadsfuture.com/monitoring-qwen-3-agents-with-mlflow-3-x-end-to-end-tracking-tutorial/",
      "label": "Monitoring Qwen 3 Agents with MLflow 3.x: End-to-End Tracing Tutorial Enhance your multi-agent application’s observabili",
      "type": "a"
    },
    {
      "href": "https://www.dataleadsfuture.com/advanced-redisvl-long-term-memory-tutorial-using-an-llm-to-extract-memories/",
      "label": "Advanced RedisVL Long-term Memory Tutorial: Using an LLM to Extract Memories Building an intelligent, context-aware memo",
      "type": "a"
    },
    {
      "href": "https://github.com/qtalen/agentic-ai-playground/tree/main/12_RedisVL_Long_Short_Memory",
      "label": "agentic-ai-playground/12_RedisVL_Long_Short_Memory at main · qtalen/agentic-ai-playground Contribute to qtalen/agentic-a",
      "type": "a"
    }
  ],
  "repair_version": 2,
  "repaired_at": "2026-10-14T10:47:47Z",
  "source_url": "https://www.dataleadsfuture.com/build-long-term-and-short-term-memory-for-agents-using-redisvl/",
  "papers": [],
  "actual_video_files": [],
  "body_chars": 16902,
  "expected_body_images": 17,
  "discovery_status": "ok",
  "delivery_status": "ok",
  "missing_reason": "",
  "raw_html": "attachments/a2f040236c41/pages/source.html",
  "local_html": "attachments/a2f040236c41/pages/article.html",
  "body_base_path": "attachments/a2f040236c41/pages/",
  "body_markdown_path": "attachments/a2f040236c41/pages/article.md"
}