feat(rag): close eval pipeline with live snapshots

This commit is contained in:
zhuyongxin
2026-07-06 21:39:27 +08:00
parent cf3333d607
commit ed7efc58b7
47 changed files with 2613 additions and 177 deletions
@@ -1,25 +1,81 @@
{
"caseId": "aiops-payment-latency-alert",
"query": "Alert HighLatency on payment-service with p95 latency above threshold",
"retrievedAt": "2026-07-05T00:00:00Z",
"candidates": [
{
"rank": 1,
"docId": "payment-service-latency",
"title": "Payment Service Latency Alert Playbook",
"breadcrumb": "AIOps > Service Alerts > Payment Latency",
"content": "For payment-service p95 latency alerts, check downstream dependency latency, thread pool saturation, gateway retries, and recent deployment changes.",
"score": 0.84,
"retrievalLayer": "L1"
"retrievedAt": "2026-07-06T00:00:00Z",
"lookupResult": {
"found": true,
"evidenceBlocks": [
{
"source": "payment-service-latency",
"title": "Payment Service Latency Alert Playbook",
"breadcrumb": "AIOps > Service Alerts > Payment Latency",
"retrievalLayer": "L1",
"content": "For payment-service p95 latency alerts, check downstream dependency latency, thread pool saturation, gateway retries, and recent deployment changes.",
"score": 0.84,
"hitReasons": ["domain_match:+0.15", "entity_match:+0.20", "keyword_match:+0.10"]
},
{
"source": "mysql-connection-pool",
"title": "MySQL Connection Pool Troubleshooting",
"breadcrumb": "Database > MySQL > Connection Pool",
"retrievalLayer": "L1",
"content": "Database connection pool saturation can increase payment latency when checkout paths wait for connections.",
"score": 0.68,
"hitReasons": ["keyword_match:+0.10"]
}
],
"contextPack": {
"packedText": "[1] Payment Service Latency Alert Playbook\nAIOps > Service Alerts > Payment Latency\nFor payment-service p95 latency alerts, check downstream dependency latency, thread pool saturation, gateway retries, and recent deployment changes.",
"strategy": "top_evidence_blocks",
"charBudget": 3500,
"usedChars": 236,
"includedSources": ["payment-service-latency", "mysql-connection-pool"],
"omittedSources": []
},
{
"rank": 2,
"docId": "mysql-connection-pool",
"title": "MySQL Connection Pool Troubleshooting",
"breadcrumb": "Database > MySQL > Connection Pool",
"content": "Database connection pool saturation can increase payment latency when checkout paths wait for connections.",
"score": 0.68,
"retrievalLayer": "L1"
"retrievalTrace": {
"originalQuery": "Alert HighLatency on payment-service with p95 latency above threshold",
"rewrittenQuery": "HighLatency payment-service p95 latency alert downstream dependency diagnosis",
"categoryFilter": "AIOps",
"selectedAttempt": "FILTERED_VECTOR",
"fallbackReason": null,
"evidenceStatus": "supported",
"queryHints": {
"domains": ["AIOps"],
"matched_keywords": ["p95 latency", "payment-service", "downstream dependency"],
"entities": ["payment-service", "HighLatency"],
"l0_titles": ["Payment Service Latency Alert Playbook"],
"l0_match_count": 1
},
"attempts": [
{
"name": "FILTERED_VECTOR",
"query": "HighLatency payment-service p95 latency alert downstream dependency diagnosis",
"categoryFilter": "AIOps",
"candidateCount": 2,
"usable": true,
"durationMs": 11,
"topScore": 0.84,
"topSimilarity": 0.84
}
]
},
"rerankTrace": {
"items": [
{
"finalRank": 1,
"source": "payment-service-latency",
"baseScore": 0.84,
"finalScore": 1.29,
"boostReasons": ["domain_match:+0.15", "entity_match:+0.20", "keyword_match:+0.10"]
},
{
"finalRank": 2,
"source": "mysql-connection-pool",
"baseScore": 0.68,
"finalScore": 0.78,
"boostReasons": ["keyword_match:+0.10"]
}
]
}
]
}
}
@@ -1,16 +1,65 @@
{
"caseId": "aiops-prometheus-alert-scope",
"query": "When an AIOps request already includes alert payload, should the agent diagnose unrelated active alerts?",
"retrievedAt": "2026-07-05T00:00:00Z",
"candidates": [
{
"rank": 1,
"docId": "aiops-alert-scope-control",
"title": "AIOps Alert Scope Control",
"breadcrumb": "AIOps > Alert Scope Control",
"content": "When payload mode is active, queryPrometheusAlerts can verify the supplied alert, but unrelated active alerts must remain scoped context and should not become full diagnoses.",
"score": 0.9,
"retrievalLayer": "L0+L1"
"retrievedAt": "2026-07-06T00:00:00Z",
"lookupResult": {
"found": true,
"evidenceBlocks": [
{
"source": "aiops-alert-scope-control",
"title": "AIOps Alert Scope Control",
"breadcrumb": "AIOps > Alert Scope Control",
"retrievalLayer": "L1",
"content": "When payload mode is used, diagnose the input alert payload and do not expand unrelated active alerts into the main diagnosis scope.",
"score": 0.88,
"hitReasons": ["domain_match:+0.15", "keyword_match:+0.10"]
}
],
"contextPack": {
"packedText": "[1] AIOps Alert Scope Control\nAIOps > Alert Scope Control\nWhen payload mode is used, diagnose the input alert payload and do not expand unrelated active alerts into the main diagnosis scope.",
"strategy": "top_evidence_blocks",
"charBudget": 3500,
"usedChars": 188,
"includedSources": ["aiops-alert-scope-control"],
"omittedSources": []
},
"retrievalTrace": {
"originalQuery": "When an AIOps request already includes alert payload, should the agent diagnose unrelated active alerts?",
"rewrittenQuery": "AIOps alert payload scope unrelated active alerts diagnosis",
"categoryFilter": "AIOps",
"selectedAttempt": "FILTERED_VECTOR",
"fallbackReason": null,
"evidenceStatus": "supported",
"queryHints": {
"domains": ["AIOps"],
"matched_keywords": ["payload", "unrelated active alerts", "scope"],
"entities": ["alert payload"],
"l0_titles": ["AIOps Alert Scope Control"],
"l0_match_count": 1
},
"attempts": [
{
"name": "FILTERED_VECTOR",
"query": "AIOps alert payload scope unrelated active alerts diagnosis",
"categoryFilter": "AIOps",
"candidateCount": 1,
"usable": true,
"durationMs": 8,
"topScore": 0.88,
"topSimilarity": 0.88
}
]
},
"rerankTrace": {
"items": [
{
"finalRank": 1,
"source": "aiops-alert-scope-control",
"baseScore": 0.88,
"finalScore": 1.13,
"boostReasons": ["domain_match:+0.15", "keyword_match:+0.10"]
}
]
}
]
}
}
@@ -1,25 +1,81 @@
{
"caseId": "chat-diagnosis-flow",
"query": "What is the standard troubleshooting flow for an application incident?",
"retrievedAt": "2026-07-05T00:00:00Z",
"candidates": [
{
"rank": 1,
"docId": "incident-diagnosis-flow",
"title": "Incident Diagnosis Flow",
"breadcrumb": "AIOps > Diagnosis Flow",
"content": "The standard flow is to collect evidence, identify the suspected fault domain, verify the hypothesis, apply remediation, and confirm recovery.",
"score": 0.82,
"retrievalLayer": "L1"
"retrievedAt": "2026-07-06T00:00:00Z",
"lookupResult": {
"found": true,
"evidenceBlocks": [
{
"source": "incident-diagnosis-flow",
"title": "Incident Diagnosis Flow",
"breadcrumb": "AIOps > Diagnosis Flow",
"retrievalLayer": "L1",
"content": "The standard flow is to collect evidence, identify the suspected fault domain, verify the hypothesis, apply remediation, and confirm recovery.",
"score": 0.82,
"hitReasons": ["domain_match:+0.15", "keyword_match:+0.10"]
},
{
"source": "rag-chunk-context-reconstruction",
"title": "RAG Chunk Context Reconstruction",
"breadcrumb": "RAG > Chunking > Context Reconstruction",
"retrievalLayer": "L1",
"content": "Long sections may require neighbor chunk expansion and breadcrumb-aware packing.",
"score": 0.55,
"hitReasons": []
}
],
"contextPack": {
"packedText": "[1] Incident Diagnosis Flow\nAIOps > Diagnosis Flow\nThe standard flow is to collect evidence, identify the suspected fault domain, verify the hypothesis, apply remediation, and confirm recovery.",
"strategy": "top_evidence_blocks",
"charBudget": 3500,
"usedChars": 192,
"includedSources": ["incident-diagnosis-flow", "rag-chunk-context-reconstruction"],
"omittedSources": []
},
{
"rank": 2,
"docId": "rag-chunk-context-reconstruction",
"title": "RAG Chunk Context Reconstruction",
"breadcrumb": "RAG > Chunking > Context Reconstruction",
"content": "Long sections may require neighbor chunk expansion and breadcrumb-aware packing.",
"score": 0.55,
"retrievalLayer": "L1"
"retrievalTrace": {
"originalQuery": "What is the standard troubleshooting flow for an application incident?",
"rewrittenQuery": "standard application incident troubleshooting flow collect evidence verify remediation",
"categoryFilter": "AIOps",
"selectedAttempt": "FILTERED_VECTOR",
"fallbackReason": null,
"evidenceStatus": "supported",
"queryHints": {
"domains": ["AIOps"],
"matched_keywords": ["collect evidence", "verify", "remediation"],
"entities": ["application incident"],
"l0_titles": ["Incident Diagnosis Flow"],
"l0_match_count": 1
},
"attempts": [
{
"name": "FILTERED_VECTOR",
"query": "standard application incident troubleshooting flow collect evidence verify remediation",
"categoryFilter": "AIOps",
"candidateCount": 2,
"usable": true,
"durationMs": 10,
"topScore": 0.82,
"topSimilarity": 0.82
}
]
},
"rerankTrace": {
"items": [
{
"finalRank": 1,
"source": "incident-diagnosis-flow",
"baseScore": 0.82,
"finalScore": 1.07,
"boostReasons": ["domain_match:+0.15", "keyword_match:+0.10"]
},
{
"finalRank": 2,
"source": "rag-chunk-context-reconstruction",
"baseScore": 0.55,
"finalScore": 0.55,
"boostReasons": []
}
]
}
]
}
}
@@ -1,25 +1,81 @@
{
"caseId": "chat-l0-domain-hint",
"query": "Should L0 keyword matching decide the final retrieval result?",
"retrievedAt": "2026-07-05T00:00:00Z",
"candidates": [
{
"rank": 1,
"docId": "rag-l0-domain-entity-hint",
"title": "RAG L0 Domain Entity Hint",
"breadcrumb": "RAG > L0 > Domain Entity Hint",
"content": "L0 should be retained as a domain detector, entity extractor, metadata filter generator, and explainability signal, not as the final retrieval decision.",
"score": 0.88,
"retrievalLayer": "L0"
"retrievedAt": "2026-07-06T00:00:00Z",
"lookupResult": {
"found": true,
"evidenceBlocks": [
{
"source": "rag-l0-domain-entity-hint",
"title": "RAG L0 Domain Entity Hint",
"breadcrumb": "RAG > L0 > Domain Entity Hint",
"retrievalLayer": "L1",
"content": "L0 should be retained as a domain detector, entity extractor, metadata filter generator, and explainability signal, not as the final retrieval decision.",
"score": 0.88,
"hitReasons": ["domain_match:+0.15", "keyword_match:+0.10"]
},
{
"source": "rag-l0-l1-fusion-ranking",
"title": "RAG L0 L1 Fusion Ranking",
"breadcrumb": "RAG > Ranking > Fusion",
"retrievalLayer": "L1",
"content": "L0 and L1 candidates should eventually be fused rather than handled as an early-return branch.",
"score": 0.75,
"hitReasons": ["domain_match:+0.15"]
}
],
"contextPack": {
"packedText": "[1] RAG L0 Domain Entity Hint\nRAG > L0 > Domain Entity Hint\nL0 should be retained as a domain detector, entity extractor, metadata filter generator, and explainability signal, not as the final retrieval decision.",
"strategy": "top_evidence_blocks",
"charBudget": 3500,
"usedChars": 219,
"includedSources": ["rag-l0-domain-entity-hint", "rag-l0-l1-fusion-ranking"],
"omittedSources": []
},
{
"rank": 2,
"docId": "rag-l0-l1-fusion-ranking",
"title": "RAG L0 L1 Fusion Ranking",
"breadcrumb": "RAG > Ranking > Fusion",
"content": "L0 and L1 candidates should eventually be fused rather than handled as an early-return branch.",
"score": 0.75,
"retrievalLayer": "L1"
"retrievalTrace": {
"originalQuery": "Should L0 keyword matching decide the final retrieval result?",
"rewrittenQuery": "RAG L0 keyword matching domain entity hint final retrieval decision",
"categoryFilter": "RAG",
"selectedAttempt": "FILTERED_VECTOR",
"fallbackReason": null,
"evidenceStatus": "supported",
"queryHints": {
"domains": ["RAG"],
"matched_keywords": ["domain detector", "entity extractor", "metadata filter"],
"entities": ["L0"],
"l0_titles": ["RAG L0 Domain Entity Hint"],
"l0_match_count": 1
},
"attempts": [
{
"name": "FILTERED_VECTOR",
"query": "RAG L0 keyword matching domain entity hint final retrieval decision",
"categoryFilter": "RAG",
"candidateCount": 2,
"usable": true,
"durationMs": 9,
"topScore": 0.88,
"topSimilarity": 0.88
}
]
},
"rerankTrace": {
"items": [
{
"finalRank": 1,
"source": "rag-l0-domain-entity-hint",
"baseScore": 0.88,
"finalScore": 1.13,
"boostReasons": ["domain_match:+0.15", "keyword_match:+0.10"]
},
{
"finalRank": 2,
"source": "rag-l0-l1-fusion-ranking",
"baseScore": 0.75,
"finalScore": 0.9,
"boostReasons": ["domain_match:+0.15"]
}
]
}
]
}
}
@@ -0,0 +1,91 @@
{
"caseId": "chat-l0-filter-fallback",
"query": "RAG query was over-filtered by L0 and filtered vector search returned low quality evidence. What should happen?",
"retrievedAt": "2026-07-06T00:00:00Z",
"lookupResult": {
"found": true,
"evidenceBlocks": [
{
"source": "rag-l0-filter-fallback",
"title": "RAG L0 Filter Fallback",
"breadcrumb": "RAG > Fallback > Unfiltered Retry",
"retrievalLayer": "L1",
"content": "When filtered vector retrieval is low quality, skip the L0 filter and run an unfiltered vector retry with the raw query before returning no evidence.",
"score": 0.83,
"hitReasons": ["domain_match:+0.15", "keyword_match:+0.10"]
},
{
"source": "rag-l0-domain-entity-hint",
"title": "RAG L0 Domain Entity Hint",
"breadcrumb": "RAG > L0 > Domain Entity Hint",
"retrievalLayer": "L1",
"content": "L0 supplies hints for metadata filtering and explanation, but it should not be treated as final fact evidence.",
"score": 0.66,
"hitReasons": ["domain_match:+0.15"]
}
],
"contextPack": {
"packedText": "[1] RAG L0 Filter Fallback\nRAG > Fallback > Unfiltered Retry\nWhen filtered vector retrieval is low quality, skip the L0 filter and run an unfiltered vector retry with the raw query before returning no evidence.",
"strategy": "top_evidence_blocks",
"charBudget": 3500,
"usedChars": 214,
"includedSources": ["rag-l0-filter-fallback", "rag-l0-domain-entity-hint"],
"omittedSources": []
},
"retrievalTrace": {
"originalQuery": "RAG query was over-filtered by L0 and filtered vector search returned low quality evidence. What should happen?",
"rewrittenQuery": "RAG L0 filtered vector low quality fallback unfiltered retry",
"categoryFilter": "RAG",
"selectedAttempt": "UNFILTERED_VECTOR_RETRY",
"fallbackReason": "filtered_vector_low_quality",
"evidenceStatus": "supported",
"queryHints": {
"domains": ["RAG"],
"matched_keywords": ["L0", "low quality", "unfiltered vector retry"],
"entities": ["L0"],
"l0_titles": ["RAG L0 Domain Entity Hint"],
"l0_match_count": 1
},
"attempts": [
{
"name": "FILTERED_VECTOR",
"query": "RAG L0 filtered vector low quality fallback unfiltered retry",
"categoryFilter": "RAG",
"candidateCount": 1,
"usable": false,
"durationMs": 7,
"topScore": 1.35,
"topSimilarity": 0.325
},
{
"name": "UNFILTERED_VECTOR_RETRY",
"query": "RAG query was over-filtered by L0 and filtered vector search returned low quality evidence. What should happen?",
"categoryFilter": null,
"candidateCount": 2,
"usable": true,
"durationMs": 13,
"topScore": 0.83,
"topSimilarity": 0.83
}
]
},
"rerankTrace": {
"items": [
{
"finalRank": 1,
"source": "rag-l0-filter-fallback",
"baseScore": 0.83,
"finalScore": 1.08,
"boostReasons": ["domain_match:+0.15", "keyword_match:+0.10"]
},
{
"finalRank": 2,
"source": "rag-l0-domain-entity-hint",
"baseScore": 0.66,
"finalScore": 0.81,
"boostReasons": ["domain_match:+0.15"]
}
]
}
}
}
@@ -1,25 +1,81 @@
{
"caseId": "chat-mysql-connection-pool",
"query": "MySQL connection pool is exhausted. How should I diagnose it?",
"retrievedAt": "2026-07-05T00:00:00Z",
"candidates": [
{
"rank": 1,
"docId": "mysql-connection-pool",
"title": "MySQL Connection Pool Troubleshooting",
"breadcrumb": "Database > MySQL > Connection Pool",
"content": "When the connection pool is exhausted, inspect HikariCP active connections, max_connections, slow SQL, leak detection, and database wait events.",
"score": 0.86,
"retrievalLayer": "L0+L1"
"retrievedAt": "2026-07-06T00:00:00Z",
"lookupResult": {
"found": true,
"evidenceBlocks": [
{
"source": "mysql-connection-pool",
"title": "MySQL Connection Pool Troubleshooting",
"breadcrumb": "Database > MySQL > Connection Pool",
"retrievalLayer": "L1",
"content": "When the connection pool is exhausted, inspect HikariCP active connections, max_connections, slow SQL, leak detection, and database wait events.",
"score": 0.86,
"hitReasons": ["domain_match:+0.15", "keyword_match:+0.10"]
},
{
"source": "incident-diagnosis-flow",
"title": "Incident Diagnosis Flow",
"breadcrumb": "AIOps > Diagnosis Flow",
"retrievalLayer": "L1",
"content": "Collect evidence, compare metrics and logs, then verify remediation before closing the incident.",
"score": 0.61,
"hitReasons": []
}
],
"contextPack": {
"packedText": "[1] MySQL Connection Pool Troubleshooting\nDatabase > MySQL > Connection Pool\nWhen the connection pool is exhausted, inspect HikariCP active connections, max_connections, slow SQL, leak detection, and database wait events.",
"strategy": "top_evidence_blocks",
"charBudget": 3500,
"usedChars": 216,
"includedSources": ["mysql-connection-pool", "incident-diagnosis-flow"],
"omittedSources": []
},
{
"rank": 2,
"docId": "incident-diagnosis-flow",
"title": "Incident Diagnosis Flow",
"breadcrumb": "AIOps > Diagnosis Flow",
"content": "Collect evidence, compare metrics and logs, then verify remediation before closing the incident.",
"score": 0.61,
"retrievalLayer": "L1"
"retrievalTrace": {
"originalQuery": "MySQL connection pool is exhausted. How should I diagnose it?",
"rewrittenQuery": "MySQL connection pool exhausted HikariCP max_connections diagnosis",
"categoryFilter": "Database",
"selectedAttempt": "FILTERED_VECTOR",
"fallbackReason": null,
"evidenceStatus": "supported",
"queryHints": {
"domains": ["Database", "MySQL"],
"matched_keywords": ["connection pool", "HikariCP", "max_connections"],
"entities": ["MySQL", "HikariCP"],
"l0_titles": ["MySQL Connection Pool Troubleshooting"],
"l0_match_count": 1
},
"attempts": [
{
"name": "FILTERED_VECTOR",
"query": "MySQL connection pool exhausted HikariCP max_connections diagnosis",
"categoryFilter": "Database",
"candidateCount": 2,
"usable": true,
"durationMs": 12,
"topScore": 0.86,
"topSimilarity": 0.86
}
]
},
"rerankTrace": {
"items": [
{
"finalRank": 1,
"source": "mysql-connection-pool",
"baseScore": 0.86,
"finalScore": 1.11,
"boostReasons": ["domain_match:+0.15", "keyword_match:+0.10"]
},
{
"finalRank": 2,
"source": "incident-diagnosis-flow",
"baseScore": 0.61,
"finalScore": 0.61,
"boostReasons": []
}
]
}
]
}
}
@@ -1,25 +1,81 @@
{
"caseId": "chat-rag-chunk-context",
"query": "If a long section is split into multiple chunks, how do we keep retrieval context?",
"retrievedAt": "2026-07-05T00:00:00Z",
"candidates": [
{
"rank": 1,
"docId": "rag-chunk-context-reconstruction",
"title": "RAG Chunk Context Reconstruction",
"breadcrumb": "RAG > Chunking > Context Reconstruction",
"content": "After a chunk hit, expand to neighbor chunk candidates from the same section and preserve breadcrumb metadata in the evidence pack.",
"score": 0.79,
"retrievalLayer": "L1"
"retrievedAt": "2026-07-06T00:00:00Z",
"lookupResult": {
"found": true,
"evidenceBlocks": [
{
"source": "rag-chunk-context-reconstruction",
"title": "RAG Chunk Context Reconstruction",
"breadcrumb": "RAG > Chunking > Context Reconstruction",
"retrievalLayer": "L1",
"content": "After a chunk hit, expand to neighbor chunk candidates from the same section and preserve breadcrumb metadata in the evidence pack.",
"score": 0.79,
"hitReasons": ["domain_match:+0.15", "keyword_match:+0.10"]
},
{
"source": "rag-breadcrumb-embedding-gap",
"title": "RAG Breadcrumb Embedding Gap",
"breadcrumb": "RAG > Embedding > Breadcrumb",
"retrievalLayer": "L1",
"content": "Embedding title and breadcrumb with content helps recover section semantics.",
"score": 0.72,
"hitReasons": ["domain_match:+0.15"]
}
],
"contextPack": {
"packedText": "[1] RAG Chunk Context Reconstruction\nRAG > Chunking > Context Reconstruction\nAfter a chunk hit, expand to neighbor chunk candidates from the same section and preserve breadcrumb metadata in the evidence pack.",
"strategy": "top_evidence_blocks",
"charBudget": 3500,
"usedChars": 203,
"includedSources": ["rag-chunk-context-reconstruction", "rag-breadcrumb-embedding-gap"],
"omittedSources": []
},
{
"rank": 2,
"docId": "rag-breadcrumb-embedding-gap",
"title": "RAG Breadcrumb Embedding Gap",
"breadcrumb": "RAG > Embedding > Breadcrumb",
"content": "Embedding title and breadcrumb with content helps recover section semantics.",
"score": 0.72,
"retrievalLayer": "L1"
"retrievalTrace": {
"originalQuery": "If a long section is split into multiple chunks, how do we keep retrieval context?",
"rewrittenQuery": "RAG chunk context reconstruction neighbor chunk same section breadcrumb",
"categoryFilter": "RAG",
"selectedAttempt": "FILTERED_VECTOR",
"fallbackReason": null,
"evidenceStatus": "supported",
"queryHints": {
"domains": ["RAG"],
"matched_keywords": ["neighbor chunk", "same section", "breadcrumb"],
"entities": ["chunk", "breadcrumb"],
"l0_titles": ["RAG Chunk Context Reconstruction"],
"l0_match_count": 1
},
"attempts": [
{
"name": "FILTERED_VECTOR",
"query": "RAG chunk context reconstruction neighbor chunk same section breadcrumb",
"categoryFilter": "RAG",
"candidateCount": 2,
"usable": true,
"durationMs": 9,
"topScore": 0.79,
"topSimilarity": 0.79
}
]
},
"rerankTrace": {
"items": [
{
"finalRank": 1,
"source": "rag-chunk-context-reconstruction",
"baseScore": 0.79,
"finalScore": 1.04,
"boostReasons": ["domain_match:+0.15", "keyword_match:+0.10"]
},
{
"finalRank": 2,
"source": "rag-breadcrumb-embedding-gap",
"baseScore": 0.72,
"finalScore": 0.87,
"boostReasons": ["domain_match:+0.15"]
}
]
}
]
}
}