本指南分享了经过验证的最佳实践和设计模式,可帮助您优化和扩缩代理应用。这些内容可帮助您降低设计时成本、降低运行时成本,并提高代理的可靠性。
常规
本部分提供了一些常规最佳实践,可帮助您开始开发代理和撰写指令。
先从简单的做起
首次开始构建代理应用时,您应从简单的使用情形入手。在简单用例正常运行后,继续构建更复杂的用例。
说明应具体明确
代理说明应明确具体。 说明应按主题进行整理和分组。 避免以杂乱无章的方式分散特定主题的说明。 说明也应便于用户遵循。
使用结构化指令
编写完指令后,您应使用重构指令功能来设置指令格式。 采用这种格式后,您的代理将更加可靠。
使用来自多种模态和渠道的模块化组件
如果代理应针对不同的模态(文本或语音)或渠道(API、电话或 Web)以不同的方式做出响应,您应使用模块化组件,并在 Python 工具和回调中检查渠道和模态。
工具
本部分提供了有关定义和使用工具的最佳实践,包括封装外部 API 和串联工具调用。
使用 Python 工具封装 API
外部 API 架构可能会定义许多与代理无关的输入和输出参数。如果您在类似情况下使用 OpenAPI 工具,可能会向模型提供不必要的上下文,从而降低可靠性。 例如,假设某个 OpenAPI 规范工具将 3 个参数作为输入,并返回一个包含 100 个键值对的大型 JSON 对象。智能体预测此工具的 3 个输入实参,并在返回时看到包含所有 100 个键值对的完整 JSON 载荷。如果只有 3 对实际上与对话相关,那么其他 97 对就是无关数据,会向对话历史记录添加令牌。虽然这看起来似乎无害,但可能会给代理带来不必要的困惑,增加推理时间,并增加延迟。
最佳实践是使用 Python 工具封装 API 调用。 封装功能可让您混淆代理和上下文历史记录中不必要的数据。您可以通过仅返回在特定时间点与代理相关的数据来精确控制代理看到的上下文。这样一来,您就可以完全控制工具定义的输入和输出参数,这些参数会与模型共享。 这种实践是一种使用工具的上下文工程。
示例代码:
def python_wrapper(arg_a: str, arg_b: str) -> dict:
"""
Call the scheduling service to schedule an appointment,
returning only relevant fields.
"""
res = complicated_external_api_call(...)
# Process result to extract only relevant key-value pairs.
processed_res = {
"appointment_time": res.json()["appointment_time"],
"appointment_location": res.json()["appointment_location"],
"confirmation_id": res.json()["confirmation_id"],
}
return processed_res
使用工具和回调来实现确定性行为
在某些对话场景中,您可能需要代理应用表现出更确定的行为。在这些情况下,您应使用工具或回调。
回调通常是实现完全确定性控制的最佳选择。 回调发生在代理的管辖范围之外,因此代理不参与回调的执行。
工具的内部结构是完全确定性的,但由代理编排的工具调用是不确定的。智能体决定调用工具、准备工具输入实参并解读工具结果。智能体可能会虚构出这种编排。
串联工具调用
与使用工具封装 API 调用类似,如果需要在对话轮次中执行多个工具,您应指示智能体调用一个工具,并实现该工具以调用其他工具。或者,您也可以指示代理调用第一个工具,并定义一个 after_tool_callback 回调来调用其余工具。
用于链接工具调用的错误模式
指示代理在对话轮次中调用多个工具以实现共同目标被认为是一种不良模式。
模型必须预测每个工具调用以及相应工具调用中的每个参数。然后,它还必须确保按顺序预测工具调用。这意味着您非常依赖模型(本质上具有不确定性)来执行确定性任务。
例如,请考虑以下工具序列:
tool_1(arg_a, arg_b)-> 输出ctool_2(arg_c)-> 输出dtool_3(arg_d)-> 输出e
如果您为这三个工具调用定义了指令,最终会得到如下所示的运行时事件序列:
- 用户输入
- 模型 -> 代理预测
tool_1(arg_a, arg_b) tool_1_response.json()已退回- 智能体解读
tool_1_response.json()并提取arg_c - 模型 -> 代理预测
tool_2(arg_c) tool_2_response.json()已退回- 智能体解读
tool_2_response.json()并提取arg_d - 模型 -> 代理预测
tool_3(arg_d) tool_3_response.json()已退回- 模型 -> 代理提供最终回答
有 4 次模型调用、3 次工具预测和 4 个输入实参。
用于串联工具调用的良好模式
当您需要调用多个工具时,一个不错的模式是指示代理调用单个工具,并实现该工具来调用其他工具。
以下工具会调用其他三个工具:
def python_wrapper(arg_a: str, arg_b: str) -> dict:
"""Makes some sequential API calls."""
res1 = tools.tool_1({"arg_a": arg_a, "arg_b": arg_b})
res2 = tools.tool_2(res1.json())
res3 = tools.tool_3(res2.json())
return res3.json()
请考虑单个工具调用的事件序列:
- 用户输入
- 模型 -> 代理预测
python_wrapper(arg_a, arg_b) python_wrapper_response.json()已退回- 模型 -> 代理提供最终回答
这种方法可以减少 token,并降低出现幻觉的概率。
清晰且明确的工具定义
对于工具定义,应应用以下最佳实践:
- 不同工具的名称不应相似。 确保工具名称彼此之间有明显的区别。
- 应从代理节点中移除未使用的工具。
对于形参名称,请使用蛇形命名法、描述性名称,并避免使用不常见的缩写。
好的示例:
first_name、phone_number、url。反面示例:
i、arg1、fn、pnum、rqst。参数应使用扁平化结构,而不是嵌套结构。结构嵌套的层级越多,您就越依赖模型来预测键值对及其正确的类型。
开发工作流
本部分介绍了在智能体开发期间进行团队协作、版本控制和测试的最佳实践。
定义智能体协作的开发流程
与团队协作开发代理应用时,您应定义开发流程。以下是一些可能的协作实践:
- 使用第三方版本控制系统: 使用导入和恢复功能将更改与第三方版本控制系统同步。 就同步、审核和合并流程达成一致意见。 明确指定负责人,并明确接受变更的步骤(例如,获得评估结果)。
- 使用内置版本控制:设置使用内置版本控制的流程。 就如何使用快照进行版本控制达成一致意见。 例如,您可以在达到里程碑(一组评估通过)时或在完成新功能开发之前要求进行快照。 就同步、审核和合并更改的流程达成一致。
使用版本保存代理状态
借助版本,您可以记录在代理应用中完成的工作或更改。在对指令、工具、变量和其他项进行更改后,您可以在进行任何其他更改之前保存该状态。 版本是智能体在特定时间点的不可变快照。当您对某些更改感到满意,并且代理应用按您设计的方式运行时,您应创建一个版本,尤其是在通过评估验证更改后。创建版本后,您可以随时回滚到该版本。
您应该经常创建版本,或许每进行 10-15 次重大更改后就创建一个版本。
对版本进行语义命名也很有帮助,您应与开发团队一起决定要使用的命名惯例。例如,描述性名称(如 pre-prod-instruction-changes 或 prod-ready-for-testing)。您还可以使用语义版本控制等标准,使用 v1.0.0、v1.0.1 等名称。版本还有一个说明字段,可用于添加更多详细信息,类似于提交消息正文。版本名称和说明应简短、有意义且易于理解,以防您需要回滚到该版本。
执行端到端测试
您的代理应用开发流程应包含端到端测试,以验证与外部系统的集成。
评估结果
本部分介绍了使用评估功能确保代理可靠性的最佳实践。
使用评估
评估有助于确保代理的可靠性。 您可以使用这些规则来设定对代理和代理所调用 API 的预期。
会话处理
本部分提供了用于管理会话生命周期的模式。
通过静态回答实现确定性问候和低延迟
您可以配置代理,使其在会话开始时说出确定的回答。 这种方法可以节省模型调用次数和 token,并缩短延迟时间。
使用 before_model_callback 可让您拦截传入的输入,然后使用静态问候消息进行响应。
def before_model_callback(
callback_context: CallbackContext,
llm_request: LlmRequest
) -> Optional[LlmResponse]:
for part in callback_context.get_last_user_input():
# Or other events or texts
if part.text == "<event>session start</event>":
return LlmResponse.from_parts(parts=[
Part.from_text(text="Hello how can I help you today?")
])
return None
在模型工作时,使用前缀消息快速回复
当会话开始时,避免强制用户等待模型生成。 您可以为回答添加前缀,以便智能体快速提供亲切的品牌问候语(例如“您好,我是 Gemini,您的个人助理”),同时模型会在后台处理用户的主要请求。
这取决于 partial = True 设置。
通常,非 FuctionCall 响应会被视为最终响应。
使用 partial = True 会强制智能体在响应后继续处理。
在以下示例中,代理应用会快速传递欢迎辞,然后继续处理主要请求。这样可以消除尴尬的输入暂停,让代理感觉响应迅速。
def before_model_callback(callback_context: CallbackContext, llm_request: LlmRequest) -> Optional[LlmResponse]:
for part in callback_context.get_last_user_input():
if part.text == "<event>session start</event>":
response = LlmResponse.from_parts([Part.from_text("Hello, I'm Gemini, your personal AI assistant.")])
response.partial = True
return response
return None
验证并强制执行强制性内容
在某些情况下,您可能希望指示代理提供特定的强制性内容(例如法律免责声明),但同时也希望验证代理是否确实添加了该内容。此模式可让您在模型正常运行时依赖其自然生成能力,但在模型失败时强制执行确定性内容。
您可以使用 after_model_callback 检查模型的输出。如果存在强制性内容,回调会返回 None(让模型的回答通过)。如果缺少,回调会构建包含必需内容的新响应。
示例变量:
| 变量名称 | 默认值 |
|---|---|
| first_turn | True |
DISCLAIMER = "THIS CONVERSATION MAY BE RECORDED FOR LEGAL PURPOSES."
def after_model_callback(
callback_context: CallbackContext,
llm_response: LlmResponse
) -> Optional[LlmResponse]:
if callback_context.variables.get("first_turn"):
callback_context.variables["first_turn"] = False
# Check if the agent's response already contains the disclaimer.
# The agent might have produced it based on instructions.
for part in callback_context.get_last_agent_output():
if part.text and DISCLAIMER in part.text:
return None
# If the agent failed to produce the disclaimer, force it.
return LlmResponse.from_parts(parts=[
Part.from_text(DISCLAIMER),
*llm_response.content.parts
])
return None
在会话结束时调用自定义工具
您可以将代理配置为在会话结束时调用特定工具。 这对于通话后清理事件非常有用,例如在退出时同步数据、将数据发送到外部 API、完成后端任务或记录通话元数据。
例如,假设您有一个现有工具(如 post_call_logging),您希望在会话结束前调用该工具:
def post_call_logging(session_id: str) -> dict:
"""Logs the session ID to external API."""
API_URL = "https://api.example.com"
response = ces_requests.post(
url=API_URL,
data={"session_id": session_id}
)
return response.json()
您可以使用 after_model_callback 执行以下序列:
- 检查智能体回答中是否存在
end_session工具调用。 - 创建
post_call_logging工具部件。 - 在
end_session工具调用之前插入post_call_logging工具调用。
这可确保代理在终止会话之前执行日志记录工具。
def after_model_callback(
callback_context: CallbackContext,
llm_response: LlmResponse
) -> Optional[LlmResponse]:
for index, part in enumerate(llm_response.content.parts):
if part.has_function_call('end_session'):
# Add an additional "post_call_logging" function call before "end_session",
# so the agent will execute the tool before ending the session.
tool_call = Part.from_function_call(
name="post_call_logging",
args={"sessionId": callback_context.session_id}
)
return LlmResponse.from_parts(
parts=llm_response.content.parts[:index] + [tool_call] + llm_response.content.parts[index:]
)
return None
使用部分响应进行实时用户界面更新
当代理执行操作(例如更新订单状态)时,模型在处理最终响应时可能会出现延迟。使用部分响应可在工具完成执行时向客户端用户界面发送通知,从而将视觉更新与模型的文本生成分离。
您的用户界面可以实时刷新状态栏、跟踪器或收据。
这取决于 partial = True 设置。
通常,非 FuctionCall 响应会被视为最终响应。
使用 partial = True 会强制智能体在响应后继续处理。
JSON 载荷不会发送给模型。 因此,代理在生成回答时不会知道有效载荷的存在。
def before_model_callback(
callback_context: CallbackContext,
llm_request: LlmRequest
) -> Optional[LlmResponse]:
if llm_request.contents[-1].parts[-1].has_function_response('update_order'):
order_state = llm_request.contents[-1].parts[-1].function_response.response['result']['order_state']
# Return a custom JSON payload before calling the model to generate the final agent response.
response = LlmResponse.from_parts([Part.from_json(data=json.dumps(order_state))])
response.partial = True
return response
return None
客户端集成
本部分提供了与客户端应用集成的模式。
使用自定义载荷驱动界面
用户希望获得动态、互动式的界面。 您可以使用自定义载荷来驱动客户端渲染,从而弥合代理与完善的应用之间的差距。您可以配置代理,使其能够检测响应中的特定模式(例如选项列表),并将其转换为高转化率的互动式界面元素(例如可点击的组件或按钮),而不是提供纯文本选项。
使用 after_model_callback 扫描智能体回答中的特定触发条件。
例如,如果模型输出为“Available options are: Refund, Track Order, Speak to Agent”,则以下回调会拦截这些选项并将其提取为 JSON 载荷,该载荷可用于界面呈现。
import json
def after_model_callback(
callback_context: CallbackContext,
llm_response: LlmResponse
) -> Optional[LlmResponse]:
prefix = 'Available options are:'
payload = {}
for part in llm_response.content.parts:
if part.text is not None and part.text.startswith(prefix):
# Return available options as chip list
payload['chips'] = part.text[len(prefix):].split(',')
break
new_parts = []
# Keep the original agent response part, as the custom payload won't be sent
# back to the model in the next turn.
new_parts.extend(llm_response.content.parts)
new_parts.append(Part.from_json(data=json.dumps(payload)))
return LlmResponse.from_parts(parts=new_parts)
显示 Markdown 和 HTML
如果您的对话界面支持使用 Markdown 和 HTML 来生成客服人员回答,您可以使用模拟器来测试这些回答,因为模拟器也支持 Markdown 和 HTML。
示例说明:
<role>
You are a "Markdown Display Assistant," an AI agent designed to demonstrate
various rich content formatting options like images, videos, and deep links
using HTML-style markdown. Your purpose is to generate and display this
content directly to the user based on their requests.
</role>
<persona>
Your primary goal is to showcase the rich content rendering capabilities of
the platform by generating HTML markdown for elements like images, videos,
and hyperlinks. You are a helpful and direct assistant. When asked to show
something, you generate the markdown for it and present it.
You should not engage in conversations outside the scope of generating and
displaying markdown. If the user asks for something unrelated, politely
state that you can only help with displaying rich content. Adhere strictly
to the defined constraints and task flow.
</persona>
<constraints>
1. **Scope Limitation:** Only handle requests related to displaying
markdown content (images, videos, links, etc.). Do not answer general
knowledge questions or perform other tasks.
2. **Tool Interaction Protocol:** You must use the \`display_markdown\`
tool to generate the formatted content string.
3. **Direct Output:** Your final response to the user must be the raw
markdown string returned by the \`display_markdown\` tool. Do not add
any conversational text around it unless the tool returns an error.
For example, if the tool returns \`"<img src='...'>"\`, your response
should be exactly \`"<img src='...'>"\`.
4. **Clarity and Defaults:** If a user's request is vague (e.g., "show me
an image"), use the tool's default values to generate a response. There
is no need to ask for clarification.
5. **Error Handling:** If the tool call fails or returns an error, inform
the user about the issue in a conversational manner.
</constraints>
<taskflow>
These define the conversational subtasks that you can take. Each subtask
has a sequence of steps that should be taken in order.
<subtask name="Generate and Display Markdown">
<step name="Parse Request and Call Tool">
<trigger>
User initiates a request to see any form of rich content (image,
video, link, etc.).
</trigger>
<action>
1. Identify the types of content the user wants to see (e.g.,
image, video, deep link).
2. Call the \`display_markdown\` tool. Set the corresponding
boolean arguments to \`True\` based on the user's request.
For example, if the user asks for a video and a link, call
\`display_markdown(show_video=True, show_deep_link=True)\`.
3. If the user makes a general request like "show me something
cool", you can enable all flags.
</action>
</step>
<step name="Output Tool Response">
<trigger>
The \`display_markdown\` tool returns a successful response
containing a \`markdown_string\`.
</trigger>
<action>
1. Extract the value of the \`markdown_string\` key from the
tool's output.
2. Use this value as your direct and final response to the
user, without any additional text or formatting.
</action>
</step>
</subtask>
</taskflow>
Python 工具示例:
from typing import Any
def display_markdown(show_image: bool, show_video: bool, show_deep_link: bool) -> dict[str, Any]:
"""
Constructs a markdown string containing HTML for various rich media elements.
This function generates an HTML-formatted string based on the boolean flags provided.
It can include an image, a video, and a hyperlink (deep link). The content for
these elements is pre-defined.
Args:
show_image (bool): If True, an <img> tag will be included in the output.
show_video (bool): If True, a <video> tag will be included in the output.
show_deep_link (bool): If True, an <a> tag will be included in the output.
Returns:
dict[str, Any]: A dictionary with a single key 'markdown_string' containing the
generated HTML markdown. If no flags are set, it returns a
message indicating nothing was requested.
"""
# MOCK: This is a mock implementation. It does not fetch any dynamic content.
# It assembles a markdown string from hardcoded HTML snippets to demonstrate
# the agent's ability to render rich content.
markdown_parts = []
if show_image:
image_html = "This is a sample image:\n<img src='https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png' alt='Google Logo' width='272' height='92' />"
markdown_parts.append(image_html)
if show_video:
video_html = "This is a sample video:\n<video controls width='320' height='240'><source src='https://www.w3schools.com/html/mov_bbb.mp4' type='video/mp4'>Sorry, your browser does not support embedded videos.</video>"
markdown_parts.append(video_html)
if show_deep_link:
link_html = "This is a sample deep link:\n<a href='https://www.google.com'>Click here to go to Google</a>"
markdown_parts.append(link_html)
if not markdown_parts:
return {"markdown_string": "You did not request any content to be displayed. Please specify if you want to see an image, video, or link."}
return {"markdown_string": "\n\n".join(markdown_parts)}
语音和音频频道控制
此部分提供用于控制语音和音频渠道的模式,包括预先录制的音频、等待音乐和插话设置。
注意:
- 支持 Linear16、mulaw 和 alaw 音频编码作为音频文件。
- 如果使用属于其他云项目的 Cloud Storage 存储桶,则必须明确向 Customer Engagement Suite 服务账号
service-<PROJECT-NUMBER>@gcp-sa-ces.授予对目标 Cloud Storage 存储桶的storage.objects.get权限。 - 您可以使用
interruptable输入实参来配置最终用户是否可以中断预录的音频。 - 对于音乐播放,您可以使用
cancellable输入实参来指示当代理生成新的回答时,应停止音乐播放。
播放特定品牌的预先录制音频
您可以将代理配置为在处理用户请求之前播放预先录制的音频文件。您可以使用此功能在会话开始时显示品牌批准的问候语或强制性法律披露声明。
使用 "transcript": "yyy" 为代理提供音频播放文本,确保代理拥有必要的上下文来生成后续回答。
使用 "interrupable": false 可确保用户无法中断音频播放。
def before_model_callback(
callback_context: CallbackContext,
llm_request: LlmRequest
) -> Optional[LlmResponse]:
for part in callback_context.get_last_user_input():
if part.text == "<event>session start</event>":
return LlmResponse.from_parts(parts=[
Part.from_json(data='{"audioUri": "gs://path/to/audio/file", "transcript": "transcript for the audio file", "interruptable": false}')
])
return None
执行慢速工具时播放预先录制的音乐(无插播)
您可以配置代理,使其在运行缓慢的“阻塞”工具(例如账号验证和激活)时播放音乐。工具执行完毕后,音乐会自动停止。 在播放音乐时,用户无法与智能体互动。
def after_model_callback(
callback_context: CallbackContext,
llm_response: LlmResponse
) -> Optional[LlmResponse]:
for index, part in enumerate(llm_response.content.parts):
if part.has_function_call("slow_tool"):
play_music = Part.from_json(
data='{"audioUri": "gs://path/to/music/file", "cancellable": true}'
)
return LlmResponse.from_parts(
parts=llm_response.content.parts[:index] +
[play_music] + llm_response.content.parts[index:]
)
return None
在执行异步工具时播放预先录制的音乐(允许插话)
您可以配置代理在异步执行工具时播放音乐,例如在用户账号验证和激活期间。如果用户尚未中断音乐,则音乐会在异步工具完成时自动终止。 最终用户可以随时中断音乐播放,继续与智能体互动。
def before_model_callback(
callback_context: CallbackContext,
llm_request: LlmRequest
) -> Optional[LlmResponse]:
for part in llm_request.contents[-1].parts:
if part.has_function_response("async_tool"):
text = Part.from_text(text="I'm submitting your order, it may take a while.")
music = Part.from_json(
data='{"audioUri": "gs://path/to/music/file", "cancellable": true}'
)
return LlmResponse.from_parts(parts=[text, music])
return None
禁止用户针对某些回答进行抢答
您可以禁止用户在代理朗读重要信息(例如法律免责声明)时打断代理,但允许用户在代理回答的其余部分进行抢答。
此方法使用 customize_response 系统工具。
您可以采用以下两种方式来实现此行为,具体取决于您是否需要确定性结果:
- 回调(确定性):强制执行来自回调的响应,如示例所示。
- 指令(智能体驱动):提示智能体在其指令中使用
customize_response工具。
def before_model_callback(
callback_context: CallbackContext,
llm_request: LlmRequest
) -> Optional[LlmResponse]:
for part in callback_context.get_last_user_input():
if part.text == "<event>session start</event>":
return LlmResponse.from_parts(parts=[
Part.from_customized_response(
content=("Hello, I'm Gemini. Please listen to the following legal "
"disclaimer: <LEGAL_DISCLAIMER>"),
disable_barge_in=True
),
Part.from_text("How can I help you today?")
])
return None
针对无输入情况的自定义响应
当代理在等待输入时超时(请参阅代理应用设置中的静默超时)时,系统默认使用生成式回答。不过,您可以在 before 模型回调中检查用户是否收到了输入,并有条件地提供响应。
def before_model_callback(
callback_context: CallbackContext,
llm_request: LlmRequest
) -> Optional[LlmResponse]:
for part in callback_context.get_last_user_input():
if part.text:
if "no user activity detected" in part.text:
return LlmResponse.from_parts(parts=[
Part.from_text(text="Hi, are you still there?")
])
return None
错误处理
本部分提供了用于处理工具错误的模式。
在工具失败时转接给其他客服人员
当特定工具执行失败时,您可以确定性地将对话移交给另一个代理来处理。 这是在运行时错误期间保护用户体验的关键安全网。
def before_model_callback(
callback_context: CallbackContext,
llm_request: LlmRequest
) -> Optional[LlmResponse]:
for part in llm_request.contents[-1].parts:
if (part.has_function_response('authentication') and
'error' in part.function_response.response['result']):
return LlmResponse.from_parts(parts=[
Part.from_text('Sorry something went wrong, let me transfer you to another agent.'),
Part.from_agent_transfer(agent='escalation agent')
])
return None
在工具出现故障时正常终止会话
当特定工具执行失败时,您可以正常终止会话。 这样可以防止在发生严重工具故障时出现无限循环和令人困惑的回答。
回调示例:
def before_model_callback(
callback_context: CallbackContext,
llm_request: LlmRequest
) -> Optional[LlmResponse]:
for part in llm_request.contents[-1].parts:
if (part.has_function_response('authentication') and
'error' in part.function_response.response['result']):
return LlmResponse.from_parts(parts=[
Part.from_text('Sorry something went wrong, please call back later.'),
Part.from_end_session(reason='Failure during user authentication.')
])
return None
上下文和变量
本部分提供了使用上下文变量的模式。
将上下文变量传递给 OpenAPI 工具
个性化 AI 需要工具来访问用户会话数据。
依靠模型手动回忆和传递会话 ID 或用户变量等重要细节,本质上是不可靠且缓慢的。相反,智能体可以将特定上下文变量传递给 OpenAPI 工具。
您可以使用 x-ces-session-context 来表示该值不需要由模型生成(并且其架构对模型不可见),而是来自上下文变量。
下表列出了可用的值:
| 值 | 说明 |
|---|---|
$context.project_id |
Google Cloud 项目 ID。 |
$context.project_number |
Google Cloud 项目编号。 |
$context.location |
代理的位置(区域)。 |
$context.app_id |
代理应用 ID。 |
$context.session_id |
会话的唯一标识符。 |
$context.variables |
所有上下文变量值(以对象形式)。 |
$context.variables.variable_name |
特定上下文变量的值。将 variable_name 替换为变量的名称。 |
openapi: 3.0.0
info:
title: test-title
description: test-description
version: 1.0.0
paths:
/test-path/{session_id}:
post:
parameters:
- name: session_id
in: path
description: The session ID.
required: true
schema:
type: string
x-ces-session-context: $context.session_id
- name: test_variable
in: query
description: Specific session variable.
required: true
schema:
type: string
x-ces-session-context: $context.variables.test_variable
requestBody:
description: test-description
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/SessionParams'
responses:
'200':
description: test-response-description
content:
application/json:
schema:
type: object
properties:
result:
type: string
components:
schemas:
SessionParams:
type: object
description: all context variables
x-ces-session-context: $context.variables
动态提示
您可以使用以下方法构建可向模型发送动态提示的智能体:
- 可用于控制提示变体的变量。
- 包含对变量的引用的指令。
- 一种可以根据对话详细信息更新变量的工具。
- before_model_callback。
例如,您可以根据用户是律师还是海盗来更改代理的指令:
变量:
| 变量名称 | 默认值 |
|---|---|
| current_instructions | 我是 Gemini,在 Google 工作。 |
| lawyer_instructions | 你是一名律师,你的工作是讲冷笑话,但要带点律师的风格。 |
| pirate_instructions | 你是一名海盗,你的任务是以海盗的身份讲一个笑话。 |
| 用户名 | 未知 |
说明:
The current user is: {username}
You can use {@TOOL: update_username} to update the user's name if they provide
it.
Follow the current instruction set below exactly.
{current_instructions}
Python 工具:
from typing import Optional
def update_username(username: str) -> Optional[str]:
"""Updates the current user's name."""
set_variable("username", username)
回调:
def before_model_callback(
callback_context: CallbackContext,
llm_request: LlmRequest
) -> Optional[LlmResponse]:
username = callback_context.get_variable("username", None)
if username == "Jenn":
new_instructions = callback_context.get_variable("pirate_instructions")
elif username == "Gary":
new_instructions = callback_context.get_variable("lawyer_instructions")
callback_context.set_variable("current_instructions", new_instructions)