跳到主要内容
IM智引科技

研究 / 资源模板

产品事实层工具箱:结构模板、提示词与校验脚本

模块十四六篇正文的收口。正文只讲思路、不放长代码,所有实现件集中在这里——四份结构模板(YAML 版与 Airtable 版)、校验规则、三条提示词、三个脚本、中英术语表起步版、资产处理规范和三份检查清单。

BLKTECH 编辑部2026年8月6日16 分钟难度 实战免费YAMLNode.jsClaudeAirtable

工具箱含四份结构模板(产品事实/供应商/供货关系/证书,YAML 与 Airtable 两版)、一份校验规则、三条提示词(资料抽取/一致性对账/产品页生成)、三个确定性脚本(单位换算/发布前泄露自查/事实层与线上对账)、60 词工业泵中英术语表、资产处理规范和三份检查清单。最小可用集只需产品事实模板 + 抽取提示词 + 上新清单三件。

产品事实层工具箱:结构模板、提示词与校验脚本

这是模块十四的收口。前面六篇讲的是为什么这样想,这一篇是照着抄的东西

正文六篇一律不放长代码,所有实现件都收在这里。这样安排的好处是:你不认同某条思路可以不用对应的件,也不影响其它部分;反过来,你换成 Notion、Airtable 甚至 Excel,思路一样成立,只是把下面的 YAML 换成表格字段。

最小可用集:如果只想先跑起来,取三件就够——产品事实模板、抽取提示词、上新清单。


一、目录结构与密级边界

项目根/
├── src/data/facts/                 # ✅ 可公开,进构建
│   ├── products.yaml               #    产品事实(型号 / 参数 / 认证)
│   ├── certificates.yaml           #    证书(编号 / 机构 / 有效期)
│   └── glossary.yaml               #    中英术语表

├── internal/                       # ⛔ 绝不进构建,不进公开仓库
│   ├── suppliers.yaml              #    供应商档案
│   └── sourcing.yaml               #    供货关系(成本 / MOQ / 交期)

└── scripts/
    ├── convert-units.mjs           #    单位换算
    ├── check-leaks.mjs             #    发布前泄露自查
    └── reconcile.mjs               #    事实层 ↔ 线上对账

两条铁规矩:

  1. internal/ 加进 .gitignore(或放独立私有仓库)。src/ 下任何文件不得引用它
  2. internal/ 从第一天起就不进公开仓库。已经进过的话,改当前版本没用,历史里还在——只能重写历史或换仓库,并假设已泄露

为什么按目录分而不是按字段分:让“能不能公开”变成一个由文件位置就能回答的问题。理由见两种死法


二、模板一:产品事实(products.yaml)

每个数值型字段带值 + 单位 + 工况 + 出处 + 可信度五样,理由见什么才算一条产品事实

- id: CP-100-SS316          # 永不复用、永不修改
  model: "CP-100"
  variant: "SS316 casing"
  category: centrifugal     # 关联到品类维度
  slug: "cp-100-ss316"      # 可改,与 id 分离
  status: active            # active | eol | sample_only | planned
  eol_replacement: null     # status=eol 时填替代型号 id

  specs:
    - key: max_flow
      label: "Max Flow Rate"
      value: 120
      unit: "m3/h"
      condition: "2900 rpm, clean water, 20°C"   # 必填,数值型字段无此项不允许发布
      confidence: supplier_doc                   # verified | supplier_doc | verbal | estimated
      source:
        doc: "CP100-datasheet-v3.pdf"
        page: 2
        received: 2026-05-11

    - key: casing_material
      label: "Casing Material"
      value: "SS316"
      unit: null                                 # 非数值型,unit 与 condition 可为 null
      condition: null
      confidence: supplier_doc
      source: { doc: "CP100-datasheet-v3.pdf", page: 1, received: 2026-05-11 }

  certs: [CERT-CE-0031]
  images:
    - file: "centrifugal-pump-cp-100-ss316-front.webp"
      alt: "CP-100 SS316 centrifugal pump, front view"
      rights: supplier_granted_written           # 见第八节
  datasheet_public: "/downloads/cp-100-datasheet-en.pdf"
  updated_at: 2026-08-06

