#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
File: PromptTemplates.py
Author: oyyz
Date: 2025-05-13
Description: 提示词模板
"""

extract_nouns_prompt="""
【智能关键词提取助手】
请根据用户问题自动识别核心关键词，并按照以下规则输出：
1. 只输出最终关键词列表，不要解释说明
2. 关键词提取范围包括但不限于以下内容：
   - 软件相关：软件名称/功能模块/操作步骤/报错提示/扩展名后缀名
   - 造价专业：费用类型/计算标准/行业规范/文件
   - 电力工程：项目类型/设备型号/工程阶段
3. 自动展开缩写（如将'导excel'转为'导入Excel'）
4. 严格基于用户问题提取关键词，不要输出与用户问题无关的关键词
5. 不要擅自揣摩、猜测、推断关键词，不要修改关键的信息(如：粘贴excel->导入excel)

三、输出格式:
{output_format}
    
四、用户问题:
{content}

"""

classification_info="""【垂直领域分类】：
1. 软件问题 -- 指涉及软件使用、功能询问、软件故障排查等方面的提问或请求。
2. 业务问题 -- 指涉及电力造价领域专业知识、造价费用计算等电力造价业务知识
3. 安装下载注册 -- 指涉及软件(或插件)安装下载、注册、激活等操作类问题。
4. 固定话术类 -- 指涉及需要固定话术回答的问题，如：规费咨询
5. 其他 -- 指与软件或电力造价专业无关的日常对话、问候、感慨、情绪表达等。

【软件问题包括以下两类】：
1. 软件功能：询问软件功能的使用、功能操作(调整)、功能位置、如何设置、如何转换等
2. 故障排查：软件运行异常、软件报错、软件显示错误等

【业务问题包括以下两类】：
1. 专业咨询：涉及电力造价规范、工程计价规则问题、行业标准解读等
2. 数据问题：涉及电力造价费用、造价指标的计算或构成等

【安装下载注册包括以下三类】：
1. 后缀名咨询：所有涉及文件扩展名的使用场景、软件关联等问题，包括但不限于：询问文件是否由特定软件打开、扩展名与软件的匹配关系、扩展名含义及关联等
示例：
"这个文件用配网软件能打开吗？（隐含扩展名关联）",
".bphq18 是什么类型的文件？",
"用哪个软件打开.BDY3文件？",
"BDD3是什么"
2. 软件锁类：询问软件锁信息、锁注册号查询、许可证查询、锁激活问题等软件锁相关问题
形如: 8116 开头连续的12位数字 或者 形如 xx-xxxxxx 的数字格式 的内容为锁的注册号，提问出现对应内容时，归类为软件锁类
3. 安装下载类：安装下载咨询、组件(插件)选择、环境配置、安装包下载、政策文件(规范文件)下载等
4. 问题排查类：软件安装下载失败、报错，系统兼容性问题等

【固定话术类包括以下一类】：
1. 规费咨询：咨询规费(规费、社保费、公积金费等)费用考虑、构成、设置等。才属于该类
规费报表在哪显示-->属于软件功能
规费怎么设置、社保费是多少-->属于规费咨询
【其他】:
1. 其他

分类优先级：
 固定话术类 > 软件问题 、 业务问题 、 安装下载注册 > 其他
"""

classification_prompt="""
    用户正在使用电力造价软件或想询问电力造价领域相关知识，你需要根据用户的输入内容集合历史对话(如果存在)，将其归类为以下垂直领域之一：
    {classification_info}

   ## 【历史对话记录】
   {chat_history}

    【用户输入】：
    {user_input}

    【输出格式要求】：
    {output_format}

    【示例】
    用户输入1: 技改T1怎样新建工程
    输出1:
    {{
    "vertical_classification":"软件咨询",
    "sub_classification":"软件功能"
    }}


   用户输入2: BDD3是什么
    输出2:
    {{
    "vertical_classification":"安装下载注册",
    "sub_classification":"后缀名咨询"
    }}
"""

query_rewrite_prompt = """

# 电力造价专业问答优化工程师

你是一名电力造价专业问答优化工程师，负责通过专业关键词集合替换原始问题中的非专业表述以提升知识库检索准确率。

