14 KiB
N02 候选评分规则解释与合理性:详细设计
状态:N02 独立代码复验与真实 MySQL/Docker 黑盒验收通过,待 Git 检查点。
文档类型:解释。目标读者为产品负责人、后端开发、独立验收人员和前端联调人员。本设计说明现有候选评分实际上计算了什么、一期应如何向学生解释,以及哪些结论不得从这些分数推出。
1. 背景与目标
当前候选评分由 CandidateScoringCalculator 计算八个维度,并由 CandidateScoringEngineService 写入或读取 candidate_dimension_scores。学生单维接口已有 subScores、reasons 和 dataSources,但这些信息由各计算方法临时拼装,缺少稳定的规则编码、解释版本、适用范围和限制说明。
N02 的一期目标是让学生能够回答以下问题:
- 这个分数使用了哪些数据;
- 哪些确定性规则实际命中;
- 每条规则对当前结果产生了什么影响;
- 哪些数据缺失、过期或仍未接入;
- 用户可以通过哪些真实、合理的方式完善资料;
- 该分数不能代表什么。
N02 同时要求企业端继续只查看聚合分与状态,不获得学生的私人明细、行为次数、测评细分或改进建议。
2. 非目标
一期不做:
- SHAP、机器学习特征贡献或 AI 生成解释;
- 人口属性公平性推断;
- 宣称规则已具备心理测量效度或预测效度;
- 自动修改评分权重、排名或推荐逻辑;
- 新增评分事实表、解释历史表或规则配置后台;
- 向企业暴露学生的细分评分证据;
- 将行为频次解释为人格、诚信、成长潜力或职业能力;
- 用解释功能引导用户刷投递、刷消息、刷简历版本。
3. 当前真实实现
3.1 代码入口
- 计算:
mydreamjob-server/src/main/java/com/mydreamjob/candidatescore/CandidateScoringCalculator.java - 服务:
CandidateScoringEngineService.java - 学生与企业接口:
CandidateScoringController.java - 快照:
CandidateDimensionScore.java、CandidateDimensionScoreRepository.java - 能力映射:
AbilityAssessmentScoreSource.java、AbilityScoreMapper.java - 申诉与回滚:
candidatescore/governance/ - 排名:
competition/CompetitionRankingCalculator.java
3.2 综合分
当前八维默认展示权重均为 12.50。只有状态为 OK 或 ESTIMATED 且分数非空的维度参与综合分:
overallScore = sum(可计算维度分数) / 可计算维度数量
最终保留两位小数,HALF_UP。PENDING 和 INSUFFICIENT_DATA 被排除后重新归一化,因此两个相同综合分可能来自不同的维度集合。解释必须展示参与维度数量与排除维度,禁止把综合分描述为完整、统一口径的能力总分。
3.3 规则版本
- 能力测评开关关闭:
candidate-scoring-v0.1; - 能力测评开关开启:
candidate-scoring-v0.2; - ABILITY 映射规则:
ability-assessment-scoring-v0.1; - 历史趋势优先使用快照自身
rulesVersion。
N02 只增加解释契约时不升级候选评分规则版本,建议新增独立的 explanationVersion=candidate-scoring-explanation-v1。只有公式、阈值、参与维度或排名输入发生变化时才升级评分规则版本。
4. 设计原则
4.1 解释必须与计算同源
每个计分分支在计算贡献值的同时生成内部 RuleContribution,不能在 Controller、DTO mapper 或另一套公式中根据最终分数反推解释。
建议内部结构:
RuleContribution
- ruleCode 稳定规则编码
- outcome APPLIED / NOT_APPLIED / MISSING / EXPIRED / UNAVAILABLE
- contribution 实际加减分;不适用时为 null
- maxContribution 该规则可能贡献的绝对上限
- publicLabel 面向学生的中性名称
- publicObservation 安全的区间或状态,不输出内部数据库字段
- explanationKey 固定解释模板编码
规则元数据由 CandidateScoringExplanationCatalog 按 ruleCode 提供名称、限制、建议和证据等级。计算器产生“事实和贡献”,目录提供“稳定语义”,Assembler 只组合,不重复计算。
当逐项贡献按两位小数展示而整体分数采用 HALF_UP 产生舍入差时,使用
SCORE_ROUNDING_ADJUSTMENT 显式记录对账差;它只解释展示精度,不改变任何评分公式。
4.2 不把解释做成刷分指南
学生可以看到区间和缺失项,例如“近 90 天存在投递记录”“求职偏好尚未完整”,但默认不暴露风控阈值组合、审计动作名称、原始消息数量或内部 SQL 字段。已经在界面契约中公开的固定能力权重可继续展示。
4.3 区分事实、推断与限制
每个维度必须有:
whatItMeasures:规则直接使用的数据;interpretation:可谨慎解释的含义;limitations:不能据此得出的结论;evidenceLevel:DIRECT_RULE、SELF_REPORTED、BEHAVIOR_PROXY、UNVALIDATED_PROXY;improvementActions:只给可合理完成的操作,不鼓励刷行为。
5. 一期响应方案
5.1 路径范围
保持现有 4 个路径,不新增 operation:
GET /profile/me/candidate-scoringGET /profile/me/candidate-scoring/dimensions/{dimension}GET /profile/me/candidate-scoring/trendGET /company/candidates/{applicationId}/scoring
OpenAPI 路径/操作数保持当前基线 172/210。
5.2 学生综合卡兼容扩展
建议新增:
explanationVersion;coverage.computableDimensions;coverage.totalDimensions=8;coverage.includedDimensions;coverage.excludedDimensions[]{dimension,status,reason};comparabilityNotice,固定说明不同参与维度集合的综合分不宜直接比较。
不得返回内部快照 ID、测评结果 ID、题目、答案、审计详情、消息正文或数据库字段名。
5.3 学生单维详情兼容扩展
保留现有 subScores/reasons/dataSources,新增:
displayName;whatItMeasures;interpretation;limitations[];evidenceLevel;ruleContributions[];improvementActions[];explanationVersion;validity:仅在存在明确有效期时返回,例如 ABILITY;calculatedAt:本次真实计算基准时间。
ruleContributions 只面向学生本人。旧字段在一期保留,避免前端破坏性升级;文档标记旧 reasons/dataSources 后续逐步由结构化字段替代。
5.4 企业端
企业端保持现有字段:applicationId/overallScore/status/dimensions/generatedAt/rulesVersion。不新增 ruleContributions、limitations、行为次数、学校分档、资料缺失项、四维能力细分或有效期。
企业页面可增加平台级固定说明,但不得把学生解释 DTO 直接复用到企业响应。
6. 时间一致性
computeAll 应在入口生成一次 capturedNow,并传递给所有时间敏感查询与规则:
- 90 天投递;
- 30 天登录和活跃操作;
- 账号月龄;
- 简历 90 天更新;
- ABILITY 有效期;
calculatedAt和数据源时间说明。
不得在同一次计算中多次调用 LocalDateTime.now() 形成不同边界。建议注入 Clock,生产使用系统时钟,测试使用固定时钟。
7. 八维解释口径
| 维度 | 一期允许的名称 | 允许解释 | 禁止解释 |
|---|---|---|---|
| EDUCATION | 教育背景信息 | 已填写学历与学校分类规则的确定性结果 | 智力、能力上限、人才质量 |
| INTERNSHIP | 实习经历信息 | 当前数据源尚未接入 | 无实习能力、经验不足 |
| ABILITY | 四维能力测评 | 最新有效自研测评的规则化聚合 | 确定性职业能力、招聘结论 |
| COMPLIANCE | 求职偏好完整度 | 五类偏好字段填写情况 | 合规意识、服从性 |
| STABILITY | 平台求职行为稳定信号 | 账号时长、撤回与登录形成的行为代理 | 人格稳定、忠诚度 |
| GROWTH | 简历维护与技能展示信号 | 简历维护和技能标签状态 | 成长潜力、学习速度 |
| INTEGRITY | 履约与资料一致性信号 | Offer 响应、反馈与资料完整度的行为代理 | 道德、诚信人格、信用评级 |
| ACTIVITY | 平台求职活跃度 | 近期投递、平台操作和沟通信号 | 工作积极性、职业投入度 |
维度代码为兼容字段,本版不改数据库枚举。产品展示名称采用上述中性名称。
8. 合理性整改分级
8.1 仅解释整改即可上线
- ABILITY:保留现有公式和有效期,补自评/情境测验限制;
- INTERNSHIP:保持 PENDING,明确“未接入”不是低分;
- 综合分:补参与维度和不可横向比较提示。
8.2 需要改名但暂不改公式
- COMPLIANCE → 求职偏好完整度;
- STABILITY → 平台求职行为稳定信号;
- GROWTH → 简历维护与技能展示信号;
- INTEGRITY → 履约与资料一致性信号;
- ACTIVITY → 平台求职活跃度。
这里只修改展示语义,不改变维度代码、快照或历史接口。
8.3 需要后续规则版本评审
- EDUCATION 的学校名单及 45% 权重;
- STABILITY 的账号时长奖励和撤回惩罚;
- GROWTH 的简历版本数量奖励;
- INTEGRITY 的 Offer 接受奖励、过期惩罚和反馈评分;
- ACTIVITY 的投递、审计和消息计数可操纵性;
- 缺失维度重新归一化后仍进入企业评分与排名。
任何一项改变分数都必须升级评分版本、完成新旧结果对账和 V32 排名回归,不能混入纯解释提交。
9. 权限与隐私
学生本人可以查看自身安全聚合解释。企业只能查看现有聚合评分卡。ADMIN 沿用治理接口,不因 N02 获得新的个人解释查询入口。
所有 HTTP 响应禁止新增:
- 原始审计动作、IP、User-Agent;
- 消息正文或对话对象;
- Offer 具体企业、岗位或时间线;
- 评价正文与评价人身份;
- assessment/ability 的题目、答案、答案键、评分规则和结果 ID;
- 内部 SQL、表名、快照 ID、用户 ID;
- 密码、Token、密钥。
学生响应中的数据来源改为产品语义名称,如“个人教育资料”“求职偏好”“平台求职活动”,不直接返回 student_profiles.education/school 等物理字段名。
10. 实现建议
建议新增内部类:
CandidateScoringExplanationCatalog:规则元数据白名单;CandidateScoringExplanationAssembler:将DimensionResult与规则元数据组装为学生 DTO;RuleContribution、ScoreCoverage等内部/DTO 类型。
修改:
CandidateScoringCalculator:统一capturedNow/Clock,每个实际分支同步生成贡献;CandidateScoringEngineService:组装覆盖率与学生解释;- 学生 DTO:兼容新增字段;
- OpenAPI、校验脚本、API 和联调文档。
原则上无新 Flyway、无新 ErrorCode、无新公网路径。解释元数据先随代码版本发布,不引入可在线修改规则的后台。
11. 测试与验收
11.1 规则同源
- 每个阈值边界独立手算;
contribution之和与真实维度分形成可证明关系;- 未命中、缺失、过期和不可用规则不能伪造成 0 分命中;
- 固定 Clock 验证 30/90 天和有效期边界;
- 不允许修改解释而改变分数,或修改分支后遗漏解释。
11.2 综合分
- 0、1、2、8 个可计算维度;
OK/ESTIMATED参与,其他状态排除;- coverage 与实际参与集合完全一致;
- 学生综合卡、趋势、企业评分和 V32 排名与既有纯函数对账。
11.3 权限与脱敏
- STUDENT 仅查看本人;
- COMPANY 只见聚合字段;
- ADMIN 不获得新增学生详情入口;
- 匿名 401,角色越权 403/2002;
- 对完整 JSON 递归扫描禁止字段;
- ABILITY 不泄露题目、答案或来源结果 ID。
11.4 防刷与边界评审
用固定样例证明重复投递、发消息、制造简历版本可能改变哪些分数,并在本版明确标为未验证代理信号。若决定保留其排名影响,必须形成书面产品决策和监测指标。
11.5 发布验证
- N02 专项、候选评分、治理、V32、V38、V39、V41、V42、V43 回归;
mvn clean verify;- 静态与运行时 OpenAPI 对账;
- 真实 MySQL 主链路和响应脱敏;
- 查询前后快照写入行为保持既有语义;
- 无新增 RabbitMQ 消息。
12. 编码前决策表
| 编号 | 决策项 | 建议方案 | 状态 |
|---|---|---|---|
| D01 | N02 是否只做解释,不改任何现有分数、权重和排名 | 是;规则合理性问题记录为后续独立评分版本 | 已确认 |
| D02 | 是否保持现有 4 个接口、0 个新增 path/operation | 是 | 已确认 |
| D03 | 是否无新 Flyway、无规则配置后台 | 是 | 已确认 |
| D04 | 是否增加独立 explanationVersion,不升级评分 rulesVersion |
是,值为 candidate-scoring-explanation-v1 |
已确认 |
| D05 | 是否兼容扩展学生综合卡,展示参与/排除维度和可比性提示 | 是 | 已确认 |
| D06 | 是否兼容扩展学生单维详情,增加结构化规则贡献、限制和建议 | 是 | 已确认 |
| D07 | 企业端是否保持现有 schema,不展示任何规则贡献与私人细分 | 是 | 已确认 |
| D08 | 是否采用中性展示名,但保持八个维度代码不变 | 是 | 已确认 |
| D09 | 是否明确 INTEGRITY 不能解释为人格诚信或信用评级 |
是 | 已确认 |
| D10 | 是否明确 GROWTH/STABILITY/COMPLIANCE/ACTIVITY 仅为平台数据代理 |
是 | 已确认 |
| D11 | 是否用单次 capturedNow 并注入 Clock 修复解释时间一致性 |
是,不改变阈值与公式 | 已确认 |
| D12 | 学生是否只看安全区间/状态,不显示可用于刷分的内部计数与审计动作 | 是 | 已确认 |
| D13 | EDUCATION 学校分档是否暂时保留计算,但增加未验证与公平性警示 | 暂留,另开评分版本评审决定移除/降权 | 已确认 |
| D14 | 缺失维度重新归一化是否暂时保留 | 暂留,明确可比性限制并在规则评审中决定 | 已确认 |
| D15 | 是否安排题库和规则证据验证,不将当前确定性规则称为已验证模型 | 是 | 已确认 |
D01–D15 已全部确认并按本设计实现。若未来 D01、D13 或 D14 的产品决策改变计分,本模块必须另行升级评分规则版本,不能通过解释增强提交混入。