# Μηδέν PII Customer Intelligence - Μέρος 1.1: Δημιουργία δεδομένων δειγμάτων (και Εικόνες) Τοπικά

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

Το [Μέρος 1](/blog/zero-pii-customer-intelligence-part1) καλύψαμε τη φιλοσοφία: διαφανής διαίρεση χωρίς PII. [Μέρος 2](/blog/zero-pii-customer-intelligence-part2) καλύπτει προφίλ συνεδριάσεων, σήματα και ορισμούς τμημάτων.

Αλλά πρώτα: **Πώς επικυρώνετε κάτι από αυτά χωρίς να αγγίζετε ποτέ πραγματικά δεδομένα πελατών;**

Για αυτή τη σειρά I δημιουργεί ένα πλήρες συνθετικό σύνολο δεδομένων ecommerce τοπικά:

- Κατάλογος προϊόντων (όνομα, περιγραφές, ετικέτες, τιμές)
- Ανώνυμοι προφίλ / personas (ενδιαφέροντα + σήματα)
- Εικόνες προϊόντων (και πορτρέτα προφίλ) μέσω ComfyUI
- Προαιρετική εισαγωγή DB ώστε η πραγματική εφαρμογή να μπορεί να τρέξει ενάντια σε αυτό

Αυτό είναι ένα από αυτά ?It αισθάνεται σαν εξαπάτηση ροή εργασίας: μπορείτε να πάρετε ρεαλιστικές εισροές, μπορείτε να τις αναγεννήσετε οποιαδήποτε στιγμή, και ποτέ δεν εισάγετε PII στο περιβάλλον dev σας.

## Γιατί τα τοπικά συνθετικά δεδομένα είναι τόσο ισχυρά

Εάν ανασυγκροτήσετε τον διαχωρισμό/την εξατομίκευση του κτιρίου, χρειάζεστε σύνολα δεδομένων που:

- Έχετε αρκετή παραλλαγή για να σπάσετε την αφελή ερεουριστική
- Είναι ασφαλές να μοιραστείτε (με κωδικό, δοκιμές, demo)
- Αναπαραγώγιμες (ώστε να μπορείτε να συγκρίνετε αλλαγές μοντέλου)

Τα πραγματικά δεδομένα είναι το αντίθετο: ευαίσθητα, ακατάστατα, δύσκολα να μετακινηθούν, και γεμάτα από ιστορικές προκαταλήψεις.

Τα συνθετικά δεδομένα σου δίνουν τρεις υπερδυνάμεις:

1. **Γρήγορη έλξη**: αλλαγή της λογικής διαίρεσης, αναγέννηση, επανάληψη.
2. **Σκλήρυνση**: προσομοιώστε περίεργες μακροχρόνιες συμπεριφορές που δεν θα δείτε σε ένα μικροσκοπικό dev σύνολο δεδομένων.
3. **Δοκιμή εξήγησης**: μπορείς *επιθεωρήστε κάθε παραγόμενο πεδίο* Και επιβεβαιώστε μου γιατί η UI είναι ειλικρινής.

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

## Το Εργαλείο (Τι Πραγματικά Λειτουργεί)

Η γεννήτρια ζει μέσα `Mostlylucid.SegmentCommerce.SampleData`.

Είναι ένα ρεαλιστικό CLI που μιλάει σε:

- **ΟλάμαCity name (optional, probably does not need a translation)** (τοπική LLM) για δομημένη γενιά JSON.
- **ComfyUI** (τοπική διασπορά στάβλου) για εικόνες φωτογραφικού τύπου προϊόντων.
- Α **ταξινομική JSON** που διατηρεί τις εξόδους συνεκτικές (κατηγορίες, τύποι, παραλλαγές, εύρος τιμών).

Η ρύθμιση είναι ενσύρματη ώστε να μπορείτε να την οδηγήσετε μέσω των μεταβλητών περιβάλλοντος:

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

