# 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