005fe504ad
GraphRAG CI/CD / build-and-deploy (push) Successful in 5m12s
- txt 流程中 content_list 不存在导致 stats 阶段崩溃 - Few-shot 示例简化,使用短句精确匹配避免对齐失败
78 lines
4.3 KiB
Python
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,
|
|
)
|