## Γρήγορη εκκίνηση

Συνήθως θα εκτελέσετε τρεις τοπικές υπηρεσίες παράλληλα με τη γεννήτρια:

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

Εκτελέστε τη γεννήτρια από τη ρίζα repo:

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

Στη συνέχεια, δημιουργήστε ένα σύνολο δεδομένων:

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

Χρήσιμοι διακόπτες:

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

Σημείωση: εάν η ComfyUI δεν είναι διαθέσιμη, η γεννήτρια v1 επιστρέφει στις εικόνες των κατόχων (χρησιμοποιεί `picsum.photos`, έτσι ώστε το μονοπάτι αυτό δεν είναι εντελώς offline . Αν θέλετε αυστηρά-τοπικό, τρέχει με `--no-images`.

## v2 Γεννήτρια: Πωλητές → Προϊόντα → Πελάτες → Παραγγελίες → Παραγγελίες

Υπάρχει επίσης μια νεώτερη εντολή γεννήτριας (`gen`) piου δηιουργεί ια piιο ολοκληρωένη βάση δεδοένων τη αγορά:

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

Ενορχηστρώνεται ως πολυφασικός αγωγός:

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

Και μπορείτε να δείτε αυτές τις φάσεις απευθείας σε κώδικα:

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

### Ενσωμάτωση (τοπική ONNX, Cached μετά την πρώτη εκτέλεση)

Η γεννήτρια v2 μπορεί να υπολογίσει τις προσθήκες χρησιμοποιώντας ένα μοντέλο ONNX (προκαθορισμένο: `all-MiniLM-L6-v2`). Την πρώτη φορά που το τρέξετε, κατεβάζετε το μοντέλο και το φωνητικό στο φάκελο εξόδου σας.

Αυτό σημαίνει:

- Πρώτη εκτέλεση χρειάζεται πρόσβαση στο δίκτυο (model download)
- Οι επόμενες διαδρομές είναι τοπικές και γρήγορες
- Αν θέλεις ποτέ δίκτυο, τρέξε. `--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);
}
```

## Πώς δημιουργούμε τα προϊόντα Shoped-Shoped-JSON (Μόνο)

Η εντολή παραγωγής προϊόντων είναι σκόπιμα αυστηρή: η LLM πρέπει να επιστρέψει JSON μόνο, με ένα ενσωματωμένο παράδειγμα JSON schema.

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

Αυτό έχει σημασία επειδή τα κατάντη συστήματα (παραγωγή εικόνας + εισαγωγή + ενσωμάτωση) θέλουν δομημένα δεδομένα. *είσοδοι σε αγωγό*, δεν γράφω πεζογραφία.

### LLM Responses: Parse JSON, or Fall Back

Οι LLMs δεν είναι μεταγλωττιστές. Ακόμα και με τον Claude JSON μόνο έτσι, εξακολουθείτε να χρειάζεστε αμυντική ανάλυση και χαριτωμένη οπισθοδρόμηση.

Η γεννήτρια v2 το κάνει αυτό μέσω ενός μικρού βοηθού (`LlmService`) που αποσπά την πρώτη `{...}` μπλοκάρει και απενεργοποιεί:

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

Και ο συνολικός αγωγός παραγωγής ελέγχει ρητά τη διαθεσιμότητα και υποβαθμίζει τα καθοριστικά πρότυπα όταν χρειάζεται:

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

### Παράδειγμα: Πελάτης Personas (v2)

Η προτροπή persona για τους πελάτες είναι σύντομη και δομημένη έτσι ώστε να μπορεί να παραχθεί γρήγορα με ένα μικρό τοπικό μοντέλο:

```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: Φωτογραφία προϊόντων μέσω API

ComfyUI είναι μεγάλη, επειδή σας δίνει ένα ελεγχόμενο αγωγό (ροές εργασίας) και όχι ένα ενιαίο μαύρο κουτί τελικό σημείο εικόνας.

Η γεννήτρια:

1. Φόρτωση προτύπου ροής εργασίας (`ComfyUI/workflows/product_image.json`)
2. Επισυνάπτει την προτροπή `CLIPTextEncode`
3. Ακτίνες `/prompt`
4. Γρίφοι `/history/{promptId}`
5. Λήψη της εικόνας μέσω `/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
```

Η επιλογή μοντέλου ComfyUI επισυνάπτεται επίσης στη ροή εργασίας σε χρόνο λειτουργίας (ώστε να μπορείτε να ανταλλάξετε σημεία ελέγχου χωρίς επεξεργασία του 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");
```

Και το μπάλωμα της ροής εργασίας είναι επίτηδες απλό και στιβαρό:

```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;
    }
}
```

## Προφίλ και Personas (Χρήσιμα, όχι ανατριχιαστικά)

Η γεννήτρια v1 δημιουργεί ανώνυμα προφίλ και στη συνέχεια τα εμπλουτίζει με μια προσωπικότητα (ακόμα δεν PII). Καταλήγετε με ρεαλιστικά δεδομένα δοκιμών σε σχήμα ανθρώπων χωρίς email, διευθύνσεις, ή οτιδήποτε που θα μπορούσατε να στείλετε κατά λάθος.

Σε v1, τα προφίλ κλειδώνονται χρησιμοποιώντας ένα μονόδρομο χασίς, έτσι δεν υπάρχει τίποτα για να ανακαλυφθεί έτσι:

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

Αυτό είναι ακριβώς η νοοτροπία ολόκληρης της σειράς: μπορείτε να διαρρεύσει ό, τι δεν αποθηκεύσατε ποτέ.

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

## Επιβεβαίωση: Τι Σας Αφήνει να Αποδείξετε

Αυτός ο τοπικός αγωγός είναι ισχυρός επειδή υποστηρίζει *Επικύρωση μοντέλου*Όχι μόνο τα ντέμο.

- **Σωματικός διαχωρισμός**: έχουν συνοχή τα τμήματα που υπολογίζεις όταν επιθεωρείς τις ονομασίες/ταμπελάκια προϊόντων και τις παραγόμενες προσωπικότητες;
- **Εξηγησιμότητα σύστασης**: μου δείχνει γιατί το σημείο σε ένα πραγματικό σήμα που μπορείτε να επιβεβαιώσετε;
- **Κρύο ξεκίνημα**: εάν σκουπίζετε το σύνολο δεδομένων και αναγεννηθείτε, μήπως το σύστημα συμπεριφέρεται προβλέψιμα;
- **Δοκιμή οπισθοδρόμησης**: αναγεννήστε το ίδιο σχήμα των δεδομένων και να εξασφαλίσει τις αλλαγές σας dont σπάσει κατάταξη, βαθμολόγηση, ή UI.

Η σημαντική λεπτότητα: με την παραγωγή και των δύο *κείμενο* και το *εικόνες*, μπορείτε να επικυρώσετε ολόκληρη την εμπειρία του προϊόντος, όχι μόνο μαθηματικά back-end.

## Ποιο είναι το επόμενο;

**[Μέρος 2](/blog/zero-pii-customer-intelligence-part2)**: Προφίλ συνεδρίας, σήματα, και ορισμοί τμήματος p i ο υ p i ρ ο σ ω p i ε ί τα ι αυτό το δ ι κ α σ 1⁄4 ό 1⁄4 εν ο δ ο κ ι 1⁄4 έ ν ο ς 1⁄4 ε το p i ε ρ ί p i τ ω σ η .

**Μέρος 3** (Έρχεται): Εκθεσιακό μοτίβο, ουρά εργασίας, και η διαφάνεια UI.

---


*Κωδικός γεννήτριας: `Mostlylucid.SegmentCommerce.SampleData/`*