创见博客
pSEO Workflow 评估
七崽爱吃小饼干2026/09/16阅读 0

你改了一版写作 Prompt。Review 通过率从 78% 涨到 91%,平均修复轮次从 2.1 降到 1.3,成本降了 15%。数据一片向好,你判定这是一次优化。

然后把新文章抽几篇给人看,反馈是:「读起来更平了,像是在填空。」

通过率上涨,是因为 Prompt 开始迎合那套 Review 规则,而不是文章变好。这就是 pSEO 工作流优化里最常见的陷阱:你优化的和你想优化的是两件事。

这篇文章给出一套端到端流程,目标是让每一次 workflow 改动都能产出一个可复现、可被反驳的结论:它到底是优化还是劣化。

一、先把「质量」拆成三层

不拆清楚,后面所有指标都会混在一起互相污染。

层级定义判定方式例子
工程可靠性能否稳定产出、失败能否定位代码/埋点,全自动job 成功率、失败阶段分布、Repair 轮次、解析失败率
合规质量是否符合硬性 SEO 规则代码,全自动meta 长度、focus keyword 覆盖、词数、H2 结构、禁用词
内容质量读者和搜索引擎是否认为有价值LLM judge + 人工校准信息增量、意图匹配、可读性、事实一致、原创性

前两层便宜、稳定、可以当门禁。第三层才是你真正想要的,也是最难测的。

关键判断:生产链路里的自动 Review 属于第二层,它不能用来评估第三层。 用它衡量质量等于自证——你优化的是「规则通过率」,代价往往是文章变得模板化。所以质量评估必须独立于生产用的那套 Review。

二、评估总架构

四个组件,缺一不可:

  1. 冻结评测集:固定的关键词列表,改动前后跑的是同一批。
  2. 冻结变量:除被测变量外,模型、temperature、竞品输入、Prompt 版本全部锁死。
  3. 版本化输出:每次产出按 workflow_version 落库,保留各阶段中间产物,而不是只存最终文章。
  4. 配对比较:同一关键词的新旧两版文章直接对比,而不是给各自打绝对分。

一个容易被忽略的点:要冻结数据采集阶段的输出。Ahrefs 数据和 SERP 每天都在变,如果不把竞品内容的快照固化下来,你测到的是「数据波动」而不是「workflow 改动」。正确做法是评测运行时直接读取已冻结的竞品 JSON,让被测改动只作用于写作、Review、内链这些下游阶段。

三、Phase 0 · 一次性搭建

整套流程只需要认真搭建一次。

Step 0.1 建评测集

从历史生产数据里筛 80 个关键词,按三个维度分层抽样:

  • 意图:信息型 / 商业型 / 交易型(比例大致 5:3:2)
  • 难度:Ahrefs KD 分桶 <20 / 20-50 / >50
  • 行业:至少覆盖 4 个不同垂类

划分为 60 个 golden、20 个 holdout。holdout 在调优期完全不看,防止你把评测集本身背下来。另外从历史失败案例里维护一个 regression 集合,初始 20 条,之后只增不减——这是防止「修一个坏一个」的唯一手段。

评测集本身也要版本化。加词、改标注都记 diff,否则某天你会不知道报告里的分数为什么变了。

判定:词表覆盖三档难度,且没有任何一个垂类占比超过 40%。

Step 0.2 冻结数据采集快照

这是整套流程能不能成立的关键。

对评测集里每个关键词,单独跑一次采集阶段(Ahrefs + 竞品抓取),把产物完整落库到 competitor_snapshot(JSON:matching terms、SERP URLs、竞品正文)。之后所有评测运行,直接读快照,跳过采集阶段。

只有当你专门要评估采集阶段的改动时才重建快照——那种情况下评测噪声大,需要多轮取多数。

判定:80 个关键词全部有非空快照,且竞品数 ≥3 的比例 100%。否则说明采集逻辑本身没达标,先修。

Step 0.3 生成 baseline

用当前线上 workflow 跑一遍评测集,产生 baseline 文章,打标签 baseline_version = 当前 workflow_version。落库 pseo_eval_run + pseo_eval_output,保留 stage_artifacts(写作产物、Review 结果、内链后正文、封面 URL)。

判定:baseline 的硬指标(成功率、平均轮次、成本)和线上监控对得上,误差 <5%。对不上说明评测环境有问题,先别往下走。

Step 0.4 锁定 judge 并做人工校准

选 judge 模型时要满足两点:比生成模型更强、且不同族——同族模型会偏爱自己的输出。记录 judge_model。

从 baseline 里抽 40 对文章,让人工盲评(不知道哪篇是哪个版本),再计算 judge 与人工的一致率。

判定:

  • 一致率 ≥ 80% → judge 可用,进入评测循环。
  • 一致率 70%~80% → 收紧 rubric 锚点、加 CoT 要求后重测。
  • < 70% → 换 judge 模型;仍不达标就说明这个维度目前只能靠人工,缩减自动评测范围。

产出:judge_v1(模型 + prompt + 一致率记录)。

