Files
prop-ai-hr/docs/物业AI人力资源系统开发规格TechSpec.md
T

561 lines
43 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.
# 物业行业 AI 人力资源系统 · 开发规格(Tech Spec)
> 版本:v2.0 | 日期:2026-07-24
> 定位:**开发层唯一依据**。回答"怎么建"——工程结构、数据表、API 契约、Prompt 规格、集成适配。
> v1.1 变更:数据模型对齐《手册》卷1 第9章 HR 主干,补 3 张 backbone 表(职位职责/雇员绩效/雇用终止),新增附录 D 对照表。
> v1.2 变更:第 6 章按 Codex 设计评审重写——状态机补异常/终止态、COACH_CHECK 工程化、评分引擎分层(P0 单 LLM / P1 融合)、澄清"单场对练评分 vs 跨期能力画像"两套评分、Prompt 加固 + RAG 硬约束、新增 6.5 P0/P1 切分。
> v1.3 变更:Qdrant 作为一期向量索引层落地;SOP 知识库检索升级为 MySQL Fulltext + Qdrant RRF 融合,MySQL/MinIO 仍是事实源。
> v1.4 变更:移动端拆为独立 `mobile/` Vue/Vite Web/H5 工程,承载员工端、候选人端、主管端;后台管理端继续在 `frontend/`。
> v1.5 变更:当前用户侧以 `mobile-uni/` 为准;员工工作上报复用 `ChatComposer` 改为语音优先会话,增加无状态 AI 整理草稿契约,确认后继续提交既有 `aihr_work_report` 审核链。
> v1.6 变更:工作助手显式“记一下”复用 `/api/knowledge/query` 的 `memoryCandidate`,确认后写 `aihr_assistant_capture`;位置字段改为可选,增加 PRIVATE/COMPANY 范围、跟进时间和待流转状态。音色不在本次实现范围。
> v1.7 文档收口:明确当前“工作上报”是四类成果投稿审核链,工作助手负责日常事实采集;项目名称选择、项目化会话、来源追溯和今日工作成果仍属后续迭代,不能从规划文档推断已实现。详见[迭代计划](工作助手与今日工作成果迭代计划-20260721.md)。
> v1.8 发布前本地实施快照:项目名称选择、项目化会话、确认记录来源/状态、员工今日成果、主管项目成果和“成果投稿”界面名称已完成本地实现与 390×844 验证;该快照记录的是发布前状态,外部线索、工单和考勤投递仍保持 PENDING。
> v1.9 发布与本轮回填: v1.8 所列多项目、项目化确认采集、来源/状态、员工今日成果、主管项目成果和“成果投稿”界面名称已于 2026-07-21 部署。成果历史日期选择、服务端拒绝未来日期及主管手机号授权兜底已于 2026-07-22 发布,并完成远端服务、schema 与产物匹配复核;外部线索、工单和考勤投递仍保持 PENDING。
> v2.0 实施快照:“问”改由 `/api/aihr/agent/**` 统一规划意图并执行受控工具,知识 RAG 退回底层能力;新增 `aihr_agent_run` 最小路由审计。该增量已完成自动化、H5 构建和部分 390×844 浏览器验证,并随 2026-07-25 完整包部署;移动身份失败关闭语义又包含在 2026-07-29 定向发布的生产后端中。正式账号完整业务和真机验收仍未完成。
> v2.1 受控生产增量:2026-08-04 新增 Grounded Agent 核心契约、`MY_CURRENT_TASKS + KNOWLEDGE_SEARCH` 双工具、证据/事实分型、有界执行、逐结论引用和结构化会话状态;生产仅在文本 `KNOWLEDGE_QA`、`LIVE_MY_WORK` 且通过计划、授权和证据门禁时使用 Grounded 运行时,其余请求回退 v2.0 路径。仓库默认仍为 `OFF`,详细契约见 [AIHR_GROUNDED_AGENT_TECHSPEC.md](AIHR_GROUNDED_AGENT_TECHSPEC.md)。
> 配套:需求见[《物业AI人力资源系统业务需求文档BRD》](物业AI人力资源系统业务需求文档BRD.md);2026-07 MVP 执行计划已归档到[《AI人力资源系统一期MVP版作战清单》](archive/2026-07-mvp-delivery/AI人力资源系统一期MVP版作战清单.md)。
> **优先级图例**:`P0`=2026-07-05 MVP 演示必需 · `P1`=一期必需 · `P2`=二期/推迟。
> 决策基线:若依基座 / 集中式前后端分离 / 本地登录 / 公有大模型API / 一期RAG / 组织人员外部同步(MVP 用快照) / 数据范围以项目为主体。
---
## 1. 技术栈与工程结构
### 1.1 技术栈
| 层 | 选型 |
|---|---|
| 后端 | Java + Spring Boot 4(若依 RuoYi 后端) |
| 管理端前端 | Vue + plus-ui(若依前端,前后端分离) |
| 移动端前端 | `mobile-uni/` uni-app Vue3 H5 + App-Plus;旧 `mobile/` 只作 MVP 演示兜底 |
| 数据库 | MySQL(主数据/事务)+ MinIO(原始文件)+ Qdrant(向量索引) |
| 检索 | MySQL Fulltext + Qdrant 混合 RAG(一期);知识图谱 Neo4j(P2) |
| 大模型 | 公有大模型 API(对话/出题/评分/案例整理) |
| 语音 | 第三方 ASR(方言:川/粤)+ TTS |
| 部署 | 集中式,前后端分离,单实例起步(无微服务、无高并发承诺) |
### 1.2 工程结构(若依约定)
```
backend/
ruoyi-admin/ # 启动入口
ruoyi-system/ # 复用:用户/角色/菜单/数据权限
ruoyi-modules/ruoyi-aihr/ # AI HR 自有业务 API、seed fallback、知识库/RAG/模型配置
script/sql/aihr_knowledge_mysql8.sql
script/sql/aihr_model_mysql8.sql
frontend/
src/views/{index,recruit,train,knowledge,system/model} # 管理端 MVP 页面
mobile-uni/
src/pages/ # 员工端/候选人端/主管端当前页面
mobile/
src/App.vue # 旧 MVP 演示兜底
```
- 复用若依 `ruoyi-system` 的用户/角色/菜单/数据权限;自有后端 API 集中在 `ruoyi-aihr`,不要塞回上游 `ruoyi-demo`。
- 管理端 `frontend/` 不承载 `/h5/*`;当前用户侧通过 `mobile-uni/` + portless 启动,入口 `https://wygj-mobile-uni.localhost/h5/`,三端路由为 `/h5/#/pages/user/today/index`、`/h5/#/pages/candidate/index/index`、`/h5/#/pages/supervisor/index/index`;旧 `/h5/user`、`/h5/candidate`、`/h5/supervisor` 仅做兼容重定向。
- AI 能力先在 `ruoyi-aihr` 内提供统一接口(对话/评分/转写/生成),便于切换厂商与兜底;后续可按模块拆分。
- 可借助已有的 "codex 若依组件生成 skill" 批量生成 CRUD 骨架。
---
## 2. 系统模块总览
| 模块 | 归属 | 一期优先级 |
|---|---|---|
| M1 主数据与同步 | 支撑 | P0 |
| M2 权限与数据范围 | 支撑 | P0 |
| M3 招聘面试(选) | 业务 | P0(英雄路径A) |
| M4 上岗/SOP/培训(用) | 业务 | P1 |
| M5 对练/训练(育) | 业务 | P0(英雄路径核心) |
| M6 能力/认证/激励(留) | 业务 | P1 |
| M7 知识库/案例库(贯穿) | 业务 | P0(RAG+案例A) |
| M8 治理/版本/审核 | 支撑 | P1 |
| M9 AI 适配层 | 支撑 | P0 |
| M10 管理驾驶舱/报表 | 分析 | P1 |
| M11 数字师傅 Agent | 业务编排 | v2.0 兼容路径仍在;v2.1 Grounded 运行时已在生产有限 ACTIVE,认证态专项回归和人工黄金集仍待完成 |
---
## 3. 数据模型
> 命名:表 snake_case;主键 `id` bigint;外部主体统一引用 `ext_party_id`;审计字段 `create_by/create_time/update_by/update_time/del_flag`(若依标准)省略未列。有效期用 `from_date/thru_date`。
### 3.1 M1 主数据与同步(P0)
| 表 | 关键字段 | 归属 | 优先级 |
|---|---|---|---|
| `sync_person`(人员快照) | id, ext_party_id(唯一), name, phone, org_unit_id, position_code, status, sync_batch_id | 外部同步只读 | P0 |
| `sync_org_unit`(组织树) | id, ext_org_id(唯一), parent_ext_org_id, org_name, org_type(集团/公司/项目), project_type(住宅/公建/景区) | 外部同步只读 | P0 |
| `sync_batch`(同步批次) | id, source, mode(full/incr), started_at, finished_at, row_count, status | 本地 | P0 |
| `employment_termination`(雇用终止,对齐卷1「雇用终止」;留存/流失分析) | id, ext_party_id, term_date, term_reason, from_sync | 外部同步/本地 | P1 |
- **候选人不进 sync_person**,见 3.3 `candidate`。
- 离职/调岗优先用 `sync_person.status` + 有效期承接;`employment_termination` 承载显式离职历史。
### 3.2 M2 权限与数据范围(P0)
| 表 | 关键字段 | 优先级 |
|---|---|---|
| `party_role`(本地角色) | id, ext_party_id, role_code(学员/师父/教练/考官/审核员/管理员/HR/面试官), scope_project_ext_org_id, from_date, thru_date | P0 |
| `role_perm_mapping`(岗位/组织→角色映射) | id, match_type(position/org), match_value, role_code, project_scope | P0 |
| `sys_role/sys_menu`(若依内置) | 复用 | P0 |
- **数据范围以项目为主体**:业务表统一带 `project_ext_org_id`,数据权限按 `party_role.scope_project_ext_org_id` 过滤(套若依数据权限)。
### 3.3 M3 招聘面试(选)—— 英雄路径 A
| 表 | 关键字段 | 优先级 |
|---|---|---|
| `candidate`(候选人) | id, name, phone, apply_position_code, project_ext_org_id, source, status, hired_ext_party_id(入职后挂钩) | P0 |
| `aihr_candidate_material`(候选人补充资料) | id, candidate_id, candidate_name, material_type, file_name, file_size, content_type, oss_id, status, create_time | P0 |
| `job_requisition`(招聘需求) | id, position_code, project_ext_org_id, headcount, jd_text, status | P1 |
| `interview_session`(面试记录) | id, candidate_id, position_code, mode(voice/text), total_score, ai_summary, status, started_at | P0 |
| `interview_question`(面试题) | id, session_id, seq, question_text, gen_source(ai/manual), reference_point | P0 |
| `interview_answer`(作答+打分) | id, question_id, answer_text, answer_audio_url, score, dimension_json, ai_comment | P0 |
### 3.4 M4 上岗 / SOP / 培训(用)
| 表 | 关键字段 | 优先级 |
|---|---|---|
| `position_responsibility`(职位职责,对齐卷1「职位职责」;SOP 挂载点) | id, position_code, responsibility_text, sop_id | P1 |
| `sop_category`(SOP 多层分类) | id, parent_id, level(大类/中类/小类/行业), name, code | P1(结构 P0 预留) |
| `sop`(SOP 主表) | id, category_id, title, content, version, status, project_type | P1 |
| `sop_applicability`(适用范围) | id, sop_id, project_type, industry, org_scope | P1 |
| `onboard_task`(培训任务) | id, ext_party_id, sop_id/course_id, type(岗前/入职), status, assign_by | P1 |
| `course` / `course_enrollment` | id, title, type, ...; id, course_id, ext_party_id, progress, status | P1 |
| `qualification_gate`(上岗资格) | id, ext_party_id, position_code, cert_id, passed, valid_thru | P1 |
### 3.5 M5 对练 / 训练(育)—— 核心
| 表 | 关键字段 | 优先级 |
|---|---|---|
| `practice_scenario`(对练场景/AI客户人设) | id, scenario_type(投诉/催费/推介/应急), title, persona_json(五维人设), difficulty, sop_ref, rubric_id, project_type | P0 |
| `practice_session`(对练记录) | id, ext_party_id, scenario_id, mode(voice/text), total_score, trust_curve_json, status, started_at | P0 |
| `practice_turn`(逐轮对话) | id, session_id, seq, role(customer/trainee/coach), text, audio_url, emotion, coach_hint | P0 |
| `practice_score`(五维评分) | id, session_id, dim_compliance, dim_emotion, dim_communication, dim_marketing, mentor_rewrite, ai_comment | P0 |
| `daily_drill`(每日一练) | id, ext_party_id, scenario_id, date, score, status | P1 |
| `training_camp`(专项训练营) | id, title, theme, days, scenario_ids | P1 |
| `mistake_book`(错题本) | id, ext_party_id, session_id, cause(知识盲区/话术不当), fix_scenario_id | P1 |
| `mentor_assignment`(师徒指派) | id, mentor_ext_party_id, apprentice_ext_party_id, scenario_id, status | P1 |
### 3.6 M6 能力 / 认证 / Rubric / 激励(留)
| 表 | 关键字段 | 优先级 |
|---|---|---|
| `rubric`(评分标准) | id, name, scenario_type, status, version | P0(单条内置) |
| `rubric_dimension`(维度+权重) | id, rubric_id, dim_code, dim_name, weight, key_indicators | P0 |
| `performance_review`(雇员绩效,对齐卷1「雇员表现」;绩效关联锚点) | id, ext_party_id, period, review_type(月度/季度考核), source(training/manual), overall_score, dimension_json, reviewer | P1 |
| `competency_assessment`(能力评估/雷达图,绩效的可视化扩展) | id, ext_party_id, period, dim_scores_json, radar_snapshot | P1 |
| `competency_dim_config`(五维权重配置) | id, dim_code(任务完成/话术规范/情绪管理/响应时效/增值转化), weight | P1 |
| `certification` / `cert_rule`(认证/规则) | id, ext_party_id, level(初/中/高), ...; id, level, condition_json | P1 |
| `incentive_point` / `badge`(积分/勋章) | id, ext_party_id, points, source; id, code, name | P1 |
### 3.7 M7 知识库 / 案例库(贯穿)—— 含英雄路径 B
| 表 | 关键字段 | 优先级 |
|---|---|---|
| `aihr_knowledge_info`(知识库元数据) | id, tenant_id, name, description, retrieve_limit, enable_hybrid, system_prompt | P0 已落 |
| `aihr_knowledge_attach`(知识库附件/文档) | id, knowledge_id, doc_id, name, type, status | P0 已落,支持同名上传替换 |
| `aihr_knowledge_fragment`(知识片段) | id, knowledge_id, doc_id, idx, content, embedding_json, embedding_model, embedding_time, FULLTEXT(content) | P0 已落,txt/md/PDF/Word/Excel/PPT 可解析入库,可写 embedding;Qdrant 只存向量索引和最小 payload |
| `case`(案例主表,脱敏) | id, title, raw_audio_url, transcript, ai_summary, curated(是否入选), project_ext_org_id, status | P0 |
| `case_tag`(多维标签) | id, case_id, dim(业务类型/紧急/业主画像/情绪/渠道), value | P1 |
| `case_video`(案例视频/样片) | id, case_id, video_url, is_sample | P1(MVP样片) |
### 3.8 M8/M9 治理 · 版本 · 集成日志
| 表 | 关键字段 | 优先级 |
|---|---|---|
| `review_task`(审核任务) | id, target_type(case/knowledge/话术), target_id, reviewer, status, decision | P1 |
| `content_version`(版本留痕) | id, target_type, target_id, version, diff, change_by | P1 |
| `llm_call_log`(大模型调用/成本) | id, module, model, tokens_in, tokens_out, cost, latency_ms, created_at | P1(成本闸门G6) |
| `asr_config`(语音配置) | id, vendor, dialect, endpoint, enabled | P0 |
| `aihr_agent_run`(Agent 最小运行审计) | run_id, tenant_id, client_key, user_id, conversation_id, context_version, intent, tool, status, source_type, duration_ms, error_code, result_ref | 本地已落;不保存原始问题、答案、附件或模型推理 |
---
## 4. 页面与路由清单(前端)
> `P0` 页面需真跑通或壳可点开;英雄路径页面必须真跑通。
| 路由 | 页面 | 优先级 |
|---|---|---|
| `/login` | 本地登录 | P0 |
| `/index` | 首页/管理驾驶舱(壳) | P0壳 |
| `/recruit/interview` | **AI 面试(英雄路径A:出题→作答→打分)** | P0跑通 |
| `/recruit/candidates` | 候选人列表 | P1 |
| `/train/practice` | **三角色对练(英雄路径核心)** | P0跑通 |
| `/h5/#/pages/user/today/index` | 员工端首页,手机号登录后可“开始训练”并同步主管待复盘计数;旧 `/h5/user` 兼容重定向 | P0跑通 |
| `/h5/#/pages/candidate/index/index` | 候选人端首页,手机号登录后可面试练习、查岗位 SOP/案例、上传补充资料;旧 `/h5/candidate` 兼容重定向 | P0跑通 |
| `/h5/#/pages/supervisor/index/index` | 主管端首页,查看团队、待复盘、案例/SOP 工具;旧 `/h5/supervisor` 兼容重定向 | P0跑通 |
| `/h5/#/pages/user/sop/index` | 问·数字师傅 Agent;文字、语音、图片/视频自动路由知识、训练、待办、记忆、媒体或全网工具,项目按名称选择 | Agent 已部署;正式账号完整业务/真机验收未完成 |
| `/h5/#/pages/user/work-results/index` | 员工工作成果;按员工、项目、自然日汇总确认记录和待跟进 | 2026-07-22 已发布历史日期选择与未来日期拒绝 |
| `/h5/#/pages/supervisor/work-results/index` | 主管项目成果;按目标项目权限查看员工成果和高优问题 | 2026-07-22 已发布历史日期选择与手机号授权兜底 |
| `/h5/#/pages/user/report/index` | 员工成果投稿;复用「问」的微信式语音会话,AI 整理确认后提交既有审核链 | 会话式页面和接口已部署;本地界面已正式改名;项目归属和媒体内容理解未实现 |
| `/train/daily` | 每日一练 | P1 |
| `/train/camp` | 专项训练营 | P1 |
| `/train/mistakes` | 错题本 | P1 |
| `/knowledge/sop` | SOP 库(住宅类检索→引用→训练题) | P0跑通 |
| `/knowledge/cases` | **案例库(英雄路径B:语音上传→整理)** | P0跑通 |
| `/knowledge/processing` | 资料处理(解析状态、处理链路、多文件/ZIP 批量导入) | P1已提前落地 |
| `/system/model` | 模型配置(供应商 Key/Base URL/模型启停/测试、向量库状态与重建) | P1已提前落地 |
| `/competency/radar` | 能力雷达图 | P1 |
| `/competency/cert` | 认证/激励 | P1 |
| `/onboard/tasks` | 上岗培训任务 | P1 |
| `/admin/*` | 权限/角色/同步/Rubric 配置 | P0壳 |
---
## 5. API 契约
> 统一响应信封:`{ code, msg, data }`(若依风格)。以下英雄路径详写,其余按 CRUD 惯例。
> 当前本地 MVP 先用 API + fallback 跑通 `/recruit/interview`、`/train/practice`、`/knowledge/cases`、`/knowledge/sop` 页面流;SOP 知识库已接 `aihr_knowledge_fragment` MySQL Fulltext 检索、Qdrant 向量召回、txt/md/PDF/Word/Excel/PPT 上传解析和 embedding 写入。
> API 对接顺序见 `docs/API_INTEGRATION.md`;面试、对练、案例仍以 seed service 为主,SOP/模型配置已建最小表。
### 5.1 英雄路径 A:AI 面试(P0)
```
POST /api/recruit/interview/start
req: { candidateId, positionCode, mode }
resp: { sessionId, questions:[{questionId, seq, questionText}] } // AI 依岗位出题
POST /api/recruit/interview/answer
req: { questionId, answerText? , answerAudioUrl? } // 语音先经 5.4 转写
resp: { score, dimensions:{...}, aiComment }
POST /api/recruit/interview/finish
req: { sessionId }
resp: { totalScore, aiSummary, records:[...] }
POST /api/aihr/mobile/candidate/materials
req: multipart file + candidateId + candidateName + materialType
resp: { id, ossId, fileName, materialType, fileSize, status, time }
GET /api/aihr/mobile/candidate/materials?candidateId=
resp: [{ id, ossId, fileName, materialType, fileSize, status, time }]
GET /api/aihr/hr/candidate/materials?status=
resp: [{ id, candidateId, candidateName, ossId, fileName, materialType, fileSize, status, time }]
POST /api/aihr/hr/candidate/materials/{id}/review
req: { status } // 待审核 / 已通过 / 已驳回
resp: { id, candidateId, candidateName, ossId, fileName, materialType, fileSize, status, time }
```
候选资料上传使用移动端登录返回的 `Authorization` 与 `clientid`;文件先经 `sys_oss`/MinIO 持久化,再写 `aihr_candidate_material` 关系行,默认状态 `待审核`。
### 5.2 英雄路径核心:三角色对练(P0)
```
POST /api/train/practice/start
req: { extPartyId, scenarioId, mode }
resp: { sessionId, opening:{ customerText, customerAudioUrl }, persona } // AI客户开场
POST /api/train/practice/turn
req: { sessionId, traineeText? , traineeAudioUrl? }
resp: { customerText, customerAudioUrl, emotion, trust, coachHint? } // 客户回应+教练微提示
POST /api/train/practice/finish
req: { sessionId }
resp: { score:{ compliance, emotion, communication, marketing }, mentorRewrite, aiComment, trustCurve } // 考官评分
```
移动端员工训练闭环复用同一组三角色对练接口。员工端请求必须带手机号登录返回的 `Authorization` 与 `clientid`,`start` 传 `mode=mobile`;`finish` 后写入 `aihr_practice_session`,并刷新 `/api/aihr/mobile/home/supervisor` 的完训人数与“待复盘对练”计数。员工端训练历史查 `GET /api/aihr/mobile/practice/history`,主管端复盘列表查 `GET /api/aihr/mobile/practice/reviews`,复盘详情查 `GET /api/aihr/mobile/practice/reviews/{id}`,标记已复盘用 `POST /api/aihr/mobile/practice/reviews/{id}/reviewed`,能力画像查 `GET /api/aihr/mobile/profile`。当前只落 session 汇总表,并用 `dialogue_json` 保存本场话术;不拆 `practice_turn/practice_score`,需要逐轮复盘明细、人工点评留痕或多次复盘记录时再拆表。
### 5.3 英雄路径 B:案例语音上传→整理(P0)
```
POST /api/knowledge/case/upload req: { audioFile, projectExtOrgId } resp: { caseId, transcript }
POST /api/knowledge/case/organize req: { caseId } resp: { aiSummary, tags[] }
POST /api/knowledge/case/curate req: { criteria, limit } resp: { selectedCaseIds[] } // 从多案例筛选
```
#### 5.3.1 成果投稿会话化交互
实现基准:[work-report-voice-conversation-v1.png](prototypes/work-report-voice-conversation-v1.png)。当前页面、整理接口、附件上传、幂等提交和“我的投稿”已经存在;该图用于视觉回归,不再作为待开发 Prompt。安全、权限、长度校验和审核状态以本 TechSpec 与后端契约为准。
员工端 `mobile-uni/src/pages/user/report/index.vue` 已复用现有 `ChatComposer` 和「问」页消息语言,不再让四类选择、标题和说明字段占据首屏。后台仍使用 `aihr_work_report` 及现有审核链,避免为视觉改版复制数据模型。
当前能力边界:附件可以上传并随正式记录保存,但成果投稿 `organize` 只根据员工文字/ASR 转写、草稿和附件名称整理,附件名称是不可信元数据;该审核链没有对图片或视频内容做视觉理解。不得把“支持发照片/视频”描述成“AI 已看懂现场”。现场媒体理解、确认记录来源绑定与日报追溯由工作助手 `/api/knowledge/query-media` 和 `aihr_assistant_capture` 链路承担,不能反向冒充成果投稿已具备视觉理解。
```text
进入成果投稿
→ 默认语音模式,可切换键盘或添加图片/视频
→ ASR 转写进入当前页面草稿
→ AI 从自然表达推断 CASE / VIDEO / SOP / KNOWLEDGE
→ 信息不足时只追问必要字段
→ 返回可编辑确认卡
→ 用户点击“确认投稿”
→ POST /api/aihr/work-report/reports
→ 返回 PENDING,并在会话与“我的投稿”中展示审核状态
```
最小接口策略:附件继续复用 `POST /api/aihr/work-report/attachment`,正式提交继续复用 `POST /api/aihr/work-report/reports`,历史继续复用 `GET /api/aihr/work-report/reports/mine`。只增加一个无状态整理接口,不新增草稿表或第二套会话表:
```text
POST /api/aihr/work-report/organize
req: { transcript, currentDraft?, attachmentOssId?, attachmentName? }
resp: { suggestedType, title, content, missingQuestions[], privacyWarnings[], confidence }
```
- `organize` 只返回结构化草稿,不得写 `aihr_work_report`;页面刷新前草稿保存在前端当前会话状态,只有确认后的正式记录持久化。
- 类型由 AI 建议但必须允许员工修改;`VIDEO` 仍由后端校验视频附件,标题和说明长度继续执行现有边界。
- 语音、文字和附件输入复用 `mobile-uni/src/components/chat/ChatComposer.vue`、`services/speech.ts` 与现有上传接口,不新增录音框架。
- 住户敏感信息应在确认卡中提示脱敏;提交、附件读取、我的上报与审核接口继续从登录态解析租户和用户,不接受客户端伪造提交人。
- 审核通过不自动写案例库或企业知识库;运营最终入库沿用现有人工流程。
#### 5.3.2 高保真评审实施细则
设计图用于确定结构和视觉方向,代码实现必须吸收以下评审修订,不得逐像素复制图中的矛盾文案:
1. **语音与文字状态唯一**
- 用户语音经 ASR 后始终显示带“语音转文字”标记的文字气泡。
- 师傅短追问直接显示文字,并在气泡内提供播放按钮;此时不显示“转文字”。
- 师傅长回答默认显示语音条,正文折叠;按钮状态只能在“转文字 / 收起文字”之间切换。
2. **分类可确认**
- `organize` 返回 `suggestedType`,确认卡展示“建议类型:{typeLabel}”和修改入口。
- `POST /reports` 使用员工最后确认的 `type`,不得直接使用模型建议值提交。
3. **脱敏提示必须真实**
- `privacyWarnings` 只描述检测结果,不代表系统已经完成脱敏。
- P0 若没有服务端脱敏能力,提示“检测到具体房号,请修改后再提交”,用户修改后确认卡重新展示最终提交文本。
- 只有服务端确实生成脱敏内容、且确认卡展示的就是该提交内容时,才允许出现“已隐藏”或自动脱敏开关。
4. **补充入口唯一**
- 确认卡只保留“修改 / 确认上报”;底部 `ChatComposer` 继续承担语音、文字和附件补充。
- 不同时展示“继续补充”按钮和可用的底部输入栏;需要引导时只显示弱提示“还可以继续说话补充”。
视觉与交互验收:
- 在 390×844 视口下,确认卡可滚动且底部输入栏不遮挡“修改 / 确认上报”。
- 页面不存在“文字追问已展开但按钮仍写转文字”的状态。
- 类型标签包含“建议类型”语义并可修改,确认提交请求使用修改后的类型。
- 未实现服务端脱敏时,页面不得出现“提交后将自动隐藏具体房号”等承诺性文案。
- 页面只有一个继续补充入口;确认提交后返回 `PENDING` 状态卡并可从“我的上报”查到同一记录。
术语边界:本节的 CASE / VIDEO / SOP / KNOWLEDGE 属于成果投稿审核链;工作助手中的晨会、巡检、业主服务、画像、线索和待跟进事项属于 `aihr_assistant_capture`,两者不得自动互写。工作助手只能提出投稿建议,员工再次确认后才能创建 `aihr_work_report`。
### 5.4 AI 适配层(P0)
```
POST /api/ai/chat req:{ system, messages, model? } resp:{ text, usage }
POST /api/ai/asr req:{ audioUrl, dialect } resp:{ text }
POST /api/ai/tts req:{ text, voice } resp:{ audioUrl }
POST /api/ai/score req:{ rubricId, dialogue } resp:{ dimensions, comment }
```
### 5.5 支撑接口
- 同步:`POST /api/sync/pull`(拉取组织人员,MVP 可读快照文件)
- 知识检索(RAG):`POST /api/knowledge/search` → `{ queryText, category, answer, reference, docs[], snippets[], training[], records[] }`
- 知识上传解析:`POST /api/knowledge/doc/upload` → `multipart/form-data { file, category }`,支持 `.txt/.md/.markdown/.pdf/.doc/.docx/.xls/.xlsx/.ppt/.pptx`、100MB 内;先落 `sys_oss` 并绑定 `aihr_knowledge_attach.oss_id`,返回 `{ docId, ossId, fileName, category, fragments, snippets[] }`;管理端上传请求 timeout 为 180s。
- 服务端目录导入:`POST /api/knowledge/doc/import-local-task` → `{ directory, category, limit }`,只允许读取 `AIHR_IMPORT_ROOT` / `aihr.import.root` 下的相对目录,写入后台导入任务并逐文件复用上传解析链路;`GET /api/knowledge/doc/import-tasks` 返回任务进度列表;`POST /api/knowledge/doc/import-tasks/{id}/cancel` 取消运行中任务;`POST /api/knowledge/doc/import-local` 保留同步调试。这组接口仅供运维/调试,不在 `/knowledge/processing` 页面暴露。
- 资料处理状态:`GET /api/knowledge/processing/overview` → 聚合附件状态、片段数、向量化状态、分类、处理链路和事件列表。
- 片段向量化:同一上传接口在 `category=vector` 模型配置可用时调用 OpenAI-compatible `/embeddings`,写入 `embedding_json/embedding_model/embedding_time`,并尽力 upsert 到 Qdrant;未配置或 Qdrant 不可用不阻塞上传。
- 向量库状态与重建:`GET /api/knowledge/doc/vector-index-status` 返回当前 vector 模型维度、Qdrant collection 维度、点数和片段向量数;`POST /api/knowledge/doc/rebuild-vector-index` 清空旧 embedding、删除 collection,并按当前 vector 模型重建。外部 embedding 成功但 Qdrant 维度不一致时不降级为本地 hash。
- 混合检索:`POST /api/knowledge/search` 先查 MySQL Fulltext,同时在 vector 模型和 Qdrant 可用时生成 query embedding 走 Qdrant,最后按 RRF 融合并回 MySQL hydrate 片段;Qdrant 不存正文事实源。
- Rubric 配置:`/api/competency/rubric/**` CRUD
### 5.6 数字师傅 Agent
```text
POST /api/aihr/agent/messages
POST /api/aihr/agent/messages/media
POST /api/aihr/agent/actions/{draftId}/confirm
POST /api/aihr/agent/actions/{draftId}/dismiss
```
- 文字请求只接受 `question`、短会话版本、当前项目、大喇叭消息引用和明确的外发同意;`question` 去空白后必填且不超过 1000 字。multipart 请求只增加当次附件,不接受客户端身份、角色、工具名、知识空间 ID 或任意 URL。
- Planner 只输出已知 `intent/tool`;服务端固定策略按认证主体与角色授权,领域工具再次校验项目、会话和资源。寒暄/澄清不调用 RAG;普通图片只做当次媒体分析,明确制度/流程问题才补充授权知识。
- 响应状态限定为 `COMPLETED/NEEDS_INPUT/NEEDS_CONFIRMATION/NO_EVIDENCE/FORBIDDEN/UNAVAILABLE/FAILED`,并分别返回来源、引用、资源、数据、动作草稿或澄清字段;客户端不得从回答文本猜按钮或业务状态。
- 全网工具必须先取得用户本次明确同意;写入只通过 30 分钟有效的 `draftId` 确认/忽略,并复用领域服务的 `expectedVersion + idempotencyKey + saveScope`。`aihr_agent_run` 只记录最小路由元数据。
- 旧 `/api/knowledge/query`、`query-media` 和 `/api/aihr/web-ai/**` 保留为底层/兼容接口。完整请求示例、错误码和当前发布边界见 [API_INTEGRATION.md](API_INTEGRATION.md)。
2026-08-04 的 Grounded Agent 增量不改变以上 HTTP DTO 契约:新 `SemanticQueryPlan`、Tool Registry、Evidence Evaluator、DecisionResult 和 Grounded Composer 已在文本请求中串联。生产 `ACTIVE` 只接管符合计划、授权和证据门禁的 `KNOWLEDGE_QA`、`LIVE_MY_WORK`;媒体/附件请求跳过,工具失败或不支持的计划回退 v2.0 Orchestrator。仓库默认 `OFF`,认证态用户逐例验证、客户端状态契约全量验收、真实依赖召回评测和人工黄金集仍是后续门禁,不得把有限 ACTIVE 推断为全量 Agent 正式验收。
---
## 6. 核心自建组件规格(无框架可复用,最关键)
> **本章 v1.2 已按 Codex 设计评审重写**:核心原则——P0 做「确定性会话编排 + 单 LLM 结构化评估」,P1 再上多模型融合与后台配置。三角色对外表现为 AI客户/AI教练/AI考官,内部先做成**一个后端编排器**,少写代码跑通演示闭环。
### 6.1 三角色对练状态机
**状态(含异常/终止,不只 happy path)**:
```
INIT → WAITING_INPUT → PROCESSING → WAITING_INPUT(loop) → FINISHED
↘ CANCELED / EXPIRED / FAILED
```
- `finish_reason ∈ {completed, user_exit, max_turns, timeout, error}`(结束原因用枚举,不为每种情况新增状态类)。
- **固定 `max_turns = 4~6`**;满足任一即结束:用户点"结束并评分"、达最大轮次、客户诉求解决、超时。前端必须有"结束并评分"按钮。
**每轮 turn 生成顺序(固定,不可乱)**:
```
收学员输入 → COACH_CHECK(卡壳/偏差判定) → 更新 trust/emotion → 生成客户下一句 + coachHint → 写 practice_turn
```
> ⚠️ **每轮只做轻量 checker + 客户回应,不跑完整评分**;评分只在 `/finish` 一次性做(见 6.3)。
**COACH_CHECK 工程化判定**:
- **卡壳 = 规则判定**(P0,不上模型):空输入 / 超时 / 过短句 / 重复"不知道·嗯" / ASR 失败。
- **流程偏差 = LLM checker**:输出 `{ needHint, reasonCode, missingSopIds, hint }`。P0 不上语义相似模型。
**信任度闭环**:每轮只更新一次 `trust = clamp(trust + delta, 0, 1)`,`delta ∈ [-0.15, 0.15]` 来自 checker JSON。**传给客户 prompt 的是"低/中/高信任"档位,不传裸浮点**(更稳)。
### 6.2 AI 客户人设(persona_json)
> 在五维基础上,**补场景收口与信息边界字段**,否则 AI 客户会自曝隐性动机或替管家解决问题。
```json
{
"basic": { "identity":"独居退休教师", "relation":"子女在国外", "environment":"楼上噪音困扰" },
"style": { "trait":"急躁/温和", "language_fingerprint":"说话慢、爱重复、爱反问" },
"motive": { "explicit":"咨询停车费", "hidden":"投诉邻居乱停、试探物业态度", "logic":"" },
"cognition":{ "knows":[], "unknowns":[], "bias":"认为物业只收钱不办事" },
"dynamic": { "init_emotion":"烦躁", "triggers":{"anger":"被敷衍","pleased":"被重视"}, "trust_init":0.3 },
"opening": "开场第一句业主话",
"success_condition": "本场诉求被满足的判定",
"forbidden_reveal": ["隐性动机不得主动自曝", "信任<中 不透露真实诉求"],
"escalation_triggers":["被敷衍→升级愤怒"],
"allowed_facts": ["仅可引用的事实/SOP要点ID"],
"max_turns": 6
}
```
### 6.3 评分引擎(分层:P0 单 LLM / P1 融合)
**⚠️ 澄清两套评分(此前易被当成矛盾)**:
- **单场对练评分(每场一次)**:4 维 —— 合规与完整度、情感应变力、沟通有效性、营销敏感性;外加**导师润色版**(不是评分维度,是话术重写对比)。
- **能力画像(跨期加权,BRD 4.5)**:5 维加权 —— 任务完成度40% / 话术规范性25% / 情绪管理20% / 响应时效10% / 增值转化5%。**由多场对练评分聚合而来,不是同一层。**
**P0(2026-07-05 MVP 演示):单 LLM 考官一次性出结构化分**
- 输入 `dialogue + rubric + sop_points + persona`,输出固定 JSON;**不做多模型融合**。
- **防漂移**:固定模型 + `temperature=0` + 固定 `prompt_version`;首次评分后**缓存 `practice_score`,刷新不重算**;分数用**档位锚点 60/75/90** 减少小数漂移。
- **可验收的可解释**:JSON 必带证据 —— `evidence_turn_ids`、`hit_sop_point_ids`、`missed_sop_point_ids`、`rewrite_before/after`;无证据的理由不展示。
- Rubric:P0 用**一条内置 seed JSON**;后台 CRUD 只做壳。
**P1(一期):再拆多模型融合**
- SOP 关键点覆盖检测 + 语义相似 + 情感/语音特征融合;Rubric 后台可配置 + 版本 + 启停;一致率校准集 + 人工评审流程。
**一致率验收口径**:`≥70%` 指**分档一致**(非原始分一致),档位建议 `<60 / 60–74 / 75–89 / ≥90`,用 ≥20 段样本对人工基准评估——**是一期目标,不是 2026-07-05 MVP 演示目标**;2026-07-05 只验端到端 + 结构化输出。
### 6.4 Prompt 规格(实际入 `hr-ai` 模板库,均需后端兜底)
- **AI 客户**(system prompt 强约束 + 2 个 few-shot):`你只扮演业主本人,只输出一句业主的话。禁止:提及系统/人设/评分/SOP;替管家给解决方案;主动自曝隐性诉求(仅当信任度达"高"或被直接问到才可透露)。保持 language_fingerprint。当前情绪={emotion},信任={低/中/高}。`
- **AI 教练**(后端强制):`对照 SOP 关键步骤 {sop_points} 与学员本轮 {trainee_text}。仅当卡壳或漏关键步骤时,返回一句 ≤20 字的方向性提示(如"先安抚,再确认诉求"),不得给具体答案;否则返回空。` → **后端 schema 校验:超 20 字重试一次,再失败用固定兜底提示。**
- **AI 考官**(模型原生 structured output):字段固定 `{ dimensions[], total, mentorRewrite, summary, risks, evidence_turn_ids, hit_sop_point_ids, missed_sop_point_ids, unsupported_claims }`;**禁 markdown 代码块**;解析失败只重试一次,再返回兜底分。
- **面试出题**:`应聘岗位 {position},生成 {n} 道结构化面试题,含考察点 reference_point。`
- **案例整理**:`将转写 {transcript} 整理为 背景/处理/结果/亮点;脱敏业主个人信息;打多维标签(业务类型/紧急/业主画像/情绪/渠道)。`
- **RAG 硬约束(控幻觉)**:prompt 传 `sop_context`(带 ID);**未命中的政策/金额/时限不得编造,只能说"需核实"**;考官只按给定 `sop_points` 判分,并输出 `unsupported_claims`。
### 6.5 三角色 P0 / P1 最小切分
- **P0(2026-07-05 MVP 演示必须)**:1 场景 × 1 人设 × 1 套 SOP × 1 套 rubric;**文本端到端先跑通**,语音作为外层 ASR/TTS,失败降级文本;`/start /turn /finish` 三接口闭环;每轮轻量 checker + 客户回应;`/finish` 单 LLM 出结构化分;固定 max_turns + 手动结束 + 评分缓存展示。
- **P1(一期)**:Rubric 后台配置与版本;SOP 覆盖/语义/情绪融合;一致率校准集 + 人工评审;多场景/多 persona/动态难度/错题本/能力画像沉淀;LLM 调用日志/成本/prompt 版本/失败重试。
---
## 7. 集成适配层
| 集成 | 接口/做法 | MVP 兜底 | 优先级 |
|---|---|---|---|
| 组织人员同步 | `hr-sync` 拉取采购系统 API → 写 `sync_*` | 读静态快照文件 | P0 |
| 登录/SSO | 管理端用若依本地账号;移动端用手机号短信登录,验证码通过后自动注册 `app_user` | SSO 不做 | P0(SSO=P2) |
| 权限映射 | `role_perm_mapping` 规则引擎 | 手工配置 | P0 |
| 大模型 | `hr-ai/chat` 封装公有 API | — | P0 |
| ASR/TTS | `hr-ai/asr,tts` 封装第三方(方言) | 1 家 1 条路径 | P0 |
| 视频生成 | 案例视频 | 预渲染样片 | P1(样片P0) |
| 企微/钉钉/工单 | 只留接口占位 | 不实现 | P2 |
---
## 8. 权限与数据范围
- 认证:管理端使用若依本地账号;移动端使用短信验证码登录,不存在的手机号自动注册 `app_user`;SSO 预留 `hr-sync` 对接点(P2)。
- 授权:`role_perm_mapping` 把外部岗位/组织映射到本地 `role_code`。
- **数据范围以项目为主体**:所有业务查询套若依数据权限,按 `party_role.scope_project_ext_org_id` 过滤;主管只见本项目数据。
---
## 9. 非功能与部署
- 部署:集中式,前后端分离,单实例起步;**不承诺高并发**(明确)。
- 性能目标:语音对练单轮响应 ≤ 5 秒(ASR+LLM+评分)。
- 合规(生产前闸门,非一期功能):业主 PII + 员工数据 脱敏/审计;大模型出境评估(G3/G6);AI 分辅助参考不决定绩效/招聘(G1/G2)。
- 成本:`llm_call_log` 记录用量,设月度上限与降级策略(G6)。
---
## 10. 实现优先级与里程碑(对齐 MVP 切割线 / 施工单)
### 10.1 P0(2026-07-05 MVP 演示必需)
- 工程骨架 + 本地登录 + 数据权限(M1/M2)
- AI 适配层:chat / asr / tts / score(M9)
- 英雄路径至少 1 条真跑通:**A 面试打分** 或 **对练** 或 **B 案例整理**(建议至少含对练或面试)
- 住宅类 SOP 入库 + RAG 检索(M7 P0 表)
- 案例语音上传→整理(可与对练二选一精做)
- 全功能点前端壳可点开
- 组织人员快照 + Rubric 单条内置
### 10.2 P1(一期)
- M4 上岗/SOP 多层分类完整、M6 能力雷达+认证+激励、M5 每日一练/训练营/错题/师徒、M7 标签/视频、M8 审核/版本、M10 驾驶舱、`llm_call_log` 成本。
### 10.3 P2(二期)
- 知识图谱(Neo4j)、原生 APP、玉溪 Agent 化、企微/钉钉深度集成、SSO、实时同步、多项目类型(公建/景区)。
---
## 附录:表 → 模块 → 优先级速查
| 优先级 | 表 |
|---|---|
| P0 | sync_person, sync_org_unit, sync_batch, party_role, role_perm_mapping, candidate, aihr_candidate_material, interview_session, interview_question, interview_answer, practice_scenario, practice_session, practice_turn, practice_score, rubric, rubric_dimension, knowledge_doc, knowledge_chunk, case, asr_config |
| P1 | job_requisition, sop_category, sop, sop_applicability, onboard_task, course, course_enrollment, qualification_gate, daily_drill, training_camp, mistake_book, mentor_assignment, competency_assessment, competency_dim_config, certification, cert_rule, incentive_point, badge, case_tag, case_video, review_task, content_version, llm_call_log |
| P2 | 知识图谱相关、SSO、企微/钉钉集成表 |
> 说明:字段清单为落地起点,DDL(主外键、唯一约束、索引、导入顺序)可据此一键生成;三角色/评分/Prompt 为核心自建,严格按第 6 章实现。
---
## 附录 D:卷1 第9章 HR 主干实体对照与补全
> 目的:把本 TechSpec 数据模型对齐《数据模型资源手册》卷1 第9章「人力资源模型」权威实体,诚实标注哪些是手册原生 backbone、哪些是本系统领域扩展、哪些手册有但一期不做。**依据:卷1笔记 §4.8 + 附录权威字典 v7 实测。**
### D.1 卷1 第9章 HR 权威实体全谱系(16 个 · 手册原文)
雇用 EMPLOYMENT · 职位 POSITION · 职位类型 POSITION TYPE · 职位职责 POSITION RESPONSIBILITY · 职位履行情况 POSITION FULFILLMENT · 职位状态 · 招聘组织 · 报告关系 · 工资级别 PAY GRADE · 支付历史 PAY HISTORY · 福利 BENEFIT · 工资册信息 PAYROLL · 求职申请 JOB APPLICATION · 雇员技能与资格 SKILL/QUALIFICATION · **雇员表现(绩效)PERFORMANCE REVIEW** · 雇用终止 TERMINATION
> 附录 v7 字典佐证(属性条数):EMPLOYMENT 102、POSITION 60、EMPLOYEE 60、BENEFIT 49、SKILL 28、TERMINATION 20、SALARY 8、PAY GRADE 6、QUALIFICATION 5、TRAINING 4、PAY HISTORY 4、PAYROLL 2。
### D.2 对照:手册实体 → TechSpec 表
| 卷1 HR 实体 | TechSpec 表 | 状态 |
|---|---|---|
| 雇用 / 职位履行 | `sync_person`(任职,外部同步) | ✅ 已覆盖 |
| 职位 / 职位类型 | `sync_person.position_code` + `sop_category` | ✅ |
| 职位职责 | `position_responsibility` | ➕ **本次补** |
| 报告关系 | `sync_org_unit`(组织树) | ✅ 同步 |
| 求职申请 JOB APPLICATION | `candidate` / `job_requisition` | ✅(命名已对齐) |
| 雇员技能 SKILL | `rubric`/`skill`/`competency_*` | ✅ |
| 资格 QUALIFICATION | `certification` / `cert_rule` | ✅ |
| **雇员表现(绩效)** | `performance_review` | ➕ **本次补(原缺!)** |
| 雇用终止 TERMINATION | `employment_termination` | ➕ **本次补** |
| 工资级别/支付历史/福利/工资册 | — | ⛔ **一期不做**(薪酬非本系统职责) |
### D.3 本系统的领域扩展(手册无,属 AI 陪练特有)
> **诚实更正**:此前口头曾说"面试记录/offer/课程/学习记录/考核/测评雷达图/认证 卷1 本来就有"——**部分说过头了**。手册 HR 章真正有的是:求职申请、技能、资格、**雇员表现(绩效)**、雇用终止。以下属**本系统领域扩展**,手册并无现成实体、也不应有,需自建:
- 面试 AI 出题/作答/打分(`interview_question`/`interview_answer`)——JOB APPLICATION 只到"申请",无 AI 面试评分
- 三角色对练 / 五维评分(`practice_*`)
- 课程 / 学习记录 / 每日一练 / 训练营 / 错题(`course`/`daily_drill`/…)——手册无 e-learning 模型
- 能力雷达图(`competency_assessment`)——「雇员表现」的可视化扩展
- 认证等级规则(`cert_rule`)——QUALIFICATION 的规则化扩展
### D.4 结论
- **补齐动作(v1.1 已落):** 新增 `performance_review`(绩效)、`position_responsibility`(职位职责)、`employment_termination`(雇用终止)三张 backbone 表;`candidate`/`skill`/`certification` 明确对齐手册 JOB APPLICATION / SKILL / QUALIFICATION。
- **绩效关联**(BRD 4.5 / 闸门 G1)由此有了正式锚点:训练/考核结果写入 `performance_review`,再挂钩(辅助参考,人可否决)。
- 薪酬/福利/工资册明确划出一期(本系统不承担 HR 薪酬)。
- 领域扩展表(对练/评分/课程/AI 面试)为**合法自建**,不因手册未收录而缺失。