Prompt Customization#

注意:本文档适用于希望扩展/改进对不同 LLM 引擎支持的开发人员。

Task-oriented Prompting#

与 LLM 的交互以面向任务的方式设计,即每次调用 LLM 时,它都必须执行特定的任务。最重要的任务是 guardrails 流程 的一部分,包括

  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 以获取完整的任务列表。

Prompt Configuration#

该工具包为每个任务和某些 LLM 模型提供了预定义的提示。它们位于 nemoguardrails/llm/prompts 文件夹中。您可以通过在 guardrails 配置中包含 prompts.yml 文件来进一步自定义提示(从技术上讲,文件名不是必需的,您也可以在通用的 config.yml 文件中包含 prompts 键)。

此外,如果设置了环境变量 PROMPTS_DIR,则工具包还将加载指定目录中定义的任何提示。加载在 python 模块加载时执行一次。该文件夹必须包含一个或多个 .yml 文件,其中包含提示定义(在 prompts 键内)。

要覆盖特定模型的提示,您需要指定 models

prompts:
  - task: general
    models:
      - databricks/dolly-v2-3b
    content: |-
      ...

  - task: generate_user_intent
    models:
      - databricks/dolly-v2-3b
    content: |-
      ...

  - ...

您可以将特定任务的提示与多个 LLM 模型关联

prompts:
  - task: generate_user_intent
    models:
      - openai/gpt-3.5-turbo
      - openai/gpt-4

...

要覆盖任何其他自定义用途的提示,您可以指定 mode 键。如果使用相同的 prompting_mode 运行相应的任务配置,则将使用自定义提示。

作为示例,让我们考虑压缩的情况。某些应用程序可能需要简洁的提示,例如为了避免处理长上下文,并降低延迟,但可能会因上下文较小而略微降低性能。为此,您可能希望为同一任务和同一模型提供多个版本的提示。这可以通过以下方式实现

任务配置

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

prompting_mode: "compact"  # Default value is "standard"

提示配置

prompts:
  - task: generate_user_intent
    models:
      - openai/gpt-3.5-turbo
      - openai/gpt-4
    content: |-
      Default prompt tailored for high accuracy with the given models for example by adding the fill {{ history }}

  - task: generate_user_intent
    models:
      - openai/gpt-3.5-turbo
      - openai/gpt-4
    content: |-
      Smaller prompt tailored for high accuracy by reducing number of few shot examples or other means
    mode: compact
...

对于给定的任务和模型,您可以拥有任意数量的不同模式,只要提示配置中的 mode 键与顶级任务配置中的 prompting_mode 键匹配,从而为提示工程实验实现轻松设置。

请注意,如果您指定自定义 prompting_mode,但未定义具有相同自定义 mode 的提示定义,则将使用该任务的 standard 提示模板。

Prompt Templates#

根据 LLM 的类型,您可以定义两种类型的模板:completionchat。对于 completion 模型(例如,gpt-3.5-turbo-instruct),您需要在提示的配置中包含 content

prompts:
  - task: generate_user_intent
    models:
      - openai/gpt-3.5-turbo-instruct
    content: |-
      ...

对于 chat 模型(例如,gpt-3.5-turbo),您需要在提示的配置中包含 messages

prompts:
  - task: generate_user_intent
    models:
      - openai/gpt-3.5-turbo
    messages:
      - type: system
        content: ...
      - type: user
        content: ...
      - type: bot
        content: ...
      # ...

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

例如,对于 generate_user_intent 任务,您可以指定以下内容

prompts:
  - task: generate_user_intent
    models:
      - openai/gpt-3.5-turbo
    max_length: 3000

Content Template#

completion 提示的内容或 chat 提示中消息的主体是一个字符串,它也可以包含变量以及可能的其他类型的构造。NeMo Guardrails 使用 Jinja2 作为模板引擎。查看 Jinja Synopsis 以获得快速入门介绍。

例如,generate_user_intent 任务的默认模板如下

"""
{{ general_instructions }}
"""

# This is how a conversation between a user and the bot can go:
{{ sample_conversation }}

# This is how the user talks:
{{ examples }}

# This is the current conversation between the user and the bot:
{{ sample_conversation | first_turns(2) }}
{{ history | colang }}

Variables#

提示中可以包含三种类型的变量

  1. 系统变量

  2. 提示变量

  3. 上下文变量

System Variables#

以下是系统变量的列表

  • general_instructions:内容对应于配置中指定的 通用说明

  • sample_conversation:内容对应于配置中指定的 示例对话

  • examples:根据任务,此变量将包含 LLM 应考虑的少量示例;

  • history:包含事件历史记录(请参阅 完整示例

  • relevant_chunks:(仅适用于 generate_bot_message 任务)如果使用了知识库,则此变量将包含基于用户查询的最相关的文本块。

Prompt Variables#

可以使用 LLMRails.register_prompt_context(name, value_or_fn) 方法注册提示变量。如果提供了函数,则将在每次渲染时计算变量的值。

Context Variables#

guardrails 配置中包含的 Flows 可以定义(和更新)各种 上下文变量。如果需要,这些变量也可以包含在提示中。

Filters#

过滤器的概念与 Jinja 中的相同(请参阅 Jinja 过滤器)。过滤器可以修改变量的内容,您可以使用管道符号 (|) 应用多个过滤器。

预定义的过滤器列表如下

  • colang:将事件数组转换为等效的 colang 表示形式;

  • remove_text_messages:从 colang 历史记录中删除文本消息(仅保留用户意图、机器人意图和其他操作);

  • first_turns(n):将 colang 历史记录限制为前 n 轮;

  • user_assistant_sequence:将事件数组转换为“用户:…/助手:…”序列;

  • to_messages:将 colang 历史记录转换为用户和机器人消息序列(适用于 chat 模型);

  • verbose_v1:将 colang 历史记录转换为更详细和明确的形式。

Output Parsers#

可选地,可以使用输出解析器解析来自 LLM 的输出。预定义的解析器列表如下

  • user_intent:解析用户意图,即删除 “User intent:” 前缀(如果存在);

  • bot_intent:解析机器人意图,即删除 “Bot intent:” 前缀(如果存在);

  • bot_message:解析机器人消息,即删除 “Bot message:” 前缀(如果存在);

  • verbose_v1:解析 verbose_v1 过滤器的输出。

Predefined Prompts#

目前,NeMo Guardrails 工具包包含用于 openai/gpt-3.5-turbo-instructopenai/gpt-3.5-turboopenai/gpt-4databricks/dolly-v2-3bcohere/commandcohere/command-lightcohere/command-light-nightly 的提示。

免责声明:评估和改进提供的提示是一项正在进行的工作。我们不建议在生产环境中使用这些提示部署此 alpha 版本。

Custom Tasks and Prompts#

如果您想创建超出 默认任务 中包含的自定义任务,则可以包含任务和关联的提示,如下例所示

prompts:
- task: summarize_text
  content: |-
      Text: {{ user_input }}
      Summarize the above text.

请参阅 “Prompt Customization”,了解在何处包含此自定义任务和提示。

在 action 中,可以通过 LLMTaskManager 渲染此提示

prompt = llm_task_manager.render_task_prompt(
    task="summarize_text",
    context={
        "user_input": user_input,
    },
)

with llm_params(llm, temperature=0.0):
    check = await llm_call(llm, prompt)
...

使用这种方法,您可以快速修改配置文件中自定义任务的提示。