配置指南#

guardrails 配置包括以下内容

  • 常规选项:要使用的 LLM,常规指令(类似于系统提示),示例对话,哪些 rails 处于活动状态,特定 rails 配置选项等;这些选项通常放在 config.yml 文件中。

  • Rails:实现 rails 的 Colang flows;这些通常放在 rails 文件夹中。

  • Actions:在 Python 中实现的自定义 actions;这些通常放在配置根目录的 actions.py 模块中,或者放在 actions 子包中。

  • 知识库文档:可以在使用内置知识库支持的 RAG(检索增强生成)场景中使用的文档;这些文档通常放在 kb 文件夹中。

  • 初始化代码:执行额外初始化的自定义 Python 代码,例如注册新的 LLM 类型。

这些文件通常包含在 config 文件夹中,该文件夹在初始化 RailsConfig 实例或启动 CLI Chat 或 Server 时被引用。

.
├── config
│   ├── rails
│   │   ├── file_1.co
│   │   ├── file_2.co
│   │   └── ...
│   ├── actions.py
│   ├── config.py
│   └── config.yml

自定义 actions 可以放在配置根目录的 actions.py 模块中,或者放在 actions 子包中

.
├── config
│   ├── rails
│   │   ├── file_1.co
│   │   ├── file_2.co
│   │   └── ...
│   ├── actions
│   │   ├── file_1.py
│   │   ├── file_2.py
│   │   └── ...
│   ├── config.py
│   └── config.yml

自定义初始化#

如果存在,config.py 模块会在初始化 LLMRails 实例之前加载。

如果 config.py 模块包含 init 函数,它将在 LLMRails 实例初始化过程中被调用。例如,您可以使用 init 函数来初始化与数据库的连接,并使用 register_action_param(...) 函数将其注册为自定义 action 参数

from nemoguardrails import LLMRails

def init(app: LLMRails):
    # Initialize the database connection
    db = ...

    # Register the action parameter
    app.register_action_param("db", db)

自定义 action 参数在自定义 actions 被调用时传递给它们。

常规选项#

以下小节描述了您可以在 config.yml 文件中使用的所有配置选项。

LLM 模型#

要配置 guardrails 配置将使用的主 LLM 模型,您可以设置 models 键,如下所示

models:
  - type: main
    engine: openai
    model: gpt-3.5-turbo-instruct

属性的含义如下

  • type:设置为 “main”,表示主 LLM 模型。

  • engine:LLM 提供商,例如 openaihuggingface_endpointself_hosted 等。

  • model:模型的名称,例如 gpt-3.5-turbo-instruct

  • parameters:任何其他参数,例如 temperaturetop_k 等。

支持的 LLM 提供商#

您可以使用 LangChain 支持的任何 LLM 提供商,例如 ai21aleph_alphaanthropicanyscaleazurecoherehuggingface_endpointhuggingface_hubopenaiself_hostedself_hosted_hugging_face。查看 LangChain 官方文档以获取完整列表。

除了上述 LangChain 提供商之外,还支持使用引擎 nvidia_ai_endpoints 或同义词 nim 连接到 Nvidia NIMs,适用于 Nvidia 托管的 NIMs(可通过 Nvidia AI Enterprise 许可证访问)以及本地下载和自托管的 NIM 容器。

注意

要使用任何提供商,您必须安装额外的软件包;当您首次尝试使用包含新提供商的配置时,通常会收到来自 LangChain 的错误,指示您应该安装哪些软件包。

重要提示

虽然您可以实例化任何先前提及的 LLM 提供商,但根据模型的功能,NeMo Guardrails 工具包在使用某些提供商时效果更好。该工具包包含针对某些类型的模型(例如 openainemollm)优化的提示。对于其他模型,您可以按照 LLM Prompts 部分中的信息自行优化提示。

用于 LLM 的 NIM#

NVIDIA NIM 是一组易于使用的微服务,旨在加速生成式 AI 模型在云、数据中心和工作站中的部署。NVIDIA NIM for LLMs 将最先进的 LLM 的强大功能带入企业应用程序,提供无与伦比的自然语言处理和理解能力。了解更多关于 NIMs 的信息

