Skip to content

Latest commit

 

History

History

README.md

ReMe Long-Term Memory in AgentScope

This example demonstrates how to:

  • Use ReMe (Reflection Memory) to provide three specialized types of persistent memory storage for AgentScope agents
  • Record and retrieve personal information, task execution trajectories, and tool usage patterns across sessions
  • Integrate long-term memory with ReActAgent for context-aware conversations and continuous learning
  • Configure DashScope embedding models and vector stores for efficient memory management

Overview

ReMe (Reflection Memory) provides three types of long-term memory for intelligent agents:

  1. Personal Memory (ReMePersonalLongTermMemory) - Records and retrieves persistent personal information, preferences, and facts about users
  2. Task Memory (ReMeTaskLongTermMemory) - Learns from task execution trajectories and retrieves relevant past experiences for similar tasks
  3. Tool Memory (ReMeToolLongTermMemory) - Records tool execution results and generates usage guidelines to improve tool calling

Prerequisites

  • Python 3.12 or higher
  • DashScope API key from Alibaba Cloud (for the examples)

QuickStart

Installation

# Install agentscope from source
cd {PATH_TO_AGENTSCOPE}
pip install -e .

# Install required dependencies
pip install reme-ai python-dotenv

Setup

Set up your API key:

export DASHSCOPE_API_KEY='YOUR_API_KEY'

Or create a .env file:

DASHSCOPE_API_KEY=YOUR_API_KEY

Run Examples

# Personal Memory Example - 5 core interfaces
python personal_memory_example.py

# Task Memory Example - 5 core interfaces
python task_memory_example.py

# Tool Memory Example - Complete workflow with ReActAgent
python tool_memory_example.py

Note: The examples use DashScope models by default. To use OpenAI or other models, modify the model initialization in the example code accordingly.

Key Features

  • Three Specialized Memory Types: Personal, Task, and Tool memory for different use cases
  • Dual Interface Design: Both tool functions (for agent calling) and direct methods (for programmatic use)
  • Vector-based Retrieval: Efficient semantic search using embedding models and vector stores
  • Async-first Architecture: Full async/await support for non-blocking operations
  • ReActAgent Integration: Seamless integration with AgentScope's ReActAgent and Toolkit
  • Automatic Context Management: Uses async context managers for proper resource handling

Core Concepts

Memory Types and Their Use Cases

Memory Type Purpose When to Use
Personal Memory Store user preferences, habits, and personal facts User profiles, personalized assistants, long-term user context
Task Memory Learn from task execution trajectories Problem-solving, debugging, repeated workflows, learning from past successes
Tool Memory Record tool usage patterns and generate guidelines Tool-using agents, improving tool call accuracy, avoiding past errors

Interface Design

Personal Memory and Task Memory provide 5 core interfaces:

  1. record_to_memory() - Tool function for agents to record memories (returns ToolResponse)
  2. retrieve_from_memory() - Tool function for agents to retrieve memories (returns ToolResponse)
  3. record() - Direct method for programmatic recording (returns None)
  4. retrieve() - Direct method for programmatic retrieval (returns str)
  5. ReActAgent Integration - Use memory with long_term_memory and long_term_memory_mode parameters

Tool Memory provides 2 core interfaces (no tool functions):

  1. record() - Direct method for recording tool execution results (returns None)
  2. retrieve() - Direct method for retrieving tool usage guidelines (returns str)

Usage Examples

1. Personal Memory

Use Case: Record and retrieve user preferences, habits, and personal information.

import asyncio
import os
from agentscope.memory import ReMePersonalLongTermMemory
from agentscope.embedding import DashScopeTextEmbedding
from agentscope.message import Msg
from agentscope.model import DashScopeChatModel


async def main():
    # Initialize personal memory
    personal_memory = ReMePersonalLongTermMemory(
        agent_name="Friday",
        user_name="user_123",
        model=DashScopeChatModel(
            model_name="qwen3-max",
            api_key=os.environ.get("DASHSCOPE_API_KEY"),
            stream=False,
        ),
        embedding_model=DashScopeTextEmbedding(
            model_name="text-embedding-v4",
            api_key=os.environ.get("DASHSCOPE_API_KEY"),
            dimensions=1024,
        ),
    )

    # Use async context manager (required!)
    async with personal_memory:
        # Interface 1: record_to_memory (tool function)
        result = await personal_memory.record_to_memory(
            thinking="User sharing travel preferences",
            content=[
                "I prefer to stay in homestays when traveling to Hangzhou",
                "I like to visit the West Lake in the morning",
                "I enjoy drinking Longjing tea",
            ],
        )

        # Interface 2: retrieve_from_memory (tool function)
        result = await personal_memory.retrieve_from_memory(
            keywords=["Hangzhou travel", "tea preference"],
        )

        # Interface 3: record (direct method)
        await personal_memory.record(
            msgs=[
                Msg(role="user", content="I work as a software engineer", name="user"),
                Msg(role="assistant", content="Got it!", name="assistant"),
            ],
        )

        # Interface 4: retrieve (direct method)
        memories = await personal_memory.retrieve(
            msg=Msg(role="user", content="What do you know about my work?", name="user"),
        )
        print(memories)


asyncio.run(main())

Integration with ReActAgent (Interface 5):

from agentscope.agent import ReActAgent
from agentscope.formatter import DashScopeChatFormatter
from agentscope.memory import InMemoryMemory
from agentscope.tool import Toolkit

async def use_with_agent():
    personal_memory = ReMePersonalLongTermMemory(...)

    async with personal_memory:
        agent = ReActAgent(
            name="Friday",
            sys_prompt="You are Friday with long-term memory. Always record user information and retrieve memories when needed.",
            model=DashScopeChatModel(...),
            formatter=DashScopeChatFormatter(),
            toolkit=Toolkit(),
            memory=InMemoryMemory(),
            long_term_memory=personal_memory,  # Attach personal memory
            long_term_memory_mode="both",  # Enable both record and retrieve tools
        )

        # Agent can now use record_to_memory and retrieve_from_memory as tools
        msg = Msg(role="user", content="I prefer staying in homestays", name="user")
        response = await agent(msg)

2. Task Memory

Use Case: Learn from task execution trajectories and retrieve relevant experiences.

from agentscope.memory import ReMeTaskLongTermMemory


async def main():
    # Initialize task memory
    task_memory = ReMeTaskLongTermMemory(
        agent_name="TaskAssistant",
        user_name="task_workspace_123",  # Acts as workspace_id
        model=DashScopeChatModel(...),
        embedding_model=DashScopeTextEmbedding(...),
    )

    async with task_memory:
        # Interface 1: record_to_memory with score
        result = await task_memory.record_to_memory(
            thinking="Recording successful debugging approach",
            content=[
                "For API 404 errors: Check route definition, verify URL path, ensure correct port",
                "Always use linter to catch typos in route paths",
            ],
            score=0.95,  # High score for successful trajectory
        )

        # Interface 2: retrieve_from_memory
        result = await task_memory.retrieve_from_memory(
            keywords=["debugging", "API errors"],
        )

        # Interface 3: record with score in direct method
        await task_memory.record(
            msgs=[
                Msg(role="user", content="I'm getting a 404 error", name="user"),
                Msg(role="assistant", content="Let's check the route path...", name="assistant"),
                Msg(role="user", content="Found the typo!", name="user"),
            ],
            score=0.95,  # Optional score for this trajectory
        )

        # Interface 4: retrieve (direct method)
        experiences = await task_memory.retrieve(
            msg=Msg(role="user", content="How to debug API errors?", name="user"),
        )
        print(experiences)


asyncio.run(main())

Integration with ReActAgent (Interface 5):

async def use_with_agent():
    task_memory = ReMeTaskLongTermMemory(...)

    async with task_memory:
        agent = ReActAgent(
            name="TaskAssistant",
            sys_prompt="You are a task assistant. Record solutions and retrieve past experiences before solving problems.",
            model=DashScopeChatModel(...),
            formatter=DashScopeChatFormatter(),
            toolkit=Toolkit(),
            memory=InMemoryMemory(),
            long_term_memory=task_memory,
            long_term_memory_mode="both",
        )

        # Agent learns from task executions over time
        msg = Msg(role="user", content="How should I optimize database queries?", name="user")
        response = await agent(msg)

3. Tool Memory

Use Case: Record tool execution results and generate usage guidelines for better tool calling.

Complete Workflow:

import json
from datetime import datetime
from agentscope.memory import ReMeToolLongTermMemory
from agentscope.tool import Toolkit, ToolResponse
from agentscope.message import Msg, TextBlock


# Step 1: Define tools
async def web_search(query: str, max_results: int = 5) -> ToolResponse:
    """Search the web for information."""
    result = f"Found {max_results} results for query: '{query}'"
    return ToolResponse(content=[TextBlock(type="text", text=result)])


