# parsers/gas_identification_parser.py from langchain_openai import ChatOpenAI from langchain_core.prompts import ChatPromptTemplate from typing import List, Dict, Any import json from config.settings import LLM_MODEL, LLM_API_KEY, LLM_BASE_URL, LLM_TIMEOUT from parser.base_parser import BaseParser class GasIdentificationParser(BaseParser): def __init__(self): super().__init__() self.llm = ChatOpenAI( model=LLM_MODEL, api_key=LLM_API_KEY, base_url=LLM_BASE_URL, timeout=LLM_TIMEOUT ) def parse(self, file_path: str) -> Dict[str, Any]: """ ✅ 优化点: 1. 只加载一次PDF 2. 只调用一次大模型 3. 一次性返回所有结构 """ # 1. 加载并清洗文本(只做一次) documents = self.load_pdf(file_path) full_text = "\n".join([doc.page_content for doc in documents]) prompt = ChatPromptTemplate.from_messages([ ("system", ''' 你是专业的**煤矿瓦斯等级鉴定报告解析专家**。 请从PDF/文档内容中**一次性精准提取所有数据**,严格输出标准JSON,**禁止任何多余文字、解释、前言、后语**。 需要提取的字段如下: === 报告主表信息 === - mine_name:矿井名称 - n_year:鉴定年度(数字,如2024) - report_month:鉴定报告所属月份(格式:yyyy-MM) - mine_abs_ch4:矿井绝对瓦斯涌出量(m³/min) - mine_rel_ch4:矿井相对瓦斯涌出量(m³/t) - return_max_abs_ch4:采面最大绝对瓦斯涌出量(m³/min) - return_max_rel_ch4:采面最大相对瓦斯涌出量(m³/t) - dig_max_abs_ch4:掘进最大绝对瓦斯涌出量(m³/min) - dig_max_rel_ch4:掘进最大相对瓦斯涌出量(m³/t) - mine_abs_co2:矿井绝对CO₂涌出量(m³/min) - mine_rel_co2:矿井相对CO₂涌出量(m³/t) - return_max_abs_co2:采面最大绝对CO₂涌出量(m³/min) - return_max_rel_co2:采面最大相对CO₂涌出量(m³/t) - dig_max_abs_co2:掘进面最大绝对CO₂涌出量(m³/min) - dig_max_rel_co2:掘进面最大相对CO₂涌出量(m³/t) - coal_and_gas_outburst:煤与瓦斯突出情况 - gas_blow_out:瓦斯喷出情况 - iden_month_product_state:鉴定月矿井生产状况 - last_year_gas_level:上年度瓦斯等级 - gas_level:本年度瓦斯等级 - report_date:编制日期(yyyy-MM-dd) - iden_date:鉴定日期(yyyy-MM-dd) - iden_unit:鉴定单位 === 各用风地点明细表(数组,可多条) === - face_name:工作面/巷道/硐室名称 - face_type:地点类型:采煤/掘进/回风巷/硐室 - avg_abs_gas:月平均绝对瓦斯涌出量 m³/min - max_abs_gas:月最大绝对瓦斯涌出量 - avg_abs_co2:月平均绝对CO₂涌出量 - max_abs_co2:月最大绝对CO₂涌出量 - gas_uneven_coeff:瓦斯涌出不均衡系数 - co2_uneven_coeff:CO₂涌出不均衡系数 - daily_production:日产量 t/d - remark:备注 ============================================== 输出JSON格式(严格遵守,不可修改): {{ "main_info": {{ "mine_name": "", "n_year": 0, "report_month": "", "mine_abs_ch4": 0.00, "mine_rel_ch4": 0.00, "return_max_abs_ch4": 0.00, "return_max_rel_ch4": 0.00, "dig_max_abs_ch4": 0.00, "dig_max_rel_ch4": 0.00, "mine_abs_co2": 0.00, "mine_rel_co2": 0.00, "return_max_abs_co2": 0.00, "return_max_rel_co2": 0.00, "dig_max_abs_co2": 0.00, "dig_max_rel_co2": 0.00, "coal_and_gas_outburst": 0.00, "gas_blow_out": "", "iden_month_product_state": "", "last_year_gas_level": "", "gas_level": "", "report_date": "2025-01-01", "iden_date": "2025-01-01", "iden_unit": "" }}, "detail_list": [ {{ "face_name": "", "face_type": "", "avg_abs_gas": 0.0000, "max_abs_gas": 0.0000, "avg_rel_gas": 0.0000, "avg_abs_co2": 0.0000, "max_abs_co2": 0.0000, "gas_uneven_coeff": 0.0000, "co2_uneven_coeff": 0.0000, "daily_production": 0.00, "remark": "" }} ] }} 解析规则: 1. 找不到的字段:字符串用"",数字用0/0.00/0.0000,禁止null 2. report_month 格式必须为 yyyy-MM 3. 日期必须为 yyyy-MM-dd 4. 文档中出现多个工作面/巷道/硐室,detail_list 输出多条 5. 只输出JSON,无任何其他内容,不要写markdown语法 6. 仔细从瓦斯等级鉴定基础数据计算表中寻找月上中下旬的的瓦斯/二氧化碳涌出总量,并计算三旬平均作为月平均绝对涌出量,找出最大值作为月最大绝对涌出量,计算最大值与月平均值的比值作为不均衡系数 '''), ("human", "请解析以下瓦斯等级鉴定报告内容:\n{text}") ]) chain = prompt | self.llm response = chain.invoke({"text": full_text}) return json.loads(response.content) if __name__ == '__main__': parser = GasIdentificationParser() result = parser.parse("C:\\Users\ky\Desktop\配风计划研判\布尔台\附件5:布尔台煤矿2024-2025年度瓦斯等级鉴定报告.pdf") print(json.dumps(result, ensure_ascii=False, indent=2))