feat: govern knowledge assets and source citations

This commit is contained in:
key
2026-08-02 01:43:43 +08:00
parent cafb836cda
commit 699cc08050
144 changed files with 17205 additions and 453 deletions
+150
View File
@@ -248,3 +248,153 @@ node scripts/verify-knowledge-platform.mjs
4. 恢复旧应用绑定或重新启用 legacy 空间。
不要删除新表,不删除查询审计,不把附件移动回旧空间,不清理 OSS,不回滚已经写入的稳定空间编码。数据库和静态资源发布仍遵循项目既有备份与发布口径。
## 9. 引用来源定位回填
引用定位迁移为 `backend/script/sql/update/aihr_20260731_knowledge_fragment_locator_mysql8.sql`。先执行只读核对:
```bash
node scripts/verify-knowledge-fragment-locators.mjs
node scripts/backfill-knowledge-fragment-locators.mjs
```
第二条命令只输出完整 `MIGRATE_DB:<sha256>` 授权串,不写数据库。仅在独立获得该完整授权串后,才可设置 `AIHR_MIGRATE_AUTH` 并追加 `--apply`。回填只新增旁路 locator,不更新附件哈希、正式来源审批、fragment、embedding 或 Qdrant point;无法确定页码或时间的旧资料只保留段落级降级位置。
## 10. 数据质量准入与索引一致性
资料上传完成只代表候选版本可供审核,不代表可检索。运营按以下顺序处理:
1. 在资料处理页查看 `REVIEW_PENDING/QUARANTINED` 资产和全部 reason code;硬问题必须修订原资料后重跑,不能勾选放行。
2. 对 `EXACT_DUPLICATE/NEAR_DUPLICATE/SEMANTIC_DUPLICATE` 对照来源、版本和适用范围;任何重复关系仅辅助人工判断,不自动删除或合并。`SEMANTIC_ANALYSIS_DEGRADED` 表示只运行了本地 hash 近似,不能当作完整语义检查。
3. 同名或精确重复上传始终创建新的附件、`docId` 和候选资产;只允许复用不可变 OSS 对象,不得把旧附件改指向新对象。同名内容变化产生 `VERSION_CONFLICT`。规范性知识发布时必须选择同租户、同来源名且仍为 `PUBLISHED/APPROVED` 的被替代资产;成功后旧版本同步变为 `DEPRECATED`。
4. 对 `EXPERT_CONFLICT` 在审核弹窗逐条查看双方来源和原文;真实冲突先确认,再依据现行制度、适用范围和版本标记已解决,误报必须写明理由。任何 `PENDING_REVIEW/CONFIRMED` claim 冲突都阻断发布。
5. 发布时填写来源权威级别、来源版本、用途、适用岗位/区域/项目和审核理由。服务端拒绝语义分析未完成、冲突未裁决、硬问题开放或软问题未逐项确认的版本,不依赖浏览器状态。
6. 发布后查询 `GET /api/knowledge/quality/index-health`。`DEAD_LETTER > 0` 或最老待处理事件持续增长时,先排查 Qdrant、维度和凭据,再由受控重放/修复流程处理;不得手工伪造索引成功。
7. 员工答案争议进入后台 SOP 的“处理争议”。`KEEP` 必须写保留依据;`WITHDRAW` 必须写撤回原因,系统先切断 MySQL 可见性,再由 DELETE outbox 最终清除向量。
8. 业务术语先创建 `DRAFT`,由人工审核为 `ACTIVE` 后才参与当前租户的召回查询扩展;项目/角色范围不匹配时不得扩展。术语 definition 只是审核说明,不能作为无引用事实直接注入模型。
9. 规则自动化先建立版本化草稿并进入 `SHADOW`,用人工或黄金集标签记录误放行/误隔离;当前接口不能进入 `CANARY/ACTIVE`,影子结果不得改变资产状态或替代人工发布。
10. 影子评估由定时任务风险抽样,也可由人工调用 `/rules/samples/schedule` 立即补充队列。差异样本必抽,其他样本按风险稳定抽样;只有登录审核人能提交复核结论。每批抽样写 `aihr_pipeline_run`,指标中的 `assetMutationCount` 必须为 0。
数据质量生命周期迁移按 `aihr_20260801` 至 `aihr_20260814` 的日期顺序执行,最后执行 `aihr_20260718_release_collation_compat_mysql8.sql`。`aihr_20260808_data_quality_monitoring_mysql8.sql` 新增 `aihr_quality_alert`,`20260809` 新增人工术语表,`20260810` 补齐 AI 案例 provenance,`20260811` 增加只观察的规则演进、影子评估和抽样复核证据,`20260812` 增加处理批次血缘和自动影子抽样,`20260813` 增加冻结黄金集、黄金评估血缘和风险验收门槛,`20260814` 增加独立隐私脱敏派生、规则版本和复扫状态;迁移可重复执行,但生产执行前仍须备份并在结构副本验证。不得用 `reset-dev-db.sh` 代替生产迁移。
日常监控入口:
```http
GET /api/knowledge/quality/metrics
GET /api/knowledge/quality/alerts?includeResolved=false&limit=100
GET /api/knowledge/quality/glossary?status=ACTIVE&limit=100
GET /api/knowledge/quality/rules?status=SHADOW&limit=100
GET /api/knowledge/quality/pipeline-runs?status=ALL&limit=100
GET /api/knowledge/quality/rules/{ruleId}/samples?status=PENDING&limit=100
GET /api/knowledge/quality/golden-datasets?status=FROZEN&limit=100
GET /api/knowledge/quality/rules/{ruleId}/readiness
GET /api/knowledge/quality/legacy/preview?afterAttachmentId=0&limit=20
GET /actuator/health
```
管理端“资料处理”页展示生产来源可追溯率、24 小时问答证据覆盖率、待裁决冲突、语义分析死信和开放告警。Actuator 中的 `aihrKnowledgeQuality` 只反映门禁与索引健康,不代替人工内容审批;告警扫描不会自动发布、删除、合并或裁决资料。`CRITICAL/ERROR` 告警应先定位 `evidenceJson` 对应的资产、outbox 或查询证据,再通过既有审核/撤回/重建流程处置,不得直接修改告警表伪造恢复。
只读健康核验:
```sql
select status, operation, count(*) events, min(create_time) oldest
from aihr_index_outbox
group by status, operation
order by status, operation;
select lifecycle_status, index_status, count(*) assets
from aihr_data_asset
group by lifecycle_status, index_status
order by lifecycle_status, index_status;
select reason_code, gate_type, status, count(*) findings
from aihr_quality_issue
group by reason_code, gate_type, status
order by reason_code, gate_type, status;
select semantic_analysis_status, semantic_embedding_model, count(*) versions,
max(semantic_retry_count) max_retries
from aihr_data_version
group by semantic_analysis_status, semantic_embedding_model
order by semantic_analysis_status, semantic_embedding_model;
select conflict_type, status, count(*) conflicts, min(create_time) oldest
from aihr_claim_conflict
group by conflict_type, status
order by conflict_type, status;
select alert_code, severity, status, occurrence_count, first_seen_time, last_seen_time
from aihr_quality_alert
order by status = 'OPEN' desc, severity, last_seen_time desc;
select status, stage, processor_name, processor_version, count(*) runs,
min(started_time) oldest, max(started_time) newest
from aihr_pipeline_run
group by status, stage, processor_name, processor_version
order by status, stage, processor_name;
```
生产查询必须同时满足当前租户/空间授权、资产 `PUBLISHED`、数据集成员 `ACTIVE` 和当前有效版本。历史纳管接口按 `afterAttachmentId` 游标读取附件;有当前租户可验证的 OSS 原件时重新执行解析、质量门禁和切片,无原件或原件不可读时创建 `QUARANTINED / SOURCE_UNAVAILABLE` 版本。不得通过现有 fragment 反向伪造原始来源,也不得自动批准历史资料。
新接入资料的原始 MinIO/OSS 对象、`parsed_content` 和 `normalized_content` 只作为受控审计证据保留。生产处理必须使用 `privacy-redaction-v1` 生成的独立脱敏派生版本;审核页通过 `GET /api/knowledge/quality/assets/{assetId}/privacy-preview` 只查看脱敏文件名、命中分类和脱敏正文预览。`privacy_status` 不是 `CLEAN/REDACTED`、缺少规则版本或派生正文时不得发布;`BLOCKED / PII_DETECTED` 必须修订来源并产生新版本,不能在发布时人工接受。
上线或批量纳管前先按租户核对隐私派生覆盖,不允许为历史版本直接回填一个“已通过”状态:
```sql
select privacy_status, redaction_policy_version, count(*) versions
from aihr_data_version
group by privacy_status, redaction_policy_version
order by privacy_status, redaction_policy_version;
select count(*) unsafe_chunks
from aihr_chunk_revision c
join aihr_data_version v on v.id = c.version_id and v.tenant_id = c.tenant_id
where v.privacy_status not in ('CLEAN', 'REDACTED')
or v.redacted_content is null
or v.redaction_policy_version is null;
```
历史版本在迁移后保持 `NOT_PROCESSED`,必须从可验证原件重新解析、脱敏、复扫和人工审核。先用少量访谈材料验证规则,再批量纳管;不得在隐私派生完成前复制现有历史 fragment。
检索结果返回后仍必须在引用水合、引用详情、相邻片段和原件下载四个读取点分别复核当前版本、`PUBLISHED`、`HUMAN_VERIFIED`、`dataset_code=production`、成员 `ACTIVE` 和有效期。Qdrant payload、查询 filter、计数和显式重建使用同一组生产标签;没有这些标签的历史点不参与生产检索,也不计入生产向量一致性。管理端的“历史未纳管”及 `UNGOVERNED_LEGACY_FRAGMENTS` 是迁移待办,不是“一键重建”提示。
历史资料按以下批次执行,严禁全量自动批准:
1. 只读导出本批附件 manifest:租户、附件 ID、OSS ID、对象 hash、当前空间和处理状态,不导出业务正文到报告。
2. 调用 `/api/knowledge/quality/legacy/stage` 时使用 `afterAttachmentId` 和 20–50 的小批量;只从同租户 MinIO 原件重新解析。
3. `SOURCE_UNAVAILABLE`、解析损坏、PII、提示词注入、版本冲突和跨租户风险一律留在隔离区;不得从旧 fragment 补造原文。
4. 内容负责人逐份确认来源、版本、适用岗位/区域/项目、有效期和 reason code。AI 分析只能提供证据,不具有批准权限。
5. 每批批准后运行该空间标准题与无答案负例,核对引用、详情、下载和 Qdrant 生产点数,再开始下一批。
6. 旧的未标记向量点保留到批次 manifest、生产点和回归结果全部对账完成;清理必须使用独立授权和可回滚清单,不与重建动作混在一起。
推荐通过 CLI 执行。默认命令不调用写接口;提供 token 时会调用只读 `/legacy/preview` 返回本批原件可用/不可用数量,不提供 token 时只做离线参数校验。显式 `--execute` 时才会写入待审或隔离数据,token 不写 manifest。批次出现失败附件时游标保持不变,修复后可从 manifest 恢复:
```bash
AIHR_LEGACY_TOKEN="$LOCAL_ADMIN_TOKEN" node scripts/stage-legacy-knowledge.mjs \
--base-url https://wygj-api.localhost \
--manifest tmp/legacy-knowledge-stage-manifest.json \
--batch-size 20 --max-batches 1
AIHR_LEGACY_TOKEN="$LOCAL_ADMIN_TOKEN" node scripts/stage-legacy-knowledge.mjs \
--execute --base-url https://wygj-api.localhost \
--manifest tmp/legacy-knowledge-stage-manifest.json \
--batch-size 20 --max-batches 1
```
黄金检索评测必须使用人工标注的业务数据集和本地登录令牌显式运行,脚本不会读取示例夹具作为正式验收结果,也不会输出令牌或问题正文:
```bash
node scripts/evaluate-knowledge-quality.mjs \
--dataset tests/fixtures/data_quality/retrieval-golden.local.json \
--base-url https://wygj-api.localhost \
--token "$AIHR_EVAL_TOKEN" \
--k 5 \
--min-recall 0.90 \
--min-mrr 0.85 \
--min-ndcg 0.85 \
--max-leakage 0 \
--max-wrong-source 0.02 \
--max-no-answer-false-positive 0.05
```
验收至少核对 Recall@5、MRR、nDCG@5、禁止片段/来源泄漏率、错误来源率和无答案误召回率;任一显式门槛不通过时脚本退出码为 2。示例文件 `tests/fixtures/data_quality/retrieval-golden.example.json` 只定义格式;正式门槛必须使用 100–300 条经业务专家确认、覆盖多租户/版本/正反案例/无答案问题的黄金集标定。