chore: initialize sandbox and overwrite remote content
Some checks failed
Pre-commit / run (ubuntu-latest) (push) Has been cancelled
Deploy Sphinx documentation to Pages / build_en (ubuntu-latest, 3.10) (push) Has been cancelled
Deploy Sphinx documentation to Pages / build_zh (ubuntu-latest, 3.10) (push) Has been cancelled
Python Unittest Coverage / test (macos-15, 3.10) (push) Has been cancelled
Python Unittest Coverage / test (macos-15, 3.11) (push) Has been cancelled
Python Unittest Coverage / test (macos-15, 3.12) (push) Has been cancelled
Python Unittest Coverage / test (ubuntu-latest, 3.10) (push) Has been cancelled
Python Unittest Coverage / test (ubuntu-latest, 3.11) (push) Has been cancelled
Python Unittest Coverage / test (ubuntu-latest, 3.12) (push) Has been cancelled
Python Unittest Coverage / test (windows-latest, 3.10) (push) Has been cancelled
Python Unittest Coverage / test (windows-latest, 3.11) (push) Has been cancelled
Python Unittest Coverage / test (windows-latest, 3.12) (push) Has been cancelled

This commit is contained in:
codex-bot
2026-03-02 22:32:27 +08:00
commit a64378956a
584 changed files with 93604 additions and 0 deletions

View File

