马一丁

Optimize SWOT prompts and information processing methods

@@ -183,8 +183,17 @@ swot_item_schema: Dict[str, Any] = { @@ -183,8 +183,17 @@ swot_item_schema: Dict[str, Any] = {
183 "detail": {"type": "string"}, 183 "detail": {"type": "string"},
184 "description": {"type": "string"}, 184 "description": {"type": "string"},
185 "evidence": {"type": "string"}, 185 "evidence": {"type": "string"},
186 - "impact": {"type": "string"},  
187 - "score": {"type": ["number", "string"]}, 186 + "impact": {
  187 + "type": "string",
  188 + "enum": ["低", "中低", "中", "中高", "高", "极高"],
  189 + "description": "影响评级,只允许填写:低/中低/中/中高/高/极高",
  190 + },
  191 + "score": {
  192 + "type": "number",
  193 + "minimum": 0,
  194 + "maximum": 10,
  195 + "description": "评分,只允许0-10的数字",
  196 + },
188 "priority": {"type": ["string", "number"]}, 197 "priority": {"type": ["string", "number"]},
189 }, 198 },
190 "required": [], 199 "required": [],
@@ -147,6 +147,9 @@ class IRValidator: @@ -147,6 +147,9 @@ class IRValidator:
147 for idx, entry in enumerate(entries): 147 for idx, entry in enumerate(entries):
148 self._validate_swot_item(entry, f"{path}.{name}[{idx}]", errors) 148 self._validate_swot_item(entry, f"{path}.{name}[{idx}]", errors)
149 149
  150 + # SWOT impact 字段允许的评级值
  151 + ALLOWED_IMPACT_VALUES = {"低", "中低", "中", "中高", "高", "极高"}
  152 +
150 def _validate_swot_item(self, item: Any, path: str, errors: List[str]): 153 def _validate_swot_item(self, item: Any, path: str, errors: List[str]):
151 """单个SWOT条目支持字符串或带字段的对象""" 154 """单个SWOT条目支持字符串或带字段的对象"""
152 if isinstance(item, str): 155 if isinstance(item, str):
@@ -165,6 +168,33 @@ class IRValidator: @@ -165,6 +168,33 @@ class IRValidator:
165 if title is None: 168 if title is None:
166 errors.append(f"{path} 缺少 title/label/text/description 等文字字段") 169 errors.append(f"{path} 缺少 title/label/text/description 等文字字段")
167 170
  171 + # 校验 impact 字段:只允许评级值
  172 + impact = item.get("impact")
  173 + if impact is not None:
  174 + if not isinstance(impact, str) or impact not in self.ALLOWED_IMPACT_VALUES:
  175 + errors.append(
  176 + f"{path}.impact 只允许填写影响评级(低/中低/中/中高/高/极高),"
  177 + f"当前值: {impact};如需详细说明请写入 detail 字段"
  178 + )
  179 +
  180 + # 校验 score 字段:只允许 0-10 的数字
  181 + score = item.get("score")
  182 + if score is not None:
  183 + valid_score = False
  184 + if isinstance(score, (int, float)):
  185 + valid_score = 0 <= score <= 10
  186 + elif isinstance(score, str):
  187 + # 兼容字符串形式的数字
  188 + try:
  189 + numeric_score = float(score)
  190 + valid_score = 0 <= numeric_score <= 10
  191 + except ValueError:
  192 + valid_score = False
  193 + if not valid_score:
  194 + errors.append(
  195 + f"{path}.score 只允许填写 0-10 的数字,当前值: {score}"
  196 + )
  197 +
168 def _validate_blockquote_block( 198 def _validate_blockquote_block(
169 self, block: Dict[str, Any], path: str, errors: List[str] 199 self, block: Dict[str, Any], path: str, errors: List[str]
170 ): 200 ):
@@ -304,7 +304,7 @@ SYSTEM_PROMPT_CHAPTER_JSON = f""" @@ -304,7 +304,7 @@ SYSTEM_PROMPT_CHAPTER_JSON = f"""
304 3. 所有段落都放入paragraph.inlines,混排样式通过marks表示(bold/italic/color/link等)。 304 3. 所有段落都放入paragraph.inlines,混排样式通过marks表示(bold/italic/color/link等)。
305 4. 所有heading必须包含anchor,锚点与编号保持模板一致,比如section-2-1。 305 4. 所有heading必须包含anchor,锚点与编号保持模板一致,比如section-2-1。
306 5. 表格需给出rows/cells/align,KPI卡请使用kpiGrid,分割线用hr。 306 5. 表格需给出rows/cells/align,KPI卡请使用kpiGrid,分割线用hr。
307 -6. SWOT分析必须优先使用 block.type="swotTable":分别填写 strengths/weaknesses/opportunities/threats 数组,单项至少包含 title/label/text 之一,可附加 detail/evidence/impact/score 字段;title/summary 字段用于概览说明。 307 +6. SWOT分析必须优先使用 block.type="swotTable":分别填写 strengths/weaknesses/opportunities/threats 数组,单项至少包含 title/label/text 之一,可附加 detail/evidence/impact/score 字段;title/summary 字段用于概览说明。**特别注意:impact 字段只允许填写影响评级("低"/"中低"/"中"/"中高"/"高"/"极高"),score 字段只允许填写 0-10 的数字;任何关于影响的文字叙述、详细说明、佐证或扩展描述必须写入 detail 字段,禁止在 impact 字段中混入描述性文字。**
308 7. 如需引用图表/交互组件,统一用widgetType表示(例如chart.js/line、chart.js/doughnut)。 308 7. 如需引用图表/交互组件,统一用widgetType表示(例如chart.js/line、chart.js/doughnut)。
309 8. 鼓励结合outline中列出的子标题,生成多层heading与细粒度内容,同时可补充callout、blockquote等。 309 8. 鼓励结合outline中列出的子标题,生成多层heading与细粒度内容,同时可补充callout、blockquote等。
310 9. engineQuote 仅用于呈现单Agent的原话:使用 block.type="engineQuote",engine 取值 insight/media/query,title 必须固定为对应Agent名字(insight->Insight Agent,media->Media Agent,query->Query Agent,不可自定义),内部 blocks 只允许 paragraph,paragraph.inlines 的 marks 仅可使用 bold/italic(可留空),禁止在 engineQuote 中放表格/图表/引用/公式等;当 reports 或 forumLogs 中有明确的文字段落、结论、数字/时间等可直接引用时,优先分别从 Query/Media/Insight 三个 Agent 摘出关键原文或文字版数据放入 engineQuote,尽量覆盖三类 Agent 而非只用单一来源,严禁臆造内容或把表格/图表改写进 engineQuote。 310 9. engineQuote 仅用于呈现单Agent的原话:使用 block.type="engineQuote",engine 取值 insight/media/query,title 必须固定为对应Agent名字(insight->Insight Agent,media->Media Agent,query->Query Agent,不可自定义),内部 blocks 只允许 paragraph,paragraph.inlines 的 marks 仅可使用 bold/italic(可留空),禁止在 engineQuote 中放表格/图表/引用/公式等;当 reports 或 forumLogs 中有明确的文字段落、结论、数字/时间等可直接引用时,优先分别从 Query/Media/Insight 三个 Agent 摘出关键原文或文字版数据放入 engineQuote,尽量覆盖三类 Agent 而非只用单一来源,严禁臆造内容或把表格/图表改写进 engineQuote。