NIMs 可以自托管(使用可下载的容器),也可以由 Nvidia 托管并通过 Nvidia AI Enterprise (NVAIE) 许可证访问。

NeMo Guardrails 支持按如下方式连接到 NIMs

自托管 NIMs#

要连接到自托管 NIMs,请将引擎设置为 nim。还要确保模型名称与托管 NIM 支持的模型名称之一匹配(您可以使用 GET 请求到 v1/models 端点获取支持的模型列表)。

models:
  - type: main
    engine: nim
    model: <MODEL_NAME>
    parameters:
      base_url: <NIM_ENDPOINT_URL>

例如,要连接到本地部署的 meta/llama3-8b-instruct 模型(端口 8000),请使用以下模型配置

models:
  - type: main
    engine: nim
    model: meta/llama3-8b-instruct
    parameters:
      base_url: http://127.0.0.1:8000/v1
NVIDIA AI 端点#

NVIDIA AI 端点 让用户可以轻松访问 NVIDIA 托管的 API 端点,用于 NVIDIA AI 基础模型,例如 Llama 3、Mixtral 8x7B 和 Stable Diffusion。这些模型托管在 NVIDIA API 目录 上,经过优化、测试并托管在 NVIDIA AI 平台上,使其能够快速且轻松地进行评估、进一步自定义,并在任何加速堆栈上无缝地以最佳性能运行。

要通过 NVIDIA AI 端点使用 LLM 模型,请使用以下模型配置

models:
  - type: main
    engine: nim
    model: <MODEL_NAME>

例如,要使用 llama3-8b-instruct 模型,请使用以下模型配置

models:
  - type: main
    engine: nim
    model: meta/llama3-8b-instruct

重要提示

要使用 nvidia_ai_endpointsnim LLM 提供商,您必须使用命令 pip install langchain-nvidia-ai-endpoints 安装 langchain-nvidia-ai-endpoints 包,并配置有效的 NVIDIA_API_KEY

有关更多信息,请参阅 用户指南

以下是使用 Ollamallama3 模型的示例配置

models:
  - type: main
    engine: ollama
    model: llama3
    parameters:
      base_url: http://your_base_url

NeMo LLM 服务#

除了 LangChain 支持的 LLM 提供商之外,NeMo Guardrails 还支持 NeMo LLM 服务。例如,要使用 GPT-43B-905 模型作为主 LLM,您应该使用以下配置

models:
  - type: main
    engine: nemollm
    model: gpt-43b-905

您还可以为特定任务使用自定义的 NeMo LLM 模型,例如,自检用户输入或机器人输出。例如

models:
  # ...
  - type: self_check_input
    engine: nemollm
    model: gpt-43b-002
    parameters:
      tokens_to_generate: 10
      customization_id: 6e5361fa-f878-4f00-8bc6-d7fbaaada915

