Tạo tác nhân dữ liệu bằng SDK Python

Trang này hướng dẫn bạn cách sử dụng SDK Python để gửi yêu cầu đến API Phân tích cuộc trò chuyện. Mã Python mẫu minh hoạ cách hoàn thành các nhiệm vụ sau:

Xác thực và thiết lập môi trường

Để sử dụng SDK Python cho API Phân tích trò chuyện, hãy làm theo hướng dẫn trong sổ tay Colaboratory SDK API Phân tích trò chuyện để tải xuống và cài đặt SDK. Xin lưu ý rằng phương thức tải xuống và nội dung của SDK Colab có thể thay đổi.

Sau khi hoàn tất hướng dẫn thiết lập trong sổ tay, bạn có thể sử dụng mã sau để nhập các thư viện SDK bắt buộc, xác thực Tài khoản Google của bạn trong môi trường Colaboratory và khởi chạy ứng dụng để tạo yêu cầu API:

from google.colab import auth
auth.authenticate_user()

from google.cloud import geminidataanalytics

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

Chỉ định dự án thanh toán và hướng dẫn hệ thống

Mã Python mẫu sau đây xác định dự án thanh toán và hướng dẫn hệ thống được sử dụng trong toàn bộ tập lệnh:

# Billing project
billing_project = "my_project_name"

# System description
system_description = "Help the user analyze their data."

Thay thế các giá trị mẫu như sau:

  • my_project_name: Mã của dự án thanh toán đã bật các API bắt buộc.
  • Help the user analyze their data.: Hướng dẫn hệ thống để hướng dẫn hành vi của tác nhân và tuỳ chỉnh tác nhân cho nhu cầu của bạn. Ví dụ: bạn có thể sử dụng hướng dẫn của hệ thống để xác định các thuật ngữ kinh doanh (chẳng hạn như tiêu chí để trở thành "khách hàng thân thiết"), kiểm soát độ dài câu trả lời ("tóm tắt trong ít hơn 20 từ") hoặc thiết lập định dạng dữ liệu ("phù hợp với tiêu chuẩn của công ty").

Kết nối với nguồn dữ liệu

Các mã mẫu Python sau đây cho biết cách xác định thông tin kết nối cho nguồn dữ liệu Looker, BigQuery hoặc Looker Studio mà trợ lý của bạn sẽ truy vấn để trả lời câu hỏi.

Kết nối với dữ liệu Looker

Các ví dụ về mã sau đây cho biết cách xác định thông tin chi tiết để kết nối với Looker Explore bằng khoá API hoặc mã truy cập.

Khoá API

Bạn có thể thiết lập kết nối với một thực thể Looker bằng các khoá API Looker đã tạo, như mô tả trong phần Xác thực và kết nối với nguồn dữ liệu bằng API Phân tích trò chuyện.

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]

Thay thế các giá trị mẫu như sau:

  • my_looker_client_id: Mã ứng dụng của khoá API Looker mà bạn đã tạo.
  • my_looker_client_secret: Mã xác thực ứng dụng của khoá API Looker mà bạn đã tạo.
  • https://my_company.looker.com: URL đầy đủ của phiên bản Looker.
  • my_model: Tên của mô hình LookML bao gồm Kênh khám phá mà bạn muốn kết nối.
  • my_explore: Tên của công cụ Looker Data Explorer mà bạn muốn tác nhân dữ liệu truy vấn.

Mã truy cập

Bạn có thể thiết lập kết nối với một phiên bản Looker bằng cách sử dụng mã thông báo truy cập, như mô tả trong phần Xác thực và kết nối với nguồn dữ liệu bằng API Phân tích trò chuyện.

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]

Thay thế các giá trị mẫu như sau:

  • my_access_token: Giá trị access_token mà bạn tạo để xác thực với Looker.
  • https://my_company.looker.com: URL đầy đủ của phiên bản Looker.
  • my_model: Tên của mô hình LookML bao gồm Kênh khám phá mà bạn muốn kết nối.
  • my_explore: Tên của công cụ Looker Data Explorer mà bạn muốn tác nhân dữ liệu truy vấn.

Kết nối với dữ liệu BigQuery

