Crear un agente de datos con el SDK de Python

En esta página se muestra cómo usar el SDK de Python para enviar solicitudes a la API Conversational Analytics. En el código de ejemplo de Python se muestra cómo completar las siguientes tareas:

Autenticar y configurar el entorno

Para usar el SDK de Python de la API Conversational Analytics, sigue las instrucciones del notebook de Colaboratory del SDK de la API Conversational Analytics para descargar e instalar el SDK. Ten en cuenta que el método de descarga y el contenido del SDK Colab pueden cambiar.

Una vez que hayas completado las instrucciones de configuración del cuaderno, puedes usar el siguiente código para importar las bibliotecas del SDK necesarias, autenticar tu cuenta de Google en un entorno de Colaboratory e inicializar un cliente para hacer solicitudes de API:

from google.colab import auth
auth.authenticate_user()

from google.cloud import geminidataanalytics

data_agent_client = geminidataanalytics.DataAgentServiceClient()
data_chat_client = geminidataanalytics.DataChatServiceClient()

Especifica el proyecto de facturación y las instrucciones del sistema

El siguiente código de Python de ejemplo define el proyecto de facturación y las instrucciones del sistema que se utilizan en toda la secuencia de comandos:

# Billing project
billing_project = "my_project_name"

# System instructions
system_instruction = "Help the user analyze their data."

Sustituye los valores de ejemplo de la siguiente manera:

  • my_project_name: el ID de tu proyecto de facturación que tiene las APIs necesarias habilitadas.
  • Help the user analyze their data.: instrucciones del sistema para guiar el comportamiento del agente y personalizarlo según tus necesidades de datos. Por ejemplo, puedes usar instrucciones del sistema para definir términos empresariales, controlar la longitud de las respuestas o definir el formato de los datos. Lo ideal es definir las instrucciones del sistema con el formato YAML recomendado en Escribir instrucciones del sistema eficaces para proporcionar directrices detalladas y estructuradas.

Conectarse a una fuente de datos

En las siguientes secciones se muestra cómo definir los detalles de conexión de las fuentes de datos de tu agente. Tu agente puede conectarse a datos de Looker, BigQuery o Looker Studio.

Conectarse a datos de Looker

En los siguientes ejemplos de código se muestra cómo definir los detalles de una conexión a una exploración de Looker con claves de API o un token de acceso. Con la API Conversational Analytics, solo puedes conectarte a una Exploración de Looker a la vez.

Claves de API

Puedes establecer una conexión con una instancia de Looker con las claves de API de Looker generadas, tal como se describe en el artículo Autenticar y conectar con una fuente de datos con la API Conversational Analytics.

looker_client_id = "my_looker_client_id"
looker_client_secret = "my_looker_client_secret"
looker_instance_uri = "https://my_company.looker.com"
lookml_model = "my_model"
explore = "my_explore"

looker_explore_reference = geminidataanalytics.LookerExploreReference()
looker_explore_reference.looker_instance_uri = looker_instance_uri
looker_explore_reference.lookml_model = lookml_model
looker_explore_reference.explore = explore

credentials = geminidataanalytics.Credentials()
credentials.oauth.secret.client_id = looker_client_id
credentials.oauth.secret.client_secret = looker_client_secret

datasource_references = geminidataanalytics.DatasourceReferences()
datasource_references.looker.explore_references = [looker_explore_reference]

# Do not include the following line during agent creation
datasource_references.credentials = credentials

Sustituye los valores de ejemplo de la siguiente manera:

  • my_looker_client_id: el ID de cliente de la clave de API de Looker que has generado.
  • my_looker_client_secret: el secreto de cliente de la clave de API de Looker que has generado.
  • https://my_company.looker.com: URL completa de su instancia de Looker.
  • my_model: nombre del modelo de LookML que incluye la Exploración a la que quieres conectarte.
  • my_explore: el nombre de la Exploración de Looker que quieres que consulte el agente de datos.

Token de acceso

