话接上文《图技术在 LLM 下的应用:知识图谱驱动的大语言模型 Llama Index》 同大家简单介绍过 LLM 和图、知识图谱相关的结合,现在我来和大家分享下最新的成果。毕竟,从 GPT-3 开始展现出超出预期的“理解能力“开始,我一直在做 Graph + LLM 技术组合、互补的研究、探索和分享,截止到现在 NebulaGraph 已经在 LlamaIndex 与 Langchain 项目做出了不少领先的贡献。

是时候,来给你展示展示我的劳动成果了。本文的主题是我们认为这个 LLM+ 领域最唾手可得、最容易摘取的果实,Text2Cypher:自然语言生成图查询。

Text2Cypher

顾名思义,Text2Cypher 做的就是把自然语言的文本转换成 Cypher 查询语句的这件事儿。和另一个大家可能已经比较熟悉的场景 Text2SQL:文本转换 SQL 在形式上没有什么区别。而本质上,大多数知识图谱、图数据库的应用都是在图上按照人类意愿进行查询,我们在图数据库上构造方便的可视化工具、封装方便的 API 的工作都是为这个目标服务的。

一直以来,阻碍图数据库、知识图谱被更广泛应用的主要因素可能就是图数据库的查询门槛了。那么,在没有大语言模型的时候,我们是怎么做的呢?

传统的 Text2Cypher

文本到查询这个领域,在大语言模型之前就一直存在这样的需求,一直是知识图谱最常见的应用之一,比如 KBQA(基于知识库的问答系统)的系统内部本质上就是 Text2Cypher。

这里以我之前写的项目 Siwi(发音:/ˈsɪwi/,一个基于篮球运动员数据集的问答应用)为例。

先来了解一下它的后端架构:

┌─────────────┬───────────────────────────────────┐
│ Speech │ Frontend │
│ ┌──────────▼──────────┐ Siwi, /ˈsɪwi/ │
│ │ Web_Speech_API │ A PoC of Dialog System │
│ │ Vue.JS │ With Graph Database │
│ │ │ Backed Knowledge Graph │
│ └──────────┬──────────┘ │
│ │ Sentence Backend │
│┌────────────┼────────────────────────────┐ │
││ ┌──────────▼──────────┐ │ │
││ │ Web API, Flask │ ./app/ │ │
││ └──────────┬──────────┘ │ │
││ │ Sentence ./bot/ │ │
││ ┌──────────▼──────────┐ │ │
││ │ Intent Matching, │ ./bot/classifier│ │
││ │ Symentic Processing │ │ │
││ └──────────┬──────────┘ │ │
││ │ Intent, Enties │ │
││ ┌──────────▼──────────┐ │ │
││ │ Intent Actor │ ./bot/actions │ │
│└─┴──────────┬──────────┴─────────────────┘ │
│ │ Graph Query │
│ ┌──────────▼──────────┐ │
│ │ Graph Database │ NebulaGraph │
│ └─────────────────────┘ │
└─────────────────────────────────────────────────┘

当一个问题语句发送过来之后,它首先要做意图识别(Intent)、实体识别(Entity),然后再利用 NLP 模型或者代码把相应的意图和实体构造成知识图谱的查询语句,最终查询图数据库,并根据返回结果构造答案。

可以想象,让程序能够:

  • 从自然语言中理解意图:对应到哪一类支持回答的问题
  • 找出实体:问题中涉及到的主要个体
  • 从意图和实体构造查询语句

这不可能是一个容易的开发工作,一个真正能够落地的实现,其训练的模型或者实现的规则代码,所需考虑的边界条件可能非常多。

三行代码搞定 Text2Cypher

而在“后大语言模型”时代,这种从前需要专门训练或者写规则的“智能”应用场景成了通用模型 + 提示工程(Prompt Engineering)就能完成的任务。

注:提示工程(prompt)是指通过自然语言描述,让生成模型、语言模型完成“智能”任务的方法。

