Crear y ejecutar extensiones

En este documento se muestra la funcionalidad clave del servicio de extensiones de Vertex AI:

Para saber cómo importar y ejecutar una extensión proporcionada por Google, consulta lo siguiente:

Crear e importar extensiones

En este documento se presupone que ya tienes un servicio de API en ejecución que puede respaldar una extensión. Para crear una extensión, debes definir su interfaz con una API externa en un archivo de especificación de API. Debe subir este archivo de especificación a un segmento de Cloud Storage o convertirlo en una cadena. A continuación, debes definir un manifiesto de extensión, incluir el archivo de especificación y enviar una solicitud de registro al servicio de extensiones.

Crear un archivo de especificación de API

Cualquier persona puede crear una extensión a través de archivos que definan y describan los endpoints de la API de la extensión. Los endpoints de la API pueden ser públicos o privados y estar alojados en cualquier nube o en un entorno local.

Un archivo de especificación de API describe la interfaz de un servicio de API. Debes proporcionar un archivo de especificación de API en formato YAML que sea compatible con OpenAPI 3.0. Este archivo de especificación debe definir lo siguiente:

  • Un objeto de servidor. Este objeto debe definir una URL de servidor de API. El servicio de extensión de Vertex AI no admite varios servidores.

    servers:
      - url: API_SERVICE_URL
    
  • Un objeto de rutas. Este objeto debe describir las distintas operaciones que proporciona el servicio de la API y los parámetros de entrada que corresponden a cada operación. Cada operación debe tener un identificador único y una respuesta.

    paths:
      ...
        get:
          operationId: API_SERVICE_OPERATION_ID
          ...
          parameters:
            - name: API_SERVICE_INPUT_VAR
              ...
          responses:
          ...
    
  • Un objeto components. Este objeto es opcional. Puede usar el objeto components para definir objetos reutilizables. Por ejemplo, puede usar el objeto components para proporcionar una definición de los esquemas de objeto que se definen en el objeto paths. También puedes usar el objeto components para describir los parámetros de salida del servicio de la API.

    components:
      schemas:
        Result:
          ...
          properties:
            API_SERVICE_OUTPUT_VAR:
            ...
    

Para obtener más información sobre OpenAPI, consulta la especificación de OpenAPI.

El siguiente ejemplo es un archivo de especificación de API para un servicio de API que dice "hola" en el idioma solicitado:

  openapi: "3.0.0"
  info:
    version: 1.0.0
    title: Hello Extension
    description: Learn to build Vertex AI extensions
  servers:
    - url: [API_SERVICE_URL]
  paths:
    /hello:
      get:
        operationId: say_hello
        description: Say hello in prompted language.
        parameters:
          - name: apiServicePrompt
            in: query
            description: Language
            required: true
            schema:
              type: string
        responses:
          '200':
            description: Successful operation.
            content:
              application/json:
                schema:
                  $ref: "#/components/schemas/Result"
  components:
    schemas:
      Result:
        description: Hello in the requested language.
        properties:
          apiServiceOutput:
            type: string

Sube el archivo de especificaciones

Puedes subir el archivo de especificación a un segmento de Cloud Storage o convertirlo en una cadena.

Si subes el archivo de especificación a un segmento de Cloud Storage, otorga a la Vertex AI Extension Service Agentcuenta de servicioservice-PROJECT_NUMBER@gcp-sa-vertex-ex.iam.gserviceaccount.com el rol Lector de objetos de almacenamiento. Para saber cómo enumerar los contenedores de tu proyecto, consulta Enumerar contenedores. Para saber cómo copiar un objeto en un segmento de Cloud Storage, consulta el artículo Copiar, cambiar de nombre y mover objetos.

Definir una solicitud de importación de extensiones

Después de crear un archivo de especificación de API, puedes definir una solicitud de importación de extensión en un archivo JSON. Una solicitud de importación de una extensión debe contener una referencia al archivo de especificación de la API (apiSpec) y a la configuración de autenticación (authConfig). Para conectar la extensión a un modelo de lenguaje grande (LLM) y ver cómo funciona, incluye el parámetro opcional toolUseExamples. Si solo quieres ejecutar la extensión, no incluyas el parámetro toolUseExamples.

