Conversational Analytics API'ye giriş

1. Giriş

Bu codelab'de, BigQuery veri kaynağıyla Conversational Analytics (CA) API Python SDK'sını kullanmayı öğreneceksiniz. Yeni bir aracı oluşturmayı, görüşme durumu yönetiminden yararlanmayı ve API'den yanıt göndermeyi ve yayınlamayı öğreneceksiniz.

Ön koşullar

  • Google Cloud ve Google Cloud Console hakkında temel bilgiler
  • Komut satırı arayüzü ve Cloud Shell'de temel beceriler
  • Python programlamada temel düzeyde yeterlilik

Neler öğreneceksiniz?

  • BigQuery veri kaynağıyla Conversational Analytics API Python SDK'sını kullanma
  • CA API'yi kullanarak yeni bir aracı oluşturma
  • Görüşme durumu yönetiminden yararlanma
  • API'den yanıt gönderme ve yayınlama

Gerekenler

  • Google Cloud hesabı ve Google Cloud projesi
  • Chrome gibi bir web tarayıcısı

2. Kurulum ve şartlar

Proje seçme

  1. Google Cloud Console'da oturum açın ve yeni bir proje oluşturun veya mevcut bir projeyi yeniden kullanın. Gmail veya Google Workspace hesabınız yoksa oluşturmanız gerekir.

fbef9caa1602edd0.png

a99b7ace416376c4.png

5e3ff691252acf41.png

  • Proje adı, bu projenin katılımcıları için görünen addır. Google API'leri tarafından kullanılmayan bir karakter dizesidir. Bu bilgiyi istediğiniz zaman güncelleyebilirsiniz.
  • Proje kimliği, tüm Google Cloud projelerinde benzersizdir ve sabittir (ayarlandıktan sonra değiştirilemez). Cloud Console, benzersiz bir dizeyi otomatik olarak oluşturur. Genellikle bu dizenin ne olduğuyla ilgilenmezsiniz. Çoğu codelab'de proje kimliğinize (genellikle PROJECT_ID olarak tanımlanır) başvurmanız gerekir. Oluşturulan kimliği beğenmezseniz başka bir rastgele kimlik oluşturabilirsiniz. Dilerseniz kendi adınızı deneyerek kullanılabilir olup olmadığını kontrol edebilirsiniz. Bu adım tamamlandıktan sonra değiştirilemez ve proje süresince geçerli kalır.
  • Bazı API'lerin kullandığı üçüncü bir değer olan Proje Numarası da vardır. Bu üç değer hakkında daha fazla bilgiyi belgelerde bulabilirsiniz.
  1. Ardından, Cloud kaynaklarını/API'lerini kullanmak için Cloud Console'da faturalandırmayı etkinleştirmeniz gerekir. Bu codelab'i tamamlamak neredeyse hiç maliyetli değildir. Bu eğitimin ötesinde faturalandırılmayı önlemek için kaynakları kapatmak üzere oluşturduğunuz kaynakları veya projeyi silebilirsiniz. Yeni Google Cloud kullanıcıları 300 ABD doları değerinde ücretsiz deneme programından yararlanabilir.

Cloud Shell'i başlatma

Google Cloud, dizüstü bilgisayarınızdan uzaktan çalıştırılabilir. Ancak bu codelab'de, Cloud'da çalışan bir komut satırı ortamı olan Google Cloud Shell'i kullanacaksınız.

Google Cloud Console'da sağ üst araç çubuğundaki Cloud Shell simgesini tıklayın:

5704d8c8d89c09d2.png

Ortamın sağlanması ve bağlantının kurulması yalnızca birkaç saniye sürer. İşlem tamamlandığında aşağıdakine benzer bir sonuç görürsünüz:

7ffe5cbb04455448.png

Bu sanal makineye, ihtiyaç duyacağınız tüm geliştirme araçları yüklenmiştir. 5 GB boyutunda kalıcı bir ana dizin sunar ve Google Cloud üzerinde çalışır. Bu sayede ağ performansı ve kimlik doğrulama önemli ölçüde iyileştirilir. Bu codelab'deki tüm çalışmalarınızı tarayıcıda yapabilirsiniz. Herhangi bir yazılım yüklemeniz gerekmez.

