# 一次诊断到底发生了什么(E2E 全流程导读)
**日期**:2026-07-28
**状态**:SUCCESS 完整诊断主文档;工具阶段按**现行**审计能力(`step_id` / `query`)说明
**文档路径**:`docs/一次诊断全流程-E2E导读.md`
### 主样本(正文数值与 timeline 来源)
| 项 | 值 |
|----|----|
| `session_id` | `e2e-rag-success-20260728162949` |
| `run_id` | `27415045-e674-41af-9cea-de01f27ce040` |
| 入口 | `POST /api/chat`(SSE) |
| 结果 | `outcome=SUCCESS`,`content_type=DIAGNOSIS_REPORT` |
| 工具 | 仅 1 次 `lookup_knowledge`(hybrid) |
| 模型 | 4 次(Router + Agent×2 + Semantic Guard) |
| Token | **13236**(`tokens_reconciled=true`) |
| 耗时 | ~**25s** |
**现行审计**(`step_id` 挂 step、`input_params.query` 等)已合入主路径,见 [§3.4.1](#341-step_id--query-审计如何写入2026-07-28-改造)。
专项 live 验收(含一次业务 FALLBACK 样本)见独立文档:
→ [RAG 审计补丁 E2E:step_id + query](RAG审计补丁-stepid-query-E2E验收.md)
**关联文档**:
- [RAG Trace / 审计架构](../mvp/architecture/RAG检索可观测性与审计.md)
- [RAG qualityScore 与后处理](RAG-Hybrid质量分与后处理.md)
- [Agent 如何读 relevance_level](RAG-Agent如何读relevance_level.md)
- [知识检索架构](../mvp/architecture/RAG知识检索架构.md)
**回放 API**:
```http
GET /api/diagnosis/{sessionId}/trace?runId={runId}
GET /api/diagnosis/{sessionId}/trace/reasoning?runId={runId}
```
本地产物(若仍在):`target/e2e-rag-success-sse.txt`、`target/e2e-rag-success-trace.json`。
---
## 1. 先建立心智模型
一次「诊断」不是「调一次 LLM 再返回答案」,而是 **Harness 编排的多阶段流水线**:
1. 协议层建 session/run,打开 SSE
2. 路由模型判定意图(本次 `DIAGNOSIS`)
3. 诊断 Agent 规划并调用工具(本次 RAG)
4. 工具返回证据(Agent 只看投影结果,完整轨迹进审计)
5. 诊断 Agent 基于证据写报告草稿
6. 证据结构门控 + 语义门控
7. 放行 `SUCCESS` 报告,或降级 `FALLBACK`
8. 落库并对账 token / timeline,供 Trace 回放
```mermaid
flowchart LR
U[用户 / 客户端] -->|POST /api/chat| API[ChatController SSE]
API --> H[Diagnosis Harness]
H --> R[Intent Router]
H --> A[Diagnosis Agent]
H --> T[Tools]
H --> G[Guards]
H --> REL[Release]
T --> RAG[lookup_knowledge
Hybrid Milvus]
T --> LOG[query_logs / 其它]
REL --> SSE[SSE content + done]
H --> DB[(MySQL 审计与 Trace)]
DB --> TR[GET .../trace]
```
**读本文时记住三句话**:
1. **SSE 是对外协议**;**timeline / tool_invocation 是对内账本**。
2. **Agent 看到的工具结果 ≠ 完整 RAG trace**(中间有投影边界)。
3. **`run.total_token_count` 含 Router + Agent + Guard**;`agent_step.tokenCount` 只含诊断 Agent 各轮。
---
## 2. 逻辑架构:谁在场
```mermaid
flowchart TB
subgraph edge["边缘 / 协议"]
CC[ChatController]
SSE[ChatSseSession]
end
subgraph app["应用用例"]
UC[ChatApplicationUseCase]
EX[DiagnosisChatExecutor]
end
subgraph harness["Harness 核心"]
CORE[DiagnosisHarnessCore
RunContext / Budget]
ROUTER[Intent Router]
AGENT[Diagnosis Agent
+ Tool Calling]
BOUND[ToolBoundary]
EG[Evidence Guard]
SG[Semantic Guard]
REL[DiagnosisReleaseUseCase]
end
subgraph tools["工具层"]
LK[LookupKnowledgeTool]
QL[QueryLogsTools]
OTHER[其它工具...]
end
subgraph rag["RAG 子系统"]
EMB[Embedding BGE-M3]
VS[VectorSearchService]
HY[MilvusHybridKnowledgeStore
dense + BM25 + RRF]
PP[Evidence PostProcessor
quality / relevance_level]
end
subgraph audit["审计与回放"]
MCA[ModelCallAuditor]
TIS[JpaToolInvocationAuditSink
+ RagLookupAuditEnricher]
DTR[DiagnosisTraceRecorder]
API2[DiagnosisTraceController]
MY[(diagnosis_run
agent_step
tool_invocation
diagnosis_trace_event)]
end
CC --> SSE
CC --> UC --> EX --> CORE
CORE --> ROUTER
CORE --> AGENT
AGENT --> BOUND --> LK
BOUND --> QL
LK --> EMB --> VS --> HY
VS --> PP
EX --> EG --> SG --> REL --> SSE
CORE --> MCA --> DTR
BOUND --> TIS --> MY
DTR --> MY
API2 --> MY
```
| 角色 | 职责一句话 |
|------|------------|
| ChatController | HTTP/SSE 适配,不承载诊断逻辑 |
| Intent Router | 判断是否进入诊断 |
| Diagnosis Agent | 规划工具、消化证据、写草稿 |
| ToolBoundary | 工具执行边界:投影给 Agent + 审计落库 |
| lookup_knowledge | 只检索,不写结论 |
| Evidence Guard | 结构/引用可核验性(偏规则) |
| Semantic Guard | 语义是否被证据支撑(偏模型) |
| Release | 终态与对外 content 形态 |
| Auditors / Trace | token、步骤、工具、事件可回放 |
---
## 3. 端到端时序(本次真实路径)
```mermaid
sequenceDiagram
autonumber
actor User as 客户端
participant API as ChatController
participant H as Harness
participant Router as Intent Router LLM
participant Agent as Diagnosis Agent LLM
participant Tool as lookup_knowledge
participant Emb as Embedding
participant Milvus as Hybrid Milvus
participant EG as Evidence Guard
participant SG as Semantic Guard LLM
participant DB as MySQL
User->>API: POST /api/chat {Id, Question}
API->>User: event metadata {session_id, run_id}
API->>H: start run
H->>DB: diagnosis_run + RUN_STARTED
API->>User: event status ROUTING
H->>Router: 路由 prompt + 用户问题
Router-->>H: intent=DIAGNOSIS (906 tokens)
H->>DB: ROUTING_* + MODEL_TOKEN_USAGE
API->>User: event status DIAGNOSIS_RUNNING
H->>Agent: round1 system/user + tools schema
Agent-->>H: tool_call lookup_knowledge (2657 tokens)
H->>DB: agent_step#0 + AGENT_MODEL_STEP
H->>Tool: execute(query)
Tool->>Emb: embed query (1024-d)
Emb-->>Tool: vector
Tool->>Milvus: hybridSearch dense+BM25+RRF
Milvus-->>Tool: topK candidates
Tool-->>H: LookupResult + projected RagToolResult
H->>DB: tool_invocation + TOOL_INVOCATION
PRECISE / hybrid / EVIDENCE_FOUND
H->>Agent: round2 user+assistant+tool
Agent-->>H: DIAGNOSIS draft JSON (4703 tokens)
H->>DB: agent_step#1
H->>EG: 校验 tool_call 引用
EG-->>H: PASSED
API->>User: event status SAFETY_VALIDATING
H->>SG: 报告 + 证据摘要
SG-->>H: verdict=SUPPORTED (4970 tokens)
H->>H: RELEASE SUCCESS
API->>User: event content DIAGNOSIS_REPORT
API->>User: event done SUCCESS
H->>DB: RUN_FINISHED tokens_reconciled
total=13236
```
---
## 4. 状态机与对外 SSE 契约
### 4.1 内部阶段机
```mermaid
stateDiagram-v2
[*] --> RUN_STARTED
RUN_STARTED --> ROUTING
ROUTING --> DIAGNOSIS_AGENT: intent=DIAGNOSIS
ROUTING --> OTHER_PATH: 非诊断意图
DIAGNOSIS_AGENT --> TOOL_LOOP: 发出 tool_call
TOOL_LOOP --> DIAGNOSIS_AGENT: 工具结果回注
DIAGNOSIS_AGENT --> EVIDENCE_GUARD: 产出草稿且不再调工具
EVIDENCE_GUARD --> SEMANTIC_GUARD: PASSED
EVIDENCE_GUARD --> FALLBACK_OR_REPAIR: 结构失败
SEMANTIC_GUARD --> RELEASE_SUCCESS: SUPPORTED
SEMANTIC_GUARD --> RELEASE_FALLBACK: 不足/不支持
RELEASE_SUCCESS --> RUN_FINISHED
RELEASE_FALLBACK --> RUN_FINISHED
OTHER_PATH --> RUN_FINISHED
```
### 4.2 SSE 事件顺序(成功路径)
```mermaid
flowchart LR
M[metadata] --> S1[status ROUTING]
S1 --> S2[status DIAGNOSIS_RUNNING]
S2 --> S3[status SAFETY_VALIDATING]
S3 --> C[content DIAGNOSIS_REPORT]
C --> D[done SUCCESS]
```
| event | 何时出现 | 本次含义 |
|-------|----------|----------|
| `metadata` | 立刻 | 绑定 `session_id` / `run_id` |
| `status` | 可多次 | 进度码:路由 / 收集证据 / 安全校验 |
| `content` | 成功终稿一次 | `DIAGNOSIS_REPORT` 载荷 |
| `done` | 最后 | `outcome=SUCCESS` / `FALLBACK` / `FAILED` |
| `failure` | 与 content 互斥 | 本次未出现 |
**请求体字段**:
| 字段 | 含义 |
|------|------|
| `Id` | 会话 ID(可多轮复用) |
| `Question` | 本轮问题 → 写入 `diagnosis_run.query` |
---
## 5. 分阶段详解:发送了什么、产出什么、字段含义
下面每阶段统一用四块说明:**职责 / 发送 / 产出 / 字段**。数值均来自样本 run。
---
### 阶段 0 — HTTP 接入与 Run 创建
**职责**:协议适配;创建 `session`/`run`;打开 SSE。不做诊断推理。
**发送**:
- 客户端 → 服务:`POST /api/chat` JSON
- 服务 → 客户端:`metadata`
**产出**:
- `diagnosis_run` 初始行
- timeline:`RUN_STARTED`
| 字段 | 含义 |
|------|------|
| `session_id` | 对话会话身份 |
| `run_id` | **这一次**诊断执行 ID(一问一 run) |
| `agent_flow` | 入口形态;Chat 为 `CHAT` |
| `query` | 用户原问题 |
```mermaid
flowchart LR
REQ[Request Id+Question] --> NEW[创建 run_id]
NEW --> META[SSE metadata]
NEW --> ROW[diagnosis_run PENDING/RUNNING]
NEW --> EV[timeline RUN_STARTED]
```
---
### 阶段 1 — ROUTING(意图路由)
**职责**:判断走诊断 / 其它路径。不调业务工具、不查知识库。
**发送**:1 次 Chat 模型(Intent Router)
| | tokens |
|--|--------|
| input | 323 |
| output | 583 |
| total | **906** |
**产出 timeline**:
1. `MODEL_TOKEN_USAGE`(`component=INTENT_ROUTER`)
2. `ROUTING_ATTEMPT`
3. `ROUTING_DECISION` → `intent=DIAGNOSIS`
| 字段 | 含义 |
|------|------|
| `component` | 模型组件名:`INTENT_ROUTER` |
| `component_round` | 该组件第几轮 |
| `input_tokens` / `output_tokens` / `total_tokens` | 本调用 usage |
| `usage_available` | 供应商是否返回 usage |
| `intent` | 路由结果;`DIAGNOSIS` 进入诊断 harness |
SSE:`status: ROUTING`。
```mermaid
flowchart TB
Q[用户问题] --> RP[路由 Prompt]
RP --> LLM[Intent Router LLM]
LLM --> D{intent}
D -->|DIAGNOSIS| DIAG[进入诊断执行器]
D -->|其它| OTH[非诊断路径]
LLM --> TU[MODEL_TOKEN_USAGE 入账]
```
---
### 阶段 2 — AGENT round 1(规划并调用工具)
**职责**:读问题与工具 schema,决定调谁、参数是什么。本轮通常 **只出 tool_call**,不写最终报告。
**发送**:1 次 Diagnosis Agent 模型
| | |
|--|--|
| `step_index` | 0 |
| duration | 1454 ms |
| tokens | in 2554 / out 103 / total **2657** |
| `modelOutput` | `has_text=false`, `tool_names=["lookup_knowledge"]` |
**产出**:
- `agent_step` #0
- timeline:`MODEL_TOKEN_USAGE` + `AGENT_MODEL_STEP`
- 内部 `tool_call_id`:`call_00_91fKPqaJg4z4gvvZIqcA8891`
| 字段 | 含义 |
|------|------|
| `stepIndex` | Agent 模型轮次,从 0 起 |
| `agentName` | 如 `diagnosis_agent` |
| `tokenCount` | **本步**模型 total tokens(不含 router/guard) |
| `durationMs` | 本步墙钟耗时 |
| `modelInput` | 输入摘要(roles、message_count),非全文 prompt |
| `modelOutput` | 输出摘要:是否有正文、工具名列表、reasoning 标记 |
| `hasToolCall` | 是否触发工具 |
| `thought` | 思维链(若有);样本为空 |
```mermaid
flowchart LR
CTX[上下文: user + tools schema] --> A1[Agent LLM r1]
A1 --> TC[tool_call
lookup_knowledge]
A1 --> ST0[agent_step 0 落库]
TC --> BOUND[进入 ToolBoundary]
```
---
### 阶段 3 — TOOL:`lookup_knowledge`(Hybrid RAG)
**职责**:**只检索**。把 query 变成可引用证据;完整轨迹进审计,Agent 只拿投影后的证据契约。
#### 3.1 工具内架构
```mermaid
flowchart TB
TC[tool_call query] --> TB[ToolBoundary]
TB --> LK[LookupKnowledgeTool]
LK --> L0[L0 Hint
关键词 / 域]
LK --> QT[QueryTransformer
category / keywords]
LK --> EMB[EmbeddingService
BGE-M3 1024d]
EMB --> VS[VectorSearchService]
VS --> HY[Milvus hybridSearch]
HY --> D[dense ANN L2]
HY --> S[BM25 sparse]
D --> RRF[服务端 RRF 融合]
S --> RRF
RRF --> PP[PostProcess
qualityScore / relevance_level
截断预算]
PP --> RAW[LookupResult 内部 JSON]
RAW --> PROJ[Projector → RagToolResult]
PROJ --> AGENT[返回 Agent]
RAW --> AUD[RagLookupAuditEnricher]
AUD --> TI[(tool_invocation)]
TB --> TL[timeline TOOL_INVOCATION]
```
#### 3.2 样本实测
| 项 | 值 |
|----|-----|
| query_chars | 50 |
| retrieveK | 20 |
| `search_mode` | **hybrid** |
| tool `duration_ms` | **1243** |
| attempt `duration_ms` | ~1174 |
| `relevance_level` | **PRECISE** |
| `evidence_status` | **EVIDENCE_FOUND** |
| candidates → blocks | 20 → 5 |
| `top_similarity` | ~0.808(dense 闸门侧) |
| context | 3022 / 4000,`truncated=false` |
| L0 domains | infrastructure, database |
| selected_attempt | `UNFILTERED_VECTOR`(无 fallback) |
#### 3.3 `retrieval_details`(`audit_schema=rag_lookup_v1`)字段词典
| 字段 | 含义 |
|------|------|
| `audit_schema` | 审计 JSON 版本 |
| `search_mode` | 配置检索模式:`hybrid` / `dense` |
| `tool_call_id` | 与 Agent tool_call 对齐 |
| `status` / `invocation_status` | 工具执行态;成功多为 `READY` |
| `evidence_status` | `EVIDENCE_FOUND` / `NO_EVIDENCE` 等 |
| `retrieval_evidence_status` | 更细状态,如 `supported` |
| `attempts[]` | 每次检索尝试列表 |
| `attempts[].name` | 如 `FILTERED_VECTOR` / `UNFILTERED_VECTOR` |
| `attempts[].usable` | 该次结果是否被采用 |
| `attempts[].duration_ms` | 该次检索耗时 |
| `attempts[].top_similarity` | 质量闸门用相似度(非 RRF 主分本身) |
| `attempts[].candidate_count` | 原始候选数 |
| `selected_attempt` | 最终采用的 attempt |
| `l0_hints.domains` | L0 域提示 |
| `l0_hints.matched_keywords` | L0 命中词 |
| `sources` | 返回块来源(可重复 doc) |
| `evidence_keys` | 稳定键,如 `docId#chunk-n` |
| `evidence_candidate_count` | 候选规模 |
| `evidence_block_count` / `returned_count` | 交给 Agent 的块数 |
| `context_used_chars` / `context_char_budget` | 证据字符占用与预算 |
| `agent_result_bytes` | 投影后 JSON 字节数 |
| `completeness_hint` | 完整度提示文案 |
| `truncated` | 是否因预算截断 |
#### 3.4 `tool_invocation` 表字段
| 字段 | 含义 | 样本 |
|------|------|------|
| `tool_name` | 工具名 | `lookup_knowledge` |
| `success` | 是否执行完成(无证据也可为 true) | 1 |
| `duration_ms` | 工具总耗时 | 1243 |
| `retrieval_layer` | 主命中层,如 L1 | L1 |
| `l0_match_count` / `l1_match_count` | L0 命中 / L1 块数 | 3 / 5 |
| `relevance_level` | PRECISE / REFERENCE / RELATED / 空 | PRECISE |
| `input_params` | 入参审计 | `tool_call_id` + `request_bytes` + 可选 `step_id` + **安全请求字段**(如 `query` 预览,≤160 字符;敏感键过滤) |
| `output_preview` | 短摘要 | level=PRECISE ... |
| `output_length` | 投影结果长度 | 3212 |
| `step_id` | 关联 `agent_step.id` | 由 `AgentStepAuditTracker` 在 Agent `beforeModel` 绑入;工具执行时写入 |
| `retrieval_details` | 上表富 JSON | rag_lookup_v1 |
#### 3.4.1 `step_id` + query 审计如何写入(2026-07-28 改造)
```mermaid
sequenceDiagram
participant Hook as HarnessAgentAuditHook
participant DB as agent_step
participant Tr as AgentStepAuditTracker
participant TB as ToolBoundary
participant Sink as JpaToolInvocationAuditSink
participant TI as tool_invocation
Hook->>DB: beforeModel 落库 step 行
DB-->>Hook: step.id
Hook->>Tr: bind(runId, stepId)
Note over Hook,TB: afterModel 发出 tool_call 后仍保持 bind
直到下一轮 beforeModel 或 run finish clear
TB->>Tr: currentStepId(runId)
Tr-->>TB: stepId
TB->>Sink: AuditEvent(stepId, requestJson)
Sink->>TI: step_id 列 + input_params 安全展开
```
| 组件 | 职责 |
|------|------|
| `AgentStepAuditTracker` | run 级当前 `agent_step.id` 绑定表 |
| `HarnessAgentAuditHook` | `beforeModel` 落 step 后 `bind` |
| `ToolBoundary.auditSafely` | 读 tracker,把 `stepId` + `requestJson` 放进 audit event |
| `JpaToolInvocationAuditSink` | 写 `step_id` 列;`input_params` 展开安全字段 |
| `TraceAuditEvents.toolInvocation` | timeline details 带 `step_id`(有则写) |
| `JpaChatRunStore.finish` | `clear(runId)` 防泄漏 |
**`input_params` 安全规则**(实现于 sink,非原样 dump request):
- 始终:`tool_call_id`、`request_bytes`;有则:`step_id`
- 从 request JSON **顶层**提取 string / number / boolean / 纯字符串数组
- 文本最多 **160** 字符;超长附加 `*_truncated`、`*_chars`
- 键名含 `password` / `token` / `secret` / `apikey` / `authorization` 等 → **不落库**
- 嵌套 object / 混合数组不整段写入
**现行 `input_params` 形态示例**(逻辑结构;含 PRECISE 时另有 `retrieval_details` 富字段):
```json
{
"query": "MySQL connection pool exhausted HikariCP diagnosis",
"step_id": 123,
"tool_call_id": "call_…",
"request_bytes": 62
}
```
| 关联 | 含义 |
|------|------|
| `agent_step.id` | 发出该 tool_call 的 Agent 轮次 |
| `tool_invocation.step_id` | 指向上述 step |
| `input_params.query` | 工具检索 query(安全截断后) |
live 数字级验收与 FALLBACK 对照见 → [审计补丁 E2E 专项](RAG审计补丁-stepid-query-E2E验收.md)。
#### 3.5 分数语义(避免误读)
```mermaid
flowchart LR
subgraph hybrid["hybrid 主路径"]
RRF[RRF 融合分] --> ORD[返回序 = 权威排序]
RRF --> SL[scoreLabel = hybrid]
end
subgraph gate["质量闸门侧"]
L2[dense L2 / similarity] --> QS[qualityScore / top_similarity]
QS --> RL[relevance_level]
end
ORD --> AGENT[Agent 所见证据序]
RL --> AGENT
```
- **排序权威**:hybrid 下是 RRF 返回序,不是 L2 重排。
- **`scoreLabel=hybrid`**:主分来自融合,不要当「越大越像 cosine」。
- **`top_similarity` / denseDistance**:服务后处理绝对质量闸门(如 L0 过滤过严时的 fallback),不覆盖 hybrid 主序。
SSE:保持 `DIAGNOSIS_RUNNING`。
---
### 阶段 4 — AGENT round 2(写诊断草稿)
**职责**:把工具结果收成结构化报告候选;遵守「不编造、证据不足写 limitations」。
**发送**:1 次 Diagnosis Agent
| | |
|--|--|
| `step_index` | 1 |
| duration | **8196 ms** |
| tokens | in 3580 / out 1123 / total **4703** |
| roles | `user` + `assistant` + `tool` |
| 输出 | `has_text=true`,`tool_names=[]`(不再调工具) |
**产出**:内部 Draft(尚未对用户最终生效)→ 进入门控。
```mermaid
flowchart TB
M1[user 原问题] --> CTX
M2[assistant tool_call] --> CTX
M3[tool RagToolResult] --> CTX
CTX[消息上下文] --> A2[Agent LLM r2]
A2 --> DRAFT[报告草稿 JSON]
DRAFT --> EG[Evidence Guard]
```
**为何 input 比 r1 大**:上下文多了 tool 结果(证据约 3k 字符级)。
---
### 阶段 5 — EVIDENCE GUARD(证据结构门控)
**职责**:**规则/结构**校验——引用是否指向真实 tool_call、有无虚构来源等。通常不再调大模型。
**样本**:
```text
EVIDENCE_GUARD_INITIAL = PASSED
violation_count = 0
referenced_tool_call_ids = [call_00_91fK...]
verified_analysis_count = 3
verified_source_count = 4
```
| 字段 | 含义 |
|------|------|
| `violation_count` | 违规条数 |
| `violations` | 违规明细 |
| `referenced_tool_call_ids` | 报告点名的工具调用 |
| `verified_analysis_count` | 通过核验的分析条数 |
| `verified_source_count` | 通过核验的来源数 |
| `invalid_tool_reference_count` | 非法工具引用数 |
```mermaid
flowchart LR
DRAFT[报告草稿] --> EG[Evidence Guard]
TI[真实 tool_call 账本] --> EG
EG -->|PASSED| SG[Semantic Guard]
EG -->|FAIL| FB[修复 / FALLBACK]
```
---
### 阶段 6 — SEMANTIC GUARD(语义门控)
**职责**:再用 **1 次模型**判断「结论是否被证据支撑」,抑制夸大与臆测根因。
**样本 tokens**:in 4141 / out 829 / total **4970**(整次 run 最大单段)
**产出**:`SEMANTIC_GUARD_DECISION`,`verdict=SUPPORTED`
| verdict 倾向 | 后果 |
|--------------|------|
| `SUPPORTED` | 可走向 SUCCESS 发布 |
| 不支持 / 证据不足 | FALLBACK 或安全改写 |
SSE:`status: SAFETY_VALIDATING`。
```mermaid
flowchart TB
DRAFT[草稿] --> SG[Semantic Guard LLM]
EV[证据摘要 / 引用] --> SG
SG --> V{verdict}
V -->|SUPPORTED| OK[可 RELEASE SUCCESS]
V -->|其它| NO[FALLBACK / 再约束]
SG --> TOK[MODEL_TOKEN_USAGE 入账]
```
> 成本观察:本样本中 Semantic Guard ≈ 总 token 的 37%。是否压缩留给后续评估。
---
### 阶段 7 — RELEASE(发布)
**职责**:终态裁决 + 选择对外 content 形态。
**样本**:
- `RELEASE_DECISION` → `release_outcome=SUCCESS`
- SSE `content_type=DIAGNOSIS_REPORT`
- SSE `done.outcome=SUCCESS`
#### 7.1 成功报告结构
```mermaid
flowchart TB
CT[content_type = DIAGNOSIS_REPORT] --> P[payload]
P --> R[report]
P --> REF[references]
R --> C[conclusion]
R --> A[analysis]
R --> AP[action_plan]
R --> RC[recommendations]
R --> L[limitations]
C --> CTXT[text]
C --> IDS[based_on_analysis_ids]
L --> SC[scope]
L --> MI[missing_info]
```
| 字段 | 含义 | 样本要点 |
|------|------|----------|
| `content_type` | 对外内容类型 | `DIAGNOSIS_REPORT`(对比 `SAFE_FALLBACK`) |
| `conclusion.text` | 结论文本 | 有 runbook、无 live 数据不能定根因 |
| `conclusion.based_on_analysis_ids` | 结论依据哪些分析 | A-001..003 |
| `analysis[]` | 分条事实/推理 | 3 条 NORMAL |
| `action_plan` / `recommendations` | 动作与建议 | 约束为空 `[]` |
| `limitations.scope` | 证据范围声明 | 仅 lookup_knowledge + 源名 |
| `limitations.missing_info` | 缺口 | 未查生产指标/日志 |
| `references[]` | 溯源列表 | 全为 `source_type=RAG` |
| `references[].source` | 源标识 | docId / upload id |
| `references[].scope` | 查询范围描述 | 本次 query 摘要 |
| `outcome` | 发布结局 | `SUCCESS` |
#### 7.2 SUCCESS vs FALLBACK(概念)
```mermaid
flowchart LR
DRAFT[草稿] --> GATES{Evidence + Semantic}
GATES -->|通过| S[SUCCESS
DIAGNOSIS_REPORT]
GATES -->|证据不足/不支持| F[FALLBACK
SAFE_FALLBACK]
F --> IE[常见 type:
INSUFFICIENT_EVIDENCE]
```
---
### 阶段 8 — 收尾、Token 对账与 Trace 回放
**职责**:汇总预算与 usage;固化 run;供 Trace API。
**样本 `RUN_FINISHED`**:
```text
model_call_count = 4
run_input_tokens = 10598
run_output_tokens = 2638
run_total_tokens = 13236
tokens_reconciled = true
usage_unavailable_count = 0
duration ≈ 25264 ms
```
#### 8.1 Token 分解
```mermaid
pie title 样本 run 总 Token 13236
"INTENT_ROUTER 906" : 906
"AGENT r1 2657" : 2657
"AGENT r2 4703" : 4703
"SEMANTIC_GUARD 4970" : 4970
```
| 调用 | component | in | out | total | 角色 |
|------|-----------|----|-----|-------|------|
| 1 | INTENT_ROUTER | 323 | 583 | 906 | 路由 |
| 2 | DIAGNOSIS_AGENT r1 | 2554 | 103 | 2657 | 规划 + tool_call |
| 3 | DIAGNOSIS_AGENT r2 | 3580 | 1123 | 4703 | 写报告 |
| 4 | SEMANTIC_GUARD | 4141 | 829 | 4970 | 语义放行 |
| **Σ** | | **10598** | **2638** | **13236** | |
**对账关系**:
```text
sum(MODEL_TOKEN_USAGE.total_tokens) = 13236
= diagnosis_run.total_token_count
= RUN_FINISHED.run_total_tokens
= audited_total_tokens
tokens_reconciled = true
```
**易混点**:
| 指标 | 含什么 | 样本 |
|------|--------|------|
| `agent_step.tokenCount` 之和 | 仅诊断 Agent 两轮 | 2657+4703=**7360** |
| `run.total_token_count` | Router+Agent+Guard 全部 | **13236** |
#### 8.2 耗时粗拆
```mermaid
gantt
title 样本墙钟粗拆(示意,非精确并行)
dateFormat X
axisFormat %s
section 路由
Intent Router :0, 2
section Agent/Tool
Agent r1 :2, 4
lookup_knowledge hybrid :4, 5
Agent r2 写报告 :5, 14
section 门控发布
Evidence + Semantic :14, 22
Release + 落库 :22, 25
```
RAG 热路径工具段约 **1.2s**;主体时间在 **LLM(尤其 r2 与 Semantic Guard)**。
---
## 6. 数据落库与 Trace 结构
### 6.1 表关系
```mermaid
erDiagram
CHAT_SESSION ||--o{ DIAGNOSIS_RUN : contains
DIAGNOSIS_RUN ||--o{ AGENT_STEP : has
DIAGNOSIS_RUN ||--o{ TOOL_INVOCATION : has
DIAGNOSIS_RUN ||--o{ DIAGNOSIS_TRACE_EVENT : timeline
DIAGNOSIS_RUN ||--o{ AGENT_REASONING_AUDIT : optional
AGENT_STEP ||--o| TOOL_INVOCATION : "step_id 已由 AgentStepAuditTracker 绑定"
DIAGNOSIS_RUN {
string run_id PK
string session_id
string status
string intent
string release_outcome
int total_duration_ms
int total_token_count
int step_count
int tool_call_count
text query
longtext answer
}
AGENT_STEP {
long id PK
string run_id
int step_index
string agent_name
int token_count
int duration_ms
json model_input
json model_output
}
TOOL_INVOCATION {
long id PK
string run_id
long step_id
string tool_name
json input_params
json retrieval_details
string relevance_level
int duration_ms
boolean success
}
DIAGNOSIS_TRACE_EVENT {
long id PK
string run_id
int sequence_no
string phase
string event_type
string status
json details
}
```
### 6.2 Trace API 响应骨架
```mermaid
flowchart TB
TR[DiagnosisTraceResponse] --> RUN[run]
TR --> STEPS[steps]
TR --> TOOLS[toolInvocations]
TR --> TL[timeline]
TR --> SUM[summary]
RUN --> R1[status / intent / tokens / answer]
STEPS --> S1[每轮 Agent 摘要]
TOOLS --> T1[RAG 富字段]
TL --> E1[15 条有序事件]
SUM --> C1[persisted vs returned 计数]
```
样本 `summary`:
| 计数 | persisted | returned |
|------|-----------|----------|
| steps | 2 | 2 |
| tools | 1 | 1 |
| timeline events | 15 | 15 |
### 6.3 样本 timeline 全表(15 事件)
| seq | phase | event_type | 要点 |
|-----|-------|------------|------|
| 1 | RUN | RUN_STARTED | 开跑 |
| 2 | ROUTING | MODEL_TOKEN_USAGE | Router 906 |
| 3 | ROUTING | ROUTING_ATTEMPT | |
| 4 | ROUTING | ROUTING_DECISION | intent=DIAGNOSIS |
| 5 | AGENT | MODEL_TOKEN_USAGE | Agent r1 2657 |
| 6 | AGENT | AGENT_MODEL_STEP | step0 tool_call |
| 7 | TOOL | TOOL_INVOCATION | lookup READY / EVIDENCE_FOUND |
| 8 | AGENT | MODEL_TOKEN_USAGE | Agent r2 4703 |
| 9 | AGENT | AGENT_MODEL_STEP | step1 写报告 |
| 10 | EVIDENCE | EVIDENCE_GUARD_INITIAL | PASSED |
| 11 | SEMANTIC | MODEL_TOKEN_USAGE | Guard 4970 |
| 12 | SEMANTIC | SEMANTIC_GUARD_ATTEMPT | |
| 13 | SEMANTIC | SEMANTIC_GUARD_DECISION | SUPPORTED |
| 14 | RELEASE | RELEASE_DECISION | SUCCESS |
| 15 | RUN | RUN_FINISHED | 13236 reconciled |
```mermaid
flowchart TB
E1[1 RUN_STARTED] --> E2[2-4 ROUTING]
E2 --> E3[5-6 AGENT r1]
E3 --> E4[7 TOOL RAG]
E4 --> E5[8-9 AGENT r2]
E5 --> E6[10 EVIDENCE PASSED]
E6 --> E7[11-13 SEMANTIC SUPPORTED]
E7 --> E8[14 RELEASE SUCCESS]
E8 --> E9[15 RUN_FINISHED]
```
---
## 7. 「边界」图:Agent 可见 vs 审计可见
这是理解 RAG 与 Trace 的关键。
```mermaid
flowchart TB
subgraph internal["工具内部(完整)"]
LR[LookupResult
retrievalTrace / attempts / blocks 全文]
end
subgraph agent_view["Agent 可见(投影后)"]
RT[RagToolResult
evidence 块 + 可选 relevance_level
无完整 internal trace]
end
subgraph audit_view["审计 / Trace 可见"]
TI[tool_invocation.retrieval_details
rag_lookup_v1 富字段]
EV[timeline TOOL_INVOCATION 摘要]
end
LK[LookupKnowledgeTool] --> LR
LR --> PROJ[RagResultProjector]
PROJ --> RT
LR --> ENR[RagLookupAuditEnricher]
ENR --> TI
ENR --> EV
RT --> AGENT[Diagnosis Agent r2]
TI --> API[Trace API]
```
| 视角 | 目的 | 不该指望它 |
|------|------|------------|
| Agent 投影 | 控制上下文体积、稳定契约 | 完整排障 trace |
| tool_invocation | 复盘检索质量与模式 | 替代评测集 |
| timeline | 阶段时序与 token | 存证据全文 |
---
## 8. 责任总表(一张表串起来)
| 阶段 | 组件 | 发送什么 | 产出什么 | 明确不负责 |
|------|------|----------|----------|------------|
| 0 接入 | ChatController | SSE 壳 | session/run | 诊断内容 |
| 1 路由 | Intent Router | 1×LLM | `intent` | 检索/结论 |
| 2 规划 | Diagnosis Agent r1 | 1×LLM | tool_call | 最终报告 |
| 3 检索 | lookup_knowledge | Embed+Milvus | 证据+audit | 写结论 |
| 4 撰写 | Diagnosis Agent r2 | 1×LLM | 报告草稿 | 放行裁决 |
| 5 证据门 | Evidence Guard | 规则 | PASS/违规 | 语义是否夸大 |
| 6 语义门 | Semantic Guard | 1×LLM | SUPPORTED 等 | 再检索 |
| 7 发布 | Release | — | SUCCESS/FALLBACK 内容 | — |
| 8 审计 | DB + Trace | — | 可回放账本 | — |
---
## 9. 本样本结论与剩余缺口
### 9.1 本 SUCCESS run 已对齐
| 能力 | 状态 | 证据 |
|------|------|------|
| hybrid RAG 命中 | 通过 | `search_mode=hybrid`,PRECISE,EVIDENCE_FOUND |
| 单次 lookup 约束 | 通过 | `tool_call_count=1` |
| 门控放行 | 通过 | Evidence PASSED → Semantic SUPPORTED → SUCCESS |
| Token 对账 | 通过 | 13236,`tokens_reconciled=true` |
| Trace 闭环 | 通过 | 2 steps / 1 tool / 15 events,persisted=returned |
| SUCCESS 报告 | 通过 | `DIAGNOSIS_REPORT`,action/rec 为空,refs=RAG |
| 现行审计能力 | 已合入代码 | 见 §3.4.1;专项 live 数字见 [审计补丁 E2E](RAG审计补丁-stepid-query-E2E验收.md) |
### 9.2 仍未关闭的缺口
| # | 问题 | 含义 | 优先级 |
|---|------|------|--------|
| 1 | 检索 top 混入弱相关源(如 payment-service-latency) | hybrid 生效但纯度一般;报告可克制,sources 仍可能挂噪声 | 后续过滤/重排 |
| 2 | Semantic Guard 约占 5k tokens | 正确但贵 | 后评估是否可降 |
| 3 | 偶发 hybrid 空结果 → FALLBACK | 环境/Milvus 抖动 | 见 [审计验收页 §4](RAG审计补丁-stepid-query-E2E验收.md#4-业务-fallback-原因与审计无关) |
缺口 1 示意:
```mermaid
flowchart TB
Q[Query: HikariCP pool] --> H[Hybrid top]
H --> G1[连接池 runbook 强相关]
H --> N1[支付延迟等弱相关]
G1 --> REPORT[SUCCESS 报告正文]
N1 --> REF[references 可能仍出现]
```
---
## 10. 如何自己复盘下一次 run
```mermaid
flowchart LR
A[拿 session_id + run_id] --> B[拉 Trace API]
B --> C[看 timeline 阶段是否闭环]
C --> D[看 toolInvocations.retrieval_details]
D --> E[核对 search_mode / relevance / attempts]
E --> F[加总 MODEL_TOKEN_USAGE]
F --> G[对比 run.total_token_count]
G --> H[读 answer 与 references]
H --> I[对照 logs/application.log]
```
**建议核对清单**:
1. `release_outcome` 与 SSE `done.outcome` 一致
2. `tool_call_count` 与真实工具次数一致
3. RAG:`search_mode`、`selected_attempt`、`evidence_status`
4. Token:`tokens_reconciled=true` 且分项和 = 总额
5. 门控:Evidence 与 Semantic 事件状态
6. 报告:`limitations` 是否覆盖未观测范围
7. **审计**:`tool_invocation.step_id` 非空且等于对应 `agent_step.id`
8. **审计**:`input_params` 含 `query`(或其它安全标量)与 `tool_call_id`
**日志关键字**:
```text
lookup_knowledge
Hybrid dense+BM25 search
relevanceLevel=
MODEL_TOKEN_USAGE (在 Trace,不在普通业务日志全文)
```
**MySQL 入口**(只读脚本):
```bash
python scripts/query_mysql.py "SELECT run_id, status, release_outcome, total_token_count, total_duration_ms, step_count, tool_call_count FROM diagnosis_run WHERE run_id = ''"
python scripts/query_mysql.py "SELECT id, step_id, tool_name, relevance_level, CAST(input_params AS CHAR) AS inputp, LEFT(CAST(retrieval_details AS CHAR), 400) AS details FROM tool_invocation WHERE run_id = '' ORDER BY id"
python scripts/query_mysql.py "SELECT id, step_index, agent_name, has_tool_call, token_count FROM agent_step WHERE run_id = '' ORDER BY step_index, id"
```
---
## 11. 一页故事版
1. 用户用 Chat 提「只用知识库、只调一次 lookup」的诊断题。
2. **Router**(~0.9k tokens)判成 `DIAGNOSIS`。
3. **Agent 第 1 轮**(~2.7k tokens)决定调用 `lookup_knowledge`;落 `agent_step` 并 bind `step_id`。
4. **Hybrid RAG**(~1.2s)命中 PRECISE;`tool_invocation` 写 `step_id` + `query`,进 Trace。
5. **Agent 第 2 轮**(~4.7k tokens)只依据证据写报告。
6. **Evidence Guard** 校验引用。
7. **Semantic Guard**(~5.0k tokens)判 `SUPPORTED`。
8. **Release** → `DIAGNOSIS_REPORT` + `SUCCESS`;**13236 tokens / ~25s**,15 步 timeline;run 结束 clear 绑定。
---
## 12. 修订记录
| 日期 | 说明 |
|------|------|
| 2026-07-28 | 初版:SUCCESS 全流程、字段词典与多图 |
| 2026-07-28 | 审计补丁代码与 §3.4.1 能力说明 |
| 2026-07-28 | 文档迁入 `docs/`;INDEX 挂接 |
| 2026-07-28 | **拆分**:FALLBACK 审计验收样本迁至 [RAG审计补丁-stepid-query-E2E验收.md](RAG审计补丁-stepid-query-E2E验收.md);本文只保留 SUCCESS 主线 |