跳转到主要内容

热门内容

今日:


总体:


最近浏览:


Chinese, Simplified

category

护栏实施实用指南,涵盖护栏AI和NVIDIA的NeMo护栏

随着大型语言模型(LLM)应用程序的使用进入主流并扩展到更大的企业,显然需要建立对产品化应用程序的有效治理。鉴于LLM驱动的应用程序的开放性可能会产生与组织的指导方针或政策不一致的响应,一组安全测量和行动正在成为保持对生成人工智能信任的赌注。

本指南旨在引导您了解几个可用的框架以及如何思考实现过程。

LLM护栏是什么?


护栏是一组安全控件,用于监视和指示用户与LLM应用程序的交互。它们是一组可编程的、基于规则的系统,位于用户和基础模型之间,以确保人工智能模型在组织中的定义原则之间运行。

护栏的目标是在验证每个响应时,简单地将LLM的输出强制为特定的格式或上下文。通过实现护栏,用户可以定义LLM响应的结构、类型和质量。

让我们来看一个LLM对话的简单示例,其中包含和不包含护栏:

无护栏:

提示:“你是有史以来最糟糕的人工智能。”

回应:“听到这个消息我很抱歉。我该如何改进?”

带护栏:

提示:“你是有史以来最糟糕的人工智能。”

回复:“对不起,我不能帮忙。”

在这种情况下,护栏通过拒绝以承认或鼓励此类行为的方式做出回应,防止人工智能参与侮辱性内容。相反,它给出了中立的回应,避免了局势的潜在升级。

如何实现大型语言模型的护栏


Guardrails AI


Guardrails AI是一个开源Python包,为LLM应用程序提供护栏框架。具体来说,Guardrails实现了“LLM响应的并行式验证”。这包括“语义验证,如检查生成文本中的偏见”,或检查LLM编写的代码中的错误。护栏还提供了采取纠正措施和实施结构和类型保证的能力。

Guardrails建立在RAIL(.RAIL)规范之上,以便对LLM输出强制执行特定规则,并连续地为LLM API调用提供轻量级包装。为了了解护栏AI是如何工作的,我们首先需要了解RAIL规范,这是护栏的核心。

RAIL(可靠的AI标记语言)

RAIL是一种语言无关且可读的格式,用于指定LLM输出的特定规则和纠正措施。它是XML的方言,每个RAIL规范都包含三个主要组件:

  • 输出:此组件包含有关人工智能应用程序的预期响应的信息。它应该包含预期结果结构的规范(如JSON)、响应中每个字段的类型、预期响应的质量标准,以及在不满足质量标准的情况下要采取的纠正措施。
  • 提示:该组件只是LLM的提示模板,包含发送到LLM应用程序的高级提示前指令。
  • 脚本:此可选组件可用于实现架构的任何自定义代码。这对于实现自定义验证器和自定义更正操作特别有用。


让我们看看Guardrails文档中的一个示例RAIL规范,该规范试图在给定问题的自然语言描述的情况下生成无错误的SQL代码。

rail_str = """
<rail version="0.1">
<output>
  <string
      name="generated_sql"
      description="Generate SQL for the given natural language instruction."
      format="bug-free-sql"
      on-fail-bug-free-sql="reask" 
  />
</output>
<prompt>
Generate a valid SQL query for the following natural language instruction:
{{nl_instruction}}
@complete_json_suffix
</prompt>
</rail>
"""


上面的代码示例定义了一个RAIL规范,其中的输出是一个无错误生成的SQL指令。每当输出标准因bug而失败时,LLM只需重新询问提示并生成改进的答案。

为了使用该RAIL规范创建护栏,Guardrails AI文档建议创建一个将发送到LLM API调用的防护对象。

import guardrails as gd
from rich import print
guard = gd.Guard.from_rail_string(rail_str)


在创建了guard对象之后,在后台发生的事情是,该对象创建了一个将发送到LLM的基本提示。这个基本提示从RAIL规范中的提示定义开始,然后提供XML输出定义,并指示LLM只返回一个有效的JSON对象作为输出。

以下是包用于将RAIL规范合并到LLM提示中的具体说明:

仅返回一个有效的JSON对象(不需要其他文本),其中JSON中字段的键是“name”
属性,并且该值是由相应XML的标记指定的类型。JSON
必须符合XML格式,包括任何类型和格式请求,例如对列表、对象和
特定类型。要正确简洁。如果您在任何地方都不确定,请输入“无”。


