From ed2738953ffe547d7cb995383c120b5d488d1fef Mon Sep 17 00:00:00 2001 From: hub-gif <2487812171@qq.com> Date: Mon, 13 Apr 2026 10:54:43 +0800 Subject: [PATCH] =?UTF-8?q?refactor(=E6=8A=A5=E5=91=8A):=20=E5=85=A8?= =?UTF-8?q?=E6=96=87=E5=A4=A7=E6=A8=A1=E5=9E=8B=E8=A1=A5=E5=85=85=E6=94=B9?= =?UTF-8?q?=E4=B8=BA=E5=B5=8C=E5=85=A5=E7=AC=AC=E5=85=AB=E7=AB=A0=E6=9C=AB?= =?UTF-8?q?=E8=80=8C=E9=9D=9E=E7=AF=87=E9=A6=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Made-with: Cursor --- backend/pipeline/jd_runner.py | 44 ++++++++++++++++++++++++-------- backend/pipeline/llm_generate.py | 25 ++++++++++-------- 2 files changed, 47 insertions(+), 22 deletions(-) diff --git a/backend/pipeline/jd_runner.py b/backend/pipeline/jd_runner.py index d0c69fd..f509d3f 100644 --- a/backend/pipeline/jd_runner.py +++ b/backend/pipeline/jd_runner.py @@ -20,8 +20,8 @@ def merge_llm_supplement_with_rules_report(llm_md: str, rules_md: str) -> str: """ **以规则引擎全文为正文**(含 §5 完整竞品矩阵、各章内嵌统计图与表格)。 - 大模型稿仅作为开篇「速读/策略补充」插入在「## 一、」之前,**不得**再用纯 LLM 稿 - 覆盖规则正文(否则会丢失矩阵与章节结构)。 + 大模型稿作为 **§8.5** 嵌入在 **第八章末、第九章策略** 之前,与 §8.2~8.4 等具体分析同卷连贯, + **不再**插在篇首「## 一、」之前。 """ body = (rules_md or "").strip() sup = (llm_md or "").strip() @@ -29,17 +29,39 @@ def merge_llm_supplement_with_rules_report(llm_md: str, rules_md: str) -> str: return body if not body: return sup - block = ( - "---\n\n" - "## 大模型速读与策略要点(补充)\n\n" - "> **说明**:以下由大模型依据结构化摘要生成,便于速览;**完整竞品对比矩阵、全部表格、" - "统计图与定量口径以正文各章(尤其 §5)为准**,请勿仅依据本段理解 SKU 明细。\n\n" - f"{sup}\n" + marker = "\n---\n\n## 九、策略与机会提示(假设清单,待验证)" + insert = ( + "\n\n---\n\n" + "### 8.5 大模型深度补充(与 §2~§8.4 定量内容互补)\n\n" + "> **说明**:本段位于**第八章末**;**竞品矩阵、价盘表、统计图与 §8.2~8.4 词频等以正文各节为准**," + "此处为跨小节语义整合,便于衔接第九章。\n\n" + f"{sup.strip()}\n" + "\n---\n\n## 九、策略与机会提示(假设清单,待验证)" ) - marker = "\n---\n\n## 一、研究范围、数据来源与局限" if marker in body: - return body.replace(marker, "\n" + block + marker, 1) - return block + "\n---\n\n" + body + return body.replace(marker, insert, 1) + # 旧版报告标题或语言差异时的回退 + for alt in ( + "\n## 九、策略与机会提示(假设清单,待验证)", + "\n## 九、策略与机会提示", + ): + if alt in body and marker not in body: + return body.replace( + alt, + "\n\n---\n\n### 8.5 大模型深度补充(与 §2~§8.4 定量内容互补)\n\n" + "> **说明**:位于第八章末;**矩阵与图表以正文为准**。\n\n" + f"{sup.strip()}\n" + + alt, + 1, + ) + app = "\n## 附录 A:数据留存说明" + if app in body: + tail = ( + "\n\n---\n\n### 8.5 大模型深度补充(与 §2~§8.4 定量内容互补)\n\n" + f"{sup.strip()}\n" + ) + return body.replace(app, tail + app, 1) + return body + "\n\n---\n\n### 8.5 大模型深度补充\n\n" + sup.strip() + "\n" def merge_llm_report_with_rules_charts(llm_md: str, rules_md: str) -> str: diff --git a/backend/pipeline/llm_generate.py b/backend/pipeline/llm_generate.py index d170a4c..41fae4b 100644 --- a/backend/pipeline/llm_generate.py +++ b/backend/pipeline/llm_generate.py @@ -35,24 +35,27 @@ def _call_llm(system_prompt: str, user_prompt: str) -> str: return ac.strip_outer_markdown_fence(raw) -REPORT_SYSTEM = """你撰写一段**短小的「速读与策略补充」**,插在完整规则报告**之前**供读者扫读。读者为业务与产品。 +REPORT_SYSTEM = """你是业务与产品读者顾问。输入 JSON 含 `keyword`、`competitor_brief`(可能经裁剪)、 +`matrix_overview_for_llm`(按细分类目的 SKU 数与品牌样本)。 + +你的输出将**嵌入在规则报告第八章末**(作为「### 8.5 …」的正文,系统已加小节标题与说明),**紧接在** +消费者反馈 §8.1~8.4 **之后**、第九章策略**之前**。因此写的是**具体分析型补充**,不是篇首速读块。 -**输入**:JSON 含 `keyword`、`competitor_brief`(可能经裁剪)、`matrix_overview_for_llm`(按细分类目的 SKU 数与品牌样本)。 所有数字、占比、条数、品牌名、价格区间等**必须严格来自输入 JSON**,禁止编造未在输入中出现的定量结论。 **硬性禁止**: -- **不要**输出完整报告目录或重复「研究范围与方法」等长章结构; -- **不要**撰写 Markdown 表格版「竞品对比矩阵」或罗列 SKU 明细——**正文报告已含完整矩阵**,此处仅可概括分组级结论(细类名、SKU 数、主要品牌来自 `matrix_overview_for_llm` / brief); -- **不要**写「matrix_by_group 已省略」「仅保留代表性品牌」等免责声明,也不要引导读者认为明细缺失; +- **不要**使用「## 一」「## 八」等会打乱宿主文档的顶级章节号;请使用 ``####`` 或必要时 ``###`` 作为本段内小节标题; +- **不要**输出完整报告目录或复述「研究范围与方法」长章; +- **不要**撰写 Markdown 表格版「竞品对比矩阵」或罗列 SKU 明细——**正文已含矩阵**,此处只做分组级语义归纳; - **不要使用** CR1、CR3 等英文缩写;集中度请用「第一大品牌份额」「前三品牌合计份额」。 -**请输出**(仅输出正文,不要前言后语): -- 使用 **Markdown**,控制在约 **800~1500 字**; -- 建议小节标题(二级):**执行摘要要点**、**竞争与价盘速读**、**用户声量与关注点**、**策略提示与数据边界**; -- 若有 `comment_sentiment_lexicon`,概括正/负向粗判与局限(非深度学习);**负向**须点出用户在抱怨的**具体事由类型**(如口感、价格、物流),避免只复述词频; -- 语气专业、中文;缺失项写「本摘要未提供该项」而非猜测。""" +**请输出**(仅输出将置于 §8.5 下的正文,不要自造「### 8.5」标题行): +- **Markdown**,约 **800~1500 字**; +- 建议用 ``####`` 组织:**执行摘要级要点**、**竞争与价盘**、**用户声量与负向事由**(须归纳用户在抱怨什么类型的问题,而非只堆关键词)、**与第九章衔接的策略边界**; +- 若有 `comment_sentiment_lexicon`,概括正/负向粗判局限;**负向**写清事由类型(口感、价格、物流等); +- 语气专业、中文;缺失项写「本段未提供该项」而非猜测。""" -REPORT_USER_PREFIX = """请根据以下 JSON 撰写完整竞品分析报告(Markdown 正文)。\n\n""" +REPORT_USER_PREFIX = """请根据以下 JSON 撰写上文所述 §8.5 嵌入段落(Markdown 正文,勿加 ### 8.5 标题)。\n\n""" def generate_competitor_report_markdown_llm(brief: dict[str, Any], keyword: str) -> str: