使用 BigQuery Graph 追蹤 AI 代理的決策

1. 簡介

BigQuery Graph、BigQuery 對話式數據分析和 BigQuery Analytics SDK 目前在 Google Cloud 處於預先發布階段。BigQuery Agent Analytics 外掛程式已正式發布。本程式碼研究室中的範例使用合成資料。

隨著自主 AI 代理承擔更多營運責任 (例如評估貸款申請、管理行銷預算、核准存取要求),機構必須能夠稽核及說明其決策。重建 AI 代理決策的確切脈絡、考慮的替代方案和最終理由,對於法規遵循、風險管理和營運信任至關重要。

本程式碼研究室會使用 BigQuery Agent Analytics SDK,將原始代理程式事件記錄轉換為「代理程式環境圖」,也就是 BigQuery Graph 中可查詢的代理程式決策圖,並排定時間執行這項作業,不必使用任何外部圖形資料庫或 ETL 管道。

重要詞彙

  • 代理程式決策追蹤記錄:從代理程式的執行作業中擷取的決策層級證據,包括代理程式評估的選項、存取的資料,以及最終結果。
  • 代理程式脈絡圖:BigQuery 圖表中的可查詢型別圖表,這些追蹤記錄會具體化為該圖表。這是產業脈絡圖概念的代理範圍執行個體 (代理產生及使用的決策脈絡的長期時間連結層);「代理」限定符會將其範圍限定為您自己的代理執行,而非企業範圍的脈絡層。

在本程式碼研究室中,bqaa context-graph 會從 agent_events 中擷取代理程式的決策追蹤記錄,並將其具體化為可使用 GQL 查詢的代理程式內容圖表,遵循業界模式,從決策追蹤記錄建構內容圖表。

代理程式脈絡圖工作流程:ADK 代理程式的事件會透過 BigQuery Agent Analytics 外掛程式流入 agent_events 資料表,bqaa 脈絡圖會將代理程式的決策追蹤記錄擷取到結構化代理程式脈絡圖中,您可以使用 GQL 和對話式分析查詢該圖

建構項目

  • 代理程式內容圖 (含 BigQuery 圖),可模擬一般代理程式決策流程:收到要求、代理程式評估選項、確定結果。
  • 已填入內容的 agent_events 表格,其中包含合成事件語料庫。
  • 工作 bqaa context-graph 執行作業,可根據這些事件填入圖表。
  • 稽核樣式的 GQL 查詢,可追蹤單一決策的端對端流程。

課程內容

  • BigQuery Agent Analytics 外掛程式如何寫入 agent_events
  • 如何只透過兩個宣告式構件 (資料表 DDL 和 CREATE PROPERTY GRAPH 結構定義) 定義內容圖表。
  • 如何對 BigQuery 圖表執行 bqaa context-graph
  • 如何使用 GQL 查詢圖形。
  • SDK 支援的實際工作環境等級功能,適用於企業部署作業。

軟硬體需求

  • 已啟用計費功能的 Google Cloud 專案。
  • 該專案的擁有者或編輯者角色。您將建立 BigQuery 資料集並授予 IAM。
  • 已安裝並驗證 gcloud CLI,或可存取 Cloud Shell。
  • Python 3.10 以上版本。
  • 熟悉 BigQuery SQL。不需要具備 GQL 知識。

本程式碼研究室適合各種程度的開發人員,包括 BigQuery 圖表新手。

本程式碼研究室建立的資源費用極低,最後一個步驟會拆除所有項目,因此您不會因閒置資料集而產生費用。

預計時間:完成本程式碼研究室約需 35 分鐘。

2. 事前準備

選擇專案和區域

開啟 Cloud Shell 或本機終端機:

export PROJECT_ID="your-project-id"
export REGION="us-central1"
export DATASET="agent_analytics_demo"
gcloud config set project "$PROJECT_ID"

單一 DATASET 變數會同時保留原始 agent_events 資料表和具體化的圖表資料表。使用單一資料集可簡化程式碼研究室。實際工作環境部署作業通常會將事件和圖表分割成不同的資料集,以便針對每個資料集授予 IAM。

啟用必要 API

執行下列指令,啟用本程式碼研究室使用的 API:

gcloud services enable \
    bigquery.googleapis.com \
    aiplatform.googleapis.com \
    --project="$PROJECT_ID"

由於 SDK 的預設擷取路徑會呼叫 BigQuery 的 AI.GENERATE 函式,因此需要 aiplatform.googleapis.com API。如果您之後改用 --extraction-mode=compiled-only 進行確定性擷取,就不再需要這個 API。

建立 BigQuery 資料集

建立資料集,用來存放原始 agent_events 資料表和具體化圖表資料表:

bq --location=US mk --dataset "$PROJECT_ID:$DATASET"

畫面上應會顯示成功訊息:

Dataset 'your-project-id:agent_analytics_demo' successfully created.

如果資料集已存在,指令會無害地發生錯誤。請勿移動。

3. 安裝 SDK

設定 Python 虛擬環境,並從 PyPI 安裝 SDK

python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install bigquery-agent-analytics

bigquery-agent-analytics 套件會提取 BigQuery 用戶端程式庫,因此您只需要安裝這個套件,即可完成整個程式碼研究室。

驗證安裝狀態:

bqaa context-graph --help | head -8

畫面上應會顯示 CLI 橫幅。

驗證

如果使用工作站:

gcloud auth login
gcloud auth application-default login

Cloud Shell 使用者可以略過這個步驟,因為系統已設定憑證。

4. 取得程式碼研究室構件

本程式碼研究室只需要兩個現成可用的構件:資料表 DDL (實體圖表資料表) 和屬性圖表結構定義 (CREATE PROPERTY GRAPH)。您不需要自行編寫,程式碼研究室會直接使用這些構件,而構件資料夾中的 README 則說明如何根據自己的決策網域調整這些構件。

屬性圖表結構定義是圖表內容的單一可靠資料來源。您只需將其套用至 BigQuery 一次,之後部署的圖表本身就是合約。實體化時,bqaa context-graph 會從 BigQuery 的 INFORMATION_SCHEMA.PROPERTY_GRAPHS 讀回圖表的定義 (以及所參照資料表的結構定義),藉此判斷要擷取哪些實體和關係,以及要將這些實體和關係寫入何處,因此系統絕不會將 SQL 檔案傳遞至實體化工具。

本程式碼研究室內容完整,因此不必下載任何項目。下列指令會將內容圖 DDL 寫入目前使用的目錄。內容與 examples/context_graph/codelab/ 中出貨的構件相同。

建立目前使用的目錄:

mkdir -p ~/context-graph-codelab
cd ~/context-graph-codelab

撰寫內容圖表 DDL (context_graph_ddl.sql)。在下一個步驟中套用檔案時,系統會填入 ${PROJECT_ID} / ${DATASET} 標記。

cat > context_graph_ddl.sql <<'SQL'

-- Node and edge table DDL for the context-graph codelab.
--
-- `bqaa context-graph` writes into these tables on every run.
-- `session_id` and `extracted_at` are SDK metadata columns that
-- `bqaa context-graph` fills automatically; they are required on
-- every table behind the graph.
CREATE TABLE IF NOT EXISTS `${PROJECT_ID}.${DATASET}.decision_request` (
  request_id STRING, request_text STRING, requested_at TIMESTAMP,
  session_id STRING, extracted_at TIMESTAMP
);
CREATE TABLE IF NOT EXISTS `${PROJECT_ID}.${DATASET}.decision_option` (
  option_id STRING, option_label STRING, confidence FLOAT64,
  session_id STRING, extracted_at TIMESTAMP
);
CREATE TABLE IF NOT EXISTS `${PROJECT_ID}.${DATASET}.decision_outcome` (
  outcome_id STRING, status STRING, rationale STRING, decided_at TIMESTAMP,
  session_id STRING, extracted_at TIMESTAMP
);
CREATE TABLE IF NOT EXISTS `${PROJECT_ID}.${DATASET}.evaluates_option` (
  request_id STRING, option_id STRING,
  session_id STRING, extracted_at TIMESTAMP
);
CREATE TABLE IF NOT EXISTS `${PROJECT_ID}.${DATASET}.resulted_in` (
  request_id STRING, outcome_id STRING,
  session_id STRING, extracted_at TIMESTAMP
);

