Documentation Index
Fetch the complete documentation index at: https://mintlify.com/QwenLM/qwen-code/llms.txt
Use this file to discover all available pages before exploring further.
Memory Tool (save_memory)
The memory tool allows Qwen Code to save and recall information across sessions, enabling personalized and context-aware assistance.
Overview
Tool Name: save_memory
Display Name: Memory
Kind: Edit
Description: Saves specific facts or information to long-term memory that persists across sessions.
Parameters
interface SaveMemoryParams {
fact: string; // Required: Fact to remember
scope?: 'global' | 'project'; // Optional: Where to save
}
Usage
Save to Global Memory
save_memory({
fact: 'My preferred programming language is TypeScript',
scope: 'global',
});
Save to Project Memory
save_memory({
fact: 'This project uses Jest for testing',
scope: 'project',
});
Auto-select Scope
// User will be prompted to choose
save_memory({
fact: 'Use tabs for indentation, not spaces',
});
Memory Scopes
Global Memory
Location: ~/.qwen/QWEN.md
Purpose: User-level preferences and information shared across all projects
Use for:
- Personal preferences
- Coding style
- Frequently used patterns
- General instructions
Example:
# ~/.qwen/QWEN.md
## Qwen Added Memories
- My preferred programming language is TypeScript
- I prefer functional programming patterns
- Use JSDoc comments for all public APIs
- My timezone is America/New_York
Project Memory
Location: <project-root>/QWEN.md
Purpose: Project-specific information
Use for:
- Project conventions
- Architecture decisions
- Team preferences
- Build instructions
Example:
# <project>/QWEN.md
## Project Context
This is a web application built with Next.js and TypeScript.
## Qwen Added Memories
- This project uses Jest for testing
- API routes are in pages/api/
- Use Prisma for database operations
- Deploy using Vercel
When to Use save_memory
Good Use Cases
✅ User preferences
save_memory({
fact: 'I prefer React over Vue.js',
scope: 'global',
});
✅ Project conventions
save_memory({
fact: 'All API endpoints must have input validation',
scope: 'project',
});
✅ Important facts
save_memory({
fact: 'The main database is PostgreSQL on port 5432',
scope: 'project',
});
✅ Coding standards
save_memory({
fact: 'Maximum line length is 100 characters',
scope: 'project',
});
When NOT to Use
❌ Conversational context
// This is ephemeral, don't save
save_memory({
fact: 'We discussed the login bug in the last message',
});
❌ Long, complex text
// Too much information
save_memory({
fact: '[Entire file contents or long documentation]',
});
❌ Temporary information
// This will change
save_memory({
fact: 'Currently working on the authentication feature',
});
❌ Uncertain information
// Only save confirmed facts
save_memory({
fact: 'Maybe the API uses REST, not sure',
});
How It Works
Memory Storage
Facts are appended to a markdown file under a special section:
# Context File
## Project Overview
... existing content ...
## Qwen Added Memories
- Fact 1
- Fact 2
- Fact 3
Memory Loading
Memory files are automatically loaded:
- On startup: Contents included in initial context
- Every session: Available to the model
- Project-specific: Project memories only load in that project
- Global always: Global memories load in all projects
Memories are stored as:
- [fact] (added: YYYY-MM-DD HH:mm:ss)
Example:
## Qwen Added Memories
- My preferred programming language is TypeScript (added: 2026-03-10 15:30:45)
- Use tabs for indentation (added: 2026-03-10 15:32:10)
Configuration
Custom Memory Files
Change the memory file name:
{
"context": {
"contextFileNames": [
"QWEN.md",
"PROJECT.md",
"CUSTOM.md"
]
}
}
All specified files will be loaded as context.
Multiple Context Files
You can have multiple context files:
<project>/
├── QWEN.md # Primary context
├── AGENTS.md # Agent configurations
├── CODING_STANDARDS.md # Custom context
└── src/
All are loaded if specified in contextFileNames.
User Interaction
Scope Selection
If scope is not provided, the user is prompted:
Where should this memory be saved?
Fact: "Use TypeScript for all new files"
[G] Global (~/.qwen/QWEN.md)
- Available in all projects
[P] Project (./QWEN.md)
- Only available in this project
[C] Cancel
Choice:
Confirmation
Memory saves show confirmation:
Memory saved to global context:
"Use TypeScript for all new files"
Saved to: ~/.qwen/QWEN.md
Managing Memories
View Memories
Read the memory file:
# Global memories
cat ~/.qwen/QWEN.md
# Project memories
cat QWEN.md
Edit Memories
Manually edit the markdown file:
# Edit global memories
vim ~/.qwen/QWEN.md
# Edit project memories
vim QWEN.md
Remove Memories
Delete specific lines from the file or remove the entire section.
Organize Memories
You can reorganize the file structure:
# QWEN.md
## User Preferences
- Preferred language: TypeScript
- Coding style: Functional
## Project Setup
- Testing framework: Jest
- Database: PostgreSQL
## Qwen Added Memories
- [New memories added here by tool]
Best Practices
1. Be Specific and Clear
✅ Good:
save_memory({
fact: 'Use React Router v6 for navigation',
scope: 'project',
});
❌ Bad:
save_memory({
fact: 'We use routing', // Too vague
});
2. Choose Appropriate Scope
// Personal preference → global
save_memory({
fact: 'I prefer functional components',
scope: 'global',
});
// Project-specific → project
save_memory({
fact: 'API base URL is https://api.example.com',
scope: 'project',
});
3. Keep Facts Concise
✅ Good:
save_memory({
fact: 'Database: PostgreSQL on localhost:5432',
});
❌ Bad:
save_memory({
fact: `The database we're using is PostgreSQL and it's
running on localhost and the port is 5432 and we
connect using username 'admin' and...`, // Too long
});
4. Avoid Duplicates
Check existing memories before adding:
// First, read the memory file
read_file({ absolute_path: '/path/to/QWEN.md' });
// Then save if not duplicate
if (!alreadyStored) {
save_memory({ fact: 'New fact' });
}
5. Update Instead of Add
If information changes, edit the file manually rather than adding a new fact.
Implementation
Location: packages/core/src/tools/memoryTool.ts
export class MemoryTool
extends BaseDeclarativeTool<SaveMemoryParams, ToolResult>
implements ModifiableDeclarativeTool<SaveMemoryParams>
{
static readonly Name = ToolNames.SAVE_MEMORY;
async execute(signal: AbortSignal): Promise<ToolResult> {
const scope = params.scope || await this.promptForScope();
const filePath = getMemoryFilePath(scope);
// Read current content
const currentContent = await readMemoryFileContent(filePath);
// Append new memory
const timestamp = new Date().toISOString();
const memoryEntry = `- ${params.fact} (added: ${timestamp})\n`;
const newContent = appendToMemorySection(
currentContent,
memoryEntry,
);
// Write updated content
await fs.writeFile(filePath, newContent, 'utf-8');
return {
llmContent: `Saved memory to ${scope} context: "${params.fact}"`,
returnDisplay: `Memory saved to ${filePath}`,
};
}
}
Memory File Functions
// Get path for scope
function getMemoryFilePath(scope: 'global' | 'project'): string {
if (scope === 'global') {
return path.join(Storage.getGlobalQwenDir(), 'QWEN.md');
}
return path.join(process.cwd(), 'QWEN.md');
}
// Append to memory section
function appendToMemorySection(
content: string,
memoryEntry: string,
): string {
const sectionHeader = '## Qwen Added Memories';
if (content.includes(sectionHeader)) {
// Append to existing section
return content.replace(
sectionHeader,
`${sectionHeader}\n\n${memoryEntry}`,
);
} else {
// Create new section
return `${content}\n\n${sectionHeader}\n\n${memoryEntry}`;
}
}
Security
No Sensitive Data
⚠️ Warning: Don’t save sensitive information:
// ❌ DON'T save secrets
save_memory({
fact: 'API key: sk-abc123xyz789', // NEVER do this
});
// ❌ DON'T save passwords
save_memory({
fact: 'Database password: mypassword', // NEVER do this
});
Memory files are plain text and may be committed to version control.
.gitignore
Consider ignoring memory files:
# .gitignore
QWEN.md
.qwen/QWEN.md
Or commit them if they only contain non-sensitive project information.
Troubleshooting
Memory Not Loaded
Problem: Saved memory doesn’t appear in context
Solutions:
- Restart Qwen Code
- Check file location:
ls ~/.qwen/QWEN.md
ls ./QWEN.md
- Verify
contextFileNames setting
- Check file permissions
Wrong Scope
Problem: Saved to wrong scope
Solution: Manually move the fact between files:
# Move from global to project
grep "fact text" ~/.qwen/QWEN.md
# Copy the line
vim QWEN.md
# Paste it
# Remove from global file
vim ~/.qwen/QWEN.md
Duplicate Memories
Problem: Same fact saved multiple times
Solution: Edit the file and remove duplicates:
vim ~/.qwen/QWEN.md
# Delete duplicate lines
Examples
Development Preferences
// Code style
save_memory({
fact: 'Use async/await instead of .then() chains',
scope: 'global',
});
// Testing preference
save_memory({
fact: 'Write tests using describe/it pattern',
scope: 'global',
});
// Documentation
save_memory({
fact: 'Add JSDoc comments to all exported functions',
scope: 'global',
});
Project Setup
// Environment
save_memory({
fact: 'Development server runs on port 3000',
scope: 'project',
});
// Build process
save_memory({
fact: 'Run npm run build before deploying',
scope: 'project',
});
// Dependencies
save_memory({
fact: 'Use npm, not yarn, for this project',
scope: 'project',
});
Architectural Decisions
// Design patterns
save_memory({
fact: 'Use Repository pattern for data access',
scope: 'project',
});
// Structure
save_memory({
fact: 'Feature-based folder structure under src/features',
scope: 'project',
});
// Conventions
save_memory({
fact: 'Name test files as *.test.ts, not *.spec.ts',
scope: 'project',
});
Next Steps