Airtable / Notion 版字段(同一套结构,换成表格):

字段
Products ID、Model、Variant、Category、Slug、Status、EOL Replacement、Updated At
Specs Product(关联)、Key、Label、Value、Unit、Condition、Confidence(单选)、Source Doc、Source Page、Received
Certificates Cert ID、Type、Number、Issuer、Issued、Expires、Scan File
Images Product(关联)、File、Alt、Rights(单选)

Specs 单独一张表是关键——一个产品有多条参数,每条都要带自己的工况和出处。塞进主表的多行文本里就没法校验也没法对账了。


三、模板二~四:证书、供应商、供货关系

certificates.yaml(可公开,但有效期要盯)

- id: CERT-CE-0031
  type: "CE"                    # CE | ATEX | UL | ISO9001 | NSF | FDA ...
  number: "CE-2024-88712"
  issuer: "TÜV SÜD"
  scope: "CP-100 series, EU Machinery Directive 2006/42/EC"
  issued: 2024-03-15
  expires: 2027-03-14           # 必填。到期前 60 天触发提醒
  scan: "internal/certs/ce-2024-88712.pdf"   # 扫描件放内部,页面只显示编号

internal/suppliers.yaml(⛔ 内部)

- id: SUP-0007
  name: "XX 泵业有限公司"
  location: "浙江温州"
  contact: { person: "王工", wechat: "...", email: "..." }
  qualifications: ["ISO 9001:2015", "ISO 14001"]
  capabilities: ["SS316 铸造", "双相钢铸造", "ISO 9906 Grade 2 水力测试"]
  payment_terms: "30% 定金 + 70% 见提单"
  notes: "打样快,批量交期不稳"       # 主观笔记,只在内部

capabilities 值得注意:厂名不能公开,但能力描述可以改写后公开——“我们对接的产线具备 SS316 与双相钢铸造能力”。这就是藏关系不藏能力的具体做法。

internal/sourcing.yaml(⛔ 内部,一个产品对多家)

- product: CP-100-SS316
  supplier: SUP-0007
  role: primary               # primary | backup | sampling
  cost: { amount: 3200, currency: CNY, ex_works: true }
  moq: 5
  lead_time_days: 25
  price_valid_until: 2026-09-30    # 必填。过期自动标为待更新
  updated_at: 2026-08-06

- product: CP-100-SS316
  supplier: SUP-0012
  role: backup
  cost: { amount: 3050, currency: CNY, ex_works: true }
  moq: 10
  lead_time_days: 30
  price_valid_until: 2026-08-31
  updated_at: 2026-07-20

备供和打样的字段可以留空——按角色的实际需要填,不要求每家都填满。


四、校验规则:让脏数据过不了构建

这是 AI 写入的护栏。放在 Astro 的内容配置旁,构建时自动跑;不用 Astro 的话,单独写个 validate.mjs 在提交前跑,效果一样。

// scripts/facts-schema.mjs
import { z } from 'zod';

const CONFIDENCE = ['verified', 'supplier_doc', 'verbal', 'estimated'];
const UNITS = ['m3/h', 'L/min', 'm', 'bar', 'kW', 'rpm', 'mm', '°C', 'cP', '%', null];

const source = z.object({
  doc: z.string().min(1),
  page: z.number().int().positive(),
  received: z.coerce.date(),
});

const spec = z.object({
  key: z.string().regex(/^[a-z0-9_]+$/),
  label: z.string().min(1),
  value: z.union([z.number(), z.string()]),
  unit: z.enum(UNITS).nullable(),
  condition: z.string().nullable(),
  confidence: z.enum(CONFIDENCE),
  source: source,
}).refine(
  // 规则一:数值型字段必须有工况
  (s) => typeof s.value !== 'number' || (s.condition && s.condition.length > 0),
  { message: '数值型参数必须填写 condition(工况条件)' }
).refine(
  // 规则二:数值型字段必须有单位(百分比与无量纲除外,用 '%' 或显式 null 声明)
  (s) => typeof s.value !== 'number' || s.unit !== undefined,
  { message: '数值型参数必须声明 unit' }
);

