Skip to main content

Customer Support Bot

The Problem

Support bots without memory force customers to repeat themselves every time they open a new ticket. A customer who reported a billing issue last week has to explain the full context again today. Agents can't reference past interactions or spot patterns across conversations.

The Solution

Store every support interaction as a memory. Use categories to organize them by topic. At the start of each conversation, retrieve the customer's history and compiled knowledge so the bot has full context before the first response.

Implementation

Install the SDK

npm install @memsolus/sdk

Initialize the client

import { Memsolus } from '@memsolus/sdk';

const memsolus = new Memsolus({
apiKey: process.env.MEMSOLUS_API_KEY,
});

Load customer history at conversation start

async function loadCustomerContext(customerId: string): Promise<string> {
const knowledge = await memsolus.knowledge.get({
userId: customerId,
merged: true,
});

return knowledge?.content ?? '';
}

Search for relevant past interactions

When the customer describes their issue, search for similar past tickets:

async function findRelatedHistory(
customerId: string,
issue: string,
): Promise<string[]> {
const results = await memsolus.memories.search({
query: issue,
userId: customerId,
mode: 'hybrid',
limit: 10,
});

return results.data.map((m) => m.content);
}

Record the interaction

After each resolved ticket, store a summary as a memory:

type SupportCategory = 'billing' | 'technical' | 'general' | 'account';

interface SupportInteraction {
customerId: string;
summary: string;
category: SupportCategory;
resolved: boolean;
}

async function recordInteraction(interaction: SupportInteraction): Promise<void> {
const statusTag = interaction.resolved ? '[Resolved]' : '[Open]';
const content = `${statusTag} ${interaction.category.toUpperCase()}: ${interaction.summary}`;

await memsolus.memories.add({
content,
userId: interaction.customerId,
metadata: {
category: interaction.category,
resolved: interaction.resolved,
timestamp: new Date().toISOString(),
},
});
}

Build a support session

Combine history retrieval and context-aware responses:

import OpenAI from 'openai';

const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

async function handleSupportTicket(
customerId: string,
customerMessage: string,
): Promise<string> {
const [customerProfile, relatedHistory] = await Promise.all([
loadCustomerContext(customerId),
findRelatedHistory(customerId, customerMessage),
]);

const systemPrompt = buildSupportSystemPrompt(customerProfile, relatedHistory);

const completion = await openai.chat.completions.create({
model: 'gpt-4o',
messages: [
{ role: 'system', content: systemPrompt },
{ role: 'user', content: customerMessage },
],
});

return completion.choices[0].message.content ?? '';
}

function buildSupportSystemPrompt(
customerProfile: string,
relatedHistory: string[],
): string {
const historySection =
relatedHistory.length > 0
? `\n\nPast interactions:\n${relatedHistory.map((h) => `- ${h}`).join('\n')}`
: '';

const profileSection = customerProfile
? `\n\nCustomer profile:\n${customerProfile}`
: '';

return (
`You are a customer support agent for Memsolus. ` +
`Be concise, helpful, and reference past interactions when relevant.` +
`${profileSection}${historySection}`
);
}

Full Example

import { Memsolus } from '@memsolus/sdk';

const memsolus = new Memsolus({ apiKey: process.env.MEMSOLUS_API_KEY });

const CUSTOMER_ID = 'customer_9f2a3b';

// Record past interactions
await recordInteraction({
customerId: CUSTOMER_ID,
summary: 'Customer was charged twice for the Pro plan in March. Refund issued.',
category: 'billing',
resolved: true,
});

await recordInteraction({
customerId: CUSTOMER_ID,
summary: 'Customer reported slow search responses when using more than 10,000 memories.',
category: 'technical',
resolved: false,
});

// New session — bot has full history
const response = await handleSupportTicket(
CUSTOMER_ID,
"I'm seeing slow search again. Is this related to my previous issue?",
);

// Bot responds with context about the unresolved technical ticket
console.log(response);

Organizing by Category

You can search memories filtered by metadata to retrieve only billing-related or technical history:

// Search only billing history
const billingHistory = await memsolus.memories.search({
query: 'payment charge refund subscription',
userId: customerId,
mode: 'keyword',
limit: 5,
});

// Search only technical history
const technicalHistory = await memsolus.memories.search({
query: 'slow search performance timeout error',
userId: customerId,
mode: 'semantic',
limit: 5,
});

What's Next