Puedes establecer una conexión con una instancia de Looker mediante un token de acceso, tal como se describe en el artículo Autenticar y conectar con una fuente de datos mediante la API Conversational Analytics.

looker_access_token = "my_access_token"
looker_instance_uri = "https://my_company.looker.com"
lookml_model = "my_model"
explore = "my_explore"

looker_explore_reference = geminidataanalytics.LookerExploreReference()
looker_explore_reference.looker_instance_uri = looker_instance_uri
looker_explore_reference.lookml_model = lookml_model
looker_explore_reference.explore = explore

credentials = geminidataanalytics.Credentials()
credentials.oauth.token.access_token = looker_access_token

datasource_references = geminidataanalytics.DatasourceReferences()
datasource_references.looker.explore_references = [looker_explore_reference]

# Do not include the following line during agent creation
datasource_references.credentials = credentials

Sustituye los valores de ejemplo de la siguiente manera:

  • my_access_token: el valor access_token que generas para autenticarte en Looker.
  • https://my_company.looker.com: URL completa de su instancia de Looker.
  • my_model: nombre del modelo de LookML que incluye la Exploración a la que quieres conectarte.
  • my_explore: el nombre de la Exploración de Looker que quieres que consulte el agente de datos.

Conectar con datos de BigQuery

Con la API Conversational Analytics, no hay límites estrictos en el número de tablas de BigQuery a las que puede conectarse. Sin embargo, si te conectas a un gran número de tablas, puede que la precisión se reduzca o que superes el límite de tokens de entrada del modelo.

El siguiente código de ejemplo define una conexión a varias tablas de BigQuery.

bigquery_table_reference = geminidataanalytics.BigQueryTableReference()
bigquery_table_reference.project_id = "my_project_id"
bigquery_table_reference.dataset_id = "my_dataset_id"
bigquery_table_reference.table_id = "my_table_id"

bigquery_table_reference_2 = geminidataanalytics.BigQueryTableReference()
bigquery_table_reference_2.project_id = "my_project_id_2"
bigquery_table_reference_2.dataset_id = "my_dataset_id_2"
bigquery_table_reference_2.table_id = "my_table_id_2"

bigquery_table_reference_3 = geminidataanalytics.BigQueryTableReference()
bigquery_table_reference_3.project_id = "my_project_id_3"
bigquery_table_reference_3.dataset_id = "my_dataset_id_3"
bigquery_table_reference_3.table_id = "my_table_id_3"

# Connect to your data source
datasource_references = geminidataanalytics.DatasourceReferences()
datasource_references.bq.table_references = [bigquery_table_reference, bigquery_table_reference_2, bigquery_table_reference_3]

Sustituye los valores de ejemplo de la siguiente manera:

  • my_project_id: ID del Google Cloud proyecto que contiene el conjunto de datos y la tabla de BigQuery a los que quiere conectarse. Para conectarte a un conjunto de datos público, especifica bigquery-public-data.
  • my_dataset_id: ID del conjunto de datos de BigQuery. Por ejemplo, san_francisco.
  • my_table_id: el ID de la tabla de BigQuery. Por ejemplo, street_trees.

Conectarse a datos de Looker Studio

El siguiente código de ejemplo define una conexión a una fuente de datos de Looker Studio.

studio_datasource_id = "my_datasource_id"

studio_references = geminidataanalytics.StudioDatasourceReference()
studio_references.datasource_id = studio_datasource_id

## Connect to your data source
datasource_references.studio.studio_references = [studio_references]

En el ejemplo anterior, sustituye my_datasource_id por el ID de la fuente de datos.

Configurar el contexto de una conversación con o sin reconocimiento del estado

La API Conversational Analytics admite conversaciones de varios turnos, lo que permite a los usuarios hacer preguntas de seguimiento que se basan en el contexto anterior. En el siguiente ejemplo de código de Python se muestra cómo configurar el contexto para una conversación con estado o sin estado:

  • Chat con estado: Google Cloud almacena y gestiona el historial de la conversación. El chat con estado es inherentemente de varias interacciones, ya que la API conserva el contexto de los mensajes anteriores. Solo tienes que enviar el mensaje actual en cada turno.
  • Chat sin estado: tu aplicación gestiona el historial de conversaciones. Debes incluir todo el historial de la conversación en cada mensaje nuevo. Para ver ejemplos detallados sobre cómo gestionar conversaciones de varios turnos en modo sin estado, consulta Crear una conversación de varios turnos sin estado.