export const productSchema = z.object({
  id: z.string().regex(/^[A-Z0-9-]+$/),
  model: z.string().min(1),
  variant: z.string().nullable(),
  category: z.string().min(1),
  slug: z.string().regex(/^[a-z0-9-]+$/),
  status: z.enum(['active', 'eol', 'sample_only', 'planned']),
  eol_replacement: z.string().nullable(),
  specs: z.array(spec).min(1),
  certs: z.array(z.string()).default([]),
  images: z.array(z.object({
    file: z.string(),
    alt: z.string().min(10),          // 规则三:alt 不允许敷衍
    rights: z.enum(['own', 'supplier_granted_written', 'rendered']),
  })).default([]),
  updated_at: z.coerce.date(),
}).refine(
  // 规则四:停产必须指明替代型号(可以是品类,但不能空着)
  (p) => p.status !== 'eol' || !!p.eol_replacement,
  { message: 'status=eol 必须填 eol_replacement' }
);

四条规则各自防的事

规则 防的是
数值必须有工况 「120 m³/h」这种没有意义的数进入事实层
可信度是枚举 AI 随手填一个自由文本,导致措辞模板匹配不上
alt 至少 10 字符 批量生成时 alt 被填成 “product image”
停产必须有替代 下线时没有 301 目标,权重直接丢掉

还要单独跑一个悬空引用检查certs 里的每个 id 在 certificates.yaml 里存在、sourcing.yaml 里的 product / supplier 都存在、eol_replacement 指向的型号存在。


五、提示词一:资料抽取

用途:把供应商的 PDF / Excel / 微信截图变成结构化条目。核心是三条硬要求,理由见AI 的边界

你是产品资料录入助手。下面是供应商提供的原始资料。
把其中的产品事实抽取成 JSON,严格遵守以下规则:

【铁律,违反任何一条都算任务失败】
1. 只抽取原文中明确出现的值。禁止推测、禁止按同类产品补全、禁止取行业典型值。
2. 原文没有的字段,一律输出 null,并把字段名加入 missing 数组。
   输出 null 是正确行为,编一个合理的值是严重错误。
3. 每个值必须回填 source(文件名 + 页码)和 quote(原文片段,10-40 字,原样照抄)。
   无法给出 quote 的值,说明你不是抄来的 —— 把它改成 null。

【单位与换算】
- 单位原样保留,不要换算。换算由脚本完成。
- 原文单位不明确时,unit 填 null 并在 warnings 里说明。

【工况】
- 数值型参数必须找到对应的工况条件(转速 / 介质 / 温度等)。
- 原文没有交代工况的数值,condition 填 null,并加入 warnings。

【可信度】
- 正式规格书 / 检测报告 → supplier_doc
- 微信、邮件正文里的口头数字 → verbal
- 不要输出 verified(那需要我们自己实测)

输出 JSON:
{
  "product": { "model": "", "variant": "", "specs": [...] },
  "missing": ["字段名"],
  "warnings": ["说明"],
  "conflicts": []
}

【冲突】
若同一字段在资料中出现两个不同值,两个都放进 conflicts,不要自己选一个。

原始资料:
---
{{PASTE_SUPPLIER_DOC}}
---

配套的第二轮:审校者回查

抽完之后换一个角色再跑一遍,这一步能捞回相当一部分错误:

你现在是审校者,不是录入者。
下面是原始资料和一份已抽取的 JSON。逐字段核对,对每个字段输出:
- verified:JSON 的值与原文一致,并指出在原文哪一处
- mismatch:不一致,给出原文的正确值
- not_found:原文中找不到依据(这类字段必须改成 null)

不要润色、不要补全、不要评价资料质量。只做核对。

原始资料:{{DOC}}
待核对 JSON:{{JSON}}

