mirror of
https://github.com/primedigitaltech/market-assistant.git
synced 2026-07-21 23:41:39 +08:00
docs(copy): 将「口径」改为计数规则、说明、价格来源等通俗表述
报告正文、简报、策略草稿、API 说明与 LLM 提示中避免「统计口径」等行话;列表 CSV 表头「销量口径」改为「销量展示」;日报目录未改。 Made-with: Cursor
This commit is contained in:
parent
a2523415d5
commit
0be4049860
@ -119,7 +119,7 @@ npm run build
|
||||
2. **任务与结果**:查看任务状态;成功任务可 **库内浏览**、文件预览与下载、导出。
|
||||
3. **报告生成**:配置统计规则并重新生成分析报告文件。
|
||||
4. **报告查看**:在线预览、单文件下载、加载结构化摘要、**一键下载简报包**(ZIP)。
|
||||
5. **结构化摘要**:与报告同口径的规则化 JSON,供联调或其它工具使用。
|
||||
5. **结构化摘要**:与报告**同一套计数规则**的规则化 JSON,供联调或其它工具使用。
|
||||
6. **市场策略制定**:选成功任务,可选填业务备注,生成策略向 Markdown(目标、战场、定位选项、支柱与行动;规则版、非大模型)。
|
||||
|
||||
任务**成功结束后**会自动执行入库;也可在「库内浏览」里从批次目录重新入库。
|
||||
|
||||
@ -118,7 +118,7 @@ OVERRIDE_PAGE_START: int | None = None
|
||||
OVERRIDE_PAGE_TO: int | None = None
|
||||
|
||||
# 评价/预览文本中可统计的「低 GI / 控糖」语境词(命中次数供侧写,非严谨 NLP)
|
||||
# 可选:第三方市场规模 / 行业增速等(每行四列:指标 | 数值与口径 | 来源 | 年份)。留空则不生成该小节。
|
||||
# 可选:第三方市场规模 / 行业增速等(每行四列:指标 | 数值与说明 | 来源 | 年份)。留空则不生成该小节。
|
||||
EXTERNAL_MARKET_TABLE_ROWS: tuple[tuple[str, str, str, str], ...] = ()
|
||||
|
||||
COMMENT_FOCUS_WORDS: tuple[str, ...] = (
|
||||
@ -362,7 +362,7 @@ _PROMO_SUBSTRINGS_IN_COPY: tuple[str, ...] = (
|
||||
def _analyze_price_promotions(rows: list[dict[str, str]]) -> dict[str, Any]:
|
||||
"""
|
||||
从列表或合并行中归纳「标价 vs 券后/到手」及卖点/腰带中的活动话术信号,
|
||||
供 §6.1 与结构化摘要使用(**页面展示口径**,非结算实付)。
|
||||
供 §6.1 与结构化摘要使用(按**页面展示价**字段归纳,非结算实付)。
|
||||
"""
|
||||
n = len(rows)
|
||||
with_jd = with_cp = with_both = 0
|
||||
@ -448,7 +448,7 @@ def _markdown_price_promotion_section(p: dict[str, Any]) -> list[str]:
|
||||
lines: list[str] = [
|
||||
"### 6.1 优惠活动与价差信号(页面展示摘录)",
|
||||
"",
|
||||
"- **口径**:与上节价量统计**同一批行**;比较的是列表/合并表中的**展示标价**与**展示券后/到手价**(字段见表头),"
|
||||
"- **统计范围**:与上节价量统计**同一批行**;比较的是列表/合并表中的**展示标价**与**展示券后/到手价**(字段见表头),"
|
||||
"反映页面呈现的活动与券信息,**不等于**用户结算实付或历史最低价。",
|
||||
"",
|
||||
]
|
||||
@ -1129,7 +1129,7 @@ def build_comment_sentiment_llm_payload(
|
||||
供大模型做正/负向语义归纳:附规则统计、按关键词规则**归类**后的抽样,以及 **sample_reviews_semantic_pool**
|
||||
(全量去重后的评价句确定性洗牌抽样,供模型结合语境自行判断褒贬)。
|
||||
|
||||
``sentiment_bucket_method`` 标明归类依据为子串词表;条形图与 lexicon 仍与此口径一致,
|
||||
``sentiment_bucket_method`` 标明归类依据为子串词表;条形图与 lexicon 计数方式与之一致,
|
||||
但正文归纳应以模型对 ``sample_reviews_semantic_pool`` 的整句理解为准。
|
||||
"""
|
||||
pos_only_texts: list[str] = []
|
||||
@ -1996,7 +1996,7 @@ def build_competitor_markdown(
|
||||
brands_for_cr = _structure_names_for_pie_counter(brands_s)
|
||||
cr1_shop, cr3_shop, top_shop_s, _ = _brand_cr(shops_for_cr)
|
||||
cr1_list_brand, cr3_list_brand, top_list_brand, _ = _brand_cr(brands_for_cr)
|
||||
# §4.3 类目分布:深入合并表口径,与 §5 竞品矩阵一致(非搜索列表行)
|
||||
# §4.3 类目分布:深入合并表(与 §5 竞品矩阵同一细类划分,非搜索列表行)
|
||||
cm_structure = _category_mix(merged_rows, top_k=12)
|
||||
min_brand_rows = max(5, int(0.02 * n_structure)) if n_structure else 5
|
||||
|
||||
@ -2088,7 +2088,7 @@ def build_competitor_markdown(
|
||||
n_sku_nop = n_sku - n_sku_pathed
|
||||
n_sku_unparsed = n_sku_pathed - n_sku_matrix
|
||||
lines.append(
|
||||
f"- **细类分析口径**:**{n_sku_matrix}** 个 SKU 具备可参与 **§5~§8** 的商详 "
|
||||
f"- **细类分析范围**:**{n_sku_matrix}** 个 SKU 具备可参与 **§5~§8** 的商详 "
|
||||
f"``detail_category_path``(且路径可解析为可读细类);另有 **{n_sku_nop}** 个缺该字段、"
|
||||
f"**{n_sku_unparsed}** 个有路径但无可读细类段,**未纳入**细类矩阵与按细类评价统计。"
|
||||
)
|
||||
@ -2207,7 +2207,7 @@ def build_competitor_markdown(
|
||||
exec_bullets.append(f"用途/场景(评价自述,可多选):{frag}(有效文本 **{scen_n_texts}** 条)。")
|
||||
if api_rc is not None:
|
||||
exec_bullets.append(
|
||||
f"PC 搜索返回的检索结果规模约 **{api_rc:,}**(站内匹配条数量级,见 §3.2;非零售额口径)。"
|
||||
f"PC 搜索返回的检索结果规模约 **{api_rc:,}**(站内匹配条数量级,见 §3.2;**不是**零售额或动销统计)。"
|
||||
)
|
||||
for b in exec_bullets:
|
||||
lines.append(f"- {b}")
|
||||
@ -2299,9 +2299,9 @@ def build_competitor_markdown(
|
||||
[
|
||||
"### 3.5 外部市场规模与行业信息(运行配置摘录)",
|
||||
"",
|
||||
"以下为本次任务报告调参中维护的**第三方市场摘录**,可与 §3.2 检索规模及 §3.3~3.4 列表参照对照使用;口径与真实性以原出处为准。",
|
||||
"以下为本次任务报告调参中维护的**第三方市场摘录**,可与 §3.2 检索规模及 §3.3~3.4 列表参照对照使用;**指标含义与真实性以原出处为准**。",
|
||||
"",
|
||||
"| 指标 | 数值与口径 | 来源 | 年份 |",
|
||||
"| 指标 | 数值与说明 | 来源 | 年份 |",
|
||||
"| --- | --- | --- | --- |",
|
||||
]
|
||||
)
|
||||
@ -2390,7 +2390,7 @@ def build_competitor_markdown(
|
||||
lines.append("*无店铺字段。*")
|
||||
lines.append("")
|
||||
|
||||
lines.extend(["### 4.3 细分类目分布(深入合并表 · 与 §5 矩阵同口径)", ""])
|
||||
lines.extend(["### 4.3 细分类目分布(深入合并表 · 与 §5 矩阵同一细类划分)", ""])
|
||||
if cm_structure and n_sku_matrix > 0:
|
||||
lines.extend(
|
||||
_embed_chart(
|
||||
@ -2558,13 +2558,13 @@ def build_competitor_markdown(
|
||||
"### 8.1 方法",
|
||||
"",
|
||||
"- **细类划分**:与 **§5 竞品矩阵** 相同,**仅**依据 ``detail_category_path`` 解析为「饼干 / 西式糕点 / …」等(规则见 §5 章首说明)。",
|
||||
"- **归因**:每条评价按其 SKU 对应到深入样本,再映射到该 SKU 所属细类;SKU 不在合并表中的评价单独归入说明性分组;**在合并表中但该 SKU 缺 ``detail_category_path`` 或路径无法解析为可读细类的,该评价不进入按细类统计**(与 §5 排除口径一致)。",
|
||||
"- **归因**:每条评价按其 SKU 对应到深入样本,再映射到该 SKU 所属细类;SKU 不在合并表中的评价单独归入说明性分组;**在合并表中但该 SKU 缺 ``detail_category_path`` 或路径无法解析为可读细类的,该评价不进入按细类统计**(与 §5 **同一条排除规则**)。",
|
||||
"- **正负面粗判(§8.2)**:先以关键词规则与图表做粗分;若任务开启 **llm_comment_sentiment**,可附**大模型对抽样原文的主题归因**(尤其负向「用户在抱怨什么」),与词频条形图互补。",
|
||||
"- **关注词与使用场景(§8.3)**:对组内评价正文做关注词子串计数(左栏条形图);对每条有效文本独立扫描**本次任务生效的场景词组**(来自报告调参或系统默认),一条可属多场景,右栏为**占该细类有效文本比例 %**(多标签下可相加 **>** 100%)。二者在 **同一张图左右并列**,与 §5 矩阵细类一一对应。",
|
||||
"",
|
||||
"### 8.2 评价正负面粗判(关键词规则)",
|
||||
"",
|
||||
f"- **有效文本条数**:{sentiment_lex.get('text_units', 0)}(与 §8.1 归因口径一致)。",
|
||||
f"- **有效文本条数**:{sentiment_lex.get('text_units', 0)}(与 §8.1 **归因规则**一致)。",
|
||||
f"- **偏正向(仅命中正向词表)**:{sentiment_lex.get('positive_only', 0)} 条;"
|
||||
f"**偏负向(仅命中负向词表)**:{sentiment_lex.get('negative_only', 0)} 条;"
|
||||
f"**混合(同条兼含正/负词)**:{sentiment_lex.get('mixed_positive_and_negative', 0)} 条;"
|
||||
@ -2574,7 +2574,7 @@ def build_competitor_markdown(
|
||||
)
|
||||
_scope = (sentiment_lex.get("lexeme_scope_note") or "").strip()
|
||||
if _scope:
|
||||
lines.append(f"- **词根统计口径**:{_scope}")
|
||||
lines.append(f"- **词根统计说明**:{_scope}")
|
||||
lines.extend(["", ""])
|
||||
lines.extend(
|
||||
_embed_chart(
|
||||
@ -2771,7 +2771,7 @@ def build_competitor_brief(
|
||||
report_config: dict[str, Any] | None = None,
|
||||
) -> dict[str, Any]:
|
||||
"""
|
||||
与 ``build_competitor_markdown`` 共用统计口径,输出可 JSON 序列化的结构化竞品摘要(**规则驱动**,无 LLM)。
|
||||
与 ``build_competitor_markdown`` 共用**同一套统计规则**,输出可 JSON 序列化的结构化竞品摘要(**规则驱动**,无 LLM)。
|
||||
"""
|
||||
focus_words, scenario_groups, _ext = resolve_report_tuning(report_config)
|
||||
sku_header = MERGED_FIELD_TO_CSV_HEADER["sku_id"]
|
||||
@ -3057,7 +3057,7 @@ def build_competitor_brief(
|
||||
"consumer_feedback_by_matrix_group": feedback_by_group,
|
||||
"comment_sentiment_lexicon": comment_sentiment_lexicon,
|
||||
"notes": [
|
||||
"与在线分析报告各章统计口径一致;关注词与场景以任务中的分析规则为准(子串命中统计,非深度主题模型)。",
|
||||
"与在线分析报告各章**计数规则**一致;关注词与场景以任务中的分析规则为准(子串命中统计,非深度主题模型)。",
|
||||
"价格来自页面展示字段抽取,含促销与规格差异;促销与标价对齐等为启发式摘录,仅供对照。",
|
||||
"评价语气为关键词粗判,非深度学习情感模型。",
|
||||
"「集中度」中:最大一家占比、前三名合计占比为小数(如 0.12 表示约 12%),对应列表或深入样本中的相关行。",
|
||||
|
||||
@ -214,7 +214,7 @@ def _merged_csv_fieldnames() -> list[str]:
|
||||
def _normalize_merged_rows_for_export(rows: list[dict[str, str]]) -> None:
|
||||
"""
|
||||
整合表落盘前:搜索侧「榜单类文案」与「榜单排名」去掉 ``榜单/曝光:`` 前缀,
|
||||
与 ``strip_buyer_ranking_line_prefix`` / 入库口径一致。
|
||||
与 ``strip_buyer_ranking_line_prefix`` / 入库规则一致。
|
||||
"""
|
||||
from pipeline.csv_schema import strip_buyer_ranking_line_prefix # noqa: WPS433
|
||||
|
||||
|
||||
@ -66,7 +66,7 @@ def build_legacy_header_map() -> dict[str, str]:
|
||||
),
|
||||
("卖点(sellingPoint)", JD_SEARCH_CSV_HEADERS["selling_point"]),
|
||||
("销量楼层(commentSalesFloor)", JD_SEARCH_CSV_HEADERS["comment_sales_floor"]),
|
||||
("销量口径(totalSales)", JD_SEARCH_CSV_HEADERS["total_sales"]),
|
||||
("销量展示(totalSales)", JD_SEARCH_CSV_HEADERS["total_sales"]),
|
||||
(
|
||||
"榜单类文案(标签/腰带/标题数组中的榜、TOP 等)",
|
||||
JD_SEARCH_CSV_HEADERS["hot_list_rank"],
|
||||
|
||||
@ -54,7 +54,7 @@ JD_SEARCH_CSV_HEADERS: dict[str, str] = {
|
||||
"original_price": "原价",
|
||||
"selling_point": "卖点",
|
||||
"comment_sales_floor": "销量楼层",
|
||||
"total_sales": "销量口径",
|
||||
"total_sales": "销量展示",
|
||||
"hot_list_rank": "榜单类文案",
|
||||
"comment_count": "评价量",
|
||||
"shop_name": "店铺名",
|
||||
@ -236,7 +236,7 @@ def remap_merged_row_english_detail_keys_to_csv_headers(merged: dict[str, str])
|
||||
|
||||
def infer_total_sales_from_sales_floor(cell: str) -> str:
|
||||
"""
|
||||
从「销量楼层(commentSalesFloor)」列文案截取可作 ``销量口径(totalSales)`` 的片段(与列表接口未单独落 totalSales 列时的兜底一致)。
|
||||
从「销量楼层(commentSalesFloor)」列文案截取可作 ``销量展示(totalSales)`` 的片段(与列表接口未单独落 totalSales 列时的兜底一致)。
|
||||
"""
|
||||
t = (cell or "").strip()
|
||||
if not t:
|
||||
@ -249,7 +249,7 @@ def infer_total_sales_from_sales_floor(cell: str) -> str:
|
||||
|
||||
|
||||
def merged_csv_effective_total_sales(row: dict[str, str]) -> str:
|
||||
"""合并表一行:优先已有 ``销量口径(totalSales)``,否则从销量楼层推断。"""
|
||||
"""合并表一行:优先已有 ``销量展示(totalSales)`` 列,否则从销量楼层推断。"""
|
||||
h_ts = MERGED_FIELD_TO_CSV_HEADER["total_sales"]
|
||||
h_fl = MERGED_FIELD_TO_CSV_HEADER["comment_sales_floor"]
|
||||
direct = str(row.get(h_ts) or "").strip()
|
||||
@ -259,7 +259,7 @@ def merged_csv_effective_total_sales(row: dict[str, str]) -> str:
|
||||
|
||||
|
||||
def search_csv_effective_total_sales(row: dict[str, str]) -> str:
|
||||
"""PC 搜索导出表一行:与 ``merged_csv_effective_total_sales`` 口径一致(中文表头)。"""
|
||||
"""PC 搜索导出表一行:与 ``merged_csv_effective_total_sales`` 解析规则一致(中文表头)。"""
|
||||
h_ts = JD_SEARCH_CSV_HEADERS["total_sales"]
|
||||
h_fl = JD_SEARCH_CSV_HEADERS["comment_sales_floor"]
|
||||
direct = str(row.get(h_ts) or "").strip()
|
||||
|
||||
@ -105,7 +105,7 @@ def _comment_row_kwargs(row: dict[str, str]) -> dict[str, str]:
|
||||
|
||||
|
||||
def _normalize_merged_csv_total_sales(row: dict[str, str]) -> None:
|
||||
"""列表未写 totalSales 列时,用销量楼层推断,保证入库与快照与报告口径一致。"""
|
||||
"""列表未写 totalSales 列时,用销量楼层推断,保证入库与快照与报告计数一致。"""
|
||||
h = MERGED_FIELD_TO_CSV_HEADER["total_sales"]
|
||||
row[h] = merged_csv_effective_total_sales(row)
|
||||
|
||||
@ -127,7 +127,7 @@ def _bulk_create_in_chunks(model, objects: list[Any]) -> None:
|
||||
def _sync_search_rows_matrix_labels(
|
||||
job: PipelineJob, merged_kw_list: list[tuple[int, dict[str, str]]]
|
||||
) -> None:
|
||||
"""按 SKU 将合并表解析出的类目回填到搜索行(与 §5 矩阵口径一致)。"""
|
||||
"""按 SKU 将合并表解析出的类目回填到搜索行(与 §5 矩阵**同一细类划分**)。"""
|
||||
sku_to_mg: dict[str, str] = {}
|
||||
for _, kw in merged_kw_list:
|
||||
sk = (kw.get("sku_id") or "").strip()
|
||||
|
||||
@ -29,7 +29,7 @@ def _ensure_crawler_detail_path() -> None:
|
||||
def write_keyword_pipeline_merged_lean_csv(run_dir: Path) -> tuple[int, Path]:
|
||||
"""
|
||||
读取已有 ``keyword_pipeline_merged.csv``(可缺列),按 lean 宽表列序重写:
|
||||
- ``销量口径`` 与入库一致(``merged_csv_effective_total_sales``)
|
||||
- ``销量展示`` 列与入库一致(``merged_csv_effective_total_sales``)
|
||||
- 商详块列优先与 ``detail_ware_export.csv`` 对齐;缺则尝试 ``detail/ware_{sku}_response.json``
|
||||
- 「榜单类文案」与「榜单排名」去掉 ``榜单/曝光:`` 前缀
|
||||
"""
|
||||
|
||||
@ -23,7 +23,7 @@ def merge_llm_supplement_with_rules_report(llm_md: str, rules_md: str) -> str:
|
||||
大模型稿作为 **§8.5** 嵌入在 **第八章末、第九章策略** 之前,与 §8.2~8.3 等具体分析同卷连贯,
|
||||
**不再**插在篇首「## 一、」之前。
|
||||
|
||||
注:API「重新生成报告」已不再调用本函数,避免整篇 LLM 与矩阵/图表口径冲突;保留供脚本或将来显式开关复用。
|
||||
注:API「重新生成报告」已不再调用本函数,避免整篇 LLM 与矩阵/图表**数据含义**冲突;保留供脚本或将来显式开关复用。
|
||||
"""
|
||||
body = (rules_md or "").strip()
|
||||
sup = (llm_md or "").strip()
|
||||
@ -91,7 +91,7 @@ def _safe_dir_segment_for_job(s: str, max_len: int = 48) -> str:
|
||||
|
||||
def resolve_pipeline_run_directory_for_job(job: PipelineJob) -> Path:
|
||||
"""
|
||||
在拉起子进程前固定本次 ``run_dir``(与 ``jd_keyword_pipeline._resolve_pipeline_run_dir`` 同口径)。
|
||||
在拉起子进程前固定本次 ``run_dir``(与 ``jd_keyword_pipeline._resolve_pipeline_run_dir`` **同一规则**)。
|
||||
调用方负责 ``mkdir``。
|
||||
"""
|
||||
root = (settings.LOW_GI_PROJECT_ROOT or "").strip()
|
||||
@ -771,7 +771,7 @@ def build_competitor_brief_for_job(
|
||||
report_config: dict[str, Any] | None = None,
|
||||
) -> dict[str, Any]:
|
||||
"""
|
||||
读取 ``run_dir`` 下合并表 / 搜索导出 / 评价 / meta,返回与 Markdown 报告同口径的 **JSON 结构化摘要**(规则驱动)。
|
||||
读取 ``run_dir`` 下合并表 / 搜索导出 / 评价 / meta,返回与 Markdown 报告**同一套计数规则**的 **JSON 结构化摘要**(规则驱动)。
|
||||
``run_dir`` 须位于 ``LOW_GI_PROJECT_ROOT/data/JD`` 下。
|
||||
"""
|
||||
low_root = (settings.LOW_GI_PROJECT_ROOT or "").strip()
|
||||
|
||||
@ -58,7 +58,7 @@ REPORT_SYSTEM = """你是业务与产品读者顾问。输入 JSON 含 `keyword`
|
||||
- 若有 `comment_sentiment_lexicon`,概括正/负向粗判局限;**负向**写清事由类型(口感、价格、物流等);
|
||||
- **归因与引语(硬性)**:`consumer_feedback_by_matrix_group` 与 `comment_sentiment_lexicon` 等均为**跨 SKU/跨店铺的关键词子串或条数统计**,**不能**单独据此推断「某一店铺某一单品」的结论。
|
||||
- **具体体验句式(含口感、包装等)**须以正文 **§8.2** 中带 ``【细类|SKU|品名|店铺】`` 前缀的抽样为准;本段**不要**新增无前缀、无店铺/品名/SKU 指向的「」引语。
|
||||
- 若写口感、包装、物流、价格等**聚合**维度,须点明口径(如「在已合并的评价文本中,『物流』『价格』类关键词命中较多,为全样本子串计数」);可结合 `matrix_overview_for_llm` 谈细类结构;**可一句**引导读者「见 §8.2 按店铺/品名的负向举例」。
|
||||
- 若写口感、包装、物流、价格等**聚合**维度,须**写明统计范围**(如「在已合并的评价文本中,『物流』『价格』类关键词命中较多,为全样本子串计数」);可结合 `matrix_overview_for_llm` 谈细类结构;**可一句**引导读者「见 §8.2 按店铺/品名的负向举例」。
|
||||
- 若 §8.2 已归纳带店铺与 SKU 的负向主题,本段**只做执行摘要级收束**,勿重复编造新引文。
|
||||
- 语气专业、中文;某类信息在输入中缺失时**一句带过数据缺口**即可,**禁止**输出「本段未提供该项」等套话占位。"""
|
||||
|
||||
@ -114,7 +114,7 @@ def generate_competitor_report_markdown_llm(brief: dict[str, Any], keyword: str)
|
||||
|
||||
SENTIMENT_LLM_SYSTEM = """你是电商/食品类用户研究助手。输入 JSON 含:
|
||||
|
||||
- ``comment_sentiment_lexicon``:子串词表统计(与报告条形图口径一致,**仅作定量参考**;子串命中≠说话人态度)。
|
||||
- ``comment_sentiment_lexicon``:子串词表统计(与报告条形图**同一计数方式**,**仅作定量参考**;子串命中≠说话人态度)。
|
||||
- ``positive_lexeme_hits_top`` / ``negative_lexeme_hits_top``:短语级命中摘要(同源)。
|
||||
- ``sentiment_bucket_method``:恒为 ``keyword_substring_heuristic``;``sample_reviews_positive_biased`` / ``negative`` / ``mixed_tone`` 是按该词表**机械归类**的抽样,**可能与整句真实褒贬不一致**(例如「软硬适中」曾被误归负向)。
|
||||
- **``sample_reviews_semantic_pool``**(若有):本批评价经去重后的**随机/洗牌抽样**,覆盖未命中任一关键词的句子。**归纳正/负向体验、引用「」短引文时,优先以此池与上述各列表中的原文为准,自行结合语境理解**:转折、对比(如「没那么甜」「软硬适中」)、先抑后扬/先扬后抑整句态度;**不得以子串是否命中负面词来断言该句为抱怨**。
|
||||
@ -125,7 +125,7 @@ SENTIMENT_LLM_SYSTEM = """你是电商/食品类用户研究助手。输入 JSON
|
||||
- **仅输出 Markdown 正文**(不要用 ``` 围栏包裹全文);
|
||||
- **不要编造**样本中未出现的具体事实、品牌、价格、医学功效;
|
||||
- **定量数字**(条数、占比、lexicon 各字段)须与 ``comment_sentiment_lexicon`` **一致**,勿编造;
|
||||
- **定性归纳**(满意点/抱怨点、引语是否算差评):以**整句语义**为准;若某句在语义上为褒义或中性描述,**不得**放入「质地差、口感硬」等负向归因;若词表归类结果与句意冲突,**以句意为准**,并在「使用注意」点明「关键词归类仅作统计口径」。
|
||||
- **定性归纳**(满意点/抱怨点、引语是否算差评):以**整句语义**为准;若某句在语义上为褒义或中性描述,**不得**放入「质地差、口感硬」等负向归因;若词表归类结果与句意冲突,**以句意为准**,并在「使用注意」点明「关键词归类**仅反映子串计数,不作态度判断**」。
|
||||
- 若某措辞**未**出现在任一抽样原文(含前缀后正文)中,**禁止**用引号写成直接引语。
|
||||
- **不要**只复述「某词出现 N 次」——条形图已展示;你的价值是**语义归纳**。
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# Generated manually for keyword_pipeline_merged.csv column 销量口径(totalSales).
|
||||
# Generated manually for keyword_pipeline_merged.csv column 销量展示(totalSales).
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
@ -108,7 +108,7 @@ def markdown_summary_from_brief(brief: dict[str, Any]) -> str:
|
||||
[
|
||||
"## 价格(展示价统计)",
|
||||
"",
|
||||
f"- **样本量(条)**:{_num(pst.get('n'))};**统计口径**:{src}",
|
||||
f"- **样本量(条)**:{_num(pst.get('n'))};**价格来源**:{src}",
|
||||
f"- **区间**:{_num(pst.get('min'))} ~ {_num(pst.get('max'))};**中位数**:{_num(pst.get('median'))}",
|
||||
"",
|
||||
]
|
||||
|
||||
@ -223,7 +223,7 @@ def build_strategy_draft_markdown(
|
||||
src = _esc(brief.get("price_stats_source")) or "—"
|
||||
lines.extend(
|
||||
[
|
||||
f"- **统计口径**:{src},有效价样本 n = {_num(pst.get('n'))}。",
|
||||
f"- **价格来源**:{src},有效价样本 n = {_num(pst.get('n'))}。",
|
||||
f"- **展示价区间**:{_num(pst.get('min'))} ~ {_num(pst.get('max'))};**中位数** {_num(pst.get('median'))}。",
|
||||
"",
|
||||
"**定位选项(请勾一条或改写,并写明理由)**",
|
||||
@ -321,7 +321,7 @@ def build_strategy_draft_markdown(
|
||||
"## 七、风险与待证伪",
|
||||
"",
|
||||
_risk_line(rk, "关注词/场景是否**以偏概全**?(需原评论抽样)"),
|
||||
_risk_line(rp, "价格带是否含大促/异常挂价?(需核对清洗口径)"),
|
||||
_risk_line(rp, "价格带是否含大促/异常挂价?(需核对清洗规则)"),
|
||||
_risk_line(rc, "列表集中度与深入样本品牌是否**矛盾**?(需解释渠道差异)"),
|
||||
"",
|
||||
]
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
"""销量/评价量文案解析(与 reporting.charts._cn_volume_int 口径一致)。"""
|
||||
"""销量/评价量文案解析(与 reporting.charts._cn_volume_int 同一套解析规则)。"""
|
||||
from __future__ import annotations
|
||||
|
||||
from django.test import SimpleTestCase
|
||||
|
||||
@ -429,7 +429,7 @@ class JobRegenerateReportView(APIView):
|
||||
|
||||
|
||||
class JobCompetitorBriefView(APIView):
|
||||
"""单次任务的结构化竞品摘要(JSON,与 ``competitor_analysis.md`` 统计口径一致,规则驱动无 LLM)。"""
|
||||
"""单次任务的结构化竞品摘要(JSON,与 ``competitor_analysis.md`` **同一套计数规则**,规则驱动无 LLM)。"""
|
||||
|
||||
def get(self, request, pk: int):
|
||||
if not (settings.LOW_GI_PROJECT_ROOT or "").strip():
|
||||
|
||||
@ -46,5 +46,5 @@ def comment_count_sort_value_from_cell(comment_count: str) -> int | None:
|
||||
|
||||
|
||||
def comment_count_sort_value_from_merged(pipeline_comment_count: str) -> int | None:
|
||||
"""宽表评价量列(与搜索侧口径类似的文案)。"""
|
||||
"""宽表评价量列(与搜索侧列表文案风格类似)。"""
|
||||
return comment_count_sort_value_from_cell(pipeline_comment_count)
|
||||
|
||||
@ -103,7 +103,7 @@
|
||||
}
|
||||
],
|
||||
"notes": [
|
||||
"与在线分析报告统计口径一致;主题词与场景为预设词表,非 NLP 主题模型。",
|
||||
"与在线分析报告各章计数规则一致;主题词与场景为预设词表,非 NLP 主题模型。",
|
||||
"价格来自展示字段抽取,含促销与规格差异。"
|
||||
]
|
||||
}
|
||||
|
||||
@ -217,7 +217,7 @@ paths:
|
||||
/api/jobs/{id}/competitor-brief/:
|
||||
get:
|
||||
tags: [jobs]
|
||||
summary: 结构化竞品摘要 JSON(与 Markdown 报告统计口径一致)
|
||||
summary: 结构化竞品摘要 JSON(与 Markdown 报告同一套计数规则)
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/JobId"
|
||||
responses:
|
||||
|
||||
@ -48,7 +48,7 @@
|
||||
|
||||
- **下载 / 预览**:通过任务对应的下载、预览能力获取(仅成功且文件已生成时可用)。
|
||||
- **重新生成报告**(不重新爬取):仅用本批次已有表格与元数据刷新**分析报告**正文。
|
||||
- **结构化竞品摘要**:规则生成的 JSON,与在线分析报告**统计口径一致**;价格等指标在能解析列表价时以列表为准,否则以深入样本为准,响应内会标明口径。
|
||||
- **结构化竞品摘要**:规则生成的 JSON,与在线分析报告**同一套计数规则**;价格等指标在能解析列表价时以列表为准,否则以深入样本为准,响应内会标明**价格来源**。
|
||||
- **一键简报包**:ZIP,内含完整分析报告稿、结构化摘要、要点摘录与说明;须已生成主报告。
|
||||
- **市场策略制定**:提交可选业务备注后返回策略向文稿(策略框架 + 附录数据速览),数据与同任务结构化摘要一致;仅成功且数据齐全时可用。
|
||||
- **商详表离线修正再入库**:由运维/研发在侧链完成后再走全量入库能力。
|
||||
|
||||
@ -294,7 +294,7 @@ watch(
|
||||
</label>
|
||||
<label class="chk">
|
||||
<input v-model="decisions.ack_risk_price" type="checkbox" />
|
||||
价格带可能含大促或异常挂价(需核对口径)
|
||||
价格带可能含大促或异常挂价(需核对清洗与计价规则)
|
||||
</label>
|
||||
<label class="chk">
|
||||
<input v-model="decisions.ack_risk_concentration" type="checkbox" />
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user