事实上,在 GPT-3 刚发布之后,我就开始利用它帮助我写很多非常复杂的 Cypher 查询语句了,我发现它可以写很多非常复杂的模式匹配、多步条件那种之前我需要一点点调试,半天才能写出来的语句。通常在它的答案之上,我只需要稍微修改就可以了,而且往往我还能从它的答案里知道我之前没了解到的 Cypher 语法盲区。

后来,在今年二月份的时候,我就试着实现了一个基于 GPT-3 (因为那时候还没有 GPT-3.5)的项目:ngql-GPT代码仓库)。

图 1:Demo 图

它的工作原理非常简单,和 Text2SQL 没有区别。大语言模型已经通过公共领域学习了 Cypher 的语法表达,我们在提出任务的时候,只需要让 LLM 知道我们要查询的图的 Schema 作为上下文就可以了。

所以,基本上 prompt 就是:

你是一位 NebulaGraph Cypher 专家,请根据给定的图 Schema 和问题,写出查询语句。
schema 如下:
---
{schema}
---
问题如下:
---
{question}
---
下面写出查询语句:

然而,真实世界的 prompt 往往还需要增加额外的要求:

  • 只返回语句,不用给出解释,不用道歉
  • 强调不要写超出 schema 之外的点、边类型

感兴趣的同学,可以参考我在 LlamaIndex 的 KnowlegeGraph Query Engine 中的实现

在真实场景中,我们想快速学习、构建大语言模型应用的时候,常常会用到 LangChain 或者 LlamaIndex 这样的编排(Orchestrator)工具,它们可以帮我们做很多合理的抽象,从而避免从头去实现很多通用的脚手架代码:

  • 和不同语言模型交互
  • 和不同向量数据库交互
  • 数据分割

而且,这些编排工具还内置了很多工程方法的最佳实践。这样,我们常常调用一个方法就可以用到最新、最好用的大语言模型研究论文的方法了,比如 FLAREGuidence

为此,我在 LlamaIndex 和 LangChain 中都贡献了可以方便进行 NebulaGraph 上 Text2Cypher 的工具,真正做到 3 行代码,Text2Cypher。

NebulaGraph 上的 Text2Cypher

在 LlamaIndex 的 KnowledgeQueryEngine 和 LangChain 的 NebulaGraphQAChain 中:NebulaGraph 图数据库的 Schema 获取、Cypher 语句生成的 prompt、各种 LLM 的调用、结果的处理、衔接,我们可以全都不用关心,开箱即用!

使用 LlamaIndex

用 LlamaIndex,我们只需要:

  • 创建一个 NebulaGraphStore 实例
  • 创建一个 KnowledgeQueryEngine

就可以直接进行问答了,是不是超级简单?具体的过程,可以参考文档:https://gpt-index.readthedocs.io/en/latest/examples/query_engine/knowledge_graph_query_engine.html

from llama_index.query_engine import KnowledgeGraphQueryEngine
from llama_index.storage.storage_context import StorageContext
from llama_index.graph_stores import NebulaGraphStore graph_store = NebulaGraphStore(
space_name=space_name, edge_types=edge_types, rel_prop_names=rel_prop_names, tags=tags)
storage_context = StorageContext.from_defaults(graph_store=graph_store) nl2kg_query_engine = KnowledgeGraphQueryEngine(
storage_context=storage_context,
service_context=service_context,
llm=llm,
verbose=True,
)
# 问答
response = nl2kg_query_engine.query(
"Tell me about Peter Quill?",
)
# 只生成语句
graph_query = nl2kg_query_engine.generate_query(
"Tell me about Peter Quill?",
)

使用 LangChain

类似的,在 Langchain 里,我们只需要:

  • 创建一个 NebulaGraph实例
  • 创建一个 NebulaGraphQAChain 实例

就可以直接提问了。还是一样,具体过程参考文档:https://python.langchain.com/docs/modules/chains/additional/graph_nebula_qa

from langchain.chat_models import ChatOpenAI
from langchain.chains import NebulaGraphQAChain
from langchain.graphs import NebulaGraph graph = NebulaGraph(
space=space_name,
username="root",
password="nebula",
address="127.0.0.1",
port=9669,
session_pool_size=30,
) chain = NebulaGraphQAChain.from_llm(
llm, graph=graph, verbose=True
) chain.run(
"Tell me about Peter Quill?",
)

