当前位置: 首页 > news >正文

Rasa学习笔记

一、CALM (Conversational AI with Language Models)

三个关键要素:

  • 业务逻辑:Flow,描述了AI助手可以处理的业务流程
  • 对话理解:旨在解释最终用户与助手沟通的内容。此过程涉及生成反映用户意图的命令,与业务逻辑和正在进行的对话的上下文保持一致。
  • 自动对话修复:修复处理会话“脱离脚本”的所有方式

CALM使用一种称为对话理解(DU)的新方法,将用户所说的内容转化为对业务逻辑的意义,关键点:

  • DU输出一系列命令,表示用户希望如何推进对话,而不是像NLU系统那样产生意图和实体
  • NLU系统被限制在一个固定的意图列表中,而DU是生成性的,根据内部语法产生一系列命令。这为我们提供了一种更丰富的语言来表达用户的需求。
  • 使用CALM比构建基于NLU的助手要快得多。CALM不依赖于意图,使用一个名为Flows的原语来定义对话逻辑

CALM使用LLM来确定用户希望如何推进对话。它不使用LLM来猜测完成该过程的正确步骤集。相比于LLM Agent,CALM可以确保业务逻辑被明确地遵循

二、工作流

在CALM中,AI助手的业务逻辑被实现为一组流。每个流程都描述了您的AI助手完成任务所使用的逻辑步骤。它描述了用户需要的信息、需要从API或数据库检索的数据,以及基于收集的信息的分支逻辑。

1. 流的定义
flows:
  a_flow: # required id
    name: "A flow" # optional name
    description: "required description of what the flow does"
    always_include_in_prompt: false # optional boolean, defaults to false
    if: "condition" # optional flow guard
    nlu_trigger: # optional list of intents that can start a flow
     - intent: "starting_flow_intent"
    persisted_slots: [] # optional list of slots that should be persisted at the conversation level after the flow ends
    steps: [] # required list of steps
  • description:必填,描述流程为用户做了什么。编写清晰的描述很重要,因为对话理解组件使用它来决定何时开始此流程
  • always_include_in_prompt:如果always_include_in_prompt字段设置为true,并且If字段中定义的流保护计算结果为true,则该流将始终包含在提示中
  • nlu_trigger:可以启动该流的意图。
  • persisted_slots:默认情况下,当流程结束时,在collect和set_slot步骤中设置的插槽将被重置。要更改此行为,可以将这些插槽添加到persisted_slots字段中,其值应在流结束后持久化。且这些slot必须在collect 或 set_slots步骤中被填充
  • steps:列出了流程步骤,有以下几种类型
    • action step: 由流运行的自定义动作或话语动作
    • collect step:向用户提出一个问题以填充一个插槽
    • call step:调用另一个流的步骤
    • link step:在该流完成后链接另一个流的步骤
    • set slots step:设置插槽的步骤
    • noop步骤:创建条件的步骤

step有id和next两个属性,用来标识当前步骤和下一个步骤,如果不标识next,则使用列表中的下一步

- collect: name
  next: the_next_step
- id: the_next_step
  collect: age

匿名next

- collect: name
  next:
    - collect: age

- collect: age
  next:
    - if: slots.age < 18
      then:
        - action: utter_not_old_enough
          next: END
    - if: slots.age >= 18 and slots.age < 65
      then: 18_to_65_step
    - else: over_65_step
2. Step
  • action:action_do_something执行命令,不需要等用户输入
- action: action_check_sufficient_funds
  • collect:用户需要输入的slot,可以添加描述字段以指导语言模型提取槽值
- collect: account_type
  description: "Account type is one of checking, savings, money market, or IRA."
  ask_before_filling:true
  reset_after_flow_ends:false
  utter: utter_ask_secondary_account_type
  
- collect: age
        rejections:
          - if: slots.age < 1
            utter: utter_invalid_age
          - if: slots.age < 18
            utter: utter_age_at_least_18
        next: ask_email

