查看 Gemini Code Assist 記錄

在 Cloud Logging 收集 Gemini Code Assist 活動記錄,即可稽核開發人員提示詞、模型回覆和中繼資料記錄,例如:遙測資料和接受的程式碼行數。您可以查詢這些記錄項目,評估整個組織的助理互動情形。如要追蹤匯總趨勢,而非原始記錄,請參閱「監控 Gemini Code Assist 用量」。

Gemini Code Assist 不會收集或傳送使用者與 Gemini Code Assist 的任何其他互動 (包括撰寫的意見回饋) 至 Cloud Logging。收集到的資料會傳送至 Cloud Logging 儲存。您可以搜尋資源類型為 cloudaicompanion.googleapis.com/Instance 的記錄項目,查看這項資料。

這項功能不會在 Vertex AI 的 Gemini 中記錄提示或回覆。如要啟用 Vertex AI 中 Gemini 的記錄,請參閱「啟用資料存取稽核記錄」。

Identity and Access Management (IAM) 角色可控管主體存取記錄檔的能力。您可以將預先定義的角色授予主體,也可以建立自訂角色。如要進一步瞭解必要權限,請參閱「存取控管」。

Cloud Logging 預設會加密靜態儲存的客戶內容。Logging 儲存在記錄檔 bucket 中的資料會以金鑰加密金鑰進行加密,這個程序稱為「信封式加密」。如要存取記錄資料,必須具備對應的金鑰加密金鑰存取權。這類金鑰由 Google 代管,您無須採取任何行動。

貴組織可能有法規、法規遵循相關或進階加密需求,而預設的靜態資料加密無法滿足這些需求。為滿足貴機構的需求,您可以自行管理加密金鑰,而非由 Google 管理用來保護資料的金鑰。

如要瞭解如何使用客戶自行管理的加密金鑰 (CMEK),包括優點和限制,請參閱「客戶自行管理的加密金鑰」。

限制

  • Gemini Code Assist 記錄資料的記錄範圍,僅限於使用者在 IDE 內與 Gemini Code Assist 的互動。

  • 根據預設,Gemini Code Assist 記錄會依專案收集。如要瞭解如何設定集中式專案,從多個專案收集記錄,請參閱「設定多專案記錄」。

事前準備

查看 Gemini Code Assist 使用者記錄和中繼資料記錄

如要查看 Gemini Code Assist 使用者記錄和中繼資料記錄,請執行下列其中一項操作:

控制台

  1. 前往 Google Cloud 控制台的 「Logs Explorer」頁面:

    前往「Logs Explorer」(記錄檔探索工具)

    如果您是使用搜尋列尋找這個頁面,請選取子標題為「Logging」的結果。

  2. 在工具列中選取 Google Cloud 控制台專案。
  3. 在工具列中展開「所有資源」選單,然後選取「Cloud AI Companion Instance」資源。

gcloud

執行下列指令:

gcloud logging read "resource.type=cloudaicompanion.googleapis.com/Instance" --project PROJECT_ID  --limit 3

將 PROJECT_ID 替換為要查看 Gemini Code Assist 記錄的專案 ID。

API

  1. 建立包含下列資訊的 JSON 檔案:

      {
        "resourceNames": [
          "projects/PROJECT_ID"
        ],
        "pageSize": 5,
        "filter": "resource.type: cloudaicompanion.googleapis.com/Instance"
      }
    

    將 PROJECT_ID 替換為要查看 Gemini Code Assist 記錄的專案 ID。

  2. 取得驗證權杖:

    TOKEN=$(gcloud auth print-access-token)
    
  3. 使用 cURL 呼叫 entries.list 方法:

    curl -X POST --data-binary @JSON_FILE_NAME \
      -H "Authorization: Bearer $TOKEN" \
      -H "Content-Type: application/json" \
      "https://logging.googleapis.com/v2/entries:list"

    將 JSON_FILE_NAME 替換為您在上一個步驟中建立的 JSON 檔案路徑。

    如要進一步瞭解驗證,請參閱「使用 REST 進行驗證」。

    回應會傳回一組記錄項目。

Gemini Code Assist 記錄

LogEntry 是 Cloud Logging 的基本資料單位。下列各節列出 Gemini Code Assist 平台事件 (例如使用者要求和 Gemini Code Assist 回覆) 的 LogEntry 欄位。

使用者要求數

下表列出使用者要求記錄項目中的欄位:

欄位 值和備註
LogEntry.resource.type Gemini Code Assist 資源類型:cloudaicompanion.googleapis.com/Instance。
LogEntry.resource.labels.resource_container 使用 Gemini Code Assist 的資源容器專屬 ID。
LogEntry.resource.labels.location 使用 Gemini Code Assist 的位置。
LogEntry.resource.labels.instance_id 使用 Gemini Code Assist 的資源專屬 ID。
LogEntry.labels.method 視叫用 logEntry 的項目而定,可能為下列其中一項:

