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,133 @@
# Tasks: 置信度评分与用户反馈机制
## T0:Flyway 迁移 + DiagnosisSession 实体加字段
**文件**:
- `src/main/resources/db/migration/V008__add_answer_to_diagnosis_session.sql`(新建)
- `src/main/java/com/superbiz/agent/domain/entity/DiagnosisSession.java`(加字段)
**迁移脚本**:
```sql
ALTER TABLE diagnosis_session ADD COLUMN answer LONGTEXT COMMENT 'Agent 返回给用户的完整答案';
```
**实体**:在 `DiagnosisSession` 加:
```java
@Column(name = "answer", columnDefinition = "LONGTEXT")
private String answer;
```
**验收标准**:应用启动不报 schema validation 错误;`diagnosis_session` 表有 answer 列
---
— LLM 自评 + 规则兜底
**文件**:`src/main/java/com/superbiz/agent/service/EvaluationService.java`
**实现**:
- `@Service @Async` 标注
- `evaluate(String sessionId, String answer)` 方法:
1. 从 `DiagnosisSessionRepository` 加载 session(含 stepCount、toolCallCount、status)
2. 调用 ChatModel 做 LLM 自评,Prompt 见下
3. 解析 JSON → 写入 `selfEvaluation`
4. 失败时走规则兜底
- 规则兜底逻辑:`computeRuleScore(session)` → 返回 JSON 字符串
**LLM 自评 Prompt(系统提示)**:
```
你是一个 AI 回答质量评估器。
请根据以下信息,评估这次 AI 回答的置信度(0-100分):
- 用户原始问题:{query}
- AI 的回答:{answer}
- 工具调用次数:{toolCallCount}
- 推理步数:{stepCount}
只返回一个 JSON,格式如下,不要输出任何其他内容:
{"confidence": <0-100的整数>, "reasoning": "<评估依据,50字以内>"}
```
**验收标准**:
- LLM 正常时:DB selfEvaluation 包含 confidence 和 reasoning,source = "llm"
- LLM 失败时:DB selfEvaluation 包含 confidence 和 source = "rule"
---
## T2:ChatService 后置调用 EvaluationService
**文件**:`src/main/java/com/superbiz/agent/service/ChatService.java`
**实现**:
- 在 `executeChat` 的 `session.setStatus("SUCCESS")` 之后,追加 `session.setAnswer(answer)` 写入完整答案,再注入 EvaluationService 调用 `evaluate(sessionId, answer)`
- 在 `executeChatComplex` 的 SUCCESS 分支同样补充 `session.setAnswer(answer)`
- 注意:EvaluationService 是 @Async,调用方不等待返回值
**验收标准**:发送一次 chat 请求后,数秒内 DB self_evaluation 非 null
---
## T3:FeedbackController + FeedbackService
**文件**:
- `src/main/java/com/superbiz/agent/controller/FeedbackController.java`(新建)
- `src/main/java/com/superbiz/agent/service/FeedbackService.java`(新建)
- `src/main/java/com/superbiz/agent/dto/FeedbackRequest.java`(新建)
- `src/main/java/com/superbiz/agent/dto/FeedbackResponse.java`(新建)
**FeedbackService.submitFeedback(sessionId, feedback)**:
1. 加载 session,sessionId 不存在抛异常
2. 校验 feedback 值(useful/not_useful)
3. 更新 `DiagnosisSession.feedback`
4. if useful:调用 `CaseLibraryService.createFromSession(session)`
5. if not_useful:更新 `DiagnosisSession.status = "BAD_CASE"`
6. 保存 session
7. 返回 FeedbackResponse
**幂等逻辑(useful 重复提交)**:
- 调用 `CaseLibraryRepository.findByDiagnosisId(sessionId)` 检查
- 已存在则返回已有 caseId,不重复插入
**FeedbackController**:
```
POST /api/feedback
@RequestBody FeedbackRequest
@ResponseBody FeedbackResponse
```
**验收标准**:
- useful:返回 200,feedback 字段有值,case_library 新增一行
- not_useful:返回 200,status = BAD_CASE
- 非法 feedback 值:返回 400
---
## T4:CaseLibraryService — createFromSession
**文件**:`src/main/java/com/superbiz/agent/service/CaseLibraryService.java`(新建)
**实现**:
- `createFromSession(DiagnosisSession session)` → `CaseLibrary`
- 直接从 `session.getAnswer()` 取完整答案
- answer 为空时用占位文本 `query + "\n(自动提取失败,请人工补充)"`
- 填写 CaseLibrary 各字段,save 后返回 caseId
**验收标准**:case_library 行的 diagnosis_id = sessionId,root_cause 非空
---
## T5:Spring @Async 配置
**文件**:检查项目是否已有 `@EnableAsync`,若无则在 `SessionConfiguration` 或新建 `AsyncConfig` 中添加
**验收标准**:EvaluationService 中 @Async 方法可被正确调度(不抛 bean 配置错误)
---
## T6:集成验证
验证步骤:
1. 启动服务,POST /api/chat,发送一条问题
2. 查 `diagnosis_session` 表,确认 self_evaluation 有值
3. POST /api/feedback `{"sessionId": "xxx", "feedback": "useful"}`,确认 case_library 新增
4. POST /api/feedback `{"sessionId": "yyy", "feedback": "not_useful"}`,确认 status = BAD_CASE
5. 重复步骤 3,确认不重复创建 case_library