默认情况下,如果slot已被提取则跳过收集步骤,ask_before_filling设置为true则依旧需要询问。可以设置为false,在域文件中添加默认值

slots:
  dress_type:
    type: categorical
    values:
      - "shirt"
      - "pants"
      - "jacket"
    mappings:
      - type: custom
  dress_size:
    type: categorical
    values:
      - "small"
      - "medium"
      - "large"
    mappings:
      - type: custom

默认情况下,当流程完成时,通过收集步骤填充的所有插槽都会重置。一旦流结束,插槽的值要么重置为null,要么重置为插槽的初始值。如果要在流完成后保留插槽的值,将reset_after_flow_ends属性设置为false。该设置和persisted_slots字段冲突

utter_ask_{slot_name}可以为收集的slot定义不同的key

actions:
  - action_ask_{slot_name}

使用action_ask_{slot_name}可以自定义收集步骤,如想将从数据库中获取的插槽的可用值显示为按钮

rejections属性用于slot的验证,如果if条件为True,则返回utter定义的内容。如果没有通过验证,助手会自动尝试再次收集信息,直到值没有被拒绝,并默认返回Sorry,可以通过utter_internal_error_rasa修改
对于更复杂的验证逻辑,您还可以在自定义操作中定义插槽验证。请注意,此自定义操作必须遵循以下命名约定:validate_{slot_name}

  • link
    链接只能用作流程的最后一步。当达到链接步骤时,当前流结束,目标流开始。
- link: "id_of_another_flow"
  • call:可以在流(父流)中使用调用步骤来嵌入另一个流(子流)。当执行到达调用步骤时,CALM会启动子流。子流完成后,执行将继续父流。
flows:
  parent_flow:
    steps:
      - call: child_flow

  child_flow:
  	if: False
    steps:
      - action: utter_child_flow

子流遇到next:END,则控件将传递回父流
激活子流时,父流的插槽不会重置。子流可以访问和修改父流的插槽。当控件返回到父流时,子流的插槽将不会重置。
如果在子流中触发CancelFlow()命令,父流也将被取消。

为了防止子流直接被用户消息触发,您可以在子流中添加流保护if: False,该流只有在父流调用它时才会触发。
另外,子流不能使用link

如果用例要求启动一个流作为另一个流的后续,那么link更适合完成两个流之间的连接。但是,如果一个流需要表现得像是另一个更大流的一部分,并且在子流完成后需要在更大流内执行更多步骤,那么应该使用call。

  • set_slots:设置slot的值,主要用于取消设置插槽值。例如,如果用户要求转账的金额超过了他们账户中的可用金额,您可能需要通知他们。只需重置金额槽,而不是结束流程。
flows:
  transfer_money:
    description: This flow lets users send money to friends and family.
    steps:
      - collect: recipient
      - id: ask_amount
        collect: amount
        description: the number of US dollars to send
      - action: action_check_sufficient_funds
        next:
          - if: not has_sufficient_funds
            then:
              - action: utter_insufficient_funds
              - set_slots:
                  - amount: null
                next: ask_amount
          - else: final_confirmation
  • noop:不需要actions、collect就能创建分支条件
flows:
  change_address:
    description: Allow a user to change their address.
    steps:
      - noop: true
        next:
          - if: not slots.authenticated
            then:
              - call: authenticate_user
                next: ask_new_address
          - else: ask_new_address
      - id: ask_new_address
        collect: address
3. 条件表达式

支持 not、and、or、is、is not 、contains、matches等

命名空间:

  • slots:用于访问插槽值
  • context:用于访问当前对话帧属性
  pattern_completed:
    description:  a flow has been completed and there is nothing else to be done
    steps:
      - noop: true
        next:
          - if: context.previous_flow_name != "greeting"
            then:
              - action: utter_what_can_help_with
                next: END
          - else: stop
      - id: stop
        action: action_stop

