Files
SuperBizAgent-java/mvp/architecture/archive/2026-07-22-legacy/feedback-architecture.md
T

292 lines
9.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 反馈与自评估架构
**更新日期**:2026-07-10
**状态**:当前可运行架构
**参考历史文档**:`archive/2026-07-05-legacy/confidence-feedback.md`
## 1. 定位
反馈架构包含两条闭环:
1. 系统自评估:基于当前 run 的工具调用、Gatekeeper、Verifier、Composer、AIOps 规则检查,写入 `diagnosis_run.self_evaluation`。
2. 用户反馈:用户标记 `useful` 或 `not_useful`,优先写入 `diagnosis_run.feedback`,其中 `useful` 会沉淀案例。
当前重要边界:
- `status` 表示执行状态,不表示答案质量。
- `feedback` 表示用户反馈,不覆盖 `status`。
- `self_evaluation` 是 JSON 容器,内部按来源分层,不再把所有评分字段平铺在根节点。
## 2. 总体闭环
```mermaid
flowchart TD
Answer["Chat / AIOps final answer"] --> Run["diagnosis_run.answer"]
subgraph SelfEval["Self evaluation"]
Invocation["tool_invocation"] --> RuleEval["EvaluationService: rule_evaluation"]
Invocation --> EvidenceRefs["evidence_refs"]
EvidenceRefs --> Gatekeeper["ExecutorGatekeeperService"]
Invocation --> TraceSummary["ToolTraceSummaryService"]
Gatekeeper --> Verifier["chat_verifier"]
TraceSummary --> Verifier
Verifier --> VerifierEval["verifier_evaluation"]
Verifier --> Composer["chat_composer"]
Composer --> VerifierEval
Invocation --> AiOpsRule["AiOpsRuleEvaluationService"]
AiOpsRule --> AiOpsEval["aiops_rule_evaluation"]
end
RuleEval --> Merge["SelfEvaluationMergeService"]
VerifierEval --> Merge
AiOpsEval --> Merge
Merge --> SelfJson["diagnosis_run.self_evaluation"]
subgraph UserFeedback["User feedback"]
UI["Feedback bar"] --> API["POST /api/feedback"]
API --> FeedbackService["FeedbackService"]
FeedbackService --> FeedbackField["diagnosis_run.feedback"]
FeedbackService --> Useful{"feedback == useful?"}
Useful -->|yes| CaseService["CaseLibraryService.createFromRun"]
CaseService --> Case["case_library"]
Useful -->|no| BadCase["Bad case by feedback=not_useful"]
end
Run --> UI
```
## 3. self_evaluation JSON
`SelfEvaluationMergeService` 统一维护当前运行的 `diagnosis_run.self_evaluation`。历史兼容数据可能仍存在于 `diagnosis_session.self_evaluation`,但新 Chat/AIOps 执行不再写旧表。
当前结构:
```json
{
"rule_evaluation": {
"evidence_score": 65,
"source": "rule",
"factors": []
},
"verifier_evaluation": {
"verdict": "PASS",
"groundedness_score": 0.8,
"critical_fact_count": 2,
"claim_checks": [],
"facts_checked": [],
"rationale": "...",
"round": 1,
"traceability_version": "v1",
"executor_output_parse_status": {},
"executor_structured_output": {},
"gatekeeper_result": {},
"composer_output": {},
"tool_trace_summary": []
},
"aiops_rule_evaluation": {
"verdict": "...",
"checks": []
}
}
```
兼容逻辑:
- 如果旧 JSON 根节点包含 `evidence_score`,会被包进 `rule_evaluation`。
- 如果旧 JSON 根节点包含 `verdict` / `groundedness_score`,会被包进 `verifier_evaluation`。
## 4. 规则评分
`EvaluationService` 只消费 `tool_invocation` 和 session 状态,输出 `rule_evaluation`。
定位:
- 衡量证据收集充分度。
- 不直接证明答案是否推理正确。
- 不依赖 LLM。
规则:
| 规则名 | 条件 | 分数变化 |
|---|---|---|
| `execution_failed` | session status = `FAILED` | 直接 0 |
| `no_tool_call` | 没有工具调用 | 直接 0 |
| `has_successful_tool_call` | 至少一次工具成功 | +30 |
| `l0_exact_match` | 任意工具调用有 L0 命中 | +35 |
| `l1_semantic_match` | 无 L0 命中但有 L1 命中 | +20 |
| `retrieval_no_hit` | 有检索调用但无命中 | -10 |
| `all_tool_calls_failed` | 工具全部失败 | -20 |
最终分数裁剪到 `[0, 100]`。
说明:
- 当前 `rule_evaluation` 是异步写入,失败时 `self_evaluation` 可能暂时为空或缺少该节点。
- L0/L1 分支互斥:有 L0 命中时优先记 L0。
- 更强的答案真实性校验由 Chat Verifier 承担。
## 5. Chat Verifier 自评估
Chat 自评估分三步:
1. Gatekeeper 用代码校验 Executor 的引用是否真实。
2. Verifier 判断已验真的 `evidence_excerpt` 是否能推出 `claim_text`。
3. Composer 只把 Verifier 允许表达的内容写成最终用户答复。
```mermaid
flowchart LR
ExecutorOutput["executor_evidence_v2"] --> Gatekeeper["ExecutorGatekeeperService"]
Invocation["tool_invocation"] --> Summary["ToolTraceSummaryService"]
Invocation --> EvidenceRefs["retrieval_details.evidence_refs"]
EvidenceRefs --> Gatekeeper
Gatekeeper --> GateResult["gatekeeper_result"]
Summary --> Evidence["tool_trace_summary"]
GateResult --> Verifier["chat_verifier"]
ExecutorOutput --> Verifier
Evidence --> Verifier
Verifier --> Output["verifier_output JSON"]
Output --> Composer["chat_composer"]
Composer --> ComposerOutput["composer_output"]
Output --> Merge["SelfEvaluationMergeService.mergeVerifierEvaluation"]
ComposerOutput --> Merge
Merge --> Run["diagnosis_run.self_evaluation.verifier_evaluation"]
```
Verifier 输出:
| 字段 | 说明 |
|---|---|
| `verdict` | `PASS` / `LOW_CONFID` / `REJECT` |
| `groundedness_score` | 关键事实证据支撑度 |
| `critical_fact_count` | 关键事实数量 |
| `claim_checks` | 对 Executor 结构化 claims 的逐条可推导性判断 |
| `facts_checked` | 逐条事实校验 |
| `rationale` | 判定原因 |
| `executor_structured_output` | Executor 输出的结构化 claims 与证据绑定 |
| `gatekeeper_result` | 引用真实性校验结果 |
| `composer_output` | 最终表达的解析状态和摘要 |
| `tool_trace_summary` | 本次校验使用的工具调用导航索引 |
ChatService 根据 verdict 决定:
- `PASS`:把允许表达的 claims 交给 Composer 输出。
- `LOW_CONFID`:必要时构造 `retry_context` 补证据;否则输出低置信提示。
- `REJECT`:降级输出,只保留已确认信息。
边界:
- `executor_final_answer` 只作为 debug/fallback 上下文;结构化输出有效时,Verifier 不得从中抽取额外确认事实。
- `$.no_evidence` 只能表达“当前查询未检索到匹配证据”,不能表达“已排除/确认没有”。
## 6. AIOps 规则自评估
AIOps 当前使用 `AiOpsRuleEvaluationService`,结果写入 `aiops_rule_evaluation`。
检查重点:
- 是否有最终报告。
- payload 模式是否聚焦输入告警。
- 是否调用 `lookup_knowledge`、日志、指标等证据工具。
- 是否把无关活跃告警扩展成主诊断对象。
这是轻量规则检查,不等价于完整 LLM Verifier。完整 AIOps Verifier 是后续增强项。
## 7. 用户反馈 API
```text
POST /api/feedback
Content-Type: application/json
{
"runId": "run-xxx",
"sessionId": "xxx",
"feedback": "useful" | "not_useful"
}
```
响应:
```json
{
"success": true,
"message": "反馈已记录",
"runId": "run-xxx",
"fallbackToLatestRun": false,
"caseId": "uuid 或 null"
}
```
后端行为:
| feedback | 行为 |
|---|---|
| `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` 记录。
字段映射:
| CaseLibrary 字段 | 来源 |
|---|---|
| `caseId` | UUID |
| `diagnosisId` | 新数据为 `DiagnosisRun.runId`;历史数据可能为 `DiagnosisSession.sessionId` |
| `sourceType` | `AUTO` |
| `faultCategory` | 当前固定为 `GENERAL` |
| `title` | `query` 前 100 字符 |
| `rootCause` | `answer` |
| `solution` | `answer` |
| `createdBy` | `system` |
幂等性:
```text
case_library.diagnosisId == runId
-> existing case: return existing
-> missing case: create new
```
## 9. Trace 呈现
Trace API 会展示:
- `feedback`
- `hasFeedback`
- `hasVerifierEvaluation`
- `hasAiOpsRuleEvaluation`
- session、step、tool invocation 明细
这让一次诊断可以被分成三种视角查看:
| 视角 | 数据来源 |
|---|---|
| 执行是否成功 | `diagnosis_run.status` |
| 证据是否充分 | `self_evaluation.rule_evaluation` / `verifier_evaluation` |
| 用户是否认可 | `diagnosis_run.feedback` |
## 10. 后续增强
近期优先:
1. 将 `rule_evaluation` 与 `verifier_evaluation` 在 Trace API 中结构化展示。
2. 将 ISS-008 / ISS-009 这类 E2E 通过样例固化进 diagnosis eval fixtures。
3. `not_useful` 反馈沉淀 bad case,而不是只写字段。
4. useful 案例自动提取 faultCategory、errorCode、service、rootCause、solution。
5. AIOps 引入 LLM Verifier。
6. 把反馈和 eval baseline 打通,形成可回归的质量改进闭环。
暂不优先:
- 用用户反馈直接修改 session status。
- 仅凭 `evidence_score` 判断答案正确。
- 在没有人工审核时自动把 bad case 反向写入 Prompt。