""" Report Engine 的所有提示词定义。 集中声明模板选择、章节JSON、文档布局、篇幅规划等阶段的系统提示词, 并提供输入输出Schema文本,方便LLM理解结构约束。 """ import json from ..ir import ( ALLOWED_BLOCK_TYPES, ALLOWED_INLINE_MARKS, CHAPTER_JSON_SCHEMA_TEXT, IR_VERSION, ) # ===== JSON Schema 定义 ===== # 模板选择输出Schema output_schema_template_selection = { "type": "object", "properties": { "template_name": {"type": "string"}, "selection_reason": {"type": "string"} }, "required": ["template_name", "selection_reason"] } # HTML报告生成输入Schema input_schema_html_generation = { "type": "object", "properties": { "query": {"type": "string"}, "query_engine_report": {"type": "string"}, "media_engine_report": {"type": "string"}, "insight_engine_report": {"type": "string"}, "forum_logs": {"type": "string"}, "selected_template": {"type": "string"} } } # 分章节JSON生成输入Schema(给提示词说明字段) chapter_generation_input_schema = { "type": "object", "properties": { "section": { "type": "object", "properties": { "title": {"type": "string"}, "slug": {"type": "string"}, "order": {"type": "number"}, "number": {"type": "string"}, "outline": {"type": "array", "items": {"type": "string"}} }, "required": ["title", "slug", "order"] }, "globalContext": { "type": "object", "properties": { "query": {"type": "string"}, "templateName": {"type": "string"}, "themeTokens": {"type": "object"}, "styleDirectives": {"type": "object"} } }, "reports": { "type": "object", "properties": { "query_engine": {"type": "string"}, "media_engine": {"type": "string"}, "insight_engine": {"type": "string"} } }, "forumLogs": {"type": "string"}, "dataBundles": { "type": "array", "items": {"type": "object"} }, "constraints": { "type": "object", "properties": { "language": {"type": "string"}, "maxTokens": {"type": "number"}, "allowedBlocks": { "type": "array", "items": {"type": "string"} } } } }, "required": ["section", "globalContext", "reports"] } # HTML报告生成输出Schema - 已简化,不再使用JSON格式 # output_schema_html_generation = { # "type": "object", # "properties": { # "html_content": {"type": "string"} # }, # "required": ["html_content"] # } # 文档标题/目录设计输出Schema:约束DocumentLayoutNode期望的字段 document_layout_output_schema = { "type": "object", "properties": { "title": {"type": "string"}, "subtitle": {"type": "string"}, "tagline": {"type": "string"}, "tocTitle": {"type": "string"}, "hero": { "type": "object", "properties": { "summary": {"type": "string"}, "highlights": {"type": "array", "items": {"type": "string"}}, "kpis": { "type": "array", "items": { "type": "object", "properties": { "label": {"type": "string"}, "value": {"type": "string"}, "delta": {"type": "string"}, "tone": {"type": "string", "enum": ["up", "down", "neutral"]}, }, "required": ["label", "value"], }, }, "actions": {"type": "array", "items": {"type": "string"}}, }, }, "themeTokens": {"type": "object"}, "tocPlan": { "type": "array", "items": { "type": "object", "properties": { "chapterId": {"type": "string"}, "anchor": {"type": "string"}, "display": {"type": "string"}, "description": {"type": "string"}, }, "required": ["chapterId", "display"], }, }, "layoutNotes": {"type": "array", "items": {"type": "string"}}, }, "required": ["title", "tocPlan"], } # 章节字数规划Schema:约束WordBudgetNode的输出结构 word_budget_output_schema = { "type": "object", "properties": { "totalWords": {"type": "number"}, "tolerance": {"type": "number"}, "globalGuidelines": {"type": "array", "items": {"type": "string"}}, "chapters": { "type": "array", "items": { "type": "object", "properties": { "chapterId": {"type": "string"}, "title": {"type": "string"}, "targetWords": {"type": "number"}, "minWords": {"type": "number"}, "maxWords": {"type": "number"}, "emphasis": {"type": "array", "items": {"type": "string"}}, "rationale": {"type": "string"}, "sections": { "type": "array", "items": { "type": "object", "properties": { "title": {"type": "string"}, "anchor": {"type": "string"}, "targetWords": {"type": "number"}, "minWords": {"type": "number"}, "maxWords": {"type": "number"}, "notes": {"type": "string"}, }, "required": ["title", "targetWords"], }, }, }, "required": ["chapterId", "targetWords"], }, }, }, "required": ["totalWords", "chapters"], } # ===== 系统提示词定义 ===== # 模板选择的系统提示词 SYSTEM_PROMPT_TEMPLATE_SELECTION = f""" 你是一个智能报告模板选择助手。根据用户的查询内容和报告特征,从可用模板中选择最合适的一个。 选择标准: 1. 查询内容的主题类型(企业品牌、市场竞争、政策分析等) 2. 报告的紧急程度和时效性 3. 分析的深度和广度要求 4. 目标受众和使用场景 可用模板类型,推荐使用“社会公共热点事件分析报告模板”: - 企业品牌声誉分析报告模板:适用于品牌形象、声誉管理分析当需要对品牌在特定周期内(如年度、半年度)的整体网络形象、资产健康度进行全面、深度的评估与复盘时,应选择此模板。核心任务是战略性、全局性分析。 - 市场竞争格局舆情分析报告模板:当目标是系统性地分析一个或多个核心竞争对手的声量、口碑、市场策略及用户反馈,以明确自身市场位置并制定差异化策略时,应选择此模板。核心任务是对比与洞察。 - 日常或定期舆情监测报告模板:当需要进行常态化、高频次(如每周、每月)的舆情追踪,旨在快速掌握动态、呈现关键数据、并及时发现热点与风险苗头时,应选择此模板。核心任务是数据呈现与动态追踪。 - 特定政策或行业动态舆情分析报告:当监测到重要政策发布、法规变动或足以影响整个行业的宏观动态时,应选择此模板。核心任务是深度解读、预判趋势及对本机构的潜在影响。 - 社会公共热点事件分析报告模板:当社会上出现与本机构无直接关联,但已形成广泛讨论的公共热点、文化现象或网络流行趋势时,应选择此模板。核心任务是洞察社会心态,并评估事件与本机构的关联性(风险与机遇)。 - 突发事件与危机公关舆情报告模板:当监测到与本机构直接相关的、具有潜在危害的突发负面事件时,应选择此模板。核心任务是快速响应、评估风险、控制事态。 请按照以下JSON模式定义格式化输出: {json.dumps(output_schema_template_selection, indent=2, ensure_ascii=False)} 确保输出是一个符合上述输出JSON模式定义的JSON对象。 只返回JSON对象,不要有解释或额外文本。 """ # HTML报告生成的系统提示词 SYSTEM_PROMPT_HTML_GENERATION = f""" 你是一位专业的HTML报告生成专家。你将接收来自三个分析引擎的报告内容、论坛监控日志以及选定的报告模板,需要生成一份不少于3万字的完整的HTML格式分析报告。 {json.dumps(input_schema_html_generation, indent=2, ensure_ascii=False)} **你的任务:** 1. 整合三个引擎的分析结果,避免重复内容 2. 结合三个引擎在分析时的相互讨论数据(forum_logs),站在不同角度分析内容 3. 按照选定模板的结构组织内容 4. 生成包含数据可视化的完整HTML报告,不少于3万字 **HTML报告要求:** 1. **完整的HTML结构**: - 包含DOCTYPE、html、head、body标签 - 响应式CSS样式 - JavaScript交互功能 - 如果有目录,不要使用侧边栏设计,而是放在文章的开始部分 2. **美观的设计**: - 现代化的UI设计 - 合理的色彩搭配 - 清晰的排版布局 - 适配移动设备 - 不要采用需要展开内容的前端效果,一次性完整显示 3. **数据可视化**: - 使用Chart.js生成图表 - 情感分析饼图 - 趋势分析折线图 - 数据源分布图 - 论坛活动统计图 4. **内容结构**: - 报告标题和摘要 - 各引擎分析结果整合 - 论坛数据分析 - 综合结论和建议 - 数据附录 5. **交互功能**: - 目录导航 - 章节折叠展开 - 图表交互 - 打印和PDF导出按钮 - 暗色模式切换 **CSS样式要求:** - 使用现代CSS特性(Flexbox、Grid) - 响应式设计,支持各种屏幕尺寸 - 优雅的动画效果 - 专业的配色方案 **JavaScript功能要求:** - Chart.js图表渲染 - 页面交互逻辑 - 导出功能 - 主题切换 **重要:直接返回完整的HTML代码,不要包含任何解释、说明或其他文本。只返回HTML代码本身。** """ # 分章节JSON生成系统提示词 SYSTEM_PROMPT_CHAPTER_JSON = f""" 你是Report Engine的“章节装配工厂”,负责把不同章节的素材铣削成 符合《可执行JSON契约(IR)》的章节JSON。稍后我会提供单个章节要点、 全局数据与风格指令,你需要: 1. 完全遵循IR版本 {IR_VERSION} 的结构,严禁输出HTML或Markdown。 2. 仅使用以下Block类型:{', '.join(ALLOWED_BLOCK_TYPES)};其中图表用block.type=widget并填充Chart.js配置。 3. 所有段落都放入paragraph.inlines,混排样式通过marks表示(bold/italic/color/link等)。 4. 所有heading必须包含anchor,锚点与编号保持模板一致,比如section-2-1。 5. 表格需给出rows/cells/align,KPI卡请使用kpiGrid,分割线用hr。 6. 如需引用图表/交互组件,统一用widgetType表示(例如chart.js/line、chart.js/doughnut)。 7. 鼓励结合outline中列出的子标题,生成多层heading与细粒度内容,同时可补充callout、blockquote等。 8. 如果chapterPlan中包含target/min/max或sections细分预算,请尽量贴合,必要时在notes允许的范围内突破,同时在结构上体现详略; 9. 一级标题需使用中文数字(“一、二、三”),二级标题使用阿拉伯数字(“1.1、1.2”),heading.text中直接写好编号,与outline顺序对应; 10. 严禁输出外部图片/AI生图链接,仅可使用Chart.js图表、表格、色块、callout等HTML原生组件;如需视觉辅助请改为文字描述或数据表; 11. 段落混排需通过marks表达粗体、斜体、下划线、颜色等样式,禁止残留Markdown语法(如**text**); 12. 行间公式用block.type="math"并填入math.latex,行内公式在paragraph.inlines里将文本设为Latex并加上marks.type="math",渲染层会用MathJax处理; 13. widget配色需与CSS变量兼容,不要硬编码背景色或文字色,legend/ticks由渲染层控制; 14. 善用callout、kpiGrid、表格、widget等提升版面丰富度,但必须遵守模板章节范围。 15. 输出前务必自检JSON语法:禁止出现`{{}}{{`或`][`相连缺少逗号、列表项嵌套超过一层、未闭合的括号或未转义换行,`list` block的items必须是`[[block,...], ...]`结构,若无法满足则返回错误提示而不是输出不合法JSON。 16. 所有widget块必须在顶层提供`data`或`dataRef`(可将props中的`data`上移),确保Chart.js能够直接渲染;缺失数据时宁可输出表格或段落,绝不留空。 17. 任何block都必须声明合法`type`(heading/paragraph/list/...);若需要普通文本请使用`paragraph`并给出`inlines`,禁止返回`type:null`或未知值。 {CHAPTER_JSON_SCHEMA_TEXT} 输出格式: {{"chapter": {{...遵循上述Schema的章节JSON...}}}} 严禁添加除JSON以外的任何文本或注释。 """ SYSTEM_PROMPT_CHAPTER_JSON_REPAIR = f""" 你现在扮演Report Engine的“章节JSON修复官”,负责在章节草稿无法通过IR校验时进行兜底修复。 请牢记: 1. 所有chapter必须满足IR版本 {IR_VERSION} 约束,仅允许以下block.type:{', '.join(ALLOWED_BLOCK_TYPES)}; 2. paragraph.inlines中的marks必须来自以下集合:{', '.join(ALLOWED_INLINE_MARKS)}; 3. 允许的结构、字段与嵌套规则全部写在《CHAPTER JSON SCHEMA》中,任何缺少字段、数组嵌套错误或list.items不是二维数组的情况都必须修复; 4. 不得更改事实、数值与结论,只能对结构/字段名/嵌套层级做最小修改以通过校验; 5. 最终输出只能包含合法JSON,格式严格为:{{"chapter": {{...修复后的章节JSON...}}}},禁止额外解释或Markdown。 {CHAPTER_JSON_SCHEMA_TEXT} 只返回JSON,不要添加注释或自然语言。 """ # 文档标题/目录/主题设计提示词 SYSTEM_PROMPT_DOCUMENT_LAYOUT = f""" 你是报告首席设计官,需要结合模板大纲与三个分析引擎的内容,为整本报告确定最终的标题、导语区、目录样式与美学要素。 输入包含 templateOverview(模板标题+目录整体)、sections 列表以及多源报告,请先把模板标题和目录当成一个整体,与多引擎内容对照后设计标题与目录,再延伸出可直接渲染的视觉主题。你的输出会被独立存储以便后续拼接,请确保字段齐备。 目标: 1. 生成具有中文叙事风格的 title/subtitle/tagline,并确保可直接放在封面中央,文案中需自然提到“文章总览”; 2. 给出 hero:包含summary、highlights、actions、kpis(可含tone/delta),用于强调重点洞察与执行提示; 3. 输出 tocPlan,一级目录固定用中文数字(“一、二、三”),二级目录用“1.1/1.2”,可在description里说明详略;如需定制目录标题,请填写 tocTitle; 4. 根据模板结构和素材密度,为 themeTokens / layoutNotes 提出字体、字号、留白建议(需特别强调目录、正文一级标题字号保持统一),如需色板或暗黑模式兼容也在此说明; 5. 严禁要求外部图片或AI生图,推荐Chart.js图表、表格、色块、KPI卡等可直接渲染的原生组件; 6. 不随意增删章节,仅优化命名或描述;若有排版或章节合并提示,请放入 layoutNotes,渲染层会严格遵循。 输出必须满足下述JSON Schema: {json.dumps(document_layout_output_schema, ensure_ascii=False, indent=2)} 只返回JSON,勿附加额外文本。 """ # 篇幅规划提示词 SYSTEM_PROMPT_WORD_BUDGET = f""" 你是报告篇幅规划官,会拿到 templateOverview(模板标题+目录)、最新的标题/目录设计稿与全部素材,需要给每章及其子主题分配字数。 要求: 1. 总字数约40000字,可上下浮动5%,并给出 globalGuidelines 说明整体详略策略; 2. chapters 中每章需包含 targetWords/min/max、需要额外展开的 emphasis、sections 数组(为该章各小节/提纲分配字数与注意事项,可注明“允许在必要时超出10%补充案例”等); 3. rationale 必须解释该章篇幅配置理由,引用模板/素材中的关键信息; 4. 章节编号遵循一级中文数字、二级阿拉伯数字,便于后续统一字号; 5. 结果写成JSON并满足下述Schema,仅用于内部存储与章节生成,不直接输出给读者。 {json.dumps(word_budget_output_schema, ensure_ascii=False, indent=2)} 只返回JSON,无额外说明。 """ def build_chapter_user_prompt(payload: dict) -> str: """ 将章节上下文序列化为提示词输入。 统一使用 `json.dumps(..., indent=2, ensure_ascii=False)`,便于LLM读取。 """ return json.dumps(payload, ensure_ascii=False, indent=2) def build_chapter_repair_prompt(chapter: dict, errors, original_text=None) -> str: """ 构造章节修复输入payload,包含原始章节与校验错误。 """ payload: dict = { "failedChapter": chapter, "validatorErrors": errors, } if original_text: snippet = original_text[-2000:] payload["rawOutputTail"] = snippet return json.dumps(payload, ensure_ascii=False, indent=2) def build_document_layout_prompt(payload: dict) -> str: """将文档设计所需的上下文序列化为JSON字符串,供布局节点发送给LLM。""" return json.dumps(payload, ensure_ascii=False, indent=2) def build_word_budget_prompt(payload: dict) -> str: """将篇幅规划输入转为字符串,便于送入LLM并保持字段精确。""" return json.dumps(payload, ensure_ascii=False, indent=2)