law / cons_graph.py
dora6668's picture
Upload folder using huggingface_hub
3c35d3b verified
Raw History Blame Contribute Delete
29.4 kB
"""
法律知识图谱构建程序
使用方法:
1. 运行单个模式:
python script.py --modes 1
2. 运行多个模式:
python script.py --modes 1,2,3
3. nohup后台运行:
nohup python script.py --modes 2,4 --sample_size 10 > output.log 2>&1 &
4. 自定义路径和参数:
python script.py --modes 1,2 --sample_size 20 --model_path /your/model/path
模式说明:
- 模式1:单个查询的综合知识图谱(案例+法条)
- 模式2:批量构建综合知识图谱(案例+法条)
- 模式3:单个查询的仅案例知识图谱
- 模式4:批量构建仅案例知识图谱
"""
import json
import os
from typing import Dict, List, Any
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM
def load_retrieval_results_by_id(folder_path):
"""按ID加载预检索结果,同时记录原始文件夹路径"""
results_dict = {}
folder_paths = {} # 记录每个query_id对应的文件夹路径
if not os.path.exists(folder_path):
print(f"警告: 检索结果文件夹不存在: {folder_path}")
return results_dict, folder_paths
for query_id in os.listdir(folder_path):
query_folder = os.path.join(folder_path, query_id)
if not os.path.isdir(query_folder):
continue
# 加载原始查询
query_file = os.path.join(query_folder, 'query.json')
if os.path.exists(query_file):
with open(query_file, 'r', encoding='utf-8') as f:
query_data = json.load(f)
actual_query_id = query_data.get('id', query_id)
# 加载检索摘要
summary_file = os.path.join(query_folder, 'search_summary.json')
retrieved_docs = []
if os.path.exists(summary_file):
with open(summary_file, 'r', encoding='utf-8') as f:
summary = json.load(f)
# 加载每个检索到的文档
for item in summary:
doc_file = os.path.join(query_folder, f"score_{item['file_name']}")
if os.path.exists(doc_file):
with open(doc_file, 'r', encoding='utf-8') as f:
doc_data = json.load(f)
retrieved_docs.append(doc_data)
# 存储结果 - 使用ID作为键,同时记录文件夹路径
results_dict[actual_query_id] = retrieved_docs
folder_paths[actual_query_id] = query_folder # 记录原始文件夹路径
print(f"已加载 {len(results_dict)} 条检索结果(按ID索引)")
return results_dict, folder_paths
def load_qwen32b_model(model_path: str):
"""加载qwen32B本地模型"""
print(f"正在加载qwen32B模型: {model_path}")
tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(
model_path,
torch_dtype=torch.bfloat16,
device_map="auto",
trust_remote_code=True
)
print("模型加载完成!")
return model, tokenizer
def call_qwen32b_for_knowledge_graph_with_laws(case_data_list: List[Dict], law_data_list: List[Dict], model, tokenizer, query_id: str) -> Dict:
"""
调用qwen32B模型构建包含案例和法条的知识图谱
"""
# 构建案例信息
cases_text = ""
if case_data_list:
cases_text = "## 相关案例:\n"
for i, case in enumerate(case_data_list[:3]): # 取top3案例
fact = case.get('fact', '')
reason = case.get('reason', '')
result = case.get('result', '')
similarity = case.get('similarity', 0)
cases_text += f"""
### 案例{i+1}(相似度:{similarity:.3f}):
**案件事实:** {fact}
**法院判决:** {reason}
**判决结果:** {result}
"""
# 构建法条信息 - 修正为实际的数据结构
laws_text = ""
if law_data_list:
laws_text = "## 相关法条:\n"
for i, law in enumerate(law_data_list[:3]): # 🎯 改为取top3法条
law_id = law.get('id', '') # ✅ 法条ID
law_content = law.get('fact', '') # ✅ 法条内容在fact字段
similarity = law.get('similarity', 0) # ✅ 相似度
rank = law.get('rank', i+1) # ✅ 排名
laws_text += f"""
### 法条{i+1}(ID:{law_id},相似度:{similarity:.3f},排名:{rank}):
**法条内容:** {law_content}
"""
# 构建综合prompt
prompt = f"""你是专业的刑法知识图谱构建专家。请基于提供的相关案例和法条,构建一个**四层关联的综合知识图谱**。这不是简单的信息抽取,而是要深度分析案例与法条之间的对应关系,构建完整的法律推理链条。
## 核心建模原则:
1. **案例与法条的对应映射**:找出每个案例事实对应的具体法条条文
2. **法律推理链条完整性**:从事实→法条依据→法院认定→最终判决的完整链条
3. **多案例法条融合**:整合多个相似案例和相关法条,形成统一的知识结构
4. **层级关系明确性**:不同层次实体间的逻辑关系要清晰准确
## 四层建模框架:
### 🏛️ 法条层(法理基础):
**核心实体类型**:
- 【法条条文】:具体的法律条款(如"刑法第XXX条")
- 【犯罪构成要件】:法条规定的构成犯罪的必要条件
- 【法定刑罚幅度】:法条规定的刑罚范围和标准
- 【适用条件】:法条的适用范围和前提条件
- 【量刑情节】:法条规定的加重、减轻情节
### 📋 事实层(客观事实):
**核心实体类型**:
- 【犯罪行为】:具体的违法行为和手段
- 【行为后果】:犯罪造成的损失和影响
- 【时空要素】:犯罪的时间、地点、环境
- 【物证材料】:涉案物品、证据、检验结果
- 【主体身份】:当事人的身份、关系、状态
### ⚖️ 推理层(法律认定):
**核心实体类型**:
- 【罪名认定】:法院确定的具体罪名
- 【构成要件匹配】:事实与法条构成要件的对应关系
- 【量刑情节认定】:法院认定的具体量刑情节
- 【法院观点】:法院的法律评价和推理过程
- 【适用法条确定】:法院选择适用的具体法条
### 📜 判决层(裁判结果):
**核心实体类型**:
- 【确定罪名】:最终认定的罪名
- 【具体刑期】:确定的刑罚期限
- 【执行方式】:刑罚执行的具体方式
- 【附加刑罚】:罚金、没收财产等附加刑
- 【程序事项】:羁押折抵、缓刑考验等
## 知识图谱构建要求:
### 第一步:实体识别与层级分类
请按照以下格式输出四层实体:
**法条层实体:**
- 【刑法第XXX条】(属性:【条文内容:..., 适用对象:..., 刑罚范围:...】)
- 【XXX罪构成要件】(属性:【主观要件:..., 客观要件:..., 主体要件:...】)
**事实层实体:**
- 【具体犯罪行为】(属性:【行为方式:..., 行为时间:..., 涉案金额:...】)
- 【被告人】(属性:【身份特征:..., 前科情况:..., 认罪态度:...】)
**推理层实体:**
- 【XXX罪认定】(属性:【认定依据:..., 构成要件满足:..., 量刑情节:...】)
- 【法院法律评价】(属性:【推理过程:..., 适用法条:..., 量刑理由:...】)
**判决层实体:**
- 【有期徒刑X年】(属性:【刑期计算:..., 执行地点:..., 特殊规定:...】)
- 【罚金X万元】(属性:【缴纳期限:..., 缴纳方式:..., 执行措施:...】)
### 第二步:层内关系构建
**法条层关系:**
1. 【刑法第XXX条】 -> 【规定】 -> 【XXX罪构成要件】
2. 【XXX罪构成要件】 -> 【决定】 -> 【法定刑罚幅度】
**事实层关系:**
1. 【被告人】 -> 【实施】 -> 【具体犯罪行为】
2. 【具体犯罪行为】 -> 【造成】 -> 【行为后果】
**推理层关系:**
1. 【构成要件匹配】 -> 【支撑】 -> 【罪名认定】
2. 【法院观点】 -> 【基于】 -> 【适用法条确定】
**判决层关系:**
1. 【确定罪名】 -> 【对应】 -> 【具体刑期】
2. 【具体刑期】 -> 【通过】 -> 【执行方式】
### 第三步:跨层映射关系(核心)
**法条→事实映射:**
1. 【XXX罪构成要件】 -> 【匹配】 -> 【具体犯罪行为】
2. 【适用条件】 -> 【符合】 -> 【被告人身份】
**事实→推理映射:**
1. 【具体犯罪行为】 -> 【证明】 -> 【构成要件匹配】
2. 【行为后果】 -> 【影响】 -> 【量刑情节认定】
**法条→推理映射:**
1. 【刑法第XXX条】 -> 【作为依据】 -> 【罪名认定】
2. 【法定刑罚幅度】 -> 【指导】 -> 【法院观点】
**推理→判决映射:**
1. 【罪名认定】 -> 【确定】 -> 【确定罪名】
2. 【量刑情节认定】 -> 【影响】 -> 【具体刑期】
**法条→判决映射:**
1. 【法定刑罚幅度】 -> 【约束】 -> 【具体刑期】
2. 【刑法条文】 -> 【直接依据】 -> 【执行方式】
## 特别注意:
1. **具体化**:避免抽象概念,多用具体的法条号、具体金额、具体时间等
2. **一致性**:同一概念在不同层次中的表述要保持一致
3. **完整性**:每个案例的推理链条要完整,从事实到法条到判决
4. **关联性**:多个案例间的共同模式要体现出来
请根据以下材料构建知识图谱:
{cases_text}
{laws_text}
## 构建要求:
请严格按照上述四个步骤,逐步构建完整的四层知识图谱。特别要注意案例中的具体事实与相关法条条文的精确对应关系。
## 输出要求:
1. 严格按照四个步骤输出一次完整的知识图谱
2. 不要重复输出相同内容
3. 不要添加额外的总结或解释
4. 输出完成后立即结束
"""
try:
# 调用qwen32B模型
inputs = tokenizer(prompt, return_tensors="pt")
inputs = {k: v.to(model.device) for k, v in inputs.items()}
with torch.no_grad():
outputs = model.generate(
**inputs,
max_new_tokens=3072, # 增加输出长度以容纳更复杂的知识图谱
temperature=0.1,
do_sample=True,
pad_token_id=tokenizer.eos_token_id
)
# 解码输出
response = tokenizer.decode(outputs[0], skip_special_tokens=True)
# 提取模型回复部分(去掉输入的prompt)
model_output = response[len(prompt):].strip()
# 构建返回结构
knowledge_graph = {
"query_id": query_id,
"total_cases": len(case_data_list),
"total_laws": len(law_data_list),
"model_output": model_output,
"source_data": {
"cases": case_data_list[:3], # 保存top3案例的完整数据
"laws": law_data_list[:3] # 🎯 改为保存top3法条的完整数据
}
}
return knowledge_graph
except Exception as e:
print(f"调用qwen32B模型时出错: {str(e)}")
return None
def call_qwen32b_for_knowledge_graph(case_data: Dict, model, tokenizer) -> Dict:
"""
调用qwen32B模型构建单个案例的知识图谱(保留原有功能)
"""
fact = case_data.get('fact', '')
reason = case_data.get('reason', '')
result = case_data.get('result', '')
# 构建prompt(与原代码相同)
prompt = f"""你是专业的刑法知识图谱构建专家。请将案件材料分为**事实层**、**推理层**、**判决层**三个层面进行建图。
## 三层建模框架:
### 事实层(基于fact字段):
**客观事实实体**:犯罪行为、时间地点、涉案物品、证据材料
**当事人实体**:被告人、被害人、证人(客观身份)
**行为属性**:具体行为描述、数量、金额、检测结果
### 推理层(基于reason字段):
**法律认定实体**:罪名、犯罪构成、量刑情节、适用法条
**司法判断实体**:法院观点、量刑理由、法律后果
**法律属性**:法律评价、刑罚种类、处罚依据
### 判决层(基于result字段):
**判决结果实体**:确定罪名、具体刑期、罚金数额、执行方式
**程序规定实体**:刑期计算、羁押折抵、罚金缴纳要求
## 输出格式:
**事实层实体:**
- 【实体名】(属性:【客观属性1:值1,客观属性2:值2】)
**推理层实体:**
- 【实体名】(属性:【法律属性1:值1,法律属性2:值2】)
**判决层实体:**
- 【实体名】(属性:【判决执行属性1:值1,属性2:值2】)
**事实层关系:**
1. 【实体1】 -> 【客观关系】 -> 【实体2】
**推理层关系:**
1. 【实体1】 -> 【法律关系】 -> 【实体2】
**判决层关系:**
1. 【实体1】 -> 【判决关系】 -> 【实体2】
**映射关系:**
1. 【事实层实体】 -> 【支撑/证明/构成】 -> 【推理层实体】
2. 【推理层实体】 -> 【依据/确定】 -> 【判决层实体】
请根据以下案件材料构建知识图谱:
**案件事实:** {fact}
**法院判决:** {reason}
**判决结果:** {result}
## 输出要求:
1. 严格按照格式输出一次完整的知识图谱
2. 不要重复输出相同内容
3. 输出完成后立即结束
"""
try:
# 调用qwen32B模型
inputs = tokenizer(prompt, return_tensors="pt")
inputs = {k: v.to(model.device) for k, v in inputs.items()}
with torch.no_grad():
outputs = model.generate(
**inputs,
max_new_tokens=2048,
temperature=0.1,
do_sample=True,
pad_token_id=tokenizer.eos_token_id
)
# 解码输出
response = tokenizer.decode(outputs[0], skip_special_tokens=True)
# 提取模型回复部分(去掉输入的prompt)
model_output = response[len(prompt):].strip()
# 构建返回结构
knowledge_graph = {
"case_id": case_data.get('id', 'unknown'),
"similarity": case_data.get('similarity', 0),
"model_output": model_output,
"raw_case_data": {
"fact": fact,
"reason": reason,
"result": result
}
}
return knowledge_graph
except Exception as e:
print(f"调用qwen32B模型时出错: {str(e)}")
return None
def build_comprehensive_knowledge_graph(query_id: str, case_results: Dict, law_results: Dict,
case_folder_paths: Dict, model, tokenizer):
"""
为指定查询ID构建包含案例和法条的综合知识图谱
Args:
query_id: 查询ID
case_results: 案例检索结果字典
law_results: 法条检索结果字典
case_folder_paths: 查询ID到案例文件夹路径的映射
model: qwen32B模型
tokenizer: 对应的tokenizer
"""
# 检查是否存在对应的检索结果
case_data_list = case_results.get(query_id, [])
law_data_list = law_results.get(query_id, [])
if not case_data_list and not law_data_list:
print(f"警告: 未找到ID为{query_id}的任何检索结果(案例或法条)")
return None
if query_id not in case_folder_paths:
print(f"警告: 未找到ID为{query_id}的文件夹路径")
return None
# 使用案例的原始文件夹路径作为输出目录(在此目录下新增文件)
output_folder = case_folder_paths[query_id]
print(f"开始为查询ID {query_id} 构建综合知识图谱...")
print(f"案例数量: {len(case_data_list)}, 法条数量: {len(law_data_list)}")
print(f"输出路径: {output_folder}")
# 调用模型构建综合知识图谱
print("调用qwen32B模型构建综合知识图谱...")
kg = call_qwen32b_for_knowledge_graph_with_laws(case_data_list, law_data_list, model, tokenizer, query_id)
if kg is None:
print(f"查询ID {query_id} 综合知识图谱构建失败")
return None
# 保存综合知识图谱到案例文件夹(新增文件,不影响原始文件)
comprehensive_output_file = os.path.join(output_folder, "knowledge_graph_comprehensive.json")
with open(comprehensive_output_file, 'w', encoding='utf-8') as f:
json.dump(kg, f, ensure_ascii=False, indent=2)
print(f"综合知识图谱已保存到: {comprehensive_output_file}")
print(f"查询ID {query_id} 的综合知识图谱构建完成!")
return kg
def build_knowledge_graphs_for_top3_cases(query_id: str, case_results: Dict, folder_paths: Dict, model, tokenizer):
"""
为指定查询ID的top3案例构建知识图谱并保存到原始文件夹(保留原有功能)
"""
if query_id not in case_results:
print(f"警告: 未找到ID为{query_id}的检索结果")
return None
if query_id not in folder_paths:
print(f"警告: 未找到ID为{query_id}的文件夹路径")
return None
# 获取top3案例
top3_cases = case_results[query_id][:3]
if not top3_cases:
print(f"警告: ID为{query_id}的检索结果为空")
return None
# 使用原始文件夹路径作为输出目录
output_folder = folder_paths[query_id]
knowledge_graphs = []
print(f"开始为查询ID {query_id} 构建top3案例的知识图谱...")
print(f"输出路径: {output_folder}")
for i, case_data in enumerate(top3_cases):
print(f"处理第{i+1}个案例,调用qwen32B模型...")
# 调用qwen32B模型构建知识图谱
kg = call_qwen32b_for_knowledge_graph(case_data, model, tokenizer)
if kg is None:
print(f"案例{i+1}知识图谱构建失败,跳过")
continue
kg["rank"] = i + 1 # 添加排名信息
knowledge_graphs.append(kg)
# 保存单个案例的知识图谱到原始文件夹(新增文件)
case_output_file = os.path.join(output_folder, f"knowledge_graph_case_{i+1}.json")
with open(case_output_file, 'w', encoding='utf-8') as f:
json.dump(kg, f, ensure_ascii=False, indent=2)
print(f"案例{i+1}知识图谱已保存到: {case_output_file}")
if not knowledge_graphs:
print(f"查询ID {query_id} 没有成功构建任何知识图谱")
return None
# 保存合并的知识图谱到原始文件夹(新增文件)
combined_output_file = os.path.join(output_folder, "knowledge_graphs_top3_combined.json")
combined_kg = {
"query_id": query_id,
"folder_path": output_folder,
"total_cases": len(knowledge_graphs),
"knowledge_graphs": knowledge_graphs,
"creation_time": str(torch.cuda.current_device()) if torch.cuda.is_available() else "cpu"
}
with open(combined_output_file, 'w', encoding='utf-8') as f:
json.dump(combined_kg, f, ensure_ascii=False, indent=2)
print(f"合并的知识图谱已保存到: {combined_output_file}")
print(f"查询ID {query_id} 的知识图谱构建完成! 共处理 {len(knowledge_graphs)} 个案例")
return knowledge_graphs
def batch_build_comprehensive_knowledge_graphs(case_results: Dict, law_results: Dict, case_folder_paths: Dict,
model, tokenizer, query_ids: List[str] = None):
"""
批量构建多个查询的综合知识图谱(案例+法条)
Args:
case_results: 案例检索结果字典
law_results: 法条检索结果字典
case_folder_paths: 查询ID到案例文件夹路径的映射
model: qwen32B模型
tokenizer: 对应的tokenizer
query_ids: 要处理的查询ID列表,如果为None则处理所有
"""
if query_ids is None:
# 合并所有可用的查询ID
all_case_ids = set(case_results.keys())
all_law_ids = set(law_results.keys())
query_ids = list(all_case_ids.union(all_law_ids))
print(f"开始批量处理 {len(query_ids)} 个查询的综合知识图谱...")
success_count = 0
for query_id in query_ids:
try:
print(f"\n{'='*60}")
print(f"正在处理查询ID: {query_id}")
print(f"{'='*60}")
result = build_comprehensive_knowledge_graph(query_id, case_results, law_results,
case_folder_paths, model, tokenizer)
if result is not None:
success_count += 1
except Exception as e:
print(f"处理查询ID {query_id} 时出错: {str(e)}")
continue
print(f"\n批量处理完成! 成功处理 {success_count}/{len(query_ids)} 个查询")
def batch_build_knowledge_graphs(case_results: Dict, folder_paths: Dict, model, tokenizer, query_ids: List[str] = None):
"""
批量构建多个查询的知识图谱(保留原有功能 - 仅案例)
"""
if query_ids is None:
query_ids = list(case_results.keys())
print(f"开始批量处理 {len(query_ids)} 个查询的知识图谱...")
success_count = 0
for query_id in query_ids:
try:
print(f"\n{'='*50}")
print(f"正在处理查询ID: {query_id}")
print(f"{'='*50}")
result = build_knowledge_graphs_for_top3_cases(query_id, case_results, folder_paths, model, tokenizer)
if result is not None:
success_count += 1
except Exception as e:
print(f"处理查询ID {query_id} 时出错: {str(e)}")
continue
print(f"\n批量处理完成! 成功处理 {success_count}/{len(query_ids)} 个查询")
# ============== 修改后的主函数 - 支持模式选择 ==============
import argparse
def main():
"""主函数 - 支持选择运行模式"""
# 添加命令行参数解析
parser = argparse.ArgumentParser(description='法律知识图谱构建程序')
parser.add_argument('--modes', type=str, default='1,2,3,4',
help='要运行的模式,用逗号分隔。例如: --modes 1,2 或 --modes 1 或 --modes 1,2,3,4')
parser.add_argument('--sample_size', type=int, default=5,
help='处理的样本数量,默认5个查询ID')
parser.add_argument('--model_path', type=str, default='/data1/xubuqiang/QWEN32',
help='模型路径')
parser.add_argument('--case_folder', type=str, default='/data2/xubuqiang/RAG_dataset/results_folder_train_5_tasks',
help='案例结果文件夹路径')
parser.add_argument('--law_folder', type=str, default='/data2/xubuqiang/RAG_dataset/results_folder_law_articles_train_5_tasks',
help='法条结果文件夹路径')
args = parser.parse_args()
# 解析要运行的模式
try:
selected_modes = [int(mode.strip()) for mode in args.modes.split(',')]
valid_modes = [1, 2, 3, 4]
selected_modes = [mode for mode in selected_modes if mode in valid_modes]
if not selected_modes:
print("❌ 错误:没有有效的模式选择,请使用1-4之间的数字")
return
except ValueError:
print("❌ 错误:模式参数格式不正确,请使用逗号分隔的数字,如: 1,2,3")
return
print(f"🚀 开始运行法律知识图谱构建程序 - 选择模式: {selected_modes}")
print("="*80)
# 使用命令行参数设置路径
model_path = args.model_path
case_results_folder = args.case_folder
law_results_folder = args.law_folder
print(f"📂 模型路径: {model_path}")
print(f"📂 案例文件夹: {case_results_folder}")
print(f"📂 法条文件夹: {law_results_folder}")
print(f"📊 样本数量: {args.sample_size}")
# 第一步:加载模型
print("📖 第一步:加载Qwen32B模型...")
try:
model, tokenizer = load_qwen32b_model(model_path)
print("✅ 模型加载成功!")
except Exception as e:
print(f"❌ 模型加载失败: {str(e)}")
return
# 第二步:加载检索结果
print("\n📂 第二步:加载检索结果...")
print("加载案例检索结果...")
case_results, case_folder_paths = load_retrieval_results_by_id(case_results_folder)
print("加载法条检索结果...")
law_results, law_folder_paths = load_retrieval_results_by_id(law_results_folder)
if not case_results and not law_results:
print("❌ 未找到任何检索结果,程序退出")
return
# 获取可用的查询ID
case_query_ids = set(case_results.keys())
law_query_ids = set(law_results.keys())
all_query_ids = list(case_query_ids.union(law_query_ids))
print(f"✅ 找到 {len(case_results)} 个案例查询结果")
print(f"✅ 找到 {len(law_results)} 个法条查询结果")
print(f"✅ 总共 {len(all_query_ids)} 个唯一查询ID")
# 取样本数量作为示例(你可以改为更多或全部)
sample_query_ids = all_query_ids[:args.sample_size]
print(f"📋 将处理的查询IDs: {sample_query_ids}")
# ================== 根据选择运行对应模式 ==================
print("\n" + "="*80)
print(f"🔥 开始运行选定的功能模式: {selected_modes}...")
print("="*80)
# 模式1:构建单个查询的综合知识图谱(案例+法条)
if 1 in selected_modes and sample_query_ids:
query_id = sample_query_ids[0]
print(f"\n🎯 模式1: 为查询ID {query_id} 构建综合知识图谱(案例+法条)...")
print("-" * 60)
try:
comprehensive_kg = build_comprehensive_knowledge_graph(
query_id, case_results, law_results, case_folder_paths, model, tokenizer
)
if comprehensive_kg:
print(f"✅ 模式1完成: 成功构建了包含 {comprehensive_kg['total_cases']} 个案例和 {comprehensive_kg['total_laws']} 个法条的综合知识图谱")
else:
print("❌ 模式1失败: 综合知识图谱构建失败")
except Exception as e:
print(f"❌ 模式1出错: {str(e)}")
# 模式2:批量构建综合知识图谱(案例+法条)
if 2 in selected_modes:
print(f"\n🎯 模式2: 批量构建综合知识图谱(案例+法条)...")
print("-" * 60)
try:
batch_build_comprehensive_knowledge_graphs(
case_results, law_results, case_folder_paths, model, tokenizer, sample_query_ids
)
print("✅ 模式2完成: 批量综合知识图谱构建完成")
except Exception as e:
print(f"❌ 模式2出错: {str(e)}")
# 模式3:构建单个查询的仅案例知识图谱
if 3 in selected_modes and sample_query_ids:
query_id = sample_query_ids[0]
print(f"\n🎯 模式3: 为查询ID {query_id} 构建仅案例知识图谱...")
print("-" * 60)
try:
case_kg = build_knowledge_graphs_for_top3_cases(
query_id, case_results, case_folder_paths, model, tokenizer
)
if case_kg:
print(f"✅ 模式3完成: 成功构建了 {len(case_kg)} 个案例的知识图谱")
else:
print("❌ 模式3失败: 案例知识图谱构建失败")
except Exception as e:
print(f"❌ 模式3出错: {str(e)}")
# 模式4:批量构建仅案例知识图谱
if 4 in selected_modes:
print(f"\n🎯 模式4: 批量构建仅案例知识图谱...")
print("-" * 60)
try:
batch_build_knowledge_graphs(
case_results, case_folder_paths, model, tokenizer, sample_query_ids
)
print("✅ 模式4完成: 批量案例知识图谱构建完成")
except Exception as e:
print(f"❌ 模式4出错: {str(e)}")
# 最终总结
print("\n" + "="*80)
print(f"🎉 选定模式 {selected_modes} 运行完成!")
print("="*80)
print(f"📊 处理统计:")
print(f" - 案例查询数量: {len(case_results)}")
print(f" - 法条查询数量: {len(law_results)}")
print(f" - 处理样本数量: {len(sample_query_ids)}")
print(f" - 运行模式: {selected_modes}")
print("\n✨ 所有知识图谱文件已保存到对应的查询文件夹中!")
if __name__ == "__main__":
main()