对话管理器在对话框架堆栈中组织流(用户定义和内置)的推进。对话帧堆栈表示LIFO(后进先出)对话帧堆栈。不同类型的对话框架被映射到内置的对话模式,以实现对话修复。

每个对话帧都有一个flow_idstep_id属性。flow_id是当前流的id,step_id是流中当前步骤的id。

4. 流的启动

nlu_trigger:包含一个可以启动流的意图列表,可以通过confidence_threshold添加置信区间阈值

flows:
  my_flow:
    description: "A flow triggered with <intent-name>"
    nlu_trigger:
      - intent:
          name: <intent-name>
          confidence_threshold: 0  # threshold value, optional
    steps:
      - action: my_action

在流定义中添加额外的if字段来指定流保护,但是如果是通过link,call,intent触发的则可以绕过限制

flows:
  show_latest_bill:
    description: A flow with a flow guard.
    if: slots.authenticated AND slots.email_verified
    steps:
      - action: my_action

三、对话理解

CALM的对话理解模块将带有对话上下文的最新用户消息转换为一组命令,助手使用这些命令来执行定义的业务逻辑。它是在命令生成器的帮助下完成的

目前支持以下几种命令生成器:

  • SingleStepLLMCommandGenerator
  • MultiStepLLMCommandGenerator
  • NLUCommandAdapter

如果想同时利用LLM和经典的NLU管道来预测命令,那么可以通过在基于LLM的命令生成器之前添加NLUCommandAdapter来实现
一般来说,如果第一个命令生成器预测了一个命令,则管道中接下来的所有其他命令生成器都会被跳过。

config.yml

pipeline:
# - ...
  - name: NLUCommandAdapter
  - name: SingleStepLLMCommandGenerator
# - ...

生成的命令包含以下:

  • Start Flow、Cancel Flow、Skip Question、Set Slot、Correct Slots、Clarify、Chit-Chat Answer、Knowledge Answer、Human Handoff、Error、Cannot Handle、Change Flow

四、域

域定义了助手的活动空间,包括:

  • Responses:发送给用户的响应模板
  • Actions:操作
  • Slots:对话的记忆
  • Session配置,如超时时间
1. Slots

插槽在域的插槽部分中定义,包含其名称、类型和默认值。存在不同的插槽类型来限制插槽可以取的可能值。

插槽类型:text、bool、categorical、float、any、list

slots:
  risk_level:
    type: categorical
    values:
      - low
      - medium
      - high
  • Slot Mappings

NLUCommandAdapter将NLU管道的输出(意图和实体)与域文件中定义的槽映射进行匹配。如果满足插槽映射,NLUCommandAdapter将发出设置插槽命令来填充插槽。

  • from _ lm
    可以使用from_llm槽映射类型用基于llm的命令生成器生成的值填充槽。如果域文件中没有明确定义映射,则这是默认的插槽映射类型。
slots:
  user_name:
    type: text
    mappings:
      - type: from_llm

在这个例子中,user_name插槽将填充基于LLM的命令生成器生成的值。允许基于LLM的命令生成器在会话流中的任何点填充此槽,而不仅仅是在该槽的相应收集步骤。NLUCommandAdapter将跳过任何具有from_llm映射的插槽,并且不会发出set插槽命令来填充这些插槽。

  • Mapping Conditions:可以定义在填充插槽之前满足插槽映射的条件。如果定义了映射到同一实体的多个插槽,但不希望在提取实体时填充所有插槽,则这特别有用
entities:
- person

slots:
  first_name:
    type: text
    mappings:
      - type: from_entity
        entity: person
        conditions:
          - active_flow: greet_user

  last_name:
    type: text
    mappings:
      - type: from_entity
        entity: person
        conditions:
          - active_flow: issue_invoice
    initial_value: "xx"
    shared_for_coexistence: True
  • 自定义Slot Mappings
actions:
- action_fill_user_name

slots:
  user_name:
    type: text
    mappings:
      - type: custom
        action: action_fill_user_name
  • 基于LLM的生成器在对话的任何时候都无法用基于NLU的预定义映射填充插槽。
  • 在插槽名称的collect步骤中,基于LLM的生成器将不会处于活动状态。如果您希望用户话语包含离题或其他意图,而不仅仅是设置插槽的信息,那么您应该使用NLU触发器来处理流中的这些特定意图。
  • 基于LLM的生成器可以在不收集插槽名称且具有from_LLM映射类型的步骤中填充其他插槽。

initial_value可以指定插槽的默认值
shared_for_coexistence属性指定共享一些CALM和基于NLU的系统都应该能够使用的插槽,如基于NLU的系统和CALM都应该能够知道用户是否登录。如果选项shared_for_coexistence未设置为true,则流定义中的reset_after_flow_ends:False属性将无效

2. Session配置
  • session_expiration_time:定义了新会话开始后的不活动时间(分钟)。
  • carry_over_slots_to_new_session:决定是否应将现有的插槽转移到新会话

默认配置:

session_config:
  session_expiration_time: 60  # value in minutes, 0 means infinitely long
  carry_over_slots_to_new_session: true  # set to false to forget slots between sessions

这意味着,如果用户在60分钟不活动后发送了第一条消息,则会触发一个新的对话会话,并且任何现有的插槽都会被转移到新会话中。

五、事件

Rasa Pro中的每个对话都代表一系列事件。事件用于跟踪用户消息和机器人响应,以及Rasa Pro在对话中采取的行动,如推进流程或设置插槽。Rasa Pro在对话的不同阶段发出事件,可以通过查询Rasa Pro分析数据管道或运行端到端测试来分析和改进您的助手

事件存储在Rasa Pro tracker store中,可以通过Rasa Pro HTTP API进行额外访问。

六、Responses

响应是助手发送给用户的消息。响应通常只是文本,但也可以包括图像和按钮等内容。

响应位于域文件中的Responses键下或单独的“Responses.yml”文件中。每个响应名称都应该以utter_开头

responses:
  utter_greet:
  - text: "Hi there!"
  utter_bye:
  - text: "See you!"

可以使用变量将信息插入到响应中。如下Rasa会自动用名为name的插槽中的值填充变量。如果这样的槽不存在或为空,则变量将填充None。
可以设置多个响应内容,会随机返回其中一个
channel属性会根据用户连接到的通道指定不同的响应变化

responses:
  utter_greet:
  - text: "Hey, {name}. How are you?"
  	channel: "slack"
  - text: "Hey, {name}. How is your day going?"

根据条件决定返回值

slots:
  logged_in:
    type: bool
    influence_conversation: False
    mappings:
    - type: custom
  name:
    type: text
    influence_conversation: False
    mappings:
    - type: custom

responses:
  utter_greet:
    - condition:
        - type: slot
          name: logged_in
          value: true
      text: "Hey, {name}. Nice to see you again! How are you?"

    - text: "Welcome. How is your day going?"
Rephraser

通过使用LLM来改写静态响应模板,机器人生成的响应听起来会更自然、更具对话性,从而增强用户交互。

通过配置 rephrase: True 来开启重写。也可以开启全局重写。rephrase_prompt用来添加提示词

responses:
  utter_greet:
    - text: "Hey! How can I help you?"
      metadata:
        rephrase: True
        rephrase_prompt: |
          The following is a conversation with
          an AI assistant. The assistant is helpful, creative, clever, and very friendly.
          Rephrase the suggested AI response staying close to the original message and retaining
          its meaning. Use simple english.
          Context / previous conversation with the user:
          {{history}}
          {{current_input}}
          Suggested AI Response: {{suggested_response}}
          Rephrased AI Response:

历史对话配置

nlg:
  - type: rephrase
    summarize_history: False  // 摘要模式
    max_historical_turns: 5   // 转录模式,保留最后n次对话的直接转录。

此外,可以配置使用的大模型、温度等参数

