GLM-4-9B-Chat知识图谱结合:结构化数据生成

想象一下,你手头有一堆杂乱无章的技术文档、产品说明或者行业报告,你想快速理清里面的关键信息,比如谁是谁、谁做了什么、谁和谁有关系。传统方法要么靠人工一点点梳理,费时费力;要么用简单的关键词匹配,抓不住深层联系。现在,把大语言模型和知识图谱结合起来,这事儿就变得简单多了。

GLM-4-9B-Chat这个模型,本身理解能力就不错,还能处理很长的文本。用它来从大段文字里自动找出人名、公司名、技术术语这些“实体”,再分析出它们之间的“关系”,最后构建成一个结构清晰的知识网络,整个过程可以自动化完成。这篇文章,我就带你看看怎么用GLM-4-9B-Chat来玩转知识图谱,从文本里自动生成结构化的数据。

1. 为什么需要大模型+知识图谱?

先说说背景。知识图谱是个好东西,它用“实体-关系-实体”这种三元组的形式,把信息组织成一张网,查询和推理起来特别方便。但建图谱有个老大难问题:怎么从非结构化的文本里,把需要的实体和关系准确无误地“挖”出来?这就是信息抽取,以前得靠精心设计的规则或者大量标注数据训练的模型,门槛不低。

大语言模型的出现改变了游戏规则。像GLM-4-9B-Chat这样的模型,经过海量文本训练,对语言的理解已经相当深入。让它来读文档,它不仅能认出哪些词是重要的实体,还能结合上下文,判断出“微软发布了Windows 11”这句话里,“微软”和“Windows 11”之间是“发布”关系。这就相当于给知识图谱的构建装上了一台强大的自动理解引擎。

把两者结合,优势很明显:自动化程度高,能处理多样化的文本,减少对大量标注数据的依赖。特别适合用来快速构建领域知识图谱,比如整理某个技术栈的文档、分析竞品信息、或是梳理客户反馈中的核心观点。

2. 核心任务拆解:从文本到图谱

用GLM-4-9B-Chat构建知识图谱,核心是让它帮我们完成三件事:

实体识别:把文本里提到的具体对象找出来。比如人名“张三”、组织名“智谱AI”、技术名词“深度学习”、产品名“GLM-4模型”。

关系抽取:找出实体之间是怎么联系的。比如“智谱AI 开发了 GLM-4模型”里的“开发”关系,“GLM-4模型 基于 Transformer 架构”里的“基于”关系。

属性抽取(可选):补充实体的详细信息。比如模型的“参数规模”是90亿,“发布时间”是2024年。

听起来复杂,但思路很直接:我们设计好提示词,引导GLM-4-9B-Chat按照我们想要的格式,从输入的文本中把这些信息“读”出来。

3. 实战:用GLM-4-9B-Chat抽取实体关系

理论说再多不如动手试。我们假设有一段关于AI模型的简介文本,目标是抽取出其中的实体和关系。

首先,确保你的环境里已经部署好了GLM-4-9B-Chat模型。这里假设你通过vLLM启动了一个兼容OpenAI API的服务。

import openai
import json

# 配置你的本地vLLM服务端信息
client = openai.OpenAI(
    api_key="your-api-key-here",  # 如果vLLM服务设置了api-key
    base_url="http://localhost:8000/v1"  # vLLM OpenAI API服务的地址
)

# 我们准备一段示例文本
sample_text = """
智谱AI于2024年发布了新一代开源模型GLM-4-9B-Chat。该模型是GLM-4系列的一部分,支持长达128K的上下文长度,并具备代码执行、工具调用等高级功能。GLM-4-9B-Chat在多项评测中表现优异,其技术报告发表在arXiv上。
"""

