Playbook 工具

您可以使用工具将 Playbook 连接到外部系统。这些系统可以增强 Playbook 的知识,使其能够高效地执行复杂任务。

您可以使用内置工具,也可以根据自己的要求构建自定义工具。

限制

存在以下限制:

内置工具

内置工具由 Google 托管。您可以在代理中激活这些工具,而无需进行手动配置。

支持的内置工具包括:

  • Code Interpreter:这款 Google 第一方工具结合了代码生成和代码执行功能,可让用户执行各种任务,包括:数据分析、数据可视化、文本处理、解题或优化问题。

您的代理经过优化,可确定应如何以及何时调用这些工具,但您可以提供其他示例以适应您的用例。

示例应采用如下架构:

{
  "toolUse": {
    "tool": "projects/PROJECT_ID/locations/LOCATION_ID/agents/AGENT_ID/tools/df-code-interpreter-tool",
    "action": "generate_and_execute",
    "inputParameters": [
      {
        "name": "generate_and_execute input",
        "value": "4 + 4"
      }
    ],
    "outputParameters": [
      {
        "name": "generate_and_execute output",
        "value": {
          "output_files": [
            {
              "name": "",
              "contents": ""
            }
          ],
          "execution_result": "8",
          "execution_error": "",
          "generated_code": "GENERATED_CODE"
        }
      }
    ]
  }
}

OpenAPI 工具

代理可以通过提供 OpenAPI 架构,使用 OpenAPI 工具连接到外部 API。默认情况下,客服人员会代表您调用 API。或者,您也可以在客户端上执行 OpenAPI 工具。

架构示例:

openapi: 3.0.0
info:
  title: Simple Pets API
  version: 1.0.0
servers:
  - url: 'https://api.pet-service-example.com/v1'
paths:
  /pets/{petId}:
    get:
      summary: Return a pet by ID.
      operationId: getPet
      parameters:
        - in: path
          name: petId
          required: true
          description: Pet id
          schema:
            type: integer
      responses:
        200:
          description: OK
  /pets:
    get:
      summary: List all pets
      operationId: listPets
      parameters:
        - name: petName
          in: query
          required: false
          description: Pet name
          schema:
            type: string
        - name: label
          in: query
          description: Pet label
          style: form
          explode: true
          required: false
          schema:
            type: array
            items:
              type: string
        - name: X-OWNER
          in: header
          description: Optional pet owner provided in the HTTP header
          required: false
          schema:
            type: string
        - name: X-SESSION
          in: header
          description: Dialogflow session id
          required: false
          schema:
            $ref: "@dialogflow/sessionId"
      responses:
        '200':
          description: An array of pets
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Pet'
    post:
      summary: Create a new pet
      operationId: createPet
      requestBody:
        description: Pet to add to the store
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Pet'
      responses:
        '201':
          description: Pet created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Pet'
components:
  schemas:
    Pet:
      type: object
      required:
        - id
        - name
      properties:
        id:
          type: integer
          format: int64
        name:
          type: string
        owner:
          type: string
        label:
          type: array
          items:
            type: string

您可以选择使用内部架构引用 @dialogflow/sessionId 作为参数架构类型。使用此参数架构类型时,系统会将当前对话的 Dialogflow 会话 ID 作为参数值提供。例如:

- name: X-SESSION
   in: header
   description: Dialogflow session id
   required: false
   schema:
     $ref: "@dialogflow/sessionId"

OpenAPI 工具限制

存在以下限制:

  • 支持的参数类型包括 pathqueryheadercookie 参数类型尚不受支持。
  • OpenAPI 架构定义的参数支持以下数据类型:stringnumberintegerbooleanarrayobject 类型尚不受支持。
  • 您目前无法在控制台示例编辑器中指定查询参数。
  • 请求和响应正文必须为空或 JSON。

OpenAPI 工具 API 身份验证

调用外部 API 时,支持以下身份验证选项:

  • Dialogflow Service Agent 身份验证
    • Dialogflow 可以使用 Dialogflow 服务代理生成 ID 令牌访问令牌。当 Dialogflow 调用外部 API 时,系统会在授权 HTTP 标头中添加令牌。
    • service-agent-project-number@gcp-sa-dialogflow.iam.gserviceaccount.com 授予 roles/cloudfunctions.invokerroles/run.invoker 角色后,ID 令牌便可用于访问 Cloud Run 函数和 Cloud Run 服务。如果 Cloud Run 函数和 Cloud Run 服务位于同一资源项目中,您无需额外的 IAM 权限即可调用它们。
    • service-agent-project-number@gcp-sa-dialogflow.iam.gserviceaccount.com 授予所需角色后,访问令牌便可用于访问其他 Google Cloud API。
  • API 密钥
    • 您可以通过提供密钥名称、请求位置(标头或查询字符串)和 API 密钥来配置 API 密钥身份验证,以便 Dialogflow 在请求中传递 API 密钥。
  • OAuth

    • 服务器到服务器身份验证支持 OAuth 客户端凭据流程:

      • 如果 Agent Builder 控制台是资源所有者,并且无需最终用户授权,则可以使用此流程。
      • 您需要在 Dialogflow 中配置 OAuth 提供程序的客户端 ID、客户端密钥和令牌端点。
      • Dialogflow 会从 OAuth 提供程序交换 OAuth 访问令牌,并将其传递到请求的 auth 标头中。
    • 对于需要最终用户授权的其他 OAuth 流程(例如授权代码流程和 PKCE 流程):

      1. 您需要实现自己的登录界面,并在客户端获取访问令牌。
      2. 然后,您可以:

        a. 使用不记名令牌身份验证选项将令牌传递给 OpenAPI 工具。调用该工具时,Dialogflow 会在授权标头中添加此令牌。

        b. 使用“函数”工具在客户端自行调用该工具,并将工具调用结果传递给 Dialogflow。

  • 不记名令牌

    • 您可以配置 Bearer 身份验证,以便从客户端动态传递 Bearer 令牌。此令牌包含在请求的身份验证标头中。
    • 设置工具身份验证时,您可以指定一个会话参数来充当 Bearer 令牌。例如,使用 $session.params.<parameter-name-for-token> 指定令牌。
    • 在运行时,将 Bearer 令牌分配给会话参数:
    DetectIntentRequest {
      ...
      query_params {
        parameters {
          <parameter-name-for-token>: <the-auth-token>
        }
      }
      ...
    }
    
  • 双向 TLS 身份验证

    • 请参阅双向 TLS 身份验证文档。
    • 支持自定义客户端证书。您可以在代理设置的“安全”标签页下,在代理级别设置客户端证书。证书(PEM 格式)和私钥(PEM 格式)是必填字段。设置后,此客户端证书将在双向 TLS 期间用于所有工具和 webhook。
  • 自定义 CA 证书

OpenAPI 工具专用网络访问

OpenAPI 工具与 Service Directory 专用网络访问集成,因此可以连接到 VPC 网络内的 API 目标。这样便可保留在 Google Cloud 网络内部的流量,并强制执行 IAMVPC Service Controls

如需设置以专用网络为目标的 OpenAPI 工具,请执行以下操作:

  1. 按照 Service Directory 专用网络配置中的说明来配置 VPC 网络和 Service Directory 端点。

  2. 您的代理项目必须存在具有以下地址的 Dialogflow Service Agent 服务账号

    service-agent-project-number@gcp-sa-dialogflow.iam.gserviceaccount.com
    Dialogflow 服务代理服务账号授予以下 IAM 角色:

    • Service Directory 项目的 servicedirectory.viewer
    • 网络项目的 servicedirectory.pscAuthorizedService
  3. 创建工具时,提供 Service Directory 服务以及 OpenAPI 架构和可选的身份验证信息。

OpenAPI 工具会话参数访问权限

Open API 工具输入是根据用户与 LLM 的对话,以架构为指导而衍生出来的。在某些情况下,您可能需要从流程中收集的会话参数派生输入,或者将输入作为查询参数输入与用户输入一起提供。