七、组件

1. 配置文件

通过配置文件config.yml定义需要的组件和策略

recipe: default.v1
language: en
assistant_id: 20230405-114328-tranquil-mustard

pipeline:
  - name: SingleStepLLMCommandGenerator

policies:
  - name: rasa.core.policies.flow_policy.FlowPolicy
  • pipeline:用于处理和理解最终用户发送助手的消息的组件
  pipeline:
    - name: SingleStepLLMCommandGenerator
      llm:
        model_group: openai_llm
      flow_retrieval:
        embeddings:
          model_group: text_embedding_model
      user_input:
        max_characters: 420
  • policies:助手将用于推进对话的对话策略
2. 模型组配置

LLM通常被部署在一个或多个组中,模型组允许在一个ID下定义多个模型,任何组件都可以使用该ID

模型组在endpoints.yml文件的model_groups键下定义

   model_groups:
     - id: openai_llm
       models:
         - provider: openai
           model: gpt-4-0613
           api_key: ${MY_OPENAI_API_KEY}
     - id: openai-gpt-35-turbo
       models:
         - provider: openai
           model: gpt-3.5-turbo
           timeout: 7

需要使用环境变量使用${}

embedding模型也在model下配置

model_groups:
     - id: text_embedding_model
       models:
         - provider: openai
           model: text-embedding-ada-002
3. 路由组件

根据路由组件决定将消息路由到NLU系统还是CALM系统,有两个路由组件可供选择:

  • IntentBasedRouter:NLU管道预测意图用于决定消息应该去哪里
  • LLMBasedRouter:此组件利用LLM来决定消息是应该路由到基于NLU的系统还是CALM

在config.yml中配置即可

 - name: IntentBasedRouter
   nlu_entry:
      sticky:
        - transfer_money
        - check_balance
        - search_transactions
      non_sticky:
        - chitchat
    calm_entry:
      sticky:
        - book_hotel
        - cancel_hotel
        - list_hotel_bookings
  • nlu_entry:
    • sticky:应该以sticky方式路由到基于NLU的系统的意图列表。
    • non_stricky:应以非粘性方式路由到基于NLU的系统的意图列表。
  • calm_entry:
    • sticky:应该以粘性方式路由到CALM的意图列表。
4. LLM 命令生成器

LLM 命令生成器利用上下文学习来输出一系列命令,这些命令表示用户希望如何推进对话

当前支持两种LLM 命令生成器:

  • SingleStepLLMCommandGenerator
  • MultiStepLLMCommandGenerator

生成器使用的默认prompt模板由静态部分和动态部分组成。动态部分由当前的上下文内容渲染得到。也可以自定义模板,自定义模板可以使用{}来获取流信息插槽信息

pipeline:
  - name: SingleStepLLMCommandGenerator
    prompt_template: prompts/command-generator.jinja2
{% for flow in available_flows %}
{{ flow.name }}: {{ flow.description }}
    {% for slot in flow.slots -%}
    slot: {{ slot.name }}{% if slot.description %} ({{ slot.description }}){% endif %}{% if slot.allowed_values %}, allowed values: {{ slot.allowed_values }}{% endif %}
    {% endfor %}
{%- endfor %}

MultiStepLLMCommandGenerator使用上下文学习在上下文中解释用户的消息,将任务分解为几个步骤,使LLM的工作更容易,步骤包括:

  • 处理流程(开始、结束等)
  • 填充插槽

因此也包含两套prompt:handle_flows和 fill_slots
在这里插入图片描述

  • 如果当前没有活动的流,则使用handle_flows提示符来启动或澄清流。
  • 如果启动了一个流,接下来将执行fill_slots提示符来填充新启动的流的任何槽。
  • 如果流当前处于活动状态,则调用fill_slots提示符来填充当前活动流的任何新插槽。如果用户消息(也)指示,例如,应启动新流或取消活动流,则会触发ChangeFlow命令。这导致调用handle_flows提示符来启动、取消或澄清流。如果该提示导致启动流,则再次执行fill_slots提示以填充该新流的任何槽。

