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
+2 -2
View File
@@ -1,6 +1,6 @@
# MVP 架构文档
**更新日期**:2026-07-08
**更新日期**:2026-07-10
这里是 MVP 当前架构的唯一入口。旧版设计、早期拆解和已经被新实现替代的方案已归档到:
@@ -29,7 +29,7 @@
## 当前架构一句话
SuperBizAgent MVP 是一个面向故障诊断的可追踪 Agent 系统:Chat 和 AIOps 入口统一进入 Agent 编排,Executor 通过显式工具收集日志、指标和知识库证据,Chat 链路由 Gatekeeper 做引用真实性校验、Verifier 做可推导性判断、Composer 生成最终表达;执行过程落到 `diagnosis_session`、`agent_step`、`tool_invocation`,最终通过 Trace API 和评测脚本证明诊断链路可解释、可回放、可对比。
SuperBizAgent MVP 是一个面向故障诊断的可追踪 Agent 系统:Chat 和 AIOps 入口统一进入 Agent 编排,Executor 通过显式工具收集日志、指标和知识库证据,Chat 链路由 Gatekeeper 做引用真实性校验、Verifier 做可推导性判断、Composer 生成最终表达;多轮会话元数据落到 `chat_session`,每次诊断运行落到 `diagnosis_run`,步骤和工具明细通过 `agent_step.run_id`、`tool_invocation.run_id` 关联,最终通过 Trace API 和评测脚本证明诊断链路可解释、可回放、可对比。
## 阅读顺序
+9 -6
View File
@@ -42,13 +42,15 @@ flowchart TB
end
subgraph Trace["Trace persistence"]
Session["diagnosis_session"]
ChatSession["chat_session"]
Run["diagnosis_run"]
Step["agent_step"]
Invocation["tool_invocation"]
SelfEval["self_evaluation"]
end
ChatService --> Session
ChatService --> ChatSession
ChatService --> Run
ChatPlanner --> Step
ChatExecutor --> Step
ChatGatekeeper --> SelfEval
@@ -57,7 +59,8 @@ flowchart TB
ChatDecision --> SelfEval
ChatComposer --> Step
AiOpsService --> Session
AiOpsService --> ChatSession
AiOpsService --> Run
AiOpsPlanner --> Step
AiOpsExecutor --> Step
AiOpsTools --> Invocation
@@ -103,7 +106,7 @@ sequenceDiagram
participant G as gatekeeper
participant V as chat_verifier
participant M as chat_composer
participant S as diagnosis_session
participant R as diagnosis_run
C->>P: 原始问题 + history + retry_context
P-->>C: planner_plan
@@ -115,13 +118,13 @@ sequenceDiagram
G-->>C: gatekeeper_result
C->>V: executor_structured_output + gatekeeper_result + tool_trace_summary
V-->>C: PASS / LOW_CONFID / REJECT
C->>S: 写入 verifier_evaluation
C->>R: 写入 verifier_evaluation
alt LOW_CONFID 且允许补证据
C->>P: retry_context: 仅补缺失证据
else PASS 或 REJECT
C->>M: allowed_claims + missing_info + recommended_actions
M-->>C: composer_output
C->>S: 保存 Composer 最终 answer
C->>R: 保存 Composer 最终 answer
end
```
+34 -21
View File
@@ -65,7 +65,8 @@ flowchart TB
end
subgraph Store["Persistence and Trace"]
Session["diagnosis_session"]
ChatSession["chat_session"]
Run["diagnosis_run"]
Step["agent_step"]
Invocation["tool_invocation"]
ApiDoc["api_document"]
@@ -130,9 +131,10 @@ RAG Retrieval
-> Milvus SDK fallback
Persistence
-> diagnosis_session
-> agent_step
-> tool_invocation
-> chat_session
-> diagnosis_run
-> agent_step.run_id
-> tool_invocation.run_id
-> api_document
-> Milvus/Zilliz collection
@@ -163,21 +165,22 @@ sequenceDiagram
User->>API: 提交诊断问题
API->>Chat: execute chat strategy
Chat->>DB: 创建 chat_session metadata + diagnosis_run(runId)
Chat->>Planner: 复杂问题进入规划
Planner->>DB: 写入 agent_step
Planner->>DB: 写入 agent_step.run_id
Planner->>Executor: 下发排查方向
Executor->>Tool: lookup_knowledge / logs / metrics
Tool->>DB: 写入 tool_invocation
Tool->>DB: 写入 tool_invocation.run_id
Tool-->>Executor: 返回证据
Executor->>Gatekeeper: 输出 executor_evidence_v2
Gatekeeper->>DB: 读取 tool_invocation.evidence_refs 并校验引用
Gatekeeper->>Verifier: 传入已验真的 claims / excerpts
Verifier->>DB: 合并 self_evaluation.verifier_evaluation
Verifier->>DB: 合并 diagnosis_run.self_evaluation.verifier_evaluation
Verifier->>Composer: 传入 allowed_claims / missing_info / actions
Composer->>Chat: 生成最终用户答复
Chat->>DB: 保存 diagnosis_session.answer
User->>Trace: GET /api/diagnosis/{sessionId}/trace
Trace->>DB: 聚合 session / step / tool
Chat->>DB: 保存 diagnosis_run.answer
User->>Trace: GET /api/diagnosis/{sessionId}/trace?runId=...
Trace->>DB: 聚合 run / step / tool
Trace-->>User: 返回可回放诊断链路
```
@@ -194,13 +197,14 @@ POST /api/chat
-> Gatekeeper 校验 Executor 证据引用真实性
-> Verifier 判断 claim 是否能由已核验证据推出
-> Composer 生成最终用户答复
-> 保存 diagnosis_session
-> 保存 agent_step
-> 保存 tool_invocation
-> 合并 self_evaluation.verifier_evaluation
-> 保存 chat_session metadata
-> 保存 diagnosis_run
-> 保存 agent_step.run_id
-> 保存 tool_invocation.run_id
-> 合并 diagnosis_run.self_evaluation.verifier_evaluation
```
Chat 链路的质量门禁由三段组成:Gatekeeper 先做代码级引用验真,Verifier 再做 LLM 可推导性判断,Composer 最后控制对用户的表达边界。Gatekeeper、Verifier、Composer 的输出合并到 `diagnosis_session.self_evaluation.verifier_evaluation`,Trace API 会展示该验证结果。
Chat 链路的质量门禁由三段组成:Gatekeeper 先做代码级引用验真,Verifier 再做 LLM 可推导性判断,Composer 最后控制对用户的表达边界。Gatekeeper、Verifier、Composer 的输出合并到当前 `diagnosis_run.self_evaluation.verifier_evaluation`,Trace API 会展示该验证结果。
Agent 编排细节见 [agent-orchestration.md](agent-orchestration.md)。
@@ -255,7 +259,7 @@ POST /api/ai_ops
-> Prometheus / logs / knowledge tools
-> 生成告警分析报告
-> AiOpsRuleEvaluationService
-> 合并 self_evaluation.aiops_rule_evaluation
-> 合并 diagnosis_run.self_evaluation.aiops_rule_evaluation
-> Trace API 可查看全链路
```
@@ -317,23 +321,30 @@ RAG 总体设计见 [rag-architecture.md](rag-architecture.md),检索运行细
## 6. 持久化模型
当前诊断持久化以三张表为核心:
当前诊断持久化以 session/run/trace 明细为核心:
```text
diagnosis_session
-> 一次诊断会话的主记录
chat_session
-> 多轮会话目录和元数据
-> session_id / status / message_pair_count
diagnosis_run
-> 一次诊断运行的主记录
-> run_id / session_id
-> query / status / agent_flow / answer
-> self_evaluation
-> step_count / tool_call_count / duration
agent_step
-> Agent 模型调用步骤
-> session_id / run_id
-> step_index / agent_name
-> model_input / model_output / thought
-> duration / token_count
tool_invocation
-> 工具调用事实
-> session_id / run_id
-> tool_name / input_params / output_preview
-> retrieval_layer / retrieval_details
-> retrieval_details.evidence_refs
@@ -343,7 +354,8 @@ tool_invocation
说明:
- 旧的 `diagnosis_record` 已不是当前主模型,迁移脚本中已经由 `diagnosis_session + agent_step + tool_invocation` 取代。
- 旧的 `diagnosis_record` 已不是当前主模型。
- `diagnosis_session` 已降级为历史兼容和回滚表,新执行写入 `chat_session + diagnosis_run`。
- `api_document` 仍用于文档元数据管理。
- 文档向量内容存放在 Milvus/Zilliz collection 中。
@@ -353,11 +365,12 @@ tool_invocation
```text
GET /api/diagnosis/{sessionId}/trace
GET /api/diagnosis/{sessionId}/trace?runId=run-...
```
Trace API 聚合:
- 会话状态和最终报告。
- 会话元数据、运行状态和最终报告。
- Agent step 序列。
- 工具调用和检索细节。
- Chat Gatekeeper / Verifier / Composer 结果。
+70 -194
View File
@@ -1,31 +1,44 @@
# 数据模型总览
**更新日期**:2026-07-08
**更新日期**:2026-07-10
**状态**:当前可运行架构
## 1. 定位
本文从架构角度说明当前 MVP 的核心数据模型。详细字段仍以 Flyway migration 和 `mvp/tables/` 为准。
本文从架构角度说明当前 MVP 的核心数据模型。详细字段以 Flyway migration、实体类和 `mvp/tables/` 为准。
核心数据分三组:
- 诊断 Trace:`diagnosis_session`、`agent_step`、`tool_invocation`
- 会话与诊断 Trace:`chat_session`、`diagnosis_run`、`agent_step`、`tool_invocation`
- 知识库:`api_document`、`knowledge_domain`、Milvus/Zilliz metadata
- 反馈沉淀:`case_library`
`diagnosis_session` 仍保留为历史兼容和回滚表,不再是新执行写入的主模型。
## 2. 总体关系
```mermaid
erDiagram
diagnosis_session ||--o{ agent_step : has
diagnosis_session ||--o{ tool_invocation : has
diagnosis_session ||--o| case_library : creates_when_useful
chat_session ||--o{ diagnosis_run : owns
diagnosis_run ||--o{ agent_step : has
diagnosis_run ||--o{ tool_invocation : has
diagnosis_run ||--o| case_library : creates_when_useful
api_document ||--o{ milvus_chunk : indexed_as
knowledge_domain ||--o{ api_document : groups
diagnosis_session {
chat_session {
bigint id
varchar session_id
varchar status
int message_pair_count
datetime last_active_at
datetime expires_at
}
diagnosis_run {
bigint id
varchar run_id
varchar session_id
text query
varchar status
varchar agent_flow
@@ -37,42 +50,23 @@ erDiagram
agent_step {
bigint id
varchar session_id
varchar run_id
int step_index
varchar agent_name
text model_input
text model_output
text thought
boolean has_tool_call
}
tool_invocation {
bigint id
varchar session_id
varchar run_id
bigint step_id
varchar tool_name
json input_params
text output_preview
varchar retrieval_layer
json retrieval_details
varchar relevance_level
varchar dedup_reason
}
api_document {
bigint id
varchar doc_id
varchar file_name
varchar file_path
varchar status
int chunk_count
text metadata
}
knowledge_domain {
bigint id
varchar domain_id
varchar description
text when_to_retrieve
int document_count
}
case_library {
@@ -84,58 +78,52 @@ erDiagram
text root_cause
text solution
}
milvus_chunk {
varchar id
text content
json metadata
vector vector
}
```
说明:Milvus/Zilliz collection 不是 MySQL 表,图中的 `milvus_chunk` 是逻辑模型。
## 3. 诊断 Trace 模型
## 3. 会话与运行模型
### diagnosis_session
### chat_session
会话级主记录。
关键字段:
`chat_session` 是会话目录表,保存 `sessionId` 的元数据:
| 字段 | 说明 |
|---|---|
| `session_id` | 外部关联键,Trace 和 Feedback 都使用它 |
| `query` | 用户原始问题或 AIOps 输入摘要 |
| `status` | 执行状态 |
| `session_id` | 外部会话 ID,用于多轮上下文和 run 列表 |
| `status` | 会话目录状态 |
| `message_pair_count` | Redis 对话轮次数快照 |
| `last_active_at` | 最近活跃时间 |
| `expires_at` | 可为空的目录 TTL 元数据 |
它不保存完整对话历史,正文消息仍由 Redis `SessionContext.messageHistory` 管理。
### diagnosis_run
`diagnosis_run` 是一次可回放诊断执行的主记录:
| 字段 | 说明 |
|---|---|
| `run_id` | 运行 ID,格式为 `run-` + UUID |
| `session_id` | 所属 `chat_session.session_id` |
| `query` | 本次 Chat 问题或 AIOps 告警摘要 |
| `status` | 本次执行状态 |
| `agent_flow` | `CHAT` / `AI_OPS` |
| `answer` | 最终答复或告警报告 |
| `self_evaluation` | rule/verifier/aiops 自评估容器 |
| `feedback` | 用户反馈 |
| `answer` | 本次运行最终答复或告警报告 |
| `self_evaluation` | 本次运行的 rule/verifier/aiops 自评估容器 |
| `feedback` | 本次运行的用户反馈 |
同一个 `sessionId` 可以有多个 `runId`。Trace、反馈、评测和案例沉淀都应优先使用 `runId`,避免多轮同 session 下的数据混合。
## 4. Trace 明细模型
### agent_step
记录模型调用步骤。
用途:
- 回放 Agent 推理过程。
- 查看 Planner / Executor / Verifier 的输入输出摘要。
- 统计 step count、duration、token count。
`agent_step` 记录模型调用步骤。新写入同时保留 `session_id` 和 `run_id`,其中 `run_id` 是回放边界。Trace 页面和评测应先按 `run_id` 隔离取数,展示顺序以 Trace API 返回顺序为准。
### tool_invocation
记录工具调用事实。
用途:
- 给 Trace API 展示证据。
- 给 Gatekeeper 提供 `retrieval_details.evidence_refs` 引用验真源。
- 给 Verifier 构造 `tool_trace_summary` 审计导航。
- 给 `EvaluationService` 计算 evidence score。
- 给 RAG eval 和人工排查提供检索细节。
`retrieval_details.evidence_refs` 是当前 Chat 证据链路的关键字段:
`tool_invocation` 记录显式工具调用事实。`retrieval_details.evidence_refs` 是 Chat 证据链路的关键字段:
```json
{
@@ -149,83 +137,28 @@ erDiagram
}
```
字段边界:
| 字段 | 说明 |
|---|---|
| `evidence_status` | 工具证据状态,例如 `supported`、`no_evidence`、`deduped`、`failed` |
| `evidence_refs[].raw_path` | Executor 可引用的稳定路径,例如 `$.logs[0]`、`$.alerts[0]`、`$.evidence_blocks[0]`、`$.no_evidence` |
| `evidence_refs[].text` | 系统抽取的最小证据文本,Gatekeeper 用它核对 `evidence_excerpt` |
`$.no_evidence` 只表示“本次工具查询未检索到匹配证据”,不能被解释为“问题不存在”或“根因已排除”。
## 4. 知识库模型
### api_document
MySQL 中的文档元数据表。
职责:
- 管理上传文件。
- 保存 file hash,用于去重。
- 记录索引状态和 chunk 数量。
- 保存 frontmatter JSON。
### knowledge_domain
领域级元数据。
职责:
- 按 category 聚合文档。
- 存储领域描述。
- 存储 `when_to_retrieve`,辅助 Planner/Executor 判断什么时候检索该领域。
### Milvus/Zilliz metadata
向量 collection 中每个 chunk 的 metadata 主要包括:
```text
docId
_source
chunkIndex
totalChunks
title
breadcrumb
category
```
这些字段支撑:
- category filter。
- source 展示。
- breadcrumb 上下文。
- docId 删除和重建索引。
- evidence block 构造。
## 5. 反馈沉淀模型
### case_library
`useful` 反馈会触发 `CaseLibraryService.createFromSession`。
`useful` 反馈会触发 `CaseLibraryService.createFromRun`。
当前自动映射:
| 字段 | 来源 |
|---|---|
| `case_id` | UUID |
| `diagnosis_id` | `diagnosis_session.session_id` |
| `diagnosis_id` | 新数据为 `diagnosis_run.run_id`;历史数据可能为 `diagnosis_session.session_id` |
| `source_type` | `AUTO` |
| `fault_category` | 当前默认 `GENERAL` |
| `title` | session query 前 100 字符 |
| `root_cause` | session answer |
| `solution` | session answer |
| `title` | run query 前 100 字符 |
| `root_cause` | run answer |
| `solution` | run answer |
| `created_by` | `system` |
## 6. self_evaluation 结构
`diagnosis_session.self_evaluation` 是 JSON 容器:
`diagnosis_run.self_evaluation` 是运行级 JSON 容器:
```json
{
@@ -235,78 +168,21 @@ category
}
```
边界:
Chat 通常写入 `rule_evaluation` 和 `verifier_evaluation`;AIOps 写入 `aiops_rule_evaluation`。
- `rule_evaluation` 评估证据收集充分度。
- `verifier_evaluation` 评估 Chat 结构化 claims 是否能由已验真证据推出,并保存 Gatekeeper、Verifier、Composer 的审计数据。
- `aiops_rule_evaluation` 评估 AIOps 报告是否聚焦告警并使用证据。
当前 `verifier_evaluation` 关键结构:
```json
{
"verdict": "PASS",
"groundedness_score": 1.0,
"critical_fact_count": 1,
"claim_checks": [],
"facts_checked": [],
"rationale": "...",
"round": 1,
"traceability_version": "v1",
"executor_output_parse_status": {},
"executor_structured_output": {},
"gatekeeper_result": {},
"composer_output": {},
"tool_trace_summary": []
}
```
必要审计字段:
| 字段 | 说明 |
|---|---|
| `executor_output_parse_status` | Executor 输出是否能解析为 `executor_evidence_v2` |
| `executor_structured_output` | Executor 结构化 claims、hypotheses、recommended_actions、missing_info |
| `gatekeeper_result` | 引用真实性校验结果,包括 rule set version、checked bindings、failed rules、warnings、errors |
| `composer_output` | Composer 最终表达及解析状态 |
| `tool_trace_summary` | Verifier 调用时使用的工具调用导航索引,不是唯一证据源 |
## 7. 数据写入时序
```mermaid
sequenceDiagram
autonumber
participant API as API
participant Svc as ChatService/AiOpsService
participant Session as diagnosis_session
participant Agent as Agent
participant Step as agent_step
participant Tool as tool_invocation
participant Eval as self_evaluation
participant Feedback as case_library
API->>Svc: request
Svc->>Session: create/update RUNNING
Agent->>Step: before/after model
Agent->>Tool: tool call record
Svc->>Session: SUCCESS/FAILED + answer
Svc->>Eval: merge evaluation
API->>Svc: feedback useful
Svc->>Feedback: create case
```
## 8. 当前边界和后续
## 7. 当前边界和后续
当前边界:
- `agent_step.session_id` 和 `tool_invocation.session_id` 通过 sessionId 关联,不强制外键。
- `tool_invocation.step_id` 可为空。
- Milvus chunk 与 `api_document` 通过 metadata.docId 逻辑关联。
- `case_library` 与 session 通过 `diagnosis_id=session_id` 关联。
- `chat_session` 只存会话元数据,不存完整正文历史。
- `diagnosis_run` 存一次运行的长期审计状态。
- `agent_step.run_id` 和 `tool_invocation.run_id` 是 Trace、Verifier、Eval 的运行边界。
- 当前实现主要使用逻辑关联,不依赖数据库外键。
- `case_library.diagnosis_id` 是过渡字段,新值按 `run_id` 解释,旧值可能按 `session_id` 解释。
- `diagnosis_session` 只作为历史兼容和回滚表保留。
后续可增强:
1. 增加 run id,支持同 session 多次独立诊断。
2. 强化 `tool_invocation.step_id` 关联。
3. 将 Gatekeeper 规则配置化时的规则元数据保存为可审计版本。
4. 将 `case_library` 的 rootCause/solution 从完整 answer 中结构化抽取。
1. 强化 `tool_invocation.step_id` 关联。
2. 将 Gatekeeper 规则配置化时的规则元数据保存为可审计版本。
3. 将 `case_library` 的 rootCause/solution 从完整 answer 中结构化抽取。
@@ -391,7 +391,7 @@ Composer 位于 Verifier 之后,输入是 ChatService 过滤后的允许表达
## 7. Trace Persistence
`diagnosis_session.self_evaluation.verifier_evaluation` 持久化:
`diagnosis_run.self_evaluation.verifier_evaluation` 持久化:
```json
{
+25 -16
View File
@@ -1,6 +1,6 @@
# 反馈与自评估架构
**更新日期**:2026-07-08
**更新日期**:2026-07-10
**状态**:当前可运行架构
**参考历史文档**:`archive/2026-07-05-legacy/confidence-feedback.md`
@@ -8,8 +8,8 @@
反馈架构包含两条闭环:
1. 系统自评估:基于工具调用、Gatekeeper、Verifier、Composer、AIOps 规则检查,写入 `diagnosis_session.self_evaluation`。
2. 用户反馈:用户标记 `useful` 或 `not_useful`,写入 `diagnosis_session.feedback`,其中 `useful` 会沉淀案例。
1. 系统自评估:基于当前 run 的工具调用、Gatekeeper、Verifier、Composer、AIOps 规则检查,写入 `diagnosis_run.self_evaluation`。
2. 用户反馈:用户标记 `useful` 或 `not_useful`,优先写入 `diagnosis_run.feedback`,其中 `useful` 会沉淀案例。
当前重要边界:
@@ -21,7 +21,7 @@
```mermaid
flowchart TD
Answer["Chat / AIOps final answer"] --> Session["diagnosis_session.answer"]
Answer["Chat / AIOps final answer"] --> Run["diagnosis_run.answer"]
subgraph SelfEval["Self evaluation"]
Invocation["tool_invocation"] --> RuleEval["EvaluationService: rule_evaluation"]
@@ -40,24 +40,24 @@ flowchart TD
RuleEval --> Merge["SelfEvaluationMergeService"]
VerifierEval --> Merge
AiOpsEval --> Merge
Merge --> SelfJson["diagnosis_session.self_evaluation"]
Merge --> SelfJson["diagnosis_run.self_evaluation"]
subgraph UserFeedback["User feedback"]
UI["Feedback bar"] --> API["POST /api/feedback"]
API --> FeedbackService["FeedbackService"]
FeedbackService --> FeedbackField["diagnosis_session.feedback"]
FeedbackService --> FeedbackField["diagnosis_run.feedback"]
FeedbackService --> Useful{"feedback == useful?"}
Useful -->|yes| CaseService["CaseLibraryService.createFromSession"]
Useful -->|yes| CaseService["CaseLibraryService.createFromRun"]
CaseService --> Case["case_library"]
Useful -->|no| BadCase["Bad case by feedback=not_useful"]
end
Session --> UI
Run --> UI
```
## 3. self_evaluation JSON
`SelfEvaluationMergeService` 统一维护 `diagnosis_session.self_evaluation`。
`SelfEvaluationMergeService` 统一维护当前运行的 `diagnosis_run.self_evaluation`。历史兼容数据可能仍存在于 `diagnosis_session.self_evaluation`,但新 Chat/AIOps 执行不再写旧表。
当前结构:
@@ -149,7 +149,7 @@ flowchart LR
Composer --> ComposerOutput["composer_output"]
Output --> Merge["SelfEvaluationMergeService.mergeVerifierEvaluation"]
ComposerOutput --> Merge
Merge --> Session["diagnosis_session.self_evaluation.verifier_evaluation"]
Merge --> Run["diagnosis_run.self_evaluation.verifier_evaluation"]
```
Verifier 输出:
@@ -198,6 +198,7 @@ POST /api/feedback
Content-Type: application/json
{
"runId": "run-xxx",
"sessionId": "xxx",
"feedback": "useful" | "not_useful"
}
@@ -209,6 +210,8 @@ Content-Type: application/json
{
"success": true,
"message": "反馈已记录",
"runId": "run-xxx",
"fallbackToLatestRun": false,
"caseId": "uuid 或 null"
}
```
@@ -217,10 +220,16 @@ Content-Type: application/json
| feedback | 行为 |
|---|---|
| `useful` | 写入 `DiagnosisSession.feedback`,调用 `CaseLibraryService.createFromSession` |
| `not_useful` | 写入 `DiagnosisSession.feedback`,不改变 session status |
| `useful` | 写入 `DiagnosisRun.feedback`,调用 `CaseLibraryService.createFromRun` |
| `not_useful` | 写入 `DiagnosisRun.feedback`,不改变 run status |
| 其他值 | 返回 HTTP 400 |
兼容行为:
- 请求带 `runId` 时,后端验证 `runId` 属于 `sessionId`。
- 请求缺少 `runId` 且存在 run-backed 数据时,后端绑定 latest run,并返回 `fallbackToLatestRun=true` 和实际 `runId`。
- 仅当没有 `diagnosis_run` 但存在历史 `diagnosis_session` 时,才使用历史 fallback;该路径不声明 latest-run fallback。
## 8. 案例沉淀
`useful` 反馈会生成或复用 `case_library` 记录。
@@ -230,7 +239,7 @@ Content-Type: application/json
| CaseLibrary 字段 | 来源 |
|---|---|
| `caseId` | UUID |
| `diagnosisId` | `DiagnosisSession.sessionId` |
| `diagnosisId` | 新数据为 `DiagnosisRun.runId`;历史数据可能为 `DiagnosisSession.sessionId` |
| `sourceType` | `AUTO` |
| `faultCategory` | 当前固定为 `GENERAL` |
| `title` | `query` 前 100 字符 |
@@ -241,7 +250,7 @@ Content-Type: application/json
幂等性:
```text
case_library.diagnosisId == sessionId
case_library.diagnosisId == runId
-> existing case: return existing
-> missing case: create new
```
@@ -260,9 +269,9 @@ Trace API 会展示:
| 视角 | 数据来源 |
|---|---|
| 执行是否成功 | `diagnosis_session.status` |
| 执行是否成功 | `diagnosis_run.status` |
| 证据是否充分 | `self_evaluation.rule_evaluation` / `verifier_evaluation` |
| 用户是否认可 | `diagnosis_session.feedback` |
| 用户是否认可 | `diagnosis_run.feedback` |
## 10. 后续增强
+4 -4
View File
@@ -36,7 +36,7 @@ flowchart TB
Tools --> Invocation["tool_invocation"]
Agent --> StepHook["AgentLoggingHook"]
StepHook --> Step["agent_step"]
Agent --> Session["diagnosis_session"]
Agent --> Run["diagnosis_run"]
Invocation --> EvidenceRefs["retrieval_details.evidence_refs"]
EvidenceRefs --> Gatekeeper["ExecutorGatekeeperService"]
@@ -49,7 +49,7 @@ flowchart TB
Invocation --> AiOpsRule["AiOpsRuleEvaluationService"]
AiOpsRule --> AiOpsEval["self_evaluation.aiops_rule_evaluation"]
Session --> TraceAPI["DiagnosisTraceService"]
Run --> TraceAPI["DiagnosisTraceService"]
Step --> TraceAPI
Invocation --> TraceAPI
SelfEval --> TraceAPI
@@ -210,7 +210,7 @@ Verifier 不再逐字核验 excerpt 真伪;这由 Gatekeeper 完成。Verifier
结果写入:
```text
diagnosis_session.self_evaluation.verifier_evaluation
diagnosis_run.self_evaluation.verifier_evaluation
```
其中同时持久化 `executor_structured_output`、`gatekeeper_result`、`tool_trace_summary`、`prompt_audit` 和 `composer_output`,用于 Trace 回放。
@@ -229,7 +229,7 @@ AIOps 当前不走 Chat Verifier,而是用 `AiOpsRuleEvaluationService` 做轻
结果写入:
```text
diagnosis_session.self_evaluation.aiops_rule_evaluation
diagnosis_run.self_evaluation.aiops_rule_evaluation
```
## 8. Eval Baseline
+6 -5
View File
@@ -34,14 +34,15 @@ flowchart TB
AiOpsFlow --> Trace
Tools --> Trace
Trace --> Session["diagnosis_session"]
Trace --> ChatSession["chat_session"]
Trace --> Run["diagnosis_run"]
Trace --> Step["agent_step"]
Trace --> Invocation["tool_invocation"]
Invocation --> Verifier["Verifier / Rule Evaluation"]
Verifier --> SelfEval["self_evaluation"]
Session --> TraceAPI["GET /api/diagnosis/{sessionId}/trace"]
Run --> TraceAPI["GET /api/diagnosis/{sessionId}/trace?runId=..."]
Step --> TraceAPI
Invocation --> TraceAPI
SelfEval --> TraceAPI
@@ -61,15 +62,15 @@ Planner 负责拆解,Executor 只负责调用知识库、日志和指标工具
AIOps 告警入口走 Supervisor 调度 Planner/Executor:
如果请求里有 alert payload,系统会进入 PAYLOAD_TARGETED 模式,报告必须聚焦这个告警,而不是被当前环境中的其他活跃告警带偏。
所有过程都会落到 diagnosis_session、agent_step、tool_invocation。
所以我可以用一个 sessionId 回放:模型怎么规划、调了哪些工具、工具返回什么、Gatekeeper 怎么验真、Verifier 怎么判定、Composer 最后怎么表达、用户最后是否反馈有用。
会话元数据会落到 chat_session,每次诊断运行会落到 diagnosis_run,步骤和工具明细通过 run_id 关联。
所以我可以用 sessionId + runId 精确回放:模型怎么规划、调了哪些工具、工具返回什么、Gatekeeper 怎么验真、Verifier 怎么判定、Composer 最后怎么表达、用户最后是否反馈有用。
```
## 4. 五个亮点
| 亮点 | 怎么讲 |
|---|---|
| 可追踪 Agent | 每次诊断都有 `sessionId`,Trace API 可以回放 session、step、tool |
| 可追踪 Agent | 每次诊断都有 `runId`,Trace API 可以回放 run、step、tool;同一 `sessionId` 可有多次独立 run |
| 显式工具证据链 | `lookup_knowledge`、日志、指标都记录到 `tool_invocation` |
| RAG 工程化 | L0 降级为 hint,Spring AI VectorStore 做主检索,SDK fallback 保底 |
| 质量门禁 | Chat Gatekeeper 验引用、Verifier 判可推导、Composer 控表达,AIOps rule evaluation 控制告警聚焦 |
+65 -115
View File
@@ -1,69 +1,68 @@
# 会话与 Trace 生命周期
**更新日期**:2026-07-08
**更新日期**:2026-07-10
**状态**:当前可运行架构
**参考历史文档**:`archive/2026-07-05-legacy/session-management.md`
## 1. 定位
旧版会话设计以 Redis 会话为主,MySQL 作为可选长期沉淀。当前 MVP 的可追踪诊断已经转为 MySQL Trace 三表为主:
当前 MVP 把“会话态”和“运行态”拆开:
```text
diagnosis_session
-> agent_step
-> tool_invocation
chat_session(sessionId)
-> diagnosis_run(runId)
-> agent_step(runId)
-> tool_invocation(runId)
```
因此本文描述的是当前可运行链路:
- `sessionId` 是一次诊断和后续 trace/feedback 的关联键。
- `diagnosis_session` 保存会话级状态、问题、答案、自评估和反馈。
- `agent_step` 保存每个 Agent 模型调用。
- `tool_invocation` 保存工具调用事实。
- `DiagnosisTraceService` 聚合三类记录,形成可回放 trace。
- `sessionId` 表示多轮会话目录和 Redis 上下文。
- `runId` 表示一次可回放诊断执行。
- `DiagnosisTraceService` 聚合一个 run 的主记录、步骤和工具调用,形成可回放 Trace。
- `diagnosis_session` 只保留为历史兼容和回滚表。
## 2. 生命周期总图
```mermaid
flowchart TD
Start["request: chat / ai_ops"] --> Resolve["resolve sessionId"]
Resolve --> Create["create or reset diagnosis_session"]
Create --> Running["status = RUNNING"]
Resolve --> Session["ensure chat_session metadata"]
Session --> Run["create diagnosis_run(runId)"]
Run --> Running["run.status = RUNNING"]
Running --> Agent["Agent workflow"]
Agent --> StepHook["AgentLoggingHook"]
StepHook --> Step["agent_step"]
Agent --> Tool["Evidence tools"]
Tool --> Invocation["tool_invocation"]
Agent --> Context["execution context(sessionId, runId)"]
Context --> StepHook["AgentLoggingHook"]
StepHook --> Step["agent_step(session_id, run_id)"]
Context --> Tool["Evidence tools"]
Tool --> Invocation["tool_invocation(session_id, run_id)"]
Invocation --> Gatekeeper["Gatekeeper evidence validation"]
Agent --> Final{"workflow result"}
Final -->|success| Success["status = SUCCESS, answer saved"]
Final -->|failed| Failed["status = FAILED"]
Final -->|success| Success["run.status = SUCCESS, answer saved"]
Final -->|failed| Failed["run.status = FAILED"]
Success --> Evaluation["self_evaluation merge"]
Success --> Evaluation["diagnosis_run.self_evaluation merge"]
Failed --> Evaluation
Evaluation --> Trace["GET /api/diagnosis/{sessionId}/trace"]
Success --> Feedback["POST /api/feedback"]
Feedback --> Case["useful -> case_library"]
Evaluation --> Trace["GET /api/diagnosis/{sessionId}/trace?runId=..."]
Success --> Feedback["POST /api/feedback(sessionId, runId)"]
Feedback --> Case["useful -> case_library(run_id)"]
```
## 3. sessionId 规则
## 3. ID 规则
| 链路 | sessionId 来源 |
|---|---|
| Chat | 如果请求带 sessionId,则复用;否则生成短 UUID |
| AIOps | 如果 payload 带 sessionId,则复用;否则生成 UUID |
| Trace | URL path 中的 `{sessionId}` |
| Feedback | request body 中的 `sessionId` |
| ID | 来源 | 含义 |
|---|---|---|
| `sessionId` | Chat request `Id`、AIOps payload `sessionId`,缺失时由服务生成 | 多轮会话目录和 Redis 上下文 |
| `runId` | 每次有效 Chat/AIOps 执行创建 | 一次诊断运行和 Trace 回放边界 |
设计含义:
- 同一个 `sessionId` 可以贯穿诊断、trace 查询和用户反馈。
- 当前诊断开始时会重置当前 session 的运行态字段,例如 answer、duration、step/tool count。
- `sessionId` 是业务关联键,不依赖数据库自增 ID 暴露给外部。
- 同一个 `sessionId` 可以贯穿多轮 Chat。
- 每次有效 Chat/AIOps 执行都会创建新的 `runId`。
- Trace 和 Feedback 新客户端应传 `runId`;只传 `sessionId` 时兼容解析 latest run。
- latest run 排序使用 `diagnosis_run.created_at DESC, id DESC`,不使用 `updated_at`。
## 4. 状态流转
## 4. 运行状态流转
```mermaid
stateDiagram-v2
@@ -77,14 +76,14 @@ stateDiagram-v2
字段边界:
| 字段 | 含义 |
|---|---|
| `status` | 执行状态:`PENDING` / `RUNNING` / `SUCCESS` / `FAILED` |
| `answer` | Agent 最终返回给用户的报告或答复 |
| `self_evaluation` | 系统自评估 JSON |
| `feedback` | 用户反馈:`useful` / `not_useful` / null |
| 字段 | 所属表 | 含义 |
|---|---|---|
| `status` | `diagnosis_run` | 单次运行执行状态 |
| `answer` | `diagnosis_run` | 本次运行最终报告或答复 |
| `self_evaluation` | `diagnosis_run` | 本次运行系统自评估 JSON |
| `feedback` | `diagnosis_run` | 本次运行用户反馈 |
`feedback` 不修改 `status`。一个执行成功但用户标记 `not_useful` 的 session,仍然应该是 `SUCCESS + feedback=not_useful`。
`feedback` 不修改 `status`。一个执行成功但用户标记 `not_useful` 的 run,仍然应该是 `SUCCESS + feedback=not_useful`。
## 5. agent_step 写入
@@ -93,93 +92,49 @@ stateDiagram-v2
```mermaid
sequenceDiagram
autonumber
participant Agent as ReactAgent
participant Agent as Agent
participant Hook as AgentLoggingHook
participant DB as agent_step
Agent->>Hook: before_model(messages, sessionId)
Hook->>DB: insert step_index / agent_name / model_input
Agent-->>Agent: model call
Agent->>Hook: after_model(messages, sessionId)
Hook->>DB: update model_output / thought / has_tool_call / duration / token_count
Agent->>Hook: before_model(messages, sessionId, runId)
Hook->>DB: insert step(session_id, run_id, model_input, step_index)
Agent->>Hook: after_model(output, sessionId, runId)
Hook->>DB: update model_output, duration, token_count, has_tool_call
```
当前记录:
- `session_id`
- `step_index`
- `agent_name`
- `model_input`
- `model_output`
- `thought`
- `has_tool_call`
- `duration_ms`
- `token_count`
新写入必须带 `run_id`,同时保留 `session_id` 便于粗粒度排查。
## 6. tool_invocation 写入
工具调用记录真实工具事实,不记录模型猜测。
关键字段:
工具调用记录同样通过执行上下文拿到 `sessionId + runId`:
```text
session_id
step_id
tool_name
input_params
output_preview
output_length
retrieval_layer
l0_match_count
l1_match_count
retrieval_details
-> evidence_refs
relevance_level
dedup_reason
duration_ms
success
error_message
ToolInvocationRecorder
-> tool_invocation.session_id
-> tool_invocation.run_id
-> retrieval_details / evidence_refs
```
对 `lookup_knowledge`,`retrieval_details` 会承载 L0/L1、领域、证据状态、去重等检索细节。对日志、指标和知识库工具,`retrieval_details.evidence_refs` 会记录 Gatekeeper 可核验的最小证据引用:
```json
{
"evidence_refs": [
{
"raw_path": "$.logs[0]",
"text": "最小证据文本"
}
]
}
```
当工具明确没有返回匹配证据时,可以记录 `raw_path=$.no_evidence`。该路径只表示“本次工具查询未检索到匹配证据”,不表示问题被排除。
Verifier、Gatekeeper 和 EvaluationService 应按 `run_id` 读取工具调用,避免同一 session 的其他 run 参与评分或证据校验。
## 7. Trace API 聚合
```text
GET /api/diagnosis/{sessionId}/trace
GET /api/diagnosis/{sessionId}/trace?runId=run-...
```
聚合逻辑:
```text
diagnosis_session by sessionId
+ agent_step ordered by step_index
+ tool_invocation ordered by id
diagnosis_run by sessionId + runId
+ chat_session metadata when available
+ agent_step where run_id = runId, ordered by the Trace API
+ tool_invocation where run_id = runId order by id
-> DiagnosisTraceResponse
```
Trace 视图回答的问题:
- 这次诊断是否成功?
- 哪些 Agent 参与了?
- 每一步模型输入输出是什么摘要?
- 调用了哪些工具?
- 工具返回了什么证据?
- Gatekeeper / Verifier / Composer / AIOps rule 是否通过?
- 用户是否反馈有用?
当 `runId` 缺失时,Trace API 为兼容旧客户端解析最新 run,并在响应中返回 resolved `runId`。当 `runId` 属于其他 `sessionId` 时,API 必须拒绝,不能泄漏其他会话的 Trace。
## 8. Chat 与 AIOps 差异
@@ -189,22 +144,17 @@ Trace 视图回答的问题:
| 编排方式 | `SequentialAgent`: Planner -> Executor -> Gatekeeper -> Verifier -> Composer | `SupervisorAgent`: Planner + Executor |
| 自评估 | `rule_evaluation` + `verifier_evaluation` | `aiops_rule_evaluation` |
| 答案字段 | Chat 最终答复 | 告警分析报告 |
| payload | 用户自然语言 + history | alert payload 或 auto-discovery |
| runId 暴露 | `/api/chat` JSON response | `/api/ai_ops` SSE metadata message |
## 9. 清理与边界
当前会话持久化边界:
- MySQL Trace 记录是主要可回放来源。
- Chat 历史仍可作为请求上下文传入 Agent,但不是本文档的主持久化模型。
- Redis 主会话存储是历史设计,不作为当前架构事实。
- `RetrievedDocTracker` 是 session 级运行时去重状态,诊断结束后清理。
- Redis 会话历史用于多轮上下文,不是长期审计记录。
- MySQL `diagnosis_run + agent_step + tool_invocation` 是主要可回放来源。
- `chat_session.expires_at` 只是目录元数据;Redis 消息历史可独立过期。
- `RetrievedDocTracker` 仍是 session 级运行时去重状态,诊断结束后清理。
## 10. 后续增强
可考虑:
1. Trace API 增加更结构化的 `self_evaluation` 展示。
2. `agent_step` 与 `tool_invocation.step_id` 建立更严格关联。
3. 对多轮同 session 诊断增加 run id,避免复用 session 时历史记录混杂。
4. 为 Trace 增加导出能力,服务面试演示和回归分析。
3. 旧 `diagnosis_session` 只读观察期结束后,再评估数据库层面的约束收紧或归档策略。