Una solicitud de importación de extensiones tiene el siguiente formato:

{
  "displayName":  "DISPLAY_NAME_HUMAN",
  "description": "DESCRIPTION_HUMAN",
  "manifest": {
    "name": "EXTENSION_NAME_LLM",
    "description": "DESCRIPTION_LLM",
    "apiSpec": { ... },
    "authConfig": { ... },
  }
  "toolUseExamples": [ ... ],
}
  • DISPLAY_NAME_HUMAN: el nombre de la extensión que se muestra a los usuarios.
  • DESCRIPTION_HUMAN: descripción de la extensión que se muestra a los usuarios.
  • EXTENSION_NAME_LLM: nombre de la extensión que usa el LLM para razonar.
  • DESCRIPTION_LLM: la descripción de la extensión que usa el LLM para razonar. Debes proporcionar una descripción significativa e informativa.

Referencia al archivo de especificación de la API

Tu solicitud de importación de extensiones debe contener una referencia a tu archivo de especificación de la API. Puede proporcionar el archivo de especificaciones de dos formas:

  • Usa openApiGcsUri para introducir el URI de Cloud Storage del archivo YAML.

    "apiSpec": {
      "openApiGcsUri": "gs://BUCKET_NAME/SPECIFICATION_FILE_NAME.yaml"
    },
    
    • BUCKET_NAME: Nombre del segmento de Cloud Storage que almacena el archivo de especificación.
    • SPECIFICATION_FILE_NAME: el nombre del archivo de especificación de la API.
  • Usa openApiYaml para introducir el archivo YAML como una cadena.

Configuración de autenticación

Las extensiones pueden ser públicas, disponibles para cualquier usuario, o privadas, disponibles solo para los usuarios autorizados de una o varias organizaciones.

Una solicitud de importación de extensiones debe contener una configuración de autenticación. Puedes elegir entre los siguientes métodos de autenticación:

  • NO_AUTH: sin autenticación
  • API_KEY_AUTH: autenticación con clave de API
  • HTTP_BASIC_AUTH: autenticación básica HTTP
  • OAUTH: autenticación OAuth
  • OIDC_AUTH: autenticación OIDC

Para obtener más información sobre las configuraciones de autenticación, consulta Especificar una configuración de autenticación.

Ejemplos que muestran cómo funciona la extensión

Para obtener los mejores resultados, una solicitud de importación de extensiones debe contener ejemplos que demuestren cómo funciona la extensión. Usa el parámetro toolUseExamples para proporcionar estos ejemplos.

En el siguiente código se muestra el formato de toolUseExamples para un solo ejemplo, con un solo parámetro de entrada y un solo parámetro de salida. En este ejemplo, tanto los parámetros de la solicitud como los de la respuesta son de tipo string.

"toolUseExamples": [
  {
      "extensionOperation": {
        "operationId": "API_SERVICE_OPERATION_ID",
      },
      "displayName": "EXAMPLE_DISPLAY_NAME",
      "query": "EXAMPLE_QUERY",
      "requestParams": {
        "fields": [
          {
            "key": "API_SERVICE_INPUT_VAR",
            "value": {
              "string_value": "EXAMPLE_INPUT",
            }
          }
        ]
      },
      "responseParams": {
        "fields": [
          {
            "key": "API_SERVICE_OUTPUT_VAR",
            "value": {
              "string_value": "EXAMPLE_OUTPUT",
            },
          }
        ],
      },
      "responseSummary": "EXAMPLE_SUMMARY"
    }
],
  • query: ejemplo de una consulta que puede aprovechar esta extensión. Usa EXAMPLE_QUERY para proporcionar el texto de la consulta.
  • extensionOperation: operación de extensión adecuada para responder a la query. Usa API_SERVICE_OPERATION_ID para proporcionar el ID de una operación de extensión definida en el archivo de especificación de la API.
  • displayName: nombre visible del ejemplo. Usa EXAMPLE_DISPLAY_NAME para proporcionar una breve descripción.
  • requestParams: los parámetros de solicitud necesarios para extensionOperation y los valores de ejemplo, en formato de par clave-valor. Usa API_SERVICE_INPUT_VAR para proporcionar un parámetro de entrada que se defina en el archivo de especificación de la API y que corresponda con API_SERVICE_OPERATION_ID. Use EXAMPLE_INPUT para proporcionar un ejemplo de valor de entrada que se corresponda con EXAMPLE_QUERY.
  • responseParams: los parámetros de respuesta de extensionOperation y valores de ejemplo en formato de par clave-valor. Usa API_SERVICE_OUTPUT_VAR para proporcionar un parámetro de salida que se defina en el archivo de especificación de la API y que corresponda con el servicio de la API. Usa EXAMPLE_OUTPUT para proporcionar un ejemplo de valor de salida que se corresponda con EXAMPLE_INPUT.
  • responseSummary: ejemplo de resumen que podría proporcionar la aplicación en respuesta a la query. Usa EXAMPLE_SUMMARY para proporcionar el texto del resumen.

