如何使用 Knowledge Graph 和 LLM 构建构建问答系统

如何使用 Knowledge Graph 和 LLM 构建构建问答系统

基于模拟 FAQ 文档构建的知识图谱

本文将介绍一个基于知识图谱(使用上一篇文章介绍的方法构建)和大型语言模型(LLM,此处使用 Gemma3-4b-it-qat)的简易问答系统。选择 Gemma3-4b 是因为其模型尺寸适中,可在普通笔记本电脑上运行,且具备出色的指令遵循能力。

我们将以一个虚构智能手机产品的 FAQ 文本为例,复用上一篇文章的代码为其构建知识图谱,并在此基础上搭建一个能够回答相关产品问题的系统,示例如下:

如何使用 Knowledge Graph 和 LLM 构建构建问答系统

问答系统示例

本文将涵盖以下内容:
1. 问答系统简介
2. 系统设计思路
3. 核心代码解析
4. 局限性及改进方向

问答系统简介

根据 Google 的定义:

问答系统是一种软件应用,它接收用户用自然语言提出的问题,通过理解问题意图并从知识源检索信息或生成新内容,来提供直接、相关的答案。

本文的“知识源”是由 Gemma3 生成的一段模拟 FAQ 文本,可在本项目的 GitHub 仓库中找到。我们可以运行仓库中的 main.py 脚本来构建知识图谱并保存到输出目录:

python main.py --inputpath ./input/sample-faq.txt --outlabel faq

该命令会将 NetworkX 图对象保存为 nx_graph.pkl 文件,后续构建问答系统时将加载此文件。

系统设计思路

核心思路是:从用户问题中提取实体和关键词,在知识图谱中找到所有相关的节点和边,然后将这些结构化信息与原始问题一同提供给 LLM,让其基于图谱中的事实进行回答。具体流程如下:

给定一个问题 q 和已构建的知识图谱 G
1. 使用 LLM 从 q 中提取命名实体(entity_keywords)和关系谓词(relation_keywords)。
2. 枚举 entity_keywords 中所有可能的实体对组合。因为我们无法预先假设某个实体在图中是源节点还是目标节点,这一步确保了查询的完整性。
3. 对于上一步得到的每一对实体 (u, v),在 G 中查找 uv 之间的所有路径。这能揭示两个实体之间所有可能的关系和知识连接,是提升系统能力的关键步骤。
4. 对于找到的每条路径,提取源节点与目标节点之间的具体关系,形成三元组(例如 (box, include, charger))。
5. 将所有提取到的三元组加入列表 relations
6. 对 relation_keywords 进行类似处理:对于每个关系关键词 r,找到所有由 r 连接的边,形成三元组并加入 relations 列表。
7. 最后,将这些三元组(作为给定事实)与原始问题 q 一起封装在一个提示词中,传递给 LLM,让其基于这些事实生成答案。

核心代码解析

首先,使用 main.py 构建知识图谱:

python main.py --inputpath ./input/sample-faq.txt --outlabel faq

然后从生成的 pickle 文件中加载图谱:

import pickle
G = pickle.load(open(graph_file, "rb"))

定义一个通用的函数,用于向 LLM 发送文本和系统提示词并获取响应:

def get_llm_response(text, system_prompt):
    response = ollama.chat(model=model, messages=[
        {"role": "system", "content": system_prompt},
        {"role": "user", "content": text}
        ])
    resp_content = response['message']['content']
    return resp_content

接下来,需要从用户查询中提取实体和关系关键词(对应设计思路的第 1 步)。为此,我们构造一个基础的系统提示词:

system_prompt_key_words = """You are a helpful assistant, expert of English language who can extracts keyword from the given question in root form (e.g. ran becomes run) and lowercase.
The returned keywords should be critical to answer the question.
Categorize the keywords into entity and relation keywords.
keywords must be in root form and lowercase.
The response should be in following format, no additional text:
{"entity": [list of entity keywords], "relation": [list of relation keywords]}"""

response = get_llm_response(query, system_prompt_key_words)
keyword_resp = json.loads(response)
entity_keywords = keyword_resp.get('entity', [])
relation_keywords = keyword_resp.get('relation', [])

假设提取到的 entity_keywords[box, charger, phone],我们需要生成所有可能的实体对组合,以便全面查询图谱:

pairs = list(combinations(entities, 2))

对于每个实体对,在图中查找所有节点和边(路径):

paths = list(nx.all_simple_paths(G, source=u, target=target_nodes))

上述所有步骤(第 1-6 步)被整合在以下函数中:

def search_kg2(G, query):
    response = get_llm_response(query, system_prompt_key_words)
    keyword_resp = json.loads(response)
    entity_keywords = keyword_resp.get('entity', [])
    relation_keywords = keyword_resp.get('relation', [])
    entities = [part.strip() for part in entity_keywords]
    pairs = list(combinations(entities, 2))
    relations = []
    for u, v in pairs:
        target_nodes = get_nodes(G, v)
        paths = list(nx.all_simple_paths(G, source=u, target=target_nodes))
        for path in paths:
            for i in range(len(path)-1):
                for key in G[path[i]][path[i+1]]:
                    rel = G[path[i]][path[i+1]][key]['relation']
                    relations.append((path[i],rel, path[i+1]))

    for rel_keyword in relation_keywords:
        relations.extend([(u, rel, v) for u, v, rel in G.edges.data("relation") if str(rel) == rel_keyword])

    return relations