同样的,MultiStepLLMCommandGenerator的prompt模板也可以自定义

pipeline:
  - name: MultiStepLLMCommandGenerator
    prompt_templates:
      handle_flows:
        file_path: prompts/handle_flows_template.jinja2
      fill_slots:
        file_path: prompts/fill_slots_template.jinja2
5. 相关流召回

随着助理技能的发展,功能流程的数量可能会扩展到数百个。然而,由于LLM上下文窗口的限制,将所有这些流同时呈现给LLM是不切实际的。为了确保效率,只考虑与给定对话相关的流的子集。我们实现了一个流检索机制,以识别和过滤命令生成器最相关的流。这种有针对性的选择有助于在LLM的上下文窗口范围内制定有效的提示。

在训练过程中,所有定义的流,都会被转换为包含流描述、插槽描述的文档。然后使用嵌入模型将这些文档转换为向量,并存储在向量存储中。当与助手交谈时,即在推理过程中,当前对话上下文被转换为向量,并与向量存储中的流进行比较。此比较确定了与当前对话上下文最相似的流,并将其包含在SingleStepLLMCommandGenerator和MultiStepLLMComandGenerator的提示中

always_include_in_prompt设置为true,则该流总会被包含在prompt内

相关流召回功能默认是开启的流召回的表现取决于流描述的质量

自定义prompt,提升准确率的技巧:

  • 提供详细的信息描述:确保流程描述准确且信息丰富,直接概述流程的目的和范围。力求简洁和信息密度之间的平衡,使用命令式语言,避免不必要的单词,以防止歧义。目标是尽可能清楚地传达基本信息。
  • 使用清晰标准的语言:避免不寻常的措辞或措辞。坚持使用清晰、普遍理解的语言
  • 明确定义上下文:明确定义流上下文,以提高模型的情境感知能力
  • 澄清隐性知识:澄清描述中的任何专业知识
  • 添加用户输入示例
pipeline:
  - name: SingleStepLLMCommandGenerator
    ...
    flow_retrieval:
      embeddings:
        model_group: openai_text_embedding
      turns_to_embed: 1
      should_embed_slots: true
      num_flows: 20
  • embeddings:模型选择,默认使用text-embedding-ada-002
  • turns_to_embed:要转换为向量的对话次数。将该值设置为1意味着只使用最新的对话回合
  • should_embed_slots:是否在训练期间将槽描述与流描述一起嵌入
  • num_flows:从向量存储中检索的最大流数
6. 多模型路由器
model_groups:
     - id: azure_llm_deployments
       models:
         - provider: azure
           deployment: gpt-4-instance-france
           api_base: https://azure-deployment-france/
           api_version: "2024-02-15-preview"
           api_key: ${MY_AZURE_API_KEY_FRANCE}
         - provider: azure
           deployment: gpt-4-instance-canada
           api_base: https://azure-deployment-canada/
           api_version: "2024-02-15-preview"
           api_key: ${MY_AZURE_API_KEY_CANADA}
       router:
           routing_strategy: simple-shuffle

在endpoints.yml中配置router实现多个模型的负载均衡。建议模型组配置中的模型部署使用相同的底层模型

可选的路由策略:

  • simple-shuffle:基于RPM(每分钟请求数)或权重进行分配
  • least-busy:把请求分发到正在进行的请求数量最少的模型
  • latency-based-routing:将请求分发到响应时间最短的模型

需要配置Redis的策略:

  • cost-based-routing:以最低成本将请求分发到部署。
  • usage-based-routing:向TPM(每分钟令牌数)使用率最低的部署分发请求
7. Policy
policies:
  - name: FlowPolicy
  - name: EnterpriseSearchPolicy

可以配置多个策略,在每一个转折点,配置中定义的每个策略都有机会以一定的置信度预测下一个操作。策略也可以决定不预测任何行动。最高置信度的策略决定了助理的下一步行动。

  • FlowPolicy

