Trang này hướng dẫn bạn cách sử dụng Python để gửi yêu cầu HTTP đến Conversational Analytics API (truy cập thông qua geminidataanalytics.googleapis.com
).
Mã Python mẫu trên trang này cho biết cách hoàn thành các nhiệm vụ sau:
- Định cấu hình chế độ cài đặt và xác thực ban đầu
- Kết nối với nguồn dữ liệu Looker, BigQuery hoặc Looker Studio
- Tạo tác nhân dữ liệu
- Tạo cuộc trò chuyện
- Sử dụng API để đặt câu hỏi
Bạn cũng có thể chạy các mã mẫu trên trang này trong sổ tay Colaboratory HTTP API Phân tích cuộc trò chuyện.
Phiên bản đầy đủ của mã mẫu được đưa vào cuối trang, cùng với các hàm trợ giúp dùng để truyền trực tuyến phản hồi API.
Định cấu hình chế độ cài đặt và xác thực ban đầu
Mã Python mẫu sau đây thực hiện các nhiệm vụ sau:
- Nhập các thư viện Python bắt buộc
- Xác định các biến cho dự án thanh toán, hướng dẫn hệ thống và câu hỏi cho tác nhân dữ liệu
- Lấy mã truy cập để xác thực HTTP bằng cách sử dụng Google Cloud CLI
from pygments import highlight, lexers, formatters
import pandas as pd
import json as json_lib
import requests
import json
import altair as alt
import IPython
from IPython.display import display, HTML
import google.auth
from google.auth.transport.requests import Request
from google.colab import auth
auth.authenticate_user()
billing_project = 'YOUR-BILLING-PROJECT'
system_description = 'YOUR-SYSTEM-INSTRUCTIONS'
question = 'YOUR-QUESTION-HERE'
access_token = !gcloud auth application-default print-access-token
headers = {
"Authorization": f"Bearer {access_token[0]}",
"Content-Type": "application/json",
}
Thay thế các giá trị mẫu như sau:
- YOUR-BILLING-PROJECT: Mã nhận dạng của dự án thanh toán mà bạn đã bật các API bắt buộc.
- YOUR-SYSTEM-INSTRUCTIONS: Hướng dẫn hệ thống để hướng dẫn hành vi của tác nhân và cho phép bạn tuỳ chỉnh tác nhân theo nhu cầu của mình. 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ư những yếu tố tạo nên một "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"). Thay thế văn bản giữ chỗ bằng hướng dẫn liên quan đến dữ liệu và trường hợp sử dụng của bạn.
- YOUR-QUESTION-HERE: Câu hỏi bằng ngôn ngữ tự nhiên để gửi đến tác nhân dữ liệu.
Xác thực với Looker
Nếu dự định kết nối với một nguồn dữ liệu Looker, bạn sẽ cần xác thực với thực thể Looker.
Sử dụng khoá API
Mã mẫu Python sau đây minh hoạ cách xác thực tác nhân của bạn với một thực thể Looker bằng các khoá API.
looker_credentials = {
"oauth": {
"secret": {
"client_id": "YOUR-LOOKER-CLIENT-ID",
"client_secret": "YOUR-LOOKER-CLIENT-SECRET",
}
}
}
Thay thế các giá trị mẫu như sau:
- YOUR-LOOKER-CLIENT-ID: Mã ứng dụng của khoá API Looker mà bạn đã tạo.
- YOUR-LOOKER-CLIENT-SECRET: Mã xác thực ứng dụng của khoá API Looker mà bạn đã tạo.
Sử dụng mã truy cập
Mã mẫu Python sau đây minh hoạ cách xác thực tác nhân của bạn với một thực thể Looker bằng mã thông báo truy cập.
looker_credentials = {
"oauth": {
"token": {
"access_token": "YOUR-TOKEN",
}
}
}
Thay thế các giá trị mẫu như sau:
- YOUR-TOKEN: Giá trị
access_token
mà bạn tạo để xác thực với Looker.
Kết nối với nguồn dữ liệu
Các mã mẫu Python sau đây minh hoạ cách xác định nguồn dữ liệu Looker, BigQuery hoặc Looker Studio để nhân viên hỗ trợ sử dụng.
Kết nối với dữ liệu Looker
Mã mẫu sau đây xác định kết nối với một mục Khám phá trên Looker. Để thiết lập kết nối với một phiên bản Looker, hãy xác minh rằng bạn đã tạo khoá API Looker, 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_data_source = {
"looker": {
"explore_references": {
"looker_instance_uri": "https://your_company.looker.com",
"lookml_model": "your_model",
"explore": "your_explore",
},
}
}
Thay thế các giá trị mẫu như sau:
- https://your_company.looker.com: URL đầy đủ của phiên bản Looker.
- your_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.
- your_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 bảng BigQuery.
bigquery_data_sources = {
"bq" : {
"tableReferences": [
{
"projectId": "bigquery-public-data",
"datasetId": "san_francisco",
"tableId": "street_trees",
}
]
}
}
Thay thế các giá trị mẫu như sau:
- bigquery-public-data: 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
. - san_francisco: Mã nhận dạng của tập dữ liệu BigQuery.
- street_trees: Mã nhận dạng của bảng BigQuery.
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.
looker_studio_data_source = {
"studio":{
"studio_references":
[
{
"studio_datasource_id": "studio_datasource_id"
}
]
}
}
Thay thế studio_datasource_id bằng mã nguồn dữ liệu.
Tạo nhân viên hỗ trợ dữ liệu
Mã mẫu sau đây minh hoạ cách tạo tác nhân dữ liệu bằng cách gửi yêu cầu POST
HTTP đến điểm cuối tạo tác nhân dữ liệu. Trọng tải yêu cầu bao gồm các thông tin chi tiết sau:
- Tên tài nguyên đầy đủ của tác nhân. Giá trị này bao gồm mã dự án, vị trí và giá trị nhận dạng duy nhất của tác nhân.
- Nội dung mô tả của tác nhân dữ liệu.
- Ngữ cảnh của tác nhân dữ liệu, bao gồm cả nội dung mô tả hệ thống (được xác định trong phần Định cấu hình chế độ cài đặt ban đầu và xác thực) và nguồn dữ liệu mà tác nhân sử dụng (được xác định trong phần Kết nối với nguồn dữ liệu).
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 đưa tham số options
vào tải trọng yêu cầu.
data_agent_url = f"https://geminidataanalytics.googleapis.com/v1alpha/projects/{billing_project}/locations/{location}/dataAgents"
data_agent_id = "data_agent_1"
data_agent_payload = {
"name": f"projects/{billing_project}/locations/{location}/dataAgents/{data_agent_id}", # Optional
"description": "This is the description of data_agent_1.", # Optional
"data_analytics_agent": {
"published_context": {
"datasource_references": bigquery_data_sources,
"system_instruction": system_instruction,
# Optional: To enable advanced analysis with Python, include the following options block:
"options": {
"analysis": {
"python": {
"enabled": True
}
}
}
}
}
}
params = {"data_agent_id": data_agent_id} # Optional
data_agent_response = requests.post(
data_agent_url, params=params, json=data_agent_payload, headers=headers
)
if data_agent_response.status_code == 200:
print("Data Agent created successfully!")
print(json.dumps(data_agent_response.json(), indent=2))
else:
print(f"Error creating Data Agent: {data_agent_response.status_code}")
print(data_agent_response.text)
Thay thế các giá trị mẫu như sau:
- data_agent_1: Giá trị nhận dạng duy nhất cho tác nhân dữ liệu. Giá trị này được dùng trong tên tài nguyên của tác nhân và làm tham số truy vấn URL
data_agent_id
. - This is the description of data_agent_1.: Nội dung mô tả về tác nhân dữ liệu.
Tạo cuộc trò chuyện
Mã mẫu sau đây minh hoạ cách tạo cuộc trò chuyện với tác nhân dữ liệu.
conversation_url = f"https://geminidataanalytics.googleapis.com/v1alpha/projects/{billing_project}/locations/{location}/conversations"
data_agent_id = "data_agent_1"
conversation_id = "conversation_1"
conversation_payload = {
"agents": [
f"projects/{billing_project}/locations/{location}/dataAgents/{data_agent_id}"
],
"name": f"projects/{billing_project}/locations/{location}/conversations/{conversation_id}"
}
params = {
"conversation_id": conversation_id
}
conversation_response = requests.post(conversation_url, headers=headers, params=params, json=conversation_payload)
if conversation_response.status_code == 200:
print("Conversation created successfully!")
print(json.dumps(conversation_response.json(), indent=2))
else:
print(f"Error creating Conversation: {conversation_response.status_code}")
print(conversation_response.text)
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 tạo một tác nhân dữ liệu và một cuộc trò chuyện, bạn có thể đặt câu hỏi về dữ liệu của mình bằng một trong các phương thức sau:
- 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: Ứng dụng của bạn chịu trách nhiệm duy trì nhật ký cuộc trò chuyện. Google Cloud không lưu trữ nhật ký cuộc trò chuyện giữa các yêu cầu. Bạn phải đưa vào các thông báo trước đó có liên quan cùng với thông báo mới cho mỗi lượt rẽ.
Để biết thêm thông tin về cuộc trò chuyện nhiều lượt, hãy xem bài viết Tạo cuộc trò chuyện nhiều lượt.
Trò chuyện có trạng thái
Gửi yêu cầu trò chuyện có trạng thái với tham chiếu cuộc trò chuyện
Mã mẫu sau đây minh hoạ cách đặt câu hỏi cho API bằng cuộc trò chuyện mà bạn đã xác định ở các bước trước. Mẫu này sử dụng hàm trợ giúp get_stream
để truyền trực tuyến phản hồi.
chat_url = f"https://geminidataanalytics.googleapis.com/v1alpha/projects/{billing_project}/locations/{location}:chat"
data_agent_id = "data_agent_1"
conversation_id = "conversation_1"
# Construct the payload
chat_payload = {
"parent": f"projects/{billing_project}/locations/global",
"messages": [
{
"userMessage": {
"text": "Make a bar graph for the top 5 states by the total number of airports"
}
}
],
"conversation_reference": {
"conversation": f"projects/{billing_project}/locations/{location}/conversations/{conversation_id}",
"data_agent_context": {
"data_agent": f"projects/{billing_project}/locations/{location}/dataAgents/{data_agent_id}",
# "credentials": looker_credentials
}
}
}
# Call the get_stream function to stream the response
get_stream(chat_url, chat_payload)
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.
Make a bar graph for the top 5 states by the total number of airports
được dùng làm lời nhắc mẫu.
Trò chuyện không có trạng thái
Gửi yêu cầu trò chuyện không có trạng thái có tham chiếu đến tác nhân dữ liệu
Mã mẫu sau đây minh hoạ cách đặt câu hỏi không có trạng thái cho API bằng cách sử dụng trình đại diện dữ liệu mà bạn đã xác định ở các bước trước. Mẫu này sử dụng hàm trợ giúp get_stream
để truyền trực tuyến phản hồi.
chat_url = f"https://geminidataanalytics.googleapis.com/v1alpha/projects/{billing_project}/locations/{location}:chat"
data_agent_id = "data_agent_1"
# Construct the payload
chat_payload = {
"parent": f"projects/{billing_project}/locations/global",
"messages": [
{
"userMessage": {
"text": "Make a bar graph for the top 5 states by the total number of airports"
}
}
],
"data_agent_context": {
"data_agent": f"projects/{billing_project}/locations/{location}/dataAgents/{data_agent_id}",
# "credentials": looker_credentials
}
}
# Call the get_stream function to stream the response
get_stream(chat_url, chat_payload)
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.
Make a bar graph for the top 5 states by the total number of airports
được dùng làm lời nhắc mẫ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 đặt câu hỏi không có trạng thái cho API bằng cách sử dụng ngữ cảnh nội tuyến. Mẫu này sử dụng hàm trợ giúp get_stream
để truyền trực tuyến phản hồi và sử dụng nguồn dữ liệu BigQuery làm ví dụ.
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 đưa tham số options
vào tải trọng yêu cầu.
chat_url = f"https://geminidataanalytics.googleapis.com/v1alpha/projects/{billing_project}/locations/global:chat"
# Construct the payload
chat_payload = {
"parent": f"projects/{billing_project}/locations/global",
"messages": [
{
"userMessage": {
"text": "Make a bar graph for the top 5 states by the total number of airports"
}
}
],
"inline_context": {
"datasource_references": bigquery_data_sources,
# Optional: To enable advanced analysis with Python, include the following options block:
"options": {
"analysis": {
"python": {
"enabled": True
}
}
}
}
}
# Call the get_stream function to stream the response
get_stream(chat_url, chat_payload)
Mã mẫu toàn diện
Mẫu mã có thể mở rộng sau đây chứa tất cả các nhiệm vụ được đề cập trong hướng dẫn này.
Tạo tác nhân dữ liệu bằng HTTP và Python
from pygments import highlight, lexers, formatters import pandas as pd import json as json_lib import requests import json import altair as alt import IPython from IPython.display import display, HTML import requests import google.auth from google.auth.transport.requests import Request from google.colab import auth auth.authenticate_user() access_token = !gcloud auth application-default print-access-token headers = { "Authorization": f"Bearer {access_token[0]}", "Content-Type": "application/json", } ################### Data source details ################### billing_project = "your_billing_project" location = "global" system_instruction = "Help the user in analyzing their data" # BigQuery data source bigquery_data_sources = { "bq": { "tableReferences": [ { "projectId": "bigquery-public-data", "datasetId": "san_francisco", "tableId": "street_trees" } ] } } # Looker data source looker_credentials = { "oauth": { "secret": { "client_id": "your_looker_client_id", "client_secret": "your_looker_client_secret", } } } # # To use access_token for authentication, uncomment the following looker_credentials code block and comment out the previous looker_credentials code block. # looker_credentials = { # "oauth": { # "token": { # "access_token": "your_looker_access_token", # } # } # } looker_data_source = { "looker": { "explore_references": { "looker_instance_uri": "https://my_company.looker.com", "lookml_model": "my_model", "explore": "my_explore", }, # "credentials": looker_credentials # Uncomment this when using looker as datasource in stateless chat } } # Looker Studio data source looker_studio_data_source = { "studio":{ "studio_references": [ { "datasource_id": "your_studio_datasource_id" } ] } } ################### Create data agent ################### data_agent_url = f"https://geminidataanalytics.googleapis.com/v1alpha/projects/{billing_project}/locations/{location}/dataAgents" data_agent_id = "data_agent_1" data_agent_payload = { "name": f"projects/{billing_project}/locations/{location}/dataAgents/{data_agent_id}", # Optional "description": "This is the description of data_agent.", # Optional "data_analytics_agent": { "published_context": { "datasource_references": bigquery_data_sources, "system_instruction": system_instruction, # Optional: To enable advanced analysis with Python, include the following options block: "options": { "analysis": { "python": { "enabled": True } } } } } } params = {"data_agent_id": data_agent_id} # Optional data_agent_response = requests.post( data_agent_url, params=params, json=data_agent_payload, headers=headers ) if data_agent_response.status_code == 200: print("Data Agent created successfully!") print(json.dumps(data_agent_response.json(), indent=2)) else: print(f"Error creating Data Agent: {data_agent_response.status_code}") print(data_agent_response.text) ################### Create conversation ################### conversation_url = f"https://geminidataanalytics.googleapis.com/v1alpha/projects/{billing_project}/locations/{location}/conversations" data_agent_id = "data_agent_1" conversation_id = "conversation _1" conversation_payload = { "agents": [ f"projects/{billing_project}/locations/{location}/dataAgents/{data_agent_id}" ], "name": f"projects/{billing_project}/locations/{location}/conversations/{conversation_id}" } params = { "conversation_id": conversation_id } conversation_response = requests.post(conversation_url, headers=headers, params=params, json=conversation_payload) if conversation_response.status_code == 200: print("Conversation created successfully!") print(json.dumps(conversation_response.json(), indent=2)) else: print(f"Error creating Conversation: {conversation_response.status_code}") print(conversation_response.text) ################### Chat with the API by using conversation (stateful) #################### chat_url = f"https://geminidataanalytics.googleapis.com/v1alpha/projects/{billing_project}/locations/{location}:chat" data_agent_id = "data_agent_1" conversation_id = "conversation _1" # Construct the payload chat_payload = { "parent": f"projects/{billing_project}/locations/global", "messages": [ { "userMessage": { "text": "Make a bar graph for the top 5 states by the total number of airports" } } ], "conversation_reference": { "conversation": f"projects/{billing_project}/locations/{location}/conversations/{conversation_id}", "data_agent_context": { "data_agent": f"projects/{billing_project}/locations/{location}/dataAgents/{data_agent_id}", # "credentials": looker_credentials #Uncomment this if your dataAgent contains looker dataSource } } } # Call the get_stream function to stream the response get_stream(chat_url, chat_payload) ################### Chat with the API by using dataAgents (stateless) #################### chat_url = f"https://geminidataanalytics.googleapis.com/v1alpha/projects/{billing_project}/locations/{location}:chat" data_agent_id = "data_agent_1" # Construct the payload chat_payload = { "parent": f"projects/{billing_project}/locations/global", "messages": [ { "userMessage": { "text": "Make a bar graph for the top 5 states by the total number of airports" } } ], "data_agent_context": { "data_agent": f"projects/{billing_project}/locations/{location}/dataAgents/{data_agent_id}", # "credentials": looker_credentials #Uncomment this if your dataAgent contains looker as dataSource } } # Call the get_stream function to stream the response get_stream(chat_url, chat_payload) ################### Chat with the API by using inline context (stateless) #################### chat_url = f"https://geminidataanalytics.googleapis.com/v1alpha/projects/{billing_project}/locations/global:chat" # Construct the payload chat_payload = { "parent": f"projects/{billing_project}/locations/global", "messages": [ { "userMessage": { "text": "Make a bar graph for the top 5 states by the total number of airports" } } ], "inline_context": { "datasource_references": bigquery_data_sources, # Optional - if wanting to use advanced analysis with python "options": { "analysis": { "python": { "enabled": True } } } } } # Call the get_stream function to stream the response get_stream(chat_url, chat_payload)
Mã mẫu có thể mở rộng sau đây chứa các hàm trợ giúp Python dùng để truyền trực tuyến phản hồi trò chuyện.
Các hàm trợ giúp Python để truyền trực tuyến phản hồi trò chuyện
def is_json(str): try: json_object = json_lib.loads(str) except ValueError as e: return False return True def handle_text_response(resp): parts = resp['parts'] print(''.join(parts)) def get_property(data, field_name, default = ''): return data[field_name] if field_name in data else default def display_schema(data): fields = data['fields'] df = pd.DataFrame({ "Column": map(lambda field: get_property(field, 'name'), fields), "Type": map(lambda field: get_property(field, 'type'), fields), "Description": map(lambda field: get_property(field, 'description', '-'), fields), "Mode": map(lambda field: get_property(field, 'mode'), fields) }) display(df) def display_section_title(text): display(HTML('<h2>{}</h2>'.format(text))) def format_bq_table_ref(table_ref): return '{}.{}.{}'.format(table_ref['projectId'], table_ref['datasetId'], table_ref['tableId']) def format_looker_table_ref(table_ref): return 'lookmlModel: {}, explore: {}, lookerInstanceUri: {}'.format(table_ref['lookmlModel'], table_ref['explore'], table_ref['lookerInstanceUri']) def display_datasource(datasource): source_name = '' if 'studioDatasourceId' in datasource: source_name = datasource['studioDatasourceId'] elif 'lookerExploreReference' in datasource: source_name = format_looker_table_ref(datasource['lookerExploreReference']) else: source_name = format_bq_table_ref(datasource['bigqueryTableReference']) 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 'generatedSql' in resp: display_section_title('SQL generated') print(resp['generatedSql']) elif 'result' in resp: display_section_title('Data retrieved') fields = map(lambda field: get_property(field, 'name'), resp['result']['schema']['fields']) dict = {} for field in fields: dict[field] = map(lambda el: get_property(el, field), resp['result']['data']) display(pd.DataFrame(dict)) def handle_chart_response(resp): if 'query' in resp: print(resp['query']['instructions']) elif 'result' in resp: vegaConfig = resp['result']['vegaConfig'] alt.Chart.from_json(json_lib.dumps(vegaConfig)).display(); def handle_error(resp): display_section_title('Error') print('Code: {}'.format(resp['code'])) print('Message: {}'.format(resp['message'])) def get_stream(url, json): s = requests.Session() acc = '' with s.post(url, json=json, headers=headers, stream=True) as resp: for line in resp.iter_lines(): if not line: continue decoded_line = str(line, encoding='utf-8') if decoded_line == '[{': acc = '{' elif decoded_line == '}]': acc += '}' elif decoded_line == ',': continue else: acc += decoded_line if not is_json(acc): continue data_json = json_lib.loads(acc) if not 'systemMessage' in data_json: if 'error' in data_json: handle_error(data_json['error']) continue if 'text' in data_json['systemMessage']: handle_text_response(data_json['systemMessage']['text']) elif 'schema' in data_json['systemMessage']: handle_schema_response(data_json['systemMessage']['schema']) elif 'data' in data_json['systemMessage']: handle_data_response(data_json['systemMessage']['data']) elif 'chart' in data_json['systemMessage']: handle_chart_response(data_json['systemMessage']['chart']) else: colored_json = highlight(acc, lexers.JsonLexer(), formatters.TerminalFormatter()) print(colored_json) print('\n') acc = ''