-- Graph DDL for the context-graph codelab.
--
-- Models a generic agent decision flow:
--   DecisionRequest -> evaluatesOption -> DecisionOption
--   DecisionRequest -> resultedIn       -> DecisionOutcome
CREATE OR REPLACE PROPERTY GRAPH `${PROJECT_ID}.${DATASET}.agent_decisions_graph`
  NODE TABLES (
    `${PROJECT_ID}.${DATASET}.decision_request` AS decision_request
      KEY (request_id)
      LABEL DecisionRequest PROPERTIES (request_id, request_text, requested_at),
    `${PROJECT_ID}.${DATASET}.decision_option` AS decision_option
      KEY (option_id)
      LABEL DecisionOption PROPERTIES (option_id, option_label, confidence),
    `${PROJECT_ID}.${DATASET}.decision_outcome` AS decision_outcome
      KEY (outcome_id)
      LABEL DecisionOutcome PROPERTIES (outcome_id, status, rationale, decided_at)
  )
  EDGE TABLES (
    `${PROJECT_ID}.${DATASET}.evaluates_option` AS evaluates_option
      KEY (request_id, option_id)
      SOURCE KEY (request_id) REFERENCES decision_request (request_id)
      DESTINATION KEY (option_id) REFERENCES decision_option (option_id)
      LABEL evaluatesOption,
    `${PROJECT_ID}.${DATASET}.resulted_in` AS resulted_in
      KEY (request_id, outcome_id)
      SOURCE KEY (request_id) REFERENCES decision_request (request_id)
      DESTINATION KEY (outcome_id) REFERENCES decision_outcome (outcome_id)
      LABEL resultedIn
  );
SQL

確認檔案位置:

ls

您應該會看到一個檔案:

context_graph_ddl.sql

他們描述的決策流程有三種節點類型和兩個異質邊緣:

程式碼研究室的圖表結構定義:DecisionRequest 節點會透過 evaluatesOption 邊緣連結至所評估的 DecisionOption 節點,並透過 resultedIn 邊緣連結至已提交的 DecisionOutcome

DecisionRequest 是代理收到的問題。DecisionOption 是代理人考慮的替代方案之一。DecisionOutcome 會記錄已確定的選擇和理由。

5. 套用屬性圖結構定義

bqaa context-graph 會寫入 BigQuery 資料表,因此必須在第一次執行前存在。context_graph_ddl.sql 會先建立五個資料表,然後建立參照這些資料表的屬性圖 (BigQuery 會拒絕指向不存在資料表的 CREATE PROPERTY GRAPH),因此單一套用會設定所有項目:

envsubst < context_graph_ddl.sql | bq query --use_legacy_sql=false

您應該會看到五個 CREATE TABLE 結果和一個 CREATE PROPERTY GRAPH 結果。DDL 具有冪等性,因此可以安全地重新執行。

這就是您唯一需要進行的結構定義作業,也是唯一會使用這些 SQL 檔案的時機。BigQuery 現在會記錄圖表的定義,而 bqaa context-graph 會依名稱從 INFORMATION_SCHEMA.PROPERTY_GRAPHS 讀取定義。沒有要傳遞給具體化工具的個別檔案,而且您使用 GQL 查詢的內容與具體化的內容絕不會不同,因為兩者是相同的已部署圖形。

6. 產生範例代理程式事件

在正式環境中,BigQuery Agent Analytics 外掛程式會在 ADK 代理執行時自動擷取事件。這個程式碼片段僅供參考,您不會在本程式碼研究室中運作執行:

from google.adk.plugins import BigQueryAgentAnalyticsPlugin

plugin = BigQueryAgentAnalyticsPlugin(
    project_id="your-project-id",
    dataset_id="agent_analytics_demo",
)
runner = Runner(agent=root_agent, plugins=[plugin])

在本程式碼研究室中,您會使用小型合成事件產生器,將相同形狀的資料列直接寫入 agent_events。執行:

bqaa seed-events \
    --project-id "$PROJECT_ID" \
    --dataset-id "$DATASET" \
    --sessions 5

這項指令會列印 JSON 報表。5 個工作階段應會顯示 "events_generated": 30"events_inserted": 30"ok": true

