Files
SuperBizAgent-java/openspec/changes/archive/2026-06-30-confidence-feedback/design.md
T

117 lines
3.9 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.
# 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