A continuación se muestra un ejemplo de toolUseExamples para un servicio de API que dice "hola" en el idioma solicitado:

"toolUseExamples": [
  {
      "extensionOperation": {
        "operationId": "say_hello",
      },
      "displayName": "Say hello in the requested language",
      "query": "Say hello in French",
      "requestParams": {
        "fields": [
          {
            "key": "apiServicePrompt",
            "value": {
              "string_value": "French",
            }
          }
        ]
      },
      "responseParams": {
        "fields": [
          {
            "key": "apiServiceOutput",
            "value": {
              "string_value": "bonjour",
            },
          }
        ],
      },
      "responseSummary": "Bonjour"
    }
],

Especificar una configuración de autenticación

Debes especificar una configuración de autenticación cuando definas una solicitud de importación de extensiones.

Si tu extensión no requiere autenticación, asigna el valor NO_AUTH a la variable authType:

"authConfig": {
  "authType": "NO_AUTH"
}

Si tu extensión requiere autenticación, debes definir el tipo de autenticación en la variable authType y proporcionar una configuración de autenticación. Puedes elegir entre los siguientes métodos de autenticación:

Autenticación con clave de API

Para admitir la autenticación con claves de API, Vertex AI se integra con SecretManager para almacenar y acceder a secretos. La plataforma Extensiones de Vertex AI no almacena los datos secretos directamente. Es tu responsabilidad gestionar el ciclo de vida de tu recurso SecretManager.

Especifica authConfig de la siguiente manera:

"authConfig": {
  "authType": "API_KEY_AUTH",
  "apiKeyConfig": {
    "name": "API_KEY_CONFIG_NAME",
    "apiKeySecret": "API_KEY_SECRET",
    "httpElementLocation": "HTTP_ELEMENT_LOCATION",
  },
}
  • API_KEY_CONFIG_NAME: el nombre de la clave de API. Por ejemplo, en la solicitud a la API https://example.com/act?api_key=<API KEY>, API_KEY_CONFIG_NAME corresponde a api_key.
  • API_KEY_SECRET: recurso de versión secreta SecretManager que almacena la clave. Este parámetro tiene el siguiente formato: projects/PROJECT_ID/secrets/SECRET_ID/versions/VERSION.
  • HTTP_ELEMENT_LOCATION: la ubicación de la clave de API en la solicitud HTTP. Los valores posibles son:

    • HTTP_IN_QUERY
    • HTTP_IN_HEADER
    • HTTP_IN_PATH
    • HTTP_IN_BODY
    • HTTP_IN_COOKIE

    Para obtener más información, consulta Descripción de los parámetros.

Autenticación básica HTTP

Para admitir la autenticación básica HTTP, Vertex AI se integra con SecretManager para almacenar secretos y acceder a ellos. La plataforma Extensiones de Vertex AI no almacena los datos secretos directamente. Debes gestionar el ciclo de vida de tu recurso SecretManager por tu cuenta.

Especifica authConfig de la siguiente manera:

"authConfig": {
  "authType": "HTTP_BASIC_AUTH",
  "httpBasicAuthConfig": {
    "credentialSecret": "CREDENTIAL_SECRET"
  },
}
  • CREDENTIAL_SECRET: recurso de versión secreta SecretManager que almacena la credencial codificada en base64. Este parámetro tiene el siguiente formato: projects/PROJECT_ID/secrets/SECRET_ID/versions/VERSION.

Autenticación OAuth

Vertex AI admite dos métodos de autenticación OAuth: token de acceso y cuenta de servicio.

Token de acceso

Especifica authConfig de la siguiente manera:

"authConfig": {
  "authType": "OAUTH",
  "oauthConfig": {}
}

Deja el campo oauthConfig en blanco al importar la extensión. Si decides ejecutar una extensión registrada, debes proporcionar un token de acceso en el campo oauthConfig de la solicitud de ejecución. Para obtener más información, consulta Ejecutar la extensión.

Cuenta de servicio

Especifica authConfig de la siguiente manera:

"authConfig": {
  "authType": "OAUTH",
  "oauthConfig": {"service_account": "SERVICE_ACCOUNT_NAME"}
}
  • SERVICE_ACCOUNT_NAME: Vertex AI usa esta cuenta de servicio para generar tokens de acceso.

Sigue estos pasos para permitir que Vertex AI Extension Service Agent obtenga tokens de acceso de SERVICE_ACCOUNT_NAME.

  1. Ve a la página Gestión de identidades y accesos.

    Ir a IAM

  2. Selecciona la pestaña Cuentas de servicio.

  3. Haz clic en tu cuenta de servicio. El valor de SERVICE_ACCOUNT_NAME en authConfig debe corresponderse con el nombre de su cuenta de servicio.

  4. Haz clic en la pestaña Permisos.

  5. Haz clic en Conceder acceso.

  6. En la sección Add principals (Añadir principales), en el campo New principals (Nuevos principales), introduce service-PROJECT_NUMBER@gcp-sa-vertex-ex.iam.gserviceaccount.com. Este principal corresponde a la cuenta de servicio Vertex AI Extension Service Agent.

  7. En la sección Asignar roles, busca y selecciona el rol de Service Account Token Creator. Este rol incluye el permiso iam.serviceAccounts.getAccessToken.

  8. Haz clic en el botón Save (Guardar).

Autenticación OIDC

Vertex AI admite dos métodos de autenticación OIDC: token de ID y cuenta de servicio.

Token de ID

Especifica authConfig de la siguiente manera:

"authConfig": {
  "authType": "OIDC_AUTH",
  "oidcConfig": {}
}

Deja el campo oidcConfig en blanco al importar la extensión. Si decides ejecutar una extensión registrada, debes proporcionar un token de ID en el campo oidcConfig de la solicitud de ejecución. Para obtener más información, consulta Ejecutar la extensión.

Cuenta de servicio

Especifica authConfig de la siguiente manera:

"authConfig": {
  "authType": "OIDC_AUTH",
  "oidcConfig": {"service_account": "SERVICE_ACCOUNT_NAME"}
}
  • SERVICE_ACCOUNT_NAME: Vertex AI usa esta cuenta de servicio para generar tokens OpenID Connect (OIDC). Vertex AI define la audiencia del token como API_SERVICE_URL, tal como se define en el archivo de especificación de la API.

Sigue estos pasos para permitir que Vertex AI Extension Service Agent obtenga tokens de acceso de SERVICE_ACCOUNT_NAME.

  1. Ve a la página Gestión de identidades y accesos.

    Ir a IAM

  2. Selecciona la pestaña Cuentas de servicio.

  3. Haz clic en tu cuenta de servicio. El valor de SERVICE_ACCOUNT_NAME en authConfig debe corresponderse con el nombre de su cuenta de servicio.

  4. Haz clic en la pestaña Permisos.

  5. Haz clic en Conceder acceso.

  6. En la sección Add principals (Añadir principales), en el campo New principals (Nuevos principales), introduce service-PROJECT_NUMBER@gcp-sa-vertex-ex.iam.gserviceaccount.com. Este principal corresponde a la cuenta de servicio Vertex AI Extension Service Agent.

  7. En la sección Asignar roles, busca y selecciona el rol de Service Account Token Creator. Este rol incluye el permiso iam.serviceAccounts.getOpenIdToken.

  8. Haz clic en el botón Save (Guardar).