六、提示词二:产品页生成(禁数字)

核心机制是占位符:模型只准输出 {{...}},不准输出数值,最后由脚本回填。

任务:为下面这个型号写一个英文产品页正文,面向欧美 B2B 工业买家。

【最重要的规则:禁止输出任何数字】
所有参数值、认证编号、日期、价格一律使用占位符,例如 {{max_flow}}、{{casing_material}}。
可用占位符清单如下,只能用这些:
{{AVAILABLE_PLACEHOLDERS}}

你输出的正文里如果出现任何具体数值(如 "120 m³/h"),本次任务作废。
需要提到某个数但清单里没有对应占位符时,改写句子避开它,并在末尾 notes 里说明。

【措辞受可信度约束】
- confidence=verified 的参数:可写 "delivers"、"tested at"
- confidence=supplier_doc 的参数:只能写 "rated at"、"per manufacturer specification"、"nominal"
- confidence=verbal / estimated 的参数:不会出现在占位符清单里,不要提及
本型号各参数的可信度:{{CONFIDENCE_MAP}}

【页面写作规格(来自关键词注册表)】
URL:{{URL}}
H1 与 Title 必须包含:{{PKW}}
H2 中自然出现:{{SKW}}
严禁出现的词:{{NKW}}

【要写的部分】
1. 开场段(80–120 词):这个型号解决什么问题,什么工况下选它
2. 为什么选它(100–150 词):从工程角度讲结构带来的实际好处
3. 典型应用(60–100 词):具体行业与场景,不要泛泛而谈
4. FAQ 三条:每条 ### 提问,第一句给结论。数值一律用占位符

【语气】
专业、直接、给工程师读。禁止 "world-class"、"leading"、"best quality" 这类空词。
美式英语。只输出正文,不要 frontmatter。

回填与校验(这一步是纯代码,不经模型):

// 回填占位符;任何未匹配的占位符都让流程失败
function fillPlaceholders(draft, specMap) {
  const missing = [];
  const filled = draft.replace(/\{\{(\w+)\}\}/g, (_, key) => {
    const spec = specMap[key];
    if (!spec) { missing.push(key); return `{{${key}}}`; }
    return spec.unit ? `${spec.value} ${spec.unit}` : `${spec.value}`;
  });
  if (missing.length) {
    throw new Error(`未匹配的占位符:${missing.join(', ')}`);
  }
  // 反向检查:正文里不该出现"裸数字 + 单位"的组合
  const leaked = filled.match(/\d+(\.\d+)?\s?(m3\/h|GPM|bar|PSI|kW|rpm)/g) || [];
  const expected = Object.values(specMap).map(s => `${s.value} ${s.unit}`);
  const suspicious = leaked.filter(x => !expected.includes(x));
  if (suspicious.length) {
    throw new Error(`正文出现来源不明的数值:${suspicious.join(', ')}`);
  }
  return filled;
}

最后那个反向检查是兜底:万一模型无视规则直接写了数字,这里会拦住。宁可构建失败,也不要发布一个来源不明的数字。


七、三个确定性脚本

7.1 单位换算

原则:有唯一正确答案的运算不交给模型

// scripts/convert-units.mjs
const FACTORS = {
  'm3/h→GPM': 4.40287,      'L/min→GPM': 0.264172,
  'm→ft': 3.28084,          'bar→PSI': 14.5038,
  'kW→HP': 1.34102,         'mm→in': 0.0393701,
};

export function convert(value, from, to, digits = 1) {
  if (from === '°C' && to === '°F') return +(value * 9 / 5 + 32).toFixed(digits);
  const f = FACTORS[`${from}→${to}`];
  if (!f) throw new Error(`未定义的换算:${from} → ${to}`);
  return +(value * f).toFixed(digits);
}

公制存原值,英制在生成页面时现算——不要把换算结果也存进事实层,否则改一个值要记得改两处,又回到分叉的老路。

7.2 发布前泄露自查

在最终产物里搜内部标识,命中就让发布失败。