在同一列中一覽語料庫,包括工作階段數、事件數和時間範圍:

bq query --use_legacy_sql=false \
    "SELECT COUNT(DISTINCT session_id) AS sessions, COUNT(*) AS events, MIN(timestamp) AS earliest_event, MAX(timestamp) AS latest_event FROM \`$PROJECT_ID.$DATASET.agent_events\`"

如果是預設的 5 個工作階段,這會顯示 5 個工作階段和 30 個事件,時間跨度為幾分鐘。(請在下方模擬實際情況,並查詢報表,大約三天內會顯示 100 個工作階段)。

確認事件是否已登陸:

bq query --use_legacy_sql=false \
    "SELECT event_type, COUNT(*) AS n FROM \`$PROJECT_ID.$DATASET.agent_events\` GROUP BY event_type ORDER BY n DESC"

您應該會看到 25 個 TOOL_COMPLETED 列和 5 個 AGENT_COMPLETED 列 (每個工作階段會發出一個 submit_request、三個 evaluate_option、一個 commit_outcome 和一個結尾 AGENT_COMPLETED,也就是每個工作階段五個工具事件加上一個代理終止符)。AGENT_COMPLETED 列是終端機事件偵測的 bqaa context-graph 鍵。

選用:實際規模的資料

上述 5 個工作階段的語料庫刻意縮小,因此第一次執行時速度快且成本低。如要取得生產環境形狀的資料 (多個代理和使用者分散在幾天內,且有失敗、孤立和截斷的工作階段),請使用 decision-realistic 案例。預設值為 72 小時內 100 個工作階段,上述首次執行路徑維持不變。

bqaa seed-events \
    --project-id "$PROJECT_ID" \
    --dataset-id "$DATASET" \
    --scenario decision-realistic \
    --sessions 100 \
    --seed 42

JSON 報表的 session_outcome_counts 會顯示組合,大約是 {"success": 70, "failed": 10, "orphaned": 10, "truncated": 10}

從資料列分類每個工作階段,確認結果分布情形 (孤立 = 無 AGENT_COMPLETED;失敗 = AGENT_COMPLETED 且有 status = 'error';截斷 = 任何有 is_truncated = true 的資料列;否則為成功)。第一階段會分類每個工作階段,第二階段則會依結果匯總:

bq query --use_legacy_sql=false \
    "WITH per_session AS (SELECT session_id, CASE WHEN COUNTIF(event_type = 'AGENT_COMPLETED') = 0 THEN 'orphaned' WHEN COUNTIF(event_type = 'AGENT_COMPLETED' AND status = 'error') > 0 THEN 'failed' WHEN COUNTIF(is_truncated) > 0 THEN 'truncated' ELSE 'success' END AS outcome FROM \`$PROJECT_ID.$DATASET.agent_events\` GROUP BY session_id) SELECT outcome, COUNT(*) AS sessions FROM per_session GROUP BY outcome ORDER BY outcome"

您應該會看到大約 70 個成功、10 個失敗、10 個孤立和 10 個截斷的項目 (如果您先前在同一個資料集中植入第一個執行階段的語料庫,還會看到 5 個成功項目)。

這 10 個孤立工作階段從未發出 AGENT_COMPLETED,因此預設 bqaa context-graph 執行會略過這些工作階段 (只會具體化終止事件關閉的工作階段)。如要將這些錯誤顯示為 session_orphaned,而不是永遠默默重試,請在運作執行時新增 --max-session-age-hours,詳情請參閱「投入實際工作環境」一文中的 --max-session-age-hours

7. 具體化脈絡圖

bqaa context-graph 會讀取原始 agent_events,然後直接從已部署的圖表衍生要擷取的內容:它會從 BigQuery 的 INFORMATION_SCHEMA.PROPERTY_GRAPHS 讀取您在「套用屬性圖表結構定義」中套用的 CREATE PROPERTY GRAPH 定義,將其與所參照資料表的結構定義聯結,計算出實體、關係和資料欄類型,並填入圖表資料表。您可以使用 --graph agent_decisions_graph 依名稱指向已部署的圖表,不必傳遞 SQL 檔案。

