import logging import time 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_TEMPERATURE, LLM_TIMEOUT from parser.base_parser import BaseParser class VentReportParser(BaseParser): def __init__(self): super().__init__() self.llm = ChatOpenAI( model=LLM_MODEL, api_key=LLM_API_KEY, base_url=LLM_BASE_URL, temperature=LLM_TEMPERATURE, timeout=LLM_TIMEOUT ) def parse(self, file_path: str) -> Dict[str, Any]: documents = self.load_pdf(file_path) full_text = "\n".join([doc.page_content for doc in documents]) return self._parse(full_text) def _parse(self, text: str) -> Dict[str, Any]: start_time = time.time() prompt = ChatPromptTemplate.from_messages([ ("system", ''' 你是专业煤矿测风报表解析助手。 请从文档中提取**矿井测风旬报/月报**全部数据,严格仅输出标准JSON,禁止输出任何多余文字、解释、前言后语。 固定JSON字段(下划线英文简写,严格使用,不可修改): mine_name 矿井名称 report_no 报表编号 report_date 报表日期 weather 天气 atm_pressure_hpa 大气压力(hPa) total_eq_area_m2 总等积孔(m²) ground_temp_c 地面温度(℃) vent_shafts 风井运行列表(数组) shaft_name 风井名称 total_inflow_m3min 总进风量(m³/min) total_outflow_m3min 总回风量(m³/min) fan_model 风机型号 fan_stator_no 主扇编号 blade_angle_deg 叶片角度(°) neg_pressure_pa 负压(Pa) input_power_kw 输入功率(kW) output_power_kw 输出功率(kW) efficiency_pct 效率(%) power_factor_pct 功率因数(%) voltage_kv 电压(kV) current_a 电流(A) mine_total_outflow_m3min 矿井总回风量(m³/min) mine_total_outflow_calc_m3min 矿井总排风量计算值(m³/min) total_inflow_m3min 总进风量(m³/min) planned_air_volume_m3min 计划风量(m³/min) effective_air_volume_m3min 有效风量(m³/min) effective_air_rate_pct 有效风量率(%) test_points 测风地点列表(数组) point_name 测风地点 point_desc 测点描述 section_area_m2 巷道断面(m²) wind_speed_ms 风速(m/s) air_volume_m3min 实测风量(m³/min) req_air_volume_m3min 需风量(m³/min) effective_air_volume_m3min 有效风量(m³/min) temp_c 温度(℃) methane_pct 瓦斯浓度(%) co2_pct 二氧化碳浓度(%) remark 备注 填充规则: 1. 无数据时:字符串填"",数值填0,禁止null 2. 数字自动剔除单位,只保留数值 3. test_points 里**绝对不要输出 id 字段** 4. 严格按给定字段输出,不新增、不减少、不改名 5. 只输出纯净JSON,无任何其他内容 '''), ("human", "请解析以下煤矿测风报表文档内容:\n{text}") ]) # 调用LLM解析 chain = prompt | self.llm response = chain.invoke({"text": text}) elapsed_time = round(time.time() - start_time, 2) logging.info(f"测风报表解析完成 | 总耗时: {elapsed_time} 秒") # 安全解析JSON try: return json.loads(response.content) except: return {"error": "解析失败,返回非标准JSON", "content": response.content} if __name__ == '__main__': parser = VentReportParser() result = parser.parse("D:\\workspace\\py\\vent_agent\\测风报表.pdf") print(json.dumps(result, ensure_ascii=False, indent=2))