336 lines
17 KiB
Python
336 lines
17 KiB
Python
from openai import OpenAI
|
||
from typing import List, Dict
|
||
import json
|
||
from langchain_text_splitters import MarkdownHeaderTextSplitter, CharacterTextSplitter
|
||
import requests
|
||
import json
|
||
from modelsAPI.model_api import OpenaiAPI
|
||
|
||
def _split_markdown(text, chunk_size=2048, chunk_overlap=50):
|
||
"""
|
||
根据 max_level 动态生成 headers_to_split_on 配置
|
||
规则:
|
||
- max_level=1 → 只按 # 分割
|
||
- max_level=2 → 按 # 和 ## 分割
|
||
- 以此类推
|
||
"""
|
||
# 动态生成 headers_to_split_on 配置(目前固定为 Header_1)
|
||
headers_to_split_on = [("#", "Header_1")]
|
||
|
||
# 初始化分割器
|
||
splitter = MarkdownHeaderTextSplitter(
|
||
headers_to_split_on=headers_to_split_on,
|
||
strip_headers=True
|
||
)
|
||
chunks = splitter.split_text(text)
|
||
|
||
char_splitter = CharacterTextSplitter(
|
||
chunk_size=chunk_size,
|
||
chunk_overlap=chunk_overlap,
|
||
length_function=len,
|
||
separator="\n\n" # 更合理的分隔符
|
||
)
|
||
|
||
final_chunks = []
|
||
start_chars = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "第", "十",
|
||
"一", "二", "三", "四", "五", "六", "七", "八", "九"," 故障"]
|
||
new_header = []
|
||
|
||
# 提取所有 Header_1 并筛选出“有效标题”
|
||
for chunk in chunks:
|
||
header_1 = chunk.metadata.get('Header_1', '')
|
||
if header_1 and header_1[0] in start_chars:
|
||
new_header.append(header_1)
|
||
|
||
new_header_set = set(new_header)
|
||
|
||
# 构建带标题前缀的 final_chunks
|
||
for chunk in chunks:
|
||
header_1 = chunk.metadata.get('Header_1', '')
|
||
content = chunk.page_content
|
||
if len(content) <= 20000:
|
||
chunk_with_header = f"{header_1}\n{content}" if header_1 else content
|
||
final_chunks.append(chunk_with_header)
|
||
else:
|
||
split_texts = char_splitter.split_documents([chunk])
|
||
for split_chunk in split_texts:
|
||
chunk_with_header = f"{header_1}\n{split_chunk.page_content}" if header_1 else split_chunk.page_content
|
||
final_chunks.append(chunk_with_header)
|
||
|
||
# ===== 重新分组,并记录每个组的 header =====
|
||
rechunked = []
|
||
rechunked_headers = [] # 新增:每个 rechunked 块对应的 header
|
||
current = ""
|
||
current_header = "" # 当前正在构建的块所属的标题
|
||
|
||
for chunk in final_chunks:
|
||
is_new_section = False
|
||
matched_header = ""
|
||
|
||
# 检查是否以某个 new_header 开头
|
||
for h in new_header_set:
|
||
if chunk.startswith(h + "\n"):
|
||
is_new_section = True
|
||
matched_header = h
|
||
break
|
||
|
||
if is_new_section:
|
||
# 保存上一段
|
||
if current:
|
||
rechunked.append(current)
|
||
rechunked_headers.append(current_header)
|
||
# 开启新段
|
||
current = chunk
|
||
current_header = matched_header
|
||
else:
|
||
# 合并到当前段
|
||
if current:
|
||
current += "\n" + chunk
|
||
else:
|
||
current = chunk
|
||
current_header = "" # 如果开头无标题,则 header 为空
|
||
|
||
# 添加最后一段
|
||
if current:
|
||
rechunked.append(current)
|
||
rechunked_headers.append(current_header)
|
||
|
||
return rechunked, rechunked_headers
|
||
|
||
Ontology = ["舰艇", "系统", "子系统", "部件", "一级零部件", "二级零部件", "故障模式", "维修方案", "操作项目", "备品备件", "维修手册", "操作使用手册"]
|
||
Relationships = ["包含", "存在", "修理", "操作时使用", "依据","存储备用","维修时使用"]
|
||
|
||
# 节点类型及其属性定义
|
||
|
||
NODE_TYPES = {
|
||
"舰艇": ["名称", "型号", "弦号", "设计单位", "总装工厂", "所属部队"],
|
||
"系统": ["名称", "型号", "生产单位", "等级","功能"],
|
||
"子系统": ["名称", "型号", "生产单位", "等级","功能"],
|
||
"一级零部件": ["名称", "型号", "技术责任单位", "生产单位"],
|
||
"二级零部件": ["名称", "型号", "技术责任单位", "生产单位"],
|
||
"故障模式": ["名称", "故障原因", "故障影响", "故障类型", "发生时间", "处置情况", "修复情况","维修方案"],
|
||
"维修方案": ["名称", "维修项目编号","维修间隔期", "安全注意事项", "保障设备(工具)", "备品备件", "消耗材料", "人力人员", "备品备件", "修前判据", "修理步骤及工艺", "验收标准"],
|
||
"操作项目": ["名称", "操作项目编号", "安全防护", "注意事项", "保障设施、保障设备(工具)", "人力人员", "操作步骤"],
|
||
"备品备件" : ["名称", "规格", "型号", "图号或标准号或代号","计量单位", "单机重量", "尺寸(长X宽X高mm)", "单机装配数量","实物图片电子文档名称","MTBF(b)","生成厂家",
|
||
"出厂日期",
|
||
"供货周期(天)",
|
||
"有效期(月)",
|
||
"使用寿命(h)",
|
||
"备件箱号",
|
||
"储存要求_环境",
|
||
"储存要求_期限",
|
||
"停产后供应方式"],
|
||
"维修手册": ["名称", "url"],
|
||
"操作使用手册": ["名称", "url"],
|
||
}
|
||
|
||
Ontology_DESCRIPTION = {
|
||
"舰艇": ["代表一艘完整海上作战或保障平台的实体,是所有系统、设备和零部件的最高层级载体。区别于“系统”或“设备”,舰艇具有独立的型号、弦号和部队归属,不可作为其他舰艇的组成部分。"],
|
||
"系统": ["舰艇中实现某一类功能(如动力、导航、通信)的集成化功能单元,由多个设备协同组成。与“设备”不同,系统本身不直接对应物理装置,而是逻辑/功能层面的集合;与“舰艇”不同,系统不具备独立航行能力或部队归属。"],
|
||
"子系统": ["系统内部为实现特定子功能而划分的独立功能模块,是系统的直接组成部分。子系统既具备相对独立的功能完整性(可单独测试或隔离),又必须依赖所属系统才能发挥最终战术效能,是连接系统逻辑与物理设备的中间层级。"],
|
||
"部件": ["构成子系统或设备的最小可独立拆卸、更换的物理实体单元(常称为LRU,即外场可更换单元)。部件具有明确的物理边界和接口,通常无需深层拆解即可进行整体替换,是维修作业中直接操作的主要对象。"],
|
||
"一级零部件": ["部件内部的核心功能组件,是部件的直接构成元素。一级零部件通常承担部件内的主要能量转换、信号处理或机械传动任务,其故障往往导致整个部件功能失效,需通过专业工具拆解部件后方可触及。"],
|
||
"二级零部件": ["一级零部件的细分构成单元,属于更深层次的基礎元件(如电阻、电容、密封圈、轴承等)。二级零部件通常不具备独立的功能意义,主要作为基础材料或标准件存在,一般仅在车间级深度维修或制造过程中涉及。"],
|
||
"故障模式": ["对舰艇装备在运行过程中表现出的异常状态、性能退化或功能丧失现象的标准化描述。故障模式明确了“发生了什么错误”(如断裂、短路、泄漏、卡滞),是关联故障现象与维修方案的桥梁,不包含原因分析或解决措施。"],
|
||
"维修方案": ["针对特定故障模式或预防性维护需求,制定的一套标准化的技术处置流程集合。维修方案详细规定了诊断步骤、拆装工艺、测试标准及所需资源,旨在指导维修人员恢复装备的技术战术性能,是维修决策的核心依据。"],
|
||
"操作项目": ["舰员在日常使用、值更或训练过程中,对装备执行的具体动作指令或检查任务(如启动、切换模式、参数读取、日常擦拭)。操作项目侧重于装备的正确使用与状态监控,区别于以修复为目的的“维修方案”。"],
|
||
"备品备件": ["为保障舰艇装备持续运行和及时修复,预先储备的可替换物理实体的总称。备品备件涵盖了从部件到二级零部件的各个层级,其管理核心在于平衡库存成本与战备完好率,确保在故障发生时能立即供应。"],
|
||
"维修手册": ["记载装备维修理论、故障排查逻辑、详细修理工艺、测试规范及安全技术要求的权威性技术文档。维修手册主要面向维修技术人员,提供“如何修”的深度指导,是实施维修方案的法定依据。"],
|
||
"操作使用手册": ["指导舰员正确、安全、高效地使用装备的功能说明与操作规程文档。操作使用手册主要面向装备操作人员,内容涵盖工作原理简介、操作步骤、应急处置及日常保养要求,侧重于“如何用”而非“如何修”。"]
|
||
}
|
||
|
||
RELATIONSHIP_TYPES = {
|
||
"包含": ["舰艇包含系统", "系统包含子系统", "子系统包含部件", "部件包含一级零部件", "一级零部件包含二级零部件"],
|
||
"操作项目时使用": ["设备操作项目时使用操作项目"],
|
||
"维修时使用": ["设备维修时使用维修项目"],
|
||
"存在": ["子系统存在故障模式","部件存在故障模式","一级零部件存在故障模式","二级零部件存在故障模式"],
|
||
"存储备用" : ["设备存储备用备品备件"],
|
||
"依据" : ["维修方案依据维修手册","操作项目依据操作使用手册"],
|
||
}
|
||
def create_extraction_prompt(
|
||
text: str,
|
||
ontology: List[str],
|
||
Ontology_DESCRIPTION: Dict[str, List[str]],
|
||
relationships: List[str],
|
||
node_types: Dict[str, List[str]],
|
||
relationship_types: Dict[str, List[str]]
|
||
) -> str:
|
||
# 构建已有本体的定义(用于上下文)
|
||
ontology_def_descriptions = []
|
||
for etype in ontology:
|
||
clean_etype = etype.strip()
|
||
if clean_etype in Ontology_DESCRIPTION:
|
||
desc = ";".join(Ontology_DESCRIPTION[clean_etype])
|
||
ontology_def_descriptions.append(f"- {clean_etype}:{desc}")
|
||
else:
|
||
ontology_def_descriptions.append(f"- {clean_etype}:无明确定义")
|
||
|
||
# 构建关系示例
|
||
rel_examples = []
|
||
for rtype, examples in relationship_types.items():
|
||
for ex in examples[:1]:
|
||
rel_examples.append(f" - {ex}")
|
||
|
||
prompt = f"""你是一个专业的舰艇维修领域工程师。请基于给出的本体和属性等信息,抽取出实体、关系以及相关属性值。
|
||
|
||
> ⚠️ 重要说明:
|
||
> - **本体(Ontology Class)是抽象概念类别**,是对特定领域中概念体系的形式化、结构化规范,用于明确定义该领域内的实体类型(类)。
|
||
|
||
|
||
### 已有本体类型:
|
||
{chr(10).join(ontology_def_descriptions)}
|
||
|
||
### 已有关系类型:
|
||
- {"、".join(relationships)}
|
||
典型用法示例:
|
||
{chr(10).join(rel_examples)}
|
||
|
||
### 待分析文本:
|
||
{text.strip()}
|
||
|
||
### 你的任务:
|
||
1、根据给出的本体、关系以及相应的属性,从文本中抽取出所有可能的实体、关系以及相关属性值。
|
||
2、不要随意添加无效属性,抽取的实体属于本体范围内,关系属于关系范围内。、
|
||
|
||
### 输出格式:
|
||
请输出json格式内容,不要输出其他格式和额外内容
|
||
{{
|
||
"entities": [
|
||
{{
|
||
"type": "系统",
|
||
"name": "1 号主机冷却系统",
|
||
"properties": {{
|
||
"名称": "1 号主机冷却系统",
|
||
"型号": "",
|
||
"技术责任单位": "XX 舰艇保障大队",
|
||
"生产单位": "",
|
||
"技术状态": "",
|
||
"生产日期": "",
|
||
"启用时间": "",
|
||
"运行时间": "",
|
||
"运行条件": ""
|
||
}}
|
||
}},
|
||
{{
|
||
"type": "故障模式",
|
||
"name": "1 号主机冷却系统温度异常升高",
|
||
"properties": {{
|
||
"故障现象": "1 号主机冷却系统温度异常升高",
|
||
"故障原因": "根据 A 设备发生的温度异常升高现象,结合相关技术手册与历史故障记录,分析如下:
|
||
(一)冷却液循环泵可能存在异常,导致流量不足;
|
||
(二)热交换器内部堵塞或外部散热片污损,影响散热效率;
|
||
(三)温度传感器或控制系统信号异常,导致误报警。
|
||
",
|
||
"故障影响": "",
|
||
"故障类型": "",
|
||
"发生时间": "2013 年 05 月 7 日 9 时 23 分 37 秒",
|
||
"处置情况": " ",
|
||
"修复情况": "",
|
||
“”
|
||
}}
|
||
}}
|
||
],
|
||
"relationships": [
|
||
{{
|
||
"type": "存在",
|
||
"from_entity": "1 号主机冷却系统",
|
||
"to_entity": "1 号主机冷却系统温度异常升高"
|
||
}}
|
||
]
|
||
}}
|
||
|
||
注意:
|
||
- 不要生成一些关系,如果没有就不要推荐
|
||
- 如果文本没有符合的关系和实体,不要进行强行抽取
|
||
"""
|
||
|
||
return prompt
|
||
|
||
async def extract_text_node_relationship(
|
||
text: str,
|
||
ontology: List[str],
|
||
Ontology_DESCRIPTION: Dict[str, List[str]],
|
||
relationships: List[str],
|
||
node_types: Dict[str, List[str]],
|
||
relationship_types: Dict[str, List[str]]
|
||
):
|
||
|
||
|
||
final_prompt = create_extraction_prompt(
|
||
text=text,
|
||
ontology=ontology,
|
||
Ontology_DESCRIPTION=Ontology_DESCRIPTION,
|
||
relationships=relationships,
|
||
relationship_types=relationship_types,
|
||
node_types=node_types
|
||
)
|
||
res_str = await OpenaiAPI.openai_chat_aysnc(final_prompt,timeout=600)
|
||
|
||
# 处理 API 调用失败
|
||
if res_str is None:
|
||
print("⚠️ 跳过当前 chunk:API 调用失败")
|
||
|
||
# 尝试解析 JSON
|
||
try:
|
||
res = json.loads(res_str)
|
||
except json.JSONDecodeError as e:
|
||
print(f"❌ JSON 解析失败: {e}")
|
||
print(f"原始响应内容: {repr(res_str)}")
|
||
|
||
# 安全访问字段
|
||
new_entities = res.get("entities", [])
|
||
new_relationships = res.get("relationships", [])
|
||
|
||
# 可选:最后汇总输出
|
||
# print("\n=== 最终结果 ===")
|
||
# print("生成文本本体:", new_entities_result)
|
||
# print("生成文本关系:", new_relationships_result)
|
||
return new_entities,new_relationships
|
||
|
||
|
||
# if __name__ == "__main__":
|
||
# text = """
|
||
# # 1)螺旋桨本体
|
||
|
||
# 功能与特性:能量转换的核心。它将主机的旋转动能转化为水流的反作用力(推力)。其特性由材料(如镍铝青铜、锰青铜)、桨叶数(3-6叶)、盘面比、螺距比等决定,直接影响效率、空泡和振动性能。
|
||
|
||
# 相互关系:直接安装在尾轴(螺旋桨轴) 末端,其扭矩由尾轴传递,其推力通过推力轴承传递给船体。
|
||
|
||
# 2)轴系
|
||
|
||
# 功能与特性:动力传递的桥梁。包括:
|
||
# s
|
||
# 推力轴及推力轴承:承受螺旋桨产生的巨大轴向推力,并将其传递给船体结构,是决定船舶能否前进、后退的关键。
|
||
|
||
# 中间轴:连接主机输出端与推力轴/尾轴。
|
||
|
||
# 尾轴(螺旋桨轴):穿过尾轴管,末端安装螺旋桨,工作环境恶劣(浸没海水中),通常需包覆铜套防腐。
|
||
|
||
# 相互关系:将主机的旋转输出与螺旋桨本体刚性连接,形成一个完整的动力传递链。推力轴承是轴系与船体结构之间的关键受力界面。
|
||
|
||
# 3)尾轴管与密封系统功能与特性:
|
||
|
||
# 尾轴管:固定于船体尾端,支撑尾轴并形成从船内(机舱)到船外(海水)的通道。
|
||
|
||
# 密封系统(首尾密封):绝对关键的安全设备。防止海水沿尾轴流入机舱(尾密封),同时防止润滑油泄漏(首尾密封均有此功能)。通常采用唇式密封或面式密封,材料耐磨、耐腐蚀。
|
||
|
||
# 相互关系:为尾轴提供支撑和润滑(油润滑或水润滑),其密封系统直接保护尾轴并确保机舱安全,与轴系和船体结构紧密集成。
|
||
|
||
# 4)毂帽与导流罩功能与特性:
|
||
|
||
# 毂帽:安装在螺旋桨毂后端,呈流线型,用于减少桨毂后部产生的涡流阻力,提高效率。
|
||
|
||
# 导流罩(如桨毂涡流消除器):安装在桨毂前方,改善流入桨叶的水流状态,尤其适用于肥大船型,能提升效率、减少振动。
|
||
|
||
# 相互关系:直接安装在螺旋桨本体的毂上,是其水动力性能的优化附件。
|
||
|
||
# 系统相互关系总结:
|
||
|
||
# 主机驱动轴系旋转,轴系末端的尾轴带动螺旋桨本体旋转。螺旋桨产生的推力通过尾轴传递至推力轴承,最终作用在船体上使其运动。尾轴管及密封系统为这一旋转运动提供支撑、润滑和至关重要的水密保障。毂帽和导流罩则作为螺旋桨本体的附件,优化其水动力性能。所有子设备协同工作的核心目标,是确保主机功率被高效、平稳、可靠地转化为推进船舶前进的有效推力。 任何一环失效(如密封泄漏、轴承损坏)都将导致整个推进系统瘫痪。
|
||
# """
|
||
# content = []
|
||
# content.append(text)
|
||
# extract_text_node_relationship(content,ontology=Ontology,Ontology_DESCRIPTION=Ontology_DESCRIPTION,relationships=Relationships,relationship_types=RELATIONSHIP_TYPES,node_types=NODE_TYPES)
|
||
|
||
|