Chat con estado

El siguiente código de ejemplo configura el contexto de una conversación con estado, donde Google Cloud almacena y gestiona el historial de la conversación. También puedes habilitar el análisis avanzado con Python incluyendo la línea published_context.options.analysis.python.enabled = True en el siguiente código de ejemplo.

# Set up context for stateful chat
published_context = geminidataanalytics.Context()
published_context.system_instruction = system_instruction
published_context.datasource_references = datasource_references
# Optional: To enable advanced analysis with Python, include the following line:
published_context.options.analysis.python.enabled = True

Chat sin estado

El siguiente código de ejemplo configura el contexto de una conversación sin estado, en la que debes enviar todo el historial de la conversación con cada mensaje. También puedes habilitar el análisis avanzado con Python incluyendo la línea inline_context.options.analysis.python.enabled = True en el siguiente código de ejemplo.

# Set up context for stateless chat
# datasource_references.looker.credentials = credentials
inline_context = geminidataanalytics.Context()
inline_context.system_instruction = system_instruction
inline_context.datasource_references = datasource_references
# Optional: To enable advanced analysis with Python, include the following line:
inline_context.options.analysis.python.enabled = True

Crear un agente de datos

El siguiente código de ejemplo de Python hace una solicitud a la API para crear un agente de datos, que puedes usar para mantener una conversación sobre tus datos. El agente de datos se configura con la fuente de datos, las instrucciones del sistema y el contexto especificados.

data_agent_id = "data_agent_1"

data_agent = geminidataanalytics.DataAgent()
data_agent.data_analytics_agent.published_context = published_context
data_agent.name = f"projects/{billing_project}/locations/global/dataAgents/{data_agent_id}" # Optional

request = geminidataanalytics.CreateDataAgentRequest(
    parent=f"projects/{billing_project}/locations/global",
    data_agent_id=data_agent_id, # Optional
    data_agent=data_agent,
)

try:
    data_agent_client.create_data_agent(request=request)
    print("Data Agent created")
except Exception as e:
    print(f"Error creating Data Agent: {e}")

En el ejemplo anterior, sustituya el valor data_agent_1 por un identificador único del agente de datos.

Crear una conversación

El siguiente código de Python de ejemplo hace una solicitud a la API para crear una conversación.

# Initialize request arguments
data_agent_id = "data_agent_1"
conversation_id = "conversation_1"

conversation = geminidataanalytics.Conversation()
conversation.agents = [f'projects/{billing_project}/locations/global/dataAgents/{data_agent_id}']
conversation.name = f"projects/{billing_project}/locations/global/conversations/{conversation_id}"

request = geminidataanalytics.CreateConversationRequest(
    parent=f"projects/{billing_project}/locations/global",
    conversation_id=conversation_id,
    conversation=conversation,
)

# Make the request
response = data_chat_client.create_conversation(request=request)

# Handle the response
print(response)

Sustituye los valores de ejemplo de la siguiente manera:

  • data_agent_1: el ID del agente de datos, tal como se define en el bloque de código de ejemplo de Crear un agente de datos.
  • conversation_1: identificador único de la conversación.

Gestionar agentes de datos y conversaciones

Los siguientes ejemplos de código muestran cómo gestionar tus agentes de datos y conversaciones mediante la API Conversational Analytics. Puedes realizar las siguientes tareas:

Obtener un agente de datos

En el siguiente código de ejemplo de Python se muestra cómo hacer una solicitud a la API para recuperar un agente de datos que hayas creado anteriormente.

# Initialize request arguments
data_agent_id = "data_agent_1"
request = geminidataanalytics.GetDataAgentRequest(
    name=f"projects/{billing_project}/locations/global/dataAgents/{data_agent_id}",
)