跑步

bqaa context-graph 本地:

bqaa context-graph \
    --project-id "$PROJECT_ID" \
    --dataset-id "$DATASET" \
    --graph agent_decisions_graph \
    --lookback-hours 24 \
    --format json

您應該會看到結構化的 JSON 報告:

{
  "run_id": "...",
  "sessions_discovered": 5,
  "sessions_materialized": 5,
  "sessions_failed": 0,
  "rows_materialized": {
    "DecisionRequest": 5,
    "DecisionOption": 15,
    "DecisionOutcome": 5
  },
  "ok": true
}

ok: true 表示 bqaa context-graph 找到五個已完成的工作階段,透過 AI.GENERATE 從每個工作階段擷取決策流程,並將對應的資料列寫入圖表資料表。確定性擷取 (--extraction-mode=compiled-only,下文會說明) 會傳回相同的報表形狀 (相同欄位、相同 ok: true),只是會略過 AI.GENERATE 呼叫。

疑難排解:擷取內容為空白

如果看到 ok: falseerror_code = "empty_extraction",最常見的原因是 aiplatform.googleapis.com API 尚未生效,或是帳戶缺少 roles/aiplatform.user。請稍候再試,或授予角色:

USER_EMAIL=$(gcloud auth list --filter=status:ACTIVE --format="value(account)")
gcloud projects add-iam-policy-binding "$PROJECT_ID" \
    --member="user:$USER_EMAIL" --role="roles/aiplatform.user"

接著重新執行上述 bqaa context-graph 指令。

確認圖表有資料列:

bq query --use_legacy_sql=false \
    "SELECT COUNT(*) AS n FROM \`$PROJECT_ID.$DATASET.decision_request\`"

畫面上應該會顯示五列。這五個工作階段總共是 25 個圖表節點 (5 個 DecisionRequest、15 個 DecisionOption 和 5 個 DecisionOutcome),以及 15 個 evaluatesOption 邊緣和 5 個 resultedIn 邊緣 (每個工作階段一個決策網)。

從事件中擷取決策的兩種方式

bqaa context-graph 提供兩種擷取路徑。請選擇符合工作負載需求的方案:

  • 預設擷取。最簡單的途徑。使用 BigQuery 的 AI.GENERATE 讀取事件內容,並推斷實體和關係。可針對任何事件形狀運作,無需額外程式碼。本程式碼研究室會使用這個版本。
  • 確定性擷取 (--extraction-mode=compiled-only)。這是成本較低且適合稽核的路徑。使用您為網域編寫的小型 Python 參照擷取器。無須呼叫 Vertex AI,不需支付權杖費用,輸出內容完全可重現。如果成本可預測性或嚴格重現性很重要,生產環境部署作業會選擇這個選項。

脈絡圖部署指南是這兩種路徑的參考資料,包括 IAM 詳細資料和如何編寫參照擷取器。

8. 查詢決策追蹤記錄

圖表填入資料後,您就可以直接回答稽核問題。舉例來說:「針對每項要求,服務專員權衡了哪些選項,以及如何解決問題?」在 GQL 中,這是指對要求、選項和結果的單一遍歷。

將查詢寫入檔案 (traversal.sql)。在下一個步驟中執行查詢時,系統會填入 ${DATASET} 標記:

cat > traversal.sql <<'SQL'
SELECT *
FROM GRAPH_TABLE (
  ${DATASET}.agent_decisions_graph
  MATCH
    (req:DecisionRequest) -[eo:evaluatesOption]-> (opt:DecisionOption),
    (req)                 -[ri:resultedIn]->      (out:DecisionOutcome)
  COLUMNS (
    req.request_id   AS request,
    req.request_text AS question,
    opt.option_label AS considered,
    opt.confidence   AS score,
    out.status       AS outcome,
    out.rationale    AS rationale
  )
);
SQL

運作執行:

envsubst < traversal.sql | bq query --use_legacy_sql=false --max_rows=20

您應該會看到十五列:每個要求有三個選項,共五個要求。每列都會顯示要求、代理程式考慮的選項、信賴分數、最終結果和基本原理。

如要瞭解單一決策的完整情況,請依 request_id 篩選,取得稽核團隊所需的資料列集:收到的問題、權衡的選項 (附有分數) 和已提交的理由。

