SingleStore is een krachtig multi-model databasesysteem en platform dat is ontworpen om een breed scala aan zakelijke gebruiksscenario’s te ondersteunen. De kenmerkende functies stellen bedrijven in staat om meerdere databasesystemen te verenigen in een enkel platform, waardoor de Totale Cost of Ownership (TCO) wordt verlaagd en de workflows voor ontwikkelaars worden vereenvoudigd door de noodzaak voor complexe integratietools te elimineren.
In dit artikel zullen we verkennen hoe SingleStore e-mailcampagnes voor een webanalysebedrijf kan transformeren, waardoor de creatie van gepersonaliseerde en zeer gerichte e-mailinhoud mogelijk wordt.
Het notitiebestand dat in het artikel wordt gebruikt, is beschikbaar op GitHub.
Introductie
Een webanalysebedrijf vertrouwt op e-mailcampagnes om in contact te komen met klanten. Een generieke benadering voor het targeten van klanten mist echter vaak kansen om het zakelijke potentieel te maximaliseren. Een effectievere oplossing zou inhouden het gebruik van een groot taalmodel (LLM) om gepersonaliseerde e-mailberichten te maken.
Stel je een scenario voor waarbij gebruikersgedragsgegevens worden opgeslagen in een NoSQL-database zoals MongoDB, terwijl waardevolle documentatie zich bevindt in een vectordatabase, zoals Pinecone. Het beheren van deze verschillende systemen kan complex en resource-intensief worden, wat de noodzaak van een geïntegreerde oplossing benadrukt.
SingleStore, een veelzijdige multi-model database, ondersteunt verschillende gegevensindelingen, waaronder JSON, en biedt ingebouwde vectorfuncties. Het integreert naadloos met LLM’s, waardoor het een krachtig alternatief is voor het beheren van meerdere databasesystemen. In dit artikel zullen we demonstreren hoe gemakkelijk SingleStore zowel MongoDB als Pinecone kan vervangen, waardoor operaties worden vereenvoudigd zonder functionaliteit in gevaar te brengen.
In onze voorbeeldtoepassing zullen we een LLM gebruiken om unieke e-mails te genereren voor onze klanten. Om de LLM te helpen leren hoe ze onze klanten kunnen targeten, zullen we een aantal bekende analysebedrijven gebruiken als leermateriaal voor de LLM.
We zullen de inhoud verder aanpassen op basis van gebruikersgedrag. Klantgegevens worden opgeslagen in MongoDB. Verschillende stadia van gebruikersgedrag worden opgeslagen in Pinecone. Het gebruikersgedrag zal de LLM in staat stellen gepersonaliseerde e-mails te genereren. Tot slot zullen we de gegevens opgeslagen in MongoDB en Pinecone consolideren door gebruik te maken van SingleStore.
Maak een SingleStore Cloud-account aan
Een vorig artikel toonde de stappen om een gratis SingleStore Cloud-account aan te maken. We zullen de Standaard Tier gebruiken en de standaardnamen voor de Workspace Group en Workspace aannemen. We zullen ook SingleStore Kai inschakelen.
We zullen onze OpenAI API Key en Pinecone API Key opslaan in de geheimenkluis met behulp van OPENAI_API_KEY
en PINECONE_API_KEY
, respectievelijk.
Importeer de Notebook
We zullen de notebook downloaden van GitHub.
Vanuit het linker navigatiepaneel in het SingleStore cloud portaal, zullen we “ONTWIKKELEN” > “Data Studio” selecteren.
In de rechterbovenhoek van de webpagina zullen we “Nieuwe Notebook” > “Importeren vanuit bestand” selecteren. We zullen de wizard gebruiken om de notebook te lokaliseren en te importeren die we van GitHub hebben gedownload.
Voer de Notebook uit
Generieke E-mail Template
We zullen beginnen met het genereren van generieke e-mailtemplates en deze vervolgens met behulp van een LLM omzetten in gepersonaliseerde berichten voor elke klant. Op deze manier kunnen we elke ontvanger bij naam aanspreken en hen kennis laten maken met de voordelen van ons webanalyseplatform.
We kunnen een generieke e-mail genereren als volgt:
people = ["Alice", "Bob", "Charlie", "David", "Emma"]
for person in people:
message = (
f"Hey {person},\n"
"Check out our web analytics platform, it's Awesome!\n"
"It's perfect for your needs. Buy it now!\n"
"- Marketer John"
)
print(message)
print("_" * 100)
Bijvoorbeeld, Alice zou het volgende bericht zien:
Hey Alice,
Check out our web analytics platform, it's Awesome!
It's perfect for your needs. Buy it now!
- Marketer John
Andere gebruikers zouden hetzelfde bericht ontvangen, maar met hun respectievelijke naam.
2. Toevoegen van een Large Language Model (LLM)
We kunnen eenvoudig een LLM in onze toepassing integreren door het een rol te geven en bepaalde informatie te verstrekken, als volgt:
system_message = """
You are a helpful assistant.
My name is Marketer John.
You help write the body of an email for a fictitious company called 'Awesome Web Analytics'.
This is a web analytics company that is similar to the top 5 web analytics companies (perform a web search to determine the current top 5 web analytics companies).
The goal is to write a custom email to users to get them interested in our services.
The email should be less than 150 words.
Address the user by name.
End with my signature.
"""
We zullen een functie maken om de LLM aan te roepen:
def chatgpt_generate_email(prompt, person):
conversation = [
{"role": "system", "content": prompt},
{"role": "user", "content": person},
{"role": "assistant", "content": ""}
]
response = openai_client.chat.completions.create(
model = "gpt-4o-mini",
messages = conversation,
temperature = 1.0,
max_tokens = 800,
top_p = 1,
frequency_penalty = 0,
presence_penalty = 0
)
assistant_reply = response.choices[0].message.content
return assistant_reply
Door te itereren door de lijst met gebruikers en de LLM aan te roepen, worden unieke e-mails gegenereerd:
openai_client = OpenAI()
# Define a list to store the responses
emails = []
# Loop through each person and generate the conversation
for person in people:
email = chatgpt_generate_email(system_message, person)
emails.append(
{
"person": person,
"assistant_reply": email
}
)
Bijvoorbeeld, dit is wat Alice zou kunnen zien:
Person: Alice
Subject: Unlock Your Website's Potential with Awesome Web Analytics!
Hi Alice,
Are you ready to take your website to new heights? At Awesome Web Analytics, we provide cutting-edge insights that empower you to make informed decisions and drive growth.
With our powerful analytics tools, you can understand user behavior, optimize performance, and boost conversions—all in real-time! Unlike other analytics platforms, we offer personalized support to guide you every step of the way.
Join countless satisfied customers who have transformed their online presence. Discover how we stack up against competitors like Google Analytics, Adobe Analytics, and Matomo, but with a focus on simplicity and usability.
Let us help you turn data into your greatest asset!
Best,
Marketer John
Awesome Web Analytics
Even unieke e-mails zullen worden gegenereerd voor de andere gebruikers.
3. Aanpassen van E-mailinhoud met Gebruikersgedrag
Door gebruikers te categoriseren op basis van hun gedragsfasen, kunnen we e-mailinhoud verder aanpassen om aan te sluiten bij hun specifieke behoeften. Een LLM zal helpen bij het opstellen van e-mails die gebruikers aanmoedigen om door verschillende fasen te gaan, wat uiteindelijk hun begrip en gebruik van verschillende diensten verbetert.
Op dit moment worden gebruikersgegevens bewaard in een MongoDB-database met een recordstructuur vergelijkbaar met de volgende:
{
'_id': ObjectId('64afb3fda9295d8421e7a19f'),
'first_name': 'James',
'last_name': 'Villanueva',
'company_name': 'Foley-Turner',
'stage': 'generating a tracking code',
'created_date': 1987-11-09T12:43:26.000+00:00
}
We zullen verbinding maken met MongoDB om de gegevens op te halen zoals hieronder:
try:
mongo_client = MongoClient("mongodb+srv://admin:<password>@<host>/?retryWrites=true&w=majority")
mongo_db = mongo_client["mktg_email_demo"]
collection = mongo_db["customers"]
print("Connected successfully")
except Exception as e:
print(e)
We zullen <password>
en <host>
vervangen door de waarden van MongoDB Atlas.
We hebben een aantal gebruikersgedragsfasen:
stages = [
"getting started",
"generating a tracking code",
"adding tracking to your website",
"real-time analytics",
"conversion tracking",
"funnels",
"user segmentation",
"custom event tracking",
"data export",
"dashboard customization"
]
def find_next_stage(current_stage):
current_index = stages.index(current_stage)
if current_index < len(stages) - 1:
return stages[current_index + 1]
else:
return stages[current_index]
Met behulp van de gegevens over gedragsfasen zullen we de LLM vragen om de e-mail verder aan te passen zoals hieronder:
limit = 5
emails = []
for record in collection.find(limit = limit):
fname, stage = record.get("first_name"), record.get("stage")
next_stage = find_next_stage(stage)
system_message = f"""
You are a helpful assistant, who works for me, Marketer John at Awesome Web Analytics.
You help write the body of an email for a fictitious company called 'Awesome Web Analytics'.
We are a web analytics company similar to the top 5 web analytics companies.
We have users at various stages in our product's pipeline, and we want to send them helpful emails to encourage further usage of our product.
Please write an email for {fname} who is on stage {stage} of the onboarding process.
The next stage is {next_stage}.
Ensure the email describes the benefits of moving to the next stage.
Limit the email to 1 paragraph.
End the email with my signature.
"""
email = chatgpt_generate_email(system_message, fname)
emails.append(
{
"fname": fname,
"stage": stage,
"next_stage": next_stage,
"email": email
}
)
Als voorbeeld, hier is een e-mail gegenereerd voor Michael:
First Name: Michael
Stage: funnels
Next Stage: user segmentation
Subject: Unlock Deeper Insights with User Segmentation!
Hi Michael,
Congratulations on successfully navigating the funnel stage of our onboarding process! As you move forward to user segmentation, you'll discover how this powerful tool will enable you to categorize your users based on their behaviors and demographics. By understanding your audience segments better, you can create tailored experiences that increase engagement and optimize conversions. This targeted approach not only enhances your marketing strategies but also drives meaningful results and growth for your business. We're excited to see how segmentation will elevate your analytics efforts!
Best,
Marketer John
Awesome Web Analytics
4. E-mailinhoud verder aanpassen
Om gebruikersvooruitgang te ondersteunen, zullen we de vector embeddings van Pinecone gebruiken, waardoor we gebruikers kunnen doorverwijzen naar relevante documentatie voor elke fase. Deze embeddings maken het eenvoudig om gebruikers naar essentiële hulpmiddelen te leiden en hun interacties met ons product verder te verbeteren.
pc = Pinecone(
api_key = pc_api_key
)
index_name = "mktg-email-demo"
if any(index["name"] == index_name for index in pc.list_indexes()):
pc.delete_index(index_name)
pc.create_index(
name = index_name,
dimension = dimensions,
metric = "euclidean",
spec = ServerlessSpec(
cloud = "aws",
region = "us-east-1"
)
)
pc_index = pc.Index(index_name)
pc.list_indexes()
We zullen de embeddings als volgt maken:
def get_embeddings(text):
text = text.replace("\n", " ")
try:
response = openai_client.embeddings.create(
input = text,
model = "text-embedding-3-small"
)
return response.data[0].embedding, response.usage.total_tokens, "success"
except Exception as e:
print(e)
return "", 0, "failed"
id_counter = 1
ids_list = []
for stage in stages:
embedding, tokens, status = get_embeddings(stage)
parent = id_counter - 1
pc_index.upsert([
{
"id": str(id_counter),
"values": embedding,
"metadata": {"content": stage, "parent": str(parent)}
}
])
ids_list.append(str(id_counter))
id_counter += 1
We zullen Pinecone doorzoeken naar overeenkomsten als volgt:
def search_pinecone(embedding):
match = pc_index.query(
vector = [embedding],
top_k = 1,
include_metadata = True
)["matches"][0]["metadata"]
return match["content"], match["parent"]
Met behulp van de gegevens kunnen we de LLM vragen om de e-mail verder aan te passen, zoals hieronder:
limit = 5
emails = []
for record in collection.find(limit = limit):
fname, stage = record.get("first_name"), record.get("stage")
# Get the current and next stages with their embedding
this_stage = next((item for item in stages_w_embed if item["stage"] == stage), None)
next_stage = next((item for item in stages_w_embed if item["stage"] == find_next_stage(stage)), None)
if not this_stage or not next_stage:
continue
# Get content
cur_content, cur_permalink = search_pinecone(this_stage["embedding"])
next_content, next_permalink = search_pinecone(next_stage["embedding"])
system_message = f"""
You are a helpful assistant.
I am Marketer John at Awesome Web Analytics.
We are similar to the current top web analytics companies.
We have users at various stages of using our product, and we want to send them helpful emails to encourage them to use our product more.
Write an email for {fname}, who is on stage {stage} of the onboarding process.
The next stage is {next_stage['stage']}.
Ensure the email describes the benefits of moving to the next stage, and include this link: https://github.com/VeryFatBoy/mktg-email-flow/tree/main/docs/{next_content.replace(' ', '-')}.md.
Limit the email to 1 paragraph.
End the email with my signature: 'Best Regards, Marketer John.'
"""
email = chatgpt_generate_email(system_message, fname)
emails.append(
{
"fname": fname,
"stage": stage,
"next_stage": next_stage["stage"],
"email": email
}
)
Als voorbeeld, hier is een e-mail gegenereerd voor Melissa:
First Name: Melissa
Stage: getting started
Next Stage: generating a tracking code
Subject: Take the Next Step with Awesome Web Analytics!
Hi Melissa,
We're thrilled to see you getting started on your journey with Awesome Web Analytics! The next step is generating your tracking code, which will allow you to start collecting valuable data about your website visitors. With this data, you can gain insights into user behavior, optimize your marketing strategies, and ultimately drive more conversions. To guide you through this process, check out our detailed instructions here: [Generating a Tracking Code](https://github.com/VeryFatBoy/mktg-email-flow/tree/main/docs/generating-a-tracking-code.md). We're here to support you every step of the way!
Best Regards,
Marketer John.
We kunnen zien dat we het generieke sjabloon hebben verfijnd en vrij gerichte e-mails hebben ontwikkeld.
Met gebruik van SingleStore
In plaats van afzonderlijke databasesystemen te beheren, zullen we onze activiteiten stroomlijnen door SingleStore te gebruiken. Met zijn ondersteuning voor JSON, tekst en vector-embeddings kunnen we alle benodigde gegevens efficiënt opslaan op één plek, waardoor de TCO wordt verlaagd en onze ontwikkelingsprocessen worden vereenvoudigd.
We zullen de gegevens van MongoDB invoeren met behulp van een pijplijn die vergelijkbaar is met de volgende:
USE mktg_email_demo;
CREATE LINK mktg_email_demo.link AS MONGODB
CONFIG '{"mongodb.hosts": "<primary>:27017, <secondary>:27017, <secondary>:27017",
"collection.include.list": "mktg_email_demo.*",
"mongodb.ssl.enabled": "true",
"mongodb.authsource": "admin",
"mongodb.members.auto.discover": "false"}'
CREDENTIALS '{"mongodb.user": "admin",
"mongodb.password": "<password>"}';
CREATE TABLES AS INFER PIPELINE AS LOAD DATA LINK mktg_email_demo.link '*' FORMAT AVRO;
START ALL PIPELINES;
We zullen <primary>
, <secondary>
, <secondary>
en <password>
vervangen door de waarden van MongoDB Atlas.
De klantentabel zal worden aangemaakt door de pijplijn. De vector-embeddings voor de gedragsfasen kunnen als volgt worden gemaakt:
df_list = []
id_counter = 1
for stage in stages:
embedding, tokens, status = get_embeddings(stage)
parent = id_counter - 1
stage_df = pd.DataFrame(
{
"id": [id_counter],
"content": [stage],
"embedding": [embedding],
"parent": [parent]
}
)
df_list.append(stage_df)
id_counter += 1
df = pd.concat(df_list, ignore_index = True)
We hebben een tabel nodig om de gegevens op te slaan:
USE mktg_email_demo;
DROP TABLE IF EXISTS docs_splits;
CREATE TABLE IF NOT EXISTS docs_splits (
id INT,
content TEXT,
embedding VECTOR(:dimensions),
parent INT
);
Vervolgens kunnen we de gegevens in de tabel opslaan:
df.to_sql(
"docs_splits",
con = db_connection,
if_exists = "append",
index = False,
chunksize = 1000
)
We zullen SingleStore doorzoeken op overeenkomsten als volgt:
def search_s2(vector):
query = """
SELECT content, parent
FROM docs_splits
ORDER BY (embedding <-> :vector) ASC
LIMIT 1
"""
with db_connection.connect() as con:
result = con.execute(text(query), {"vector": str(vector)})
return result.fetchone()
Met behulp van de gegevens kunnen we de LLM vragen de e-mail aan te passen als volgt:
limit = 5
emails = []
# Create a connection
with db_connection.connect() as con:
query = "SELECT _more :> JSON FROM customers LIMIT :limit"
result = con.execute(text(query), {"limit": limit})
for customer in result:
customer_data = customer[0]
fname, stage = customer_data["first_name"], customer_data["stage"]
# Retrieve current and next stage embeddings
this_stage = next((item for item in stages_w_embed if item["stage"] == stage), None)
next_stage = next((item for item in stages_w_embed if item["stage"] == find_next_stage(stage)), None)
if not this_stage or not next_stage:
continue
# Get content
cur_content, cur_permalink = search_s2(this_stage["embedding"])
next_content, next_permalink = search_s2(next_stage["embedding"])
# Create the system message
system_message = f"""
You are a helpful assistant.
I am Marketer John at Awesome Web Analytics.
We are similar to the current top web analytics companies.
We have users that are at various stages in using our product, and we want to send them helpful emails to get them to use our product more.
Write an email for {fname} who is on stage {stage} of the onboarding process.
The next stage is {next_stage['stage']}.
Ensure the email describes the benefits of moving to the next stage, then always share this link: https://github.com/VeryFatBoy/mktg-email-flow/tree/main/docs/{next_content.replace(' ', '-')}.md.
Limit the email to 1 paragraph.
End the email with my signature: 'Best Regards, Marketer John.'
"""
email = chatgpt_generate_email(system_message, fname)
emails.append(
{
"fname": fname,
"stage": stage,
"next_stage": next_stage["stage"],
"email": email,
}
)
Als voorbeeld, hier is een e-mail gegenereerd voor Joseph:
First Name: Joseph
Stage: generating a tracking code
Next Stage: adding tracking to your website
Subject: Take the Next Step in Your Analytics Journey!
Hi Joseph,
Congratulations on generating your tracking code! The next step is to add tracking to your website, which is crucial for unlocking the full power of our analytics tools. By integrating the tracking code, you will start collecting valuable data about your visitors, enabling you to understand user behavior, optimize your website, and drive better results for your business. Ready to get started? Check out our detailed guide here: [Adding Tracking to Your Website](https://github.com/VeryFatBoy/mktg-email-flow/tree/main/docs/adding-tracking-to-your-website.md).
Best Regards,
Marketer John.
Samenvatting
Door deze praktische demonstratie hebben we gezien hoe SingleStore onze e-mailcampagnes verbetert met zijn multi-model mogelijkheden en door AI-gestuurde personalisatie. Door SingleStore als onze enige bron van waarheid te gebruiken, hebben we onze workflows vereenvoudigd en ervoor gezorgd dat onze e-mailcampagnes maximale impact en waarde leveren aan onze klanten.
Erkenningen
Ik wil Wes Kennedy bedanken voor de originele democode die werd aangepast voor dit artikel.
Source:
https://dzone.com/articles/how-to-build-a-chatgpt-super-app