## 核心任务
将用户的原始问题结合专业术语库进行规范化重构，提高知识库检索的准确性和专业性。

## 处理流程
### 第一阶段：输入解析
1. 解析基础信息
   - 原始问题(需保留核心语义)：{query}
   - 关键词集合：{keywords}

### 第二阶段：匹配分析
**匹配规则：**
1. 检查原始问题中是否包含关键词集合中的`name`字段或`synonymous`字段中的任何词汇
2. 统计匹配的术语数量
3. 判断执行路径：
   - 匹配术语 ≥ 1个 → 执行重构流程
   - 匹配术语 = 0个 → 直接输出原始问题

### 第三阶段：问题重构
**重构原则（按优先级排序）：**

1. **语义保真**：严格保持原问题的核心意图和诉求
2. **术语规范**：
   - 将匹配到的同义词替换为对应的标准术语（name字段）
   - 对在关键词中的标准术语使用【】进行标记
   - 保留在原问题中未在关键词库中的专业术语、限定词和修饰词
3. **结构优化**：
   - 保持原问题的语态特征5W2H
   - 保持主谓宾结构清晰
   - 保留时间、版本等限定条件

**术语处理规则：**
- 优先级1：保留原问题中的专业术语、限定词和修饰词（即使不在关键词库中）
- 优先级2：将同义词替换为标准术语并用【】标记
- 优先级3：对原问题中已存在的标准术语添加【】标记
      
# 输出规范
{output_format}

# 示范案例库
▶ 案例1（有效匹配）
输入：
原始问题：怎么把旧版西藏定额工程转到Z1新版
关键词：【'老版本定额升级', '批量设置定额', '西藏造价软件Z1'】
输出：
{{"rewrite":"【西藏造价软件Z1】如何执行【老版本定额升级】操作？"}}

▶ 案例2（无效匹配）
输入：
原始问题：程序界面文字显示过小如何处理？
关键词：【'定额升级', '工程批量导入'】
输出：
{{"rewrite":"程序界面文字显示过小如何处理？"}}

▶ 案例3（部分匹配，但保留修饰限定词）
输入：
原始问题："配网软件D3能导出清单的计算公式吗？
关键词：【'配网工程计价通D3软件', '计算式'】
输出(保留限定修饰词"清单")：
{{"rewrite":"【配网工程计价通D3软件】能导出清单的【计算式】吗？"}}

## 质量检查清单
执行前请确认：
- [ ] 是否保持了原问题的核心诉求？
- [ ] 是否正确执行了同义词替换？
- [ ] 是否保留了原问题中的专业术语和限定条件？
- [ ] 是否正确使用了【】标记？
- [ ] 重构后的问题是否自然流畅？
    """


query_rewrite_prompt_pro="""
# 问答优化工程师
**角色**：基于历史对话和术语库重构问题，提升知识库检索准确率。
**最高准则**：
1、保持问题核心意图，允许指代消除
2. 所有新增内容必须源于历史对话或聊天背景，禁止捏造。  
3. 归一化替换需严格全词匹配：查询中的词必须与术语库同义词完全一致(不区分大小写)。部分匹配（如子字符串）或不匹配，保留原词 


## 核心原则
1. **指代消除 → 当指示代词（"那"/"这"）出现时，强制继承历史对话的最新核心主题（如功能或任务），并应用到当前主体。**  
2. 术语规范 → 提问中出现的同义词(synonymous)替换为标准词(name)并【】标记
3. 语义保真 → 保持问题核心意图，允许指代消除

## 归一化替换规则
1. 只有当问题中的词与术语库中某一项的同义词列表中的某个词完全相同时，才替换为对应的标准词


## 处理流程
### 一、输入解析
   - 原始问题(需保留核心语义):
   <query> {query} </query>

   - 术语库集合(用于同义词转标准词环节)：
   <keywords>
   {keywords}
   </keywords>

   - 历史对话记录：
   <history>
   {chat_history}
   </history>

### 一、重构流程
1、问题是否指代不明，指代不明时根据历史对话补充上下文
2、问题是否包含同义词，包含同义词时进行同义词转标准词

