代码块

定义 Playbook 时,您可以视需要提供代码块,这些代码块是可用于更好地控制代理行为的内嵌 Python 代码。此代码由带有特殊装饰符的函数和您需要的任何实用函数组成。

编写代码时,您可以使用代码块系统库来控制代理行为。

限制

存在以下限制:

  • 代码块不得包含任何会保留数据的对象。不过,您可以使用工具来保留数据和维护状态。
  • 代码块无法直接进行远程调用。 例如,您无法使用 Python requests 库。不过,您可以使用工具间接进行远程调用。
  • 转换为 Python 名称的资源名称必须是合法的 Python 名称
  • 除非发生流程转换,否则代码块无法读取或写入会话参数。
  • 当代码块使用 OpenAPI 工具并收到非 200 HTTP 状态代码时,代码块会失败,并且无法捕获错误。

内嵌操作

内嵌操作的行为类似于工具操作。它们具有定义好的输入和输出架构,该架构由 Python 函数签名(包括类型注解和文档字符串)决定。与工具调用类似,LLM 不知道实现操作的代码。

示例 :

@Action
def is_prime(n: int): bool
  """Returns true if n is prime."""
  import math
  return (all([False for i in range(2, math.sqrt(n)
               if n % i == 0 ]) and not n < 2)

对于此函数,LLM 将获得有关操作、其输入和输出的信息。

如需在 Playbook 说明中引用内嵌操作,只需使用反引号引用操作名称,并说明其使用方式即可。

place_order 内嵌操作示例:

Take the customer's order, then call the `place_order` action when the order is ready.

如需创建使用内嵌操作的示例,请使用输入和输出部分中的 inline-action 工具类型。

如需了解详情,请参阅 @Action 参考文档。

触发器函数

触发器函数用于在代码中定义条件操作

触发器函数使用修饰符进行声明。您可以使用以下触发器函数装饰器:

装饰器 装饰器参数 说明
@EventTrigger event: str, condition: str,其中 condition 为可选 由事件触发
@BeforeModelTrigger condition: str,其中 condition 为可选 在 LLM 预测下一步操作之前触发一次。
@BeforeActionTrigger condition: str,其中 condition 为可选 在 LLM 执行操作之前触发。
@BeforePlaybookTrigger condition: str,其中 condition 为可选 在首次启动 Playbook 时触发。

例如,这些函数展示了如何使用这些装饰器和装饰器参数,以及如何使用 respond 代码块系统库函数。

# No decorator parameter
@PlaybookStartTrigger
def my_playbook_conditional_action():
  respond("How can I help?")

# With a condition decorator parameter
@BeforeActionTrigger('$next-action.name = "search"')
def my_before_action_conditional_action():
  respond("One moment please")

# Event
@EventTrigger(event="welcome")
def my_welcome_event():
  respond("hi")

# Event with a condition:
@EventTrigger(event="welcome",
              condition="$sys.func.NOW().hours < 10")
def my_good_morning_event():
  respond("Good morning ☕")

引用流程、Playbook 和工具

在代码块中,您可以使用手册工具全局变量引用特定流程、手册和工具。

这些对象中的每个成员都与相应资源的名称匹配。这些名称需要是合法的 Python 名称

示例 :

  add_override(playbooks.troubleshooting, {})
  add_override(flows.billing)
  add_override(tools.weather_api.get_weather, {"location": "San Francisco"})

在代码块中引用流程和 Playbook 时,您还必须在 Playbook 说明中使用以下语法引用它们:

${RESOURCE_TYPE: my_resource_name}

例如,如果您的代码块包含 flows.myflowplaybooks.myplaybook,则您的 Playbook 说明应包含:

${FLOW: myflow}
${PLAYBOOK: myplaybook}

操作替换项

您可以使用代码块创建一个操作队列,这些操作将在 LLM 确定的任何后续操作之前执行,并且可能会替换这些操作。您可以使用 add_override 全局函数创建操作替换项。

所有已加入队列的替换操作都会依序执行,并且操作输出将可供 LLM 使用。队列为空后,操作会返回到 LLM 以进行操作和输入选择,除非替换项使用 respond 或其他用于完成转弯的函数完成转弯。

函数参数:

  • action:要执行的操作。 对于内嵌操作,请使用 my_function_name。对于工具操作,请使用 tools.my_tool_name.my_tool_action。对于流程操作,请使用 flows.my_flow_name
  • inputs:操作的可选输入。 例如:{"location": "Omaha"}

样本:

# Assuming remote tool named "dmv" with operationId "search_offices"
# remote tool with only requestBody
add_override(tools.dmv.search_offices,{"address": "95030"})

# remote tool with only parameters
add_override(tools.pets.get_pet, {"id": "123"})

# remote tool with requestBody + parameters:
add_override(tools.pets.create_pet, {"requestBody": {"arg1":"foo"}, "param1": "bar"})

# datastore. Assumes existing datastore tool named "Menu".
add_override(tools.menu.Menu, {"query": "what is the menu"})

# code block action. Assumes another code block @Action my_action.
add_override(my_action)

响应替换项

与操作替换项类似,但专门针对客服人员回答,您可以使用 respond 全局函数强制客服人员使用特定内容回复用户。

示例 :

respond("Hello")

通话工具

在代码块函数中,您可以调用为代理定义的工具。与替换工具操作不同,直接调用工具时,LLM 无法使用工具执行结果。

样本:

# Assumes existing tool named "DMV" with operationId "search_offices"
# remote tool with only request body.
offices = tools.dmv.search_offices({"address": "95030"})

# remote tool with parameters and request body
offices = tools.dmv.search_offices({"requestBody": {"address":"95030"}, "param1":"foo"})

# datastore actions. Assumes existing datastore tool named "Menu".
data = tools.menu.Menu({"query": "get the menu"})["snippets"]

匹配 intent

代码块可以使用 Flow.match_intent 函数以编程方式匹配给定流程的 intent。

示例 :

matches = flows.flow1.match_intent(history.last_user_utterance).matches
if matches and matches[0].intent == "some_intent":
  to_country = matches[0].parameters.get("to_country")
  if to_country:
    respond(f"To confirm, you're going to {to_country}, right?")

调试

您可以使用模拟器调试代码块函数。这些函数将在模拟器中显示为操作,并会根据需要提供详细信息。

其他控件

本指南介绍了代码块系统库的一些常见用法。如需了解其他类型的控件,请参阅库文档。