符号推理:Drools规则引擎 + LangChain4j大模型演示


混合推理,也称为神经符号人工智能,是一种将机器学习和符号推理相结合的人工智能,旨在实现互补,弥补前者的不足,如可靠性、可重复性和透明度的不足。

该项目的主要思想是通过简单但引人注目的例子展示混合推理,特别是如何将 LLM 与规则引擎相结合,允许在不同的业务领域中实现聊天机器人,这些聊天机器人既方便用户使用,又能够以严格的方式应用该特定领域的业务规则,而不会产生任何幻觉。

如果没有控制,力量就毫无意义

如今,使用 ChatGPT 等 LLM 系统可以做的事情简直令人难以置信。我必须承认,我无法停止惊讶,有时甚至会从座位上跳起来想:“我没想到人工智能也能做到这一点!”。这里有点误导的是,我们现在所说的和倾向于认同的人工智能实际上是深度学习,它只是所有可用人工智能技术的一个子集。

换句话说,深度学习只是整个 AI 故事的一小部分。此外,在很多情况下,你最不希望的是感到惊讶。当你的银行拒绝向你发放抵押贷款时,你不会想跳起来,因为你没有任何人类可以理解或可追踪的理由,而只是因为 LLM 说不。甚至银行也可能只愿意向那些在其严格、明确且无可置疑的业务规则下被视为可行的申请人发放抵押贷款。

本质上,训练有素的深度学习模型所提供的能力和灵活性几乎是无限的,但正如许多学术论文所讨论的那样,鉴于其统计性质,它们并不完全可靠,并且幻觉等重大缺陷是不可避免的。

实际上,至少在应用程序的某些部分,您经常需要的是更受限制且绝对可预测的控制,以使其与您的业务领域保持一致并完美地遵守其规则。

结合 LLM 灵活性和规则引擎可预测性
鉴于这些前提,为什么不将深度学习和符号推理等两个非常不同且互补的 AI 分支混合在一起呢?继续以抵押贷款为例,这将使我们有机会实施一款应用程序,该应用程序具有银行严格的业务规则所要求的企业严谨性,但可以以最人性化的方式进行查询。

该项目的目标是展示Quarkus如何在其DroolsLangChain4j 扩展的帮助下轻松集成这两种技术并将它们结合起来实现这个抵押贷款示例和其他有趣的用例。

安装并集成本地 LLM 引擎
LangChain4j 在底层 LLM 之上提供了一个抽象,因此您可以在不同的实现之间切换,例如集成 ChatGPT,而只需进行很少的配置更改。为了拥有一个独立的应用程序,不依赖于任何外部服务,当前配置在本地运行的InstructLab服务器上使用。

InstructLab API 与 OpenAI 的 API 完全兼容,因此要集成它,您可以使用扩展quarkus-langchain4j-openai并在 Quarkusapplication.properties文件中对其进行配置,如下所示:

# Configure openai server to use Merlinite 7B model
quarkus.langchain4j.openai.chat-model.model-name=models/merlinite-7b-lab-Q4_K_M.gguf
# Choose a low temperature to minimize hallucination
quarkus.langchain4j.openai.chat-model.temperature=0
# Set timeout to 3 minutes (local LLM can be quite slow)
quarkus.langchain4j.openai.timeout=180s
# Enable logging of both requests and responses
quarkus.langchain4j.openai.log-requests=true
quarkus.langchain4j.openai.log-responses=true


抵押贷款示例
正如预期的那样,这个第一个也是最简单的例子结合了 Drools 和 LLM,目的是让我们的用户以最顺畅和最不结构化的方式与银行聊天机器人进行交互,但在做出有关授予抵押贷款的决定时仍然应用银行冷冰冰、不灵活的业务规则。

实际上,实施的规则要求非常基本,只要有足够的收入,当然还要成年,所以当我们输入类似

马里奥是弗斯科家的长子,出生于 1974 年 3 月 18 日。现在他是一名软件工程师,年薪 25 万美元。

聊天机器人温柔地回答

可以,马里奥-弗斯科可以获得抵押贷款

了解这里幕后发生的事情很有趣。

该应用程序通过 langchain4j 集成,要求 LLM 从输入消息中提取抵押贷款申请人的相关数据。

{"model":"mistral","prompt":"Extract information about a person from {\"message\":\"Mario the firstborn of the Fusco family is born the 18th day of March 1974 Nowadays he works as software engineer and earns a quarter million a year\"}. When income is null, it is set to 0. The response must contain only the JSON with person's data and without any other sentence.\nYou must answer strictly in the following JSON format: {\n\"firstName\": (type: string),\n\"lastName\": (type: string),\n\"birthDate\": (type: date string (2023-12-31)),\n\"income\": (type: integer),\n}","options":{"temperature":0.1,"num_predict":128,"top_p":0.9,"top_k":40},"stream":false}

根据请求,LLM 回复了包含这些数据的 JSON

{"firstName": "Mario", "lastName": "Fusco", "birthDate": "1974-03-18", "income": 250000}

这些内容会被 LangChain4j 自动转换为类的实例Person。此时,可以直接将此Person对象插入 Drools 会话,并让其根据该会话评估银行业务规则。

该解决方案的另一个好处(在类似情况下也很可能要求)是规则引擎是一种完全透明且可追踪的人工智能形式,因此如果你写了类似这样的内容:

马里奥-弗斯科的女儿索菲亚出生于 2011 年 9 月 26 日。她是一个非常聪明的学生。

系统不仅正确地拒绝授予抵押贷款,而且还解释了拒绝的原因。

不能向索菲亚-弗斯科发放抵押贷款,因为[索菲亚-弗斯科太小,索菲亚-弗斯科的收入太低]。

密码生成器示例
生成一个强大但容易记住的密码是一项非常常见的任务,我们在浏览互联网时不时会被要求执行这项任务,那么为什么不利用 LLM 的创造力来完成这项任务呢?

实际上,在这种情况下,我们不需要完全可靠的 LLM。相反,如果它能比平时更有创意,那就更重要了。为此,我们可以提高 LLM 温度,这是一个影响语言模型输出的参数,决定输出是更随机、更有创意还是更可预测。温度越高,概率就越低,即输出越有创意。

由于 Quarkus 集成,这可以轻松实现定义 a second and hotter LLM model并配置密码生成器configuring the password generator to use it来 使用它。

通过这种方式,我们可以例如要求 LLM 生成一个与 相关的随机单词,football然后它可以回复goalkeeper。

不幸的是,我们几乎从来不被允许使用这么简单的单词作为密码。实际上,密码应该遵循一些简单的规则,例如具有一定的长度,并且至少包含一个大写字母、一个数字、一个符号和一个在满月之夜被杀死的黑面包师的血液。

有了这些前提,自然就可以用 Drools 对这些规则进行编码,让规则引擎为您应用这些规则,将 LLM 最初建议的单词转化为更安全的 G0alk&&p。

航空公司聊天机器人示例
在这个例子中,业务规则很简单:每延误一分钟,客户可获得 2 美元的退款(如果航班延误至少一小时),如果是老年客户(年龄超过 65 岁),则可以获得 10% 的退款。

然而,规则引擎不仅用于计算最终退款金额,还用于定义另一组实现状态机的规则。该状态机的目的是引导我们的聊天机器人完成数据采集的不同阶段,为当前阶段选择正确的数据提取器。从本质上讲,我们的聊天机器人的架构可以用这种方式直观地总结出来。