Files
PlantAI-rag/docs/V2_USAGE_GUIDE.md
2026-07-10 17:59:59 +08:00

556 lines
13 KiB
Markdown
Executable File

# V2 版本使用指南
> 版本: v2.0
> 日期: 2026-03-18
> 用途: 使用 PlantConnectome 优化版提示词提取 70+ 维结构化信息
---
## 快速开始 (3步)
### 第1步: 准备环境
```bash
# 进入项目目录
cd /home/xia-lab/gene-family-mas
# 确保依赖已安装
pip install openai PyMuPDF -q
# 设置 API 密钥
export DASHSCOPE_API_KEY="your-api-key"
```
### 第2步: 准备文件
```bash
# 确保提示词文件存在
ls -la prompts/extraction_prompt_v2.md
# 准备 PDF 文件
# 将你的论文 PDF 放在 paper/ceshi/1pian/ 目录下
```
### 第3步: 运行提取
```bash
# 使用 V2 提示词提取
python3 scripts/extract_structured.py \
paper/ceshi/1pian/你的论文.pdf \
--output paper/ceshi/1pian/extracted/v2_result.json
```
---
## 详细使用说明
## 方法一: 使用现有提取脚本 (推荐)
### 1.1 基本用法
```bash
# 基本提取
python3 scripts/extract_structured.py \
paper/ceshi/1pian/苦荞SPL2019BMCplantbios12870-019-1916-6.pdf \
--output paper/ceshi/1pian/extracted/v2_extraction.json
```
### 1.2 修改脚本使用 V2 提示词
编辑 `scripts/extract_structured.py`,修改提示词加载部分:
```python
# 找到 call_llm_extract 函数
# 修改提示词加载路径
def call_llm_extract(pdf_text: str, api_key: str = "", model: str = DEFAULT_MODEL):
"""调用LLM提取结构化信息"""
# 加载 V2 提示词
prompt_path = Path(__file__).parent.parent / "prompts" / "extraction_prompt_v2.md"
with open(prompt_path, 'r', encoding='utf-8') as f:
prompt_template = f.read()
# 替换占位符
user_prompt = prompt_template.replace("{chunk_text}", pdf_text[:120000])
# 调用 API...
```
### 1.3 批量提取
```bash
# 创建批量提取脚本
for pdf in paper/ceshi/1pian/*.pdf; do
echo "处理: $pdf"
python3 scripts/extract_structured.py "$pdf" \
--output "paper/ceshi/1pian/extracted/$(basename $pdf .pdf)_v2.json"
done
```
---
## 方法二: 使用 Python 直接调用
### 2.1 完整示例代码
创建 `run_v2_extraction.py`:
```python
#!/usr/bin/env python3
"""
V2 版本提取示例
"""
import os
import json
from pathlib import Path
# 配置
API_KEY = os.getenv("DASHSCOPE_API_KEY", "")
MODEL = "kimi-k2.5" # 或 "qwen-max"
def extract_from_pdf(pdf_path: str, output_path: str = None):
"""
使用 V2 提示词从 PDF 提取结构化信息
Args:
pdf_path: PDF 文件路径
output_path: 输出 JSON 文件路径 (可选)
Returns:
提取结果字典
"""
from openai import OpenAI
import fitz # PyMuPDF
# 1. 读取 PDF
print(f"📄 读取 PDF: {pdf_path}")
doc = fitz.open(pdf_path)
text = ""
for page in doc:
text += page.get_text("text") + "\n"
doc.close()
print(f" 文本长度: {len(text)} 字符")
# 2. 加载 V2 提示词
prompt_path = "/home/xia-lab/gene-family-mas/prompts/extraction_prompt_v2.md"
with open(prompt_path, 'r', encoding='utf-8') as f:
prompt_template = f.read()
# 3. 替换占位符
user_prompt = prompt_template.replace("{chunk_text}", text[:120000])
# 4. 调用 API
print(f"🤖 调用 {MODEL} 提取...")
client = OpenAI(
api_key=API_KEY,
base_url="https://coding.dashscope.aliyuncs.com/v1"
)
response = client.chat.completions.create(
model=f"bailian/{MODEL}",
messages=[
{"role": "system", "content": "You are a specialized bioinformatics paper information extraction expert."},
{"role": "user", "content": user_prompt}
],
temperature=0.1,
max_tokens=6000
)
# 5. 解析结果
result_text = response.choices[0].message.content
# 清理 JSON
import re
result_text = re.sub(r'[\x00-\x08\x0b-\x0c\x0e-\x1f]', '', result_text)
if "```json" in result_text:
result_text = result_text.split("```json")[1]
if "```" in result_text:
result_text = result_text.split("```")[0]
result_text = result_text.strip()
try:
result = json.loads(result_text)
print("✅ 提取成功!")
except json.JSONDecodeError as e:
print(f"⚠️ JSON 解析失败: {e}")
result = {"error": "JSON解析失败", "raw": result_text[:500]}
# 6. 保存结果
if output_path:
os.makedirs(os.path.dirname(output_path), exist_ok=True)
with open(output_path, 'w', encoding='utf-8') as f:
json.dump(result, f, ensure_ascii=False, indent=2)
print(f"💾 结果已保存: {output_path}")
return result
# 使用示例
if __name__ == "__main__":
pdf_path = "paper/ceshi/1pian/苦荞SPL2019BMCplantbios12870-019-1916-6.pdf"
output_path = "paper/ceshi/1pian/extracted/v2_result.json"
result = extract_from_pdf(pdf_path, output_path)
# 打印统计
if "error" not in result:
entities = result.get("entities", [])
relations = result.get("relations", [])
print(f"\n📊 提取统计:")
print(f" 实体数量: {len(entities)}")
print(f" 关系数量: {len(relations)}")
```
### 2.2 运行代码
```bash
# 设置 API 密钥
export DASHSCOPE_API_KEY="your-api-key"
# 运行提取
python3 run_v2_extraction.py
```
---
## 方法三: 使用 Jupyter Notebook
### 3.1 创建 Notebook
```python
# Cell 1: 导入依赖
import os
import json
from openai import OpenAI
import fitz
# Cell 2: 配置
API_KEY = os.getenv("DASHSCOPE_API_KEY")
MODEL = "kimi-k2.5"
# Cell 3: 读取 PDF
pdf_path = "paper/ceshi/1pian/苦荞SPL2019BMCplantbios12870-019-1916-6.pdf"
doc = fitz.open(pdf_path)
text = ""
for page in doc:
text += page.get_text("text") + "\n"
doc.close()
print(f"文本长度: {len(text)} 字符")
# Cell 4: 加载 V2 提示词
with open("prompts/extraction_prompt_v2.md", 'r') as f:
prompt_template = f.read()
user_prompt = prompt_template.replace("{chunk_text}", text[:120000])
# Cell 5: 调用 API
client = OpenAI(api_key=API_KEY, base_url="https://coding.dashscope.aliyuncs.com/v1")
response = client.chat.completions.create(
model=f"bailian/{MODEL}",
messages=[
{"role": "system", "content": "You are a specialized bioinformatics paper information extraction expert."},
{"role": "user", "content": user_prompt}
],
temperature=0.1,
max_tokens=6000
)
# Cell 6: 解析结果
result_text = response.choices[0].message.content
result = json.loads(result_text) # 可能需要清理
# Cell 7: 查看结果
print(f"实体数量: {len(result.get('entities', []))}")
print(f"关系数量: {len(result.get('relations', []))}")
# Cell 8: 保存
with open("v2_result.json", 'w') as f:
json.dump(result, f, ensure_ascii=False, indent=2)
```
---
## 验证提取结果
### 检查实体
```python
import json
with open("paper/ceshi/1pian/extracted/v2_result.json", 'r') as f:
result = json.load(f)
entities = result.get("entities", [])
print(f"实体总数: {len(entities)}")
# 按类型分组
from collections import Counter
type_counts = Counter(e.get("type", "unknown") for e in entities)
print("\n实体类型分布:")
for t, c in type_counts.most_common():
print(f" {t}: {c}")
# 显示前5个实体
print("\n前5个实体:")
for e in entities[:5]:
print(f" - {e.get('display_name', e.get('name'))}")
```
### 检查关系
```python
relations = result.get("relations", [])
print(f"关系总数: {len(relations)}")
# 按类型分组
rel_counts = Counter(r.get("relationship", "unknown") for r in relations)
print("\n关系类型分布 (Top 10):")
for r, c in rel_counts.most_common(10):
print(f" {r}: {c}")
# 显示前5个关系
print("\n前5个关系:")
for r in relations[:5]:
print(f" [{r.get('source_type')}] {r.get('source')}")
print(f" {r.get('relationship')}")
print(f" [{r.get('target_type')}] {r.get('target')}")
```
---
## 常见问题
### Q1: API 密钥未设置
**错误**: `未设置API密钥: DASHSCOPE_API_KEY`
**解决**:
```bash
export DASHSCOPE_API_KEY="your-api-key"
# 或在代码中设置
os.environ["DASHSCOPE_API_KEY"] = "your-api-key"
```
### Q2: PyMuPDF 未安装
**错误**: `No module named 'fitz'`
**解决**:
```bash
pip install PyMuPDF
```
### Q3: JSON 解析失败
**错误**: `JSON解析失败`
**解决**: 检查并清理返回的文本
```python
import re
# 移除控制字符
text = re.sub(r'[\x00-\x08\x0b-\x0c\x0e-\x1f]', '', text)
# 提取 JSON 块
if "```json" in text:
text = text.split("```json")[1]
if "```" in text:
text = text.split("```")[0]
```
### Q4: Token 超限
**错误**: `max_tokens 超限`
**解决**: 截断 PDF 文本
```python
# 只取前 120000 字符
text = text[:120000]
```
### Q5: 提取结果为空
**检查**:
1. PDF 是否可读
2. 提示词是否正确加载
3. API 调用是否成功
4. 返回内容是否包含 JSON
---
## 高级用法
### 批量处理多篇论文
```python
import os
import glob
from pathlib import Path
def batch_extract(pdf_dir: str, output_dir: str):
"""批量提取多篇论文"""
pdf_files = glob.glob(f"{pdf_dir}/*.pdf")
for pdf_path in pdf_files:
filename = Path(pdf_path).stem
output_path = f"{output_dir}/{filename}_v2.json"
print(f"\n{'='*60}")
print(f"处理: {filename}")
try:
result = extract_from_pdf(pdf_path, output_path)
if "error" not in result:
entities = len(result.get("entities", []))
relations = len(result.get("relations", []))
print(f"✅ 成功: {entities} 实体, {relations} 关系")
else:
print(f"❌ 失败: {result.get('error')}")
except Exception as e:
print(f"❌ 错误: {e}")
# 使用
batch_extract(
"paper/ceshi/1pian",
"paper/ceshi/1pian/extracted"
)
```
### 对比 V1 和 V2 结果
```python
def compare_results(v1_path: str, v2_path: str):
"""对比 V1 和 V2 提取结果"""
with open(v1_path) as f:
v1 = json.load(f)
with open(v2_path) as f:
v2 = json.load(f)
# 统计
v1_entities = len(v1.get("entities", []))
v2_entities = len(v2.get("entities", []))
v1_relations = len(v1.get("relations", []))
v2_relations = len(v2.get("relations", []))
print("V1 vs V2 对比:")
print(f" 实体: {v1_entities} → {v2_entities} ({v2_entities/v1_entities:.1f}x)")
print(f" 关系: {v1_relations} → {v2_relations} (提升: {v2_relations - v1_relations})")
```
---
## 最佳实践
### 1. 预处理 PDF
```python
# 清理 PDF 文本
def clean_pdf_text(text: str) -> str:
"""清理 PDF 提取的文本"""
# 移除多余空白
text = re.sub(r'\n+', '\n', text)
# 移除页眉页脚
lines = [l for l in text.split('\n') if not l.strip().isdigit()]
return '\n'.join(lines)
```
### 2. 后处理结果
```python
def post_process(result: dict) -> dict:
"""后处理提取结果"""
# 去重实体
entities = result.get("entities", [])
seen = set()
unique_entities = []
for e in entities:
key = (e.get("name"), e.get("type"))
if key not in seen:
seen.add(key)
unique_entities.append(e)
result["entities"] = unique_entities
# 去重关系
relations = result.get("relations", [])
seen = set()
unique_relations = []
for r in relations:
key = (r.get("source"), r.get("relationship"), r.get("target"))
if key not in seen:
seen.add(key)
unique_relations.append(r)
result["relations"] = unique_relations
return result
```
### 3. 质量检查
```python
def quality_check(result: dict) -> dict:
"""检查提取质量"""
issues = []
# 检查实体
entities = result.get("entities", [])
if len(entities) < 10:
issues.append(f"实体数量过少: {len(entities)}")
for e in entities:
if not e.get("type"):
issues.append(f"实体缺少类型: {e.get('name')}")
if not e.get("display_name"):
issues.append(f"实体缺少display_name: {e.get('name')}")
# 检查关系
relations = result.get("relations", [])
if len(relations) < 5:
issues.append(f"关系数量过少: {len(relations)}")
for r in relations:
if not r.get("source_type"):
issues.append(f"关系缺少source_type")
if not r.get("target_type"):
issues.append(f"关系缺少target_type")
return {
"quality_score": max(0, 100 - len(issues) * 10),
"issues": issues
}
```
---
## 总结
### 最简单的使用方式
```bash
# 1. 设置密钥
export DASHSCOPE_API_KEY="your-key"
# 2. 运行提取
python3 scripts/extract_structured.py \
paper/ceshi/1pian/你的论文.pdf \
--output paper/ceshi/1pian/extracted/v2_result.json
# 3. 查看结果
cat paper/ceshi/1pian/extracted/v2_result.json | jq '.entities | length'
cat paper/ceshi/1pian/extracted/v2_result.json | jq '.relations | length'
```
### 关键文件
| 文件 | 路径 | 说明 |
|------|------|------|
| V2 提示词 | `prompts/extraction_prompt_v2.md` | PlantConnectome优化版 |
| 提取脚本 | `scripts/extract_structured.py` | 主提取程序 |
| 使用指南 | `docs/V2_USAGE_GUIDE.md` | 本文档 |
---
*文档版本: v1.0*
*更新日期: 2026-03-18*