第六章 使用大模型构建知识图谱
本章的重点在于从原始文本中提取并结构化数据,将其转化为可以用于知识图谱构建的可用格式。
6.1 原理
网络上的数据或者企业内部数据,大多数以非结构化形式存在,如各类文档。仅仅使用文本嵌入明显无法满足相关的需求。以法律文本为例,当你需要具体检索来自某一章节的文档时,如果仅仅使用分块文本嵌入,会得到一些没什么检索返回的 top-k 文本块可能来自不同且无关的文档,从而影响回答的质量。因为系统仅基于语义相似度排序返回最高相关性块,而未始终判断这些块是否源自正确的章节,法律文本中经常会有很多相似的术语。随着分块数量的增加,误差只会越积累越多。同时,普通文本嵌入主要用于检索语义相近的内容,无法胜任过滤、排序或聚合等操作。此类任务必须依赖结构化数据,因为仅靠文本嵌入难以支持这些计算型操作。例如你想查询某领域有多少条法条。
对应的解决方法是预先设计结构化数据结构,基于大模型的自然与亚能理解能力,进行自动化抽取。万事万物都离不开具体问题具体分析。
当前我们假设的任务是从给出的文本中提取出客户公司的相关信息。
6.2 实现
这是我们使用的txt文件
戴尔股份有限公司(英语:Dell Inc.,简称戴尔)是总部位于美国得克萨斯州朗德罗克的公司,由迈克尔·戴尔于1984年创立。创立时公司的名称是PC's Limited,1987年改为现在的名字。戴尔以生产、设计、销售家用以及办公室电脑而闻名,它同时也涉足高端电脑市场,生产与售卖服务器、数据储存设备和网络设备等。戴尔的其他产品还包括软件、打印机及电脑周边产品等。当公司逐渐发展到其它非电脑领域后,公司的股东们在2003年的股东大会中批准公司从“戴尔电脑”(Dell Computer)改名为“戴尔公司”。
受益于戴尔的直接商业模式(即去除中间人,直接向客人卖产品),公司能够以更低廉的价格为客人提供各种产品,并保证送货上门。此外也确保戴尔的产品还未生产出来就已经售出,即是先有订单,之后才按客户要求组装电脑。
该公司以创办人迈克尔·戴尔命名,是全球前几大的科技公司,目前全球员工已经超过九万六千名。于2010年戴尔入选美国《财富》杂志每年评选的“500强公司”排行榜的第38名。《财富》同时也将戴尔列入科技业中全球第五大最受尊崇的公司。
戴尔成长的方式包括了内部运营增长以及非运营增长,意即戴尔在成立之际,有多次令人瞩目的收购和合并行动,例如2006年的Alienware及2009年的Perot Systems。在2009年戴尔出售的产品包括个人电脑、服务器、资料存储设备、网络交换器、软件及电脑周边设备。戴尔同时也贩售打印机及由其他厂商所生产的电子产品。戴尔因为在供应链管理及电子商务的各项创新而受到赞誉。
2012年,《财富》杂志根据总营收将戴尔列为全美第44大公司以及在德州的第6大公司,同时也是德州第二大非石油公司(仅次于AT&T),也是在奥斯汀地区最大的公司。
=====
恒大集团(英语:Evergrande Group,港交所:3333),简称恒大,是总部位于深圳的中国大型综合性企业集团,1996年由许家印在广州创办。[3]集团核心业务为房地产开发,是中国大型地产发展商之一,项目遍及全国两百多个城市,此外亦发展新能源汽车、旅游、体育、金融、健康养老等多元化业务。其入股的广州恒大淘宝足球俱乐部是亚洲近年表现最出色的足球俱乐部之一。集团于2016年进入《财富》世界500强,[4]2020年排行第152位。[5]2021年9月时,恒大集团深陷债务危机,欠供应商、债权人和投资者总计1.9665万亿元人民币(合3000多亿美元),大致相当于2020年中国国内生产总值的2%。[6]赵长龙于2021年7月8日调任为恒大物业集团有限公司的执行董事兼副董事长兼总经理。[7]2023年,恒大连续补发2021年报及2022年报,截至2022年末,负债总额为2.44兆元。[8][9]同年8月,恒大集团依据美国“破产法”第十五章向纽约曼哈顿法庭提出相关申请[10]。9月28日,恒大集团于香港联交所发布公告,董事会主席许家印因涉嫌违法犯罪,已被依法采取强制措施。恒大集团及旗下公司股票全面暂停交易,当中包括恒大集团、恒大物业集团有限公司和恒大新能源汽车集团有限公司[11]。2024年,香港高等法院下令中国恒大集团即时清盘,并在几个月后要求前高层披露资产。[12][13]
=====
高盛集团公司(英语:The Goldman Sachs Group, Inc.)是一家美国跨国投资银行与金融服务公司,其总部位于纽约市曼哈顿。高盛集团提供投资管理、证券、资产管理、主经纪商与证券承销等服务。高盛集团是全球最大的投资机构之一;[2]同时是美国国库证券的国债一级自营商,也是通常意义上的知名做市商。高盛集团还拥有一家直销银行——高盛美国银行(Goldman Sachs Bank USA)。高盛集团成立于1869年,其总部位于曼哈顿下城的韦斯特街200号;同时也在全球各大金融中心设有办事处。[3]
由于在次贷危机期间参与了资产证券化,高盛集团在2007年至2008年全球金融危机中遭受损失。[4][5] 作为问题资产救助计划的一部分,高盛集团得到了美国财政部100亿美元的投资;该金融纾困计划源自《经济稳定紧急法案》。该投资于2008年11月开始,并于2009年6月开始偿还。[6][7]
想要实现这个功能, 首先要根据自己任务抽象出数据模型,并对其进行实现。然后通过编写提示词实现基于大模型的结构化数据提取功能。最后使用Pydantic库定义数据模式,将模式可传递给模型,引导其生成符合规范的输出。
import requests
import json
import re
from neo4j import GraphDatabase
from typing import List, Dict, Optional
from pydantic import BaseModel, Field
# 第一步:数据模型构造
# 构建用于信息提取的结构化数据模型
# 公司类型枚举定义
company_types = [
"科技公司",
"房地产",
"咨询服务"
]
class Location(BaseModel):
"""
位置对象:用于表示公司的物理地址信息
"""
address: Optional[str] = Field(
None,
description="The street address of the location. 位置的街道地址"
)
city: Optional[str] = Field(
None,
description="The city where the location is situated. 位置所在的城市"
)
state_province: Optional[str] = Field(
None,
description="The state or province of the location. 位置所在的州或省份"
)
country: Optional[str] = Field(
None,
description="The country of the location. 位置所在的国家"
)
class Company(BaseModel):
"""
公司对象:用于表示公司的核心信息
"""
# 必需字段 - 核心识别信息
name: str = Field(
..., # 必需字段
description="The official name of the company. 公司的正式名称"
)
founded_year: int = Field(
..., # 必需字段
description="The year when the company was founded. 公司成立年份"
)
headquarters: Location = Field(
..., # 必需字段 (Location对象本身是必需的)
description="The headquarters location of the company. 公司总部位置信息"
)
is_public: bool = Field(
..., # 必需字段
description="Whether the company is publicly traded or privately held. 公司是否为上市公司"
)
company_type: str = Field(
..., # 必需字段
description="The type of company. 公司类型",
enum=company_types, # 使用枚举限制取值范围
)
# 可选字段 - 补充信息
founded_date: Optional[str] = Field(
None, # 可选字段
description="The date when the company was founded. Use yyyy-MM-dd format. 公司成立日期,使用yyyy-MM-dd格式"
)
website: Optional[str] = Field(
None, # 可选字段
description="The official website URL of the company. 公司官方网站URL"
)
# 第二步:信息提取
# 使用大语言模型从文本中提取结构化信息
# Neo4j 数据库连接配置
NEO4J_URI = "bolt://localhost:7687"
NEO4J_USER = "neo4j"
NEO4J_PASSWORD = "你的密码"
# Ollama 本地大语言模型配置
OLLAMA_BASE_URL = "http://localhost:11434"
LLM_MODEL = "qwen3:32b"
# 初始化 Neo4j 数据库连接
neo4j_driver = GraphDatabase.driver(NEO4J_URI, auth=(NEO4J_USER, NEO4J_PASSWORD))
def remove_think_tags(text: str) -> str:
"""
从文本中移除 <think> 标签及其内容
"""
pattern = r'<think>.*?</think>'
cleaned_text = re.sub(pattern, '', text, flags=re.DOTALL)
return cleaned_text.strip()
def extract_json_from_response(response_text: str) -> Optional[str]:
"""
从LLM响应中提取JSON内容,忽略<think>标签
"""
if not response_text:
print(f"[JSON解析] 响应文本为空")
return None
# 首先尝试提取代码块中的JSON
import re
code_block_pattern = r'```(?:json)?\s*({[^`]*?})\s*```'
match = re.search(code_block_pattern, response_text, re.DOTALL)
if match:
try:
json_str = match.group(1)
json.loads(json_str) # 验证JSON有效性
print(f"[JSON解析] 从代码块中提取JSON成功")
return json_str
except json.JSONDecodeError as e:
print(f"[JSON解析] 代码块JSON验证失败: {
e}")

最低0.47元/天 解锁文章
98

被折叠的 条评论
为什么被折叠?