CompleteTask:例如來自 Gemini Code Assist 的對話要求。

GenerateCode:例如生成程式碼的要求,像是 Gemini Code Assist 中的程式碼轉換要求。

CompleteCode:例如在 IDE 中工作時完成程式碼的要求,像是 Gemini Code Assist 中的內嵌建議。
LogEntry.labels.product 記錄檔適用的服務名稱。與 Gemini Code Assist 使用情形相關的記錄會使用產品值 code_assist。如果記錄與 Gemini Cloud Assist 相關,這個值會是 cloud_assist。否則,這個值為 unknown。
LogEntry.labels.request_id 用來建立要求與回覆記錄項目關聯的專屬 ID。
LogEntry.labels.user_id 發起這項要求的使用者 ID。
LogEntry.jsonPayload 記錄項目的酬載。
LogEntry.logName 識別記錄。

以下範例顯示聊天提示事件的記錄項目:

{
  "insertId": "654581e30003b19e340bbd96",
  "resource": {
    "type": "cloudaicompanion.googleapis.com/Instance",
    "labels": {
        instance_id: "default"
        location: "global"
        resource_container: "my-project-id"
     }
  },
  "timestamp": "2023-11-03T23:27:31.242078Z",
  "labels": {
    "product": "code_assist",
    "request_id": "4ea1e265-ea5d-4d11-b3c8-39bad9c96326"
    "user_id": "user@company.com"
  },
  "jsonPayload" : {
    @type: "type.googleapis.com/google.cloud.cloudaicompanion.logging.v1.RequestLog"
    "taskCompletionRequest":
      input: {
        messages: [{
          author: "USER"
          content: "What are some best practices to save cost on my Google Cloud bill?"
        }]
        preamble: ""
      }
  }
  "logName": "projects/my-project-id/logs/cloudaicompanion.googleapis.com%2Frequest",
  "receiveTimestamp": "2023-11-03T23:27:31.255648319Z"
  "severity": "INFO"
}

以下範例顯示自動RequestLog項目的範例項目,適用於內嵌程式碼建議提示和在程式碼檔案中提示 Gemini Code Assist。

內嵌程式碼建議的提示資料會使用 codeCompletionRequest 物件 (如下列範例所示),手動觸發的生成作業則會使用 codeGenerationRequest。

{
  "insertId": "654581e30003b19e340bbd96",
  "resource": {
    "type": "cloudaicompanion.googleapis.com/Instance",
    "labels": {
        instance_id: "default"
        location: "global"
        resource_container: "my-project-id"
     }
  },
  "timestamp": "2023-11-03T23:27:31.242078Z",
  "labels": {
    "product": "code_assist",
    "request_id": "4ea1e265-ea5d-4d11-b3c8-39bad9c96326"
    "user_id": "user@company.com"
  },
  "jsonPayload" : {
    @type: "type.googleapis.com/google.cloud.cloudaicompanion.logging.v1.RequestLog"
    "codeCompletionRequest": {
      "input_data_context": {
        "additional_context": {
          "files": [
            {
              "language": "go",
              "path": "{/path/to/../current-file.go",
              "segments": [
                {
                  "content": "...Prefix Text..."
                },
                {
                  "content": "...Suffix Text..."
                }
              ],
              "state": ["EDITED"]
            },
            {
              "language": "go",
              "path": "/path/to/../recent-file.go",
              "segments": [
                {
                  "content": "...File Text..."
                }
              ],
              "state": ["RECENTLY_OPENED"]
            }
          ]
        }
      }
    }
  }
  "logName": "projects/my-project-id/logs/cloudaicompanion.googleapis.com%2Frequest",
  "receiveTimestamp": "2023-11-03T23:27:31.255648319Z"
  "severity": "INFO"
}

代理互動記錄

與 Gemini 互動時,單一使用者動作可能會產生多筆記錄項目 (要求、回應和中繼資料)。這類互動包括:

  • 代理執行涉及工具使用的任務 (例如模型叫用內部函式,如記錄範例中的 read_file 或 replace)。
  • 代理與其他代理互動。
要求記錄項目

以下範例顯示啟動代理程式互動的要求記錄項目:

{
  "insertId": "qe9xxub2r",
  "jsonPayload": {
    "taskCompletionRequest": {
      "input": {
        "messages": [
          {
            "author": "USER",
            "content": "hi can you add one test here\nCurrent File Path:\n```cpp\n/usr/local/google/home/pdec/test.cpp\n```\n\n"
          }
        ],
        "preamble": ""
      }
    },
    "@type": "type.googleapis.com/google.cloud.cloudaicompanion.logging.v1.RequestLog"
  },
  "resource": {
    "type": "cloudaicompanion.googleapis.com/Instance",
    "labels": {
      "resource_container": "my-project-id",
      "instance_id": "default",
      "location": "global"
    }
  },
  "timestamp": "2025-10-08T10:09:52.225165428Z",
  "severity": "INFO",
  "labels": {
    "request_id": "e60facb1485b17b7",
    "client_version": "unknown",
    "product": "code_assist",
    "method": "CompleteTask",
    "user_id": "user@company.com",
    "client_name": "cloudcode_cli"
  },
  "logName": "projects/my-project-id/logs/cloudaicompanion.googleapis.com%2Frequest",
  "receiveTimestamp": "2025-10-08T10:09:52.581787548Z"
}
回覆記錄項目

以下範例顯示代理程式互動的回應記錄項目,其中包含多則訊息:

{
  "insertId": "qe9xxub2t",
  "jsonPayload": {
    "@type": "type.googleapis.com/google.cloud.cloudaicompanion.logging.v1.ResponseLog",
    "taskCompletionResponse": {
      "output": {
        "messages": [
          {
            "content": "**Reading File Contents**\n\nI'm currently focused on reading the contents of `/usr/local/google/home/pdec/test.cpp`. This will inform what kind of test needs to be written and how it should be structured.\n\n\n",
            "author": "MODEL"
          },
          {
            "author": "MODEL",
            "content": "**File Inspection Begins**\n\nI've initiated the process of reading the test file. My immediate goal is to grasp its existing structure and identify the testing framework, if one exists. This will directly influence the design of the new test case I'll be adding.\n\n\n"
          },
          {
            "author": "MODEL",
            "content": "Of course. What is the test about? I'll read the file to understand the context."
          },
          {
            "content": "read_file({\"absolute_path\":\"/usr/local/google/home/pdec/test.cpp\"})",
            "author": "MODEL"
          }
        ]
      }
    }
  },
  "resource": {
    "type": "cloudaicompanion.googleapis.com/Instance",
    "labels": {
      "resource_container": "my-project-id",
      "instance_id": "default",
      "location": "global"
    }
  },
  "timestamp": "2025-10-08T10:09:52.227354297Z",
  "severity": "INFO",
  "labels": {
    "product": "code_assist",
    "request_id": "e60facb1485b17b7",
    "user_id": "user@company.com",
    "client_version": "unknown",
    "method": "CompleteTask",
    "client_name": "cloudcode_cli"
  },
  "logName": "projects/my-project-id/logs/cloudaicompanion.googleapis.com%2Fresponse",
  "receiveTimestamp": "2025-10-08T10:09:52.581787548Z"
}
中繼資料記錄項目

以下範例顯示代理互動的中繼資料記錄項目:

{
  "insertId": "qe9xxub2s",
  "jsonPayload": {
    "apiRequest": {},
    "clientName": "cloudcode_cli",
    "requestId": "e60facb1485b17b7",
    "@type": "type.googleapis.com/google.cloud.cloudaicompanion.logging.v1.MetadataLog",
    "clientVersion": "unknown"
  },
  "resource": {
    "type": "cloudaicompanion.googleapis.com/Instance",
    "labels": {
      "location": "global",
      "instance_id": "default",
      "resource_container": "my-project-id"
    }
  },
  "timestamp": "2025-10-08T10:09:52.226420727Z",
  "severity": "INFO",
  "labels": {
    "method": "CompleteTask",
    "product": "code_assist",
    "user_id": "user@company.com"
  },
  "logName": "projects/my-project-id/logs/cloudaicompanion.googleapis.com%2Fmetadata",
  "receiveTimestamp": "2025-10-08T10:09:52.581787548Z"
}

以下範例顯示代理互動的另一個記錄項目範例,要求 ID 為 4b66a582bad9cf2c:

要求記錄項目

