# 物业行业 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` 双工具、证据/事实分型、有界执行、逐结论引用和结构化会话状态;现役 `/api/aihr/agent/**` 仍由 v2.0 路径生成用户可见响应,新运行时只在文本响应完成后以默认关闭的异步 SHADOW 旁路执行,未切流、未部署。详细契约见 [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 运行时仅本地影子验证,未切流 | --- ## 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 响应契约:新 `SemanticQueryPlan`、Tool Registry、Evidence Evaluator、DecisionResult 和 Grounded Composer 已在文本请求完成旧响应后通过异步 SHADOW 旁路串联,默认 `OFF`,其结果与失败均不进入客户端;媒体/附件请求跳过。只有完成真实模型/授权知识库回归、客户端状态契约和独立发布验收后,才能逐步接管 v2.0 Orchestrator;不得从旁路存在推断已切流或已部署。 --- ## 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 面试)为**合法自建**,不因手册未收录而缺失。