定义 playbook 时,您可以选择提供代码块,这些代码块是可用于更好地控制代理行为的内嵌 Python 代码。此代码由带有特殊装饰器的函数以及您所需的任何实用函数组成。
编写代码时,您可以使用代码块系统库来控制代理行为。
已知问题
存在以下已知问题:
- VPC-SC 边界内限制 Artifact Registry 访问权限的项目也会拒绝代码块部署
限制
存在以下限制:
- 代码块不能包含任何会保留数据的对象。不过,您可以使用工具来保留数据并维护状态。
- 代码块无法直接进行远程调用。 例如,您无法使用 Python requests 库。不过,您可以利用工具间接进行远程调用。
- 转换为 Python 名称的资源名称必须是合法的 Python 名称。
- 除非发生流程转换,否则代码块无法写入会话参数。
内嵌操作
内嵌操作的行为与工具操作类似。它们具有由 Python 函数签名(包括类型注释和 docstring)确定的已定义输入和输出架构。与工具调用类似,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 提供有关操作、输入和输出的信息。
如需在剧本说明中引用内嵌操作,只需在反引号中引用操作名称,并说明应如何使用该操作。
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 和工具
在代码块中,您可以使用 flows、playbooks 和 tools 全局变量来引用特定的流程、剧本和工具。
这些对象各自都包含与相应资源名称匹配的成员。 这些名称必须是合法的 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.myflow
和 playbooks.myplaybook
,则剧本指令应包含:
${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"]
匹配意图
代码块可以使用 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?")
读取会话参数
代码块可以读取执行时可用的参数。
示例 :
state["$session.params.my-param"]
state["$request.session-id"]
调试
您可以使用模拟器来调试代码块函数。这些功能将以操作的形式显示在模拟器中,并会根据需要提供我们的详细信息。
其他控制措施
本指南介绍了代码块系统库的一些常见用途。如需了解其他类型的控制,请参阅库文档。