{
  "insertId": "4qvt8nb2k",
  "jsonPayload": {
    "taskCompletionRequest": {
      "input": {
        "messages": [
          {
            "author": "USER",
            "content": "FunctionResponse{name: read_file, response: {\"output\":\"#include <iostream>\\n\\n// Function to calculate the greatest common divisor (GCD) of two numbers.\\nint gcd(int a, int b) {\\n    if (b == 0) {\\n        return a;\\n    }\\n    return gcd(b, a % b);\\n}\\n\\n// Function to calculate the least common multiple (LCM) of two numbers.\\nint lcm(int a, int b) {\\n    return (a * b) / gcd(a, b);\\n}\\n\\n// Function to check if a number is prime.\\nint is_prime(int a) {\\n    if (a < 2) {\\n        return 0;\\n    }\\n    for (int i = 2; i * i <= a; ++i) {\\n        if (a % i == 0) {\\n            return 0;\\n        }\\n    }\\n    return 1;\\n}\\n\\n// Function for extended Euclidean algorithm.\\nint extended_gcd(int a, int b, int &x, int &y) {\\n    if (b == 0) {\\n        x = 1;\\n        y = 0;\\n        return a;\\n    }\\n    int x1, y1;\\n    int d = extended_gcd(b, a % b, x1, y1);\\n    x = y1;\\n    y = x1 - (a / b) * y1;\\n    return d;\\n}\\n\\n// Test function\\nvoid run_tests() {\\n    // Test gcd\\n    if (gcd(10, 15) == 5) {\\n        std::cout << \\\"gcd(10, 15) passed\\\" << std::endl;\\n    } else {\\n        std::cout << \\\"gcd(10, 15) failed\\\" << std::endl;\\n    }\\n\\n    // Test lcm\\n    if (lcm(10, 15) == 30) {\\n        std::cout << \\\"lcm(10, 15) passed\\\" << std::endl;\\n    } else {\\n        std::cout << \\\"lcm(10, 15) failed\\\" << std::endl;\\n    }\\n\\n    // Test is_prime\\n    if (is_prime(7) == 1) {\\n        std::cout << \\\"is_prime(7) passed\\\" << std::endl;\\n    } else {\\n        std::cout << \\\"is_prime(7) failed\\\" << std::endl;\\n    }\\n    if (is_prime(10) == 0) {\\n        std::cout << \\\"is_prime(10) passed\\\" << std::endl;\\n    } else {\\n        std::cout << \\\"is_prime(10) failed\\\" << std::endl;\\n    }\\n\\n    // Test extended_gcd\\n    int x, y;\\n    int g = extended_gcd(35, 15, x, y);\\n    if (g == 5 && 35 * x + 15 * y == g) {\\n        std::cout << \\\"extended_gcd(35, 15) passed\\\" << std::endl;\\n    } else {\\n        std::cout << \\\"extended_gcd(35, 15) failed\\\" << std::endl;\\n    }\\n\\n    // Test is_prime with 1\\n    if (is_prime(1) == 0) {\\n        std::cout << \\\"is_prime(1) passed\\\" << std::endl;\\n    } else {\\n        std::cout << \\\"is_prime(1) failed\\\" << std::endl;\\n    }\\n\\n    // Test is_prime with 9\\n    if (is_prime(9) == 0) {\\n        std::cout << \\\"is_prime(9) passed\\\" << std::endl;\\n    } else {\\n        std::cout << \\\"is_prime(9) failed\\\" << std::endl;\\n    }\\n\\n    // Test is_prime with 13\\n    if (is_prime(13) == 1) {\\n        std::cout << \\\"is_prime(13) passed\\\" << std::endl;\\n    } else {\\n        std::cout << \\\"is_prime(13) failed\\\" << std::endl;\\n    }\\n\\n    // Test lcm with 7 and 9\\n    if (lcm(7, 9) == 63) {\\n        std::cout << \\\"lcm(7, 9) passed\\\" << std::endl;\\n    } else {\\n        std::cout << \\\"lcm(7, 9) failed\\\" << std::endl;\\n    }\\n\\n    // Test gcd with 12 and 18\\n    if (gcd(12, 18) == 6) {\\n        std::cout << \\\"gcd(12, 18) passed\\\" << std::endl;\\n    } else {\\n        std::cout << \\\"gcd(12, 18) failed\\\" << std::endl;\\n    }\\n\\n    // Test gcd with two primes\\n    if (gcd(7, 13) == 1) {\\n        std::cout << \\\"gcd(7, 13) passed\\\" << std::endl;\\n    } else {\\n        std::cout << \\\"gcd(7, 13) failed\\\" << std::endl;\\n    }\\n\\n    // Test is_prime with 97\\n    if (is_prime(97) == 1) {\\n        std::cout << \\\"is_prime(97) passed\\\" << std::endl;\\n    } else {\\n        std::cout << \\\"is_prime(97) failed\\\" << std::endl;\\n    }\\n\\n    // Test extended_gcd with 48 and 18\\n    int x2, y2;\\n    int g2 = extended_gcd(48, 18, x2, y2);\\n    if (g2 == 6 && 48 * x2 + 18 * y2 == g2) {\\n        std::cout << \\\"extended_gcd(48, 18) passed\\\" << std::endl;\\n    } else {\\n        std::cout << \\\"extended_gcd(48, 18) failed\\\" << std::endl;\\n    }\\n\\n    // Test gcd with 27 and 18\\n    if (gcd(27, 18) == 9) {\\n        std::cout << \\\"gcd(27, 18) passed\\\" << std::endl;\\n    } else {\\n        std::cout << \\\"gcd(27, 18) failed\\\" << std::endl;\\n    }\\n    // test 999 and 123\\n    if (gcd(999, 123) == 3) {\\n        std::cout << \\\"gcd(999, 123) passed\\\" << std::endl;\\n    } else {\\n        std::cout << \\\"gcd(999, 123) failed\\\" << std::endl;\\n    }\\n    \\n    \\n}\\n\\nint main() {\\n    run_tests();\\n    return 0;\\n}\"}}"
          }
        ],
        "preamble": ""
      }
    },
    "@type": "type.googleapis.com/google.cloud.cloudaicompanion.logging.v1.RequestLog"
  },
  "resource": {
    "type": "cloudaicompanion.googleapis.com/Instance",
    "labels": {
      "resource_container": "my-project-id",
      "instance_id": "default",
      "location": "global"
    }
  },
  "timestamp": "2025-10-08T10:10:03.457717366Z",
  "severity": "INFO",
  "labels": {
    "request_id": "4b66a582bad9cf2c",
    "method": "CompleteTask",
    "client_version": "unknown",
    "product": "code_assist",
    "client_name": "cloudcode_cli",
    "user_id": "user@company.com"
  },
  "logName": "projects/my-project-id/logs/cloudaicompanion.googleapis.com%2Frequest",
  "receiveTimestamp": "2025-10-08T10:10:03.606059154Z"
}

回應記錄項目

{
  "insertId": "4qvt8nb2m",
  "jsonPayload": {
    "taskCompletionResponse": {
      "output": {
        "messages": [
          {
            "author": "MODEL",
            "content": "**Testing the functions**\\n\\nI'm focusing on adding a new test case to `test.cpp`.  The existing `run_tests` function is a great starting point. I'm considering which function to test further – maybe `extended_gcd`? I'll review the current tests for that function and then devise a new test scenario to add.\\n\\n\\n"
          },
          {
            "author": "MODEL",
            "content": "**Evaluating LCM Test**\\n\\nI've finalized the new test case for the `lcm` function within the `test.cpp` file.  I'm adding a test for `lcm(12, 18)` to confirm the result is 36. I plan to use the `replace` command to inject this new test directly before the closing brace of the `run_tests` function.  I've identified a unique line in `test.cpp` as the anchor for replacement.\\n\\n\\n"
          },
          {
            "author": "MODEL",
            "content": "**Inserting the new test**\\n\\nI've created a test case for `lcm(12, 18)`, confirming the expected result of 36. To implement this, I'm targeting the `run_tests` function.  I'll use the `replace` command and will search the end of the `run_tests` function to inject the new test, right before the closing brace.  I'm ready to implement this and confirm that it passes.\\n\\n\\n"
          },
          {
            "author": "MODEL",
            "content": "I've reviewed the file. I'll add a test case for the `lcm` function with inputs 12 and 18."
          },
          {
            "content": "replace({\"file_path\":\"/usr/local/google/home/pdec/test.cpp\",\"instruction\":\"add a test for the lcm function with 12 and 18\",\"new_string\":\"    // test 999 and 123\\n    if (gcd(999, 123) == 3) {\\n        std::cout << \\\"gcd(999, 123) passed\\\" << std::endl;\\n    } else {\\n        std::cout << \\\"gcd(999, 123) failed\\\" << std::endl;\\n    }\\n    \\n    // Test lcm with 12 and 18\\n    if (lcm(12, 18) == 36) {\\n        std::cout << \\\"lcm(12, 18) passed\\\" << std::endl;\\n    } else {\\n        std::cout << \\\"lcm(12, 18) failed\\\" << std::endl;\\n    }\\n    \\n}\",\"old_string\":\"    // test 999 and 123\\n    if (gcd(999, 123) == 3) {\\n        std::cout << \\\"gcd(999, 123) passed\\\" << std::endl;\\n    } else {\\n        std::cout << \\\"gcd(999, 123) failed\\\" << std::endl;\\n    }\\n    \\n    \\n}\"})",
            "author": "MODEL"
          }
        ]
      }
    },
    "@type": "type.googleapis.com/google.cloud.cloudaicompanion.logging.v1.ResponseLog"
  },
  "resource": {
    "type": "cloudaicompanion.googleapis.com/Instance",
    "labels": {
      "location": "global",
      "resource_container": "my-project-id",
      "instance_id": "default"
    }
  },
  "timestamp": "2025-10-08T10:10:03.461137399Z",
  "severity": "INFO",
  "labels": {
    "client_name": "cloudcode_cli",
    "client_version": "unknown",
    "method": "CompleteTask",
    "request_id": "4b66a582bad9cf2c",
    "product": "code_assist",
    "user_id": "user@company.com"
  },
  "logName": "projects/my-project-id/logs/cloudaicompanion.googleapis.com%2Fresponse",
  "receiveTimestamp": "2025-10-08T10:10:03.606059154Z"
}

