Lecture Notes:
Typical database technologies used for storing conversational memory in AI systems, along with sample code and workflows.
This will expand on the JSON file-based approach we used in the lab and introduce more scalable solutions.
Lecture Note: Database Technologies for AI Conversational Memory
In production AI systems, especially those dealing with large-scale conversational data, we typically use more robust and scalable database solutions than simple JSON files.
Here are some common database technologies used in AI applications:
1. NoSQL Databases (JSON)
2. Relational Databases
3. Vector Databases
1. NoSQL Databases:
NoSQL databases are often preferred for storing conversational data due to their flexibility with unstructured data and scalability.
MongoDB is a popular document-based JSON NoSQL database that stores data in BSON (Binary JSON) format, making it ideal for JSON-like conversational data.
Sample code using PyMongo (MongoDB's Python driver):
```python
from pymongo import MongoClient
# Connect to MongoDB
client = MongoClient('mongodb://localhost:27017/')
db = client['conversational_ai_db']
conversations = db['conversations']
# Store a conversation
conversation = {
"conversation_id": "12345",
"participants": ["user", "ai"],
"messages": [
{
"sender": "user",
"content": "Hello, how are you?",
"timestamp": "2023-11-20T10:00:00Z"
},
{
"sender": "ai",
"content": "Hello! I'm functioning well, thank you. How can I assist you today?",
"timestamp": "2023-11-20T10:00:05Z"
}
]
}
result = conversations.insert_one(conversation)
print(f"Conversation inserted with id: {result.inserted_id}")
# Retrieve a conversation
retrieved_conv = conversations.find_one({"conversation_id": "12345"})
print(retrieved_conv)
```
2. Relational Databases:
While less common for storing raw conversational data, relational databases are often used in conjunction with NoSQL databases for structured metadata or analytics.
Example: PostgreSQL
Sample code using psycopg2 (PostgreSQL adapter for Python):
```python
import psycopg2
import json
# Connect to PostgreSQL
conn = psycopg2.connect("dbname=conversational_ai user=postgres password=password")
cur = conn.cursor()
# Create tables
cur.execute("""
CREATE TABLE IF NOT EXISTS conversations (
id SERIAL PRIMARY KEY,
conversation_id VARCHAR(255) UNIQUE,
participants JSONB,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
""")
cur.execute("""
CREATE TABLE IF NOT EXISTS messages (
id SERIAL PRIMARY KEY,
conversation_id VARCHAR(255) REFERENCES conversations(conversation_id),
sender VARCHAR(50),
content TEXT,
timestamp TIMESTAMP
)
""")
# Insert a conversation
conversation = {
"conversation_id": "12345",
"participants": ["user", "ai"],
"messages": [
{
"sender": "user",
"content": "Hello, how are you?",
"timestamp": "2023-11-20T10:00:00Z"
},
{
"sender": "ai",
"content": "Hello! I'm functioning well, thank you. How can I assist you today?",
"timestamp": "2023-11-20T10:00:05Z"
}
]
}
cur.execute(
"INSERT INTO conversations (conversation_id, participants) VALUES (%s, %s)",
(conversation['conversation_id'], json.dumps(conversation['participants']))
)
for message in conversation['messages']:
cur.execute(
"INSERT INTO messages (conversation_id, sender, content, timestamp) VALUES (%s, %s, %s, %s)",
(conversation['conversation_id'], message['sender'], message['content'], message['timestamp'])
)
conn.commit()
# Retrieve a conversation
cur.execute("""
SELECT c.conversation_id, c.participants,
json_agg(json_build_object('sender', m.sender, 'content', m.content, 'timestamp', m.timestamp)) as messages
FROM conversations c
JOIN messages m ON c.conversation_id = m.conversation_id
WHERE c.conversation_id = %s
GROUP BY c.conversation_id, c.participants
""", ("12345",))
retrieved_conv = cur.fetchone()
print(json.dumps(retrieved_conv, indent=2))
cur.close()
conn.close()
```
3. Vector Databases:
For advanced AI applications, especially those involving semantic search or similarity matching, vector databases are becoming increasingly popular.
Example: Pinecone
Sample code using Pinecone:
```python
import pinecone
from sentence_transformers import SentenceTransformer
# Initialize Pinecone
pinecone.init(api_key="your-api-key", environment="your-environment")
index_name = "conversational-ai"
# Create index if it doesn't exist
if index_name not in pinecone.list_indexes():
pinecone.create_index(index_name, dimension=384, metric="cosine")
# Connect to the index
index = pinecone.Index(index_name)
# Load a sentence transformer model
model = SentenceTransformer('all-MiniLM-L6-v2')
# Function to upsert conversation
def upsert_conversation(conversation):
for i, message in enumerate(conversation['messages']):
vector = model.encode(message['content']).tolist()
unique_id = f"{conversation['conversation_id']}_{i}"
metadata = {
"conversation_id": conversation['conversation_id'],
"sender": message['sender'],
"timestamp": message['timestamp']
}
index.upsert([(unique_id, vector, metadata)])
# Upsert a conversation
conversation = {
"conversation_id": "12345",
"messages": [
{
"sender": "user",
"content": "Hello, how are you?",
"timestamp": "2023-11-20T10:00:00Z"
},
{
"sender": "ai",
"content": "Hello! I'm functioning well, thank you. How can I assist you today?",
"timestamp": "2023-11-20T10:00:05Z"
}
]
}
upsert_conversation(conversation)
# Query similar messages
query_vector = model.encode("How are you doing?").tolist()
results = index.query(query_vector, top_k=5, include_metadata=True)
for result in results['matches']:
print(f"Score: {result['score']}, Content: {result['metadata']}")
```
Workflow Considerations:
1. Data Ingestion: Set up a pipeline to continuously ingest conversational data into your chosen database.
2. Data Processing: Implement pre-processing steps (e.g., tokenization, embedding generation) before storage.
3. Indexing: For faster retrieval, create appropriate indexes on frequently queried fields.