Importar la extensión con Vertex AI

Después de definir una solicitud de importación de extensión, puedes importar la extensión con Vertex AI.

  1. Define las siguientes variables de shell:

    ENDPOINT="LOCATION-aiplatform.googleapis.com"
    URL="https://${ENDPOINT}/v1beta1/projects/PROJECT_ID/locations/LOCATION"
    
    • PROJECT_ID: tu proyecto.
    • LOCATION: la región que elijas. Si no lo tienes claro, elige us-central1.
  2. Ejecuta el siguiente comando curl para enviar la solicitud de importación:

    curl -X POST \
      -H "Authorization: Bearer $(gcloud auth print-access-token)" \
      -H "Content-Type: application/json; charset=utf-8" \
      -d @IMPORT_REQUEST.json "${URL}/extensions:import"
    

    La respuesta tiene el siguiente formato:

    {
      "name": "projects/[PROJECT_NUMBER]/locations/[LOCATION]/extensions/[EXTENSION_ID]/operations/[IMPORT_OPERATION_ID]",
      "metadata": {
        "@type": "type.googleapis.com/google.cloud.aiplatform.v1beta1.ImportExtensionOperationMetadata",
        "genericMetadata": {
          "createTime": "[CREATE_TIME]",
          "updateTime": "[UPDATE_TIME]"
        }
      }
    }
    
  3. Define variables de shell en función del resultado de la solicitud de importación:

    EXTENSION_ID=EXTENSION_ID
    IMPORT_OPERATION_ID=IMPORT_OPERATION_ID
    
  4. Para comprobar el estado de la importación, ejecuta el siguiente comando curl:

    curl -X GET \
      -H "Authorization: Bearer $(gcloud auth print-access-token)" \
      -H "Content-Type: application/json; charset=utf-8" \
    "${URL}/operations/${IMPORT_OPERATION_ID}"
    

Gestionar extensiones

Para enumerar todas las extensiones registradas, ejecuta el siguiente comando curl:

curl -X GET \
  -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  -H "Content-Type: application/json; charset=utf-8" \
"${URL}/extensions"

Para obtener una extensión, ejecuta el siguiente comando curl:

curl -X GET \
  -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  -H "Content-Type: application/json; charset=utf-8" \
"${URL}/extensions/${EXTENSION_ID}"

Puedes actualizar el displayName, el description o el toolUseExamples de la extensión. Si especificas toolUseExamples al actualizar una extensión, la actualización sustituirá los ejemplos. Por ejemplo, si tienes los ejemplos a y b, y actualizas la extensión con el ejemplo c, la extensión actualizada solo contendrá el ejemplo c.Para actualizar la descripción de una extensión, ejecuta el siguiente comando curl:

curl -X PATCH \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
${URL}/extensions/${EXTENSION_ID}?update_mask="description" \
-d '{
  "description": "A nice tool.",
}'

Para eliminar una extensión, ejecuta el siguiente comando curl:

curl \
 -X DELETE \
 -H "Authorization: Bearer $(gcloud auth print-access-token)" \
 -H "Content-Type: application/json" \
${URL}/extensions/${EXTENSION_ID}

Ejecutar una extensión

Hay dos formas de ejecutar una extensión:

  • execute: este modo se centra únicamente en la ejecución de APIs. La extensión activa la operación de API especificada y devuelve los resultados sin procesar sin ningún otro procesamiento.

  • query: este modo se ha diseñado para ofrecer interacciones inteligentes. Implica varios pasos:

    • Solicitud de modelo: la consulta y el esquema de la extensión se proporcionan a Gemini como petición y FunctionDeclaration, respectivamente.
    • Ejecución de la API: si el modelo determina que es necesario usar una herramienta, la extensión llama automáticamente a la operación de la API en nombre del modelo y obtiene los resultados.
    • Integración del modelo: los resultados de la API se introducen en el modelo, que los procesa para generar la respuesta final, que es pertinente en el contexto. En esencia, query actúa como un agente de una sola herramienta, que usa la API para alcanzar sus objetivos.