3. Başlamadan önce

Gerekli API'leri etkinleştirme

Google Cloud hizmetlerini kullanmak için önce projenizde ilgili API'leri etkinleştirmeniz gerekir. Bu codelab'de aşağıdaki Google Cloud hizmetlerini kullanacaksınız:

  • Gemini ile Veri Analizi API'si
  • Google Cloud için Gemini
  • BigQuery API

Bu hizmetleri etkinleştirmek için Cloud Shell terminalinde aşağıdaki komutları çalıştırın:

gcloud services enable geminidataanalytics.googleapis.com
gcloud services enable cloudaicompanion.googleapis.com
gcloud services enable bigquery.googleapis.com

Python paketlerini yükleme

Herhangi bir Python projesine başlamadan önce sanal ortam oluşturmak iyi bir uygulamadır. Bu, projenin bağımlılıklarını yalıtarak diğer projelerle veya sistemin genel Python paketleriyle çakışmaları önler. Bu bölümde, Cloud Shell'de pip zaten mevcut olduğundan uv'ı pip'ten yükleyeceksiniz.

uv paketini yükleme

pip install uv

uv'nin doğru şekilde yüklenip yüklenmediğini doğrulama

uv --version

Beklenen çıkış

Çıkışta uv ile başlayan bir satır görüyorsanız sonraki adıma geçebilirsiniz. Sürüm numarasının farklı olabileceğini unutmayın:

3d81dc0243d27240.png

Sanal ortam oluşturma ve paketleri yükleme

uv init ca-api-codelab
cd ca-api-codelab
uv venv --python 3.12
uv add google-cloud-geminidataanalytics pandas altair
uv pip list | grep -E 'altair|pandas|google-cloud-geminidataanalytics'

Beklenen çıkış

Üç paketi içeren çıkış satırları görüyorsanız sonraki adıma geçebilirsiniz. Sürüm numaralarının farklılık gösterebileceğini unutmayın:

4d777e586e20bf3d.png

Python'ı başlatma

uv run python

Ekranınız aşağıdaki gibi görünmelidir:

a50bf86ade7dec15.png

4. Temsilci oluşturun

Geliştirme ortamınız kurulup hazır olduğuna göre, Gemini Veri Analizi API'sinin temelini oluşturmanın zamanı geldi. SDK, bu süreci basitleştirerek aracınızı oluşturmak için yalnızca birkaç temel yapılandırma yapmanızı gerektirir.

Değişkenleri ayarlama

geminidataanalytics paketini içe aktarın ve ortam değişkenlerimizi ayarlayın:

import os
from google.cloud import geminidataanalytics

data_agent_client = geminidataanalytics.DataAgentServiceClient()

location = "global"
billing_project = os.environ.get('DEVSHELL_PROJECT_ID')
data_agent_id = "google_trends_analytics_agent"

Aracı için sistem talimatlarını ayarlama

CA API, referans verilen tablolar ve sütunlar hakkında daha fazla bağlam bilgisi edinmek için BigQuery meta verilerini okur. Bu herkese açık veri kümesinde sütun açıklamaları olmadığından, YAML biçimli bir dize olarak temsilciye ek bağlam sağlayabilirsiniz. En iyi uygulamalar ve kullanabileceğiniz bir şablon için belgelere bakın:

system_instruction = """
system_instruction:
  - You are a data analyst specializing in the Google Trends dataset.
  - When querying, always use the 'week' column for date-based filtering. This needs to be a Sunday. If you are doing week over week comparison, make sure you specify a date that is a Sunday.
  - The following columns should be ignored in all queries 'dma_id', 'refresh_date'
  - The 'dma_name' column represents the city and state for about 210 metro areas in the USA.
tables:
  top_terms:
    description: "Represents the 25 most popular search terms by weekly search volume in a given US metro area (DMA)."
    fields:
      term: "The search query string."
      week: "The start date of the week (Sunday) for which the ranking is valid."
      rank: "The term's popularity rank from 1 (most popular) to 25."
      score: "Relative search interest, where 100 is the peak popularity for the term in that week."
      dma_name: "The name of the US metro area, e.g., 'New York NY'."
  top_rising_terms:
    description: "Represents the 25 fastest-growing ('breakout') search terms by momentum in a given US metro area (DMA)."
    fields:
      term: "The surging search query string."
      week: "The start date of the week (Sunday) for which the ranking is valid."
      rank: "The term's breakout rank from 1 (top rising) to 25."
      percent_gain: "The percentage growth in search volume compared to the previous period."
      dma_name: "The name of the US metro area, e.g., 'Los Angeles CA'."
      score: "Relative search interest, where 100 is the peak popularity for the term in that week."
join_instructions:
  goal: "Find terms that are simultaneously popular and rising in the same week and metro area."
  method: "INNER JOIN the two tables on their common keys."
  keys:
    - "term"
    - "week"
    - "dma_name"
golden_queries:
  - natural_language_query: "Find all terms in the 'New York NY' area that were in both the top 25 and top 25 rising lists for the week of July 6th, 2025, and show their ranks and percent gain."
    sql_query: |
      SELECT
          top.term,
          top.rank AS top_25_rank,
          rising.rank AS rising_25_rank,
          rising.percent_gain
      FROM
          `bigquery-public-data.google_trends.top_terms` AS top
      INNER JOIN
          `bigquery-public-data.google_trends.top_rising_terms` AS rising
      ON
          top.term = rising.term
          AND top.week = rising.week
          AND top.dma_name = rising.dma_name
      WHERE
          top.week = '2025-07-06'
          AND top.dma_name = 'New York NY'
      ORDER BY
          top.rank;
"""

BigQuery Tablo Veri kaynaklarını ayarlama

Artık BigQuery tablo veri kaynaklarını ayarlayabilirsiniz. CA API, bir dizideki BigQuery tablolarını kabul eder:

# BigQuery table data sources
bq_top = geminidataanalytics.BigQueryTableReference(
    project_id="bigquery-public-data", dataset_id="google_trends", table_id="top_terms"
)
bq_rising = geminidataanalytics.BigQueryTableReference(
    project_id="bigquery-public-data", dataset_id="google_trends", table_id="top_rising_terms"
)
datasource_references = geminidataanalytics.DatasourceReferences(
    bq=geminidataanalytics.BigQueryTableReferences(table_references=[bq_top, bq_rising]))

Durumlu sohbet için bağlam ayarlama

Sistem talimatlarını, veri kaynağı referanslarını ve diğer seçenekleri bir araya getiren yayınlanmış bağlam ile yeni bir aracı oluşturabilirsiniz.

Yayınlamadan önce değişiklikleri test etmek ve doğrulamak için stagingContext oluşturma işlevini kullanabilirsiniz. Bu sayede geliştiriciler, sohbet isteğinde contextVersion'ı belirterek veri aracına sürüm oluşturma özelliği ekleyebilir. Bu codelab'de doğrudan yayınlama yapacaksınız:

# Context setup for stateful chat
published_context = geminidataanalytics.Context(
    system_instruction=system_instruction,
    datasource_references=datasource_references,
    options=geminidataanalytics.ConversationOptions(
        analysis=geminidataanalytics.AnalysisOptions(
            python=geminidataanalytics.AnalysisOptions.Python(
                enabled=False
            )
        )
    ),
)

data_agent = geminidataanalytics.DataAgent(
    data_analytics_agent=geminidataanalytics.DataAnalyticsAgent(
        published_context=published_context
    ),
)

# Create the agent
data_agent_client.create_data_agent(request=geminidataanalytics.CreateDataAgentRequest(
    parent=f"projects/{billing_project}/locations/{location}",
    data_agent_id=data_agent_id,
    data_agent=data_agent,
))