// scripts/check-leaks.mjs
import { readdir, readFile } from 'fs/promises';
import { join } from 'path';
import yaml from 'js-yaml';

const DIST = 'dist';
const EXT = ['.html', '.js', '.json', '.xml', '.txt', '.css'];

// 黑名单从内部文件动态生成,避免手工维护
const suppliers = yaml.load(await readFile('internal/suppliers.yaml', 'utf8'));
const NEEDLES = [
  ...suppliers.map(s => s.name),
  ...suppliers.map(s => s.id),
  ...suppliers.flatMap(s => [s.location, s.contact?.email, s.contact?.wechat]),
  'ex_works', 'price_valid_until', 'lead_time_days', 'moq',
].filter(Boolean);

async function* walk(dir) {
  for (const e of await readdir(dir, { withFileTypes: true })) {
    const p = join(dir, e.name);
    if (e.isDirectory()) yield* walk(p);
    else if (EXT.some(x => e.name.endsWith(x))) yield p;
  }
}

const hits = [];
for await (const file of walk(DIST)) {
  const text = await readFile(file, 'utf8');
  for (const n of NEEDLES) if (text.includes(n)) hits.push({ file, needle: n });
}

if (hits.length) {
  console.error('❌ 构建产物中发现内部信息:');
  for (const h of hits) console.error(`   ${h.file} ← "${h.needle}"`);
  process.exit(1);
}
console.log(`✅ 已扫描构建产物,未发现内部信息(${NEEDLES.length} 个标识)`);

关键设计:黑名单从内部文件动态生成。新增一家供应商不需要记得来更新脚本——这就是不让正确行为依赖记性

放进构建流程:astro build && node scripts/check-leaks.mjs,并在 CI 里跑。

7.3 事实层 ↔ 线上对账

检出四种错配

// scripts/reconcile.mjs —— 输出报告,不自动改任何东西
const issues = [];

for (const p of products) {
  const page = pages.find(x => x.slug === p.slug);

  if (p.status === 'active' && !page)
    issues.push({ level: 'warn',  type: '漏发',     id: p.id });

  if (p.status === 'eol' && page && !page.hasNoticeAndRedirect)
    issues.push({ level: 'warn',  type: '该下线',   id: p.id });

  if (page) for (const s of p.specs) {
    if (!page.text.includes(`${s.value}`))
      issues.push({ level: 'error', type: '参数不一致', id: p.id, key: s.key });
  }

  for (const certId of p.certs) {
    const c = certs.find(x => x.id === certId);
    if (c && new Date(c.expires) < new Date() && page)
      issues.push({ level: 'error', type: '证书已过期仍在宣称', id: p.id, cert: certId });
    if (c && daysUntil(c.expires) < 60)
      issues.push({ level: 'warn',  type: '证书即将到期', id: p.id, cert: certId });
  }
}

「证书已过期仍在宣称」是唯一应该当天处理的一类。


八、中英术语表起步版

术语表属于事实层:未登记的词报错,不让模型临场翻译。下面是工业泵方向的起步版,换品类照这个格式替换即可。

# src/data/facts/glossary.yaml
# 结构类
离心泵:      { en: "centrifugal pump" }
磁力泵:      { en: "magnetic drive pump", alt_forbidden: ["magnetic pump"] }
齿轮泵:      { en: "gear pump" }
螺杆泵:      { en: "screw pump" }
自吸泵:      { en: "self-priming pump" }
潜水泵:      { en: "submersible pump" }
计量泵:      { en: "metering pump", alt_forbidden: ["dosing pump"] }
卧式:        { en: "horizontal" }
立式:        { en: "vertical" }
单级:        { en: "single-stage" }
多级:        { en: "multistage" }

# 部件类
机封:        { en: "mechanical seal", alt_forbidden: ["shaft seal", "sealing device"] }
填料密封:    { en: "packing seal" }
叶轮:        { en: "impeller" }
泵壳:        { en: "casing", alt_forbidden: ["pump shell", "housing"] }
:          { en: "shaft" }
联轴器:      { en: "coupling" }
底座:        { en: "base plate" }
口环:        { en: "wear ring" }