四、Phase 1 · 每次改动的评测循环

整个循环由一次 workflow 变更触发,跑完大约 20~40 分钟。

Step 1.1 登记变更

打新版本号 workflow_version = v23,在变更记录里写清楚:改了什么、预期改善哪个指标、影响哪些阶段。

一次只改一个变量。改了写作 prompt 又顺手改了内链库,测出来分不清是谁的功劳。

Step 1.2 判定影响面,决定重跑范围

不同改动只需要重跑不同的下游阶段,复用冻结产物能大幅省成本:

改动位置需要重跑复用的冻结产物
采集阶段(Ahrefs/过滤)全部无(快照失效,需重建)
写作 Prompt / 模型写作→Review→内链→封面竞品快照
Review 规则 / judgeReview→Repair→内链→封面竞品快照 + 首次写作产物
内链库 / 插入算法内链→封面竞品快照 + 通过 Review 的正文
封面图封面全部上游
发布链路不跑内容评测,跑发布回归—

注:任何涉及采集、模型切换的改动,随机性大,评测集内每个关键词跑 3 次取多数,避免单次噪声。

Step 1.3 生成新版本产出

按影响面范围跑新版本,写入 pseo_eval_output,保留完整 stage_artifacts:每个阶段的输入输出、passed、msg、repair 轮次。

判定:run 状态 success 且覆盖率 100%。有 job 失败先看失败阶段分布,别急着看质量分。

Step 1.4 计算硬指标 diff

自动对比新旧 run:

指标门禁
job 成功率跌幅 >2pp → 拦
平均 Repair 轮次涨幅 >0.5 轮 → 警告
首次 JSON 解析成功率跌幅 >3pp → 拦
客观规则通过率任一规则跌幅 >3pp → 拦
每篇成本涨幅 >20% → 需质量显著提升才放行
P95 耗时涨幅 >30% → 警告

任一「拦」触发,直接进失败处置,不进入 judge。

Step 1.5 Judge 配对评测

对每个关键词,把 baseline(A)和新版(B)配对喂给 judge,跑两次:第一次 A=v22/B=v23,第二次 A=v23/B=v22(位置交换),用来消除位置偏差。

Rubric 的每个维度都要给出明确锚点,避免「整体感觉」这种无法对齐的口径:

维度权重1 分3 分5 分
信息增量25%与竞品重复部分新信息明显超出竞品
意图匹配20%答非所问基本回答正面且完整
事实一致20%存在编造/冲突基本无冲突可溯源、与竞品一致
可读性15%生硬模板化通顺节奏自然、有人味
结构规范10%结构混乱结构合理层次最优
语言质量10%语法错误多偶有小错干净准确

Judge Prompt 固定模板:

text
你是 SEO 内容评审。给定同一关键词下的两篇文章 A 和 B,以及参考竞品内容。
只依据提供的文本判断,不要引入外部知识。

对每个维度分别给 A、B 打 1/3/5 分,并引用原文片段作为证据,最后给出总胜者。

硬约束:
1. 先写 evidence,再写分数,最后写 winner。
2. evidence 必须是原文的逐字引用。
3. winner 输出 A / B / tie。

只输出 JSON:
{
  "dimensions": {
    "info_gain":   {"a": 1|3|5, "b": 1|3|5, "evidence": "..."},
    "intent_fit":  {...}, "fact_consistency": {...},
    "readability": {...}, "structure": {...}, "language": {...}
  },
  "weighted_score": {"a": 0.0, "b": 0.0},
  "winner": "A"|"B"|"tie",
  "reason": "..."
}

[竞品内容] {{competitor_snapshot}}
[文章A] {{article_a}}
[文章B] {{article_b}}

消偏手段:

  • 用两个不同族 judge,投票。
  • 两次位置交换结果不一致 → 该样本记为 tie 并进入人工队列。
  • 两个 judge 结果不一致 → 进人工队列。

事实一致是最难的一项。模型自己也会编,「事实正确」这句判断不可信。做法是单独开一条链路:把文章里的可验证陈述与竞品原文做检索/引用比对,能对上的算通过,对不上的进人工。

Step 1.6 聚合报告

把 pseo_eval_verdict 聚合成结论。核心指标是配对胜率,用二项检验判断显著性:

ts
const pairs = verdicts.filter(v => v.winner !== 'tie');
const wins = pairs.filter(v => v.winner === (v.position_swapped ? 'A' : 'B')).length;
const winRate = wins / pairs.length;
const p = binomialTest(wins, pairs.length, 0.5); // 单侧

报告要给结论,不要只给数字:

text
v23 vs v22  (n=80, 有效配对=71, 平局=9)
硬指标:  成功率 -0.0pp | 成本 +9% | 轮次 1.3 (↓0.8)
质量:    win_rate 62%  (p=0.02)  ← 显著
维度:    信息增量 +0.6 | 可读性 -0.2 | 事实一致 +0.0
结论:    采纳;可读性需关注