# Make the request
response = data_agent_client.get_data_agent(request=request)

# Handle the response
print(response)

En el ejemplo anterior, sustituya el valor data_agent_1 por el identificador único del agente de datos que quiera recuperar.

Mostrar agentes de datos

En el siguiente código se muestra cómo enumerar todos los agentes de datos de un proyecto determinado llamando al método list_data_agents. Para ver todos los agentes, debes tener el permiso geminidataanalytics.dataAgents.list en el proyecto. Para obtener más información sobre qué roles de gestión de identidades y accesos incluyen este permiso, consulta la lista de roles predefinidos.

billing_project = "YOUR-BILLING-PROJECT"
location = "global"
request = geminidataanalytics.ListDataAgentsRequest(
    parent=f"projects/{billing_project}/locations/global",
)

# Make the request
page_result = data_agent_client.list_data_agents(request=request)

# Handle the response
for response in page_result:
    print(response)

Sustituye YOUR-BILLING-PROJECT por el ID de tu proyecto de facturación.

Mostrar agentes de datos accesibles

En el siguiente código se muestra cómo enumerar todos los agentes de datos accesibles de un proyecto determinado llamando al método list_accessible_data_agents.

billing_project = "YOUR-BILLING-PROJECT"
creator_filter = "YOUR-CREATOR-FILTER"
location = "global"
request = geminidataanalytics.ListAccessibleDataAgentsRequest(
    parent=f"projects/{billing_project}/locations/global",
    creator_filter=creator_filter
)

# Make the request
page_result = data_agent_client.list_accessible_data_agents(request=request)

# Handle the response
for response in page_result:
    print(response)

Sustituye los valores de ejemplo de la siguiente manera:

  • YOUR-BILLING-PROJECT: el ID de tu proyecto de facturación.
  • YOUR-CREATOR-FILTER: el filtro que se va a aplicar en función del creador del agente de datos. Los valores posibles son NONE (predeterminado), CREATOR_ONLY y NOT_CREATOR_ONLY.

Actualizar un agente de datos

En el siguiente código de ejemplo se muestra cómo actualizar un agente de datos llamando al método update_data_agent en el recurso del agente de datos. La solicitud requiere un objeto DataAgent que incluya los nuevos valores de los campos que quiera cambiar y un parámetro update_mask que tome un objeto FieldMask para especificar qué campos se deben actualizar.

Para actualizar un agente de datos, debes tener el permiso de gestión de identidades y accesos geminidataanalytics.dataAgents.update en el agente. Para obtener más información sobre qué roles de gestión de identidades y accesos incluyen este permiso, consulta la lista de roles predefinidos.

data_agent_id = "data_agent_1"
billing_project = "YOUR-BILLING-PROJECT"
data_agent = geminidataanalytics.DataAgent()
data_agent.data_analytics_agent.published_context = published_context
data_agent.name = f"projects/{billing_project}/locations/global/dataAgents/{data_agent_id}"
data_agent.description = "Updated description of the data agent."

update_mask = field_mask_pb2.FieldMask(paths=['description', 'data_analytics_agent.published_context'])

request = geminidataanalytics.UpdateDataAgentRequest(
    data_agent=data_agent,
    update_mask=update_mask,
)

try:
    # Make the request
    data_agent_client.update_data_agent(request=request)
    print("Data Agent Updated")
except Exception as e:
    print(f"Error updating Data Agent: {e}")

Sustituye los valores de ejemplo de la siguiente manera:

  • data_agent_1: el ID del agente de datos que quieres actualizar.
  • YOUR-BILLING-PROJECT: el ID de tu proyecto de facturación.
  • Updated description of the data agent.: descripción del agente de datos actualizado.

Definir la política de gestión de identidades y accesos de un agente de datos

Para compartir un agente, puedes usar el método set_iam_policy para asignar roles de gestión de identidades y accesos a los usuarios de un agente específico. La solicitud incluye enlaces que especifican qué roles se deben asignar a qué usuarios.

