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

<!--category-- Product, Privacy, LLM, ComfyUI, C# -->
<datetime class="hidden">2025-12-31T20:00</datetime>

I [Del 1](/blog/zero-pii-customer-intelligence-part1) vi täckte filosofin:", transparent segmentation utan PII, . [Del 2](/blog/zero-pii-customer-intelligence-part2) 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

```mermaid
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:

```csharp
// 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.

```mermaid
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:

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

Sedan generera en datauppsättning:

```bash
# 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:

```bash
# 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

```bash
# 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.

```mermaid
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:

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

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

```csharp
// 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:

```csharp
// 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:

```mermaid
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:

```csharp
// 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?...`

```mermaid
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

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

```csharp
// 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 ’

```csharp
// 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.

```mermaid
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](/blog/zero-pii-customer-intelligence-part2)**: 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/`*