feat(feedback): 置信度评分与用户反馈机制 & 归档 confidence-feedback change

This commit is contained in:
zhuyongxin
2026-06-30 18:01:06 +08:00
parent 3ffa5cc366
commit 2a796da490
16 changed files with 771 additions and 18 deletions
@@ -0,0 +1,116 @@
# Design: 置信度评分与用户反馈机制
## 架构约束(来自 devflow)
- Spring Boot 3.2 + Spring AI Alibaba
- JPA ddl-auto=validate,变更走 Flyway
- 已有实体:`DiagnosisSession`(含 selfEvaluation JSON、feedback VARCHAR)、`CaseLibrary`
- **新增字段**:`DiagnosisSession.answer TEXT`,存储返回给用户的完整答案,Flyway V008 迁移
- 已有 Repository:`DiagnosisSessionRepository`、`CaseLibraryRepository`
- 当前主流程入口:`ChatService.executeChat`(非流式)、`executeChatComplex`(多 Agent)
## 模块链路
```
用户对话
↓
ChatService.executeChat / executeChatComplex
↓ SUCCESS 后异步
EvaluationService.evaluate(sessionId, answer, steps)
├─ LLM 自评 → 写 selfEvaluation(含 confidence + reasoning)
└─ 规则兜底(LLM 失败时)→ 写 selfEvaluation(含 source: "rule")
用户提交反馈
↓
POST /api/feedback { sessionId, feedback }
↓
FeedbackService.submitFeedback(sessionId, feedback)
├─ 写 DiagnosisSession.feedback
├─ feedback=useful → 写 CaseLibrary
└─ feedback=not_useful → 更新 status=BAD_CASE
```
## 数据结构定义
### DiagnosisSession.selfEvaluation(JSON 字符串)
```json
{
"evidence_score": 65,
"source": "rule",
"factors": [
{"name": "has_successful_tool_call", "delta": 30, "description": "有成功的工具调用(2次)"},
{"name": "l1_semantic_match", "delta": 20, "description": "L1 语义匹配命中"}
]
}
```
字段说明:
- `evidence_score`:0-100,衡量证据收集充分度(非答案准确性)
- `source`:评分来源,当前固定为 `"rule"`;预留 `"llm"` 供后续 LLM 观点叠加
- `factors`:命中的规则因子列表,每项含 name / delta / description,可直接用于分析
- `llm_opinion`:预留字段,LLM 观点叠加时扩展此处,不改变现有规则逻辑
### FeedbackRequest(新 DTO)
```java
public class FeedbackRequest {
String sessionId; // 必填
String feedback; // "useful" | "not_useful"
}
```
### FeedbackResponse(新 DTO)
```java
public class FeedbackResponse {
boolean success;
String message;
String caseId; // useful 时返回生成的 case_id,否则 null
}
```
### CaseLibrary 生成规则(useful 时)
| CaseLibrary 字段 | 来源 |
|---|---|
| caseId | UUID |
| diagnosisId | DiagnosisSession.sessionId |
| sourceType | SourceType.AUTO |
| faultCategory | FaultCategory.GENERAL(暂时) |
| title | DiagnosisSession.query 前 100 字符 |
| rootCause | DiagnosisSession.answer(完整答案,不截断) |
| solution | DiagnosisSession.answer(同上) |
| createdBy | "system" |
## 关键技术决策
### 决策 1:LLM 自评异步执行
置信度计算在 Agent 主流程结束后异步进行(`@Async` + Spring 线程池),不阻塞用户响应。
原因:LLM 自评耗时 1-3 秒,主流程不应等待。
### 决策 2:置信度规则兜底参数
```
基础分:60
工具调用加分:toolCallCount × 5,上限 +20
步数少加分:stepCount <= 3 → +10
status=FAILED → 直接 0
```
### 决策 3:BAD_CASE 用 status 字段而非新字段
`DiagnosisSession.status` 已有 PENDING/RUNNING/SUCCESS/FAILED,扩展为允许包含 BAD_CASE。
该字段是 VARCHAR 16,直接存字符串,无需枚举类(Java 端用常量控制)。
### 决策 4:案例内容提取策略
useful 时,`rootCause` 和 `solution` 从 `AgentStepRepository.findBySessionIdOrderByStepIndex` 的最后一步 `thought` 字段提取。
如果 thought 为空,则用 DiagnosisSession.query + "(自动提取失败,请人工补充)" 占位。
## 接口影响等级
- `POST /api/feedback`:新增接口,L2(内部,前端新消费)
- `ChatService.executeChat`:新增异步后置调用,不改返回值,L1
- `DiagnosisSession.status` 增加 BAD_CASE 值:原调用方只读不写此字段,L2