.
billing_project = "YOUR-BILLING-PROJECT"
location = "global"
data_agent_id = "data_agent_1"
role = "roles/geminidataanalytics.dataAgentEditor"
users = "222larabrown@gmail.com, cloudysanfrancisco@gmail.com"

resource = f"projects/{billing_project}/locations/global/dataAgents/{data_agent_id}"

# Construct the IAM policy
binding = policy_pb2.Binding(
    role=role,
    members= [f"user:{i.strip()}" for i in users.split(",")]
)

policy = policy_pb2.Policy(bindings=[binding])

# Create the request
request = iam_policy_pb2.SetIamPolicyRequest(
    resource=resource,
    policy=policy
)

# Send the request
try:
    response = data_agent_client.set_iam_policy(request=request)
    print("IAM Policy set successfully!")
    print(f"Response: {response}")
except Exception as e:
    print(f"Error setting IAM policy: {e}")

Sustituye los valores de ejemplo de la siguiente manera:

  • YOUR-BILLING-PROJECT: el ID de tu proyecto de facturación.
  • data_agent_1: el ID del agente de datos para el que quieres definir la política de gestión de identidades y accesos.
  • 222larabrown@gmail.com, cloudysanfrancisco@gmail.com: lista separada por comas de las direcciones de correo de los usuarios a los que quieres asignar el rol especificado.

Obtener la política de gestión de identidades y accesos de un agente de datos

El siguiente código de muestra muestra cómo usar el método get_iam_policy para obtener la política de IAM de un agente de datos. La solicitud especifica la ruta del recurso del agente de datos.

billing_project = "YOUR-BILLING-PROJECT"
location = "global"
data_agent_id = "data_agent_1"

resource = f"projects/{billing_project}/locations/global/dataAgents/{data_agent_id}"
request = iam_policy_pb2.GetIamPolicyRequest(
            resource=resource,
        )
try:
    response = data_agent_client.get_iam_policy(request=request)
    print("IAM Policy fetched successfully!")
    print(f"Response: {response}")
except Exception as e:
    print(f"Error setting IAM policy: {e}")

Sustituye los valores de ejemplo de la siguiente manera:

  • YOUR-BILLING-PROJECT: el ID de tu proyecto de facturación.
  • data_agent_1: el ID del agente de datos del que quiere obtener la política de gestión de identidades y accesos.

Eliminar un agente de datos

El siguiente código de muestra muestra cómo usar el método delete_data_agent para eliminar de forma lógica un agente de datos. Cuando eliminas un agente de forma no definitiva, se elimina, pero se puede recuperar en un plazo de 30 días. La solicitud especifica la URL del recurso del agente de datos.

billing_project = "YOUR-BILLING-PROJECT"
location = "global"
data_agent_id = "data_agent_1"

request = geminidataanalytics.DeleteDataAgentRequest(
    name=f"projects/{billing_project}/locations/global/dataAgents/{data_agent_id}",
)

try:
    # Make the request
    data_agent_client.delete_data_agent(request=request)
    print("Data Agent Deleted")
except Exception as e:
    print(f"Error deleting Data Agent: {e}")

Sustituye los valores de ejemplo de la siguiente manera:

  • YOUR-BILLING-PROJECT: el ID de tu proyecto de facturación.
  • data_agent_1: el ID del agente de datos que quieres eliminar.

Obtener una conversación

En el siguiente código de muestra se indica cómo usar el método get_conversation para obtener información sobre una conversación. La solicitud especifica la ruta del recurso de conversación.

billing_project = "YOUR-BILLING-PROJECT"
location = "global"
conversation_id = "conversation_1"

request = geminidataanalytics.GetConversationRequest(
    name = f"projects/{billing_project}/locations/global/conversations/{conversation_id}"
)

# Make the request
response = data_chat_client.get_conversation(request=request)

# Handle the response
print(response)

Sustituye los valores de ejemplo de la siguiente manera:

  • YOUR-BILLING-PROJECT: el ID de tu proyecto de facturación.
  • conversation_1: el ID de la conversación que quieres obtener.