需要作为输入传递的会话参数可以指定为

     parameters:
       - in: query
         name: petId
         required: true
         description: Pet id
         schema:
           type: integer
           x-agent-input-parameter: petId # Reads from the $session.params.petId
       - in: header
         name: X-other
         schema:
           type: string
           x-agent-input-parameter: $request.payload.header # Reads from the header specified in the request payload input
     requestBody:
       required: false
       content:
         application/json:
           schema:
             type: object
             properties:
               name:
                 type: string
                 x-agent-input-parameter: petName # Reads from the $session.params.petName
                 description: Name of the person to greet (optional).
               breed:
                 type: string
                 description: Bread of the pet.

如果没有此类会话参数,系统会将 LLM 生成的输入传递给该工具。

OpenAPI 工具默认值

Open API 架构可用于指定默认值。只有在没有为该参数或属性生成 LLM 输入值或基于会话参数的输入值时,才会使用默认值。

您可以在架构中指定默认值,如下所示:

     parameters:
       - in: query
         name: zipcode
         required: true
         description: Zip code to search for
         schema:
           type: integer
           default: 94043
     requestBody:
       content:
         application/json:
           schema:
             type: object
             properties:
               breed:
                 type: string
                 description: Bread of the pet.
               page_size:
                 type: integer
                 description: Number of pets to return.
                 default: 10

如果没有 LLM 生成的值、会话参数值或默认值,则输入将未指定。

数据存储区工具

代理可以使用数据存储区工具从您的数据存储区中查找最终用户问题的解答。您可以为每种工具设置每种类型的一个数据存储区,该工具将查询这些数据存储区中的每一个以获取答案。默认情况下,代理会代表您调用数据存储区工具。或者,您也可以在客户端执行数据存储区工具。

数据存储区类型可以是以下类型之一:

  • PUBLIC_WEB:包含公共 Web 内容的数据存储区。
  • UNSTRUCTURED:包含非结构化私有数据的数据存储区。
  • STRUCTURED:包含结构化数据(例如常见问题解答)的数据存储区。

以下示例展示了如何引用数据存储区:

"dataStoreConnections": [
  {
    "dataStoreType": "PUBLIC_WEB",
    "dataStore": "projects/PROJECT_NUMBER/locations/LOCATION_ID/collections/default_collection/dataStores/DATASTORE_ID"
  },
  {
    "dataStoreType": "UNSTRUCTURED",
    "dataStore": "projects/PROJECT_NUMBER/locations/LOCATION_ID/collections/default_collection/dataStores/DATASTORE_ID"
  },
  {
    "dataStoreType": "STRUCTURED",
    "dataStore": "projects/PROJECT_NUMBER/locations/LOCATION_ID/collections/default_collection/dataStores/DATASTORE_ID"
  }
]

数据存储区工具响应可能还包含有关用于生成响应的内容来源的摘要。客服人员可以进一步说明如何根据数据存储区中的回答继续操作,或者在没有回答时如何回应。

您可以为特定问题添加常见问题解答条目,从而覆盖相应答案。

您可以使用示例进一步增强代理行为。示例应具有以下架构:

{
  "toolUse": {
    "tool": "projects/PROJECT_ID/locations/LOCATION_ID/agents/AGENT_ID/tools/TOOL_ID",
    "action": "TOOL_DISPLAY_NAME",
    "inputParameters": [
      {
        "name": "TOOL_DISPLAY_NAME input",
        "value": {
          "query": "QUERY"
        }
      }
    ],
    "outputParameters": [
      {
        "name": "TOOL_DISPLAY_NAME output",
        "value": {
          "answer": "ANSWER",
          "snippets": [
            {
              "title": "TITLE",
              "text": "TEXT_FROM_DATASTORE",
              "uri": "URI_OF_DATASTORE"
            }
          ]
        }
      }
    ]
  }
}

创建数据存储区