判定标准:

  • 有效配对 <30 → 样本不足,结论标「不显著」。
  • win_rate ≥ 0.55 且 p < 0.05 → 优化成立。
  • 0.45 ≤ win_rate ≤ 0.55 → 无显著差异。
  • win_rate ≤ 0.45 → 劣化。
  • 任一维度均分跌幅 >0.3 → 即使总体胜出也标警告。

Step 1.7 门禁判定

按顺序走:

text
硬指标有「拦」?          → 判失败,回滚
事实一致维度跌幅 >0.3?    → 判失败,回滚
win_rate ≤ 0.45?         → 判劣化,回滚
win_rate ∈ [0.45,0.55]?   → 判无差异,按成本/复杂度决定是否保留
win_rate ≥ 0.55 且显著?   → 判优化,进入人工抽检
成本涨 >20% 但质量显著?   → 需人工确认收益是否值这个成本

Step 1.8 人工抽检与校准

从 judge 判定结果里抽 10 条:包括所有分歧样本、所有平局、以及随机 5 条一致样本。人工盲评,对比 judge 结论。若抽检一致率 <80%,暂停自动门禁,先修 judge。

Step 1.9 归档与决策

  • 采纳:workflow_version 提升为 v23,baseline 更新。
  • 回滚:保留 run 记录用于分析,baseline 不变。
  • 无论哪种,pseo_eval_run / output / verdict 全部归档,stage_artifacts 不可删。

五、Phase 2 · 周期性校准

每月重跑人工校准,检查 judge 与人工的一致率是否仍 ≥80%,并确认 regression 集全部通过。

每季度把离线评测结论与线上指标(收录率、排名、CTR、停留时长)做对照。如果离线「优化」的版本线上表现平平,说明 rubric 权重偏了,调整权重并重新校准。

六、数据模型

沿用现有任务表体系,新增四张评测表,和生产数据隔离:

sql
-- 评测集定义
CREATE TABLE pseo_eval_set (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(128),
  keyword VARCHAR(255),
  intent VARCHAR(32),
  split ENUM('golden','holdout','regression'),
  competitor_snapshot JSON,   -- 冻结的竞品内容
  version INT,
  created_at DATETIME
);

-- 一次评测运行
CREATE TABLE pseo_eval_run (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  workflow_version VARCHAR(64),
  baseline_version VARCHAR(64),
  eval_set_version INT,
  status ENUM('running','success','failed'),
  created_at DATETIME
);

-- 每个关键词的产出与硬指标
CREATE TABLE pseo_eval_output (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  run_id BIGINT,
  keyword VARCHAR(255),
  article_json JSON,          -- 最终文章
  stage_artifacts JSON,       -- 各阶段中间产物,可 diff
  repair_rounds INT,
  first_parse_ok TINYINT,
  tokens INT,
  cost_usd DECIMAL(10,6),
  duration_ms INT
);

-- judge 结果
CREATE TABLE pseo_eval_verdict (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  run_id BIGINT,
  keyword VARCHAR(255),
  judge_model VARCHAR(64),
  position_swapped TINYINT,
  winner ENUM('A','B','tie'),
  dimensions JSON,
  reason TEXT,
  created_at DATETIME
);

stage_artifacts 是排查的核心:当质量掉了,你能直接定位是写作阶段还是内链阶段引入的,而不是对着一篇成品猜。

七、必须防的陷阱

  • Reward hacking:用 Review 通过率当质量=自己考自己。质量 judge 必须独立。
  • 数据采集漂移:不冻结竞品输入,测的就是噪声。
  • 随机性噪声:temperature 不为 0 时,单次对比的差异可能是丢硬币。要么固定随机性,要么每词多次取多数。
  • 过拟合评测集:没有 holdout,你会亲手把 Prompt 调成一本评测集答案。
  • judge 漂移:judge prompt 和 judge 模型版本都要锁,并定期与人工对齐。
  • 只看分数不看分布:均分没变,但方差变大、尾部变差,同样是劣化。

八、决策树速查

text
变更 → 打版本 → 确定影响面 → 生成新产出
  ├─ 硬指标回退 ─────────────→ 回滚
  ├─ 事实一致下降 ───────────→ 回滚
  └─ 通过硬指标 → judge 配对
       ├─ 胜率 ≤45% ─────────→ 回滚
       ├─ 胜率 45~55% ───────→ 无差异,按成本定
       └─ 胜率 ≥55% 且显著
            ├─ 人工抽检一致 ─→ 采纳
            └─ 抽检不一致 ───→ 修 judge,重评

结语

pSEO 工作流评估的本质,不是「找个人判断文章好不好」,而是把质量判断变成一套可重复、可证伪的实验流程:固定评测集、冻结变量、版本化产物、配对盲评、分层门禁,人工只负责校准 judge。

离线评测终究是代理指标,真正的 ground truth 在线上:收录率、排名、CTR、停留时长、转化。离线评测负责快速迭代,线上指标负责回测。

判断一次改动是否值得留,不该依赖感觉,而该依赖一个能复现、能被反驳的结论。让模型输出内容,让评测保证它真的在变好。

评论
0/100