Mostrar conversaciones

En el siguiente ejemplo de código se muestra cómo enumerar las conversaciones de un proyecto determinado llamando al método list_conversations. La solicitud especifica la URL del recurso superior, que es el proyecto y la ubicación (por ejemplo, projects/my-project/locations/global).

De forma predeterminada, este método devuelve las conversaciones que has creado. Los administradores (usuarios con el rol de gestión de identidades y accesos cloudaicompanion.topicAdmin) pueden ver todas las conversaciones del proyecto.

billing_project = "YOUR-BILLING-PROJECT"
location = "global"
request = geminidataanalytics.ListConversationsRequest(
    parent=f"projects/{billing_project}/locations/global",
)

# Make the request
response = data_chat_client.list_conversations(request=request)

# Handle the response
print(response)

Sustituye YOUR-BILLING-PROJECT por el ID del proyecto de facturación en el que has habilitado las APIs necesarias.

Listar los mensajes de una conversación

En el siguiente código de ejemplo se muestra cómo usar el método list_messages para obtener todos los mensajes de una conversación. La solicitud especifica la ruta del recurso de conversación.

Para ver los mensajes, debes tener el permiso cloudaicompanion.topics.get en la conversación.

billing_project = "YOUR-BILLING-PROJECT"
location = "global"

conversation_id = "conversation_1"

request = geminidataanalytics.ListMessagesRequest(
    parent=f"projects/{billing_project}/locations/global/conversations/{conversation_id}",
)

# Make the request
response = data_chat_client.list_messages(request=request)

# Handle the response
print(response)

Sustituye los valores de ejemplo de la siguiente manera:

  • YOUR-BILLING-PROJECT: el ID de tu proyecto de facturación.
  • conversation_1: el ID de la conversación de la que quieres obtener una lista de mensajes.

Usar la API para hacer preguntas

Después de crear un agente de datos y una conversación, el siguiente código de Python de ejemplo envía una consulta al agente. El código usa el contexto que configures para el chat con o sin estado. La API devuelve un flujo de mensajes que representan los pasos que sigue el agente para responder a la consulta.

Chat con estado

Enviar una solicitud de chat con estado con una referencia Conversation

Puedes enviar una solicitud de chat con estado al agente de datos haciendo referencia a un recurso Conversation que hayas creado anteriormente.

# Create a request that contains a single user message (your question)
question = "Which species of tree is most prevalent?"
messages = [geminidataanalytics.Message()]
messages[0].user_message.text = question

data_agent_id = "data_agent_1"
conversation_id = "conversation_1"

# Create a conversation_reference
conversation_reference = geminidataanalytics.ConversationReference()
conversation_reference.conversation = f"projects/{billing_project}/locations/global/conversations/{conversation_id}"
conversation_reference.data_agent_context.data_agent = f"projects/{billing_project}/locations/global/dataAgents/{data_agent_id}"
# conversation_reference.data_agent_context.credentials = credentials

# Form the request
request = geminidataanalytics.ChatRequest(
    parent = f"projects/{billing_project}/locations/global",
    messages = messages,
    conversation_reference = conversation_reference
)

# Make the request
stream = data_chat_client.chat(request=request)

# Handle the response
for response in stream:
    show_message(response)

Sustituye los valores de ejemplo de la siguiente manera:

  • Which species of tree is most prevalent?: pregunta en lenguaje natural que se envía al agente de datos.
  • data_agent_1: identificador único del agente de datos, tal como se define en Crear un agente de datos.
  • conversation_1: identificador único de la conversación, tal como se define en Crear una conversación.

Chat sin estado

En los siguientes ejemplos de código se muestra cómo enviar una consulta al agente de datos cuando hayas configurado el contexto de una conversación sin estado. Puedes enviar consultas sin estado haciendo referencia a un recurso DataAgent definido anteriormente o usando el contexto insertado en la solicitud.

Enviar una solicitud de chat sin estado con una referencia DataAgent