En esta sección se describe cómo execute una extensión.

Si tu extensión usa la autenticación OAuth y un token de acceso, consulta Ejecutar una extensión con autenticación OAuth y un token de acceso.

Si tu extensión usa la autenticación OIDC y un token de ID, consulta Ejecutar una extensión con autenticación OIDC y un token de ID.

De lo contrario, puedes ejecutarlo siguiendo estos pasos:

  1. Crea un archivo llamado execute-extension.json con el siguiente contenido:

    {
      "operation_id": "API_SERVICE_OPERATION_ID",
      "operation_params": {
        "API_SERVICE_INPUT_VAR": "API_SERVICE_INPUT_VALUE"
      }
    }
    
    • API_SERVICE_OPERATION_ID: el ID de la operación del servicio de la API que quieres ejecutar. Las operaciones de servicio de la API se definen en el archivo de especificación de la API.
    • API_SERVICE_INPUT_VAR: variable de entrada que se corresponde con API_SERVICE_OPERATION_ID y que se define en el archivo de especificación de la API.
    • API_SERVICE_INPUT_VALUE: valor de entrada de la extensión.
  2. Ejecuta el siguiente comando curl:

    curl \
      -H "Authorization: Bearer $(gcloud auth print-access-token)" \
      -H "Content-Type: application/json; charset=utf-8" -d @execute-extension.json \
    "${URL}/extensions/${EXTENSION_ID}:execute"
    

    La respuesta tiene el siguiente formato:

    {
      "output": {
        "content": "{\"API_SERVICE_OUTPUT_VAR\": \"API_SERVICE_OUTPUT_VALUE\"}"
      }
    }
    
    • API_SERVICE_OUTPUT_VAR: parámetro de salida definido en el archivo de especificación de la API que corresponde al servicio de la API.
    • API_SERVICE_OUTPUT_VALUE: valor de cadena que es una serialización del objeto de respuesta. Si el archivo de especificación de la API define un esquema de respuesta JSON, debes analizar esta cadena de salida en JSON por tu cuenta.

Ejecutar una extensión con autenticación OAuth y un token de acceso

Si tu extensión usa la autenticación OAuth y un token de acceso, puedes ejecutarla siguiendo estos pasos:

  1. Crea un archivo llamado execute-extension.json con el siguiente contenido:

    {
      "operation_id": "API_SERVICE_OPERATION_ID",
      "operation_params": {...},
      "runtime_auth_config": {
        "authType": "OAUTH",
        "oauth_config": {"access_token": "'$(gcloud auth print-access-token)'"}
      }
    }
    
    • API_SERVICE_OPERATION_ID: el ID de la operación del servicio de la API que quieres ejecutar. Las operaciones de servicio de la API se definen en el archivo de especificación de la API.
  2. Ejecuta el siguiente comando curl:

    curl \
      -H "Authorization: Bearer $(gcloud auth print-access-token)" \
      -H "Content-Type: application/json; charset=utf-8" -d @execute-extension.json \
    "${URL}/extensions/${EXTENSION_ID}:execute"
    

Ejecutar una extensión con autenticación OIDC y un token de ID

Si tu extensión usa la autenticación OIDC y un token de ID, puedes ejecutarla siguiendo estos pasos:

  1. Crea un archivo llamado execute-extension.json con el siguiente contenido:

    {
      "operation_id": "API_SERVICE_OPERATION_ID",
      "operation_params": {...},
      "runtime_auth_config": {
        "authType": "OIDC_AUTH",
        "oidc_config": {"id_token": "$(gcloud auth print-identity-token)"}
      }
    }
    
    • API_SERVICE_OPERATION_ID: el ID de la operación del servicio de la API que quieres ejecutar. Las operaciones de servicio de la API se definen en el archivo de especificación de la API.
  2. Ejecuta el siguiente comando curl:

    curl \
      -H "Authorization: Bearer $(gcloud auth print-access-token)" \
      -H "Content-Type: application/json; charset=utf-8" -d @execute-extension.json \
    "${URL}/extensions/${EXTENSION_ID}:execute"
    

Siguientes pasos