实体抽取与关系提取
课程简介
用 LLM Agent 自动抽取实体与关系,构建图谱骨架。
实体抽取与关系提取:Agent 驱动方案详解
一、超越传统 NER
传统命名实体识别(NER)系统基于序列标注模型,在标准数据集上表现良好,但在实际应用中存在明显局限:
- 领域迁移困难:在新闻语料上训练的 NER 模型迁移到医疗领域,准确率大幅下降
- 实体类型固定:只能识别预定义的几种实体类型(人名、地名、组织名)
- 难以处理嵌套实体:如「上海交通大学」中的「上海」
- 上下文利用有限:无法利用深层语义信息进行实体消歧
Agent 驱动的实体抽取通过 LLM 的语义理解和推理能力,在这些方面都实现了质的突破。
二、提示词设计
实体抽取 Agent 的核心是提示词设计。一个好的提示词应该包含以下要素:
2.1 角色定义
entity_extraction_prompt = '''
你是一个{领域}实体抽取专家。你的任务是从非结构化文本中精确抽取实体和关系。
角色要求:
- 对{领域}概念有深入理解
- 能够识别显式和隐式的实体提及
- 能够处理缩写、别名和共指关系
- 在不确定时标注置信度而非猜测
实体类型定义:
{entity_type_definitions}
关系类型定义:
{relation_type_definitions}
输出格式:
{output_schema}
'''
2.2 输出格式约束
使用 JSON Schema 确保输出可解析:
{
"type": "object",
"properties": {
"entities": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {"type": "string"},
"type": {"type": "string", "enum": ["Company", "Person", "Product"]},
"mentions": {"type": "array", "items": {"type": "string"}},
"confidence": {"type": "number", "minimum": 0, "maximum": 1}
},
"required": ["name", "type"]
}
},
"relations": {
"type": "array",
"items": {
"type": "object",
"properties": {
"subject": {"type": "string"},
"relation": {"type": "string"},
"object": {"type": "string"},
"confidence": {"type": "number"}
},
"required": ["subject", "relation", "object"]
}
}
}
}
2.3 处理规则
提示词中应该包含明确的处理规则:
处理规则:
1. 共指消解:如果「苹果公司」后文简称为「该公司」或「苹果」,归并为同一实体
2. 别名处理:「Apple Inc.」、「Apple」、「苹果公司」视为同一实体
3. 边界条件:
- 如果对实体类型不确定,confidence 设为 < 0.7
- 如果对实体边界不确定,标记为 low_confidence
- 如果遇到超出定义类型但语义上应被抽取的实体,标记为 unknown_type
4. 需要请求人工确认的情况:
- 实体类型完全无法确定
- 两个候选实体高度相似但无法判断是否同一实体
- 抽取结果中的关系与已知事实矛盾
三、多阶段抽取流程
一次性抽取所有实体和关系往往效果不佳。推荐多阶段流程:
3.1 第一阶段:粗粒度扫描
def stage1_coarse_extraction(text):
'''第一阶段的粗粒度扫描'''
prompt = f'''
扫描以下文本,标记所有可能是实体的名词短语。
不需要分类,只需要标记边界和可能的类型候选。
文本:{text}
输出格式:[{{"mention": "...", "span": [start, end], "type_candidates": ["..."]}}]
'''
candidates = llm.generate(prompt)
return parse_candidates(candidates)
此阶段的目标是召回而非精确。宁可多召回非实体,也不要遗漏潜在实体。
3.2 第二阶段:细粒度分类
def stage2_fine_classification(candidates, context):
'''第二阶段:对候选实体进行精确分类'''
results = []
for candidate in candidates:
prompt = f'''
在上下文中对候选实体进行精确分类。
上下文:{context}
候选实体:{candidate["mention"]}(位置:{candidate["span"]})
候选类型:{self.entity_types}
请判断该候选实体的类型。如果确信是实体,输出类型和置信度。
如果判断不是实体,输出 null。
'''
result = llm.generate(prompt)
if result["entity_type"]:
results.append({
"name": candidate["mention"],
"type": result["entity_type"],
"confidence": result["confidence"]
})
return results
3.3 第三阶段:关系抽取
def stage3_relation_extraction(entities, text):
'''第三阶段:识别实体之间的关系'''
# 构建实体上下文
entity_context = "
".join([f"- {e['name']} ({e['type']})" for e in entities])
prompt = f'''
在以下文本中,分析已识别实体之间的关系。
文本:{text}
已识别实体:
{entity_context}
可能的关系类型:
{self.relation_types}
对每对可能有关系的实体,判断关系类型和方向。
如果关系与文本时间信息相关,标注时间属性。
'''
relations = llm.generate(prompt)
return parse_relations(relations)
3.4 多阶段的优势
多阶段相比一次性抽取的优势:
- 精度更高:每个阶段聚焦一个子任务,降低认知负载
- 错误隔离:前阶段的错误不会污染后阶段的判断
- 中间结果可审查:每个阶段的结果都可以由人工审核或自动化检查
四、冲突解决
多来源抽取必然产生冲突。Agent 驱动的冲突解决机制:
class ConflictResolver:
'''基于 Agent 的冲突解决'''
def resolve(self, conflicts, sources):
'''解决实体抽取中的冲突'''
resolved = []
for conflict in conflicts:
# 按置信度排序
sorted_by_confidence = sorted(
conflict.candidates,
key=lambda x: x.confidence,
reverse=True
)
# 最高的置信度明显高于其他 → 选择最高置信度
if sorted_by_confidence[0].confidence - sorted_by_confidence[1].confidence > 0.3:
resolved.append(sorted_by_confidence[0])
# 置信度接近 → 让 Agent 根据证据推理
elif sorted_by_confidence[0].confidence - sorted_by_confidence[1].confidence <= 0.3:
resolution = self._agent_based_resolution(conflict)
resolved.append(resolution)
# 所有候选置信度都低 → 标记为需人工确认
elif all(c.confidence < 0.6 for c in conflict.candidates):
resolved.append({
"status": "needs_review",
"candidates": conflict.candidates,
"reason": "所有候选置信度均低于阈值"
})
return resolved
def _agent_based_resolution(self, conflict):
'''让 Agent 基于证据推理解决冲突'''
evidence_prompt = f'''
以下是对同一实体抽取结果的分歧:
{conflict}
请基于以下证据进行判断:
1. 上下文证据:实体在文本中的使用上下文
2. 一致性检查:与知识图谱已有事实的一致性
3. 来源可靠性:不同数据源的可靠性评估
请给出最终的实体类型和理由。
'''
resolution = llm.generate(evidence_prompt)
return resolution
五、增量更新
知识图谱不是一次性构建完成的,而是持续更新的。Agent 驱动的增量更新策略:
class IncrementalUpdater:
'''增量更新管理'''
def process_new_document(self, document, existing_kg):
# 1. 抽取新实体和关系
new_entities, new_relations = self.extract(document)
# 2. 与已有知识关联
for new_entity in new_entities:
# 检查是否已存在于图谱
existing = existing_kg.find_similar(new_entity.name)
if existing:
# 关联到已有节点
new_entity.link_to(existing)
else:
# 创建新节点
new_node = existing_kg.create_node(new_entity)
# 检查是否需要合并已有相似节点
merge_candidates = existing_kg.find_merge_candidates(new_entity)
if merge_candidates:
self._suggest_merge(new_entity, merge_candidates)
# 3. 更新关系
for relation in new_relations:
# 优先关联到已有实体,而非创建新关系
subject = existing_kg.find(relation.subject) or relation.subject
obj = existing_kg.find(relation.object) or relation.object
# 检查关系是否已存在
if not existing_kg.has_relation(subject, relation.type, obj):
existing_kg.create_relation(subject, relation.type, obj, relation.properties)
return new_entities, new_relations
六、质量保证机制
def agent_quality_check(extracted_data, source_document):
'''Agent 驱动的质量检查'''
checks = [
check_entity_completeness, # 是否遗漏重要实体?
check_relation_accuracy, # 关系判断是否准确?
check_consistency, # 与已知事实是否一致?
check_temporal_consistency, # 时间信息是否一致?
check_format_compliance # 输出格式是否符合要求?
]
issues = []
for check in checks:
result = check(extracted_data, source_document)
issues.extend(result)
return issues
七、总结
Agent 驱动的实体抽取和关系提取通过精心设计的提示词、多阶段流程、冲突解决机制和增量更新策略,实现了比传统 NER 系统更灵活、更精确的知识抽取能力。多阶段流程让每个 Agent 聚焦于单一子任务,冲突解决机制处理多来源不一致的情况,增量更新策略确保新知识与已有图谱的平滑集成。这些技术的综合应用,使得大规模、持续性的知识图谱构建成为可能。
五、实战:用 LLM Agent 进行实体抽取
5.1 单阶段抽取
最简单的方案是让 LLM 一次性完成实体识别和关系提取:
def single_pass_extraction(text):
prompt = f"""
从以下文本中抽取所有实体和关系:
文本:{text}
输出格式:
实体列表:[{名称, 类型}, ...]
关系列表:[{头实体, 关系, 尾实体}, ...]
"""
return llm.generate(prompt)
5.2 多阶段抽取
更可靠的方式是分阶段进行:
def multi_stage_extraction(text):
# 阶段1:实体识别
entities = extract_entities(text)
# 阶段2:实体链接(解决同义、歧义)
linked = link_entities(entities, existing_kg)
# 阶段3:关系提取
relations = extract_relations(text, linked)
# 阶段4:质量验证
validated = validate_triples(linked, relations)
return validated
六、实体链接(Entity Linking)
实体链接是决定图谱质量的关键步骤。它解决的主要问题:
- 同义合并:“Apple”、“Apple Inc.”、“苹果公司”指向同一实体
- 歧义消解:“苹果”是水果还是公司?根据上下文判断
- 别名管理:“埃隆·马斯克”、“Elon Musk”、“马斯克”
七、挑战与最佳实践
- 长文本处理:文档太长时需要分段处理
- 跨段落关联:同一实体的信息分散在多段中
- 隐含关系:有些关系不是显式表达的
- 领域术语:专业领域的实体识别需要领域知识
八、总结
实体抽取和关系提取是知识图谱构建的核心工序。
关键要点回顾:
- 两阶段流程:先实体识别,再关系提取
- 多阶段抽取方案比单阶段更可靠
- 实体链接解决同义合并和歧义消解
- 关系类型提示显着提升提取质量
- 质量验证是确保图谱准确性的关键
五、实战:用 LLM Agent 进行实体抽取
5.1 单阶段抽取
最简单的方案是让 LLM 一次性完成实体识别和关系提取:
def single_pass_extraction(text):
prompt = f"""
从以下文本中抽取所有实体和关系:
文本:{text}
输出格式:
实体列表:[{名称, 类型}, ...]
关系列表:[{头实体, 关系, 尾实体}, ...]
"""
return llm.generate(prompt)
5.2 多阶段抽取
更可靠的方式是分阶段进行:
def multi_stage_extraction(text):
# 阶段1:实体识别
entities = extract_entities(text)
# 阶段2:实体链接(解决同义、歧义)
linked = link_entities(entities, existing_kg)
# 阶段3:关系提取
relations = extract_relations(text, linked)
# 阶段4:质量验证
validated = validate_triples(linked, relations)
return validated
六、实体链接(Entity Linking)
实体链接是决定图谱质量的关键步骤。它解决的主要问题:
- 同义合并:“Apple”、“Apple Inc.”、“苹果公司”指向同一实体
- 歧义消解:“苹果”是水果还是公司?根据上下文判断
- 别名管理:“埃隆·马斯克”、“Elon Musk”、“马斯克”
七、挑战与最佳实践
- 长文本处理:文档太长时需要分段处理
- 跨段落关联:同一实体的信息分散在多段中
- 隐含关系:有些关系不是显式表达的
- 领域术语:专业领域的实体识别需要领域知识
八、总结
实体抽取和关系提取是知识图谱构建的核心工序。
关键要点回顾:
- 两阶段流程:先实体识别,再关系提取
- 多阶段抽取方案比单阶段更可靠
- 实体链接解决同义合并和歧义消解
- 关系类型提示显着提升提取质量
- 质量验证是确保图谱准确性的关键
五、实战:用 LLM Agent 进行实体抽取
5.1 单阶段抽取
最简单的方案是让 LLM 一次性完成实体识别和关系提取:
def single_pass_extraction(text):
prompt = f"""
从以下文本中抽取所有实体和关系:
文本:{text}
输出格式:
实体列表:[{名称, 类型}, ...]
关系列表:[{头实体, 关系, 尾实体}, ...]
"""
return llm.generate(prompt)
5.2 多阶段抽取
更可靠的方式是分阶段进行:
def multi_stage_extraction(text):
# 阶段1:实体识别
entities = extract_entities(text)
# 阶段2:实体链接(解决同义、歧义)
linked = link_entities(entities, existing_kg)
# 阶段3:关系提取
relations = extract_relations(text, linked)
# 阶段4:质量验证
validated = validate_triples(linked, relations)
return validated
六、实体链接(Entity Linking)
实体链接是决定图谱质量的关键步骤。它解决的主要问题:
- 同义合并:“Apple”、“Apple Inc.”、“苹果公司”指向同一实体
- 歧义消解:“苹果”是水果还是公司?根据上下文判断
- 别名管理:“埃隆·马斯克”、“Elon Musk”、“马斯克”
七、挑战与最佳实践
- 长文本处理:文档太长时需要分段处理
- 跨段落关联:同一实体的信息分散在多段中
- 隐含关系:有些关系不是显式表达的
- 领域术语:专业领域的实体识别需要领域知识
八、总结
实体抽取和关系提取是知识图谱构建的核心工序。
关键要点回顾:
- 两阶段流程:先实体识别,再关系提取
- 多阶段抽取方案比单阶段更可靠
- 实体链接解决同义合并和歧义消解
- 关系类型提示显着提升提取质量
- 质量验证是确保图谱准确性的关键
延伸阅读
- 📺 B 站播放列表:Agentic Knowledge Graph — 智能体驱动知识图谱构建
- 📚 更多学习资源,请访问 deeplearning.ai 官网