Files
GraphRAGAgent/backend/pipeline/entity_extractor.py
T
admin 005fe504ad
GraphRAG CI/CD / build-and-deploy (push) Successful in 5m12s
fix: 修复 txt 索引 content_list 变量未定义 + 简化示例对齐
- txt 流程中 content_list 不存在导致 stats 阶段崩溃
- Few-shot 示例简化,使用短句精确匹配避免对齐失败
2026-06-18 17:10:05 +08:00

78 lines
4.3 KiB
Python

"""
Entity Extractor — LangExtract + DeepSeek entity extraction.
Independent implementation for the GraphRAG Studio backend.
"""
from __future__ import annotations
import os
from pathlib import Path
from dotenv import load_dotenv
import langextract as lx
from langextract.providers.openai import OpenAILanguageModel
load_dotenv(Path(__file__).parent.parent / ".env", override=True)
DEEPSEEK_API_KEY = os.getenv("DEEPSEEK_API_KEY", "")
DEEPSEEK_BASE_URL = os.getenv("DEEPSEEK_BASE_URL", "https://api.deepseek.com")
MODEL_ID = "deepseek-chat"
PROMPT_DESCRIPTION = (
"从建筑规范文本中按出现顺序提取命名实体。"
"实体类型:"
"构件 — 建筑构件和部位(防火墙、防火门、楼梯间、电梯井、管道井、变形缝、外墙、屋面、楼板、梁、柱、承重墙、隔墙、门窗、幕墙、雨篷、阳台、走廊、前室、竖井等);"
"设备 — 消防设备和系统(消火栓、灭火器、喷淋系统、报警系统、防烟排烟系统、应急照明、疏散指示、防火卷帘、消防电梯、消防水箱、消防水泵、气体灭火系统、火灾自动报警系统、电气火灾监控系统等);"
"设施 — 建筑设施和配套(停车场、锅炉房、变配电室、发电机房、储油间、空调机房、通风机房、电梯机房、消防控制室、水泵房等);"
"指标 — 技术参数和量化要求(耐火等级、防火间距、疏散宽度、最大面积、高度限值、距离要求、时间要求、容量要求、温度限值、压力要求等);"
"场所 — 建筑分类和空间类型(高层建筑、地下建筑、公共建筑、住宅建筑、工业建筑、商业建筑、医疗建筑、教育建筑、娱乐场所、仓库、厂房、中庭、避难层、避难走道、敞开楼梯间等);"
"材料 — 建筑材料和产品(不燃材料、难燃材料、可燃材料、防火涂料、防火玻璃、防火密封件、保温材料、装饰材料、钢结构防火保护材料等);"
"措施 — 防火措施和策略(防火分隔、防火封堵、自然排烟、机械加压送风、机械排烟、安全疏散、防火保护、消防供电、消防水源、灭火救援等);"
"条款 — 规范条文引用(强制性条文、推荐性条文、术语定义、一般规定、基本要求等)。"
)
EXAMPLES = [
lx.data.ExampleData(
text="公共建筑应设置防火墙。甲级防火门耐火极限为2.0h。消防控制室采用不燃材料。",
extractions=[
lx.data.Extraction(extraction_class="场所", extraction_text="公共建筑"),
lx.data.Extraction(extraction_class="构件", extraction_text="防火墙"),
lx.data.Extraction(extraction_class="构件", extraction_text="甲级防火门"),
lx.data.Extraction(extraction_class="指标", extraction_text="2.0h"),
lx.data.Extraction(extraction_class="设施", extraction_text="消防控制室"),
lx.data.Extraction(extraction_class="材料", extraction_text="不燃材料"),
],
),
lx.data.ExampleData(
text="住宅建筑应设室内消火栓。高位消防水箱容积为18m3。消防电梯前室设安全出口。",
extractions=[
lx.data.Extraction(extraction_class="场所", extraction_text="住宅建筑"),
lx.data.Extraction(extraction_class="设备", extraction_text="室内消火栓"),
lx.data.Extraction(extraction_class="设备", extraction_text="高位消防水箱"),
lx.data.Extraction(extraction_class="指标", extraction_text="18m3"),
lx.data.Extraction(extraction_class="构件", extraction_text="消防电梯前室"),
lx.data.Extraction(extraction_class="构件", extraction_text="安全出口"),
],
),
]
def create_model() -> OpenAILanguageModel:
if not DEEPSEEK_API_KEY:
raise ValueError("DEEPSEEK_API_KEY not set in backend/.env")
return OpenAILanguageModel(
model_id=MODEL_ID,
api_key=DEEPSEEK_API_KEY,
base_url=DEEPSEEK_BASE_URL,
)
def extract_entities(page_text: str, model: OpenAILanguageModel) -> lx.data.AnnotatedDocument:
return lx.extract(
text_or_documents=page_text,
prompt_description=PROMPT_DESCRIPTION,
examples=EXAMPLES,
model=model,
show_progress=False,
)