You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

759 lines
30 KiB
Java

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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<String, String> 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"
},
{
"": "12",
"": "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列且列标题为**具体分类**(如"20231231"、""
- 示例:
```
| 项目 | 附注 | 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": "202335%202450%"
}
输出:
{"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",
"": "20241020"
}
},
{
"type": "",
"attributes": {
"": "",
"": ""
}
}
],
"relations": [
{
"type": "",
"attributes": {
}
},
{
"type": "",
"attributes": {
"": ""
"""2025528"
}
}
],
"typed_triplets": [
[
"",
"",
""
],
[
"",
"",
""
]
]
}
## 注意事项:
- 仅提取 `domainMetadata` 中定义的标签和属性。
- 若属性无对应值,可留空或忽略。
- 确保提取的值与原文一致,不进行推断或改写。
- 输出纯JSON格式不要使用```json ```等任何Markdown标记包装
""";
}