SingleStore ist ein leistungsstarkes Multi-Model-Datenbanksystem und eine Plattform, die entwickelt wurde, um eine Vielzahl von Geschäftsanwendungsfällen zu unterstützen. Ihre einzigartigen Funktionen ermöglichen es Unternehmen, mehrere Datenbanksysteme in eine einzige Plattform zu integrieren, was die Gesamtbetriebskosten reduziert und die Arbeitsabläufe für Entwickler vereinfacht, indem komplexe Integrationswerkzeuge überflüssig werden.
In diesem Artikel werden wir untersuchen, wie SingleStore E-Mail-Kampagnen für ein Web-Analyseunternehmen transformieren kann, um die Erstellung personalisierter und hoch zielgerichteter E-Mail-Inhalte zu ermöglichen.
Die im Artikel verwendete Notizdatei ist auf GitHub verfügbar.
Einführung
Ein Web-Analyseunternehmen ist auf E-Mail-Kampagnen angewiesen, um mit Kunden in Kontakt zu treten. Ein generischer Ansatz zur Zielgruppenansprache verpasst jedoch oft Chancen, das Geschäftspotenzial zu maximieren. Eine effektivere Lösung würde die Verwendung eines großen Sprachmodells (LLM) beinhalten, um personalisierte E-Mail-Nachrichten zu erstellen.
Stellen Sie sich ein Szenario vor, in dem Benutzerverhaltensdaten in einer NoSQL-Datenbank wie MongoDB gespeichert sind, während wertvolle Dokumentation in einer Vektordatenbank wie Pinecone vorhanden ist. Das Verwalten dieser verschiedenen Systeme kann komplex und ressourcenintensiv werden und unterstreicht die Notwendigkeit einer vereinheitlichten Lösung.
SingleStore, eine vielseitige Multi-Model-Datenbank, unterstützt verschiedene Datenformate, einschließlich JSON, und bietet integrierte Vektorfunktionen. Es integriert nahtlos mit LLMs und ist damit eine leistungsstarke Alternative zur Verwaltung mehrerer Datenbanksysteme. In diesem Artikel werden wir demonstrieren, wie einfach SingleStore sowohl MongoDB als auch Pinecone ersetzen kann, indem wir Operationen vereinfachen, ohne die Funktionalität zu beeinträchtigen.
In unserer Beispielanwendung verwenden wir ein LLM, um eindeutige E-Mails für unsere Kunden zu generieren. Um dem LLM beizubringen, wie es unsere Kunden ansprechen kann, verwenden wir eine Reihe bekannter Analyseunternehmen als Lernmaterial für das LLM.
Wir werden den Inhalt weiter anhand des Nutzerverhaltens anpassen. Kundendaten werden in MongoDB gespeichert. Unterschiedliche Phasen des Nutzerverhaltens werden in Pinecone gespeichert. Das Nutzerverhalten ermöglicht es dem LLM, personalisierte E-Mails zu generieren. Schließlich werden wir die in MongoDB und Pinecone gespeicherten Daten mit SingleStore konsolidieren.
Erstellen Sie ein SingleStore Cloud-Konto
Ein früherer Artikel hat die Schritte zur Erstellung eines kostenlosen SingleStore Cloud-Kontos gezeigt. Wir werden die Standard-Tier verwenden und die Standardnamen für die Arbeitsgruppe und den Arbeitsbereich übernehmen. Wir werden auch SingleStore Kai aktivieren.
Wir werden unseren OpenAI API-Schlüssel und Pinecone API-Schlüssel im geheimen Tresor unter Verwendung von OPENAI_API_KEY
und PINECONE_API_KEY
speichern.
Importieren Sie das Notebook
Wir werden das Notebook von GitHub herunterladen.
Von der linken Navigationsleiste im SingleStore-Cloud-Portal wählen wir „ENTWICKELN“ > „Data Studio.“
Oben rechts auf der Webseite wählen wir „Neues Notebook“ > „Aus Datei importieren.“ Wir verwenden den Assistenten, um das Notebook zu finden und zu importieren, das wir von GitHub heruntergeladen haben.
Notebook ausführen
Generische E-Mail-Vorlage
Wir beginnen mit der Erstellung generischer E-Mail-Vorlagen und verwenden dann ein LLM, um sie in personalisierte Nachrichten für jeden Kunden umzuwandeln. Auf diese Weise können wir jeden Empfänger beim Namen ansprechen und sie mit den Vorteilen unserer Web-Analyseplattform vertraut machen.
Wir können eine generische E-Mail wie folgt erstellen:
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)
Zum Beispiel würde Alice die folgende Nachricht sehen:
Hey Alice,
Check out our web analytics platform, it's Awesome!
It's perfect for your needs. Buy it now!
- Marketer John
Andere Benutzer würden dieselbe Nachricht erhalten, jedoch mit ihrem jeweiligen Namen.
2. Hinzufügen eines Large Language Model (LLM)
Wir können leicht ein LLM in unsere Anwendung integrieren, indem wir ihm eine Rolle zuweisen und ihm einige Informationen geben, wie folgt:
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.
"""
Wir werden eine Funktion erstellen, um das LLM aufzurufen:
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
Indem wir die Liste der Benutzer durchlaufen und das LLM aufrufen, werden einzigartige E-Mails generiert:
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
}
)
Zum Beispiel könnte Alice Folgendes sehen:
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
Ebenso einzigartige E-Mails werden für die anderen Benutzer generiert.
3. Anpassen des E-Mail-Inhalts an das Nutzerverhalten
Durch die Kategorisierung von Benutzern basierend auf ihren Verhaltensstufen können wir den E-Mail-Inhalt weiter anpassen, um ihn an ihre spezifischen Bedürfnisse anzupassen. Ein LLM wird dabei helfen, E-Mails zu erstellen, die Benutzer dazu ermutigen, durch verschiedene Stufen voranzukommen und letztendlich ihr Verständnis und ihre Nutzung verschiedener Dienste zu verbessern.
Zurzeit werden Benutzerdaten in einer MongoDB-Datenbank mit einer Aufzeichnungsstruktur ähnlich der folgenden gespeichert:
{
'_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
}
Wir werden uns mit MongoDB verbinden, um die Daten wie folgt zu erhalten:
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)
Wir werden <password>
und <host>
durch die Werte von MongoDB Atlas ersetzen.
Wir haben eine Reihe von Benutzerverhaltensstufen:
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]
Basierend auf den Daten zu Verhaltensstufen werden wir den LLM bitten, die E-Mail weiter anzupassen, wie folgt:
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
}
)
Zum Beispiel hier ist eine E-Mail für Michael generiert:
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-Mail-Inhalt weiter anpassen
Um den Fortschritt der Benutzer zu unterstützen, werden wir die Vektor-Einbettungen von Pinecone verwenden, um Benutzer zu relevanten Dokumentationen für jede Stufe zu leiten. Diese Einbettungen machen es mühelos, Benutzer zu wichtigen Ressourcen zu lenken und ihre Interaktionen mit unserem Produkt weiter zu verbessern.
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()
Wir werden die Einbettungen wie folgt erstellen:
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
Wir werden Pinecone nach Übereinstimmungen durchsuchen, wie folgt:
def search_pinecone(embedding):
match = pc_index.query(
vector = [embedding],
top_k = 1,
include_metadata = True
)["matches"][0]["metadata"]
return match["content"], match["parent"]
Basierend auf den Daten können wir den LLM bitten, die E-Mail weiter anzupassen, wie folgt:
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
}
)
Zum Beispiel hier ist eine E-Mail für Melissa generiert:
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.
Wir können sehen, dass wir die generische Vorlage verfeinert und ziemlich zielgerichtete E-Mails entwickelt haben.
Unter Verwendung von SingleStore
Anstatt separate Datenbanksysteme zu verwalten, werden wir unsere Abläufe durch die Verwendung von SingleStore optimieren. Mit seiner Unterstützung für JSON, Text und Vektoreinbettungen können wir alle erforderlichen Daten effizient an einem Ort speichern, was die Gesamtkosten reduziert und unsere Entwicklungsprozesse vereinfacht.
Die Daten werden aus MongoDB über eine ähnliche Pipeline wie die folgende eingelesen:
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;
Wir werden <primary>
, <secondary>
, <secondary>
und <password>
durch die Werte aus MongoDB Atlas ersetzen.
Die Kundentabelle wird durch die Pipeline erstellt. Die Vektoreinbettungen für die Verhaltensstufen können wie folgt erstellt werden:
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)
Wir benötigen eine Tabelle, um die Daten zu speichern:
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
);
Dann können wir die Daten in der Tabelle speichern:
df.to_sql(
"docs_splits",
con = db_connection,
if_exists = "append",
index = False,
chunksize = 1000
)
Wir werden SingleStore nach Übereinstimmungen durchsuchen, wie folgt:
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()
Mit den Daten können wir den LLM bitten, die E-Mail anzupassen, wie folgt:
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 Beispiel hier eine für Joseph generierte E-Mail:
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.
Zusammenfassung
In dieser praktischen Demonstration haben wir gesehen, wie SingleStore unsere E-Mail-Kampagnen mit seinen Multi-Model-Fähigkeiten und KI-gesteuerter Personalisierung verbessert. Durch die Verwendung von SingleStore als unsere einzige Wahrheitsquelle haben wir unsere Abläufe vereinfacht und sichergestellt, dass unsere E-Mail-Kampagnen maximalen Einfluss und Wert für unsere Kunden bieten.
Danksagungen
Ich danke Wes Kennedy für den ursprünglichen Demo-Code, der für diesen Artikel angepasst wurde.
Source:
https://dzone.com/articles/how-to-build-a-chatgpt-super-app