import json from openai import OpenAI from kg_build_v2.Prompt import Prompt_anli from kg_build_v2.extract_html import extract_fault_sections,extract_by_unit,extract_cases,extract_content_slices import re from modelsAPI.model_api import OpenaiAPI def read_markdown_file(file_path): """ 读取 Markdown 文件并返回其全部内容作为字符串。 参数: file_path (str): Markdown 文件的路径(支持相对或绝对路径) 返回: str 或 None: 成功时返回文件内容;出错时返回 None """ try: with open(file_path, 'r', encoding='utf-8') as f: content = f.read() return content except FileNotFoundError: print(f"错误:文件未找到 - {file_path}") except PermissionError: print(f"错误:没有权限读取文件 - {file_path}") except UnicodeDecodeError: print(f"错误:文件编码不是 UTF-8,无法读取 - {file_path}") except Exception as e: print(f"读取文件时发生未知错误: {e}") return None def safe_json_loads(s: str): try: return json.loads(s) except json.JSONDecodeError as e: # 尝试修复常见问题 s = s.replace("\\n", "\\\n").replace("\r", "\\r").replace("\t", "\\t") # 或者直接清理非法字符 import re s = re.sub(r'[\x00-\x1f\x7f]', '', s) # 移除控制字符 try: return json.loads(s) except: raise e # def openai_chat(query:str, model="Qwen3-32B"): # """调用OpenAI API""" # try: # client = OpenAI( # api_key= "none", # base_url= "http://192.168.0.46:59800/v1" # ) # response = client.chat.completions.create( # model=model, # messages=[ # {"role": "user", "content": query}, # ], # temperature=0.1, # stream=False, # response_format = {"type": "json_object"}, # extra_body={"chat_template_kwargs": {"enable_thinking": False}} # ) # return response.choices[0].message.content # except Exception as e: # print(f"调用OpenAI API时出错: {e}") # return None def extract_wxanli(chunks): """ 批量处理一个文档的多个切片(chunks),每个切片调用大模型结构化,并返回全部结果。 :param chunks: List[str] - 同一文档的多个文本切片 :return: List[Dict] - 结构化结果列表 """ all_results = [] all_entities = [] all_relationships = [] for idx, block in enumerate(chunks, 1): print(f"=== 维修案例 Block {idx} ===") print(block) print("\\n" + "="*60 + "\\n") final_prompt = Prompt_anli.replace("text",block) raw_response = OpenaiAPI.openai_chat(final_prompt,timeout=180) # 尝试解析 JSON try: cleaned = raw_response.strip() if cleaned.startswith("```json"): cleaned = cleaned[7:].lstrip() if cleaned.endswith("```"): cleaned = cleaned[:-3].rstrip() # ✅ 修复:移除 ensure_ascii 和 indent json_result = safe_json_loads(cleaned) entities = json_result.get("entities", []) relationships = json_result.get("relationships", []) for entity in entities: # 确保 entity 有 "properties" 键,且其值为字典 if "properties" in entity and isinstance(entity["properties"], dict): entity["properties"]["切片"] = block # 打印美化版 all_entities.extend(entities) all_relationships.extend(relationships) # 将当前结果追加到总列表 # all_results.append({ # "entities": entities, # 已添加切片属性的实体列表 # "relationships": relationships, # 关系列表 # }) # 可选:打印美化版(使用 dumps) success = True except Exception as e: print(f" ⚠️ 第 {idx} 切片 JSON 解析失败: {e}") print(f" 原始响应: {repr(raw_response)}") continue # 跳过保存失败项 result = { "entities": all_entities, "relationships": all_relationships } return result def get_wxanli_entity_rela(markdown_content): keywords = ["一、故障现象", "故障名称:", "单位:"] chunks = extract_content_slices(markdown_content,keywords) valid_chunks = [chunk for chunk in chunks if chunk and len(chunk.strip()) > 10] if valid_chunks: # 调用处理函数 results = extract_wxanli(valid_chunks) # 这里可以将 results 保存到文件,例如按文件名保存为 JSON else: results = [] return results # if __name__ == "__main__": # input_directory = r"F:\zklnlp\HJ\hj_kg_code\kgrag\table_extract\files-1\图解目录_shenghna_output11_full_content.md" # # 调用目录处理函数 # mdcontent = read_markdown_file(input_directory) # if mdcontent is None: # print("无法读取文件,程序退出") # exit(1) # res = get_wxanli_entity_rela(markdown_content=mdcontent) # print(res)