Mã mẫu sau đây xác định một kết nối đến một bảng BigQuery.

bq_project_id = "my_project_id"
bq_dataset_id = "my_dataset_id"
bq_table_id = "my_table_id"

bigquery_table_reference = geminidataanalytics.BigQueryTableReference()
bigquery_table_reference.project_id = bq_project_id
bigquery_table_reference.dataset_id = bq_dataset_id
bigquery_table_reference.table_id = bq_table_id

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

Thay thế các giá trị mẫu như sau:

  • my_project_id: Mã nhận dạng của dự án Google Cloud chứa tập dữ liệu và bảng BigQuery mà bạn muốn kết nối. Để kết nối với một tập dữ liệu công khai, hãy chỉ định bigquery-public-data.
  • my_dataset_id: Mã nhận dạng của tập dữ liệu BigQuery. Ví dụ: san_francisco.
  • my_table_id: Mã nhận dạng của bảng BigQuery. Ví dụ: street_trees.

Kết nối với dữ liệu Looker Studio

Mã mẫu sau đây xác định một kết nối với nguồn dữ liệu 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]

Trong ví dụ trước, hãy thay thế my_datasource_id bằng mã nguồn dữ liệu.

Thiết lập ngữ cảnh cho cuộc trò chuyện có trạng thái hoặc không có trạng thái

Mã Python mẫu sau đây minh hoạ cách thiết lập ngữ cảnh cho cuộc trò chuyện có trạng thái hoặc không có trạng thái:

  • Trò chuyện có trạng thái: Google Cloud lưu trữ và quản lý nhật ký trò chuyện. Bạn chỉ cần gửi thông báo hiện tại cho mỗi lượt.
  • Trò chuyện không có trạng thái: Bạn phải gửi toàn bộ nhật ký trò chuyện cùng với mỗi tin nhắn.

Trò chuyện có trạng thái

Mã mẫu sau đây thiết lập ngữ cảnh cho cuộc trò chuyện có trạng thái, trong đó Google Cloud lưu trữ và quản lý nhật ký trò chuyện. Bạn cũng có thể bật tính năng phân tích nâng cao bằng Python (không bắt buộc) bằng cách thêm dòng published_context.options.analysis.python.enabled = True vào mã mẫu sau.

# 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

Trò chuyện không có trạng thái

Mã mẫu sau đây thiết lập ngữ cảnh cho cuộc trò chuyện không có trạng thái, trong đó bạn phải gửi toàn bộ nhật ký trò chuyện cùng với mỗi tin nhắn. Bạn cũng có thể bật tính năng phân tích nâng cao bằng Python (không bắt buộc) bằng cách thêm dòng inline_context.options.analysis.python.enabled = True vào mã mẫu sau.

# 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

Tạo nhân viên hỗ trợ dữ liệu

Mã Python mẫu sau đây tạo một yêu cầu API để tạo một tác nhân dữ liệu. Sau đó, bạn có thể sử dụng tác nhân này để trò chuyện về dữ liệu của mình. Tác nhân dữ liệu được định cấu hình bằng nguồn dữ liệu, hướng dẫn hệ thống và ngữ cảnh đã chỉ định.

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}")

Trong ví dụ trước, hãy thay thế giá trị data_agent_1 bằng giá trị nhận dạng duy nhất cho tác nhân dữ liệu.

Truy xuất nhân viên hỗ trợ dữ liệu

Mã Python mẫu sau đây minh hoạ cách tạo một yêu cầu API để truy xuất tác nhân dữ liệu mà bạn đã tạo trước đó.

# 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)

Trong ví dụ trước, hãy thay thế giá trị data_agent_1 bằng giá trị nhận dạng duy nhất cho tác nhân dữ liệu mà bạn muốn truy xuất.

Tạo cuộc trò chuyện

Mã Python mẫu sau đây tạo một yêu cầu API để tạo cuộc trò chuyệ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)

Thay thế các giá trị mẫu như sau:

  • data_agent_1: Mã nhận dạng của tác nhân dữ liệu, như được xác định trong khối mã mẫu trong phần Tạo tác nhân dữ liệu.
  • conversation_1: Giá trị nhận dạng duy nhất của cuộc trò chuyện.