@@ -0,0 +1,609 @@
# 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
```bash
# 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:
```bash
export DASHSCOPE_API_KEY='YOUR_API_KEY'
```
Or create a `.env` file:
```bash
DASHSCOPE_API_KEY=YOUR_API_KEY
```
### Run Examples
```bash
# 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.
```python
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):
```python
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.
```python
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):
```python
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**:
```python
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:
```python
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:
```python
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:
```python
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
```python
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:
```python
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:
```python
# 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
- [ReMe Library](https://github.com/modelscope/ReMe) - Core memory implementation
- [AgentScope Documentation](https://github.com/modelscope/agentscope) - Framework documentation
- [DashScope API](https://dashscope.aliyun.com/) - Model API for examples

View File

@@ -0,0 +1,295 @@
# -*- coding: utf-8 -*-
"""Personal memory example demonstrating ReMe personal memory.
This module provides examples of how to use the ReMePersonalMemory
class.
The example demonstrates 5 core interfaces:
1. record_to_memory - Tool function for explicit memory recording
2. retrieve_from_memory - Tool function for keyword-based retrieval
3. record - Direct method for recording message conversations
4. retrieve - Direct method for query-based retrieval
5. ReActAgent integration - Using personal memory with ReActAgent
"""
import asyncio
import os
from dotenv import load_dotenv
from agentscope.agent import ReActAgent
from agentscope.embedding import DashScopeTextEmbedding
from agentscope.formatter import DashScopeChatFormatter
from agentscope.memory import InMemoryMemory
from agentscope.memory import ReMePersonalLongTermMemory
from agentscope.message import Msg
from agentscope.model import DashScopeChatModel
from agentscope.tool import ToolResponse, Toolkit
load_dotenv()
async def test_record_to_memory(
memory: ReMePersonalLongTermMemory,
) -> None:
"""Test the record_to_memory tool function interface."""
print("Interface 1: record_to_memory (Tool Function)")
print("-" * 70)
print("Purpose: Explicit memory recording with structured content")
print("Test case: Recording user's travel preferences...")
result: ToolResponse = await memory.record_to_memory(
thinking=("The user is sharing their travel preferences and habits"),
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",
],
)
result_text = " ".join(
block.get("text", "")
for block in result.content
if block.get("type") == "text"
)
print(f"✓ Result: {result_text}")
print(
f"✓ Status: {'Success' if 'Success' in result_text else 'Failed'}",
)
print()
async def test_retrieve_from_memory(
memory: ReMePersonalLongTermMemory,
) -> None:
"""Test the retrieve_from_memory tool function interface."""
print("Interface 2: retrieve_from_memory (Tool Function)")
print("-" * 70)
print("Purpose: Keyword-based memory retrieval")
print()
result = await memory.retrieve_from_memory(
keywords=["Hangzhou travel", "tea preference"],
)
retrieved_text = " ".join(
block.get("text", "")
for block in result.content
if block.get("type") == "text"
)
print("✓ Retrieved memories:")
print(f"{retrieved_text}")
print()
async def test_record_direct(memory: ReMePersonalLongTermMemory) -> None:
"""Test the direct record method interface."""
print("Interface 3: record (Direct Recording)")
print("-" * 70)
print("Purpose: Direct recording of message conversations")
print()
print("Test case: Recording work preferences and habits...")
try:
await memory.record(
msgs=[
Msg(
role="user",
content=(
"I work as a software engineer and prefer "
"remote work"
),
name="user",
),
Msg(
role="assistant",
content=(
"Understood! You're a software engineer who "
"values remote work flexibility."
),
name="assistant",
),
Msg(
role="user",
content=(
"I usually start my day at 9 AM with a "
"cup of coffee"
),
name="user",
),
],
)
print("✓ Status: Successfully recorded conversation messages")
print(
"✓ Messages recorded: 3 messages (user-assistant dialogue)",
)
except Exception as e:
print(f"✗ Status: Failed - {str(e)}")
print()
async def test_retrieve_direct(memory: ReMePersonalLongTermMemory) -> None:
"""Test the direct retrieve method interface."""
print("Interface 4: retrieve (Direct Retrieval)")
print("-" * 70)
print("Purpose: Query-based memory retrieval using messages")
print()
print(
"Test case: Querying 'What do you know about my "
"work preferences?'...",
)
memories = await memory.retrieve(
msg=Msg(
role="user",
content="What do you know about my work preferences?",
name="user",
),
)
print("✓ Retrieved memories:")
print(f"{memories if memories else 'No memories found'}")
status = (
"Success - Found memories"
if memories
else "No relevant memories found"
)
print(f"✓ Status: {status}")
print()
async def test_react_agent_with_memory(
memory: ReMePersonalLongTermMemory,
) -> None:
"""Test ReActAgent integration with personal memory."""
print("Interface 5: ReActAgent with Personal Memory")
print("-" * 70)
print(
"Purpose: Demonstrate how ReActAgent uses personal memory tools",
)
print()
print("Test case: Agent-driven memory recording and retrieval...")
toolkit = Toolkit()
agent = ReActAgent(
name="Friday",
sys_prompt=(
"You are a helpful assistant named Friday with long-term "
"memory capabilities. "
"\n\n## Memory Management Guidelines:\n"
"1. **Recording Memories**: When users share personal "
"information, preferences, "
"habits, or facts about themselves, ALWAYS record them "
"using `record_to_memory` "
"for future reference.\n"
"\n2. **Retrieving Memories**: BEFORE answering questions "
"about the user's preferences, "
"past information, or personal details, you MUST FIRST "
"call `retrieve_from_memory` "
"to check if you have any relevant stored information. "
"Do NOT rely solely on the "
"current conversation context.\n"
"\n3. **When to Retrieve**: Call `retrieve_from_memory` "
"when:\n"
" - User asks questions like 'what do I like?', "
"'what are my preferences?', "
"'what do you know about me?'\n"
" - User asks about their past behaviors, habits, or "
"preferences\n"
" - User refers to information they mentioned before\n"
" - You need context about the user to provide "
"personalized responses\n"
"\nAlways check your memory first before claiming you "
"don't know something about the user."
),
model=DashScopeChatModel(
model_name="qwen3-max",
api_key=os.environ.get("DASHSCOPE_API_KEY"),
stream=False,
),
formatter=DashScopeChatFormatter(),
toolkit=toolkit,
memory=InMemoryMemory(),
long_term_memory=memory,
long_term_memory_mode="both",
)
await agent.memory.clear()
print(
"→ User: 'When I travel to Hangzhou, I prefer to stay in "
"a homestay'",
)
msg = Msg(
role="user",
content=(
"When I travel to Hangzhou, I prefer to stay in " "a homestay"
),
name="user",
)
msg = await agent(msg)
print(f"✓ Agent response: {msg.get_text_content()}\n")
print("→ User: 'what preference do I have?'")
msg = Msg(
role="user",
content="what preference do I have?",
name="user",
)
msg = await agent(msg)
print(f"✓ Agent response: {msg.get_text_content()}\n")
print(
"✓ Status: Successfully demonstrated ReActAgent with "
"personal memory",
)
print()
async def main() -> None:
"""Demonstrate the 5 core interfaces of ReMePersonalMemory.
This example shows how to use:
1. record_to_memory - Tool function for explicit memory recording
2. retrieve_from_memory - Tool function for keyword-based retrieval
3. record - Direct method for recording message conversations
4. retrieve - Direct method for query-based retrieval
5. ReActAgent integration - Using personal memory with ReActAgent
"""
long_term_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,
),
)
print("=" * 70)
print("ReMePersonalMemory - Testing 5 Core Interfaces")
print("=" * 70)
print()
# Use async context manager to ensure proper initialization
async with long_term_memory:
# await test_record_to_memory(long_term_memory)
# await test_retrieve_from_memory(long_term_memory)
# await test_record_direct(long_term_memory)
# await test_retrieve_direct(long_term_memory)
await test_react_agent_with_memory(long_term_memory)
# Alternative way: manually call __aenter__ and __aexit__
# This is equivalent to using "async with long_term_memory" above
# await long_term_memory.__aenter__()
# await test_react_agent_with_memory(long_term_memory)
# await long_term_memory.__aexit__()
print("=" * 70)
print("Testing Complete: All 5 Core Interfaces Verified!")
print("=" * 70)
if __name__ == "__main__":
asyncio.run(main())

View File

@@ -0,0 +1,342 @@
# -*- coding: utf-8 -*-
"""Task memory example demonstrating ReMe task memory.
This module provides examples of how to use the ReMeTaskMemory class
using the ReMe library.
The example demonstrates 5 core interfaces:
1. record_to_memory - Tool function for recording task information
2. retrieve_from_memory - Tool function for keyword-based retrieval
3. record - Direct method for recording message conversations
with scores
4. retrieve - Direct method for retrieving task experiences
5. ReActAgent integration - Using task memory with ReActAgent
"""
import asyncio
import os
from dotenv import load_dotenv
from agentscope.agent import ReActAgent
from agentscope.embedding import DashScopeTextEmbedding
from agentscope.formatter import DashScopeChatFormatter
from agentscope.memory import InMemoryMemory
from agentscope.memory import ReMeTaskLongTermMemory
from agentscope.message import Msg
from agentscope.model import DashScopeChatModel
from agentscope.tool import ToolResponse, Toolkit
load_dotenv()
async def test_record_to_memory(memory: ReMeTaskLongTermMemory) -> None:
"""Test the record_to_memory tool function interface."""
print("Interface 1: record_to_memory (Tool Function)")
print("-" * 70)
print(
"Purpose: Record task execution information with thinking and content",
)
print()
print("Test case: Recording project planning task information...")
result: ToolResponse = await memory.record_to_memory(
thinking=(
"Recording project planning best practices and "
"development approach"
),
content=[
"For web application projects, break down into phases: "
"Requirements gathering, Design, Development, Testing, "
"Deployment",
"Development phase recommendations: Frontend (React), "
"Backend (FastAPI), Database (PostgreSQL), Agile "
"methodology with 2-week sprints",
"Dependency management: Use npm for frontend and pip for "
"Python backend, maintain requirements.txt and "
"package.json files",
],
score=0.9, # Optional: score for this trajectory (1.0)
)
result_text = " ".join(
block.get("text", "")
for block in result.content
if block.get("type") == "text"
)
print(f"✓ Result: {result_text}")
print(
f"✓ Status: {'Success' if 'Success' in result_text else 'Failed'}",
)
print()
async def test_retrieve_from_memory(
memory: ReMeTaskLongTermMemory,
) -> None:
"""Test the retrieve_from_memory tool function interface."""
print("Interface 2: retrieve_from_memory (Tool Function)")
print("-" * 70)
print("Purpose: Keyword-based retrieval of task experiences")
print()
print(
"Test case: Searching with keywords 'project planning', "
"'development phase'...",
)
result = await memory.retrieve_from_memory(
keywords=["project planning", "development phase"],
)
retrieved_text = " ".join(
block.get("text", "")
for block in result.content
if block.get("type") == "text"
)
print("✓ Retrieved experiences:")
print(f"{retrieved_text}")
has_experiences = (
retrieved_text and "No task experiences found" not in retrieved_text
)
status = (
"Success - Found experiences"
if has_experiences
else "No relevant experiences found"
)
print(f"✓ Status: {status}")
print()
async def test_record_direct(memory: ReMeTaskLongTermMemory) -> None:
"""Test the direct record method interface."""
print("Interface 3: record (Direct Recording)")
print("-" * 70)
print("Purpose: Direct recording of message conversations with scores")
print()
print("Test case: Recording debugging task conversation...")
try:
await memory.record(
msgs=[
Msg(
role="user",
content="I'm getting a 404 error on my API endpoint",
name="user",
),
Msg(
role="assistant",
content=(
"Let's troubleshoot: 1) Check if the route is "
"properly defined, 2) Verify the URL path, "
"3) Ensure the server is running on the correct "
"port"
),
name="assistant",
),
Msg(
role="user",
content="Found it! The route path had a typo.",
name="user",
),
Msg(
role="assistant",
content=(
"Great! Always double-check route paths and use "
"a linter to catch typos early."
),
name="assistant",
),
],
score=0.95, # Optional: score (default: 1.0)
)
print("✓ Status: Successfully recorded debugging trajectory")
print("✓ Messages recorded: 4 messages with score 0.95")
except Exception as e:
print(f"✗ Status: Failed - {str(e)}")
print()
async def test_retrieve_direct(memory: ReMeTaskLongTermMemory) -> None:
"""Test the direct retrieve method interface."""
print("Interface 4: retrieve (Direct Retrieval)")
print("-" * 70)
print("Purpose: Query-based retrieval using messages")
print()
print("Test case: Querying 'How to debug API errors?'...")
memories = await memory.retrieve(
msg=Msg(
role="user",
content=(
"How should I approach debugging API errors in my "
"application?"
),
name="user",
),
)
print("✓ Retrieved experiences:")
print(f"{memories if memories else 'No experiences found'}")
status = (
"Success - Found experiences"
if memories
else "No relevant experiences found"
)
print(f"✓ Status: {status}")
print()
async def test_react_agent_with_memory(
memory: ReMeTaskLongTermMemory,
) -> None:
"""Test ReActAgent integration with task memory."""
print("Interface 5: ReActAgent with Task Memory")
print("-" * 70)
print(
"Purpose: Demonstrate how ReActAgent uses task memory tools",
)
print()
print(
"Test case: Agent-driven task experience recording and "
"retrieval...",
)
toolkit = Toolkit()
agent = ReActAgent(
name="TaskAssistant",
sys_prompt=(
"You are a helpful task assistant named TaskAssistant "
"with long-term task memory. "
"\n\n## Task Memory Management Guidelines:\n"
"1. **Recording Task Experiences**: When you provide "
"technical solutions, solve problems, "
"or complete tasks, ALWAYS record the key insights using "
"`record_to_memory`. Include:\n"
" - Specific techniques and approaches used\n"
" - Best practices and implementation details\n"
" - Lessons learned and important considerations\n"
" - Step-by-step procedures that worked well\n"
"\n2. **Retrieving Past Experiences**: BEFORE solving a "
"problem or answering technical "
"questions, you MUST FIRST call `retrieve_from_memory` "
"to check if you have relevant "
"past experiences. This helps you:\n"
" - Avoid repeating past mistakes\n"
" - Leverage proven solutions\n"
" - Provide more accurate and tested approaches\n"
"\n3. **When to Retrieve**: Always retrieve when:\n"
" - Asked about technical topics or problem-solving "
"approaches\n"
" - Asked to provide recommendations or best practices\n"
" - Dealing with tasks similar to ones you may have "
"handled before\n"
" - User explicitly asks 'what do you know about...?' "
"or 'have you seen this before?'\n"
"\nAlways check your task memory first to provide the "
"most informed responses."
),
model=DashScopeChatModel(
model_name="qwen3-max",
api_key=os.environ.get("DASHSCOPE_API_KEY"),
stream=False,
),
formatter=DashScopeChatFormatter(),
toolkit=toolkit,
memory=InMemoryMemory(),
long_term_memory=memory,
long_term_memory_mode="both",
)
await agent.memory.clear()
print(
"→ User: 'Here are some database optimization techniques "
"I learned'",
)
msg = Msg(
role="user",
content=(
"I just learned some valuable database optimization "
"techniques for slow queries: "
"1) Add indexes on foreign keys and WHERE clause columns "
"to speed up joins and filtering. "
"2) Use table partitioning to divide large tables by "
"date or category for faster queries. "
"3) Implement query result caching with Redis to avoid "
"repeated database hits. "
"4) Optimize JOIN order - put smallest tables first to "
"reduce intermediate result sets. "
"5) Use EXPLAIN ANALYZE to identify bottlenecks and "
"missing indexes. "
"Please record these optimization techniques for future "
"reference."
),
name="user",
)
msg = await agent(msg)
print(f"✓ Agent response: {msg.get_text_content()}\n")
print(
"→ User: 'What do you know about database optimization?'",
)
msg = Msg(
role="user",
content=(
"What do you know about database optimization? "
"Can you retrieve any past experiences?"
),
name="user",
)
msg = await agent(msg)
print(f"✓ Agent response: {msg.get_text_content()}\n")
print()
async def main() -> None:
"""Demonstrate the 5 core interfaces of ReMeTaskMemory.
This example shows how to use:
1. record_to_memory - Tool function for recording task information
2. retrieve_from_memory - Tool function for keyword-based retrieval
3. record - Direct method for recording message conversations with scores
4. retrieve - Direct method for retrieving task experiences
5. ReActAgent integration - Using task memory with ReActAgent
"""
long_term_memory = ReMeTaskLongTermMemory(
agent_name="TaskAssistant",
user_name="task_workspace_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,
),
)
print("=" * 70)
print("ReMeTaskMemory - Testing 5 Core Interfaces")
print("=" * 70)
print()
# Use async context manager to ensure proper initialization
async with long_term_memory:
# await test_record_to_memory(long_term_memory)
# await test_retrieve_from_memory(long_term_memory)
# await test_record_direct(long_term_memory)
# await test_retrieve_direct(long_term_memory)
await test_react_agent_with_memory(long_term_memory)
# Alternative way: manually call __aenter__ and __aexit__
# This is equivalent to using "async with long_term_memory" above
# await long_term_memory.__aenter__()
# await test_react_agent_with_memory(long_term_memory)
# await long_term_memory.__aexit__()
print("=" * 70)
print("Testing Complete: All 5 Core Interfaces Verified!")
print("=" * 70)
if __name__ == "__main__":
asyncio.run(main())

View File

@@ -0,0 +1,436 @@
# -*- coding: utf-8 -*-
"""Tool memory example demonstrating ReMe tool memory with ReActAgent.
This module demonstrates the complete workflow:
1. Mock a tool function and register it to Toolkit
2. Record tool execution results to tool memory using record()
3. Retrieve tool usage guidelines using retrieve()
4. Inject guidelines into ReActAgent's system prompt
5. Use ReActAgent with tool memory
This workflow helps LLMs learn from past tool usage patterns and
improve their tool calling decisions over time.
"""
import asyncio
import json
import os
from datetime import datetime
from dotenv import load_dotenv
from agentscope.agent import ReActAgent
from agentscope.embedding import DashScopeTextEmbedding
from agentscope.formatter import DashScopeChatFormatter
from agentscope.memory import InMemoryMemory
from agentscope.memory import ReMeToolLongTermMemory
from agentscope.message import Msg
from agentscope.message import TextBlock
from agentscope.model import DashScopeChatModel
from agentscope.tool import Toolkit, ToolResponse
load_dotenv()
# ============================================================================
# Step 1: Mock tool functions
# ============================================================================
async def web_search(query: str, max_results: int = 5) -> ToolResponse:
"""Search the web for information.
Args:
query: The search query string
max_results: Maximum number of results to return
Returns:
ToolResponse containing search results
"""
# Simulate web search
result = f"Found {max_results} results for query: '{query}'"
return ToolResponse(
content=[
TextBlock(
type="text",
text=result,
),
],
)
async def calculate(expression: str) -> ToolResponse:
"""Calculate a mathematical expression.
Args:
expression: Mathematical expression to evaluate
Returns:
ToolResponse containing calculation result
"""
try:
# Simple calculation (in real scenario, use safer evaluation)
result = eval(expression) # noqa: S307
return ToolResponse(
content=[
TextBlock(
type="text",
text=f"Result: {result}",
),
],
)
except Exception as e:
return ToolResponse(
content=[
TextBlock(
type="text",
text=f"Error calculating '{expression}': {str(e)}",
),
],
)
# ============================================================================
# Step 2: Record tool execution history to tool memory
# ============================================================================
async def record_tool_history(
tool_memory: ReMeToolLongTermMemory,
) -> None:
"""Record historical tool execution results to tool memory.
This simulates past tool usage that the agent can learn from.
"""
print("=" * 70)
print("Step 1: Recording Tool Execution History to Memory")
print("=" * 70)
print()
# Record successful web_search examples
web_search_histories = [
{
"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,
},
{
"create_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"tool_name": "web_search",
"input": {
"query": "machine learning basics",
"max_results": 5,
},
"output": ("Found 5 results for query: 'machine learning basics'"),
"token_cost": 120,
"success": True,
"time_cost": 1.8,
},
]
# Record failed web_search example (empty query)
web_search_fail = {
"create_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"tool_name": "web_search",
"input": {
"query": "",
"max_results": 5,
},
"output": "Error: Query cannot be empty",
"token_cost": 20,
"success": False,
"time_cost": 0.1,
}
# Record calculate examples
calculate_histories = [
{
"create_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"tool_name": "calculate",
"input": {
"expression": "2 + 2",
},
"output": "Result: 4",
"token_cost": 30,
"success": True,
"time_cost": 0.05,
},
{
"create_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"tool_name": "calculate",
"input": {
"expression": "10 * 5 + 3",
},
"output": "Result: 53",
"token_cost": 30,
"success": True,
"time_cost": 0.05,
},
]
# Record all histories
all_histories = (
web_search_histories + [web_search_fail] + calculate_histories
)
print(f"Recording {len(all_histories)} tool execution histories...")
await tool_memory.record(
msgs=[
Msg(
role="assistant",
content=json.dumps(history),
name="assistant",
)
for history in all_histories
],
)
print(f"✓ Successfully recorded {len(all_histories)} tool executions")
print()
# ============================================================================
# Step 3: Retrieve tool guidelines and create enhanced system prompt
# ============================================================================
async def retrieve_tool_guidelines(
tool_memory: ReMeToolLongTermMemory,
tool_names: list[str],
) -> str:
"""Retrieve tool usage guidelines from memory.
Args:
tool_memory: The ReMeToolMemory instance
tool_names: List of tool names to retrieve guidelines for
Returns:
Combined guidelines text to be added to system prompt
"""
print("=" * 70)
print("Step 2: Retrieving Tool Usage Guidelines from Memory")
print("=" * 70)
print()
all_guidelines = []
for tool_name in tool_names:
print(f"Retrieving guidelines for '{tool_name}'...")
guidelines = await tool_memory.retrieve(
msg=Msg(
role="user",
content=tool_name,
name="user",
),
)
if guidelines:
all_guidelines.append(
f"## Guidelines for {tool_name}:\n{guidelines}",
)
print(f"✓ Retrieved guidelines for '{tool_name}'")
print(f" Preview: {guidelines}")
else:
print(
f"✓ No guidelines found for '{tool_name}' " "(first time use)",
)
print()
if all_guidelines:
combined_guidelines = "\n\n".join(all_guidelines)
guidelines_prompt = f"""
# Tool Usage Guidelines (from past experience)
{combined_guidelines}
Please follow these guidelines when using the tools.
"""
return guidelines_prompt
else:
return ""
# ============================================================================
# Step 4: Use ReActAgent with tool memory
# ============================================================================
async def use_react_agent_with_tool_memory(
toolkit: Toolkit,
tool_guidelines: str,
) -> None:
"""Create and use ReActAgent with tool memory guidelines.
Args:
toolkit: The Toolkit with registered tools
tool_guidelines: Retrieved tool usage guidelines
"""
print("=" * 70)
print("Step 3: Using ReActAgent with Tool Memory")
print("=" * 70)
print()
# Create enhanced system prompt with tool guidelines
base_sys_prompt = (
"You are a helpful AI assistant named ToolBot.\n"
"You have access to various tools to help users complete "
"their tasks.\n"
"Please use the tools appropriately based on the user's "
"requests."
)
if tool_guidelines:
sys_prompt = f"{base_sys_prompt}\n{tool_guidelines}"
print(
"✓ System prompt enhanced with tool memory guidelines",
)
else:
sys_prompt = base_sys_prompt
print(
"✓ Using base system prompt (no guidelines available)",
)
print()
# Create ReActAgent
agent = ReActAgent(
name="ToolBot",
sys_prompt=sys_prompt,
model=DashScopeChatModel(
model_name="qwen-max",
api_key=os.environ.get("DASHSCOPE_API_KEY"),
stream=False,
),
formatter=DashScopeChatFormatter(),
toolkit=toolkit,
memory=InMemoryMemory(),
max_iters=5,
)
print("✓ ReActAgent created successfully")
print()
# Test queries
test_queries = [
"Search the web for 'Python design patterns'",
"Calculate 15 * 7 + 23",
]
print("-" * 70)
print("Testing ReActAgent with tool memory...")
print("-" * 70)
print()
for i, query in enumerate(test_queries, 1):
print(f"Query {i}: {query}")
print("-" * 70)
msg = Msg(
role="user",
content=query,
name="user",
)
response = await agent(msg)
print(f"Response: {response.get_text_content()}")
print()
print()
async def main() -> None:
"""Demonstrate the workflow of using ReMeToolMemory with ReActAgent.
This example shows:
1. Create mock tools and register them to Toolkit
2. Record historical tool execution results to tool memory
3. Retrieve tool usage guidelines from memory
4. Inject guidelines into ReActAgent's system prompt
5. Use ReActAgent to complete tasks with tool memory
"""
print("=" * 70)
print("ReMeToolMemory + ReActAgent Integration Example")
print("=" * 70)
print()
print("This workflow demonstrates:")
print("1. Mock tools → Register to Toolkit")
print("2. Record tool execution history → Tool Memory")
print("3. Retrieve guidelines → Enhance system prompt")
print("4. Use ReActAgent with tool memory")
print()
# Initialize tool memory
tool_memory = ReMeToolLongTermMemory(
agent_name="ToolBot",
user_name="tool_workspace_demo",
model=DashScopeChatModel(
model_name="qwen-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,
),
)
# Create and register tools to toolkit
toolkit = Toolkit()
toolkit.register_tool_function(web_search)
toolkit.register_tool_function(calculate)
print()
# Use async context manager for tool memory
async with tool_memory:
# Step 1: Record historical tool executions to memory
await record_tool_history(tool_memory)
# Step 2: Retrieve tool usage guidelines
tool_names = ["web_search", "calculate"]
tool_guidelines = await retrieve_tool_guidelines(
tool_memory,
tool_names,
)
# Step 3: Use ReActAgent with enhanced system prompt
await use_react_agent_with_tool_memory(
toolkit,
tool_guidelines,
)
# Alternative way: manually call __aenter__ and __aexit__
# This is equivalent to using "async with tool_memory" above
# await tool_memory.__aenter__()
# tool_guidelines = await retrieve_tool_guidelines(tool_memory, tool_names)
# await tool_memory.__aexit__()
print("=" * 70)
print("Workflow Complete!")
print("=" * 70)
print()
print("Summary:")
print("✓ Mock tools created and registered to Toolkit")
print("✓ Historical tool executions recorded to tool memory")
print("✓ Tool usage guidelines retrieved from memory")
print("✓ ReActAgent system prompt enhanced with guidelines")
print(
"✓ ReActAgent successfully used tools with memory guidance",
)
print()
print("Benefits:")
print("- Agent learns from past tool usage patterns")
print("- Reduced errors by following proven guidelines")
print("- Better tool parameter selection")
print("- Improved success rate over time")
print("=" * 70)
if __name__ == "__main__":
asyncio.run(main())