Demo

如果你对 Text2Cypher 感兴趣,可以去 Demo 地址:https://www.siwei.io/demos/text2cypher/ 体验下。

这个 Demo 展示了如何利用 LLM 从不同类型的信息源(以维基百科为例)中抽取知识三元组,并存储到图数据库 NebulaGraph 中。

本 Demo 中,我们先抽取了维基百科中关于《银河护卫队3》的信息,再利用 LLM 生成的知识三元组,构建了一个图谱。跟着,利用 Cypher 查询图谱,最后利用 LlamaIndex 和 LangChain 中的 Text2Cypher,实现了自然语言查询图谱的功能。

当然,你可以点击其他标签亲自试玩图谱的可视化、Cypher 查询、自然语言查询(Text2Cypher)等功能。

这里可以下载 完整的 Jupyter Notebook。

结论

有了 LLM,知识图谱、NebulaGraph 图数据库中的的数据中进行 Text2Cypher 从来没有这么简单过。

一个具有更强人机、机器接入的知识图谱可以代表了全新的时代,我们可能不需要从前那样高额成本去实现图库之上的后端服务,也不再需要培训才能让领域专家从图中获取重要的洞察了。

利用 LlamaIndex 或者 LangChain 中的生态集成,我们可以几乎没有开发成本地几行代码把自己的应用、图数据智能化。

然而,Text2Cypher 只是一个开始,请大家关注我们后续的文章,展现更多知识图谱、图数据库为大语言模型生态带来的变革。

相关阅读

