package com.supervision.pdfqaserver.cache; import java.util.HashMap; import java.util.Map; /** * 提示词缓存 */ public class PromptCache { public static final String DOERE_TEXT = "DOERE_TEXT"; public static final String DOERE_TABLE = "DOERE_TABLE"; public static final String TEXT_TO_CYPHER = "TEXT_TO_CYPHER"; public static final String GENERATE_ANSWER = "GENERATE_ANSWER"; public static final String CHINESE_TO_ENGLISH = "CHINESE_TO_ENGLISH"; public static final String ERE_TO_INSERT_CYPHER = "ERE_TO_INSERT_CYPHER"; public static final String CLASSIFY_TABLE = "CLASSIFY_TABLE"; public static final String EXTRACT_TABLE_TITLE = "EXTRACT_TABLE_TITLE"; /** * 分类PDF内容类型 */ public static final String CLASSIFY_CONTENT_TYPE = "CLASSIFY_CONTENT_TYPE"; /** * 识别行业类型 */ public static final String CLASSIFY_INDUSTRY = "CLASSIFY_INDUSTRY"; /** * 识别意图 */ public static final String CLASSIFY_INTENT = "CLASSIFY_INTENT"; /** * 识别意图(训练使用) */ public static final String CLASSIFY_INTENT_TRAIN = "CLASSIFY_INTENT_TRAIN"; /** * 识别意图元数据 */ public static final String EXTRACT_INTENT_METADATA = "EXTRACT_INTENT_METADATA"; /** * 识别三元组 */ public static final String EXTRACT_ERE_BASE_INTENT = "EXTRACT_ERE_BASE_INTENT"; public static final Map promptMap = new HashMap<>(); static { init(); } private static void init(){ promptMap.put(DOERE_TEXT, DOERE_TEXT_PROMPT); promptMap.put(DOERE_TABLE, DOERE_TABLE_PROMPT); promptMap.put(CHINESE_TO_ENGLISH, CHINESE_TO_ENGLISH_PROMPT); promptMap.put(ERE_TO_INSERT_CYPHER, ERE_TO_INSERT_CYPHER_PROMPT); promptMap.put(TEXT_TO_CYPHER, TEXT_TO_CYPHER_PROMPT); promptMap.put(GENERATE_ANSWER, GENERATE_ANSWER_PROMPT); promptMap.put(CLASSIFY_TABLE, CLASSIFY_TABLE_PROMPT); promptMap.put(EXTRACT_TABLE_TITLE, EXTRACT_TABLE_TITLE_PROMPT); promptMap.put(CLASSIFY_CONTENT_TYPE, CLASSIFY_CONTENT_TYPE_PROMPT); promptMap.put(CLASSIFY_INDUSTRY, CLASSIFY_INDUSTRY_PROMPT); promptMap.put(CLASSIFY_INTENT, CLASSIFY_INTENT_PROMPT); promptMap.put(CLASSIFY_INTENT_TRAIN, CLASSIFY_INTENT_TRAIN_PROMPT); promptMap.put(EXTRACT_INTENT_METADATA, EXTRACT_INTENT_METADATA_PROMPT); promptMap.put(EXTRACT_ERE_BASE_INTENT, EXTRACT_ERE_BASE_INTENT_PROMPT); } private static final String DOERE_TEXT_PROMPT = """ 你是一个高级信息抽取引擎,请从给定文本中提取以下结构化信息并以JSON数据输出,不要进行解释: 1. **节点提取**: - 识别所有实体作为节点 - 自动推断每个节点的类型 - 记录节点的所有相关属性(键值对形式) 2. **关系提取**: - 识别所有节点间的关系 - 自动推断关系类型 - 记录关系的所有相关属性(键值对形式) 3. **类型化三元组**: - 生成由 (头节点类型, 关系类型, 尾节点类型) 组成的元组 **输出要求**: - 输出纯JSON格式,不要使用```json ```等任何Markdown标记包装 - 使用如下JSON Schema: { "nodes": [ { "name": "节点名称", "type": "节点类型", "attributes": { "属性名1": "属性值1", "属性名2": "属性值2" } } ], "relations": [ { "source": "头节点名称", "target": "尾节点名称", "type": "关系类型", "attributes": { "关系属性名1": "关系属性值1" } } ], "typed_triplets": [ ["头节点类型", "关系类型", "尾节点类型"] ] } **处理规则**: 1. 节点类型和关系类型由你根据上下文语义自动创建(如"科学家"/"发明"/"研究所") 2. 属性字段应包含文本中明确提及或可推导的特征(如数值、时间、状态等) 3. 对同一实体的不同指代需进行合并(如"特斯拉"和"埃隆·马斯克的公司") **示例文本**: "爱因斯坦在1905年发表了狭义相对论论文,这篇革命性理论后来被普林斯顿高等研究院深入研究" **期望输出**: { "nodes": [ { "name": "爱因斯坦", "type": "物理学家", "attributes": { "领域": "理论物理" } }, { "name": "狭义相对论", "type": "科学理论", "attributes": { "发表年份": 1905, "重要性": "革命性" } }, { "name": "普林斯顿高等研究院", "type": "科研机构", "attributes": { "研究领域": "理论科学" } } ], "relations": [ { "source": "爱因斯坦", "target": "狭义相对论", "type": "发表", "attributes": { "时间": 1905 } }, { "source": "普林斯顿高等研究院", "target": "狭义相对论", "type": "研究", "attributes": { "强度描述": "深入" } } ], "typed_triplets": [ ["物理学家", "发表", "科学理论"], ["科研机构", "研究", "科学理论"] ] } 请处理以下文本: {} """; private static final String DOERE_TABLE_PROMPT = """ 你是一个表格数据处理专家,请严格按以下要求从给出的表格中提取数据,直接给出结果,不进行解释: **处理规则:** 1. 完全保留原始表头字段名称,不做任何中英文转换或修改 2. 将每行数据转换为一个独立对象 3. 所有数值保留原始格式(包括逗号分隔符和小数点) 4. 去除数值中的转移符号 5. 表格第一列作为主键字段 **输出格式:** { "table_data": [ { "[第一列表头]": "[第一列值]", "[第二列表头]": "[第二列值]", "[第三列表头]": "[第三列值]" }, // 后续行... ] } **示例表格:** | 账龄 | 期末余额 | 年初余额 | | --- | --- | --- | | 1年以内 | 310,844,201.27 | 337,641,834.84 | | 1至2年 | 52,374,904.35 | 15,041,750.36 | **期望输出:** { "table_data": [ { "账龄": "1年以内", "期末余额": "310,844,201.27", "年初余额": "337,641,834.84" }, { "账龄": "1至2年", "期末余额": "52,374,904.35", "年初余额": "15,041,750.36" } ] } 请处理以下表格: {} """; private static final String TEXT_TO_CYPHER_PROMPT = """ 你是一个专业的 Neo4j Cypher 查询语句生成器,专门用于构建针对特定结构的查询语句。 --- **【数据库结构说明】** - **关系类型(relationType)**: {relationTypeList} - **源节点类型(sourceType)**: {sourceTypeList} - **目标节点类型(targetType)**: {targetTypeList} --- **【生成规则】** 1. 识别用户问题中的实体及意图,映射为 `Cypher 查询语句` 2. 使用无条件匹配,不假设任何属性名称,不添加 `WHERE` 子句过滤。 3. 返回所有满足该关系的查询语句,仅使用 c 表示源节点,r 表示关系,t 表示目标节点,并返回它们的所有属性。 4. 仅输出 字符串格式的 JSON 对象,格式为:\\{ "cypherQueries": [ "MATCH ... RETURN c, r, t", ... ] \\},不需要加任何解释或说明。 5. 如无法从结构中推断 relationType、sourceType 或 targetType,输出: "无法根据数据库结构生成查询" 6. 只能使用relationType、sourceType 或 targetType中的数据 --- **【示例】** 1. - **用户问题:** 龙源电力收购了哪些公司? - **生成的 Cypher 查询:** "\\{ "cypherQueries": [ "MATCH (c:`公司`)-[r:`收购`]->(t:`公司`) RETURN c, r, t", "MATCH (c:`上市公司`)-[r:`收购`]->(t:`公司`) RETURN c, r, t", "MATCH (c:`公司`)-[r:`收购`]->(t:`上市公司`) RETURN c, r, t", "MATCH (c:`电力公司`)-[r:`收购`]->(t:`国有企业`) RETURN c, r, t", ..... ] \\}" 2. - **用户问题:** 龙源电力包含了哪些报告? - **生成的 Cypher 查询:** "\\{ "cypherQueries": [ "MATCH (c:`公司`)-[r:`包含`]->(t:`报告`) RETURN c, r, t", ..... ] \\}" 【用户问题】 {query} 【你的任务】 根据以上数据库结构和用户问题,生成正确的Cypher查询语句。 """; private static final String GENERATE_ANSWER_PROMPT = """ 一、任务说明 你是一个审计报告的整理助手,你需要对用户询问的问题根据产考数据进行回答。 二、参考数据: {example_text} 三、用户输入: {query} 四、注意事项 1. 参考数据进行问答:使用参考数据来回答用户问题 2. 问题范围界定:如果参考数据中没有与用户问题相关的信息,统一采用以下话术回复。 "抱歉目前知识库没有这个问题的答案." 3. 参考数据是绝对正确的,不需要质疑。不需要解释。 /no_think """; private static final String CHINESE_TO_ENGLISH_PROMPT = """ 你是一个Neo4j图数据库命名规范转换专家,请将以下中文短语转换为符合Neo4j命名规范的英文名称。要求: 1. **命名规范**: - 使用`UpperCamelCase`命名实体(如`ProductCategory`) - 禁止特殊字符(如空格、括号、引号、换行符等) - 优先选择技术领域通用术语 2. **转换规则**: - 直译或意译均可,但需确保语义清晰 - 若中文含多义词,选择最贴近技术场景的译法 - 对品牌/专有名词保留原始英文(如"腾讯"→ Tencent) 3. **输入输出示例**: - 输入: "用户订单" → 输出: UserOrder - 输入: "属于2023年" → 输出: BELONGS_TO_2023 - 输入: "5G网络设备" → 输出: 5GNetworkDevice - 输入: "评分大于90" → 输出: SCORE_ABOVE_90 4. **待转换文本**: {} 5. **输出要求**: - 不要使用``````等任何Markdown标记包装 - 只需返回转换后的英文名称,无需解释。 """; private static final String ERE_TO_INSERT_CYPHER_PROMPT = """ 请将以下三元组数据转换为Neo4j的Cypher语句,要求: 1. **节点**用`(n:Label {name: "Value"})`表示,其中`Label`是实体类型(如`Person`、`Company`); 2. **关系**用`[r:RELATION_TYPE]`表示,保持与三元组中关系一致; 3. 如果节点或关系已存在,使用`MERGE`避免重复创建; 4. 返回完整的Cypher语句,不要解释。 ### 输入三元组示例 [ {"source": "人物","sourceType": "Person", "relation": "创始人", "relationType": "FOUNDED","target": "公司","targetType": "Company"}, {"source": "公司","sourceType": "Company ", "relation": "位于", "relationType": "LOCATED_IN","target": "城市","targetType": "City "} ] ### 输出示例 MERGE (p:Person {name: "人物"}) MERGE (c:Company {name: "公司"}) MERGE (city:City {name: "城市"}) MERGE (p)-[r1:FOUNDED]->(c) MERGE (c)-[r2:LOCATED_IN]->(city) ### 规则补充 1. 实体类型映射: - "人物" → `Person` - "公司" → `Company` - "城市" → `City` 2. 关系类型映射: - "创始人" → `FOUNDED` - "位于" → `LOCATED_IN` 3. 属性统一用`name`字段存储实体名称。 ### 禁止行为 1. 不要为关系添加属性(除非明确提供); 2. 不要使用中文标签(如`人物`→`Person`); 3. 不要省略MERGE的安全约束。 ### 请转换以下三元组: {} """; private static final String CLASSIFY_TABLE_PROMPT = """ 你是一个表格数据处理专家,直接给出结果,不要解释。 **请根据表格行的标题类型,区分表格行标题是否是描述性标题:** 1. **描述性标题型定义** - 行标题为**描述性文本**(如审计事项说明、应对措施等) - 内容以**段落式文字**为主,而非结构化数据 - 列数较少(通常2列),且列标题为**概括性说明**(如"关键审计事项"、"审计应对") - 示例: ``` | 关键审计事项 | 在审计中如何应对该事项 | |---------------------------|-----------------------------| | 无形资产减值准备... | 我们对管理层...进行测试... | ``` 2. **分类标签型定义** - 行标题为**分类标签**(如会计科目、项目名称) - 内容以**结构化数据**为主(如数字、日期、代码) - 列数较多(通常≥6列),且列标题为**具体分类**(如"2023年12月31日"、"附注") - 示例: ``` | 项目 | 附注 | 2023年12月31日 | 2023年1月1日 | |--------------|------|---------------------|-------------------| | 货币资金 | 六.1 | 4,879,272,436.13 | 20,493,232,077.05 | ``` **输出要求** - 如果是描述性标题输出**是**,否则输出**否** - 不需要解释说明 **示例表格** | 三产收人确认 关键审计事项 | 在审计中如何应对该事项 | | --- | --- | | 如财务报表附注六注释49营业收入、营 业成本所示,2023年营业收入376\\.42亿 元与上年相比减少5\\.57%,由于收入是 龙源电力的关键绩效指标之一,我们将 其收入的确认作为关键审计事项。 | 我们对收入确认执行的审计程序包括: 1、评价管理层与销售和收款相关的内部控制的设 计和运行有效性;| **期望输出** 是 请处理以下表格: {} """; private static final String EXTRACT_TABLE_TITLE_PROMPT = """ 你是一个表格处理专家,直接给出结果,不用解释。 **任务** - 从文本中挑选出表格的标题。 **说明** - 文本内容是表格上部的一段文字。 **输出要求**: - 直接给出结果,不要解释 **需要处理的文本** {} """; private static final String CLASSIFY_CONTENT_TYPE_PROMPT = """ # PDF文档类型分类器提示词 ## 功能说明 根据指定的固定分类类型(`ContentType`),验证输入的PDF文本是否符合该类型特征,并返回JSON格式结果。 ## 分类类型 {ContentType} ## 输入参数 PDF文本内容: {text} ## 处理规则 1. **入参 `ContentType` 决定验证目标类型** - 根据 `ContentType` 的值,严格匹配对应类型的特征: - `0`:验证是否符合研报类型(专业术语、财务数据) - `1`:验证是否符合对话类型(多轮对话标记) - `2`:验证是否符合记录类型(时间戳、条目化描述) 2. **验证逻辑** - 若文本特征与 `ContentType` 指定类型匹配 → 返回 `{"ContentType": 指定值}` - 若文本特征不匹配 → 返回 `{}`(表示类型不符) 3. **类型定义** ```json { "0": "研报类型(行业分析、财务数据)", "1": "对话类型(会议记录、问答交流)", "2": "记录类型(操作日志、事务记录)" } ``` ## 验证示例 ```json // 示例1:指定类型0,文本符合研报特征 输入: { "text": "2023年新能源汽车渗透率达35%(乘联会),预计2024年突破50%" } 输出: {"ContentType": 0} // 示例2:指定类型1,文本不符合对话特征 输入: { "text": "系统启动执行数据同步" } 输出: {} // 示例3:指定类型2,文本符合记录特征 输入: { "text": "2023-10-01 14:00 用户登录异常;14:05 触发安全警报" } 输出: {"ContentType": 2} ``` --- **设计说明** - 入参 `ContentType` 为固定值,用于声明待验证的目标类型,而非自动分类。 - 输出结果仅表示文本是否符合声明的类型,实现“类型断言”功能。 - 参数命名与原文档保持一致,但调整了逻辑语义以符合用户需求。 ## 输出要求 1. 严格遵循JSON格式 2. 不需要解释,不需要说明。 仅返回以下两种结果之一: - 匹配成功:`{"ContentType": 0/1/2}` - 匹配失败:`{}` ./no_think """; private static final String CLASSIFY_INDUSTRY_PROMPT = """ ### 行业类型识别 你是一个专业的行业分类专家。你的任务是根据给定的文本内容,判断这段文本最可能属于下面行业列表中哪个行业。 请结合文本内容中的专业术语、关键领域、上下文信息,准确判断其所属行业,并返回对应的行业名称。 ### 输入: ``` {text} ``` ### 行业列表 {industryCategory} ### 输出要求: * 请只输出**一个最可能的行业类型**,不要输出概率或多个行业; * 只返回**行业名称**,不需要解释、分析、备注等; * 行业名称请选择行业列表中的行业。 * 输出纯JSON格式,不要使用```json ```等任何Markdown标记包装 ### 示例输出: ``` { industryCategory:软件与信息技术 } ``` """; private static final String CLASSIFY_INTENT_PROMPT = """ # 从文本中识别预定义意图类型 ## 功能说明 根据提供的准确意图列表,识别文本段落中匹配的意图类型。 ## 可用意图列表 {IntentType} ## 处理规则 1. 严格匹配文本内容与意图类型的关联性 2. 文本可能匹配多个意图类型 3. 若无匹配则返回空对象 ## 待处理文本 {text} ## 验证示例 ```json // 示例1:匹配单个意图 输入: { "text": "本公司注册地址为上海市浦东新区张江高科技园区" } 输出: { "IntentTypeList": ["公司地址"] } // 示例2:匹配多个意图 输入: { "text": "2023年度财务报告显示公司总部位于北京,全年营收..." } 输出: { "IntentTypeList": ["公司地址", "公司年度报告"] } // 示例3:无匹配意图 输入: { "text": "今天的天气很适合户外活动" } 输出: {} """; private static final String CLASSIFY_INTENT_TRAIN_PROMPT = """ # 提取出文本片段的意图 ## 功能说明 识别PDF文本内容中某一段落的意图类型 ## 待处理文本 {text} ## 验证示例 ```json // 示例1: 输入: { "text": "..." } 输出: { "IntentTypeList": ["...", "..."] } // 示例2:文本意图无法识别 输入: { "text": "人生短短几个球" } 输出: {} ``` ## 输出要求 1. 严格遵循 JSON 格式。 2. 输出纯JSON格式,不要使用```json ```等任何Markdown标记包装 3. 不需要解释,不需要说明,仅返回以下两种结果: 匹配成功: ```json {"IntentTypeList": ["...", "..."]} ``` - 匹配失败: ```json {} ``` 3.每个意图标签必须独立表述,禁止使用“...和...”等连接词合并两个意图。 ./no_think """; private static final String EXTRACT_INTENT_METADATA_PROMPT = """ # 元数据提取指令 ## 任务描述 你是一个专业的元数据提取引擎,需要从给定的文本片段中识别出符合指定意图的实体、关系及其属性,并按照标准JSON格式输出。 ## 输入数据 - 文本片段: {text} - 可选意图标签: {IntentTypeList} ## 输出要求 1. 分析文本内容,识别与意图标签相关的实体和关系 2. 每个结果应包含: - source(来源实体) - relation(关系) - target(目标实体) - intent(匹配的意图标签) 3. 每个实体/关系应包含: - type(类型) - attributes(相关属性列表) 4. 使用以下示例格式: ```json [ { "source": { "type": "实体类型1", "attributes": ["属性1", "属性2"] }, "relation": { "type": "关系类型", "attributes": [] }, "target": { "type": "实体类型2", "attributes": ["属性3"] }, "intent": "匹配的意图标签" } ] 5. 属性只代表属性名称:例如“名称“,”数量“ """; private static final String EXTRACT_ERE_BASE_INTENT_PROMPT = """ # 提示词 ## 任务描述: 你是一个信息抽取引擎,需要从给定的文本中提取符合指定三元组标签(实体、关系、属性)的结构化数据。 ## 输入数据: - 待处理文本:{text} - 三元组标签及属性名称: {domainMetadata} ## 示例: { "nodes": [ { "type": "公司", "attributes": { "名称": "龙源(酒泉)风力发电有限公司", "地址": "雨花台区" } }, { "type": "电子银行承兑汇票", "attributes": { "金额": "100.00万元", "打印时间": "2024年10月20号" } }, { "type": "公司", "attributes": { "名称": "杭州六小龙", "地址": "杭州高新区" } } ], "relations": [ { "type": "持有", "attributes": { } }, { "type": "收购", "attributes": { "收购类型": "全资收购" "收购时间":"2025年5月28号" } } ], "typed_triplets": [ [ "公司", "持有", "电子银行承兑汇票" ], [ "公司", "收购", "公司" ] ] } ## 注意事项: - 仅提取 `domainMetadata` 中定义的标签和属性。 - 若属性无对应值,可留空或忽略。 - 确保提取的值与原文一致,不进行推断或改写。 - 输出纯JSON格式,不要使用```json ```等任何Markdown标记包装 """; }