mirror of
https://github.com/primedigitaltech/market-assistant.git
synced 2026-07-22 08:01:34 +08:00
fix(llm): restore matrix/comment/price group advisor prompts and callers
Re-add MATRIX/COMMENT/PRICE_GROUPS_SYSTEM and generate_*_group_summaries_llm removed in afe2748; align comment-group prompt with shop in attribution prefix. Default report_config now includes the three llm_*_summaries flags. Made-with: Cursor
This commit is contained in:
parent
dd5fa8a407
commit
15ba8b3370
@ -168,6 +168,9 @@ def get_default_report_config() -> dict[str, Any]:
|
||||
return {
|
||||
"llm_comment_sentiment": False,
|
||||
"llm_section_bridges": False,
|
||||
"llm_matrix_group_summaries": False,
|
||||
"llm_comment_group_summaries": False,
|
||||
"llm_price_group_summaries": False,
|
||||
"comment_focus_words": list(jcr.COMMENT_FOCUS_WORDS),
|
||||
"comment_scenario_groups": [
|
||||
{"label": lbl, "triggers": list(trs)}
|
||||
|
||||
@ -270,3 +270,136 @@ def generate_strategy_draft_markdown_llm(
|
||||
raw = json.dumps(payload, ensure_ascii=False)
|
||||
user = STRATEGY_USER_PREFIX + raw
|
||||
return _call_llm(STRATEGY_SYSTEM, user)
|
||||
|
||||
|
||||
MATRIX_GROUPS_SYSTEM = """你是竞品分析顾问。输入为 JSON:``keyword`` 与 ``groups`` 数组。
|
||||
每个 group 含 ``group``(细分类目名)、``sku_count``、``price_stats``(该细类深入合并行可解析展示价的 min/max/median/mean/n,与 **§6「按细类价盘」** 分位数表同源;无则 n=0 或缺字段)、
|
||||
``lines``(该细类下若干 SKU 的标题/卖点/配料**摘录**,均来自页面抓取拼接,可能截断)。
|
||||
|
||||
请**为每个细类**输出一小段 Markdown(全部 groups 都要写,顺序与输入一致):
|
||||
- 以 ``#### `` + 与该 group 字段**完全一致**的细类名作为小节标题(不要使用 ``##`` 一级标题);
|
||||
- 每段约 **100~200 字**中文:**主体**归纳该细类下**卖点表述共性**、**配料类型/宣称共性**(摘录中无配料则写「配料摘录较少」);**品牌格局**可一句概括(仅依据摘录中可见品牌/系列,勿编造销量排名);
|
||||
- **价带/价位**:若 ``price_stats.n`` 为大于 0 的整数,**仅允许**用该对象里的数值写价带(如 min~max、中位数),且须与 ``price_stats`` **完全一致**,**禁止**写「价格带未明确」「未体现具体价位」「多为中端」等**与上述数值相矛盾**的表述;若 n=0 或无可信数值,**不要猜测价位**,可写一句「深入样本可解析数值价不足,价盘以 **§6** 表格为准」;
|
||||
- **禁止**输出 Markdown 表格、禁止逐条复述 SKU 明细表;勿编造功效、认证;
|
||||
- 若 ``lines`` 很少,明确写「样本较少,归纳供启发」。
|
||||
|
||||
总输出约 **800~3500 字**(细类多则偏长)。仅输出正文 Markdown,不要用代码围栏包裹全文。"""
|
||||
|
||||
|
||||
MATRIX_GROUPS_USER_PREFIX = (
|
||||
"请根据以下 JSON 撰写竞品报告第五章末「细类要点归纳」正文(Markdown)。\n\n"
|
||||
)
|
||||
|
||||
|
||||
def generate_matrix_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)
|
||||
ln = g2.get("lines")
|
||||
if isinstance(ln, list) and len(ln) > 22:
|
||||
g2["lines"] = ln[:22]
|
||||
trimmed.append(g2)
|
||||
payload = {"keyword": keyword, "groups": trimmed}
|
||||
raw = json.dumps(payload, ensure_ascii=False)
|
||||
if len(raw) > 95_000:
|
||||
for g2 in trimmed:
|
||||
ln = g2.get("lines")
|
||||
if isinstance(ln, list) and len(ln) > 12:
|
||||
g2["lines"] = ln[:12]
|
||||
raw = json.dumps({"keyword": keyword, "groups": trimmed}, ensure_ascii=False)
|
||||
user = MATRIX_GROUPS_USER_PREFIX + raw
|
||||
return _call_llm(MATRIX_GROUPS_SYSTEM, user)
|
||||
|
||||
|
||||
COMMENT_GROUPS_SYSTEM = """你是用户研究与品类顾问。输入为 JSON:``keyword`` 与 ``groups``。
|
||||
每个 group 含 ``group``(与 §5 矩阵一致的细分类目名)、``comment_flat_rows``、``effective_text_lines``、
|
||||
``focus_hit_lines``(关注词子串命中摘要,与 §8.3 同源)、``sample_text_snippets``(评价短摘录,已截断)。
|
||||
摘录行通常以 ``【细类:…|SKU:…|品名:…|店铺:…】`` 开头:细类可与本 group 名对照,**品名/SKU/店铺**表示该句具体出自哪条链接;归纳时若引用原话,**须交代是「哪家店、哪条 SKU、哪款品名」上的反馈**,勿只写「有用户说口感差」而不指代产品。
|
||||
|
||||
请**为每个细类**输出一小段 Markdown(全部 groups 都要写,顺序与输入一致):
|
||||
- 以 ``#### `` + 与该 group 字段**完全一致**的细类名作为小节标题(不要使用 ``##`` 一级标题);
|
||||
- 每段约 **100~220 字**中文:归纳该细类下**消费者在讨论什么**(口感、价格、物流、功效疑虑等)、**关注词命中反映的诉求**;勿编造摘录中未出现的品牌、医学结论;
|
||||
- **禁止**输出 Markdown 表格、禁止逐条复述全部评价;
|
||||
- 若 ``effective_text_lines`` 很少,明确写「样本较少,归纳供启发」。
|
||||
|
||||
总输出约 **600~3200 字**。仅输出正文 Markdown,不要用代码围栏包裹全文。"""
|
||||
|
||||
|
||||
COMMENT_GROUPS_USER_PREFIX = (
|
||||
"请根据以下 JSON 撰写竞品报告第八章末「细类评论与关注词要点归纳」正文(Markdown)。\n\n"
|
||||
)
|
||||
|
||||
|
||||
def generate_comment_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("sample_text_snippets")
|
||||
if isinstance(sn, list) and len(sn) > 16:
|
||||
g2["sample_text_snippets"] = sn[:16]
|
||||
fh = g2.get("focus_hit_lines")
|
||||
if isinstance(fh, list) and len(fh) > 14:
|
||||
g2["focus_hit_lines"] = fh[: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("sample_text_snippets")
|
||||
if isinstance(sn, list) and len(sn) > 10:
|
||||
g2["sample_text_snippets"] = sn[:10]
|
||||
raw = json.dumps({"keyword": keyword, "groups": trimmed}, ensure_ascii=False)
|
||||
user = COMMENT_GROUPS_USER_PREFIX + raw
|
||||
return _call_llm(COMMENT_GROUPS_SYSTEM, user)
|
||||
|
||||
|
||||
PRICE_GROUPS_SYSTEM = """你是定价与渠道顾问。输入为 JSON:``keyword`` 与 ``groups``。
|
||||
每个 group 含 ``group``(细分类目名,与 §5 矩阵、§6「按细类价盘」小节一致)、``sku_count``、``price_stats``(该细类可解析展示价的 min/max/median/mean/n,与 §6 各细类 Markdown 分位数表同源)、
|
||||
``listing_snippets``(若干「标题|标价|券后|详情价」摘录,来自合并表字段,已截断)。
|
||||
|
||||
请**为每个细类**输出一小段 Markdown(全部 groups 都要写,顺序与输入一致):
|
||||
- 以 ``#### `` + 与该 group 字段**完全一致**的细类名作为小节标题;
|
||||
- 每段约 **80~200 字**中文,**只写价盘与价差**:用 ``price_stats`` 概括价带/离散度(如 min~max、中位数、相对集中或拉得开);用 ``listing_snippets`` 归纳**标价 vs 券后 vs 详情价**是否常一致、是否常见券后低于标价、价差幅度的大致印象;**可一句**联系标题里**显式出现的规格数字**(如克重、件数)解释**价高/价差大是否可能来自大规格或组合装**——仅当摘录里确有数字时写,勿展开成宣称解读;
|
||||
- **硬性禁止**(本章不是卖点章):不要列举或归纳「0 蔗糖 / 低 GI / 全麦 / 代餐 / 孕妇 / 控糖」等**营销宣称或场景关键词**;不要写配料、功效、品牌叙事、用户画像;这些若出现应留给报告 **§5 细类要点归纳** 或 **§7**;
|
||||
- **禁止** Markdown 表格、禁止罗列全部 SKU;勿编造未出现的到手价、销量排名;
|
||||
- 若 ``price_stats`` 中 n=0 或缺失,写「该细类无可解析数值价,从略」。
|
||||
|
||||
总输出约 **500~2800 字**。仅输出正文 Markdown,不要用代码围栏包裹全文。"""
|
||||
|
||||
|
||||
PRICE_GROUPS_USER_PREFIX = (
|
||||
"请根据以下 JSON 撰写竞品报告第六章末「细类价盘要点归纳」正文(Markdown)。"
|
||||
"本章只写**数值价带与标价/券后/详情价关系**,勿写卖点宣称关键词归纳。\n\n"
|
||||
)
|
||||
|
||||
|
||||
def generate_price_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("listing_snippets")
|
||||
if isinstance(sn, list) and len(sn) > 14:
|
||||
g2["listing_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("listing_snippets")
|
||||
if isinstance(sn, list) and len(sn) > 8:
|
||||
g2["listing_snippets"] = sn[:8]
|
||||
raw = json.dumps({"keyword": keyword, "groups": trimmed}, ensure_ascii=False)
|
||||
user = PRICE_GROUPS_USER_PREFIX + raw
|
||||
return _call_llm(PRICE_GROUPS_SYSTEM, user)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user