中繼資料記錄項目

{
  "insertId": "4qvt8nb2l",
  "jsonPayload": {
    "clientVersion": "unknown",
    "apiRequest": {},
    "clientName": "cloudcode_cli",
    "requestId": "4b66a582bad9cf2c",
    "@type": "type.googleapis.com/google.cloud.cloudaicompanion.logging.v1.MetadataLog"
  },
  "resource": {
    "type": "cloudaicompanion.googleapis.com/Instance",
    "labels": {
      "resource_container": "my-project-id",
      "location": "global",
      "instance_id": "default"
    }
  },
  "timestamp": "2025-10-08T10:10:03.459902984Z",
  "severity": "INFO",
  "labels": {
    "product": "code_assist",
    "user_id": "user@company.com",
    "method": "CompleteTask"
  },
  "logName": "projects/my-project-id/logs/cloudaicompanion.googleapis.com%2Fmetadata",
  "receiveTimestamp": "2025-10-08T10:10:03.606059154Z"
}

Gemini Code Assist 回覆

下表列出 Gemini Code Assist 回覆欄位和說明:

欄位 值和備註
LogEntry.resource.type Gemini Code Assist 資源類型:cloudaicompanion.googleapis.com/Instance。
LogEntry.resource.labels.resource_container 使用 Gemini Code Assist 的資源容器專屬 ID。
LogEntry.resource.labels.location 使用 Gemini Code Assist 的位置。
LogEntry.resource.labels.instance_id 使用 Gemini Code Assist 的資源專屬 ID。
LogEntry.labels.method 視叫用 logEntry 的項目而定,可能為下列其中一項:

CompleteTask:例如來自 Gemini Code Assist 的對話要求。

GenerateCode:例如生成程式碼的要求,像是 Gemini Code Assist 中的程式碼轉換要求。

CompleteCode:例如在 IDE 中工作時完成程式碼的要求,像是 Gemini Code Assist 中的內嵌建議。
LogEntry.labels.product 記錄檔適用的服務名稱。Gemini Code Assist 相關記錄會使用產品值 code_assist。如果記錄與 Gemini Cloud Assist 相關,這個值就會是 cloud_assist。否則,這個值為 unknown。
LogEntry.labels.request_id 用來建立要求與回覆記錄項目關聯的專屬 ID。
LogEntry.labels.user_id 發起這項要求的使用者 ID。
LogEntry.jsonPayload 記錄項目的酬載。用於生成回覆的所有來源引用內容都會以 attribution_context 形式納入這個物件。
LogEntry.logName 用於識別記錄。

Gemini Code Assist 中繼資料記錄

如要讓系統產生中繼資料記錄,必須啟用 VS Code 和 IntelliJ 的 Gemini Code Assist 擴充功能遙測設定。

Gemini Code Assist 中繼資料記錄的結構與 Gemini Code Assist 記錄相同,但指定的欄位不同。下表列出使用者要求記錄項目中的欄位:

欄位 值和備註
LogEntry.@type Gemini Code Assist 中繼資料資源類型:type.googleapis.com/google.cloud.cloudaicompanion.logging.v1.MetadataLog。
LogEntry.labels.method 如果是中繼資料記錄,這個標籤值為 Export.Metrics。
LogEntry.labels.product 記錄檔適用的服務名稱。Gemini Code Assist 相關記錄會使用產品值 code_assist。如果記錄與 Gemini Cloud Assist 相關,這個值會是 cloud_assist。否則,這個值為 unknown。
LogEntry.labels.user_id 發起這項要求的使用者 ID。
LogEntry.jsonPayload 表示 codeExposure 事件或 code.Acceptance 事件。codeExposure 事件代表系統向使用者顯示程式碼建議。code.Acceptance 事件代表使用者接受程式碼的事件,例如透過輸入覆寫、按 Tab 鍵接受,或完整接受。
LogEntry.jsonPayload.clientName IDE 名稱,例如 CloudCodeVscode。
LogEntry.jsonPayload.clientVersion IDE 版本號碼。
LogEntry.jsonPayload.codeAcceptance 僅適用於 VS Code 和 IntelliJ IDE,表示有使用者接受程式碼的事件,如透過輸入覆寫、按 Tab 鍵接受,或完整接受。也包含下列欄位:
  • linesCount:使用者接受的程式碼總行數。
  • commentLinesCount:使用者接受的程式碼中,註解行數。只有在 Gemini Code Assist 能夠判斷接受的程式碼行數中有多少是註解行時,才會顯示這項屬性。
  • originalRequestId:將 codeExposure 事件連結至零或多個 codeAcceptance 事件的 ID。可用於計算接受率和接受的程式碼行數。
  • programmingLanguage:接受程式碼的程式設計語言,例如 python。
