# 零 PII 客户情报@-部分 @1.1: 生成样本数据\(和图像=)本地

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

内 [部分#1](/blog/zero-pii-customer-intelligence-part1) 我们覆盖了哲学 : 透明分割,没有 PII . [部分#2](/blog/zero-pii-customer-intelligence-part2) 会话剖析档@, 信号 @, 和段定义_.

但首先 : **如何验证这些内容而不触及真实的客户数据?**

为本系列,我制作了一个完整的合成电子商务数据集 本地=:

- 产品目录 @( @%names@,}描述,}标签 @MS K3}价格_)}
- 匿名@“ @professions_”} @/ @personas @(#兴趣$+#信号>)
- 通过 ComfyUI 制作产品图像 @(\和配置文件肖像@)
- 可选 DB 导入DB , 这样真应用程序就可以运行在它上

这是其中一种““ ” , 它感觉就像作弊一样 “” 工作流程 @ : 你得到现实的输入@, 你可以随时重生它们, 并且你从不将 PII 引入您的 dev 环境 #%.}

## 为什么本地合成数据如此强大

如果您是’re 正在建构分隔区块 @/个性化@,你需要数据集, 该数据集=:

- 有足够的变异来打破天真的经济主义
- 是否安全共享 {(} in code\ ,} 测试@,\ 演示})} *
- 可复制 {(} 。 这样您就可以比较模型更改@ )} @

真实数据是反面的::@敏感 @,}乱七八糟#,}很难移动,充满历史偏见_.

合成数据为您提供三个超级功率:

1. **快速迭代**: 更改分隔逻辑, regenerate @, reMS K3run}.
2. **硬化**“:”模拟怪异的长篇作风“-”和“tail 行为”,您在微小的数据元件中看到的是“MS K2”
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
```

## 工具 # ( @ what Factually runs\ MS K1}#

发电机在 `Mostlylucid.SegmentCommerce.SampleData`.

它不是故意的,它是一个务实的CLI 和:交谈。

- **奥拉马** JSON 结构化的JSON一代的(当地LLM)
- **comfyUI** ( @当地稳定传播@)}产品摄影的-#System图像 @.
- AA **杰森(JSON)** 保持输出一致性@(_categories,}类型 @,}变体{,}价格范围=).}

配置被连接起来, 这样您就可以通过环境变量驱动@ : @ {}

```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 root 运行生成器@: @%

```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 是 @’}% t可提供 ,}v1}生成器返回到占位符图像@(}使用 `picsum.photos`,}( 所以路径不是@ MS K1 @ title 离线@ I”).) 如果您想要严格使用% k3 @ local_ , 运行 `--no-images`.

## v2Q 发电机 :QSellers @→Q 产品 *→Q 客户@→Q 命令 @MS K5Q 嵌入式

这里还有一个新的发电机指令 @ (@`gen`建立更完整的 “ smarkedplace @-\smagic@”}数据元件_:}

```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, 第一次运行后被封存

v2}生成器可以用 ONNX 模型来计算嵌入@ (_ default @ MS K2}{ `all-MiniLM-L6-v2`). 第一次运行时, 它将模型和 vocab 下载到输出文件夹@.

意思是:

- 首运行需要网络访问@(_#模型下载 @)}%
- 随后是当地快速的本地运行
- 如果您想要 @ “no 网络, 请运行\ MS K1 `--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);
}
```

## 我们如何生成““LLM”和“MS K1 共享”、“””产品 “( @Json only)}

产品生成的及时性是刻意严格地“:”LLM必须用一个嵌入 JSON schema example@.将JSON只返回 JSonson @,。

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

这一点很重要,因为下游系统 @(#image generation {+} 导入+} 嵌入MS K2)}想要结构化数据 *.}LLM正在生产 *管道投入*@, @% 没有写稿@ .}

### LLM 响应=: 分析 JSON,或后退

LLMs不是编译者 . 即使有 @“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
```

### 例如::-客户人 @(_v2)_@

对顾客的提示是短短和结构化的,因此可以使用小型本地型号“:”快速生成。

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

## 通过 API 拍摄产品照片

comfyUI 是很棒的, 因为它给了您一个可控管道 @ ( workflows@ MS K1, 而不是 @ I“ single Blackbox 图像端点@ MPK3}

产生器=:}

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

## 配置和人称 @(_usedful@,}不是克里皮・)

V1 生成器创建匿名配置文件, 然后用个人来丰富它们。 @ (} chill no PII}).}你最终会得到现实的@“}{properation*-}{fid{”}测试数据 而没有电子邮件>,}地址<,}或任何您可能无意中发运的东西〞.}

在 v1,} 剖析档使用一个密钥键 。 @ -_ way hash_ MS K2} 因此, ’} 对 MSC4_ recover@”:}没有问题

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

{\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}这和整个系列的心态完全一样...

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

## 校验@: @ what this 让您证明

这条本地管道很强大,因为它支持 *模式验证*不只是演示而已

- **分解正常度**: 在检查产品名称时, 您计算 & “ feeel @ MS K2 一致性的区段@ / tags and produced personas @ MPK4}
- **建议解释可解释性**@:}“ 告訴我為什麼”會指向一個真正的信號,
- **寒冷开始**: 如果你擦去数据元件和再生 ,是否系统的行为可以预测?
- **回归测试**: 重新生成同一种数据形状并确保您的更改 Don @’t 折叠排序@, 评分{,} 或UI.

重要的细微的\:通过产生 *文本文字* 和 *图像图象*, 您可以验证整个产品体验 *% 1} 不只是备份@-end Maths.*

## 下一步是什么?

**[部分#2](/blog/zero-pii-customer-intelligence-part2)**“:”会话简介“,”信号“MS K2”和段定义“MSC3” 我们将样本数据输入工作区块“.”

**部分#3** @(_coming):_Outbox stands\ ,}工作队列@,}和透明性UIQ.{

---


*发电机代码@: @% `Mostlylucid.SegmentCommerce.SampleData/`*