Introduction
In this tutorial, you'll learn how to build a simplified version of Google Cloud's Always-On Memory Agent using Gemini 3.1 Flash-Lite. Unlike traditional Retrieval-Augmented Generation (RAG) systems that rely on vector databases and embeddings, this approach treats memory as a continuous process, storing structured data in SQLite and using an orchestrator to manage ingestion, consolidation, and querying. This approach enables real-time memory management without the overhead of external vector databases.
This tutorial assumes you have basic familiarity with Python, LLMs, and database operations. You'll create a working prototype that demonstrates the core concepts behind the Always-On Memory Agent, including structured memory management, continuous consolidation, and query routing.
Prerequisites
- Python 3.8 or higher installed
- Google Cloud account with access to Gemini 3.1 Flash-Lite
- Basic understanding of SQLite and database operations
- Basic knowledge of LLM concepts and API usage
- Installed Python packages:
google-generativeai,sqlite3,json,datetime
Step-by-Step Instructions
1. Set Up Your Development Environment
First, ensure you have the required Python packages installed. Create a new virtual environment and install the necessary dependencies:
python -m venv memory_agent_env
source memory_agent_env/bin/activate # On Windows: memory_agent_env\Scripts\activate
pip install google-generativeai
This creates an isolated environment for our project, ensuring no conflicts with existing packages.
2. Initialize Google Generative AI Client
Next, set up your Gemini client with your API key:
import google.generativeai as genai
import os
# Set your API key
os.environ['GOOGLE_API_KEY'] = 'your-api-key-here'
# Initialize the model
genai.configure(api_key=os.environ['GOOGLE_API_KEY'])
model = genai.GenerativeModel('gemini-3.1-flash-lite')
This initializes the connection to Gemini 3.1 Flash-Lite, which will be used for all LLM operations in our memory agent.
3. Create the Memory Database Structure
Now, create the SQLite database schema to store structured memory:
import sqlite3
def init_memory_db():
conn = sqlite3.connect('memory_agent.db')
cursor = conn.cursor()
# Create memory table
cursor.execute('''
CREATE TABLE IF NOT EXISTS memory (
id INTEGER PRIMARY KEY AUTOINCREMENT,
content TEXT NOT NULL,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
category TEXT,
source TEXT
)
''')
# Create consolidated memory table
cursor.execute('''
CREATE TABLE IF NOT EXISTS consolidated_memory (
id INTEGER PRIMARY KEY AUTOINCREMENT,
summary TEXT NOT NULL,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
category TEXT
)
''')
conn.commit()
conn.close()
init_memory_db()
This creates two tables: one for raw memory entries and another for consolidated knowledge, mimicking how the Always-On Memory Agent structures its data.
4. Implement the Ingest Agent
The Ingest Agent receives new information and stores it in the database:
def ingest_memory(content, category, source):
conn = sqlite3.connect('memory_agent.db')
cursor = conn.cursor()
cursor.execute('''
INSERT INTO memory (content, category, source)
VALUES (?, ?, ?)
''', (content, category, source))
conn.commit()
conn.close()
print(f'Memory ingested: {content[:50]}...')
# Example usage
ingest_memory("The weather today is sunny and warm.", "weather", "user_input")
This function stores raw memory entries with metadata, allowing for future consolidation and retrieval.
5. Implement the Consolidate Agent
The Consolidate Agent processes raw memory entries and creates summaries:
def consolidate_memory():
conn = sqlite3.connect('memory_agent.db')
cursor = conn.cursor()
# Retrieve recent memory entries
cursor.execute('''
SELECT content, category FROM memory
WHERE timestamp > datetime('now', '-1 day')
''')
entries = cursor.fetchall()
if not entries:
print('No recent entries to consolidate')
return
# Prepare prompt for LLM
prompt = f"Summarize the following information in one sentence: {', '.join([entry[0] for entry in entries])}"
# Use Gemini to generate summary
response = model.generate_content(prompt)
summary = response.text
# Store consolidated memory
cursor.execute('''
INSERT INTO consolidated_memory (summary, category)
VALUES (?, ?)
''', (summary, entries[0][1] if entries else 'general'))
conn.commit()
conn.close()
print(f'Consolidated memory: {summary}')
# Example usage
consolidate_memory()
This agent processes recent memory entries and creates structured summaries, reducing the need for vector embeddings by using LLMs for content synthesis.
6. Implement the Query Agent
The Query Agent retrieves information from both raw and consolidated memory:
def query_memory(query):
conn = sqlite3.connect('memory_agent.db')
cursor = conn.cursor()
# Search in consolidated memory first
cursor.execute('''
SELECT summary FROM consolidated_memory
WHERE summary LIKE ?
ORDER BY timestamp DESC
''', (f'%{query}%',))
results = cursor.fetchall()
if not results:
# Fallback to raw memory
cursor.execute('''
SELECT content FROM memory
WHERE content LIKE ?
ORDER BY timestamp DESC
''', (f'%{query}%',))
results = cursor.fetchall()
conn.close()
return [result[0] for result in results]
# Example usage
results = query_memory('weather')
print('Query results:', results)
This agent provides a unified interface for querying both raw and consolidated memory, demonstrating how the orchestrator routes queries appropriately.
7. Create the Orchestrator
Finally, create the orchestrator that coordinates between all agents:
class MemoryOrchestrator:
def __init__(self):
self.model = model
def process_input(self, user_input):
# Ingest the input
ingest_memory(user_input, 'user_input', 'user')
# Consolidate memory
consolidate_memory()
# Query for response
query_results = query_memory(user_input)
# Generate response using LLM
if query_results:
prompt = f"Based on the following information: {', '.join(query_results)}, respond to: {user_input}"
response = self.model.generate_content(prompt)
return response.text
return "I don't have specific information about that."
# Example usage
orchestrator = MemoryOrchestrator()
response = orchestrator.process_input("Tell me about today's weather")
print(response)
The orchestrator demonstrates how the three agents work together in a continuous loop, managing memory from ingestion to query.
Summary
In this tutorial, you've built a simplified version of Google Cloud's Always-On Memory Agent using Gemini 3.1 Flash-Lite. You've learned how to:
- Set up a memory database using SQLite
- Implement ingestion, consolidation, and querying agents
- Use LLMs for content summarization and response generation
- Create an orchestrator that coordinates all agents
This approach eliminates the need for vector databases and embeddings by treating memory as a continuous process, storing structured data and using LLMs for intelligent consolidation and retrieval. While this is a simplified prototype, it demonstrates the core concepts behind Google's Always-On Memory Agent architecture.



