Back to "Null PII Kunden Intelligence - Del | 1.1: | Genererande av proverdata ♫ ( ♫ och bilder ♫) ♫ Lokalt"

This is a viewer only at the moment see the article on how this works.

To update the preview hit Ctrl-Alt-R (or ⌘-Alt-R on Mac) or Enter to refresh. The Save icon lets you save the markdown file to disk

This is a preview from the server running through my markdig pipeline

C# ComfyUI LLM Privacy Product

Null PII Kunden Intelligence - Del | 1.1: | Genererande av proverdata ♫ ( ♫ och bilder ♫) ♫ Lokalt

Wednesday, 31 December 2025

I Del 1 vi täckte filosofin:", transparent segmentation utan PII, . Del 2 täcker sessionsprofiler, signaler , och segmentdefinitioner

Men först hur kan man validera något av detta utan att någonsin röra vid riktiga kunders data?

För den här serien genererar jag en komplett syntetisk e-commerce dataset lokalt:

  • Produktkatalog ( namn , beschreibungar, märkenM SK3 priserMSC4
  • Anonyma “profiler” / personer ( intressen + signaler)
  • Produktbilder ( och profilporträtt ) via ComfyUI
  • Optionell DB-import så att den riktiga appen kan köra emot den

Det här är en av dom där. “, det känns som att fuska. ♫ ”, arbetsflöden. ♪ :, du får realistiska ingångar. | ,, du kan regenerera dem närsomhelst.

Varför är lokala syntetiska data så kraftfulla

Om du bygger segmentering, personalisering och personalisering, behöver du datamängder som:

  • Ha tillräckligt med variation för att bryta naivt heuristik
  • Är säkra att dela med sig av ( i koden , tester
  • Är reproducerbara ( så att du kan jämföra modellförändringarM SK1

Verkliga data är motsatsen.

Syntetiska data ger dig tre superkrafter:

  1. snabb repetition: byta segmenteringslogiken , regenerera M SK2 återskapa
  2. Förhärdning: simulera märkliga långa kretsar
  3. Förklaringstest: kan du inspektera varje genererade fält och bekräfta din “skaffa mig varför
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

verktyget ( Vad som faktiskt körs)

Generatoren lever i Mostlylucid.SegmentCommerce.SampleData.

Det är inte avsiktligt ett ramverk, det är en pragmatisk CLI som talar med

  • Ollama (lokal LLM) för strukturerad generation av JSONM SK2
  • KomfyUI (lokal stabil diffusering) för produktfotografering -stilbilderM SK3
  • A taksonom JSON som håller utsläppen konsekventa (kategorier, typerM SK2 varianter , prissegmenter

Konfigurationen är kopplad upp så att du kan köra den via miljövariabler:

// Mostlylucid.SegmentCommerce.SampleData/Program.cs
var configuration = new ConfigurationBuilder()
    .SetBasePath(AppContext.BaseDirectory)
    .AddJsonFile("appsettings.json", optional: true)
    .AddEnvironmentVariables("SAMPLEDATA_")
    .Build();

Vinnigstart

Du kommer typically att köra tre lokala tjänster tillsammans med generatorn.

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

kör generatorn från repo root:

dotnet run --project Mostlylucid.SegmentCommerce.SampleData -- status

Sedan generera en datauppsättning:

# 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

användbara skivor:

# 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

Beteckning: om ComfyUI inte är tillgängligt’ , så ramlar generatorn tillbaka till placeholderbilderna M SK4 den använder picsum.photos, så att vägen inte är --no-images.

v2 Generatorn : Försäljare | → | produkter | МSK3 | kunder |→ | order | → | inrymme

Det finns också ett nytt genereringskommando (gen) som bygger upp en mer komplett

# 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

Den är orkestrerad som en multi- -Phass- -Pipeline.

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

Och du kan se dessa faser direkt i koden:

// 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

Embeddings (Local ONNX , Cached after first run)

Generatoren v2 kan bearbeta embeddings med hjälp av en ONNX-modell. all-MiniLM-L6-v2). När du kör den första gången , så laddas den ned modellen och kommer in i ditt utgångsordnet

Det betyder:".

  • Den första körningen behöver tillgång till nätverk (modelldownload)
  • Efterföljande prover är lokala och snabba
  • Om du vill köra “ inget nätverk någonsin --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);
}

Hur vi genererar “LLM-formadeM SK2 produkter (JSON-onlystMSC4

Product generation prompten är uppsåtligt strikt: LLM måste bara ge tillbaka JSON , med ett inbyggdt JSON-skemaexamples

// 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:
    """;

Detta spelar roll eftersom system i nedströmning (bildskapande + införing ♫ + ♫ inbäddar ♫) ♫ vill ha strukturerade data ♫ ingångar till en pipeline, inte skriva noter

LLM-responser : analysera JSON, eller falla tillbaka

LLMs är inte kompilatorer. Även med “JSON baraM SK2 behöver du fortfarande försvarsmässigt analysera och eleganta fallbackar

Generatoren v2 gör det via en liten hjälpman (LlmService) som extraherar den första {...} blockera och deserialisera den:

// 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
    });
}

Och den totala produktionskedjan explicit kontrollerar tillgänglighet och nedgraderingar till deterministiska templater när det behövs:

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

exempel: Kunden Personas (vM SK2

Person prompten för kunder är kort och strukturerad så den kan skapas snabbt med en liten lokal modell:

// 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: Produktfotografering via API

ComfyUI är jättebra eftersom det ger dig en styrbar pipeline ( arbetsflöden ) snarare än ett ♫ “ en enda svarta låda bild slutpunkt ”.

Generatorn:

  1. Lader ett arbetsflödes-template (ComfyUI/workflows/product_image.json)
  2. Patchar prompten till CLIPTextEncode
  3. köer /prompt
  4. Poller /history/{promptId}
  5. ladda ned bilden via /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

KomfyUI-modellselektionen är också patchad in i arbetsflödet vid starttid ( så du kan byta kontrollpunkter utan att redigera JSON

// 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");

Och arbetsflödet att patcha är avsiktligt enkelt och 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 och personligheter (användbar, Inte läskigtM SK2

Generatoren v1 skapar anonyma profiler och förstärker dem med en person. (still ingen PII, ). Då får du realistiska data.

I v1,-profiler aktiveras med hjälp av en oneM SK1way hash , så det finns inget att ’

// 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();
}

Att "’" är exakt samma tankesätt som hela serien, att ":", du kan "’", att inte läcka ut det du aldrig har lagrat.

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

Validation: Vad detta låter dig bevisa

Den här lokala pipelinen är kraftfull eftersom den modellvalidering, inte bara demonstrerade

  • Segmenteringshygien: gör segmenten du bearbetar “ känner dig koherent | ” | när du undersöker produkternas namn
  • Förklaringsförmågan till förslaget: visar mig varför
  • Kaldstart: om du löser datauppsättningen och återskapar den , beter systemet förutsägbart
  • Regressionstest: återskapa samma form av data och se till att dina ändringar inte bryter pris

Den viktiga subtiliteten : genom att generera både text och bilder, du kan validera hela produktupplevelsen , inte bara tillbaka

Vad' är nästa

Del 2: Sektionsprofiler , signaler M SK2 och segmentdefinitioner — där vi kopplar dessa data till arbetssegmentationen

Del 3 ( kommande ): utgångsmönsterna i utboxen M SK2 arbetslinjet , och transparenta gränssnittet


Generatorkod: Mostlylucid.SegmentCommerce.SampleData/

logo

© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.