LogEntry.jsonPayload.codeExposure 僅適用於 VS Code 和 IntelliJ IDE,表示系統已向使用者顯示程式碼建議。也包含下列欄位:
  • programmingLanguage:曝光的程式設計語言,例如 python。
  • originalRequestId:將 codeExposure 事件連結至零或多個 codeAcceptance 事件的 ID。可用於計算接受率和接受的程式碼行數。
LogEntry.jsonPayload.chatExposure 表示使用者看到聊天回覆。也包含下列欄位:
  • originalRequestId:將 chatExposure 事件連結至零或多個 chatAcceptance 事件的 ID。這項資料可用於計算即時通訊接受率和接受的即時通訊行數。
  • is_agentic:這個 ID 指出 chatExposure 是否來自代理模式。這項指標可用於區分 Agent 模式和非 Agent 模式的聊天接受率,以及接受的程式碼行數。
LogEntry.jsonPayload.chatAcceptance 表示使用者對對話回覆中的程式碼區塊,執行了某些接受事件。也包含下列欄位:
  • interactionType:使用者與程式碼區塊的互動類型,例如 ACCEPT_CODE_BLOCK。
  • programmingLanguage:接受程式碼的程式設計語言,例如 python。
  • linesCount:使用者接受的程式碼總行數。
  • originalRequestId:將 chatExposure 事件連結至零或多個 chatAcceptance 事件的 ID。
  • is_agentic:用於識別 chatAcceptance 是否來自代理模式。這項指標可用來區分代理模式和非代理模式的對話接受率,以及接受的程式碼行數。

以下提供 codeExposure 記錄項目範例:

{
  insertId: "whfrqgc1gj"
  jsonPayload: {
    @type: "type.googleapis.com/google.cloud.cloudaicompanion.logging.v1.MetadataLog"
    clientName: "CloudCodeVscode"
    clientVersion: "1.93.1"
    codeExposure: {
      originalRequestId: "cac019824a0b25ba"
      programmingLanguage: "python"
    }
  requestId: "0c5178fe-446f-4ab6-b996-520dec100cf8"
  }
  labels: {
    method: "Export.Metrics"
    product: "code_assist"
    user_id: "user@company.com"
  }
  logName: "projects/my-project-id/logs/cloudaicompanion.googleapis.com%2Fmetadata"
  receiveTimestamp: "2025-02-03T23:34:35.662837985Z"
  resource: {
    labels: {
      instance_id: "default"
      location: "global"
      resource_container: "my-project-id"
    }
  type: "cloudaicompanion.googleapis.com/Instance"
  }
  severity: "INFO"
  timestamp: "2025-02-03T23:34:35.021564463Z"
}

以下是 codeAcceptance 記錄項目範例:

{
  insertId: "whfrqgc1gk"
  jsonPayload: {
    @type: "type.googleapis.com/google.cloud.cloudaicompanion.logging.v1.MetadataLog"
    clientName: "CloudCodeVscode"
    clientVersion: "1.93.1"
    codeAcceptance: {
      linesCount: 2
      originalRequestId: "cac019824a0b25ba"
      programmingLanguage: "python"
    }
    requestId: "ddf11040-c315-452e-b7cd-928c3f97984e"
  }
  labels: {
    method: "Export.Metrics"
    product: "code_assist"
    user_id: "user@company.com"
  }
  logName: "projects/my-project-id/logs/cloudaicompanion.googleapis.com%2Fmetadata"
  receiveTimestamp: "2025-02-03T23:34:37.632662272Z"
  resource: {
    labels: {
      instance_id: "default"
      location: "global"
      resource_container: "my-project-id"
    }
    type: "cloudaicompanion.googleapis.com/Instance"
  }
  severity: "INFO"
  timestamp: "2025-02-03T23:34:36.778692483Z"
} 

以下提供 chatAcceptance 記錄項目範例:

{
  "insertId": "1oru1grbow",
  "jsonPayload": {
    "clientVersion": "1.103.2",
    "requestId": "32a0b0b8c967d8e8",
    "clientName": "CloudCodeVscode",
    "chatAcceptance": {
      "interactionType": "ACCEPT_CODE_BLOCK",
      "programmingLanguage": "go",
      "linesCount": "15",
      "originalRequestId": "75f7c41e63162567"
    },
    "@type": "type.googleapis.com/google.cloud.cloudaicompanion.logging.v1.MetadataLog"
  },
  "resource": {
    "type": "cloudaicompanion.googleapis.com/Instance",
    "labels": {
      "resource_container": "my-project-id",
      "instance_id": "default",
      "location": "global"
    }
  },
  "timestamp": "2025-08-25T09:34:01.240377123Z",
  "severity": "INFO",
  "labels": {
    "product": "code_assist",
    "method": "Export.Metrics",
    "user_id": "user@company.com"
  },
  "logName": "projects/my-project-id/logs/cloudaicompanion.googleapis.com%2Fmetadata",
  "receiveTimestamp": "2025-08-25T09:34:01.704925625Z"
}

以下是 chatExposure 記錄項目範例:

{
  insertId: "3diaj2c208"
  jsonPayload: {
    @type: "type.googleapis.com/google.cloud.cloudaicompanion.logging.v1.MetadataLog"
    clientName: "CloudCodeVscode"
    clientVersion: "1.93.1"
    chatExposure: {
      originalRequestId: "cac019824a0b25ba"
    }
  requestId: "0c5178fe-446f-4ab6-b996-520dec100cf8"
  }
  labels: {
    method: "Export.Metrics"
    product: "code_assist"
    user_id: "user@company.com"
  }
  logName: "projects/my-project-id/logs/cloudaicompanion.googleapis.com%2Fmetadata"
  receiveTimestamp: "2025-02-03T23:34:35.662837985Z"
  resource: {
    labels: {
      instance_id: "default"
      location: "global"
      resource_container: "my-project-id"
    }
  type: "cloudaicompanion.googleapis.com/Instance"
  }
  severity: "INFO"
  timestamp: "2025-02-03T23:34:35.021564463Z"
}

計算接受率

下列各節說明如何使用 Gemini Code Assist 中繼資料記錄,計算程式碼建議接受率、對話回覆接受率,以及總合併接受率。

計算程式碼接受率

如要使用 Gemini Code Assist 中繼資料記錄計算程式碼接受率,請找出 codeAcceptance.originalRequestId 事件的專屬 ID 總數,然後除以 codeExposure.originalRequestId 事件的專屬 ID 總數。

您可以透過程式設計語言和使用者,使用各自的元資料記錄事件欄位,進一步精確計算。

計算即時通訊接受率

如要使用 Gemini Code Assist 中繼資料記錄計算對話接受率,請找出 chatAcceptance.originalRequestId 事件的專屬 ID 總數,然後除以 chatExposure.originalRequestId 事件的專屬 ID 總數。

您可以使用各自的中繼資料記錄事件欄位,依程式設計語言和使用者進一步精細調整這項計算。

計算總接受率

如要使用 Gemini Code Assist 中繼資料記錄計算總接受率,請找出接受事件總數,然後除以曝光事件總數:

總接受率 = 接受事件總數 ÷ 曝光事件總數

  • 接受的事件總數:codeAcceptance.originalRequestId 事件的專屬 ID 總數,加上 chatAcceptance.originalRequestId 事件的專屬 ID 總數。
  • 曝光事件總數:codeExposure.originalRequestId 事件的專屬 ID 總數,加上 chatExposure.originalRequestId 事件的專屬 ID 總數。

這個公式提供的接受率,反映了所有 Gemini Code Assist 功能中,任何建議被接受的整體機率。

計算接受的程式碼行數

以下各節說明如何使用 Gemini Code Assist 中繼資料記錄,計算採用的程式碼建議行數、採用的對話程式碼行數,以及採用的程式碼總行數。

計算接受的程式碼行數

如要計算接受的程式碼行數,請找出每個不重複 codeAcceptance.originalRequestId 的 codeAcceptance.linesCount 最大值。接著,將這些最大值相加,即可算出採用的程式碼總行數。

您可以透過程式設計語言和使用者,使用各自的元資料記錄事件欄位,進一步精確計算。

計算從對話接受的程式碼行數

如要計算從對話接受的程式碼行數,請找出每個不重複 chatAcceptance.originalRequestId 的 chatAcceptance.linesCount 欄位值。接著,將這些最大值相加,即可算出接受的即時通訊總行數。

計算接受的程式碼總行數

如要使用 Gemini Code Assist 中繼資料記錄,計算接受的程式碼總行數,請將接受的程式碼行數和接受的對話程式碼行數相加。

後續步驟