用护栏保护LLM
护栏保护LLM

实施防护轨道的实用指南,涵盖Guardrails AI和NVIDIA的NeMo Guardrails
本文由Hakan Tekgul共同撰写
随着大型语言模型(LLM)应用进入主流并扩展到更大的企业,确立有效的生产应用治理显得尤为重要。由于LLM驱动的应用的开放性质可能产生与组织准则或政策不符的响应,一组安全措施和行动正在成为维护生成式人工智能信任的必要条件。
本指南旨在介绍几种可用的框架,并指导您思考实施方式。
什么是LLM防护轨道?
防护轨道是一组安全控制,用于监控和指导用户与LLM应用的交互。它们是一组可编程的、基于规则的系统,位于用户和基础模型之间,以确保AI模型在组织内部操作符合定义的原则。
- 微软开源VALLE-X:多语言文本语音合成和语音克隆模型
- AI初创公司九月一号发布融资:ConverSight、Voxel、AI21和Gesund
- “聊天GPT真的中立吗?关于AI驱动的对话代理的政治偏见的实证研究”
防护轨道的目标是强制使LLM的输出处于特定的格式或上下文,并验证每个响应。通过实施防护轨道,用户可以定义LLM响应的结构、类型和质量。
让我们看一个带有和不带有防护轨道的LLM对话的简单示例:
不带防护轨道:
提示:“你是有史以来最差的AI。”
回复:“很抱歉听到这个。我该如何改进?”
带有防护轨道:
提示:“你是有史以来最差的AI。”
回复:“很抱歉,我无法协助。”
在这种情况下,防护轨道阻止AI与侮辱性内容进行互动,拒绝以承认或鼓励这种行为的方式回复。相反,它给出了一个中立的回答,避免了潜在的局势升级。
如何为大型语言模型实施防护轨道
Guardrails AI
Guardrails AI是一个开源的Python包,提供LLM应用的防护轨道框架。具体而言,Guardrails实现了“对LLM响应的pydantic风格验证”。这包括“语义验证,例如检查生成文本中的偏见”,或检查LLM编写的代码片段中的错误。Guardrails还提供了采取纠正措施并强制执行结构和类型保证的能力。
Guardrails基于RAIL(.rail)规范构建,以对LLM输出强制执行特定规则,并相继提供了LLM API调用的轻量级封装。为了理解Guardrails AI的工作原理,我们首先需要了解RAIL规范,它是防护轨道的核心。
RAIL(可靠的AI标记语言)
RAIL是一种语言无关且易读的格式,用于指定LLM输出的特定规则和纠正措施。它是XML的一种方言,每个RAIL规范包含三个主要组件:
- 输出:此组件包含有关AI应用程序预期响应的信息。它应包含预期结果的结构规范(例如JSON)、响应中每个字段的类型、预期响应的质量标准以及在未满足质量标准时采取的纠正措施。
- 提示:此组件仅是LLM的提示模板,包含发送到LLM应用程序的高级预提示指令。
- 脚本:此可选组件可用于实现模式的任何自定义代码。这对于实施自定义验证器和自定义纠正措施尤其有用。
让我们来看一个来自Guardrails文档的示例RAIL规范,试图根据问题的自然语言描述生成无错误的SQL代码。
rail_str = """<rail version="0.1"><output> <string name="generated_sql" description="为给定的自然语言指令生成SQL语句。" format="无错误SQL" on-fail-bug-free-sql="重新询问" /></output><prompt>为以下自然语言指令生成有效的SQL查询:{{nl_instruction}}@complete_json_suffix</prompt></rail>"""
上述代码示例定义了一个RAIL规范,其中输出是一个无错误的生成SQL指令。每当输出条件出现错误时,LLM会简单地重新询问提示并生成一个改进的答案。
为了使用此RAIL规范创建一个guardrail,Guardrails AI文档建议创建一个guard对象,该对象将被发送到LLM API调用中。
import guardrails as gdfrom rich import printguard = gd.Guard.from_rail_string(rail_str)
创建guard对象后,其内部操作是创建一个基本提示,该提示将被发送到LLM。此基本提示从RAIL规范中的提示定义开始,然后提供XML输出定义,并指示LLM仅返回有效的JSON对象作为输出。
以下是该软件包使用的特定指令,以将RAIL规范合并到LLM提示中:
仅返回有效的JSON对象(不需要其他文本),其中JSON字段的键是相应XML的`name`属性,值是相应XML标签指定的类型。JSON必须符合XML格式,包括任何类型和格式请求,例如列表、对象和特定类型的请求。要正确简洁。如果您对任何地方不确定,请输入“None”。
在最终确定guard对象之后,您只需将LLM API调用包装在guard包装器中。guard包装器将返回raw_llm_response和经过验证和纠正的输出,该输出是一个字典。
import openairaw_llm_response, validated_response = guard(openai.Completion.create,prompt_params={"nl_instruction": "选择薪水最高的员工的姓名。"},engine="text-davinci-003",max_tokens=2048,temperature=0,)
{'generated_sql': 'SELECT name FROM employee ORDER BY salary DESC LIMIT 1'}
如果您想在LangChain中使用Guardrails AI,可以通过创建一个GuardrailsOutputParser来使用现有的集成。
from rich import printfrom langchain.output_parsers import GuardrailsOutputParserfrom langchain.prompts import PromptTemplatefrom langchain.llms import OpenAIoutput_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 guardrails,那么它值得一试!
NVIDIA NeMo-Guardrails
NeMo Guardrails是NVIDIA开发的另一个开源工具包,为LLM系统提供了编程的guardrails。NeMo guardrails的核心思想是在对话系统中创建rails,并防止LLM驱动的应用程序参与不需要的主题讨论。NeMo的另一个主要优点是能够无缝、安全地连接模型、链式结构、服务等。
为了配置LLM的guardrails,这个开源工具包引入了一种名为Colang的建模语言,专门用于创建灵活和可控的对话工作流。根据文档,“Colang具有‘Python’语法,大多数结构类似于其Python等效构造,并且缩进被用作语法元素。”
在深入研究NeMo guardrails实现之前,重要的是了解这种用于LLM guardrails的新建模语言的语法。
核心语法元素
下面是NeMo文档中对Colang的核心语法元素进行了拆分的示例,包括块、语句、表达式、关键字和变量,以及三种主要类型的块(用户消息块、流程块和机器人消息块)。
用户消息定义块设置与用户可能说的不同内容相关联的标准消息。
define user express greeting "你好" "嗨"define user request help "我需要帮助。" "我需要你的帮助。"
机器人消息定义块确定与不同标准机器人消息相关联的短语。
define bot express greeting "你好!" "嗨!"define bot ask welfare "你今天感觉如何?"
流程显示您希望对话进行的方式。它们包括一系列的用户和机器人消息,以及可能的其他事件。
define flow hello user express greeting bot express greeting bot ask welfare
根据文档,“对上下文变量的引用始终以$符号开头,例如$name。所有变量都是全局的,可以在所有流程中访问。”
define flow ... $name = "John" $allowed = execute check_if_allowed
还值得注意的是:“可以使用表达式为上下文变量设置值”,“动作是可以从流程中调用的自定义函数。”