Text2Cypher:大语言模型驱动的图查询生成的更多相关文章

  1. PowerDesigner(八)-面向对象模型(用例图,序列图,类图,生成Java源代码及Java源代码生成类图)(转)

    面向对象模型 面向对象模型是利用UML(统一建模语言)的图形来描述系统结构的模型,它从不同角度实现系统的工作状态.这些图形有助于用户,管理人员,系统分析人员,开发人员,测试人员和其他人员之间进行信息交 ...

  2. 八、面向对象模型(用例图,序列图,类图,生成Java源代码及Java源代码生成类图)

    面向对象模型 面向对象模型是利用UML(统一建模语言)的图形来描述系统结构的模型,它从不同角度实现系统的工作状态.这些图形有助于用户,管理人员,系统分析人员,开发人员,测试人员和其他人员之间进行信息交 ...

  3. 大数据江湖之即席查询与分析(下篇)--手把手教你搭建即席查询与分析Demo

    上篇小弟分享了几个“即席查询与分析”的典型案例,引起了不少共鸣,好多小伙伴迫不及待地追问我们:说好的“手把手教你搭建即席查询与分析Demo”啥时候能出?说到就得做到,差啥不能差人品,本篇只分享技术干货 ...

  4. GAIA-IR: GraphScope 上的并行化图查询引擎

    在本文中,我们将介绍 GraphScope 图交互式查询引擎 GAIA-IR,它支持高效的 Gremlin 语言表达的交互图查询,同时高度抽象了图上的查询计算,具有高可扩展性. 背景介绍 在海量数据的 ...

  5. java环境中基于jvm的两大语言:scala,groovy

    一.java环境中基于jvm的两大语言:scala,groovy 可以在java项目里混编这两种语言: scala:静态语言,多范式语言,糅合了面向对象.面向过程:可以与java和net互操作:融汇了 ...

  6. Python 爬取 热词并进行分类数据分析-[热词关系图+报告生成]

    日期:2020.02.05 博客期:144 星期三 [本博客的代码如若要使用,请在下方评论区留言,之后再用(就是跟我说一声)] 所有相关跳转: a.[简单准备] b.[云图制作+数据导入] c.[拓扑 ...

  7. CSS雪碧图自动生成软件

    下载地址 http://www.99css.com/1524/ 包含详细的下载地址.下载步骤以及使用教程 亮点:自动合成雪碧图+自动生成雪碧图background-position代码 简单过程 下载 ...

  8. CSS实现大数据热点波纹图

    CSS实现大数据热点波纹图 实现效果: 涉及知识点: 定位 盒子阴影 动画 思想:以3道波纹为例.首先使用一个div盒子作为圆心,然后每道波纹作为一个div.4个盒子均使用定位属性定位到圆心.然后设置 ...

  9. excel制作折线图太麻烦?试试这些折线图在线生成工具

    折线图是以折线的上升或下降来表示统计数量的增减变化的统计图,叫作折线统计图.用折线的起伏表示数据的增减变化情况,不仅可以表示数量的多少,而且可以反映数据的增减变化情况.并且折线图也是目前最方便的一种统 ...

  10. angr原理与实践(二)—— 各类图的生成(CFG CG ACFG DDG等)

    ​  本文系原创,转载请说明出处 Please Subscribe Wechat Official Account:信安科研人,获取更多的原创安全资讯 上一篇文章介绍了angr的原理,自此篇文章开始, ...

随机推荐

  1. 《最新出炉》系列初窥篇-Python+Playwright自动化测试-2-playwright的API及其他知识

    1.简介 上一篇宏哥已经将Python+Playwright的环境搭建好了,而且也简单的演示了一下三款浏览器的启动和关闭,是不是很简单啊.今天主要是把一篇的中的代码进行一次详细的注释,然后说一下pla ...

  2. 一次 HPC 病毒感染与解决经历

    周一的时候,有同事反馈说,HPC 的项目报告路径正在不断产生 *.exe 和 *.pif 文件,怀疑是不是被病毒感染! 收到信息,第一时间进去目录,的确发现该目录每个几秒钟就自动生成一个 *.exe ...

  3. Linux下程序时间消耗监控与统计

    良好的计时器可帮助程序开发人员确定程序的性能瓶颈,或对不同算法进行性能比较.但要精确测量程序的运行时间并不容易,因为进程切换.中断.共享的多用户.网络流量.高速缓存访问及转移预测等因素都会对程序计时产 ...

  4. flutter 的 in_app_web_view实现下载功能

    flutter与前端交互,利用in_app_web_view实现下载功能: 首先下载库,终端输入 flutter pub add flutter_inappwebview 之后导出 import 'p ...

  5. Python异步编程之web框架 异步vs同步 数据库IO任务压测对比

    测试基本信息 主题:比较异步框架和同步框架在数据库IO操作的性能差异 python版本:python 3.8 数据库:mysql 8.0.27 (docker部署) 压测工具:locust web框架 ...

  6. 【QCustomPlot】配置帮助文档

    说明 使用 QCustomPlot 绘图库辅助开发时整理的学习笔记.同系列文章目录可见 <绘图库 QCustomPlot 学习笔记>目录.本篇介绍 QCustomPlot 帮助文档的配置. ...

  7. 使用Docker将Vite Vue项目部署到Nginx二级目录

    Vue项目配置 使用Vite创建一个Vue项目,点我查看如何创建 配置打包路径 在Nginx中如果是二级目录,例如/web时,需要设置线上的打包路径 在项目跟路径下创建两个文件:.env.produc ...

  8. 带你彻底掌握Bean的生命周期

    摘要:我们将深入研究Spring Framework的核心部分--Spring Bean的生命周期. 本文分享自华为云社区<Spring高手之路5--彻底掌握Bean的生命周期>,作者: ...

  9. 尚医通day16-网站怎么接入微信扫码支付?

    第01章-准备工作 1.微信支付产品介绍 参考资料:产品中心 - 微信支付商户平台 (qq.com) 付款码支付.JSAPI支付.小程序支付.Native支付.APP支付.刷脸支付 1.1.付款码支付 ...

  10. 「学习笔记」vector

    本文并不是 vector 的入门教程. 定义 std::vector 是封装动态数组的顺序容器. vector 通常占用多于静态数组的空间,因为要分配更多内存以管理将来的增长.如果元素数量已知,可以使 ...