feat(trace): finish run-aware demo verification

This commit is contained in:
zhuyongxin
2026-07-10 21:37:43 +08:00
parent 78c1477198
commit f9df94377b
28 changed files with 779 additions and 459 deletions
+9 -5
View File
@@ -5,14 +5,15 @@
## 定位
`agent_step` 记录一次诊断过程中每个 Agent 步骤的模型输入、输出、耗时和 Token 消耗。页面展示执行链路时应优先按 `step_index` 排序。
`agent_step` 记录一次诊断运行中每个 Agent 步骤的模型输入、输出、耗时和 Token 消耗。`run_id` 是执行隔离边界;Trace 页面展示顺序以 Trace API 返回顺序为准。
## 字段
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `id` | BIGINT | 是 | 自增主键 |
| `session_id` | VARCHAR(64) | 是 | 关联 `diagnosis_session.session_id` |
| `session_id` | VARCHAR(64) | 是 | 所属会话目录 ID,保留用于粗粒度过滤和兼容 |
| `run_id` | VARCHAR(64) | 否 | 所属 `diagnosis_run.run_id`;新执行应写入 |
| `step_index` | INT | 是 | 步骤序号,从 0 开始 |
| `agent_name` | VARCHAR(32) | 是 | Agent 名称,例如 planner、executor、verifier、composer |
| `model_input` | TEXT | 否 | 模型输入摘要;`V006` 已从 JSON 改为 TEXT |
@@ -27,15 +28,18 @@
| 索引 | 字段 | 用途 |
|---|---|---|
| `idx_session_step` | `session_id, step_index` | Trace 页面按会话和步骤顺序查询 |
| `idx_session_step` | `session_id, step_index` | 历史兼容和粗粒度排查 |
| `idx_agent_step_run_step` | `run_id, step_index` | 按运行筛选步骤并辅助顺序查询 |
| `idx_agent_name` | `agent_name` | 按 Agent 类型筛选 |
## 关系
- `agent_step.session_id` 逻辑关联 `diagnosis_session.session_id`。
- `agent_step.run_id` 逻辑关联 `diagnosis_run.run_id`。
- `agent_step.session_id` 保留为 `chat_session.session_id` 的冗余关联,便于粗粒度过滤和兼容查询。
- `tool_invocation.step_id` 可关联 `agent_step.id`,但当前允许为空且不强制外键。
## 注意点
- 前端展示步骤时应按 `step_index` 排序,而不是按 `created_at` 或数据库返回顺序。
- 前端展示步骤时应使用 Trace API 返回顺序;服务端会在同一 `run_id` 范围内整理步骤顺序。
- 新 Trace、Verifier 和评测读路径应按 `run_id` 取数,避免同一 `sessionId` 多轮诊断混入。
- Verifier 应在 Executor 循环完成后出现;如果 `step_index` 中 Verifier 提前,通常意味着编排或记录顺序有问题。
+14 -8
View File
@@ -1,6 +1,6 @@
# MVP 数据表索引
**更新日期**:2026-07-09
**更新日期**:2026-07-10
**状态**:当前表文档入口
本目录保存当前 MVP 使用的数据表说明。详细结构以 Flyway migration 和实体类为准;本目录用于面试讲解、排查索引和快速理解数据流。
@@ -9,26 +9,32 @@
| 表 | 用途 | 文档 |
|---|---|---|
| `diagnosis_session` | 会话级主记录,保存 query、状态、最终答案和自评估 | [诊断会话表-diagnosis_session.md](诊断会话表-diagnosis_session.md) |
| `agent_step` | Agent 步骤记录,按 `step_index` 回放执行链路 | [Agent步骤表-agent_step.md](Agent步骤表-agent_step.md) |
| `tool_invocation` | 工具调用记录,支撑 Trace、Verifier 和评测 | [工具调用表-tool_invocation.md](工具调用表-tool_invocation.md) |
| `chat_session` | 会话目录元数据,保存同一个 `sessionId` 的多轮会话状态快照 | [聊天会话表-chat_session.md](聊天会话表-chat_session.md) |
| `diagnosis_run` | 运行级主记录,保存一次 Chat/AIOps 诊断的 query、状态、答案、自评估和反馈 | [诊断运行表-diagnosis_run.md](诊断运行表-diagnosis_run.md) |
| `agent_step` | Agent 步骤记录,按 `run_id` 隔离回放执行链路 | [Agent步骤表-agent_step.md](Agent步骤表-agent_step.md) |
| `tool_invocation` | 工具调用记录,按 `run_id` 支撑 Trace、Verifier 和评测 | [工具调用表-tool_invocation.md](工具调用表-tool_invocation.md) |
| `api_document` | 知识库文档元数据,和向量库 chunk 通过 `doc_id` 关联 | [文档元数据表-api_document.md](文档元数据表-api_document.md) |
| `knowledge_domain` | 知识域元数据,支撑 RAG domain hint 和检索策略 | [知识域表-knowledge_domain.md](知识域表-knowledge_domain.md) |
| `case_library` | 用户反馈沉淀出的高质量诊断案例 | [案例库表-case_library.md](案例库表-case_library.md) |
| `diagnosis_session` | 历史兼容和回滚表,新执行写入不再依赖它 | [诊断会话表-diagnosis_session.md](诊断会话表-diagnosis_session.md) |
## 已归档表
| 表 | 归档原因 | 文档 |
|---|---|---|
| `diagnosis_record` | 已由 `V007` 删除,被 `diagnosis_session + agent_step + tool_invocation` 替代 | [archive/2026-07-09-doc-cleanup/旧诊断记录表-diagnosis_record.md](archive/2026-07-09-doc-cleanup/旧诊断记录表-diagnosis_record.md) |
| `diagnosis_record` | 已由 `V007` 删除,历史上被 `diagnosis_session + agent_step + tool_invocation` 替代;当前新模型是 `chat_session + diagnosis_run + trace detail` | [archive/2026-07-09-doc-cleanup/旧诊断记录表-diagnosis_record.md](archive/2026-07-09-doc-cleanup/旧诊断记录表-diagnosis_record.md) |
## 核心关系
```text
chat_session.session_id
-> diagnosis_run.session_id
-> agent_step.run_id
-> tool_invocation.run_id
-> case_library.diagnosis_id (new AUTO cases use run_id)
diagnosis_session.session_id
-> agent_step.session_id
-> tool_invocation.session_id
-> case_library.diagnosis_id
-> historical compatibility / rollback only
api_document.doc_id
-> vector chunk metadata.docId / doc_id
@@ -5,14 +5,15 @@
## 定位
`tool_invocation` 记录 Agent 显式调用工具的事实,包括工具名、入参、输出摘要、检索层级、证据引用和失败信息。它是 Trace、Verifier、评测和人工排查的共同数据源。
`tool_invocation` 记录 Agent 在一次诊断运行中显式调用工具的事实,包括工具名、入参、输出摘要、检索层级、证据引用和失败信息。它是 Trace、Verifier、评测和人工排查的共同数据源。
## 字段
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `id` | BIGINT | 是 | 自增主键 |
| `session_id` | VARCHAR(64) | 是 | 关联 `diagnosis_session.session_id` |
| `session_id` | VARCHAR(64) | 是 | 所属会话目录 ID,保留用于粗粒度过滤和兼容 |
| `run_id` | VARCHAR(64) | 否 | 所属 `diagnosis_run.run_id`;新执行应写入 |
| `step_id` | BIGINT | 否 | 可关联 `agent_step.id` |
| `tool_name` | VARCHAR(64) | 是 | 工具名称,例如 `lookup_knowledge`、日志查询、指标查询 |
| `input_params` | JSON | 是 | 工具入参 |
@@ -34,13 +35,15 @@
| 索引 | 字段 | 用途 |
|---|---|---|
| `idx_session_id` | `session_id` | 按会话查询工具调用 |
| `idx_session_id` | `session_id` | 历史兼容和粗粒度排查 |
| `idx_tool_invocation_run_id` | `run_id, id` | Trace、Verifier、评测按运行查询工具调用 |
| `idx_tool_name` | `tool_name` | 按工具类型排查 |
| `idx_retrieval_layer` | `retrieval_layer` | 观察 RAG L0/L1 行为 |
## 关系
- `tool_invocation.session_id` 逻辑关联 `diagnosis_session.session_id`。
- `tool_invocation.run_id` 逻辑关联 `diagnosis_run.run_id`。
- `tool_invocation.session_id` 保留为 `chat_session.session_id` 的冗余关联,便于粗粒度过滤和兼容查询。
- `tool_invocation.step_id` 可关联 `agent_step.id`,但当前不强制。
## 关键 JSON
+5 -4
View File
@@ -5,7 +5,7 @@
## 定位
`case_library` 保存高质量诊断案例,用于后续相似案例推荐和知识沉淀。当前自动沉淀路径来自 `useful` 用户反馈:系统把 `diagnosis_session` 中的 query 和 answer 映射为案例内容。
`case_library` 保存高质量诊断案例,用于后续相似案例推荐和知识沉淀。当前自动沉淀路径来自 `useful` 用户反馈:新数据把 `diagnosis_run` 中的 query 和 answer 映射为案例内容。
## 字段
@@ -13,7 +13,7 @@
|---|---|---|---|
| `id` | BIGINT | 是 | 自增主键 |
| `case_id` | VARCHAR(64) | 是 | 案例唯一 ID |
| `diagnosis_id` | VARCHAR(64) | 否 | 关联诊断会话;当前自动生成时存 `diagnosis_session.session_id` |
| `diagnosis_id` | VARCHAR(64) | 否 | 关联诊断来源;新自动生成时存 `diagnosis_run.run_id`,历史数据可能是 `diagnosis_session.session_id` |
| `source_type` | VARCHAR(16) | 否 | 来源类型:`AUTO` 或 `MANUAL` |
| `fault_category` | VARCHAR(32) | 否 | 故障类别,实体侧使用 `FaultCategory` |
| `fault_source` | VARCHAR(128) | 否 | 故障源,例如服务、系统或省份 |
@@ -35,16 +35,17 @@
| `idx_error_code` | `error_code` | 按错误码精确匹配 |
| `idx_fault_source` | `fault_source` | 按故障源筛选 |
| `idx_fault_target` | `fault_target(100)` | 按故障目标筛选 |
| `idx_diagnosis_id` | `diagnosis_id` | 追溯来源会话 |
| `idx_diagnosis_id` | `diagnosis_id` | 追溯来源运行或历史会话 |
| `idx_reference_count` | `reference_count` | 推荐排序 |
| `idx_created_at` | `created_at` | 时间排序 |
## 关系
- `case_library.diagnosis_id` 当前逻辑关联 `diagnosis_session.session_id`,不是旧的 `diagnosis_record`。
- `case_library.diagnosis_id` 是过渡字段:新自动案例逻辑关联 `diagnosis_run.run_id`,历史自动案例可能仍是 `diagnosis_session.session_id`。
- 人工录入案例可以不填写 `diagnosis_id`。
## 注意点
- 旧文档里提到的 `diagnosis_record` 已被 `V007` 删除,不再是当前主模型。
- 查询新自动案例时优先按 `run_id` 追溯;遇到旧值时再按历史 `session_id` 解释。
- 当前自动沉淀仍比较粗:`root_cause` 和 `solution` 都可能来自完整 answer。后续可从结构化结论中拆分根因、证据和修复建议。
@@ -0,0 +1,40 @@
# 聊天会话表:chat_session
**状态**:当前会话目录表
**来源**:`V011__add_session_run_isolation.sql`、`ChatSession`
## 定位
`chat_session` 保存多轮 Chat 会话的元数据,用于把同一个 `sessionId` 下的多次诊断运行组织在一起。它不保存完整对话历史;正文消息仍由 Redis `SessionContext.messageHistory` 管理。
## 字段
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `id` | BIGINT | 是 | 自增主键 |
| `session_id` | VARCHAR(64) | 是 | 会话目录 ID,外部 API 仍通过它定位会话 |
| `status` | VARCHAR(16) | 否 | `ACTIVE`、`EXPIRED`、`CLOSED` |
| `message_pair_count` | INT | 否 | Redis 会话中问答轮次数的快照 |
| `created_at` | DATETIME | 是 | 创建时间 |
| `last_active_at` | DATETIME | 否 | 最近活跃时间 |
| `expires_at` | DATETIME | 否 | 目录元数据,可为空;Redis 消息历史可独立过期 |
## 索引
| 索引 | 字段 | 用途 |
|---|---|---|
| `session_id` unique | `session_id` | 会话目录唯一约束 |
| `idx_chat_session_last_active` | `last_active_at` | 最近会话列表和排查 |
| `idx_chat_session_status` | `status` | 按状态筛选 |
| `idx_chat_session_expires_at` | `expires_at` | 过期目录排查 |
## 关系
- `diagnosis_run.session_id` 逻辑关联 `chat_session.session_id`。
- 当前不强制数据库外键,服务层校验 run/session ownership。
- 一个 `chat_session` 可以拥有多个 `diagnosis_run`。
## 注意点
- `chat_session` 是会话元数据,不是诊断执行记录。
- 不要把 query、answer、self_evaluation、feedback 写入该表;这些属于 `diagnosis_run`。
@@ -1,18 +1,18 @@
# 诊断会话表:diagnosis_session
**状态**:当前主表
**状态**:历史兼容和回滚表
**来源**:`V005__create_session_storage.sql`、`V008__add_answer_to_diagnosis_session.sql`、`DiagnosisSession`
## 定位
`diagnosis_session` 是一次 Chat 或 AIOps 诊断的会话级主记录,负责保存用户问题、执行状态、最终答案、总体统计和自评估结果。
`diagnosis_session` 是旧版 session 级诊断主记录。`V011` 之后,新 Chat/AIOps 执行的运行态写入已经切到 `chat_session + diagnosis_run`;本表保留用于历史兼容、迁移回填和回滚比较。
## 字段
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `id` | BIGINT | 是 | 自增主键 |
| `session_id` | VARCHAR(64) | 是 | 会话唯一 ID,Trace API 和反馈接口使用它 |
| `session_id` | VARCHAR(64) | 是 | 旧版会话唯一 ID,也是兼容 run 回填来源 |
| `query` | TEXT | 是 | 用户原始问题或 AIOps 输入摘要 |
| `status` | VARCHAR(16) | 否 | `PENDING`、`RUNNING`、`SUCCESS`、`FAILED` |
| `agent_flow` | VARCHAR(32) | 否 | `CHAT` 或 `AI_OPS` |
@@ -37,11 +37,12 @@
## 关系
- `agent_step.session_id` 逻辑关联 `diagnosis_session.session_id`。
- `tool_invocation.session_id` 逻辑关联 `diagnosis_session.session_id`。
- `case_library.diagnosis_id` 在自动生成案例时保存 `diagnosis_session.session_id`。
- 迁移时每条 `diagnosis_session` 会生成一条兼容 `diagnosis_run`。
- 历史 `agent_step.run_id` 和 `tool_invocation.run_id` 会尽量从兼容 `diagnosis_run` 回填。
- 历史自动案例可能仍使用 `case_library.diagnosis_id = diagnosis_session.session_id`。
## 注意点
- 当前没有数据库外键,Trace 聚合依赖 `session_id`。
- `self_evaluation` 是扩展容器,里面可能包含 `rule_evaluation`、`verifier_evaluation`、`aiops_rule_evaluation`。
- 新执行不应再把 query、answer、self_evaluation、feedback、统计计数写入本表。
- 新 Trace 聚合优先读取 `diagnosis_run + agent_step.run_id + tool_invocation.run_id`。
- 历史 fallback 仅在没有 run-backed 数据时读取本表。
@@ -0,0 +1,51 @@
# 诊断运行表:diagnosis_run
**状态**:当前诊断运行主表
**来源**:`V011__add_session_run_isolation.sql`、`DiagnosisRun`
## 定位
`diagnosis_run` 表示一次可回放的 Chat 或 AIOps 诊断执行。`run_id` 是运行级边界,Trace、反馈、自评估、案例沉淀和统计都应优先按 `run_id` 绑定。
## 字段
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `id` | BIGINT | 是 | 自增主键 |
| `run_id` | VARCHAR(64) | 是 | 运行唯一 ID,格式为 `run-` + UUID |
| `session_id` | VARCHAR(64) | 是 | 所属 `chat_session.session_id` |
| `query` | TEXT | 是 | 本次 Chat 问题或 AIOps 告警摘要 |
| `status` | VARCHAR(16) | 否 | `PENDING`、`RUNNING`、`SUCCESS`、`FAILED` |
| `agent_flow` | VARCHAR(32) | 否 | `CHAT` 或 `AI_OPS` |
| `answer` | LONGTEXT | 否 | 本次运行的最终答复或告警报告 |
| `self_evaluation` | JSON | 否 | 本次运行的 rule、verifier、aiops 自评估容器 |
| `feedback` | VARCHAR(16) | 否 | 本次运行的用户反馈 |
| `total_duration_ms` | INT | 否 | 本次运行总耗时 |
| `total_token_count` | INT | 否 | 本次运行 Token 消耗 |
| `step_count` | INT | 否 | 本次运行的 Agent 步骤数 |
| `tool_call_count` | INT | 否 | 本次运行的工具调用数 |
| `created_at` | DATETIME | 是 | 创建时间 |
| `updated_at` | DATETIME | 是 | 更新时间 |
## 索引
| 索引 | 字段 | 用途 |
|---|---|---|
| `run_id` unique | `run_id` | 运行唯一约束 |
| `idx_diagnosis_run_session_created` | `session_id, created_at, id` | session 下最新运行解析和运行列表 |
| `idx_diagnosis_run_session_run` | `session_id, run_id` | exact trace / feedback ownership 校验 |
| `idx_diagnosis_run_status` | `status` | 状态筛选 |
| `idx_diagnosis_run_agent_flow` | `agent_flow` | 区分 Chat / AIOps |
## 关系
- `diagnosis_run.session_id` 逻辑关联 `chat_session.session_id`。
- `agent_step.run_id` 逻辑关联 `diagnosis_run.run_id`。
- `tool_invocation.run_id` 逻辑关联 `diagnosis_run.run_id`。
- 新的自动案例沉淀使用 `case_library.diagnosis_id = diagnosis_run.run_id`。
## 注意点
- `GET /api/diagnosis/{sessionId}/trace` 未带 `runId` 时只为兼容解析 latest run;新 demo 和新客户端应传 `runId`。
- latest run 排序使用 `created_at DESC, id DESC`,避免 feedback 或自评估更新 `updated_at` 后改变回放目标。
- 历史 `diagnosis_session` 会被迁移成兼容 run,但旧混合数据不能被还原成真实多轮边界。