当使用 NeMo LLM 模型时,您可以使用 parameters 键指定其他参数。支持的参数有

  • temperature:应该用于进行调用的温度;

  • api_host:指向 NeMo LLM 服务主机(默认为 ‘https://api.llm.ngc.nvidia.com’);

  • api_key:应该使用的 NeMo LLM 服务密钥;

  • organization_id:应该使用的 NeMo LLM 服务组织 ID;

  • tokens_to_generate:要生成的最大 token 数;

  • stop:应该使用的停止词列表;

  • customization_id:如果使用自定义,则应指定 ID。

api_hostapi_keyorganization_id 分别从环境变量 NGC_API_HOSTNGC_API_KEYNGC_ORGANIZATION_ID 自动获取。

有关更多详细信息,请参阅 NeMo LLM 服务文档,并查看 NeMo LLM 示例配置

TRT-LLM#

NeMo Guardrails 还支持连接到 TRT-LLM 服务器。

models:
  - type: main
    engine: trt_llm
    model: <MODEL_NAME>

以下是支持的参数及其默认值列表。请参阅 TRT-LLM 文档以获取更多详细信息。

models:
  - type: main
    engine: trt_llm
    model: <MODEL_NAME>
    parameters:
      server_url: <SERVER_URL>
      temperature: 1.0
      top_p: 0
      top_k: 1
      tokens: 100
      beam_width: 1
      repetition_penalty: 1.0
      length_penalty: 1.0

自定义 LLM 模型#

要注册自定义 LLM 提供商,您需要创建一个从 BaseLanguageModel 继承的类,并使用 register_llm_provider 注册它。

重要的是要实现以下方法

必需:

  • _call

  • _llm_type

可选:

  • _acall

  • _astream

  • _stream

  • _identifying_params

换句话说,要创建您的自定义 LLM 提供商,您需要实现以下接口方法:_call_llm_type,以及可选的 _acall_astream_stream_identifying_params。以下是如何操作的方法

from typing import Any, Iterator, List, Optional

from langchain.base_language import BaseLanguageModel
from langchain_core.callbacks.manager import (
    CallbackManagerForLLMRun,
    AsyncCallbackManagerForLLMRun,
)
from langchain_core.outputs import GenerationChunk

from nemoguardrails.llm.providers import register_llm_provider


class MyCustomLLM(BaseLanguageModel):

    def _call(
        self,
        prompt: str,
        stop: Optional[List[str]] = None,
        run_manager: Optional[CallbackManagerForLLMRun] = None,
        **kwargs,
    ) -> str:
        pass

    async def _acall(
        self,
        prompt: str,
        stop: Optional[List[str]] = None,
        run_manager: Optional[AsyncCallbackManagerForLLMRun] = None,
        **kwargs,
    ) -> str:
        pass

    def _stream(
        self,
        prompt: str,
        stop: Optional[List[str]] = None,
        run_manager: Optional[CallbackManagerForLLMRun] = None,
        **kwargs: Any,
    ) -> Iterator[GenerationChunk]:
        pass

    # rest of the implementation
    ...

register_llm_provider("custom_llm", MyCustomLLM)

然后,您可以在配置中使用自定义 LLM 提供商

models:
  - type: main
    engine: custom_llm

为每个任务配置 LLM#

与 LLM 的交互以面向任务的方式结构化。每次调用 LLM 都与特定任务相关联。这些任务是 guardrail 流程不可或缺的一部分,包括

  1. generate_user_intent:此任务将原始用户话语转换为规范形式。例如,“你好” 可能会转换为 express greeting

  2. generate_next_steps:此任务确定机器人的响应或要执行的操作。示例包括 bot express greetingbot respond to question

  3. generate_bot_message:此任务决定要返回的确切机器人消息。

  4. general:此任务根据用户和机器人消息的历史记录生成下一个机器人消息。当没有定义对话 rails 时(即,没有用户消息规范形式)使用它。

有关任务的完整列表,请参阅 Task type

您可以为特定任务使用不同的 LLM 模型。例如,您可以为来自不同提供商的 self_check_inputself_check_output 任务使用不同的模型。以下是示例配置

models:
  - type: main
    model: meta/llama-3.1-8b-instruct
    engine: nim
  - type: self_check_input
    model: meta/llama3-8b-instruct
    engine: nim
  - type: self_check_output
    model: meta/llama-3.1-70b-instruct
    engine: nim

在前面的示例中,self_check_inputself_check_output 任务使用不同的模型。甚至可以更细粒度,并为像 generate_user_intent 这样的任务使用不同的模型

models:
  - type: main
    model: meta/llama-3.1-8b-instruct
    engine: nim
  - type: self_check_input
    model: meta/llama3-8b-instruct
    engine: nim
  - type: self_check_output
    model: meta/llama-3.1-70b-instruct
    engine: nim
  - type: generate_user_intent
    model: meta/llama-3.1-8b-instruct
    engine: nim

提示

请记住,最适合您需求的模型将取决于您的具体要求和约束。尝试不同的模型,看看哪个模型最适合您的特定用例通常是一个好主意。

Embeddings 模型#

要配置用于 guardrails 流程中各个步骤的 embedding 模型,例如规范形式生成和下一步生成,请在 models 键中添加模型配置,如下面的配置文件所示

models:
  - ...
  - type: embeddings
    engine: FastEmbed
    model: all-MiniLM-L6-v2

FastEmbed 引擎是默认引擎,并使用 all-MiniLM-L6-v2 模型。NeMo Guardrails 还支持使用 OpenAI 模型来计算 embeddings,例如

models:
  - ...
  - type: embeddings
    engine: openai
    model: text-embedding-ada-002

支持的 Embedding 提供商#

下表列出了支持的 embedding 提供商

提供商名称

engine_name

模型

FastEmbed(默认)

FastEmbed

all-MiniLM-L6-v2(默认)等。

OpenAI

openai

text-embedding-ada-002 等。

SentenceTransformers

SentenceTransformers

all-MiniLM-L6-v2 等。

NVIDIA AI 端点

nvidia_ai_endpoints

nv-embed-v1 等。

注意

您可以为任何支持的 embedding 提供商使用任何支持的模型。上表包含一个可以使用的模型示例。

自定义 Embedding 提供商#

您还可以使用 LLMRails.register_embedding_provider 函数注册自定义 embedding 提供商。

要注册自定义 LLM 提供商,请创建一个从 EmbeddingModel 继承的类,并在您的 config.py 中注册它。

from typing import List
from nemoguardrails.embeddings.providers.base import EmbeddingModel
from nemoguardrails import LLMRails


class CustomEmbeddingModel(EmbeddingModel):
    """An implementation of a custom embedding provider."""
    engine_name = "CustomEmbeddingModel"

    def __init__(self, embedding_model: str):
        # Initialize the model
        ...

    async def encode_async(self, documents: List[str]) -> List[List[float]]:
        """Encode the provided documents into embeddings.

        Args:
            documents (List[str]): The list of documents for which embeddings should be created.

        Returns:
            List[List[float]]: The list of embeddings corresponding to the input documents.
        """
        ...

    def encode(self, documents: List[str]) -> List[List[float]]:
        """Encode the provided documents into embeddings.

        Args:
            documents (List[str]): The list of documents for which embeddings should be created.

        Returns:
            List[List[float]]: The list of embeddings corresponding to the input documents.
        """
        ...


def init(app: LLMRails):
    """Initialization function in your config.py."""
    app.register_embedding_provider(CustomEmbeddingModel, "CustomEmbeddingModel")

然后,您可以在配置中使用自定义 embedding 提供商

models:
  # ...
  - type: embeddings
    engine: SomeCustomName
    model: SomeModelName      # supported by the provider.

Embedding 搜索提供商#

NeMo Guardrails 使用 embedding 搜索(也称为向量数据库)来实现 guardrails 流程知识库 功能。默认的 embedding 搜索使用 FastEmbed 来计算 embeddings (all-MiniLM-L6-v2 模型) 和 Annoy 来执行搜索。如上一节所示,embeddings 模型同时支持 FastEmbed 和 OpenAI。SentenceTransformers 也被支持。

对于高级用例或与现有知识库的集成,您可以提供自定义 embedding 搜索提供商

常规指令#

常规指令(类似于系统提示)会附加到每个 prompt 的开头,您可以按如下所示配置它们

instructions:
  - type: general
    content: |
      Below is a conversation between the NeMo Guardrails bot and a user.
      The bot is talkative and provides lots of specific details from its context.
      If the bot does not know the answer to a question, it truthfully says it does not know.

未来将支持多种类型的指令,因此有 type 属性和数组结构。

示例对话#

示例对话设置了用户和机器人之间对话的基调。它将帮助 LLM 更好地学习对话的格式、语气以及响应应该有多详细。本节应至少包含两个轮次。由于我们将此示例对话附加到每个 prompt,因此建议保持简短且相关。

sample_conversation: |
  user "Hello there!"
    express greeting
  bot express greeting
    "Hello! How can I assist you today?"
  user "What can you do for me?"
    ask about capabilities
  bot respond about capabilities
    "As an AI assistant, I can help provide more information on NeMo Guardrails toolkit. This includes question answering on how to set it up, use it, and customize it for your application."
  user "Tell me a bit about the what the toolkit can do?"
    ask general question
  bot response for general question
    "NeMo Guardrails provides a range of options for quickly and easily adding programmable guardrails to LLM-based conversational systems. The toolkit includes examples on how you can create custom guardrails and compose them together."
  user "what kind of rails can I include?"
    request more information
  bot provide more information
    "You can include guardrails for detecting and preventing offensive language, helping the bot stay on topic, do fact checking, perform output moderation. Basically, if you want to control the output of the bot, you can do it with guardrails."
  user "thanks"
    express appreciation
  bot express appreciation and offer additional help
    "You're welcome. If you have any more questions or if there's anything else I can help you with, please don't hesitate to ask."

Actions 服务器 URL#

如果使用 actions 服务器,则必须在 config.yml 中配置 URL

actions_server_url: ACTIONS_SERVER_URL

LLM Prompts#

您可以使用 prompts 键自定义用于各种 LLM 任务(例如,生成用户意图、生成下一步、生成机器人消息)的 prompts。例如,要覆盖用于 openai/gpt-3.5-turbo 模型的 generate_user_intent 任务的 prompt

prompts:
  - task: generate_user_intent
    models:
      - openai/gpt-3.5-turbo
    max_length: 3000
    output_parser: user_intent
    content: |-
      <<This is a placeholder for a custom prompt for generating the user intent>>

对于每个任务,您还可以指定用于 LLM 调用的 prompt 的最大长度(以字符数计)。如果您想限制 LLM 使用的 token 数量,或者当您想确保 prompt 长度不超过最大上下文长度时,这非常有用。当超过最大长度时,prompt 将被截断,方法是从对话历史记录中删除较旧的轮次,直到 prompt 的长度小于或等于最大长度。默认最大长度为 16000 个字符。

NeMo Guardrails 工具包使用的任务的完整列表如下

  • general:在不使用规范形式时生成下一个机器人消息;

  • generate_user_intent:生成规范的用户消息;

  • generate_next_steps:生成机器人应该做的/说的下一件事;

  • generate_bot_message:生成下一个机器人消息;

  • generate_value:生成上下文变量的值(也称为提取用户提供的值);

  • self_check_facts:根据提供的证据检查机器人响应中的事实;

  • self_check_input:检查是否应允许来自用户的输入;

  • self_check_output:检查是否应允许机器人响应;

  • self_check_hallucination:检查机器人响应是否为幻觉。

您可以在 prompts 文件夹中查看默认 prompts。

多步生成#

对于针对指令遵循进行微调的大型语言模型 (LLM),尤其是那些超过 1000 亿参数的模型,可以启用复杂的多步 flows 的生成。

实验性:此功能是实验性的,仅应用于测试和评估目的。

enable_multi_step_generation: True

最低温度#

此温度将用于需要确定性行为的任务(例如,dolly-v2-3b 需要严格正值)。

lowest_temperature: 0.1

事件源 ID#

此 ID 将用作 Colang 运行时发出的所有事件的 source_uid。如果您需要在系统中区分多个 Colang 运行时(例如,在多代理场景中),将此设置为不同于默认值(默认值为 NeMoGuardrails-Colang-2.x)的值非常有用。

event_source_uid : colang-agent-1

自定义数据#

如果您需要将其他配置数据传递给配置的任何自定义组件,则可以使用 custom_data 字段。

custom_data:
  custom_config_field: "some_value"

例如,您可以访问 config.pyinit 函数内的自定义配置(请参阅 自定义初始化)。

def init(app: LLMRails):
    config = app.config

    # Do something with config.custom_data

Guardrails 定义#

Guardrails(或简称为 rails)通过 flows 实现。根据其作用,rails 可以分为几个主要类别

  1. 输入 rails:当收到来自用户的新输入时触发。

  2. 输出 rails:当应将新输出发送给用户时触发。

  3. 对话 rails:在解释用户消息后触发,即已识别出规范形式。

  4. 检索 rails:在执行检索步骤后触发(即,retrieve_relevant_chunks action 已完成)。

  5. 执行 rails:在 action 被调用之前和之后触发。

活动 rails 使用 config.yml 中的 rails 键进行配置。以下是一个快速示例

rails:
  # Input rails are invoked when a new message from the user is received.
  input:
    flows:
      - check jailbreak
      - check input sensitive data
      - check toxicity
      - ... # Other input rails

  # Output rails are triggered after a bot message has been generated.
  output:
    flows:
      - self check facts
      - self check hallucination
      - check output sensitive data
      - ... # Other output rails

  # Retrieval rails are invoked once `$relevant_chunks` are computed.
  retrieval:
    flows:
      - check retrieval sensitive data

所有不是输入、输出或检索 flows 的 flows 都被视为对话 rails 和执行 rails,即指示对话应如何进行以及何时以及如何调用 actions 的 flows。对话/执行 rail flows 不需要在配置中显式枚举。但是,还有一些其他配置选项可用于控制其行为。

rails:
  # Dialog rails are triggered after user message is interpreted, i.e., its canonical form
  # has been computed.
  dialog:
    # Whether to try to use a single LLM call for generating the user intent, next step and bot message.
    single_call:
      enabled: False

      # If a single call fails, whether to fall back to multiple LLM calls.
      fallback_to_multiple_calls: True

    user_messages:
      # Whether to use only the embeddings when interpreting the user's message
      embeddings_only: False

输入 Rails#

输入 rails 处理来自用户的消息。例如

define flow self check input
  $allowed = execute self_check_input

  if not $allowed
    bot refuse to respond
    stop

输入 rails 可以通过更改 $user_message 上下文变量来更改输入。

输出 Rails#

输出 rails 处理机器人消息。要处理的消息在上下文变量 $bot_message 中可用。输出 rails 可以更改 $bot_message 变量,例如,掩盖敏感信息。

您可以通过将 $skip_output_rails 上下文变量设置为 True,为下一个机器人消息暂时停用输出 rails。

检索 Rails#

检索 rails 处理检索到的 chunks,即 $relevant_chunks 变量。

对话 Rails#

对话 rails 强制执行特定的预定义对话路径。要使用对话 rails,您必须为各种用户消息定义规范形式,并使用它们来触发对话 flows。查看 Hello World 机器人以获取快速示例。有关稍微高级的示例,请查看 ABC 机器人,其中对话 rails 用于确保机器人不谈论特定主题。

对话 rails 的使用需要一个三步过程

  1. 生成规范用户消息

  2. 决定下一步并执行它们

  3. 生成机器人话语

有关详细描述,请查看 Guardrails 流程

上述每个步骤都可能需要调用 LLM。

单次调用模式#

0.6.0 版本开始,NeMo Guardrails 还支持“单次调用”模式,其中所有三个步骤都使用单次 LLM 调用执行。要启用它,您必须将 single_call.enabled 标志设置为 True,如下所示。

rails:
  dialog:
    # Whether to try to use a single LLM call for generating the user intent, next step and bot message.
    single_call:
      enabled: True

      # If a single call fails, whether to fall back to multiple LLM calls.
      fallback_to_multiple_calls: True

在典型的 RAG(检索增强生成)场景中,使用此选项可将延迟提高 3 倍,并减少 37% 的 token 使用量。

重要提示:目前,单次调用模式 只能预测作为下一步的机器人消息。这意味着如果您希望 LLM 推广并决定在动态生成的用户规范形式消息上执行 action,则它将不起作用。

仅 Embeddings#

加速对话 rails 的另一种选择是仅使用预定义用户消息的 embeddings 来决定用户输入的规范形式。要启用此选项,您必须设置 embeddings_only 标志,如下所示

rails:
  dialog:
    user_messages:
      # Whether to use only the embeddings when interpreting the user's message
      embeddings_only: True
      # Use only the embeddings when the similarity is above the specified threshold.
      embeddings_only_similarity_threshold: 0.75
      # When the fallback is set to None, if the similarity is below the threshold, the user intent is computed normally using the LLM.
      # When it is set to a string value, that string value will be used as the intent.
      embeddings_only_fallback_intent: None

重要提示:仅当提供足够示例时,才建议这样做。此处使用的阈值为 0.75,如果相似度低于此值,则会触发 LLM 调用以生成用户意图。如果遇到误报,请考虑将阈值增加到 0.8。请注意,阈值取决于模型。

异常#

NeMo Guardrails 支持从流程内部引发异常。异常是一个事件,其名称以 Exception 结尾,例如 InputRailException。当引发异常时,最终输出是一条消息,其角色设置为 exception,内容设置为关于异常的附加信息。例如

define flow input rail example
  # ...
  create event InputRailException(message="Input not allowed.")
{
  "role": "exception",
  "content": {
    "type": "InputRailException",
    "uid": "45a452fa-588e-49a5-af7a-0bab5234dcc3",
    "event_created_at": "9999-99-99999:24:30.093749+00:00",
    "source_uid": "NeMoGuardrails",
    "message": "Input not allowed."
  }
}

Guardrails 库异常#

默认情况下,Guardrails 库 中包含的所有 guardrail 在触发时都会返回预定义的消息。您可以通过在 config.yml 文件中将 enable_rails_exceptions 键设置为 True 来更改此行为

enable_rails_exceptions: True

启用此设置后,当触发 rail 时,它们将返回异常消息。为了更好地理解底层原理,以下是 self check input rail 的实现方式

define flow self check input
  $allowed = execute self_check_input
  if not $allowed
    if $config.enable_rails_exceptions
      create event InputRailException(message="Input not allowed. The input was blocked by the 'self check input' flow.")
    else
      bot refuse to respond
      stop

注意

在 Colang 2.x 中,您必须将 $config.enable_rails_exceptions 更改为 $system.config.enable_rails_exceptions,并将 create event 更改为 send

self check input rail 被触发时,将返回以下异常。

{
  "role": "exception",
  "content": {
    "type": "InputRailException",
    "uid": "45a452fa-588e-49a5-af7a-0bab5234dcc3",
    "event_created_at": "9999-99-99999:24:30.093749+00:00",
    "source_uid": "NeMoGuardrails",
    "message": "Input not allowed. The input was blocked by the 'self check input' flow."
  }
}

追踪#

NeMo Guardrails 包含一个追踪功能,允许您监控和记录交互,以实现更好的可观察性和调试。可以通过现有的 config.yml 文件轻松配置追踪。以下是在您的项目中启用和配置追踪的步骤。

启用追踪#

要启用追踪,请在 config.yml 的追踪部分下将 enabled 标志设置为 true

tracing:
  enabled: true

重要提示

您必须安装必要的依赖项才能使用追踪适配器。

  pip install "opentelemetry-api opentelemetry-sdk aiofiles"

配置追踪适配器#

追踪支持多个适配器,这些适配器决定了交互日志的导出方式和位置。您可以通过在 adapters 列表中指定一个或多个适配器来配置它们。以下是配置内置 OpenTelemetryFileSystem 适配器的示例

tracing:
  enabled: true
  adapters:
    - name: OpenTelemetry
      service_name: "nemo_guardrails_service"
      exporter: "console"  # Options: "console", "zipkin", etc.
      resource_attributes:
        env: "production"
    - name: FileSystem
      filepath: './traces/traces.jsonl'

警告

“console” 仅用于调试和演示目的,不应在生产环境中使用。使用此导出器会将追踪信息直接输出到控制台,这可能会干扰应用程序输出、扭曲用户界面、降低性能,并可能暴露敏感信息。对于生产用途,请配置合适的导出器,将追踪数据发送到专用的后端或监控系统。

OpenTelemetry 适配器#

OpenTelemetry 适配器与 OpenTelemetry 框架集成,允许您将追踪导出到各种后端。主要配置选项包括

service_name:您的服务名称。 • exporter:要使用的导出器类型(例如,console、zipkin)。 • resource_attributes:要包含在追踪资源中的其他属性(例如,environment)。

FileSystem 适配器#

FileSystem 适配器将交互日志导出到本地 JSON Lines 文件。主要配置选项包括

filepath:将存储追踪的文件路径。如果未指定,则默认为 ./.traces/trace.jsonl

配置示例#

以下是 config.yml 文件的完整示例,其中启用了 OpenTelemetryFileSystem 适配器

tracing:
  enabled: true
  adapters:
    - name: OpenTelemetry
      service_name: "nemo_guardrails_service"
      exporter: "zipkin"
      resource_attributes:
        env: "production"
    - name: FileSystem
      filepath: './traces/traces.jsonl'

要使用此配置,您必须确保 Zipkin 在本地运行或可通过网络访问。

将 Zipkin 用作导出器#

要使用 Zipkin 作为导出器,请按照以下步骤操作

  1. 安装 OpenTelemetry 的 Zipkin 导出器

    pip install opentelemetry-exporter-zipkin
    
  2. 使用 Docker 运行 Zipkin 服务器

    docker run -d -p 9411:9411 openzipkin/zipkin
    

注册 OpenTelemetry 导出器#

您还可以通过在 config.py 文件中注册其他 OpenTelemetry 导出器。为此,您需要使用 register_otel_exporter 并注册导出器类。以下是注册 Jaeger 导出器的示例

# This assumes that Jaeger exporter is installed
# pip install opentelemetry-exporter-jaeger

from opentelemetry.exporter.jaeger.thrift import JaegerExporter
from nemoguardrails.tracing.adapters.opentelemetry import register_otel_exporter

register_otel_exporter(JaegerExporter, "jaeger")

然后,您可以按如下方式在 config.yml 文件中使用它

tracing:
  enabled: true
  adapters:
    - name: OpenTelemetry
      service_name: "nemo_guardrails_service"
      exporter: "jaeger"
      resource_attributes:
        env: "production"

自定义 InteractionLogAdapters#

NeMo Guardrails 允许您通过创建自定义 InteractionLogAdapter 类来扩展其追踪功能。这种灵活性使您能够将交互日志转换为适合您需要的任何后端或格式并导出。

实现自定义适配器#

要创建自定义适配器,您需要实现 InteractionLogAdapter 抽象基类。以下是您必须遵循的接口

from abc import ABC, abstractmethod
from nemoguardrails.tracing import InteractionLog

class InteractionLogAdapter(ABC):
    name: Optional[str] = None


    @abstractmethod
    async def transform_async(self, interaction_log: InteractionLog):
        """Transforms the InteractionLog into the backend-specific format asynchronously."""
        raise NotImplementedError

    async def close(self):
        """Placeholder for any cleanup actions if needed."""
        pass

    async def __aenter__(self):
        """Enter the runtime context related to this object."""
        return self

    async def __aexit__(self, exc_type, exc_value, traceback):
        """Exit the runtime context related to this object."""
        await self.close()

注册您的自定义适配器#

实现自定义适配器后,您需要注册它,以便 NemoGuardrails 可以识别和使用它。这通过在您的 config.py: 中添加注册调用来完成

from nemoguardrails.tracing.adapters.registry import register_log_adapter
from path.to.your.adapter import YourCustomAdapter

register_log_adapter(YourCustomAdapter, "CustomLogAdapter")

示例:创建自定义适配器#

以下是一个将交互日志记录到自定义后端的自定义适配器的简单示例

from nemoguardrails.tracing.adapters.base import InteractionLogAdapter
from nemoguardrails.tracing import InteractionLog

class MyCustomLogAdapter(InteractionLogAdapter):
    name = "MyCustomLogAdapter"

    def __init__(self, custom_option1: str, custom_option2: str):
      self.custom_option1 = custom_option1
      self.custom_option2 = custom

    def transform(self, interaction_log: InteractionLog):
        # Implement your transformation logic here
        custom_format = convert_to_custom_format(interaction_log)
        send_to_custom_backend(custom_format)

    async def transform_async(self, interaction_log: InteractionLog):
        # Implement your asynchronous transformation logic here
        custom_format = convert_to_custom_format(interaction_log)
        await send_to_custom_backend_async(custom_format)

    async def close(self):
        # Implement any necessary cleanup here
        await cleanup_custom_resources()

使用您的 CustomLogAdapter 更新 config.yml

注册后,您可以像配置任何其他适配器一样在 config.yml 中配置您的自定义适配器

tracing:
  enabled: true
  adapters:
    - name: MyCustomLogAdapter
      custom_option1: "value1"
      custom_option2: "value2"

通过执行这些步骤,您可以利用内置的追踪适配器或创建和集成您自己的自定义适配器,以增强 NeMo Guardrails 驱动的应用程序的可观察性。无论您选择将日志导出到文件系统、与 OpenTelemetry 集成,还是实施定制的日志记录解决方案,追踪都提供了满足您需求的灵活性。

知识库文档#

默认情况下,LLMRails 实例支持使用一组文档作为生成机器人响应的上下文。要将文档作为知识库的一部分包含在内,您必须将它们放置在 config 文件夹内的 kb 文件夹中

.
├── config
│   └── kb
│       ├── file_1.md
│       ├── file_2.md
│       └── ...

目前,仅支持 Markdown 格式。对其他格式的支持将在不久的将来添加。