# 设计一个系统提示词,告诉模型我们要做什么
system_prompt = """你是一个信息抽取专家。你的任务是从用户提供的文本中,识别出所有重要的实体(如组织、产品、技术、时间等),以及这些实体之间的关系。
请严格按照以下JSON格式输出结果:
{
  "entities": [
    {"id": 1, "name": "实体名称", "type": "实体类型"},
    ...
  ],
  "relations": [
    {"subject_id": 主体实体ID, "predicate": "关系描述", "object_id": 客体实体ID},
    ...
  ]
}
实体类型请从以下选项中选择:ORGANIZATION(组织), PRODUCT(产品), TECHNOLOGY(技术), DATE(时间), PERSON(人物), LOCATION(地点), OTHER(其他)。
关系描述请使用简洁的动词或动词短语,如“发布”、“属于”、“支持”、“发表在”等。
"""

# 组合消息
messages = [
    {"role": "system", "content": system_prompt},
    {"role": "user", "content": f"请分析以下文本:\n{sample_text}"}
]

# 调用模型
response = client.chat.completions.create(
    model="glm-4-9b-chat",  # 你的模型服务名
    messages=messages,
    temperature=0.1,  # 温度设低一点,让输出更稳定
    max_tokens=1024
)

# 解析输出
result_text = response.choices[0].message.content
print("模型原始输出:")
print(result_text)
print("\n" + "="*50 + "\n")

# 尝试解析JSON(模型有时会在JSON外加说明)
try:
    # 尝试直接查找JSON部分
    import re
    json_match = re.search(r'\{.*\}', result_text, re.DOTALL)
    if json_match:
        result_json = json.loads(json_match.group())
    else:
        result_json = json.loads(result_text)
    
    print("解析后的结构化结果:")
    print(json.dumps(result_json, indent=2, ensure_ascii=False))
except json.JSONDecodeError as e:
    print("解析JSON失败,输出内容为:")
    print(result_text)

运行这段代码,你可能会得到类似下面的输出(具体内容可能因模型微调而异):

{
  "entities": [
    {"id": 1, "name": "智谱AI", "type": "ORGANIZATION"},
    {"id": 2, "name": "GLM-4-9B-Chat", "type": "PRODUCT"},
    {"id": 3, "name": "GLM-4系列", "type": "PRODUCT"},
    {"id": 4, "name": "2024年", "type": "DATE"},
    {"id": 5, "name": "128K上下文", "type": "TECHNOLOGY"},
    {"id": 6, "name": "代码执行", "type": "TECHNOLOGY"},
    {"id": 7, "name": "工具调用", "type": "TECHNOLOGY"},
    {"id": 8, "name": "arXiv", "type": "OTHER"}
  ],
  "relations": [
    {"subject_id": 1, "predicate": "发布", "object_id": 2},
    {"subject_id": 2, "predicate": "属于", "object_id": 3},
    {"subject_id": 2, "predicate": "支持", "object_id": 5},
    {"subject_id": 2, "predicate": "具备", "object_id": 6},
    {"subject_id": 2, "predicate": "具备", "object_id": 7},
    {"subject_id": 2, "predicate": "发表在", "object_id": 8}
  ]
}

看,模型成功地从一段话里,抽出了8个实体和6组关系。有了这个结构化的数据,离知识图谱就只有一步之遥了。

4. 构建知识图谱与查询优化

拿到实体和关系数据后,我们可以用图数据库(比如Neo4j、Nebula Graph)或者更轻量级的Python库(如networkx)把它存起来,形成一个真正的知识图谱。

import networkx as nx
import matplotlib.pyplot as plt

# 假设我们从上一步得到了result_json
data = result_json  # 这里用上面解析的结果示例

# 创建一个有向图
G = nx.DiGraph()

# 添加实体节点
for entity in data['entities']:
    G.add_node(entity['id'], label=entity['name'], type=entity['type'])

# 添加关系边
for rel in data['relations']:
    subject_name = next(e['name'] for e in data['entities'] if e['id'] == rel['subject_id'])
    object_name = next(e['name'] for e in data['entities'] if e['id'] == rel['object_id'])
    G.add_edge(rel['subject_id'], rel['object_id'], label=rel['predicate'])