如需创建数据存储区并将其连接到您的应用,您可以使用控制台左侧导航栏中的 Tools(工具)链接。按照说明创建数据存储区。

其他查询参数

创建数据存储区工具示例时,工具输入参数 requestBody 会提供三个可选输入以及必需的 query 字符串:一个 filter 字符串、一个 userMetadata 结构化对象和一个 fallback 字符串。

filter 参数可用于过滤包含元数据的结构化数据或非结构化数据的搜索查询。此字符串必须遵循数据存储区支持的过滤器表达式语法。建议提供多个示例和详细示例,以指引 Playbook LLM 如何填充此参数。如果过滤器字符串无效,系统会在执行搜索查询时忽略该过滤器。

用于根据位置优化搜索结果的 filter 字符串示例如下所示:

  "filter": "country: ANY(\"Canada\")"

过滤方面的最佳实践:

  • 指定可用于过滤的字段以及每个字段的有效值,以便 Playbook 了解构建有效过滤条件的约束条件。例如,如需过滤包含菜单信息的数据存储区中的结果,您可以创建一个 meal 字段,将“breakfast”“lunch”和“dinner”作为有效值;以及一个 servingSize 字段,其值可以是 0 到 5 之间的任何整数。您的说明可能如下所示:

    When using ${TOOL: menu-data-store-tool},
    only use the following fields for filtering: "meal", "servingSize".
    Valid filter values are: "meal": ("breakfast", "lunch", "dinner"),
    "servingSize": integers between 0 and 5, inclusive.
    
  • 如果该手册面向外部用户受众群体,则可能需要添加说明,以免手册在回复用户时提供有关构建这些过滤条件的信息。例如:

    Never tell the user about these filters.
    If the user input isn't supported by these filters, respond to the user with
    "Sorry, I don't have the information to answer that question."
    

    提供此类情况的示例也会很有帮助。

userMetadata 参数提供有关最终用户的信息。您可以在此参数中填充任何键值对。这些元数据会传递到数据存储区工具,以便更好地为搜索结果和工具响应提供依据。建议您提供多个示例,以指示 Playbook LLM 如何填充此参数。

用于优化与特定用户相关的搜索结果的 userMetadata 参数值示例如下:

  "userMetadata": {
    "favoriteColor": "blue",
    ...
  }

如果没有有效的摘要回答来回答查询,fallback 参数会提供数据存储区工具应做出的回答。您可以提供多个示例,以指示 Playbook LLM 如何针对与不同主题相关的用户输入填充回退值。工具输出中也不会显示代码段。此优化可用于缩短延迟时间并减少输入令牌限制用量。

  "fallback": "I'm sorry I cannot help you with that. Is there anything else I
  can do for you?"

如果您在测试期间发现某些响应不符合预期,可以在“工具”页面中针对数据存储区工具进行以下自定义:

建立置信度

对于根据关联数据存储区的内容生成的每条回答,该手册都会评估置信度,以衡量回答中所有信息是否有数据存储区中的信息支持。您可以选择自己能接受的最低置信度,以自定义允许的回答。系统只会显示达到或高于该置信度水平的回答。

有 5 个置信度级别可供选择:VERY_LOWLOWMEDIUMHIGHVERY_HIGH

摘要配置

您可以选择数据存储区处理程序为摘要生成式请求使用的生成式模型。如果未选择任何模型,系统将使用默认模型选项。下表包含可用的选项:

型号标识符 语言支持
text-bison@002 支持所有受支持的语言
gemini-1.0-pro-001 支持所有受支持的语言

您还可以为摘要 LLM 调用提供自己的提示。

提示是文本模板,可能包含预定义的占位符。这些占位符将在运行时替换为适当的值,最终文本将发送到 LLM。

