Zero PII-Kundenintelligenz Teil zur Generierung von Beispieldaten und Bildern
Im Teil wir deckten die Philosophie aus, die durchsichtige Segmentierung ohne PII.. Teil deckt Sitzungsprofile und Segmentdefinitionen ab
Aber zuerst wie validieren Sie irgendetwas davon, ohne jemals echte Kundendaten zu berühren?
Für diese Serie erstelle ich einen kompletten synthetischen E-Commerce-Datensatz lokal.
- Produktkatalog Bezeichnungen Bezeichnungen Beschreibungen
- Anonyme Benutzerprofile”, personas, (, interests, signals, ),
- Produktbilder und Profilporträts über ComfyUI
- Optionaler DB-Import, damit die echte App dagegen laufen kann
Dies ist einer von denen, die sich als betrügen anfühlt, dass ”... Workflows... du erhältst realistische Eingänge... du kannst sie jederzeit regenerieren und nie PII in deine Dev-Umgebung einführen.
Warum lokale synthetische Daten so stark sind
Wenn Sie die Segmentierung der Gebäude ,/ , Personalisierung , , , benötigen Sie Datensätze , die .: ,
- Haben Sie genug Variation, um naive Heuristiken zu brechen
- Sind sicher, um zu teilen (-in Code-Tests ,-Demos
- Sind reproduzierbar -( , so können Sie Modelländerungen vergleichen - )
Echte Daten sind die gegensätzlichen, sensiblen und chaotischen Daten, die schwer zu bewegen sind.
Synthetische Daten geben Ihnen drei Superkräfte
- Schnelle IterationÄndern Sie die Segmentierungslogik.
- HärtungSimulieren Sie seltsames langes Verhalten, das Sie in einem winzigen dev Datensatz sehen konnten.
- ErklärbarkeitsprüfungSie können jedes generierte Feld inspizieren und bestätige deine “, zeige mir warum ”, UI wahr ist.
flowchart LR
Taxonomy[gadget-taxonomy.json] --> Gen[SampleData generator]
Gen --> Products[products.json]
Gen --> Profiles[profiles.json]
Gen --> Images[images/*]
Products --> Import[Import into Postgres]
Profiles --> Import
style Taxonomy stroke:#1971c2,stroke-width:3px
style Gen stroke:#1971c2,stroke-width:3px
style Import stroke:#2f9e44,stroke-width:3px
Das Tooling - Was läuft eigentlich?
Der Generator lebt in Mostlylucid.SegmentCommerce.SampleData.
Es ist absichtlich nicht ein Rahmen, der ”; ist ein pragmatisches CLI, das zu spricht
- Ollama LLM-) für die strukturierte JSON-Generation
- ComfyUI Lokale stabile Diffusion für die Produktfotografie
- A Taxonomie JSON Das hält die Ausgänge kohärente Kategorien, Arten, Varianten, Preisbereiche
Die Konfiguration ist nach oben verdrahtet, so dass Sie es über Umgebungsvariablen fahren können.
// Mostlylucid.SegmentCommerce.SampleData/Program.cs
var configuration = new ConfigurationBuilder()
.SetBasePath(AppContext.BaseDirectory)
.AddJsonFile("appsettings.json", optional: true)
.AddEnvironmentVariables("SAMPLEDATA_")
.Build();
Schnellstart
Sie laufen typischerweise drei lokale Dienste neben dem Generator.
flowchart LR
CLI[SampleData CLI] --> Ollama["Ollama
http://localhost:11434"]
CLI --> Comfy["ComfyUI
http://localhost:8188"]
CLI -. optional .-> DB[(Postgres)]
style CLI stroke:#1971c2,stroke-width:3px
style Ollama stroke:#1971c2,stroke-width:3px
style Comfy stroke:#2f9e44,stroke-width:3px
style DB stroke:#fab005,stroke-width:3px
Ausführen des Generators aus der repo root
dotnet run --project Mostlylucid.SegmentCommerce.SampleData -- status
Dann erzeugen Sie einen Datensatz.
# v1 generator: taxonomy + optional Ollama + optional ComfyUI
# Writes ./Output/products.json, ./Output/profiles.json, ./Output/images/...
dotnet run --project Mostlylucid.SegmentCommerce.SampleData -- generate --count 20
Nützliche Schalter
# No LLM calls, taxonomy only
dotnet run --project Mostlylucid.SegmentCommerce.SampleData -- generate --no-ollama
# No ComfyUI images
dotnet run --project Mostlylucid.SegmentCommerce.SampleData -- generate --no-images
# Write into Postgres (uses configured connection string)
dotnet run --project Mostlylucid.SegmentCommerce.SampleData -- generate --db
Hinweis: Wenn ComfyUI verfügbar ist, fällt der Generator von v-1 auf Platzhalterbilder zurück. picsum.photosSo, dass der Pfad nicht offline läuft. --no-images.
Produkte Produkte Produkte Kunden Bestellungen Produkte Produkte
Es ist auch ein neuerer Generator Befehl (gen), die einen vollständigeren Marktplatz baut
# v2 generator
# Writes dataset.json plus sellers/products/customers/orders split files
dotnet run --project Mostlylucid.SegmentCommerce.SampleData -- gen --sellers 50 --products 20 --customers 1000
Es ist als eine mehrphasige Pipeline orchestriert
flowchart LR
A[Sellers] --> B[Products]
B --> C[Customers]
C --> D[Orders]
D --> E[Embeddings]
B -. optional .-> I[ComfyUI images]
style A stroke:#1971c2,stroke-width:3px
style B stroke:#1971c2,stroke-width:3px
style C stroke:#1971c2,stroke-width:3px
style D stroke:#1971c2,stroke-width:3px
style E stroke:#2f9e44,stroke-width:3px
style I stroke:#2f9e44,stroke-width:3px
Und du kannst diese Phasen direkt im Code sehen.
// Mostlylucid.SegmentCommerce.SampleData/Services/DataGenerator.cs
// 1. Generate Sellers
// 2. Generate Products for each seller
// 3. Generate Customers
// 4. Generate Orders (with fake checkout data via Bogus)
// 5. Generate embeddings for all entities
Einbetten von lokalen ONNX-,Cached nach dem ersten Lauf
Der Generator kann Einbettungen mit einem ONNX-Modell berechnen. all-MiniLM-L6-v2Das erste Mal, wenn Sie es ausführen, lädt es das Modell und Vokabeln in Ihren Ausgabeordner herunter.
Das bedeutet:
- Erster Lauf benötigt Netzwerkzugriff -(-Modell herunterladen -)-
- Nachfolgende Runs sind lokal und schnell
- Wenn Sie möchten, dass kein Netzwerk jemals ausgeführt wird
--no-embeddings
// Mostlylucid.SegmentCommerce.SampleData/Services/EmbeddingService.cs
private const string ModelUrl = "https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2/resolve/main/onnx/model.onnx";
private const string VocabUrl = "https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2/resolve/main/vocab.txt";
// Download model if not exists
if (!File.Exists(_config.ModelPath))
{
await DownloadFileAsync(ModelUrl, _config.ModelPath, ct);
}
Wie wir Produkte erzeugen, die nur für (JSON bestimmt sind
Die Produktgenerierungs-Prompt ist absichtlich streng, das LLM muss nur JSON zurückgeben.Mit einem eingebetteten JSON-Schemabeispiel.
// Mostlylucid.SegmentCommerce.SampleData/Services/OllamaProductGenerator.cs
return $"""
You are a product catalog generator for an e-commerce store. Generate {count} unique, realistic product listings for the \"{category.DisplayName}\" category.
Category description: {category.Description}
Example products in this category: {category.ExampleProducts}
Price range: £{category.PriceRange.Min:F2} - £{category.PriceRange.Max:F2}
For each product, provide:
1. A compelling product name (realistic brand-style naming)
2. A detailed description (2-3 sentences, highlighting key features and benefits)
3. A realistic price within the range
4. Optional original price if on sale (20-40% higher than current price)
5. 3-5 relevant tags
6. Whether it's trending (about 20% should be trending)
7. Whether it's featured (about 15% should be featured)
8. An image prompt for AI image generation (detailed, product photography style)
9. 2-3 colour variants for the product
IMPORTANT: Respond with ONLY valid JSON, no markdown formatting, no code blocks, no explanations.
Generate {count} diverse products now:
""";
Dies ist wichtig, weil nachgelagerte Systeme -(-Bildgenerierung -+-Import-Embeddings - )-gewünschte strukturierte Daten - .-Der LLM produziert Eingänge zu einer PipelineNicht Prosa schreiben
LLM-Antworten
LLMs sind nicht Compiler... Auch mit nur “.JSON müssen Sie immer noch defensive Parsing und anmutigen Fallback.
Das macht der Generator über einen kleinen Helfer.LlmService-), die das erste extrahiert {...} Blockieren und deserialisieren es
// Mostlylucid.SegmentCommerce.SampleData/Services/LlmService.cs
var jsonStart = response.IndexOf('{');
var jsonEnd = response.LastIndexOf('}');
if (jsonStart >= 0 && jsonEnd > jsonStart)
{
var jsonStr = response.Substring(jsonStart, jsonEnd - jsonStart + 1);
return JsonSerializer.Deserialize<T>(jsonStr, new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
});
}
Und die gesamte Generation Pipeline überprüft explizit Verfügbarkeit und Downgrades zu deterministischen Vorlagen, wenn erforderlich .
flowchart LR
A[EnableLlm=true?] -->|no| F[Fallback templates]
A -->|yes| B[GET /api/tags]
B -->|model present| C[LLM JSON prompts]
B -->|not available| F
style A stroke:#1971c2,stroke-width:3px
style C stroke:#2f9e44,stroke-width:3px
style F stroke:#fab005,stroke-width:3px
Beispiel:
Die persona prompt für die Kunden ist kurz und strukturiert, so dass sie schnell mit einem kleinen lokalen Modell erzeugt werden kann.
// Mostlylucid.SegmentCommerce.SampleData/Services/DataGenerator.cs
var prompt = $$"""
Generate a shopper persona interested in: {{string.Join(", ", categoryNames)}}.
Return JSON only:
{
"persona": "Brief persona description (e.g. 'Tech enthusiast who values quality')",
"name": "Realistic first name",
"bio": "One sentence about their shopping habits",
"age": 25,
"shopping_style": "budget|value|premium|luxury",
"preferred_categories": ["category1", "category2"]
}
""";
ComfyUI-:-Produktfotografie über API
ComfyUI ist toll, weil es Ihnen eine steuerbare Pipeline gibt -( workflows- -) anstelle eines einzigen Black Box Bildendpunktes-MSC3
Der Generator
- Lädt eine Workflow-Vorlage
ComfyUI/workflows/product_image.json) - Patchet die Eingabeaufforderung in
CLIPTextEncode - Warteschlangen
/prompt - Umfragen
/history/{promptId} - Laden Sie das Bild über
/view?...
sequenceDiagram
participant Gen as SampleData
participant Comfy as ComfyUI
Gen->>Comfy: POST /prompt (workflow + prompt)
Comfy-->>Gen: prompt_id
loop poll
Gen->>Comfy: GET /history/{prompt_id}
Comfy-->>Gen: outputs / images
end
Gen->>Comfy: GET /view?filename=...&type=output
Comfy-->>Gen: PNG bytes
Die ComfyUI-Modellauswahl wird auch zur Laufzeit in den Workflow gepatcht. So können Sie Checkpoints tauschen, ohne das JSON-): zu bearbeiten.
// Mostlylucid.SegmentCommerce.SampleData/Services/ComfyUIImageGenerator.cs
TryPatchCheckpoint(workflow, _config.ComfyUICheckpointName ?? "sd_xl_base_1.0.safetensors");
TryPatchRefiner(workflow, _config.ComfyUIRefinerName ?? "sd_xl_refiner_1.0.safetensors");
Und das Workflow-Patching ist bewusst einfach und robust
// Mostlylucid.SegmentCommerce.SampleData/Services/ComfyUIImageGenerator.cs
// Update CLIPTextEncode nodes with our prompt
if (classType == "CLIPTextEncode")
{
var inputs = nodeObj["inputs"]?.AsObject();
if (inputs != null && inputs.ContainsKey("text"))
{
var currentText = inputs["text"]?.GetValue<string>() ?? "";
if (!currentText.Contains("bad") && !currentText.Contains("ugly") && !currentText.Contains("deformed"))
{
inputs["text"] = prompt;
}
}
}
// Update image dimensions
if (classType == "EmptyLatentImage")
{
var inputs = nodeObj["inputs"]?.AsObject();
if (inputs != null)
{
inputs["width"] = _config.ImageWidth;
inputs["height"] = _config.ImageHeight;
}
}
Profile und Personen
Der Generator erzeugt anonyme Profile und bereichert sie dann mit einer Person, die immer noch keine PII.). macht Du endest mit realistischen “Peoples...-[formed]”« Testdaten ohne E-Mails, ,[adressen] ,« oder irgendetwas was du jemals versehentlich versenden könntest.
In v-1,-Profile werden mit einem One---way-Hash keyed , also gibt es , ’ , nichts zu entdecken ,“ , ”:
// Mostlylucid.SegmentCommerce.SampleData/Services/ProfileGenerator.cs
var profileKey = Hash($"fp-{Guid.NewGuid():N}");
private static string Hash(string input)
{
using var sha = SHA256.Create();
var bytes = sha.ComputeHash(Encoding.UTF8.GetBytes(input));
return Convert.ToHexString(bytes).ToLowerInvariant();
}
Das ist genau die Mentalität der ganzen Serie... du kannst ’ nicht undicht was du nie gespeichert hast.
flowchart TB
Signals["Generated signals
views/cart/purchase weights"] --> Persona["Persona enrichment
Ollama JSON-only"]
Persona --> Portrait[Portrait prompt]
Portrait --> Comfy[ComfyUI]
style Signals stroke:#1971c2,stroke-width:3px
style Persona stroke:#1971c2,stroke-width:3px
style Comfy stroke:#2f9e44,stroke-width:3px
Validierung - :- Was lässt Sie beweisen,
Diese lokale Pipeline ist leistungsfähig, weil sie ModellvalidierungNicht nur Demos, sondern auch
- SegmentierungsgeistMachen Sie die Segmente, die Sie berechnen.
- Erklärbarkeit der EmpfehlungZeigen Sie mir, warum es ein echtes Signal gibt, das Sie überprüfen können.
- KaltstartWenn du den Datensatz wischst und regenerierst, verhält sich das System vorhersehbar.
- RegressionsprüfungErneuern Sie die gleiche Form von Daten und stellen Sie sicher, dass Ihre Änderungen Don-Don-’.T Break Ranging - ,.Scoring -,.
Die wichtige Subtilität, indem die beiden Text und der BilderSie können das gesamte Produkterlebnis validieren , nicht nur zurück ,- , end math , . ,
Was kommt als nächstes?
**Teil**Sitzungsprofile, signale, und Segmentdefinitionen—wo wir diese Musterdaten in Arbeitssegmentierung verdrahten
Teil (-Coming-):-Outboxmuster,-Job Warteschlange,- und die Transparenz-UIM.-
Generatorcode Mostlylucid.SegmentCommerce.SampleData/