# 简单查询示例:找到所有由“智谱AI”发布的产品
def find_products_by_org(graph_data, org_name):
    """查找指定组织发布的所有产品"""
    products = []
    entities = graph_data['entities']
    relations = graph_data['relations']
    
    # 找到组织实体的ID
    org_id = None
    for e in entities:
        if e['name'] == org_name and e['type'] == 'ORGANIZATION':
            org_id = e['id']
            break
    
    if org_id is None:
        return products
    
    # 查找关系
    for rel in relations:
        if rel['subject_id'] == org_id and rel['predicate'] == '发布':
            product_id = rel['object_id']
            product_name = next(e['name'] for e in entities if e['id'] == product_id)
            products.append(product_name)
    
    return products

# 执行查询
org_name = "智谱AI"
products = find_products_by_org(data, org_name)
print(f"组织 '{org_name}' 发布的产品有:{products}")

# 可视化图谱(小型图谱适用)
plt.figure(figsize=(10, 8))
pos = nx.spring_layout(G, seed=42)

# 绘制节点
node_colors = []
for node in G.nodes():
    node_type = G.nodes[node]['type']
    # 根据类型简单着色
    if node_type == 'ORGANIZATION':
        node_colors.append('lightblue')
    elif node_type == 'PRODUCT':
        node_colors.append('lightgreen')
    elif node_type == 'TECHNOLOGY':
        node_colors.append('orange')
    else:
        node_colors.append('gray')

nx.draw_networkx_nodes(G, pos, node_color=node_colors, node_size=1500)
nx.draw_networkx_labels(G, pos, labels={n: G.nodes[n]['label'] for n in G.nodes()})

# 绘制边
nx.draw_networkx_edges(G, pos, edge_color='gray', arrows=True)
edge_labels = nx.get_edge_attributes(G, 'label')
nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels)

plt.title("从文本抽取构建的知识图谱")
plt.axis('off')
plt.tight_layout()
plt.show()

这段代码做了两件事:一是演示了如何基于抽取结果进行简单的图查询(比如找某个公司发布了什么产品);二是把图谱可视化出来,让你直观地看到实体和关系网络。对于更复杂的查询,比如“找出所有支持工具调用功能的产品”,就需要在图数据库里写专门的查询语句了。

5. 打造智能问答系统

有了知识图谱,一个很自然的应用就是做智能问答。用户不用记复杂的查询语法,直接用自然语言问就行,比如“GLM-4-9B-Chat支持哪些功能?”

实现思路是:把用户的问题扔给GLM-4-9B-Chat,让它理解问题的意图,并转换成对知识图谱的查询(比如生成Cypher查询语句),执行查询得到答案后,再用自然语言组织好回复给用户。