Sử dụng API để đặt câu hỏi

Sau khi bạn tạo một tác nhân dữ liệu và một cuộc trò chuyện, mã Python mẫu sau đây sẽ gửi một truy vấn đến tác nhân. Mã này sử dụng ngữ cảnh mà bạn thiết lập cho cuộc trò chuyện có trạng thái hoặc không có trạng thái. API trả về một luồng thông báo thể hiện các bước mà tác nhân thực hiện để trả lời truy vấn.

Trò chuyện có trạng thái

Gửi yêu cầu trò chuyện có trạng thái bằng tham chiếu Conversation

Bạn có thể gửi yêu cầu trò chuyện có trạng thái đến tác nhân dữ liệu bằng cách tham chiếu tài nguyên Conversation mà bạn đã tạo trước đó.

# 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)

Thay thế các giá trị mẫu như sau:

  • Which species of tree is most prevalent?: Câu hỏi bằng ngôn ngữ tự nhiên để gửi đến tác nhân dữ liệu.
  • data_agent_1: Giá trị nhận dạng duy nhất cho tác nhân dữ liệu, như được xác định trong phần Tạo tác nhân dữ liệu.
  • conversation_1: Giá trị nhận dạng duy nhất của cuộc trò chuyện, như được xác định trong phần Tạo cuộc trò chuyện.

Trò chuyện không có trạng thái

Các mã mẫu sau đây minh hoạ cách gửi truy vấn đến tác nhân dữ liệu khi bạn đã thiết lập ngữ cảnh cho cuộc trò chuyện không có trạng thái. Bạn có thể gửi truy vấn không có trạng thái bằng cách tham chiếu tài nguyên DataAgent đã xác định trước hoặc bằng cách sử dụng ngữ cảnh nội tuyến trong yêu cầu.

Gửi yêu cầu trò chuyện không có trạng thái bằng tham chiếu DataAgent

Bạn có thể gửi truy vấn đến tác nhân dữ liệu bằng cách tham chiếu tài nguyên DataAgent mà bạn đã tạo trước đó.

# 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)

Thay thế các giá trị mẫu như sau:

  • Which species of tree is most prevalent?: Câu hỏi bằng ngôn ngữ tự nhiên để gửi đến tác nhân dữ liệu.
  • data_agent_1: Giá trị nhận dạng duy nhất cho tác nhân dữ liệu, như được xác định trong phần Tạo tác nhân dữ liệu.

Gửi yêu cầu trò chuyện không có trạng thái có ngữ cảnh nội tuyến

Mã mẫu sau đây minh hoạ cách sử dụng tham số inline_context để cung cấp ngữ cảnh ngay trong yêu cầu trò chuyện không có trạng thái.

# 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)

Trong ví dụ trước, hãy thay thế Which species of tree is most prevalent? bằng một câu hỏi bằng ngôn ngữ tự nhiên để gửi đến tác nhân dữ liệu.

Tạo yêu cầu nhiều lượt

Bạn có thể tạo cuộc trò chuyện nhiều lượt bằng cách gửi câu hỏi tiếp theo cho tác nhân dữ liệu. Mã mẫu sau đây minh hoạ cách tạo các yêu cầu nhiều lượt, dựa trên các phản hồi trước đó để tinh chỉnh cuộc trò chuyện. Để biết thêm thông tin, hãy xem phần Tạo cuộc trò chuyện nhiều lượt.

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

# 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
  input_message.append(message)

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

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

  # Handle the response
  for response in stream:
    show_message(response)
    input_message.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?")

Trong ví dụ trước, hãy thay thế các giá trị mẫu như sau:

  • Which species of tree is most prevalent?: Câu hỏi bằng ngôn ngữ tự nhiên để gửi đến tác nhân dữ liệu.
  • Can you show me the results as a bar chart?: Câu hỏi tiếp theo dựa trên hoặc tinh chỉnh câu hỏi trước đó.

Xác định hàm trợ giúp

Mã mẫu sau đây chứa các định nghĩa hàm trợ giúp được dùng trong các mã mẫu trước. Các hàm này giúp phân tích cú pháp phản hồi từ API và hiển thị kết quả.

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')