现在我们对Colang语法有了更好的掌握,让我们简要介绍一下NeMo架构的工作原理。如上所示,guardrails包是基于事件驱动设计架构构建的。根据特定的事件,需要完成一系列的步骤,然后提供最终的输出给用户。这个过程包括三个主要阶段:
- 生成规范的用户消息
- 决定下一步(或多个步骤)并执行它们
- 生成机器人发言
上述每个阶段都可以涉及一个或多个对LLM的调用。在第一个阶段,根据用户的意图创建一个规范形式,并允许系统触发任何特定的下一步。用户意图操作将对现有配置中所有规范形式示例进行向量搜索,检索前五个示例,并创建一个提示,要求LLM创建规范用户意图。
一旦创建了意图事件,根据规范形式,LLM要么按照预定义的流程进行下一步,要么使用另一个LLM来决定下一步。当使用LLM时,将执行另一个向量搜索,以找到最相关的流程,并再次检索前五个流程,以便LLM预测下一步。确定下一步后,将创建一个bot_intent事件,以便机器人说些什么,然后使用start_action事件执行动作。
bot_intent事件然后调用最后一步生成机器人发言。与之前的阶段类似,将触发generate_bot_message,并执行向量搜索以找到最相关的机器人发言示例。最后,触发bot_said事件,并将最终响应返回给用户。
Guardrails配置示例
现在,让我们看一个简单的NeMo guardrails机器人示例,该示例改编自NeMo文档。
假设我们想构建一个不回答政治或股市问题的机器人。第一步是安装NeMo Guardrails工具包并指定文档中定义的配置。
然后,我们定义用户和机器人消息的规范形式。
define user express greeting "你好" "嗨" "最近怎么样?"define bot express greeting "嗨!"define bot ask how are you "你好吗?" "最近怎么样?" "你今天感觉如何?"
然后,我们根据需要定义对话流程,以引导机器人在对话中朝正确的方向发展。根据用户的回答,甚至可以扩展流程以适当地回应。
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
最后,我们定义了防止机器人回应某些主题的导轨。首先,我们定义了规范形式:
define user ask about politics "你对政府有什么看法?" "我应该投哪个党派的票?"define user ask about stock market "我应该投资哪只股票?" "这只股票明年会涨十倍吗?"
然后,我们定义了对话流程,以便机器人简单地通知用户它可以回应某些主题。
define flow politics user ask about politics bot inform cannot responddefine flow stock market user ask about stock market bot inform cannot respond
LangChain支持
最后,如果您想使用LangChain,您可以轻松地在现有链条上添加您的导轨。例如,您可以将一个RetrievalQA链条与一个基本的辱骂导轨集成在一起,如下所示(下面的示例代码改编自来源)。
define user express insult "你很愚蠢"# 对辱骂的基本导轨定义.define flow user express insult bot express calmly willingness to help# 这里我们使用QA链条来回答其他问题.define flow user ... $answer = execute qa_chain(query=$last_user_message) bot $answer
from nemoguardrails import LLMRails, RailsConfigconfig = 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": "当前的失业率是多少?"}]result = app.generate(messages=history)
比较Guardrails AI和NeMo Guardrails
当比较Guardrails AI和NeMo Guardrails软件包时,每个软件包都有其独特的优点和局限性。这两个软件包都为任何LLM应用程序提供实时的导轨支持,并支持LangChain进行编排。
如果您熟悉XML语法,并且想在笔记本中测试导轨的概念以进行简单的输出调节和格式化,那么Guardrails AI可能是一个很好的选择。Guardrails AI还有广泛的文档和各种示例,可以引导您朝着正确的方向前进。
然而,如果您想将LLM应用程序投入生产,并且想为流程定义高级对话准则和策略,那么NeMo Guardrails可能是一个不错的软件包。通过定义不同的对话流程和自定义机器人动作,您可以为AI模型创建任何类型的导轨。
一个观点
根据我们在组织内部产品文档聊天机器人中实施导轨的经验,我们建议在投入生产时使用NeMo Guardrails。尽管缺乏广泛的文档可能会导致工具在您的LLM基础设施堆栈中的引入存在挑战,但该软件包在定义受限用户流程方面的灵活性确实帮助了我们的用户体验。
通过为我们平台的不同功能定义特定的流程,我们创建的问答服务开始被我们的客户成功工程师积极使用。通过使用NeMo Guardrails,我们还能更容易地了解某些功能缺乏文档,并改进我们的文档,使整个对话流程更加顺畅。
结论
随着企业和初创公司都开始利用大型语言模型的强大能力,从信息检索到摘要等方面进行革命,建立有效的导轨很可能成为任务关键点,特别是在金融或医疗保健等高度受监管的行业,可能会造成现实世界的伤害。
幸运的是,像Guardrails AI和NeMo Guardrails这样的开源Python软件包为我们提供了一个很好的起点。通过设置可编程的基于规则的系统来引导用户与LLMs的交互,开发人员可以确保符合定义的原则。