[2ff88f42] einfügen
einfügen
This commit is contained in:
@@ -205,8 +205,12 @@ class Persona(Base):
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
name = Column(String, unique=True, index=True) # Matches the 'role' string in JobRolePattern
|
||||
|
||||
description = Column(Text, nullable=True) # NEW: Role description / how they think
|
||||
pains = Column(Text, nullable=True) # JSON list or multiline string
|
||||
gains = Column(Text, nullable=True) # JSON list or multiline string
|
||||
convincing_arguments = Column(Text, nullable=True) # NEW: What convinces them
|
||||
typical_positions = Column(Text, nullable=True) # NEW: Typical titles
|
||||
kpis = Column(Text, nullable=True) # NEW: Relevant KPIs
|
||||
|
||||
created_at = Column(DateTime, default=datetime.utcnow)
|
||||
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
||||
|
||||
@@ -93,9 +93,16 @@ def generate_prompt(industry: Industry, persona: Persona) -> str:
|
||||
persona_pains = [persona.pains] if persona.pains else []
|
||||
persona_gains = [persona.gains] if persona.gains else []
|
||||
|
||||
# Advanced Persona Context
|
||||
persona_context = f"""
|
||||
BESCHREIBUNG/DENKWEISE: {persona.description or 'Nicht definiert'}
|
||||
WAS DIESE PERSON ÜBERZEUGT: {persona.convincing_arguments or 'Nicht definiert'}
|
||||
RELEVANTE KPIs: {persona.kpis or 'Nicht definiert'}
|
||||
"""
|
||||
|
||||
prompt = f"""
|
||||
Du bist ein kompetenter Lösungsberater und brillanter Texter.
|
||||
AUFGABE: Erstelle 3 Textblöcke (Subject, Introduction_Textonly, Industry_References_Textonly) für eine E-Mail an einen Entscheider.
|
||||
Du bist ein kompetenter Lösungsberater und brillanter Texter für B2B-Marketing.
|
||||
AUFGABE: Erstelle 3 hoch-personalisierte Textblöcke (Subject, Introduction_Textonly, Industry_References_Textonly) für eine E-Mail an einen Entscheider.
|
||||
|
||||
--- KONTEXT ---
|
||||
ZIELBRANCHE: {industry.name}
|
||||
@@ -106,20 +113,27 @@ FOKUS-PRODUKT (LÖSUNG):
|
||||
{product_context}
|
||||
|
||||
ANSPRECHPARTNER (ROLLE): {persona.name}
|
||||
PERSÖNLICHE HERAUSFORDERUNGEN DES ANSPRECHPARTNERS (PAIN POINTS):
|
||||
{persona_context}
|
||||
|
||||
SPEZIFISCHE HERAUSFORDERUNGEN (PAIN POINTS) DER ROLLE:
|
||||
{chr(10).join(['- ' + str(p) for p in persona_pains])}
|
||||
|
||||
SPEZIFISCHE NUTZEN (GAINS) DER ROLLE:
|
||||
{chr(10).join(['- ' + str(g) for g in persona_gains])}
|
||||
|
||||
--- DEINE AUFGABE ---
|
||||
Deine Texte müssen "voll ins Zentrum" der Rolle treffen. Vermeide oberflächliche Floskeln. Nutze die Details zur Denkweise, den KPIs und den Überzeugungsargumenten, um eine tiefgreifende Relevanz zu erzeugen.
|
||||
|
||||
1. **Subject:** Formuliere eine kurze Betreffzeile (max. 6 Wörter). Richte sie **direkt an einem der persönlichen Pain Points** des Ansprechpartners oder dem zentralen Branchen-Pain. Sei scharfsinnig, nicht werblich.
|
||||
|
||||
2. **Introduction_Textonly:** Formuliere einen prägnanten Einleitungstext (max. 2 Sätze).
|
||||
- **WICHTIG:** Gehe davon aus, dass die spezifische Herausforderung des Kunden bereits im Satz davor [Opener] genannt wurde. **Wiederhole die Herausforderung NICHT.**
|
||||
- **Satz 1 (Die Lösung & der Gain):** Beginne direkt mit der Lösung. Nenne die im Kontext `FOKUS-PRODUKT` definierte **Produktkategorie** (z.B. "automatisierte Reinigungsroboter") und verbinde sie mit dem zentralen Nutzen (Gain) aus den `BRANCHEN-HERAUSFORDERUNGEN`. Beispiel: "Genau hier setzen unsere automatisierten Reinigungsroboter an, indem sie eine lückenlose und auditsichere Hygiene gewährleisten."
|
||||
- **Satz 2 (Die Relevanz):** Stelle die Relevanz für die Zielperson her, indem du einen ihrer `PERSÖNLICHE HERAUSFORDERUNGEN` adressierst. Beispiel: "Für Sie als Infrastruktur-Verantwortlicher bedeutet dies vor allem eine reibungslose Integration in bestehende Abläufe, ohne den Betrieb zu stören."
|
||||
- **Satz 1 (Die Lösung & der Gain):** Beginne direkt mit der Lösung. Nenne die im Kontext `FOKUS-PRODUKT` definierte **Produktkategorie** (z.B. "automatisierte Reinigungsroboter") und verbinde sie mit einem Nutzen, der für diese Rolle (siehe `WAS DIESE PERSON ÜBERZEUGT` und `GAINS`) besonders kritisch ist.
|
||||
- **Satz 2 (Die Relevanz):** Stelle die Relevanz für die Zielperson her, indem du eine ihrer `PERSÖNLICHE HERAUSFORDERUNGEN` oder `KPIs` adressierst. Beispiel: "Für Sie als [Rolle] bedeutet dies vor allem [Nutzen bezogen auf KPI oder Pain]."
|
||||
|
||||
3. **Industry_References_Textonly:** Formuliere einen **strategischen Referenz-Block (ca. 2-3 Sätze)** nach folgendem Muster:
|
||||
- **Satz 1 (Social Proof):** Beginne direkt mit dem Nutzen, den vergleichbare Unternehmen in der Branche {industry.name} bereits erzielen. (Erfinde keine Firmennamen, sprich von "Führenden Einrichtungen" oder "Vergleichbaren Häusern").
|
||||
- **Satz 2 (Rollen-Relevanz):** Schaffe den direkten Nutzen für die Zielperson. Formuliere z.B. 'Dieser Wissensvorsprung hilft uns, Ihre [persönlicher Pain Point der Rolle] besonders effizient zu lösen.'
|
||||
- **Satz 2 (Rollen-Relevanz):** Schaffe den direkten Nutzen für die Zielperson. Nutze dabei die Informationen aus `BESCHREIBUNG/DENKWEISE`, um den Ton perfekt zu treffen.
|
||||
|
||||
--- BEISPIEL FÜR EINEN PERFEKTEN OUTPUT ---
|
||||
{{
|
||||
|
||||
@@ -16,13 +16,14 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
NOTION_TOKEN_FILE = "/app/notion_token.txt"
|
||||
# Sector & Persona Master DB
|
||||
PERSONAS_DB_ID = "2e288f42-8544-8113-b878-ec99c8a02a6b"
|
||||
PERSONAS_DB_ID = "30588f42-8544-80c3-8919-e22d74d945ea"
|
||||
|
||||
VALID_ARCHETYPES = {
|
||||
"Wirtschaftlicher Entscheider",
|
||||
"Operativer Entscheider",
|
||||
"Infrastruktur-Verantwortlicher",
|
||||
"Innovations-Treiber"
|
||||
"Innovations-Treiber",
|
||||
"Influencer"
|
||||
}
|
||||
|
||||
def load_notion_token():
|
||||
@@ -65,6 +66,10 @@ def extract_title(prop):
|
||||
if not prop: return ""
|
||||
return "".join([t.get("plain_text", "") for t in prop.get("title", [])])
|
||||
|
||||
def extract_rich_text(prop):
|
||||
if not prop: return ""
|
||||
return "".join([t.get("plain_text", "") for t in prop.get("rich_text", [])])
|
||||
|
||||
def extract_rich_text_to_list(prop):
|
||||
"""
|
||||
Extracts rich text and converts bullet points/newlines into a list of strings.
|
||||
@@ -94,7 +99,8 @@ def sync_personas(token, session):
|
||||
|
||||
for page in pages:
|
||||
props = page.get("properties", {})
|
||||
name = extract_title(props.get("Name"))
|
||||
# The title property is 'Role' in the new DB, not 'Name'
|
||||
name = extract_title(props.get("Role"))
|
||||
|
||||
if name not in VALID_ARCHETYPES:
|
||||
logger.debug(f"Skipping '{name}' (Not a target Archetype)")
|
||||
@@ -105,6 +111,11 @@ def sync_personas(token, session):
|
||||
pains_list = extract_rich_text_to_list(props.get("Pains"))
|
||||
gains_list = extract_rich_text_to_list(props.get("Gains"))
|
||||
|
||||
description = extract_rich_text(props.get("Rollenbeschreibung"))
|
||||
convincing_arguments = extract_rich_text(props.get("Was ihn überzeugt"))
|
||||
typical_positions = extract_rich_text(props.get("Typische Positionen"))
|
||||
kpis = extract_rich_text(props.get("KPIs"))
|
||||
|
||||
# Upsert Logic
|
||||
persona = session.query(Persona).filter(Persona.name == name).first()
|
||||
if not persona:
|
||||
@@ -116,6 +127,10 @@ def sync_personas(token, session):
|
||||
|
||||
persona.pains = json.dumps(pains_list, ensure_ascii=False)
|
||||
persona.gains = json.dumps(gains_list, ensure_ascii=False)
|
||||
persona.description = description
|
||||
persona.convincing_arguments = convincing_arguments
|
||||
persona.typical_positions = typical_positions
|
||||
persona.kpis = kpis
|
||||
|
||||
count += 1
|
||||
|
||||
|
||||
Reference in New Issue
Block a user