# 一次诊断到底发生了什么(E2E 全流程导读) **日期**:2026-07-28 **状态**:SUCCESS 完整诊断主文档;工具阶段按**现行**审计能力(`step_id` / `query`)说明 **文档路径**:`mvp/engineering/diagnosis/一次诊断全流程-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/RAG审计补丁-stepid-query-E2E验收.md) **关联文档**: - [RAG Trace / 审计架构\](../../architecture/RAG检索可观测性与审计.md) - [RAG qualityScore 与后处理](../rag/RAG-Hybrid质量分与后处理.md) - [Agent 如何读 relevance_level](../rag/RAG-Agent如何读relevance_level.md) - [知识检索架构\](../../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/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/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/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-29 | 迁入 `mvp/engineering/diagnosis/`,与 RAG 工程纪要集中到 mvp | | 2026-07-28 | **拆分**:FALLBACK 审计验收样本迁至 [RAG审计补丁-stepid-query-E2E验收.md](../rag/RAG审计补丁-stepid-query-E2E验收.md);本文只保留 SUCCESS 主线 |