Part 4: Adding Conversation Memory
Recap: Parts 1-3 built our foundation and created an AI-powered chat endpoint that responds intelligently to user messages.
There’s one major limitation with our current setup: our AI has amnesia. Each message is treated as a brand new conversation with no memory of what was said before. Today we’ll fix this using LangChain.
The Memory Problem
Try asking your current AI assistant: “My name is Sarah” followed by “What’s my name?” It won’t remember. This makes proper customer support impossible—imagine having to re-explain your issue with every message!
Installing LangChain
npm install @langchain/openai @langchain/core
Creating Memory-Enabled Service
Create src/services/memoryService.js
:
const { AzureChatOpenAI } = require('@langchain/openai');
const { BufferMemory } = require('@langchain/core/memory');
const { ConversationChain } = require('@langchain/core/chains');
class MemoryService {
constructor() {
this.model = new AzureChatOpenAI({
azureOpenAIApiKey: process.env.AZURE_OPENAI_API_KEY,
azureOpenAIApiInstanceName: this.extractInstanceName(),
azureOpenAIApiDeploymentName: process.env.AZURE_OPENAI_DEPLOYMENT,
azureOpenAIApiVersion: '2023-12-01-preview'
});
this.memory = new BufferMemory({
returnMessages: true,
memoryKey: 'chat_history'
});
this.chain = new ConversationChain({
llm: this.model,
memory: this.memory
});
}
extractInstanceName() {
const match = process.env.AZURE_OPENAI_ENDPOINT.match(/https:\/\/(.+?)\.openai\.azure\.com/);
return match ? match[1] : '';
}
async processMessage(userMessage) {
try {
const response = await this.chain.predict({
input: userMessage
});
return response;
} catch (error) {
console.error('Memory Service Error:', error);
return 'Sorry, I encountered an issue processing your message.';
}
}
clearMemory() {
this.memory.clear();
}
}
module.exports = new MemoryService();
Adding Memory to Chat Route
Update src/app.js
to use the memory service:
require('dotenv').config();
const express = require('express');
const { getAIResponse } = require('./services/aiService');
const memoryService = require('./services/memoryService');
const app = express();
app.use(express.json());
// Original chat without memory
app.post('/chat', async (req, res) => {
const aiResponse = await getAIResponse(req.body.message);
res.json({ response: aiResponse });
});
// New chat with memory
app.post('/chat-memory', async (req, res) => {
const { message, clearHistory } = req.body;
if (clearHistory) {
memoryService.clearMemory();
}
const response = await memoryService.processMessage(message);
res.json({ response });
});
app.listen(3000, () => console.log('AI server with memory running'));
Testing Memory
Test the dramatic difference memory makes:
# First message
curl -X POST http://localhost:3000/chat-memory \
-H "Content-Type: application/json" \
-d '{"message": "Hi, my name is Sarah and I have a login issue"}'
# Second message - it remembers your name and issue!
curl -X POST http://localhost:3000/chat-memory \
-H "Content-Type: application/json" \
-d '{"message": "What was my name again?"}'
What We’ve Achieved
Our AI assistant can now maintain context across multiple messages, making it suitable for real customer support scenarios. It remembers names, issues, and conversation history—a huge leap from our amnesia-prone version.
Next: Part 5
In Part 5, we’ll address cost optimization by implementing smart memory management that maintains context while controlling token usage for production applications.