流策略是一个状态机,它确定性地执行流中定义的业务逻辑。流策略监督助手的状态,处理状态转换,并在会话修复需要时启动新流。

FlowPolicy采用对话堆栈结构(后进先出)和内部插槽来管理对话的状态。

  • Intentless Policy

无意图策略用于发送在域中定义的Response,但这些Response不是任何流的一部分。这有助于有效地处理闲聊、上下文问题和高风险话题

policies:
  - name: IntentlessPolicy
    prompt: prompts/intentless-policy-template.jinja2

可以通过在config.yml中设置prompt属性来更改用于生成Response的prompt

无意图策略通常可以以零样本方式选择正确的响应。可以通过添加示例对话来提高策略的性能,将端到端的故事添加到data/e2e_stories.yml到您的训练数据中。这些对话将被用作示例,以帮助学习无障碍政策。可以定义您的助手可以发送的经过审查的、人工撰写的回复

- story: currencies
  steps:
    - user: How many different currencies can I hold money in?
    - action: utter_faq_4

- story: automatic transfers travel
  steps:
    - user: Can I add money automatically to my account while traveling?
    - action: utter_faq_5

- story: user gives a reason why they can't visit the branch
  steps:
    - user: I'd like to add my wife to my credit card
    - action: utter_faq_10
    - user: I've got a broken leg
    - action: utter_faq_11

此外,对于高风险的话题,最安全的方法是发送一个自包含的、经过审查的答案,而不是依赖于生成模型。无障碍政策在CALM助理中提供了这种能力。

8. 自定义召回策略

自定义的类需继承自InformationRetrieval,并实现 connect 和 search 方法

from rasa.utils.endpoints import EndpointConfig
from rasa.core.information_retrieval import SearchResultList, InformationRetrieval

class MyVectorStore(InformationRetrieval):
    def connect(self, config: EndpointConfig) -> None:
        # Create a connection to the search system
        pass

    async def search(
        self, query: Text, tracker_state: dict[Text, Any], threshold: float = 0.0
    ) -> SearchResultList:
        # Implement the search functionality to retrieve relevant results based on the query and top_n parameter.
        pass

可以使用 self.embeddings 来使用域中定义的embedding模型

  • connect方法:建立与信息检索系统的连接。config是在endpoints.yml中对信息召回的配置
  • search方法:用于检索召回信息,query是查询的值,一般是用户的最后一个问题;tracker_state为当前跟踪器的状态,是Rasa Tracker的快照,包含有关Rasa对话的元数据。它可用于获取有关任何对话事件的信息。;threshold为置信阈值

在policies中定义自定义的类即可使用

policies:
  - ...
  - name: EnterpriseSearchPolicy
    vector_store:
      type: "addons.custom_information_retrieval.MyVectorStore"

自定义召回策略的应用场景:

  • 接入最先进的搜索引擎
  • 基于插槽的检索:通过自定义信息检索,您可以利用tracker_state提供的对话上下文和插槽。
  • 自定义搜索查询:助理开发人员可以根据可用的对话上下文自定义或重新表述搜索查询。
  • 支持其他嵌入模型
  • 支持其他库
9. 提取式搜索

如果对于某些问题想要确定的结果,而不使用大模型生成的答案,可以使用提取式搜索

被搜索的问题答案需要按照给定的格式存储在向量库中

[
    {
        "metadata": {
            "title": "who_finley",
            "type": "faq",
            "answer": "Finley is your smart assistant for the FinX App. You can add him to your favorite messenger and tell him what you need help with.",
        },
        "page_content": "Who is Finley?",
    },
    {
        "metadata": {
            "title": "how_finley_work",
            "type": "faq",
            "answer": "Finley is powered by the latest chatbot technology leveraging a unique interplay of large language models and secure logic.",
        },
        "page_content": "How does Finley work?"
    },
]