在 BigQuery Studio 中以圖表呈現

BigQuery Studio 也能以視覺化方式呈現圖表。在 BigQuery 控制台中開啟 BigQuery Studio,執行下列路徑查詢,然後將結果窗格切換至「圖表」分頁,即可查看決策網。有了這個實際規模的語料庫,您就能取得要求、選項和結果的視覺化地圖:

GRAPH agent_analytics_demo.agent_decisions_graph
MATCH p = (a)-[e]->(b)
RETURN TO_JSON(p) AS path_json

從 GQL 路徑查詢在 BigQuery Studio 的「圖表」檢視畫面中算繪的具體化內容圖表

以簡單的英文提問

並非所有稽核讀取者都會編寫 GQL。透過 BigQuery 對話式數據分析 (預先發布版),法規遵循團隊可以自然語言提出相同類型的問題,並取得結構化答案資訊卡,不必學習查詢語法,也不必瞭解聯結。

agent_decisions_graph (連同 agent_events 和決策表) 註冊為對話式數據分析資料來源,然後直接提出稽核問題:

稽核問題 (簡單用語): 「哪些要求從未達成已承諾的結果?」

對話式分析會根據圖表進行推論、為您編寫 SQL,並以直白的英文回覆,附上支援的表格。在下例中,表格顯示每項記錄的要求都達到預期結果:

對話式數據分析在脈絡圖上回答「哪些要求從未達成已承諾的結果?」:所有記錄的要求都已達成已承諾的結果 (孤立無援的工作階段不會具體化為圖形節點)

上述回覆反映了選用「realistic-scale data」(實際規模資料)步驟中的實際規模語料庫 (90 個具體化要求,全數已提交);實際數字取決於您播種的語料庫,而預設的 5 個工作階段執行作業會顯示五個。

如需設定方式,請參閱對話式數據分析說明文件

9. 實際推出

上述本機執行作業使用預設行為,已涵蓋實際部署作業的基本事項:每次執行都會留下稽核追蹤記錄 (結構化 Cloud Logging,以及資料集狀態表中的每次執行資料列)、暫時性失敗會自動重試,且進度只會在工作階段完全成功時推進,因此不會重複計算。

製作控制項 (確定性擷取 (--extraction-mode=compiled-only)、偵測卡住的工作階段 (--max-session-age-hours)、一次性重播過去的視窗 (--backfill --from / --to,與一般重新整理分開追蹤,因此不會干擾直播時間表),以及每次執行的批次界限 (--max-sessions)) 是您需要時可選擇使用的旗標。脈絡圖部署指南會記錄每個步驟,並提供完整的 IAM 矩陣和建議時間表。

10. 清理

拆除您建立的項目,以免系統針對閒置資料集收費:

bq rm -r -f --dataset "$PROJECT_ID:$DATASET"

這項單一指令會一併移除資料集、代理程式事件、圖表資料表和狀態資料表。

11. 恭喜

恭喜!您已將原始代理程式事件記錄轉換為可查詢的代理程式內容圖表,並端對端追蹤單一決策,無需外部圖表資料庫或 ETL 管道。

凡是代理程式做出重大決策的領域,都適用相同的模式:信用評估、事前授權、行銷預算調動、採購、客戶服務和內部 IT。如要建構自己的代理程式脈絡圖,請複製 Codelab 構件做為起點,根據您的網域調整兩個宣告式檔案 (資料表 DDL + CREATE PROPERTY GRAPH 架構),然後套用至 BigQuery - bqaa context-graph --graph 會從 INFORMATION_SCHEMA 讀取已部署的圖表,並推導出其餘部分。

目前所學內容

  • 如何建立 BigQuery 資料集,並套用描述代理程式決策領域的屬性圖表結構定義。
  • 如何使用合成事件語料庫填入 agent_events
  • 如何執行 bqaa context-graph,從這些事件將代理的決策追蹤記錄擷取到代理內容圖表中,並從 INFORMATION_SCHEMA 讀回圖表定義。
  • 如何使用 GQL 查詢產生的圖表,以及如何閱讀稽核風格的答案。

參考文件