对话日志架构
本文档介绍了 BigQuery 中对话分析对话日志记录的表布局、列、事件类型、用户身份字段和 JSON 载荷结构。如需简要了解对话日志记录的工作原理,请参阅对话日志记录概览。
表布局和自动创建
在启用日志记录之前,请在数据智能体所在的项目中创建目标数据集;Conversational Analytics API 服务代理会在首次记录对话轮次时,在数据集所在的位置创建表(或向现有兼容表中添加任何缺失的架构列)。自动创建的表按天在 timestamp 上分区(继承数据集上的任何默认分区到期时间),并在 event_type、agent 和 user_id 上聚簇。查询表时,请始终对 timestamp 进行过滤。
Columns
下表介绍了对话日志记录目标表中的列。
| 列 | 类型 | 模式 | 目录 |
|---|---|---|---|
timestamp |
TIMESTAMP |
REQUIRED |
事件发生的世界协调时间 (UTC)。分区列。 |
event_id |
STRING |
NULLABLE |
事件的唯一 ID。如果重试写入,该 ID 会保持不变,因此您可以使用它来移除重复项。 |
event_type |
STRING |
NULLABLE |
事件类型。请参阅事件类型。 |
agent |
STRING |
NULLABLE |
智能体类型,而非智能体的名称或 ID(例如 ConversationalAnalyticsAgent)。如需区分智能体,请使用数据智能体 ID(请参阅attributes 中的字段)。 |
session_id |
STRING |
NULLABLE |
单轮对话,而非完整对话。一个问题及其答案的所有事件共享一个 session_id。如需将轮次分组到对话中,请使用 attributes 中的对话 ID。 |
invocation_id |
STRING |
NULLABLE |
一轮对话中的一次执行。 |
user_id |
STRING |
NULLABLE |
提出问题的来电者。请参阅用户身份。 |
trace_id |
STRING |
NULLABLE |
OpenTelemetry 跟踪记录 ID(32 个十六进制字符)。 |
span_id |
STRING |
NULLABLE |
此操作在轮次执行树中的 ID。 |
parent_span_id |
STRING |
NULLABLE |
父级操作的 ID。 |
content |
JSON |
NULLABLE |
事件载荷。其形状取决于 event_type。 |
content_parts |
RECORD |
REPEATED |
多部分内容,每个部分一个元素(例如 mime_type、uri、object_ref、text、part_index、part_attributes 和 storage_mode)。 |
attributes |
JSON |
NULLABLE |
元数据:数据智能体 ID、对话 ID、内部用户密钥、模型版本和详细的 token 使用情况。 |
latency_ms |
JSON |
NULLABLE |
延迟时间的衡量指标,例如 total_ms 和 time_to_first_token_ms。 |
status |
STRING |
NULLABLE |
OK 或 ERROR。 |
error_message |
STRING |
NULLABLE |
错误详情。如果模型因正常停止以外的原因(例如,达到最大 token 限制)而停止,也可以在 OK
LLM_RESPONSE 行上设置该值。 |
is_truncated |
BOOLEAN |
NULLABLE |
如果事件中的任何文本值超过 512,000 个字符 (500 * 1,024) 并被截断,则为 true。切值以 ...[TRUNCATED] 结尾。移除的部分无法恢复。 |
事件类型
下表介绍了 event_type 列中可能显示的值,以及存储每个事件的数据的列或 JSON 字段。
event_type 值 |
说明 | 填充的列和 JSON 字段 |
|---|---|---|
INVOCATION_STARTING |
回合开始。 | 无 |
USER_MESSAGE_RECEIVED |
用户的问题。 | content.text_summary |
AGENT_RESPONSE |
智能体的回答,以结构化对象的形式呈现。 | content.text_summary(纯文本)和 content.response(请参阅 AGENT_RESPONSE 的结构) |
LLM_RESPONSE |
每个模型调用对应一行,包括请求了工具的调用(如果某个回合直接通过经过验证的查询回答,则不会写入,其中 attributes.fast_path 为 true)。模型的输出不会存储。 |
令牌:content.usage.prompt、content.usage.completion、content.usage.total。
模型:attributes.model_version。完成原因:attributes.finish_reason。详细用法:attributes.usage_metadata(例如 cached_content_token_count 和 thoughts_token_count)。 |
INVOCATION_COMPLETED |
一轮对话结束,并显示每轮对话的延迟时间。content 为空。 |
latency_ms.total_ms |
EMBEDDING_SUGGESTION |
针对智能体所有者的建议,指出哪些列可以从嵌入中受益。它仅针对部分代理显示。 | content.reason,
content.suggested_columns |
INVOCATION_ERROR、AGENT_ERROR、LLM_ERROR |
失败的对话轮次。status 为 ERROR,content 为 NULL。 |
error_message(单行摘要,其中 SQL 语句和表名称已隐去) |
用户身份
user_id 列包含调用方的邮箱:用户的邮箱、API 调用方使用服务账号进行身份验证时的服务账号账号邮箱,或者如果调用方没有邮箱(例如某些员工身份联合身份),则为 NULL。内部用户密钥也会记录在每行的 attributes.session_metadata.user_id 中,因此您可以使用 internal_user_key 统计不同的用户(请参阅创建跨代理事件视图)。
如需在通过服务账号调用 API 时将对话轮次归因于您自己的最终用户,请在应用中记录用户映射。该 API 不接受用于日志记录的最终用户标识符。
attributes 内的字段
下表显示了用于从 attributes JSON 列中提取元数据字段的 GoogleSQL 表达式。
| 所需条件 | GoogleSQL 表达式 |
|---|---|
| 数据智能体 ID | JSON_VALUE(attributes, '$.session_metadata.state."data-agent-id"') |
| 数据智能体完整资源名称 | JSON_VALUE(attributes, '$.adk.app_name') |
| 对话 ID | JSON_VALUE(attributes, '$.session_metadata.state."conversation-id"') |
| 内部用户密钥 | JSON_VALUE(attributes, '$.session_metadata.user_id') |
模型版本(LLM_RESPONSE 行) |
JSON_VALUE(attributes, '$.model_version') |
AGENT_RESPONSE 的结构
如需以纯文本形式读取代理的回答,请使用 JSON_VALUE(content, '$.text_summary')。它会合并回答的 Markdown、假设和数据洞见部分,以及任何澄清问题。在 AGENT_RESPONSE 行中,content.response 是 JSON 对象,而不是字符串,因此 JSON_VALUE(content, '$.response') 会返回 NULL。
下表介绍了 content.response 下的路径。
content.response 下的路径 |
类型 | 目录 |
|---|---|---|
parts |
ARRAY<JSON> |
答案就在这些部分中。 |
parts[].markdown |
STRING |
回答文本 (Markdown)。 |
parts[].insight |
STRING |
从数据中得出的分析洞见。 |
parts[].assumption |
STRING |
智能体做出的假设。 |
parts[].data_result_artifact_name |
STRING |
数据结果的名称。 |
parts[].chart_artifact_name |
STRING |
图表的名称。 |
followup_questions |
ARRAY<STRING> |
建议的后续问题。 |
clarifying_question |
STRING |
在智能体向用户提出澄清式问题而不是回答问题时设置。 |
citation_sources |
JSON |
回答中引用的来源。 |