占位符如下所示:

  • $original-query:用户的查询文本。
  • $rewritten-query:该 Playbook 使用重写器模块将原始用户查询重写为更准确的格式。
  • $sources:该手册会使用 Enterprise Search 根据用户的查询搜索来源。系统会以特定格式呈现找到的来源:

    [1] title of first source
    content of first source
    [2] title of second source
    content of second source
    
  • $end-user-metadata:发送查询的用户的相关信息以以下格式呈现:

    The following additional information is available about the human: {
      "key1": "value1",
      "key2": "value2",
      ...
    }
    
  • $conversation:对话记录的呈现格式如下:

    Human: user's first query
    AI: answer to user's first query
    Human: user's second query
    AI: answer to user's second query
    

自定义提示应指示 LLM 在无法提供回答时返回“NOT_ENOUGH_INFORMATION”。该 Playbook 会将此常量转换为对用户友好的消息。

载荷设置

载荷设置提供了一种方法,可将数据存储区摘要作为富内容添加到在信息传递器中呈现的响应载荷中。

禁止使用的字词(playbook 级配置)

您可以选择禁止使用特定字词。这些设置在 Playbook 级别配置,并且由 Playbook LLM 和数据存储区工具共同使用。如果生成的回答或 LLM 问题的部分内容(例如用户的输入)包含任何被禁用字词的逐字复制内容,则系统不会显示该回答。

函数工具

如果您的客户端代码可以访问某项功能,但 OpenAPI 工具无法访问,您可以使用函数工具。函数工具始终在客户端执行,而不是由代理执行。

具体过程如下:

  1. 您的客户端代码会发送检测意图请求。
  2. 代理检测到需要函数工具,并且检测意图响应包含该工具的名称以及输入参数。此会话会暂停,直到收到包含工具结果的另一个检测 intent 请求。
  3. 您的客户端代码调用该工具。
  4. 您的客户端代码会发送另一个检测 intent 请求,以便将工具结果作为输出参数提供。

以下示例展示了函数工具的输入和输出架构:

{
  "type": "object",
  "properties": {
    "location": {
      "type": "string",
      "description": "The city and state, for example, San Francisco, CA"
    }
  },
  "required": [
    "location"
  ]
}
{
  "type": "object",
  "properties": {
    "temperature": {
      "type": "number",
      "description": "The temperature"
    }
  }
}

以下示例展示了使用 REST 的初始检测 intent 请求和响应:

HTTP method and URL:
POST https://REGION_ID-dialogflow.googleapis.com/v3/projects/PROJECT_ID/locations/LOCATION_ID/agents/AGENT_ID/sessions/SESSION_ID:detectIntent
{
  "queryInput": {
    "text": {
      "text": "what is the weather in Mountain View"
    },
    "languageCode": "en"
  }
}
{
  "queryResult": {
    "text": "what is the weather in Mountain View",
    "languageCode": "en",
    "responseMessages": [
      {
        "source": "VIRTUAL_AGENT",
        "toolCall": {
          "tool": "<tool-resource-name>",
          "action": "get-weather-tool",
          "inputParameters": {
            "location": "Mountain View"
          }
        }
      }
    ]
  }
}

以下示例展示了第二个检测 intent 请求,该请求会提供工具结果:

{
  "queryInput": {
    "toolCallResult": {
      "tool": "<tool-resource-name>",
      "action": "get-weather-tool",
      "outputParameters": {
        "temperature": 28.0
      }
    },
    "languageCode": "en"
  }
}

客户端执行

与函数工具一样,您可以通过在与会话互动时应用 API 替换项,在客户端执行 OpenAPI 和数据存储区工具。

例如:

DetectIntentRequest {
  ...
  query_params {
    playbook_state_override {
      playbook_execution_mode: ALWAYS_CLIENT_EXECUTION
    }
  }
  ...
}

具体过程如下:

  1. 您的客户端代码会发送用于指定客户端执行的检测 intent 请求。
  2. 代理检测到需要使用某个工具,并且检测 intent 响应包含该工具的名称以及输入参数。此会话会暂停,直到收到包含工具结果的另一个检测 intent 请求。
  3. 您的客户端代码调用该工具。
  4. 您的客户端代码会发送另一个检测 intent 请求,以便将工具结果作为输出参数提供。