async def main():
    # Initialize tool memory
    tool_memory = ReMeToolLongTermMemory(
        agent_name="ToolBot",
        user_name="tool_workspace_demo",
        model=DashScopeChatModel(...),
        embedding_model=DashScopeTextEmbedding(...),
    )

    async with tool_memory:
        # Step 2: Record tool execution history (accepts JSON strings in msgs)
        tool_result = {
            "create_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
            "tool_name": "web_search",
            "input": {"query": "Python asyncio tutorial", "max_results": 10},
            "output": "Found 10 results for query: 'Python asyncio tutorial'",
            "token_cost": 150,
            "success": True,
            "time_cost": 2.3
        }

        # Interface 1: record (accepts JSON strings in message content)
        await tool_memory.record(
            msgs=[Msg(role="assistant", content=json.dumps(tool_result), name="assistant")],
        )

        # Step 3: Retrieve tool guidelines
        # Interface 2: retrieve returns summarized guidelines
        guidelines = await tool_memory.retrieve(
            msg=Msg(role="user", content="web_search", name="user"),
        )

        # Step 4: Inject guidelines into agent system prompt
        toolkit = Toolkit()
        toolkit.register_tool_function(web_search)

        base_prompt = "You are ToolBot, a helpful AI assistant."
        enhanced_prompt = f"{base_prompt}\n\n# Tool Guidelines:\n{guidelines}"

        agent = ReActAgent(
            name="ToolBot",
            sys_prompt=enhanced_prompt,  # Guidelines enhance tool usage
            model=DashScopeChatModel(...),
            formatter=DashScopeChatFormatter(),
            toolkit=toolkit,
            memory=InMemoryMemory(),
        )

        # Agent now uses tools with learned guidelines
        msg = Msg(role="user", content="Search for Python design patterns", name="user")
        response = await agent(msg)


asyncio.run(main())

Note: Tool Memory does NOT provide record_to_memory() and retrieve_from_memory() tool functions. It only provides direct record() and retrieve() methods. Tool Memory is designed to be used programmatically to enhance agent system prompts, not as agent-callable tools.

API Reference

Common Parameters

All memory types share these initialization parameters:

ReMePersonalLongTermMemory(
    agent_name: str,           # Name of the agent using this memory
    user_name: str,            # User identifier (acts as workspace_id in ReMe)
    model: ModelWrapper,       # LLM for summarization and processing
    embedding_model: EmbeddingWrapper,  # Embedding model for vector retrieval
    vector_store_dir: str = "./memory_vector_store",  # Storage location
)

Interface Specifications

Personal Memory

Interface Type Signature Returns Description
record_to_memory Tool Function (thinking: str, content: list[str]) ToolResponse Record personal information with reasoning
retrieve_from_memory Tool Function (keywords: list[str], limit: int = 3) ToolResponse Retrieve memories by keywords
record Direct Method (msgs: list[Msg]) None Record message conversations
retrieve Direct Method (msg: Msg, top_k: int = 3) str Query-based retrieval

Parameters:

  • thinking: Reasoning about what to record
  • content: List of strings to remember
  • keywords: Search keywords
  • limit: Results per keyword (tool function, default: 3)
  • top_k: Total results to retrieve (direct method, default: 3)

Task Memory

Interface Type Signature Returns Description
record_to_memory Tool Function (thinking: str, content: list[str], score: float = 1.0) ToolResponse Record task trajectory with score
retrieve_from_memory Tool Function (keywords: list[str], top_k: int = 5) ToolResponse Retrieve experiences by keywords
record Direct Method (msgs: list[Msg], score: float = 1.0) None Record message conversations with score
retrieve Direct Method (msg: Msg, top_k: int = 5) str Query-based experience retrieval

Parameters:

  • thinking: Reasoning about the task execution
  • content: Task execution information and insights
  • score: Success score for the trajectory (0.0-1.0, default: 1.0)
  • keywords: Search keywords (e.g., task type, domain)
  • top_k: Number of results to retrieve (default: 5)

Tool Memory

Interface Type Signature Returns Description
record Direct Method (msgs: list[Msg]) None Record tool results as messages (JSON format)
retrieve Direct Method (msg: Msg) str Retrieve guidelines for tools

Parameters:

  • msgs: List of messages where content contains JSON strings with tool execution metadata:
    • create_time: Timestamp ("%Y-%m-%d %H:%M:%S")
    • tool_name: Tool identifier
    • input: Parameters used (dict)
    • output: Execution result (str)
    • token_cost: Token usage (int)
    • success: Execution status (bool)
    • time_cost: Duration in seconds (float)
  • msg: Message containing tool name to retrieve guidelines for
  • Note: Tool Memory does NOT provide tool functions (record_to_memory and retrieve_from_memory). It only provides direct methods for programmatic use.

ReActAgent Integration Modes

When attaching Personal Memory or Task Memory to ReActAgent, use the long_term_memory_mode parameter:

agent = ReActAgent(
    name="Assistant",
    long_term_memory=memory,  # ReMePersonalLongTermMemory or ReMeTaskLongTermMemory
    long_term_memory_mode="both",  # Options: "record", "retrieve", "both"
    # ... other parameters
)

Modes:

  • "record": Only adds record_to_memory tool to agent
  • "retrieve": Only adds retrieve_from_memory tool to agent
  • "both": Adds both tools (recommended for most use cases)