这种格式可确保当用户询问“Who is finley?”时,返回对应的answer

需要在配置文件中关闭llm

policies:
...
- name: EnterpriseSearchPolicy
  use_generative_llm: false

八、对话修复

Rasa提供了一系列默认的流来修复对话:

  • pattern_continue_interrupted:处理偏离
  • pattern_correction:处理修改
  • pattern_cancel_flow:处理取消
  • pattern_skip_question:处理跳过
  • pattern_chitchat:处理闲聊
  • pattern_completed:处理完结
  • pattern_clarification:处理分辨意图
  • pattern_internal_error:处理内部错误
  • pattern_cannot_handle:处理无法解决的问题(如当企业搜索策略无法从矢量存储中检索任何相关文档时,它会触发此机制。)
  • pattern_human_handoff:处理人工接入

对话修复是开箱即用的。这意味着,如果默认行为对于助手的用例来说足够好,那么在助手的项目目录中就不需要与处理修复用例的模式相对应的流

如果要修改默认行为,自定义一个名称相同的类即可覆盖

flows:
  pattern_completed:
    description: Completion of a user's flow
    steps:
      - action: utter_can_do_something_else

responses:
  utter_can_do_something_else:
    - text: "Is there anything else I can assist you with?"

如修改人工接入

flows:
  pattern_human_handoff:
    description: Human handoff implementation
    steps:
      - collect: confirm_human_handoff
        next:
          - if: slots.confirm_human_handoff
            then:
            - action: action_human_handoff
              next: END
          - else:
            - action: utter_human_handoff_cancelled
              next: END
slots:
  confirm_human_handoff:
    type: bool
    mappings:
      - type: custom

actions:
  - action: action_human_handoff

responses:
  utter_ask_confirm_human_handoff:
    - text: "Do you want to be connected to a human agent?"
      buttons:
        - payload: "yes"
          title: "Yes"
        - payload: "no"
          title: "No"
  utter_human_handoff_cancelled:
    - text: "Ok, I understand you don't want to be connected to a human agent. Is there something else I can help you with?"
      metadata:
        rephrase: True

相关文章:

  • 基于HAL库的按钮实验
  • 【个人开发】deepspeed+Llama-factory 本地数据多卡Lora微调
  • 【AI战略思考15】我对做自媒体视频博主的初步探索和一些思考
  • ubuntu下ollama/vllm两种方式在本地部署Deepseek-R1
  • 数据结构 堆和priority_queue
  • 跨平台数字内容整合策略:提升全域用户体验的关键路径
  • 一键终结环境配置难题:ServBay 1.9 革新 AI 模型本地部署体验
  • 使用 HTML CSS 和 JAVASCRIPT 的黑洞动画
  • 解决IDEA报错:java 找不到符号
  • 鸿蒙应用开发者基础
  • AI前端开发:驶向国际化职业发展快车道
  • 09 解决方案 - 开源机器人+具身智能+AI
  • 2010年上半年软件设计师考试上午真题的知识点整理(附真题及答案解析)
  • Ubuntu 下 nginx-1.24.0 源码分析 - ngx_localtime 函数
  • 3D数字化技术:重塑“人货场”,开启营销新纪元
  • 机器学习周报-文献阅读
  • 刷SQL总结
  • [matlab优化算法-18期】基于遗传算法的模糊PID控制优化
  • 2025-alibaba-分布式事务组件-Seata
  • 神经网络新手入门(2)基础认知:神经网络发展简史
  • 夜读丨庭院春韵
  • 三杀皇马剑指四冠,硬扛到底的巴萨,赢球又赢人
  • 新任浙江省委常委、组织部长杨荫凯到嘉兴南湖瞻仰红船
  • 乌方称泽连斯基与特朗普进行简短会谈
  • 人大法工委:涉核领域还需要有一部统领性的基础法律
  • “2025上海西九文化周”启动,香港顶尖文艺6月齐聚申城