Esquema de registro de conversaciones
En este documento, se describen el diseño de la tabla, las columnas, los tipos de eventos, los campos de identidad del usuario y la estructura de la carga útil de JSON para el registro de conversaciones de estadísticas de conversaciones en BigQuery. Para obtener una descripción general de cómo funciona el registro de conversaciones, consulta Descripción general del registro de conversaciones.
Diseño y creación automática de tablas
Crea el conjunto de datos de destino en el mismo proyecto que el agente de datos antes de
habilitar el registro. El agente de servicio de la API de Conversational Analytics crea la tabla en
la ubicación del conjunto de datos en el primer turno registrado (o agrega las columnas de esquema que falten
a una tabla compatible existente). La tabla creada automáticamente se particiona
por día en timestamp (hereda cualquier vencimiento de partición predeterminado en el
conjunto de datos) y se agrupa en clústeres en event_type, agent y user_id. Siempre filtra por
timestamp cuando consultes la tabla.
Columnas
En la siguiente tabla, se describen las columnas de la tabla de destino del registro de conversaciones.
| Columna | Tipo | Modo | Contenido |
|---|---|---|---|
timestamp |
TIMESTAMP |
REQUIRED |
Es la hora UTC del evento. Es la columna de partición. |
event_id |
STRING |
NULLABLE |
Es el ID único del evento. Se mantiene igual si se vuelve a intentar una escritura, por lo que puedes usarlo para quitar duplicados. |
event_type |
STRING |
NULLABLE |
Es el tipo de evento. Consulta Tipos de eventos. |
agent |
STRING |
NULLABLE |
Es el tipo de agente, no el nombre ni el ID de tu agente (por ejemplo,
ConversationalAnalyticsAgent). Para distinguir a los agentes, usa el
ID del agente de datos (consulta
Campos dentro de
attributes). |
session_id |
STRING |
NULLABLE |
Un turno, no una conversación completa. Todos los eventos de
una pregunta y su respuesta comparten un session_id. Para agrupar
los turnos en conversaciones, usa el ID de conversación en
attributes. |
invocation_id |
STRING |
NULLABLE |
Una ejecución dentro de un turno. |
user_id |
STRING |
NULLABLE |
Es el emisor que hizo la pregunta. Consulta Identidad del usuario. |
trace_id |
STRING |
NULLABLE |
ID de seguimiento de OpenTelemetry (32 caracteres hexadecimales). |
span_id |
STRING |
NULLABLE |
Es el ID de esta operación en el árbol de ejecución del turno. |
parent_span_id |
STRING |
NULLABLE |
Es el ID de la operación superior. |
content |
JSON |
NULLABLE |
Carga útil del evento. Su forma depende de event_type. |
content_parts |
RECORD |
REPEATED |
Contenido de varias partes, con un elemento por parte (por ejemplo,
mime_type, uri, object_ref,
text, part_index, part_attributes
y storage_mode). |
attributes |
JSON |
NULLABLE |
Metadatos: ID del agente de datos, ID de la conversación, clave de usuario interna, versión del modelo y uso detallado de tokens. |
latency_ms |
JSON |
NULLABLE |
Mediciones de latencia, como total_ms y
time_to_first_token_ms |
status |
STRING |
NULLABLE |
OK o ERROR. |
error_message |
STRING |
NULLABLE |
Detalles del error. También se puede establecer en las filas OK
LLM_RESPONSE cuando el modelo se detiene por un motivo que no sea
una detención normal (por ejemplo, cuando alcanza el límite máximo de
tokens). |
is_truncated |
BOOLEAN |
NULLABLE |
true si algún valor de texto del evento superó los 512,000
caracteres (500 * 1,024) y se cortó. Los valores de corte terminan con
...[TRUNCATED]. La parte que quites no se podrá recuperar. |
Tipos de eventos
En la siguiente tabla, se describen los valores que pueden aparecer en la columna event_type
y las columnas o los campos JSON que almacenan los datos de cada evento.
Valor event_type |
Descripción | Columnas y campos JSON propagados |
|---|---|---|
INVOCATION_STARTING |
Inicio de un giro | Ninguno |
USER_MESSAGE_RECEIVED |
La pregunta del usuario. | content.text_summary |
AGENT_RESPONSE |
La respuesta del agente, como un objeto estructurado. | content.text_summary (texto sin formato) y content.response (consulta Estructura de AGENT_RESPONSE) |
LLM_RESPONSE |
Una fila para cada llamada al modelo, incluidas las llamadas que solicitaron una herramienta
(no se escribe cuando un turno se responde directamente desde una consulta verificada, en la que
attributes.fast_path es true). El resultado del modelo
no se almacena. |
Tokens: content.usage.prompt,
content.usage.completion, content.usage.total.
Modelo: attributes.model_version. Motivo de finalización:
attributes.finish_reason. Uso detallado:
attributes.usage_metadata (por ejemplo,
cached_content_token_count y
thoughts_token_count). |
INVOCATION_COMPLETED |
Fin de un turno, con latencia por turno. content está vacío. |
latency_ms.total_ms |
EMBEDDING_SUGGESTION |
Sugerencias para el propietario del agente sobre las columnas que podrían beneficiarse de los embeddings. Solo aparece para algunos agentes. | content.reason,
content.suggested_columns |
INVOCATION_ERROR, AGENT_ERROR, LLM_ERROR |
Giro incorrecto. status es ERROR y
content es NULL. |
error_message (resumen de una línea con sentencias de SQL y
nombres de tablas ocultos) |
Identidad de usuario
La columna user_id contiene la dirección de correo electrónico del emisor: la dirección de correo electrónico del usuario, la dirección de correo electrónico de una cuenta de servicio cuando un emisor de la API se autentica con una cuenta de servicio o NULL si el emisor no tiene dirección de correo electrónico (como algunas identidades de la federación de identidades de personal). También se registra una clave de usuario interna
en attributes.session_metadata.user_id en cada fila, por lo que puedes contar usuarios
distintos con internal_user_key (consulta Crea la vista de eventos
entre agentes).
Para atribuir turnos a tus propios usuarios finales cuando llamas a la API a través de una cuenta de servicio, registra la asignación de usuarios en tu aplicación. La API no acepta un identificador de usuario final para el registro.
Campos dentro de attributes
En la siguiente tabla, se muestran las expresiones de GoogleSQL que se usan para extraer
campos de metadatos de la columna JSON attributes.
| Requisitos | Expresión de GoogleSQL |
|---|---|
| ID del agente de datos | JSON_VALUE(attributes, '$.session_metadata.state."data-agent-id"') |
| Nombre completo del recurso del agente de datos | JSON_VALUE(attributes, '$.adk.app_name') |
| ID de la conversación | JSON_VALUE(attributes, '$.session_metadata.state."conversation-id"') |
| Clave de usuario interno | JSON_VALUE(attributes, '$.session_metadata.user_id') |
Versión del modelo (en LLM_RESPONSE filas) |
JSON_VALUE(attributes, '$.model_version') |
Estructura de AGENT_RESPONSE
Para leer la respuesta del agente como texto sin formato, usa
JSON_VALUE(content, '$.text_summary'). Combina las partes de Markdown,
suposición y conclusión de la respuesta, y cualquier pregunta aclaratoria. En las filas de AGENT_RESPONSE,
content.response es un objeto JSON, no una cadena, por lo que
JSON_VALUE(content, '$.response') devuelve NULL.
En la siguiente tabla, se describen las rutas de acceso en content.response.
Ruta de acceso en content.response |
Tipo | Contenido |
|---|---|---|
parts |
ARRAY<JSON> |
La respuesta, en partes. |
parts[].markdown |
STRING |
Texto de respuesta (Markdown). |
parts[].insight |
STRING |
Una conclusión extraída de los datos |
parts[].assumption |
STRING |
Una suposición que hizo el agente. |
parts[].data_result_artifact_name |
STRING |
Es el nombre de un resultado de datos. |
parts[].chart_artifact_name |
STRING |
Es el nombre de un gráfico. |
followup_questions |
ARRAY<STRING> |
Preguntas de seguimiento sugeridas |
clarifying_question |
STRING |
Se establece cuando el agente le hace al usuario una pregunta aclaratoria en lugar de responder. |
citation_sources |
JSON |
Fuentes citadas en la respuesta. |