零 PII 客户情报 -- -- 第1.1部分:在当地生成抽样数据(和图像) (中文 (Chinese Simplified))

零 PII 客户情报 -- -- 第1.1部分:在当地生成抽样数据(和图像)

Wednesday, 24 December 2025

//

6 minute read

第一部分 第一部分 我们覆盖了这个理念:透明分割,没有PII。 第二部分 第二部分 会议概况、信号和段段定义。

但首先: 你如何在不触及真正的客户数据的情况下 验证这一切?

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

  • 产品目录(名称、说明、标签、价格)
  • 匿名“简讯”/个人(利益+信号)
  • 通过ComfyUI 的产品图像( 和配置文件肖像)
  • 可选 DB 导入 DB , 使真应用程序能够与它对着运行

这是那些“感觉像作弊”的工作流程之一:你得到现实的投入,你可以随时再生它们,你从来没有将 PII 引入到您的 Dev 环境中。

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

如果您正在构建分区/个性化,您需要以下数据集:

  • 有足够的变异 足以打破天真的经济主义
  • 安全共享( 在代码、 测试、 演示中)
  • 是可以复制的( 这样您就可以比较模式变化)

真实数据正好相反:敏感、混乱、难以移动、充满历史偏见。

合成数据给了你三个超能力:

  1. 快速迭代:改变分割逻辑,再生,再运行。
  2. 硬化模拟在微小的德维数据集中看不到的奇怪的长尾行为。
  3. 可解释性测试:你可以 检查每个生成的字段 并证实你所说的“你告诉我为什么”是真实的。
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,它谈论:

  • 奥拉马 (当地LLM)用于结构化的JSON一代。
  • comfyUI comfyUI 合成界面 (当地稳定传播)用于产品摄影式图像。
  • A A A 杰森(JSON) 保持产出的一致性(类别、类型、变式、价格幅度)。

将配置连接起来, 以便您可以通过环境变量驱动 :

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

快速启动

你通常会经营三个本地服务,

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 运行生成器 :

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

然后生成数据集 :

# 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

有用开关 :

# 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,这样这条路径就不会“完全离线 ” 。如果您想要严格本地的路径,请使用 --no-images.

v2 发电机:销售商 产品 客户 订单 嵌入器

也有一个更新的发电机指令(gen建立更完整的“市场型”数据集:

# 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

由多阶段管道组成:

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

你可以直接从代码中看到这些阶段:

// 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 模型计算嵌入( 默认 : all-MiniLM-L6-v2)第一次运行时,它会将模型和 vocab 下载到输出文件夹中。

这意味着:

  • 首运行需要网络接入(模型下载)
  • 随后的运行是当地快速的本地运行
  • 如果您想要“永远没有网络”,请运行 --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);
}

我们如何生成“LLM-Shaped”产品(仅JSON)

产品生成的及时性是刻意严格的:LLM必须只归还JSON, 并附有一个嵌入的JSON计划的例子。

// 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 响应: 分析 JSON, 或后退

LLMs不是编译者,即使只有JSON(JSON),你仍然需要防守和优雅的后退。

V2 生成器通过一个小助手(小助手)这样做(小助手)LlmService提取第一个 {...} 块, 并使它分流 :

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

以及整个发电管道 明确检查是否提供 和下调到确定性模板 必要时:

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)

对顾客的提示是简短和结构化的,因此可以用一个小的当地模式迅速生成:

// 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. 装入工作流程模板( W)ComfyUI/workflows/product_image.json)
  2. 将快速补补到 CLIPTextEncode
  3. 队列 /prompt
  4. 彩票 /history/{promptId}
  5. 下载图像通过 /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

ComfyUI 模式选择也被补入运行时的工作流程(这样您就可以在不编辑 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");

工作流程的补丁是故意简单和稳健的:

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

概况和人(有用、不可怕)

V1 生成器创建了匿名配置文件,然后用个人( 仍然没有 PII ) 来丰富它们。 最后,你得到了现实的“ 人形” 测试数据,而没有电子邮件、 地址或任何您可以不小心发送的东西。

在 v1 中, 剖面图使用单向散列键键, 所以没有什么可以“ 恢复” :

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

这正是整个系列的心态:你不能泄露你从未储存的东西。

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

校验:让您证明的是什么

这条本地管道很强大 因为它支撑着 模式验证不仅仅是演示

  • 分解正常度:在检查产品名称/标签和产品生成者时,您计算“感觉”的分节是否一致?
  • 建议解释可解释性:“告诉我为什么”是否指向一个你可以核实的真正信号?
  • 寒冷开始:如果删除数据集和再生,系统是否可预见地运行?
  • 回归测试:重新生成相同的数据形状,确保您的更改不会打破排名、评分或UI。

重要的微妙之处在于:通过产生 文字文字文字文字图像图像图像,您可以验证整个产品经验, 而不仅仅是后端数学。

下一个是什么

**第二部分 第二部分**会议概况、信号和段段定义——我们将这些抽样数据连接成工作区块。

第三部分 第三部分 发件箱模式、工作排队和透明化界面。


发电机代码 : Mostlylucid.SegmentCommerce.SampleData/

Finding related posts...
logo

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