def answer_question_with_knowledge_graph(question, graph_data, client):
    """
    结合知识图谱回答用户问题
    """
    # 第一步:让模型分析问题,并尝试生成查询思路
    analysis_prompt = f"""你是一个知识图谱查询助手。基于以下已知的图谱信息,请分析用户的问题,并给出回答该问题可能需要查找的实体和关系路径。
    
已知实体列表(格式:ID: 名称 [类型]):
{chr(10).join([f"{e['id']}: {e['name']} [{e['type']}]" for e in graph_data['entities']])}

已知关系列表(格式:主体 -> 关系 -> 客体):
{chr(10).join([f"{next(e['name'] for e in graph_data['entities'] if e['id'] == r['subject_id'])} -> {r['predicate']} -> {next(e['name'] for e in graph_data['entities'] if e['id'] == r['object_id'])}" for r in graph_data['relations']])}

用户问题:{question}

请简要说明:
1. 问题可能涉及的核心实体是什么?
2. 需要查找哪些关系?
3. 如果可能,直接给出答案。
"""
    
    analysis_response = client.chat.completions.create(
        model="glm-4-9b-chat",
        messages=[{"role": "user", "content": analysis_prompt}],
        temperature=0.1,
        max_tokens=512
    )
    
    analysis = analysis_response.choices[0].message.content
    print("问题分析:")
    print(analysis)
    print("\n" + "-"*50 + "\n")
    
    # 第二步:根据分析,我们可以编写逻辑来实际查询图谱数据
    # 这里简化处理:如果分析中直接包含了答案,就返回;否则尝试从图谱中匹配
    
    # 一个简单的关键词匹配示例(实际应用需要更复杂的逻辑)
    answer = "根据知识图谱信息:\n"
    
    # 检查问题类型
    if "功能" in question or "支持" in question:
        # 查找产品的功能/技术
        for rel in graph_data['relations']:
            subject = next(e for e in graph_data['entities'] if e['id'] == rel['subject_id'])
            obj = next(e for e in graph_data['entities'] if e['id'] == rel['object_id'])
            
            if subject['name'] == "GLM-4-9B-Chat" and rel['predicate'] in ['支持', '具备']:
                answer += f"- {subject['name']} {rel['predicate']} {obj['name']}\n"
    
    elif "发布" in question:
        # 查找发布关系
        for rel in graph_data['relations']:
            if rel['predicate'] == '发布':
                subject = next(e for e in graph_data['entities'] if e['id'] == rel['subject_id'])
                obj = next(e for e in graph_data['entities'] if e['id'] == rel['object_id'])
                answer += f"- {subject['name']} 发布了 {obj['name']}\n"
    
    else:
        answer += "暂时无法从现有知识中找到确切答案。"
    
    return answer

# 测试问答
test_question = "GLM-4-9B-Chat支持哪些功能?"
answer = answer_question_with_knowledge_graph(test_question, data, client)
print(f"问题:{test_question}")
print(f"回答:{answer}")

这个例子展示了问答系统的基本框架。实际应用中,你需要更鲁棒的自然语言理解、更精确的查询生成模块,以及处理更复杂图谱查询的能力。但核心思想不变:让大模型充当“理解用户意图”和“组织自然语言答案”的大脑,让知识图谱充当存储精确结构化知识的“记忆库”。

6. 效果怎么样?实际体验与建议

我用自己的文档试了试这套流程。整体感觉,GLM-4-9B-Chat在实体识别和关系抽取上的准确率挺不错的,尤其是对于技术领域的专有名词,识别得比较准。长上下文支持(128K)在处理多页文档时是个巨大优势,不用切分得太碎。

不过也有需要注意的地方。首先,提示词的设计非常关键。你需要清晰地告诉模型你想要什么格式的输出,实体类型有哪些,关系怎么描述。一开始我的提示词没写好,模型输出的格式五花八门,后来调整了几次才稳定下来。

其次,对于关系复杂的文本,模型偶尔会抽取出一些不太准确或冗余的关系。这时候,后处理规则或者用少量样本对模型进行微调,能有效提升效果。另外,这套流程处理大量文档时,调用API会有成本(时间或金钱),需要考虑批量处理和异步调用来优化速度。

最后,知识图谱的构建不是一劳永逸的。数据源更新了,图谱也需要更新。可以设计一个定期运行的自动化流水线:抓取新文档 -> 用GLM-4-9B-Chat抽取 -> 更新图谱数据库。

7. 总结

把GLM-4-9B-Chat和知识图谱结合起来用,确实为从文本中生成结构化数据打开了一扇新的大门。它降低了构建知识图谱的技术门槛,让自动化、智能化的信息整理成为可能。从简单的技术文档分析,到复杂的行业情报梳理,这个组合都能派上用场。

当然,它也不是万能的。对于精度要求极高的场景,可能还需要结合规则方法或人工校验。但毫无疑问,对于大多数希望从文本数据中挖掘价值的应用来说,这已经是一个强大且实用的工具链了。如果你正苦于如何处理堆积如山的文档,不妨试试这个思路,或许会有意想不到的收获。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