Note: Tool Memory does NOT support ReActAgent integration with tool functions. Use Tool Memory programmatically to enhance system prompts as shown in the Tool Memory example.

Async Context Manager (Required!)

All ReMe memory types must be used with async context managers:

async with long_term_memory:
    # All memory operations must be within this context
    await long_term_memory.record(msgs=[...])
    result = await long_term_memory.retrieve(msg=...)

This ensures:

  • Proper initialization of the ReMe backend
  • Resource cleanup after operations
  • Vector store connection management

Custom Configuration

from agentscope.memory import ReMePersonalLongTermMemory

# Custom storage location and models
memory = ReMePersonalLongTermMemory(
    agent_name="Friday",
    user_name="user_123",
    model=your_custom_model,  # Any AgentScope-compatible LLM
    embedding_model=your_embedding,  # Any AgentScope-compatible embedding model
    vector_store_dir="./custom_path",  # Custom storage directory
)

Example Files Overview

personal_memory_example.py

Demonstrates 5 core interfaces for personal memory:

  1. record_to_memory() - Record user preferences using tool function
  2. retrieve_from_memory() - Search memories by keywords using tool function
  3. record() - Direct recording of message conversations
  4. retrieve() - Direct query-based retrieval
  5. ReActAgent Integration - Agent autonomously uses memory tools

Key Features:

  • Recording travel preferences, work habits, and personal information
  • Keyword-based and query-based retrieval
  • System prompt guidelines for agent memory usage
  • Automatic memory tool calling by ReActAgent

task_memory_example.py

Demonstrates 5 core interfaces for task memory:

  1. record_to_memory() - Record task experiences with scores
  2. retrieve_from_memory() - Retrieve relevant experiences by keywords
  3. record() - Direct recording with trajectory scores
  4. retrieve() - Direct experience retrieval
  5. ReActAgent Integration - Agent learns from past task executions

Key Features:

  • Recording project planning, debugging, and development experiences
  • Score-based trajectory evaluation (0.0-1.0)
  • Learning from successful and failed attempts
  • Continuous improvement through experience retrieval

tool_memory_example.py

Demonstrates the complete workflow for tool memory:

  1. Mock tools - Define and register tools to Toolkit
  2. Record tool history - Store execution results with metadata using record()
  3. Retrieve guidelines - Get summarized usage guidelines using retrieve()
  4. Enhance agent prompt - Inject guidelines into system prompt
  5. Use ReActAgent - Agent uses tools with learned guidelines

Key Features:

  • JSON-formatted tool execution recording via direct record() method
  • Automatic guideline generation through summarization
  • Multi-tool guideline retrieval via direct retrieve() method
  • System prompt enhancement for better tool usage
  • Note: Tool Memory does NOT provide agent-callable tool functions

Architecture

Inheritance Hierarchy

ReMeLongTermMemoryBase (abstract base)
├── ReMePersonalLongTermMemory
├── ReMeTaskLongTermMemory
└── ReMeToolLongTermMemory

ReMeLongTermMemoryBase provides:

  • Integration with ReMe library's ReMeApp
  • Async context manager implementation
  • Common interface definitions
  • Vector store and embedding management

Memory Storage

  • Location: ./memory_vector_store/ (configurable)
  • Isolation: Each user_name maintains separate storage
  • Persistence: Memories persist across sessions
  • Format: Vector embeddings with metadata

Best Practices

1. System Prompt Design

For agents with long-term memory, clearly specify when to record and retrieve:

sys_prompt = """
You are an assistant with long-term memory.

Recording Guidelines:
- Record when users share personal information, preferences, or important facts
- Record successful task execution approaches and solutions
- Record tool execution results with detailed metadata

Retrieval Guidelines:
- ALWAYS retrieve before answering questions about past information
- Retrieve when dealing with similar tasks to past executions
- Check tool guidelines before using tools
"""

2. Score Assignment (Task Memory)

Use meaningful scores to prioritize experiences:

# Successful trajectory
await task_memory.record_to_memory(..., score=0.95)

# Partially successful
await task_memory.record_to_memory(..., score=0.6)

# Failed trajectory (still useful to learn from)
await task_memory.record_to_memory(..., score=0.2)

3. Tool Memory Workflow

Follow this pattern for tool memory:

1. Execute tool → 2. Record result → 3. Trigger summarization → 4. Retrieve guidelines → 5. Use in agent

Troubleshooting

Common Issues

Issue: RuntimeError: Memory not initialized

  • Solution: Always use async with memory: context manager

Issue: No memories retrieved

  • Solution: Ensure you've recorded memories first and check user_name matches

Issue: Tool memory not generating guidelines

  • Solution: Record multiple tool executions to trigger summarization

Issue: Agent not using memory tools

  • Solution: Check long_term_memory_mode="both" and verify system prompt encourages memory usage

References