### 三、重构优先级
1. **指代消除 → 当指示代词出现时，结合历史对话补充上下文**  
2. 同义词转标准词 → 将提问中出现的同义词(synonymous)替换为对应标准词(name) 并使用【】标记
3. 结构优化 → 保持原问题的5W2H特征，指代消除、背景继承下允许微调意图。

## 输出规范
{output_format}

## 质量自检
- [] **主题是否合理继承？**
- [] 核心诉求是否保留？
- [] 语句是否自然流畅？
- [] 避免补充无关信息
"""

slot_filling_prompt = """
你是一个专业的电力造价领域问题槽位填充助手。你需要从用户问题中提取关键信息，并填充到对应的数据结构中。

【用户问题】
{query}

## 【会话背景信息】
{conversation_context}

## 【历史对话记录】
{chat_history}

## 【历史槽位信息】
{previous_slots}

【问题分类】
垂直领域分类: {vertical_classification}
子分类: {sub_classification}

【输出格式】
{output_format}

【任务要求】
1. 仔细分析用户问题，从中提取所有可能的槽位信息
2. 对于必填槽位，必须尽力从问题中提取，如果确实无法提取则留空
3. 对于选填槽位，如果能从问题中提取则填写，否则留空
4. 只输出符合格式的JSON数据，不要有任何额外的解释

【示例】
用户问题: "我的西藏Z1软件，新建工程报错：找不到许可证，怎么解决？"
分类: 软件问题/故障排查
输出:
{{
  "software_name": "西藏电力工程计价通Z1软件",
  "function_name": "新建工程",
  "error_message": "报错：找不到许可证",
  "software_version": null,
  "os_version": null,
  "reproduction_steps": "新建工程"
}}
"""

# 意图优化环节提示词模板
step_back_prompt = """
# 后退提示生成器

你是一个专业的电力造价领域问题抽象专家。你的任务是根据用户的具体问题，提出一个更抽象、更高层次的问题，帮助系统更好地理解用户的意图。

## 任务说明
1. 分析用户的原始问题，理解其核心意图和需求
2. 考虑历史对话和会话背景，理解用户当前问题的上下文
3. 生成更抽象、更高层次的问题，称为"后退问题",后退问题可以生成多个，依次后退到更抽象、更高层次的问题
4. 后退问题应该：
   - 更加通用和抽象，不应包含原始问题的具体细节(包括场景限定、界面限定等其他限定词语)
   - 涵盖原始问题的核心主题
   - 去除过于具体的限制条件（如时间、地点、特定版本、特定工程等）
   - 保持在同一领域和主题范围内
   - 依次移除问题中的限定词或者修饰词

## 输入
用户原始问题: {query}
历史对话记录: {chat_history}

## 输出格式
{output_format}

## 示例
原始问题: "2023版本如何在Windows 11系统上导入单位工程量清单？"
后退问题: 
{{
    "original_query": "2023版本如何在Windows 11系统上导入单位工程量清单？",
    "can_use_back_prompt": True,
    "step_back_query": ["如何在Windows 11系统上导入单位工程量清单？", "如何导入单位工程量清单？"]
}}

原始问题: "某个设备更换后，如何在系统中更新对应的定额？"
后退问题: 
{{
    "original_query": "某个设备更换后，如何在系统中更新对应的定额？",
    "can_use_back_prompt": True,
    "step_back_query": ["如何更新设备对应的定额？", "如何更新定额？"]
}}

"""

follow_up_questions_prompt = """
# 后续问题生成器

你是一个专业的电力造价领域对话理解专家。你的任务是根据历史对话和当前问题，生成一个完整的独立问题，确保即使没有历史上下文也能理解。

## 任务说明
1. 分析历史对话记录和当前用户问题
2. 识别当前问题中可能引用了历史对话的部分（如代词、省略内容等）
3. 生成一个完整的独立问题，该问题应该：
   - 包含历史对话中的关键上下文
   - 明确指代所有代词和省略内容
   - 保持原问题的核心意图不变
   - 即使没有历史对话也能被理解

## 输入
历史对话记录: {chat_history}
当前用户问题: {query}