Puedes enviar una consulta al agente de datos haciendo referencia a un recurso DataAgent que hayas creado anteriormente.

# Create a request that contains a single user message (your question)
question = "Which species of tree is most prevalent?"
messages = [geminidataanalytics.Message()]
messages[0].user_message.text = question

data_agent_id = "data_agent_1"

data_agent_context = geminidataanalytics.DataAgentContext()
data_agent_context.data_agent = f"projects/{billing_project}/locations/global/dataAgents/{data_agent_id}"
# data_agent_context.credentials = credentials

# Form the request
request = geminidataanalytics.ChatRequest(
    parent=f"projects/{billing_project}/locations/global",
    messages=messages,
    data_agent_context = data_agent_context
)

# Make the request
stream = data_chat_client.chat(request=request)

# Handle the response
for response in stream:
    show_message(response)

Sustituye los valores de ejemplo de la siguiente manera:

  • Which species of tree is most prevalent?: pregunta en lenguaje natural que se envía al agente de datos.
  • data_agent_1: identificador único del agente de datos, tal como se define en Crear un agente de datos.

Enviar una solicitud de chat sin estado con contexto insertado

El siguiente código de ejemplo muestra cómo usar el parámetro inline_context para proporcionar contexto directamente en tu solicitud de chat sin estado.

# Create a request that contains a single user message (your question)
question = "Which species of tree is most prevalent?"
messages = [geminidataanalytics.Message()]
messages[0].user_message.text = question

request = geminidataanalytics.ChatRequest(
    inline_context=inline_context,
    parent=f"projects/{billing_project}/locations/global",
    messages=messages,
)

# Make the request
stream = data_chat_client.chat(request=request)

# Handle the response
for response in stream:
    show_message(response)

En el ejemplo anterior, sustituye Which species of tree is most prevalent? por una pregunta en lenguaje natural para enviarla al agente de datos.

Crear una conversación de varios turnos sin estado

Para hacer preguntas de seguimiento en una conversación sin estado, tu aplicación debe gestionar el contexto de la conversación enviando todo el historial de mensajes con cada nueva solicitud. En el siguiente ejemplo se muestra cómo crear una conversación de varios turnos haciendo referencia a un agente de datos o usando el contexto insertado para proporcionar la fuente de datos directamente.

# List that is used to track previous turns and is reused across requests
conversation_messages = []

data_agent_id = "data_agent_1"

# Use data agent context
data_agent_context = geminidataanalytics.DataAgentContext()
data_agent_context.data_agent = f"projects/{billing_project}/locations/global/dataAgents/{data_agent_id}"
# data_agent_context.credentials = credentials

# Helper function for calling the API
def multi_turn_Conversation(msg):

    message = geminidataanalytics.Message()
    message.user_message.text = msg

    # Send a multi-turn request by including previous turns and the new message
    conversation_messages.append(message)

    request = geminidataanalytics.ChatRequest(
        parent=f"projects/{billing_project}/locations/global",
        messages=conversation_messages,
        # Use data agent context
        data_agent_context=data_agent_context,
        # Use inline context
        # inline_context=inline_context,
    )

    # Make the request
    stream = data_chat_client.chat(request=request)

    # Handle the response
    for response in stream:
      show_message(response)
      conversation_messages.append(response)

# Send the first turn request
multi_turn_Conversation("Which species of tree is most prevalent?")

# Send follow-up turn request
multi_turn_Conversation("Can you show me the results as a bar chart?")

En el ejemplo anterior, sustituye los valores de ejemplo de la siguiente manera:

  • data_agent_1: identificador único del agente de datos, tal como se define en el bloque de código de ejemplo de Crear un agente de datos.
  • Which species of tree is most prevalent?: pregunta en lenguaje natural que se envía al agente de datos.
  • Can you show me the results as a bar chart?: una pregunta de seguimiento que se basa en la pregunta anterior o la mejora.

Definir funciones auxiliares

El siguiente código de ejemplo contiene definiciones de funciones auxiliares que se utilizan en los ejemplos de código anteriores. Estas funciones ayudan a analizar la respuesta de la API y a mostrar los resultados.