从上述函数获得所有以三元组形式表示的知识图谱边后,我们将它们嵌入到一个指令式提示词中,发送给 LLM 生成最终答案:

context = f"""
    You are given facts from a knowledge graph:

    {triples}

    Answer the user query based ONLY on these facts.
    Answer in full sentence.
    Query: {query}
    """
response = ollama.chat(model="gemma3:4b-it-qat",
             messages=[{"role": "user", "content": context}])
print(f'query: {query}nAnswer:{response["message"]["content"]}')

系统会返回如下答案:

如何使用 Knowledge Graph 和 LLM 构建构建问答系统

可以看到,对于知识图谱中缺乏相关事实的问题,LLM 会合理地拒绝回答。

本文所有代码可在以下文件中找到:
https://github.com/nayash/knowledge-graph-demo/blob/master/qa-from-kg.ipynb

局限性

如上所示,我们以较小的代价创建了一个基础的问答系统,因为 LLM 承担了文本预处理、信息抽取等大量工作。但该系统仍不完美,初步评估中发现了以下问题:

例如,系统无法回答 “what is the warranty period?”,因为“warranty”在图中是关系的标签,但从问题中被提取为命名实体,导致系统找不到对应的边。这表明用于构建知识图谱和抽取关键词的核心提示词仍有优化空间。

此外,一些问题需要经过轻微改写系统才能回答。这类问题通常可归因于知识图谱的构建方式或从查询中提取的关键词不准确。两者都可以通过改进提示词来修复。例如,当前图谱中存在这样一条边:phone → support_dual_sim → nano sim

这种方法仍有改进空间,但可以通过更精细地设计用于构建知识图谱的提示词来优化。正如本系列上一部分所讨论的,最初的提示词基于 ChatGPT 生成并进行了微调。在实际生产部署中,投入更多精力迭代和优化提示词至关重要。对于企业级应用,在资源充足的情况下,也可以考虑使用能力更强的大语言模型以获得更好的效果。

总体而言,结合知识图谱与 LLM 的问答系统架构前景广阔。未来,可以进一步探索将其与检索增强生成技术相结合,以综合提升答案的准确性和完整性。后续或许能通过设计更精细的提示词,并与 RAG 深度集成,来持续优化系统性能。


关注“鲸栖”小程序,掌握最新AI资讯

本文来自网络搜集,不代表鲸林向海立场,如有侵权,联系删除。转载请注明出处:https://www.itsolotime.com/archives/13509

(0)
上一篇 2025年11月13日 上午8:30
下一篇 2025年11月13日 上午11:40

相关推荐

  • 从理论到实践:使用Model Context Protocol构建多工具AI代理的完整指南

    类比 我们都熟悉《Kaun Banega Crorepati(KBC)》节目中的“Phone a Friend(打电话求助)”环节。这是印度版的《Who Wants to Be a Millionaire?》。 现在,想象一下如果 KBC 节目诞生于“电话尚未发明”的时代。 在没有电话的世界里:如果节目想让选手“打电话”求助朋友,就必须为每一位求助的朋友进行…

    2025年11月25日
    9400
  • 澳洲放羊大叔的AI编程革命:5行Bash脚本引爆硅谷,睡觉时AI自动完成5万美元项目

    最近,一个名为“Ralph”的AI编程技巧在全球技术社区迅速走红。其核心魔力在于:用户无需手动编写代码,只需设定目标,AI便能在后台自动完成整个开发流程,甚至在你睡觉时完成工作。令人惊讶的是,如此强大的工具,其核心代码仅由5行Bash脚本构成。 在Ralph迅速走红之后,Claude Code官方也推出了一套Ralph Wiggum插件。该插件通过“停止钩子…

    2026年1月23日
    6400
  • 构建本体驱动GraphRAG:从数据填埋场到零噪声知识图谱的蜕变之路

    构建一个自我演进的知识图谱,它不仅能存储数据,更能理解、校验并持续演化。 gemini 在初次构建 GraphRAG 系统时,我遵循了多数教程的路径:将文档输入大语言模型(LLM),抽取实体,将生成的 JSON 导入 Neo4j,然后宣告完成。在演示环境中,一切运行完美。直到我将它应用于真实的医疗记录。 问题随之暴露。LLM 在一份报告中抽取了“John D…

    2025年12月15日
    9500
  • Gemini 3深度评测:硬核编程的SOTA王者,为何在Web开发上“翻车”?

    📌 简短结论:强得离谱,但并非全能 综合各类基准测试与我的实际体验,可以得出结论:Gemini 3 是目前我测试过最接近“真实智能”的模型。特别是在硬核编程任务上,其表现超越了包括 GPT-5 Pro 和 Gemini 2.5 Deep Think 在内的所有竞品。 ✅ 当前处于 SOTA(最优)水平的领域: 调试复杂的编译器 Bug 无逻辑错误地重构大型代…

    2025年11月22日
    8900
  • 上海云宇星空大模型:6000亿参数重构政务AI,从“能调图”到“敢决策”的深度革命

    当大模型能调图、会统计、会写报告,政务工作流正在被重构。 当下,政务大模型的落地路径,正在分化出两条截然不同的跑道:当不少地方政府选择以“轻量化”的方式,将通用模型快速接入政务系统时,上海市规划和自然资源局给出了一条更“重”、更深的路线。 近日,由上海市规划资源局与商汤大装置联合打造的全国规划资源领域首个基础大模型“云宇星空大模型”(专业版)上线。这并非一个…

    2025年12月25日
    11000

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注