## 输出格式
{output_format}

## 示例
历史对话:
用户: "我在使用配网D3软件"
助手: "好的，请问您遇到什么问题？"
当前问题: "怎么导入清单？"
生成的独立问题: "在配网D3软件中，怎么导入清单？"

历史对话:
用户: "技改T1软件中的设备更换功能在哪里？"
助手: "设备更换功能在'工程管理'菜单下的'设备管理'子菜单中。"
当前问题: "更新后如何保存？"
生成的独立问题: "在技改T1软件中使用设备更换功能后，如何保存更新的设备信息？"
"""

hyde_prompt = """
# 假设性文档生成器

你是一个专业的电力造价领域知识专家。你的任务是根据用户的问题和历史对话，生成一个假设性的回答，该回答可能包含的信息和模式将有助于在知识库中检索相关文档。

## 任务说明
1. 分析用户的问题，理解其核心意图和需求
2. 考虑历史对话和会话背景，理解用户当前问题的上下文
3. 生成一个假设性的回答，该回答应该：
   - 尽可能准确地回答用户问题
   - 包含可能与问题相关的专业术语和概念
   - 包含可能在知识库文档中出现的模式和结构
   - 考虑历史对话中的相关信息
   - 即使你不确定答案的准确性，也要提供一个合理的假设

## 输入
用户问题: {query}
历史对话记录: {chat_history}

## 输出格式
{output_format}

## 示例
用户问题: "配网D3软件如何导入Excel清单？"
假设性回答: "在配网D3软件中导入Excel清单的步骤如下：
1. 打开配网D3软件，进入工程管理模块
2. 点击菜单栏中的'导入/导出'选项
3. 选择'导入Excel清单'功能
4. 在弹出的对话框中选择已准备好的Excel文件
5. 确认导入格式和映射关系
6. 点击'确定'完成导入
注意：导入的Excel文件需要符合特定的格式要求，建议先在软件中导出一个样例文件作为模板。"
"""

multi_questions_prompt = """
# 多角度问题生成器

你是一个专业的电力造价领域问题分解专家。你的任务是根据用户的原始问题和历史对话，从不同角度生成多个子问题，以帮助系统更全面地理解和回答用户的需求。

## 任务说明
1. 分析用户的原始问题，理解其核心意图和需求
2. 考虑历史对话和会话背景，理解用户当前问题的上下文
3. 从不同角度生成1-3个子问题，这些子问题应该：
   - 分别关注原始问题的不同方面或组成部分
   - 更加具体和直接
   - 共同覆盖原始问题的完整意图
   - 考虑历史对话中的相关信息
   - 每个子问题都应该是自包含的，可以独立回答

## 输入
用户原始问题: {query}
历史对话记录: {chat_history}

## 输出格式
{output_format}

## 示例
原始问题: "配网D3软件中如何处理定额调整和工程量清单导入？"
子问题:
1. "配网D3软件中如何进行定额调整？"
2. "配网D3软件中如何导入工程量清单？"
3. "定额调整后，是否会影响已导入的工程量清单？"
按格式输出：
{{
   "original_query":"配网D3软件中如何处理定额调整和工程量清单导入？"
    "sub_questions": [
        "配网D3软件中如何进行定额调整？",
        "配网D3软件中如何导入工程量清单？",
        "定额调整后，是否会影响已导入的工程量清单？"
    ]
}}

原始问题: "技改T1软件和配网D3软件的区别是什么？"
子问题:
1. "技改T1软件的主要功能和适用范围是什么？"
2. "配网D3软件的主要功能和适用范围是什么？"
3. "技改T1软件和配网D3软件在使用场景上有什么不同？"
4. "如何选择使用技改T1软件还是配网D3软件？"
按格式输出：
{{
   "original_query":"技改T1软件和配网D3软件的区别是什么？"
   "sub_questions": [
      "技改T1软件的主要功能和适用范围是什么？",
      "配网D3软件的主要功能和适用范围是什么？",
      "技改T1软件和配网D3软件在使用场景上有什么不同？",
      "如何选择使用技改T1软件还是配网D3软件？"
   ]
}}
"""