# 材质类
铸铁:        { en: "cast iron" }
不锈钢 304:  { en: "SS304", alt_forbidden: ["stainless steel 304", "SUS304"] }
不锈钢 316:  { en: "SS316", alt_forbidden: ["stainless steel 316", "SUS316"] }
双相钢:      { en: "duplex stainless steel" }
哈氏合金:    { en: "Hastelloy" }
氟塑料:      { en: "PVDF" }
碳化硅:      { en: "silicon carbide (SiC)" }

# 参数类
流量:        { en: "flow rate" }
扬程:        { en: "head" }
功率:        { en: "power" }
效率:        { en: "efficiency" }
转速:        { en: "rotational speed" }
汽蚀余量:    { en: "NPSH" }
黏度:        { en: "viscosity" }
介质温度:    { en: "media temperature" }
工作压力:    { en: "operating pressure" }
防护等级:    { en: "IP rating" }
绝缘等级:    { en: "insulation class" }
能效等级:    { en: "IE efficiency class" }

# 标准与认证
出厂测试:    { en: "factory acceptance test (FAT)" }
水力性能测试: { en: "hydraulic performance test per ISO 9906" }
防爆:        { en: "explosion-proof (ATEX)" }
食品级:      { en: "food-grade" }
卫生级:      { en: "sanitary / hygienic design" }

alt_forbidden 是明确禁用的其它译法。同一个概念只允许一种英文写法——理由不是文风统一,是避免把一个词的信号拆成三份弱信号


九、资产处理规范

图片

文件名品类-型号-变体-视图.webp

✅ centrifugal-pump-cp-100-ss316-front.webp
❌ IMG_20260511_143022.webp
❌ 温州XX泵业-CP100.webp        ← 文件名里带厂名,等于泄露

处理顺序:重命名 → 转 WebP 压缩 → 生成多尺寸 → 清除 EXIF → 写 alt

清 EXIF 不能跳过:供应商拍的照片里可能带 GPS 位置。一行命令的事:

exiftool -all= -overwrite_original *.webp

alt 写法:型号 + 关键特征 + 视图,一句话讲清画面。不堆关键词。

✅ alt="CP-100 SS316 centrifugal pump, front view showing suction flange"
❌ alt="pump, centrifugal pump, stainless steel pump, industrial pump China"

授权rights 字段的三个值):

含义 能不能用
own 自己拍的 / 自己渲染的 ✅ 随便用
supplier_granted_written 供应商书面确认可用 ✅ 可用,保留确认记录
rendered 按尺寸图自己做的 3D / 线稿 ✅ 可用

不在这三类里的图,不进事实层。去掉别家的水印不等于取得授权,只是让侵权变得不明显。拿授权其实很简单,微信问一句“这些图我可以用在自己网站上吗,麻烦回复确认一下”,截图存档。

规格书 PDF

内外两版:

版本 内容 位置
内部版 供应商原件,带 logo 与工厂信息 internal/datasheets/
公开版 去掉供应商 logo 与工厂信息,换成自己的 public/downloads/

公开版记得改 PDF 属性里的作者字段——原件的属性里常常直接写着工厂名,这是最容易漏的一条泄露路径。

exiftool -Author="Your Company" -Creator="Your Company" -Producer= cp-100-datasheet-en.pdf

留邮箱换 PDF 的话,接询盘表单那套流程即可。


十、三份清单

10.1 新产品上新清单

【入库】
□ 供应商资料齐全(规格书 / 图片 / 认证扫描件)
□ 图片与规格书的使用授权已书面确认
□ 跑抽取提示词 → 得到 JSON + missing + warnings + conflicts
□ 跑审校者回查 → mismatch 与 not_found 全部处理
□ 每个数值型参数有工况条件
□ 每个值有出处(文件名 + 页码 + 日期)
□ 可信度按实际来源标注,没有伪造 verified
□ conflicts 已人工裁决(或拆成两个型号)

