mirror of
https://github.com/primedigitaltech/market-assistant.git
synced 2026-07-22 08:01:34 +08:00
fix(report): default LLM flags, embed §5 matrix charts, slim table
Merge missing keys from get_default_report_config into effective report_config so llm_* switches default on when absent. §5 embeds chart_matrix_prices_reviews per fine category (price + review-volume bars, Y=title) and replaces the wide matrix with a compact table. Matrix chart Y-labels allow longer titles (48 chars). Made-with: Cursor
This commit is contained in:
parent
4bb94173a5
commit
9d1ff31b23
@ -1472,6 +1472,21 @@ def _competitor_matrix_md_line(
|
||||
)
|
||||
|
||||
|
||||
def _competitor_matrix_compact_md_line(
|
||||
row: dict[str, str], *, sku_header: str, title_h: str
|
||||
) -> str:
|
||||
"""§5 简表:与矩阵条形图同源字段,便于对照;不含配料与长摘要。"""
|
||||
sku = _md_cell(_cell(row, sku_header), 14)
|
||||
title = _md_cell(_cell(row, title_h), 72)
|
||||
brand = _md_cell(_cell(row, "detail_brand"), 16)
|
||||
df = _cell(row, "detail_price_final").strip()
|
||||
pj = _cell(row, "标价(jdPrice,jdPriceText,realPrice)").strip()
|
||||
price_cell = _md_cell(df or pj or "—", 12)
|
||||
cc = _md_cell(_cell(row, "评价量(commentFuzzy)"), 12)
|
||||
shop = _md_cell(_cell(row, "店铺名(shopName)", "detail_shop_name"), 20)
|
||||
return f"| {sku} | {title} | {brand} | {shop} | {price_cell} | {cc} |"
|
||||
|
||||
|
||||
def _strategy_hints(
|
||||
*,
|
||||
cr1: float | None,
|
||||
@ -1555,6 +1570,12 @@ def _focus_keywords_group_bar_filename(group: str, index: int) -> str:
|
||||
return f"chart_focus_keywords_bar__{slug}.png"
|
||||
|
||||
|
||||
def _matrix_prices_reviews_chart_filename(group: str, index: int) -> str:
|
||||
"""与 ``report_charts.generate_report_charts`` 中 ``chart_matrix_prices_reviews__*`` 一致。"""
|
||||
slug = _scenario_group_asset_slug(group, index)
|
||||
return f"chart_matrix_prices_reviews__{slug}.png"
|
||||
|
||||
|
||||
def _lines_4_reading_brand(
|
||||
*,
|
||||
cr1: float | None,
|
||||
@ -2104,18 +2125,14 @@ def build_competitor_markdown(
|
||||
"分组**仅**使用合并表列 ``detail_category_path``(商详类目路径):**三级路径**取中间一段(如 … > **饼干** > 粗粮饼干),"
|
||||
"**四级及以上**取倒数第二段(如 … > **面条** > 挂面)。**该列为空**或路径段均为内部编码、**无法解析出可读细类**的 SKU **不进入**本矩阵,亦**不参与**第八章按细类的评价统计。",
|
||||
"",
|
||||
"维度说明:**产品**(标题/规格)、**价格**(列表展示)、**渠道**(京东店铺)、**推广**(卖点/榜单文案)、"
|
||||
"**类目路径**(``detail_category_path``)、**配料表**(见下)、**声量**(评价量与摘要)。",
|
||||
"",
|
||||
"**配料表**:优先使用配料正文列(开启配料视觉解析时为识别出的文字);"
|
||||
"仅有详情长图链接时列内会提示;若商详参数含「配料/配料表:」则摘录该段。"
|
||||
"均为页面信息摘录,**以包装实物与法规标签为准**。",
|
||||
"**读图方式**:每个细类下优先给出**并列横向条形图**(左:**展示价**(元);右:**评价量**(搜索列表侧文案,作**声量 proxy**,**非**平台销量/动销)),"
|
||||
"纵轴为**产品标题**(与图文件 ``chart_matrix_prices_reviews__*.png`` 同源)。下方附**精简对照表**(SKU、店铺、价与评价量);配料、卖点与评价摘要等完整列见合并表 CSV。",
|
||||
"",
|
||||
]
|
||||
)
|
||||
matrix_header = [
|
||||
"| SKU | 产品(标题) | 品牌 | 标价 | 详情价 | 渠道(店铺) | 推广(卖点) | 榜单/标签 | 类目路径(商详) | 配料表 | 评价量(搜索) | 消费者反馈摘要 |",
|
||||
"| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
|
||||
matrix_header_compact = [
|
||||
"| SKU | 产品(标题) | 品牌 | 渠道(店铺) | 展示价(详情优先) | 评价量(搜索) |",
|
||||
"| --- | --- | --- | --- | --- | --- |",
|
||||
]
|
||||
grouped_matrix = _merged_rows_grouped_for_matrix(merged_rows)
|
||||
if not grouped_matrix:
|
||||
@ -2127,14 +2144,30 @@ def build_competitor_markdown(
|
||||
else:
|
||||
lines.append("*无合并表 SKU。*")
|
||||
lines.append("")
|
||||
for gname, grows in grouped_matrix:
|
||||
for gi, (gname, grows) in enumerate(grouped_matrix):
|
||||
lines.append(f"### {gname}(**{len(grows)}** 款)")
|
||||
lines.append("")
|
||||
lines.extend(matrix_header)
|
||||
grows_sorted = sorted(grows, key=lambda r: _cell(r, sku_header) or "")
|
||||
mx_chart = _matrix_prices_reviews_chart_filename(gname, gi)
|
||||
lines.extend(
|
||||
_embed_chart(
|
||||
run_dir,
|
||||
mx_chart,
|
||||
f"「{_md_cell(gname, 20)}」· 展示价与评价量(搜索侧声量 proxy);纵轴为产品标题,与下图简表一致。",
|
||||
)
|
||||
)
|
||||
if not (run_dir / "report_assets" / mx_chart).is_file():
|
||||
lines.append(
|
||||
f"*(尚未生成 ``report_assets/{mx_chart}``:请确认已执行报告出图流程,或重新生成报告。)*"
|
||||
)
|
||||
lines.append("")
|
||||
lines.extend(matrix_header_compact)
|
||||
grows_sorted = sorted(
|
||||
grows,
|
||||
key=lambda r: (_cell(r, title_h) or _cell(r, sku_header) or "").strip(),
|
||||
)
|
||||
for row in grows_sorted:
|
||||
lines.append(
|
||||
_competitor_matrix_md_line(
|
||||
_competitor_matrix_compact_md_line(
|
||||
row, sku_header=sku_header, title_h=title_h
|
||||
)
|
||||
)
|
||||
@ -2145,9 +2178,9 @@ def build_competitor_markdown(
|
||||
lines.extend(
|
||||
[
|
||||
"",
|
||||
"#### 细类要点归纳(大模型,与上表矩阵互补)",
|
||||
"#### 细类要点归纳(大模型,与上文条形图及简表互补)",
|
||||
"",
|
||||
"> **说明**:与 §5 相同的细类划分下归纳卖点与配料共性;**具体 SKU、价格与表格列以正文为准**。",
|
||||
"> **说明**:与 §5 相同的细类划分下归纳卖点与配料共性;**具体 SKU、价格与条形图以正文为准**。",
|
||||
"",
|
||||
_llm_mx,
|
||||
"",
|
||||
|
||||
@ -219,6 +219,10 @@ def write_competitor_analysis_for_run_dir(
|
||||
eff_rc: dict[str, Any] = (
|
||||
dict(report_config) if isinstance(report_config, dict) else {}
|
||||
)
|
||||
# 任务仅保存部分调参时,补齐默认项(含各 llm_* 开关);显式写入的键不被覆盖
|
||||
for _k, _v in get_default_report_config().items():
|
||||
if _k not in eff_rc:
|
||||
eff_rc[_k] = _v
|
||||
all_tx = _flat_comment_texts(comment_rows)
|
||||
suggest_path = run_dir / "keyword_suggest_llm.json"
|
||||
suggest_record: dict[str, Any] = {
|
||||
|
||||
@ -426,7 +426,7 @@ def generate_report_charts(run_dir: Path, brief: dict[str, Any]) -> list[str]:
|
||||
sku = str(s.get("sku_id") or "").strip()
|
||||
# 与 §5 矩阵「产品」列一致:纵轴优先品名,无标题时再退化为 SKU
|
||||
if title:
|
||||
label = title if len(title) <= 30 else title[:28] + "…"
|
||||
label = title if len(title) <= 48 else title[:46] + "…"
|
||||
elif sku:
|
||||
label = sku if len(sku) <= 22 else sku[:20] + "…"
|
||||
else:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user