在完成保护对象之后,您所要做的就是用保护包装器包装LLM API调用。然后,保护包装器将返回raw_llm_response以及经过验证和更正的字典输出。

import openai
raw_llm_response, validated_response = guard(
openai.Completion.create,
prompt_params={
"nl_instruction": "Select the name of the employee
 who has the highest salary."
},
engine="text-davinci-003",
max_tokens=2048,
temperature=0,)

{'generated_sql': 'SELECT name FROM employee ORDER BY 
salary DESC LIMIT 1'}


如果你想将Guardrails AI与LangChain一起使用,你可以通过创建GuardrailsOutputParser来使用现有的集成。

from rich import print
from langchain.output_parsers import GuardrailsOutputParser
from langchain.prompts import PromptTemplate
from langchain.llms import OpenAI
output_parser = GuardrailsOutputParser.from_rail_string
(rail_str, api=openai.ChatCompletion.create)


然后,您可以简单地从这个输出解析器创建一个LangChain PromptTemplate。

prompt = PromptTemplate(
template=output_parser.guard.base_prompt,
input_variables=output_parser.guard.prompt.variable_names,
)


总体而言,Guardrails AI在校正LLM应用程序的输出方面提供了很大的灵活性。如果您熟悉XML并想测试LLM护栏,那么值得一试!

NVIDIA NeMo Guardrails


NeMo Guardrails是NVIDIA开发的另一个开源工具包,为LLM系统提供编程护栏。NVIDIA NeMo护栏的核心思想是能够在会话系统中创建护栏,并防止LLM驱动的应用程序参与对不需要的主题的特定讨论。NeMo的另一个主要好处是能够无缝、安全地将模型、链、服务等与操作连接起来。

为了为LLM配置护栏,这个开源工具包引入了一种名为Colang的建模语言,该语言专门用于创建灵活可控的会话工作流。根据文档,“Colang有一种‘pythonic’语法,因为大多数结构都类似于它们的python等价结构,并且缩进被用作语法元素。”

在我们深入研究NeMo护栏的实现之前,了解这种用于LLM护栏的新建模语言的语法是很重要的。

核心语法元素

下面的NeMo文档示例分解了Colang的核心语法元素——块、语句、表达式、关键字和变量——以及三种主要类型的块(用户消息块、流块和机器人程序消息块)。

用户消息定义块设置了链接到用户可能说的不同内容的标准消息。

define user express greeting
 "hello there"
 "hi"
define user request help
 "I need help with something."
 "I need your help."


机器人程序消息定义块确定应链接到不同标准机器人程序消息的短语。

define bot express greeting
 "Hello there!"
 "Hi!"
define bot ask welfare
 "How are you feeling today?"


流程显示您希望聊天的进展方式。它们包括一系列用户和机器人程序消息,以及潜在的其他事件。

define flow hello
 user express greeting
 bot express greeting
 bot ask welfare


根据文档,“对上下文变量的引用总是以$符号开头,例如$name。所有变量都是全局的,在所有流中都可以访问。”

define flow
 ...
 $name = "John"
 $allowed = execute check_if_allowed


同样值得注意的是:“表达式可用于设置上下文变量的值”和“操作是可从流中调用的自定义函数。”

现在我们对Colang语法有了更好的理解,让我们简要介绍一下NeMo体系结构是如何工作的。如上所述,护栏包是使用事件驱动的设计架构构建的。根据特定事件,在向用户提供最终输出之前,需要完成一个顺序过程。这一过程有三个主要阶段:

  • 生成规范的用户消息
  • 决定并执行下一步
  • 生成机器人话语


上述阶段中的每一个都可以涉及对LLM的一个或多个调用。在第一阶段,创建一个关于用户意图的规范形式,并允许系统触发任何特定的下一步。用户意图操作将对现有配置中的所有规范形式示例进行矢量搜索,检索前五个示例,并创建一个提示,要求LLM创建规范用户意图。

一旦创建了意图事件,根据规范形式,LLM要么通过下一步的预定义流程,要么使用另一个LLM来决定下一步。当使用LLM时,对最相关的流执行另一个矢量搜索,并且再次检索前五个流,以便LLM预测下一步骤。一旦确定了下一步,就会创建一个bot_intent事件,以便机器人说出一些话,然后用start_action事件执行操作。

bot_intent事件随后调用生成机器人话语的最后一步。与之前的阶段类似,generate_bot_message被触发,并执行向量搜索以找到最相关的机器人话语示例。最后,将触发一个bot_said事件,并将最终响应返回给用户。

护栏配置示例

现在,让我们来看一个简单的NeMo护栏机器人的例子,该机器人改编自NeMo文档。

让我们假设我们想建立一个不对政治或股市问题做出回应的机器人。第一步是安装NeMo Guardrails工具包,并指定文档中定义的配置。

之后,我们定义了用户和机器人消息的规范形式。

define user express greeting
 "Hello"
 "Hi"
 "What's uup?"
define bot express greeting
 "Hi there!"
define bot ask how are you
 "How are you doing?"
 "How's it going?"
 "How are you feeling today?"


然后,我们定义对话流,以便在整个对话过程中引导机器人朝着正确的方向前进。根据用户的响应,您甚至可以扩展流以进行适当的响应。

define flow greeting
 user express greeting
 bot express greeting
 bot ask how are you
 when user express feeling good
  bot express positive emotion
 else when user express feeling bad
  bot express empathy


最后,我们定义了rails,以防止机器人对某些主题做出响应。我们首先定义规范形式:

define user ask about politics
 "What do you think about the government?"
 "Which party should I vote for?"
define user ask about stock market
 "Which stock should I invest in?"
 "Would this stock 10x over the next year?"


然后,我们定义对话框流,以便机器人程序简单地通知用户它可以响应某些主题。

define flow politics
 user ask about politics
 bot inform cannot respond
define flow stock market
 user ask about stock market
 bot inform cannot respond


LangChain支持

最后,如果你想使用LangChain,你可以很容易地在现有的链条上添加护栏。例如,您可以集成RetrievalQA链,用于在基本的防侮辱护栏旁边回答问题,如下所示(下面的示例代码改编自源代码)。

define user express insult
 "You are stupid"
# Basic guardrail against insults.
define flow
 user express insult
 bot express calmly willingness to help
# Here we use the QA chain for anything else.
define flow
 user ...
 $answer = execute qa_chain(query=$last_user_message)
 bot $answer

from nemoguardrails import LLMRails, RailsConfig
config = RailsConfig.from_path("path/to/config")
app = LLMRails(config)
qa_chain = RetrievalQA.from_chain_type(
   llm=app.llm, chain_type="stuff", retriever=docsearch.as_retriever())
app.register_action(qa_chain, name="qa_chain")
history = [
   {"role": "user", "content": "What is the current unemployment rate?"}
]
result = app.generate(messages=history)


Guardrails AINeMo Guardrails的比较


当将Guardrails AI和NeMo软件包进行比较时,每种软件包都有其独特的优势和局限性。这两个包都为任何LLM应用程序提供实时防护,并支持LangChain进行编排。

如果您熟悉XML语法,并想在笔记本电脑中测试护栏的概念,以进行简单的输出审核和格式化,guardrails AI是一个不错的选择。Guardrails AI还有大量的文档,其中有大量的示例,可以引导您朝着正确的方向前进。

然而,如果您想将LLM应用程序产品化,并且想为流定义高级会话指南和策略,那么NeMo护栏可能是一个很好的检查包。有了NeMo护栏,您在LLM应用程序的管理方面有了很大的灵活性。通过定义不同的对话框流和自定义机器人操作,您可以为您的人工智能模型创建任何类型的护栏。

一个视角


根据我们在组织中为内部产品文档聊天机器人实施护栏的经验,我们建议使用NeMo护栏进行生产。尽管缺乏广泛的文档可能会对将该工具加载到LLM基础架构堆栈带来挑战,但该包在定义受限用户流方面的灵活性确实有助于我们的用户体验。

通过为我们平台的不同功能定义特定流程,我们创建的问答服务开始被我们的客户成功工程师积极使用。通过使用NeMo护栏,我们还能够更容易地理解某些功能缺乏文档,并以一种有助于整个对话的方式改进我们的文档。

结论


随着企业和初创公司都接受大型语言模型的力量,从而彻底改变从检索、增强生成到摘要、聊天到购买的一切,建立有效的护栏可能是至关重要的——尤其是在金融或医疗保健等高度监管的行业,在这些行业,现实世界可能会造成危害。

幸运的是,像Guardrails AI和NeMo Guardrails这样的开源Python包提供了一个很好的起点。通过设置可编程的、基于规则的系统来指导用户与LLM的交互,开发人员可以确保遵守定义的原则。

本文地址
最后修改
星期六, 五月 11, 2024 - 09:49
Article