【关键词登记】← 最容易跳过,跳过就等着自己抢自己
□ 主关键词已在注册表登记,无归属冲突
□ URL 已确定且未与已有页面重复
□ 负面边界词已列出

【发布】
□ 校验通过(schema + 悬空引用)
□ 页面正文无来源不明的数值(回填反向检查通过)
□ 措辞与可信度匹配(supplier_doc 没写成 delivers)
□ 图片已重命名 / 压缩 / 清 EXIF / 写 alt
□ 规格书公开版已去除供应商信息、改过 PDF 属性
□ 内链回品类页 + 相关场景页
□ 结构化数据已生成
□ 泄露自查脚本通过

10.2 维护日历(按腐烂速度排,不做每月全量)

触发条件 动作
证书到期前 60 天 找供应商要新证书;到期日当天页面上的宣称必须撤下
报价有效期到 标为待更新;未更新前不对外报价
供应商发来新版规格书 按出处字段定位受影响的参数,重新抽取核对
每季度 问主供一次:还在产吗、参数有变吗
每季度 跑一次完整对账,处理四类错配
供应商通知停产 走下线流程(下面这份)

10.3 停产下线清单

□ 事实层里 status 改为 eol,填上 eol_replacement
□ 页面加停产标注(别让客户询价之后才知道)
□ 页面上给出替代型号并链接过去
□ 配置 301 → 替代型号页;无替代则跳品类页
□ 从 sitemap 移除(但页面本身保留)
□ 检查站内还有哪些页面链向它,改成指向替代型号
□ 不要删除页面,不要删除事实层记录

最后两条是重点:页面积累的排名和外链是资产,记录删了就再也检不出“站上有页面但产品已不存在”这类错配。


十一、怎么开始

不要一次全建。按这个顺序,每一步都能单独产生价值:

步骤 做什么 产出
1 3 个主力型号,按模板一填完整(含工况、出处、可信度) 你会立刻发现有多少参数其实来源不明
2 跑一遍抽取提示词处理下一个新型号 验证流程能不能省时间
3 加上校验规则 从此脏数据进不来
4 把内部数据挪进 internal/,接上泄露自查 关掉最贵的那个风险
5 接上页面生成(占位符 + 回填) 上新从半天变成十分钟
6 接上对账脚本与维护日历 半年后它还准

第 1 步就有价值,哪怕后面几步一直没做。因为那三个型号会告诉你一件事:你现在对外发布的参数里,有多少是你其实说不清来源的。


十二、扩展:真实问题挖掘(配合第 72 篇)

事实层解决“页面上的数字从哪来”,这一节解决“除了数字还该写什么”。用法见从 Reddit 挖真实用户问题

12.1 聚类提示词

下面是一批来自技术论坛 / 客户询盘的原始提问文本。
你的任务是归纳提问,不是解答。

【绝对禁止】
- 不要回答任何技术问题
- 不要判断某个说法对不对
- 不要改写成营销文案
任何技术结论一律放进 to_verify,不要给出答案。

【输出 JSON】
{
  "clusters": [
    {
      "topic": "用一句话概括这一类在纠结什么",
      "type": "terminology | question | tradeoff | complaint",
      "frequency": 出现次数,
      "sources": ["来源标识"],
      "raw_phrasings": ["原文照抄的片段,保留他们的用词"],
      "their_terms": ["他们使用的术语,标出和我们说法不同的"],
      "implied_conditions": ["提问中隐含的工况,全部视为待核实"],
      "classification_confidence": "high | low"
    }
  ],
  "to_verify": [
    { "claim": "论坛里出现的技术说法", "source": "哪来的", "how_to_verify": "该问谁 / 查哪个标准" }
  ]
}

【四分法定义】
terminology:只是叫法不同 → 改术语表,不产出内容
question:有明确答案、答完即止
tradeoff:没有唯一答案,取决于工况取舍(最有价值)
complaint:踩坑、被坑、验货问题