Aracı oluşturduktan sonra aşağıdakine benzer bir çıkış görürsünüz:

a7824f586c550d28.png

Aracıyı edinme

Oluşturulduğundan emin olmak için temsilciyi test edelim:

# Test the agent
request = geminidataanalytics.GetDataAgentRequest(
    name=data_agent_client.data_agent_path(
        billing_project, location, data_agent_id)
)
response = data_agent_client.get_data_agent(request=request)
print(response)

Yeni temsilcinizdeki meta verileri görmeniz gerekir. Oluşturulma zamanı, sistem talimatları ve veri kaynaklarındaki aracı bağlamı gibi bilgiler buna dahildir.

5. Konuşma oluşturun

Artık ilk görüşmenizi oluşturmaya hazırsınız. Bu codelab'de, temsilcinizle durum bilgisi içeren bir sohbet için görüşme referansı kullanacaksınız.

CA API, farklı eyalet ve temsilci yönetimi seçenekleriyle sohbet etmenin çeşitli yollarını sunar. 3 yaklaşımın kısa bir özetini aşağıda bulabilirsiniz:

Durum

Görüşme Geçmişi

Temsilci

Code

Açıklama

Konuşma referansı kullanarak sohbet etme

Durum bilgili

API ile yönetilen

Evet

conversationReference

Mevcut bir görüşmeye ve ilişkili temsilci bağlamına referans veren bir sohbet mesajı göndererek durum bilgisi içeren bir görüşmeye devam eder. Çok turlu görüşmelerde Google Cloud, görüşme geçmişini saklar ve yönetir.

Veri aracısı referansı kullanarak sohbet etme

Durum bilgisiz

Kullanıcı tarafından yönetilen

Evet

dataAgentContext

Bağlam için kaydedilmiş bir veri aracısına referans veren durum bilgisi içermeyen bir sohbet mesajı gönderir. Çok turlu görüşmelerde uygulamanız, görüşme geçmişini yönetmeli ve her istekle birlikte sağlamalıdır.

Satır içi bağlamı kullanarak sohbet etme

Durum bilgisiz

Kullanıcı tarafından yönetilen

Hayır

inlineContext

Kayıtlı bir veri aracısı kullanmadan tüm bağlamı doğrudan istekte sağlayarak durum bilgisi içermeyen bir sohbet mesajı gönderir. Çok turlu görüşmelerde uygulamanız, görüşme geçmişini yönetmeli ve her istekle birlikte sağlamalıdır.

Görüşmenizi ayarlamak ve görüşme için benzersiz bir kimlik sağlamak üzere bir işlev oluşturursunuz:

def setup_conversation(conversation_id: str):
    data_chat_client = geminidataanalytics.DataChatServiceClient()
    conversation = geminidataanalytics.Conversation(
        agents=[data_chat_client.data_agent_path(
            billing_project, location, data_agent_id)],
    )
    request = geminidataanalytics.CreateConversationRequest(
        parent=f"projects/{billing_project}/locations/{location}",
        conversation_id=conversation_id,
        conversation=conversation,
    )
    try:
        data_chat_client.get_conversation(name=data_chat_client.conversation_path(
            billing_project, location, conversation_id))
        print(f"Conversation '{conversation_id}' already exists.")
    except Exception:
        response = data_chat_client.create_conversation(request=request)
        print("Conversation created successfully:")
        print(response)


conversation_id = "my_first_conversation"
setup_conversation(conversation_id=conversation_id)

İleti dizisinin başarıyla oluşturulduğuna dair bir mesaj gösterilir.

6. Yardımcı işlevler ekleme

Temsilciyle sohbet etmeye başlamak için neredeyse hazırsınız. Bunu yapmadan önce, mesajların daha kolay okunacak şekilde biçimlendirilmesine ve görselleştirmelerin oluşturulmasına yardımcı olacak bazı yardımcı işlevler ekleyelim. CA API, altair paketini kullanarak çizebileceğiniz bir vega spesifikasyonu gönderir:

# Utility functions for streaming and formatting responses
import altair as alt
import http.server
import pandas as pd
import proto
import socketserver
import threading

_server_thread = None
_httpd = None


# Prints a formatted section title
def display_section_title(text):
    print(f"\n--- {text.upper()} ---")


# Handles and displays data responses
def handle_data_response(resp):
    if "query" in resp:
        query = resp.query
        display_section_title("Retrieval query")
        print(f"Query name: {query.name}")
        print(f"Question: {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 = {field: [] for field in fields}
        for el in resp.result.data:
            for field in fields:
                d[field].append(el[field])
        print(pd.DataFrame(d))


# Starts a local web server to preview charts
def preview_in_browser(port: int = 8080):
    """Starts a web server in a background thread and waits for user to stop it."""
    global _server_thread, _httpd
    if _server_thread and _server_thread.is_alive():
        print(
            f"\n--> A new chart was generated. Refresh your browser at http://localhost:{port}")
        return
    Handler = http.server.SimpleHTTPRequestHandler
    socketserver.TCPServer.allow_reuse_address = True
    try:
        _httpd = socketserver.TCPServer(("", port), Handler)
    except OSError as e:
        print(f"❌ Could not start server on port {port}: {e}")
        return
    _server_thread = threading.Thread(target=_httpd.serve_forever)
    _server_thread.daemon = False
    _server_thread.start()
    print("\n" + "=" * 60)
    print(" 📈 CHART READY - PREVIEW IN BROWSER ".center(60))
    print("=" * 60)
    print(
        f"1. In the Cloud Shell toolbar, click 'Web Preview' and select port {port}.")
    print(f"2. Or, open your local browser to http://localhost:{port}")
    print("=" * 60)
    try:
        input(
            "\n--> Press Enter here after viewing all charts to shut down the server...\n\n")
    finally:
        print("Shutting down server...")
        _httpd.shutdown()
        _server_thread.join()
        _httpd, _server_thread = None, None
        print("Server stopped.")


# Handles chart responses
def handle_chart_response(resp, chart_generated_flag: list):
    def _value_to_dict(v):
        if isinstance(v, proto.marshal.collections.maps.MapComposite):
            return {k: _value_to_dict(v[k]) for k in v}
        elif isinstance(v, proto.marshal.collections.RepeatedComposite):
            return [_value_to_dict(el) for el in v]
        return v
    if "query" in resp:
        print(resp.query.instructions)
    elif "result" in resp:
        vega_config_dict = _value_to_dict(resp.result.vega_config)
        chart = alt.Chart.from_dict(vega_config_dict)
        chart_filename = "index.html"
        chart.save(chart_filename)
        if chart_generated_flag:
            chart_generated_flag[0] = True


# Displays the schema of a data source
def display_schema(data):
    fields = getattr(data, "fields")
    df = pd.DataFrame({
        "Column": [f.name for f in fields],
        "Type": [f.type for f in fields],
        "Description": [getattr(f, "description", "-") for f in fields],
        "Mode": [f.mode for f in fields],
    })
    print(df)


# Displays information about a BigQuery data source
def display_datasource(datasource):
    table_ref = datasource.bigquery_table_reference
    source_name = f"{table_ref.project_id}.{table_ref.dataset_id}.{table_ref.table_id}"
    print(source_name)
    display_schema(datasource.schema)


# Handles and displays schema resolution responses
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)


# Handles and prints simple text responses
def handle_text_response(resp):
    parts = resp.parts
    print("".join(parts))


# Processes and displays different types of system messages
def show_message(msg, chart_generated_flag: list):
    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"), chart_generated_flag)
    print("\n")

7. Sohbet işlevi oluşturma

Son adım, yeniden kullanabileceğiniz bir sohbet işlevi oluşturmak ve yanıt akışındaki her parça için show_message işlevini çağırmaktır:

def stream_chat_response(question: str):
    """
    Sends a chat request, processes the streaming response, and if a chart
    was generated, starts the preview server and waits for it to be closed.
    """
    data_chat_client = geminidataanalytics.DataChatServiceClient()
    chart_generated_flag = [False]
    messages = [
        geminidataanalytics.Message(
            user_message=geminidataanalytics.UserMessage(text=question)
        )
    ]
    conversation_reference = geminidataanalytics.ConversationReference(
        conversation=data_chat_client.conversation_path(
            billing_project, location, conversation_id
        ),
        data_agent_context=geminidataanalytics.DataAgentContext(
            data_agent=data_chat_client.data_agent_path(
                billing_project, location, data_agent_id
            ),
        ),
    )
    request = geminidataanalytics.ChatRequest(
        parent=f"projects/{billing_project}/locations/{location}",
        messages=messages,
        conversation_reference=conversation_reference,
    )
    stream = data_chat_client.chat(request=request)
    for response in stream:
        show_message(response, chart_generated_flag)
    if chart_generated_flag[0]:
        preview_in_browser()

stream_chat_response işlevi artık tanımlandı ve istemlerinizle kullanılmaya hazır.

8. Start Chattin'

1. Soru

Artık soru sormaya başlayabilirsiniz. Bu temsilcinin başlangıç olarak neler yapabileceğine bakalım:

question = "Hey what data do you have access to?"
stream_chat_response(question=question)

Aracı, aşağıdakine benzer bir yanıt vermelidir:

c63ae1edc9cc3dc8.png

2. Soru

Harika. En son popüler arama terimleri hakkında daha fazla bilgi bulmaya çalışalım:

question = "What are the top 20 most popular search terms last week in NYC based on rank? Display each term and score as a column chart"
stream_chat_response(question=question)

Bu işlemin çalışması biraz zaman alabilir. Şemanın ve meta verilerin alınması, SQL sorgusunun yazılması, sonuçların alınması, görselleştirme talimatlarının belirtilmesi ve sonuçların özetlenmesi gibi çeşitli adımları uygulayan ve güncellemeleri yayınlayan aracı görebilirsiniz.

Grafiği görüntülemek için Cloud Shell araç çubuğuna gidin, "Web Önizlemesi"ni tıklayın ve 8080 numaralı bağlantı noktasını seçin:

e04d97ef6d2f7d3a.png

Görselleştirmenin aşağıdaki gibi bir oluşturulmuş halini görürsünüz:

d19b28630514a76.png

Sunucuyu kapatıp devam etmek için Enter tuşuna basın.

3. Soru

Şimdi de bu sonuçları daha ayrıntılı incelemek için bir takip sorusu soralım:

question = "What was the percent gain in growth for these search terms from the week before?"
stream_chat_response(question=question)

Aşağıdakine benzer bir ifade görürsünüz. Bu durumda, temsilci, yüzdelik kazancı bulmak için 2 tabloyu birleştirecek bir sorgu oluşturdu. Sorgunuzun biraz farklı görünebileceğini unutmayın:

1819f64371ccbf1.png

Görselleştirildiğinde ise şöyle görünür:

df7d3361f46d98fc.png

9. Temizleme

Bu codelab'de uzun süreli çalışan ürünler kullanılmadığından, terminale exit() girerek etkin Python oturumunuzu durdurmanız yeterlidir.

Proje Klasörlerini ve Dosyalarını Silme

Kodu Cloud Shell ortamınızdan kaldırmak istiyorsanız aşağıdaki komutları kullanın:

cd ~
rm -rf ca-api-codelab

API'leri devre dışı bırakma

Daha önce etkinleştirilen API'leri devre dışı bırakmak için bu komutu çalıştırın.

gcloud services disable geminidataanalytics.googleapis.com
gcloud services disable cloudaicompanion.googleapis.com
gcloud services disable bigquery.googleapis.com

10. Sonuç

CA SDK'yı kullanarak basit bir Konuşma Analizi Aracısı'nı başarıyla oluşturdunuz. Daha fazla bilgi edinmek için referans materyallerine göz atın.

Referans materyalleri: