fix(pipeline): scope comment-evidence rules to COMMENT_GROUPS only

Revert duplicate-opening and benefit-claim constraints from matrix, scenario, price, promo, §8.5 report, and strategy prompts. Strengthen COMMENT_GROUPS_SYSTEM: comment-only sourcing, no keyword boilerplate as user voice, varied openings, evidence-anchored benefits.

Made-with: Cursor
This commit is contained in:
hub-gif 2026-04-15 17:42:51 +08:00
parent 6280e436d8
commit b5012a366e

View File

@ -46,6 +46,7 @@ REPORT_SYSTEM = """你是业务与产品读者顾问。输入 JSON 含 `keyword`
所有数字占比条数品牌名价格区间等**必须严格来自输入 JSON**禁止编造未在输入中出现的定量结论 所有数字占比条数品牌名价格区间等**必须严格来自输入 JSON**禁止编造未在输入中出现的定量结论
**硬性禁止** **硬性禁止**
- 正文中****第九章策略与机会等与宿主文档已有标题**重复**的章名小节名或起首套话本段小节仅用 ``####`` 业务主题;
- **不要**使用## 一」「## 八」等会打乱宿主文档的顶级章节号;请使用 ``####`` 或必要时 ``###`` 作为本段内小节标题; - **不要**使用## 一」「## 八」等会打乱宿主文档的顶级章节号;请使用 ``####`` 或必要时 ``###`` 作为本段内小节标题;
- **不要**输出完整报告目录或复述研究范围与方法长章 - **不要**输出完整报告目录或复述研究范围与方法长章
- **不要**撰写 Markdown 表格版竞品对比矩阵或罗列 SKU 明细**正文已含矩阵**此处只做分组级语义归纳 - **不要**撰写 Markdown 表格版竞品对比矩阵或罗列 SKU 明细**正文已含矩阵**此处只做分组级语义归纳
@ -53,13 +54,13 @@ REPORT_SYSTEM = """你是业务与产品读者顾问。输入 JSON 含 `keyword`
**请输出**仅输出将置于 §8.5 下的正文不要自造### 8.5」标题行): **请输出**仅输出将置于 §8.5 下的正文不要自造### 8.5」标题行):
- **Markdown** **8001500 ** - **Markdown** **8001500 **
- 建议用 ``####`` 组织:**执行摘要级要点**、**竞争与价盘**、**用户声量与负向事由**(须归纳用户在抱怨什么类型的问题,而非只堆关键词)、**与第九章衔接的策略边界** - 建议用 ``####`` 组织:**执行摘要级要点**、**竞争与价盘**、**用户声量与负向事由**(须归纳用户在抱怨什么类型的问题,而非只堆关键词)、**后续可验证动作(假设)**(不写第九章目录或重复策略章内容)
- 若有 `comment_sentiment_lexicon`概括正/负向粗判局限**负向**写清事由类型口感价格物流等 - 若有 `comment_sentiment_lexicon`概括正/负向粗判局限**负向**写清事由类型口感价格物流等
- **归因与引语硬性**`consumer_feedback_by_matrix_group` `comment_sentiment_lexicon` 等均为** SKU/跨店铺的关键词子串或条数统计****不能**单独据此推断某一店铺某一单品的结论 - **归因与引语硬性**`consumer_feedback_by_matrix_group` `comment_sentiment_lexicon` 等均为** SKU/跨店铺的关键词子串或条数统计****不能**单独据此推断某一店铺某一单品的结论
- **具体体验句式含口感包装等**须以正文 **§8.2** 中带 ``细类SKU品名店铺`` 前缀的抽样为准本段**不要**新增无前缀无店铺/品名/SKU 指向的引语 - **具体体验句式含口感包装等**须以正文 **§8.2** 中带 ``细类SKU品名店铺`` 前缀的抽样为准本段**不要**新增无前缀无店铺/品名/SKU 指向的引语
- 若写口感包装物流价格等**聚合**维度须点明口径在已合并的评价文本中物流价格类关键词命中较多为全样本子串计数可结合 `matrix_overview_for_llm` 谈细类结构**可一句**引导读者 §8.2 按店铺/品名的负向举例 - 若写口感包装物流价格等**聚合**维度须点明口径在已合并的评价文本中物流价格类关键词命中较多为全样本子串计数可结合 `matrix_overview_for_llm` 谈细类结构**可一句**引导读者 §8.2 按店铺/品名的负向举例
- §8.2 已归纳带店铺与 SKU 的负向主题本段**只做执行摘要级收束**勿重复编造新引文 - §8.2 已归纳带店铺与 SKU 的负向主题本段**只做执行摘要级收束**勿重复编造新引文
- 语气专业中文缺失项写本段未提供该项而非猜测""" - 语气专业中文某类信息在输入中缺失时**一句带过数据缺口**即可**禁止**输出本段未提供该项等套话占位"""
REPORT_USER_PREFIX = """请根据以下 JSON 撰写上文所述 §8.5 嵌入段落Markdown 正文,勿加 ### 8.5 标题)。\n\n""" REPORT_USER_PREFIX = """请根据以下 JSON 撰写上文所述 §8.5 嵌入段落Markdown 正文,勿加 ### 8.5 标题)。\n\n"""
@ -365,6 +366,7 @@ COMMENT_GROUPS_SYSTEM = """你是用户研究与品类顾问。输入为 JSON
**为每个细类**输出一小段 Markdown全部 groups 都要写顺序与输入一致 **为每个细类**输出一小段 Markdown全部 groups 都要写顺序与输入一致
- ``#### `` + 与该 group 字段**完全一致**的细类名作为小节标题(不要使用 ``##`` 一级标题); - ``#### `` + 与该 group 字段**完全一致**的细类名作为小节标题(不要使用 ``##`` 一级标题);
- 每段约 **100220 **中文归纳该细类下**消费者在讨论什么**口感价格物流功效疑虑等**关注词命中反映的诉求**勿编造摘录中未出现的品牌医学结论 - 每段约 **100220 **中文归纳该细类下**消费者在讨论什么**口感价格物流功效疑虑等**关注词命中反映的诉求**勿编造摘录中未出现的品牌医学结论
- **去重与可证本章仅评论侧**本段****依据评价/关注词摘录**禁止** ``keyword``品类常识或商品标题卖点套话写成用户评价**禁止**各细类段首复用同一句总括整体上满足了消费者对低 GI高蛋白便携性的需求每段开头句式须**有变化**并至少一句体现**该细类与相邻细类在讨论焦点上的差异****利益/诉求词** GI高蛋白便携代餐控糖等**仅当** ``sample_text_snippets````effective_text_lines`` ``focus_hit_lines`` **原文**中可子串命中或可明确同义便携随身小包装单片独立装等时才写若上述字段中****出现蛋白便携随身小包装单片**不得**高蛋白便携性**禁止**为凑齐常见卖点组合而脑补未在输入中出现的词
- **禁止**输出 Markdown 表格禁止逐条复述全部评价 - **禁止**输出 Markdown 表格禁止逐条复述全部评价
- ``effective_text_lines`` 很少明确写样本较少归纳供启发 - ``effective_text_lines`` 很少明确写样本较少归纳供启发
@ -627,7 +629,7 @@ PRICE_GROUPS_SYSTEM = """你是定价与渠道顾问。输入为 JSON``keywor
**为每个细类**输出一小段 Markdown全部 groups 都要写顺序与输入一致 **为每个细类**输出一小段 Markdown全部 groups 都要写顺序与输入一致
- ``#### `` + 与该 group 字段**完全一致**的细类名作为小节标题; - ``#### `` + 与该 group 字段**完全一致**的细类名作为小节标题;
- 每段约 **80200 **中文**只写价盘与价差** ``price_stats`` 概括价带/离散度 minmax中位数相对集中或拉得开 ``listing_snippets`` 归纳**标价 vs 券后 vs 详情价**是否常一致是否常见券后低于标价价差幅度的大致印象**可一句**联系标题里**显式出现的规格数字**如克重件数解释**价高/价差大是否可能来自大规格或组合装**仅当摘录里确有数字时写勿展开成宣称解读 - 每段约 **80200 **中文**只写价盘与价差** ``price_stats`` 概括价带/离散度 minmax中位数相对集中或拉得开 ``listing_snippets`` 归纳**标价 vs 券后 vs 详情价**是否常一致是否常见券后低于标价价差幅度的大致印象**可一句**联系标题里**显式出现的规格数字**如克重件数解释**价高/价差大是否可能来自大规格或组合装**仅当摘录里确有数字时写勿展开成宣称解读
- **硬性禁止**本章不是卖点章不要列举或归纳0 蔗糖 / GI / 全麦 / 代餐 / 孕妇 / 控糖**营销宣称或场景关键词**不要写配料功效品牌叙事用户画像这些若出现应留给报告 **§5 细类要点归纳** - **硬性禁止**本章不是卖点章不要列举或归纳0 蔗糖 / GI / 全麦 / 代餐 / 孕妇 / 控糖**营销宣称或场景关键词**不要写配料功效品牌叙事用户画像这些若出现应留给报告 **§5 细类要点归纳**
- **禁止** Markdown 表格禁止罗列全部 SKU勿编造未出现的到手价销量排名 - **禁止** Markdown 表格禁止罗列全部 SKU勿编造未出现的到手价销量排名
- ``price_stats`` n=0 或缺失该细类无可解析数值价从略 - ``price_stats`` n=0 或缺失该细类无可解析数值价从略
@ -662,3 +664,89 @@ def generate_price_group_summaries_llm(
raw = json.dumps({"keyword": keyword, "groups": trimmed}, ensure_ascii=False) raw = json.dumps({"keyword": keyword, "groups": trimmed}, ensure_ascii=False)
user = PRICE_GROUPS_USER_PREFIX + raw user = PRICE_GROUPS_USER_PREFIX + raw
return _call_llm(PRICE_GROUPS_SYSTEM, user) return _call_llm(PRICE_GROUPS_SYSTEM, user)
PROMO_GROUPS_SYSTEM = """你是电商促销与价盘顾问。输入为 JSON``keyword`` 与 ``groups``。
每个 group ``group``细分类目名 §5 矩阵§6 一致``sku_count````rows_with_buyer_promo_text``该细类合并表中促销摘要非空行数
``promo_snippets``若干条摘录标题 + 促销摘要/购买者侧榜单/列表卖点与腰带等已截断
**为每个细类**输出一小段 Markdown全部 groups 都要写顺序与输入一致
- ``#### `` + 与该 group 字段**完全一致**的细类名作为小节标题;
- 每段约 **80220 **中文**只写促销与活动形态**如券后/满减/百亿补贴/新人包邮/限购提示/到手价展示方式 **§6.1** 规则统计可对照的**活动话术密度**印象可一句点出**榜单/腰带**是否常见是否与价格带并存
- **硬性禁止**不要展开配料功效用户画像不要复述 §5 的配料归纳不要编造未在摘录中出现的具体金额或活动规则
- 若该细类 ``rows_with_buyer_promo_text`` 0 且摘录几乎只有标题该细类缺少购买者侧促销摘要从略
总输出约 **5002800 **仅输出正文 Markdown不要用代码围栏包裹全文"""
PROMO_GROUPS_USER_PREFIX = (
"请根据以下 JSON 撰写竞品报告第六章「细类促销与活动要点归纳」正文Markdown"
"依据 ``promo_snippets`` 中的促销摘要与列表文案,**不写**价带分位数(留给上一小节)。\n\n"
)
def generate_promo_group_summaries_llm(
groups: list[dict[str, Any]], *, keyword: str
) -> str:
trimmed: list[dict[str, Any]] = []
for g in groups:
if not isinstance(g, dict):
continue
g2 = dict(g)
sn = g2.get("promo_snippets")
if isinstance(sn, list) and len(sn) > 14:
g2["promo_snippets"] = sn[:14]
trimmed.append(g2)
payload = {"keyword": keyword, "groups": trimmed}
raw = json.dumps(payload, ensure_ascii=False)
if len(raw) > 95_000:
for g2 in trimmed:
sn = g2.get("promo_snippets")
if isinstance(sn, list) and len(sn) > 8:
g2["promo_snippets"] = sn[:8]
raw = json.dumps({"keyword": keyword, "groups": trimmed}, ensure_ascii=False)
user = PROMO_GROUPS_USER_PREFIX + raw
return _call_llm(PROMO_GROUPS_SYSTEM, user)
STRATEGY_OPPORTUNITIES_SYSTEM = """你是 B 端市场与增长顾问。输入 JSON 含 ``keyword`` 与 ``competitor_brief``(与本任务规则报告同源的结构化摘要,可能经裁剪,并含 ``matrix_overview_for_llm``)。
请输出 **Markdown 正文**不要用 ``` 围栏包裹**直接嵌入**宿主文档中**已存在章节标题之下**的小节读者已知当前处于策略与机会相关章节
**标题与措辞硬性**
- **禁止**在正文开头或任何位置重复宿主已有章名/小节名包括但不限于第九章第9章策略与机会提示策略与机会建议策略与机会**不要**自造 ``##`` 一级标题;
- 小节标题**仅允许**使用业务主题式 ``####``(如下所列),从第一句起就进入实质内容。
**必须遵守**
- **数字与事实**价格分位数集中度份额条数占比等**只能**来自输入 JSON 中已有字段**禁止编造**未出现的品牌销量具体 GMV未给出的到手价
- **语气**分节给出**可操作的假设性建议**定价区间思路应对齐的差异化观测点应规避的风险促销与机制设计线索转化与详情页/评价侧改进方向每条建议用假设待验证等标明不确定性
- **结构**至少使用 ``####`` 组织以下主题(可合并子条,但须覆盖):**定价与价带**、**差异化与应对齐的优势**、**风险与避免项**、**促销与活动机制**、**转化与体验**
- **禁止**不要写完整报告目录不要复述研究范围与方法不要使用 CR1/CR3 缩写第一大份额前三家合计不要输出与输入矛盾的价带描述
篇幅约 **9003200 **数据丰富可偏长"""
STRATEGY_OPPORTUNITIES_USER_PREFIX = (
"请根据以下 JSON 撰写策略归纳正文Markdown。宿主报告已含章节标题**勿在输出中写第九章或「策略与机会」类标题**。\n\n"
)
def generate_strategy_opportunities_llm(
brief: dict[str, Any], *, keyword: str
) -> str:
"""
基于 ``build_competitor_brief`` 全量摘要生成策略与机会小节正文不含章名由宿主 Markdown 加标题
"""
compact = compact_brief_for_llm(brief, max_chars=100_000)
payload = {"keyword": keyword, "competitor_brief": compact}
raw = json.dumps(payload, ensure_ascii=False)
if len(raw) > 110_000:
compact = compact_brief_for_llm(brief, max_chars=65_000)
payload = {"keyword": keyword, "competitor_brief": compact}
raw = json.dumps(payload, ensure_ascii=False)
if len(raw) > 110_000:
compact = compact_brief_for_llm(brief, max_chars=40_000)
payload = {"keyword": keyword, "competitor_brief": compact}
raw = json.dumps(payload, ensure_ascii=False)
user = STRATEGY_OPPORTUNITIES_USER_PREFIX + raw
return _call_llm(STRATEGY_OPPORTUNITIES_SYSTEM, user)