from pygments import highlight, lexers, formatters
import pandas as pd
import requests
import json as json_lib
import altair as alt
import IPython
from IPython.display import display, HTML

import proto
from google.protobuf.json_format import MessageToDict, MessageToJson

def handle_text_response(resp):
  parts = getattr(resp, 'parts')
  print(''.join(parts))

def display_schema(data):
  fields = getattr(data, 'fields')
  df = pd.DataFrame({
    "Column": map(lambda field: getattr(field, 'name'), fields),
    "Type": map(lambda field: getattr(field, 'type'), fields),
    "Description": map(lambda field: getattr(field, 'description', '-'), fields),
    "Mode": map(lambda field: getattr(field, 'mode'), fields)
  })
  display(df)

def display_section_title(text):
  display(HTML('<h2>{}</h2>'.format(text)))

def format_looker_table_ref(table_ref):
 return 'lookmlModel: {}, explore: {}, lookerInstanceUri: {}'.format(table_ref.lookml_model, table_ref.explore, table_ref.looker_instance_uri)

def format_bq_table_ref(table_ref):
  return '{}.{}.{}'.format(table_ref.project_id, table_ref.dataset_id, table_ref.table_id)

def display_datasource(datasource):
  source_name = ''
  if 'studio_datasource_id' in datasource:
   source_name = getattr(datasource, 'studio_datasource_id')
  elif 'looker_explore_reference' in datasource:
   source_name = format_looker_table_ref(getattr(datasource, 'looker_explore_reference'))
  else:
    source_name = format_bq_table_ref(getattr(datasource, 'bigquery_table_reference'))

  print(source_name)
  display_schema(datasource.schema)

def handle_schema_response(resp):
  if 'query' in resp:
    print(resp.query.question)
  elif 'result' in resp:
    display_section_title('Schema resolved')
    print('Data sources:')
    for datasource in resp.result.datasources:
      display_datasource(datasource)

def handle_data_response(resp):
  if 'query' in resp:
    query = resp.query
    display_section_title('Retrieval query')
    print('Query name: {}'.format(query.name))
    print('Question: {}'.format(query.question))
    print('Data sources:')
    for datasource in query.datasources:
      display_datasource(datasource)
  elif 'generated_sql' in resp:
    display_section_title('SQL generated')
    print(resp.generated_sql)
  elif 'result' in resp:
    display_section_title('Data retrieved')

    fields = [field.name for field in resp.result.schema.fields]
    d = {}
    for el in resp.result.data:
      for field in fields:
        if field in d:
          d[field].append(el[field])
        else:
          d[field] = [el[field]]

    display(pd.DataFrame(d))

def handle_chart_response(resp):
  def _value_to_dict(v):
    if isinstance(v, proto.marshal.collections.maps.MapComposite):
      return _map_to_dict(v)
    elif isinstance(v, proto.marshal.collections.RepeatedComposite):
      return [_value_to_dict(el) for el in v]
    elif isinstance(v, (int, float, str, bool)):
      return v
    else:
      return MessageToDict(v)

  def _map_to_dict(d):
    out = {}
    for k in d:
      if isinstance(d[k], proto.marshal.collections.maps.MapComposite):
        out[k] = _map_to_dict(d[k])
      else:
        out[k] = _value_to_dict(d[k])
    return out

  if 'query' in resp:
    print(resp.query.instructions)
  elif 'result' in resp:
    vegaConfig = resp.result.vega_config
    vegaConfig_dict = _map_to_dict(vegaConfig)
    alt.Chart.from_json(json_lib.dumps(vegaConfig_dict)).display();

def show_message(msg):
  m = msg.system_message
  if 'text' in m:
    handle_text_response(getattr(m, 'text'))
  elif 'schema' in m:
    handle_schema_response(getattr(m, 'schema'))
  elif 'data' in m:
    handle_data_response(getattr(m, 'data'))
  elif 'chart' in m:
    handle_chart_response(getattr(m, 'chart'))
  print('\n')