拿不准是 question 还是 tradeoff 的,classification_confidence 填 low。

原始文本:
---
{{PASTE_RAW_POSTS}}
---

12.2 四分法归类与去处对照

type 去处 产出内容?
terminology glossary.yaml,全站替换 ❌ 不产出
question 型号页 FAQ 模块 ✅ 一问一答
tradeoff 独立技术资源页 ✅ 有立场的对比
complaint 选型陷阱 / 验货要点 / 信任页 ✅ 清单式

12.3 待观察清单(频次未达门槛)

# content-queue/observing.yaml
# 门槛:独立来源 ≥ 3 才进写作队列
- topic: "磁力泵在含固介质里的轴承寿命"
  type: tradeoff
  frequency: 2
  sources: ["reddit:r/AskEngineers", "inquiry:2026-06-18"]
  first_seen: 2026-06-18
  status: observing        # observing | queued | written | dropped
  note: "再出现一次就写"

status: dropped 是必须保留的一个值——明确判断为个例并放弃,比让它永远挂在待办里好。

12.4 待核实清单

论坛说法进不了事实层,只能进这里(理由见什么才算一条产品事实):

# content-queue/to-verify.yaml
- claim: "CP-100 介质温度上限 120°C"
  confidence: verbal            # 论坛陌生人说的,最低档
  source: "reddit:r/AskEngineers, 2026-07-02"
  how_to_verify:
    - 向主供索取温度-材质对应表
    - 查密封件材质标准耐温
  status: open                  # open | verified | rejected
  resolved_value: null          # 核实后填入,然后才允许进 products.yaml

只有 status: verified 的条目才能变成事实层里的一条参数,并且要按正常规则带上工况、可信度和出处。

12.5 效果验证记录

三个信号,手工记就够(做法见第 72 篇):

□ GSC 该页面是否出现未登记过的长尾 query?(写完 2–6 周后看)
□ 把原始问题丢进 ChatGPT / Perplexity,是否引用本站?(记日期与结果)
□ 是否收到引用了本页内容的询盘?(最强信号,人工留意)

第二个信号后来有了正式做法:固定问题集 + 固定引擎 + 季度频率,结果回写进注册表。见GEO 审计升级


十三、对外接口:fact_refs

事实层不只被页面模板读,还被GEO 意图注册表读。那张表里每条对外答案都要声明自己用了哪些事实:

# GEO 意图注册表中的一条
id: Q-017
canonical_answer: "The CP-100 handles fluids up to 80°C continuously,
                   or 95°C intermittently with PTFE-lined bearings."
fact_refs:
  - cp-100.temp_max_continuous
  - cp-100.temp_max_intermittent

引用格式就是点号路径<product_id>.<field>,工况变体加后缀(temp_max_continuous)。不需要新增字段,事实层的现有结构直接当地址空间用。

这条引用关系换来三件事:

能力 没有 fact_refs 时怎么做 有了之后
供应商换版后的影响面 靠记性翻页面 查一次:哪些答案引了这个字段
数字一致性对账 人工核对 脚本扫全站答案 × 事实层,不一致即 error
过期传导 事实层标了过期,页面照旧 过期字段的所有下游答案一起标红

校验规则加一条fact_refs 里的路径必须在事实层存在,悬空即报错。这和第四节里“参数必须有出处”是同一类检查——只是方向相反,那条查上游,这条查下游。

反过来的约束也成立:答案里出现的每个数字都必须有对应的 fact_refs。没有的话,说明这个数字是模型编的,或者是从某封邮件里抄来但从未登记的——两种都是第 68 篇划的红线。

对账脚本在GEO 意图注册表工具箱,它复用本篇 7.x 节的事实层加载逻辑,不重复实现。


相关文章

模块十四(思路)

模块十五(内容素材来源)

上下游

NEXT ACTION / 下一步

继续系列:AI 外贸站建设全系列

把读到的方法变成一个小行动,完成后再回来迭代。

继续

RELATED / 相关推荐

接着读这些

按同一分类、系列与标签为你挑选。