Back to skills
SKILL.md
Career Personality
ASecurity当用户提到MBTI、职业性格、性格测试或性格特征时调用本Skill,用于分析性格倾向及其在工作环境中的表现。
- 28 stars
- 0 votes
- 0 copies
- 4 views
- Added September 12, 2026
Security analysis
100/100Pro scans all 6 files and shows the line behind each finding
npx -y skills add ahang1598/doubao-workbuddy-qwenwork-skills --skill career-personality --agent claude-codeAre you the author of Career Personality?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/ahang1598-career-personality)---
name: career-personality
display_name: 职业性格测评
display_name_en: Career Personality Assessment
description: 当用户提到MBTI、职业性格、性格测试或性格特征时调用本Skill,用于分析性格倾向及其在工作环境中的表现。
description_zh: 结合MBTI等性格测评方法,分析用户的性格倾向、沟通方式、行为偏好与工作环境倾向。
description_en: Use when users mention MBTI, career personality, personality tests, or personality traits to analyze tendencies and workplace behaviors.
category: 15-Education
version: 2.1.0
author: 上海高顿教育科技有限公司
---
# MBTI 职业性格测评 Skill
## Overview
生成 MBTI 职业性格测评题目并计算结果,覆盖 4 对维度:
- EI:外倾(E) - 内倾(I)
- SN:实感(S) - 直觉(N)
- TF:思维(T) - 情感(F)
- JP:判断(J) - 知觉(P)
本测评共 44 题,每题二选一(A/B),每个选项归属一个维度字母。
8 个字母各均匀出现 11 次(共 88 个选项),保证 4 对维度的对称设计。
## When to Use This Skill
在以下场景触发本 skill:
- 用户明确说出“测MBTI”“做MBTI测试”“帮我测一下MBTI”“启动MBTI测评”这类完整指令
- 用户直接询问“我是什么MBTI”“生成我的MBTI人格报告”“帮我算我的MBTI类型”
- 用户主动提及“打开MBTI测评工具”“开始MBTI测评”
- 用户说“我要做人格测试,指定是MBTI的”“我想测MBTI的完整维度”
- 用户历史对话3轮内明确提过要做MBTI测评,当前轮次说“继续”“开始吧”“下一步”
- 用户直接发送“MBTI测评”“MBTI测试”作为唯一指令,无其他无关内容
在以下**边界场景**建议先与用户确认测评意图:用一句简短反问(例如"您是想做 44 题 MBTI 职业性格测评吗?"),用户明确确认后再启动测评流程。若当前对话模式不支持中途询问(如 Visualizer 一次性渲染 / 已直接加载题目卡片),按以下兜底规则处理:
- 同轮若还含其他无关任务(如"帮我查 MBTI,再做下测评"),不启动测评,等用户单独询问测评时再触发
- 用户连续两轮仍在同一边界场景徘徊且未明确确认,默认判定为非测评需求,按下方"When NOT to Use This Skill"处理,改用纯 MBTI 知识科普
- 7 类边界场景示例:
- 用户只单独发送"MBTI"三个字,没有后续补充任何内容
- 用户讨论某类MBTI人格特征后,说"我好像就是这种人""我感觉我符合这个类型"
- 用户说"我想了解自己的性格类型""帮我做个性格测试",没有明确指定是MBTI
- 用户说"我想看看我的人格是什么样的""分析一下我的性格",没有限定测评类型
- 用户提到"我朋友说我是XX型MBTI,想验证一下",没有直接说要启动测评
- 用户在讨论MBTI相关话题后,说"帮我测测看",没有明确指向其他测评工具
- 用户说"我想做个测试看看我适合什么MBTI类型",表述模糊未直接唤起测评
## 派生请求前置 gate(强制,先判别再走流程)
> **任何轮次触发本 skill 时,渲染任何 widget_code 之前,必须先回答下方 3 个判定问题。任一答案为"是",本轮即进入"派生请求"模式,必须按本节 4 步顺序执行完毕后才能继续走 §0/§R 渲染流程。**
**判定 3 问(命中任一即视为派生请求)**:
1. **触发词判定**:本轮用户消息是否包含下列任一触发词/语义?
- **重测类**:"再来一份 / 再出一份 / 给我一份 / 重置再来一遍 / 我想再做一遍 / 再来一次 / 重新测 / 重测 / 重新跑一遍"
- **复制类**:"朋友也要测 / 同事也来一套 / 给 朋友 / 同事 / 孩子 / 家属 也做一套 / 把上次的卡片给我 / 给我之前那份 / 之前那张卡 / 把卡片发我"
- **改样式类**:"换个 UI / 换个样式 / 试试别的风格 / 加个主题 / 改个颜色 / 美化一下 / 精简一下 / 适配一下主题 / 加点渐变 / 加个阴影 / 字号小一点 / 按钮大一点"
- **出报告类**(上一轮已发出卡片后):"出报告 / 算一下 / 看结果 / 跑分 / 评分 / 提交答案 / 把结果给我"
2. **会话上下文判定**:用户上一轮已收到本 skill 题目卡片或测评报告,本轮再次要求测评相关动作。
3. **轮次判定**:本对话流中 skill 已被加载 ≥ 2 次或题目卡片已被渲染 ≥ 2 次。
**派生请求进入后必须执行(强制,4 步顺序不可换)**:
1. **第一步(read 证据)**:`Read references/template.md` 并按 §T1/§T2 原样逐字符读取完整 HTML 模板;**禁止凭记忆渲染、禁止复制本对话上文已发出的 widget_code 当新产物**。
2. **第二步(数据替换)**:§T1 用 `Read references/questions.md` 解析出的题库 JSON 替换 `/*__QUESTIONS_JSON__*/`;§T2 用 `python scripts/calculate_mbti.py --display-answers <原样回传 JSON> --compact` 输出替换 `/*__REPORT_JSON__*/`(remap 与校验由脚本内置完成,见 §3.2.2,**禁止手写 remap**)。
3. **第三步(inline 自查)**:依次核对下方"前置 gate 自查"段 4 项(Read 证据 / 数据替换 / root ID / ID 后缀扫描),全部通过后方可输出 widget_code。
4. **第四步(byte-stable)**:禁止以"重测第二轮 / 朋友专用 / 主题调整"等任何理由对 widget_code 任何字符做出与首发不一致的修改(包括标题、分段文案、按钮文案、类名、颜色、字重、尺寸、圆角)。**除数据占位符外,每一个字符都必须与首发 byte-stable 一致**。
**前置 gate 的强度升级**:
- 第 119 行 "派生请求渲染约束(强制,禁止走捷径)" 段规则在派生场景下自动升级为**硬约束**——任何"复制上文 widget_code 然后改 ID 后缀"、"自绘一份卡片"行为一律按硬违规处理;禁止"参考上文""上次那么做""我没读到 template.md 但我记得差不多"等任何绕过说法。
- §7.禁止事项 段关于"提交按钮延迟出现""复制答案回传""先返部分题目再补全"等链路违反,一律按硬违规处理。
**前置 gate 自查(输出 widget_code 之前必查,否则禁止输出)**:
- [ ] **证据**:本对话流最近 5 条消息内必须出现至少 1 次 `Read references/template.md` 工具调用;不出现即视为走捷径,必须重新 Read 并重做。
- [ ] **数据替换**:题目卡片必然包含 4 个 `.q-sec` 提示词(段标题"第一部分 外倾-内倾(E/I)"等);测评报告必然以 `#mbti-rpt{...}` 为根 CSS。
- [ ] **root ID**:widget 首项 CSS 必须以 `#mbti-card{...}` 或 `#mbti-rpt{...}` 开头;出现 `.mbti-card{` / 自定义类名 / `<div id="app">` 即违规。
- [ ] **改 ID 后缀扫描**:widget 内(除数据占位符外的 `id=` / `class=` / `data-attr`)不出现 `-v2` / `-重测` / `-friend` / `-重做` / `-retest` / `-theme` 等任何派生后缀。
任一自查项不通过,必须**整体重做**——禁止"小修小补"伪装通过;禁止绕过 gate 单独走 §0.1 渲染流程。
## When NOT to Use This Skill
以下场景**不触发**本 skill:
- 用户仅询问MBTI基础科普:“MBTI有多少种类型”“MBTI的四个维度是什么”“MBTI的起源是什么”
- 用户仅查询某类MBTI人格的特征:“INTJ的特点是什么”“INFP适合什么职业”“ESTP的恋爱观”
- 用户讨论MBTI的非测评应用场景:“MBTI面试技巧”“用MBTI做职场沟通”“MBTI社交指南”
- 用户在讨论其他完全无关的话题时,偶然提到MBTI:“我昨天和朋友聊到MBTI”“我同事是ISFJ”
- 用户明确要求其他类型的测试:“我要做九型人格测试”“帮我测DISC性格”“生成霍兰德职业测试”
- 用户的需求是内容生成类:“帮我写一篇MBTI主题的小红书文案”“生成MBTI相关的短视频脚本”
- 用户同时提出多个混合需求,且没有明确表示要做测评:“帮我查MBTI类型,再写一份职场沟通方案”
- 用户明确表示“我不想做测评”“我只是想了解MBTI的知识”,直接拦截所有测评唤起
## 题目元数据
```yaml
assessment_id: MBTI-44-001
assessment_name: "MBTI 职业性格测评"
question_total: 44
dimension_count: 8 # E/I/S/N/T/F/J/P
dimension_pairs: 4 # EI/SN/TF/JP
role_type_count: 16 # ISTJ...ESFJ
references_path: "references/questions.md" # 数据文件形态 B(多文件,当前仓库采用):题库在 questions.md;另有 profiles.md / dimensions.md。脚本未指定任何路径时自动加载这 3 个文件;指定 --references-path 可回退单文件模式(含全部 3 个 H2 段的合并 mbti.md)
score_calculation_path: "scripts/calculate_mbti.py"
score_function: "calculate_scores"
entrypoint: "python scripts/calculate_mbti.py --display-answers '{\"1\":\"A\",\"2\":\"B\",...,\"44\":\"B\"}'"
```
## references 数据文件结构(关键,允许单文件或多文件)
测评数据(题库 / 16 型档案 / 维度对详情)以 **3 个 H2 段** 组织,每段必须包含一段散文说明 + 一个 ```json 代码块,段顺序固定如下(**H2 标题改名会破坏脚本解析,禁止改名**):
1. `## 题库` → 44 题题库数组
2. `## 16 型人格档案` → 16 型档案数组
3. `## 维度对详情` → 4 维度对 + 8 端详情数组
**文件形态(二选一,均受支持,按需选用)**:
- **形态 A:单文件(兼容保留,非当前采用)**:3 个 H2 段全部放在一个合并 md 文件内(如 `references/mbti.md`),脚本用 `--references-path` 指定。
- **形态 B:多文件拆分(默认,当前仓库采用)**:3 个 H2 段拆分为 3 个独立 md 文件:
- `references/questions.md`(含 `## 题库`)
- `references/profiles.md`(含 `## 16 型人格档案`)
- `references/dimensions.md`(含 `## 维度对详情`)
- 每个拆分文件内**仍必须保留对应的 H2 标题与 ```json 代码块**(解析锚点不变),仅文件边界变化;
- 脚本**不传任何路径时自动加载这 3 个文件**;也可用 `--questions-path` / `--profiles-path` / `--dimensions-path` 分别覆盖;传入 `--references-path` 则整体回退单文件模式。
脚本 `calculate_mbti.py` 的 `load_md_section(md_path, section_title)` 按 H2 标题定位段、提取 ```json 代码块、`json.loads` 解析;**单文件与多文件两种形态共用同一解析逻辑**。若任意一段缺失或代码块未闭合,脚本会抛 `ValueError`。拆分/合并只是文件组织方式,不影响评分逻辑与输出。
## 题目加载硬约束(关键)
1. 本 skill **仅有唯一测评流程**:展示 44 题 → 用户作答 → 输出完整测评报告。不存在其他题数或版本,不询问用户"要做多少题"、不提供任何"版本二选一"入口。
2. 触发测评后必须直接展示全部 44 题进入答题流程,不得插入任何"选择题目数量""选择版本"的中间步骤。
3. 题目必须从 references 数据文件的 `## 题库` 段内 ```json 代码块中读取 `questions` 数组,按 `id` 1→44 原序展示;**禁止模型自行编造或凭印象生成题目**。题库段的数据源形态见"references 数据文件结构"一节:当前仓库采用形态 B(多文件),题库从 `references/questions.md` 读取。
4. 题库共 44 题,每题必须包含 `id` / `question` / `prompt` / `options`(每个 option 含 `option` / `content` / `dimension`)四要素,渲染时不得遗漏任一字段,尤其不得省略 `options.content`。
5. 若题库读取失败或不足 44 题,必须直接报错说明,不得用"部分题目"凑数、不得用模型自拟题补齐。
6. 一次性展示全部 44 道题,不得分页、不得"先展示前几题"、不得逐题加载。
### 题目数据加载流程
模型在渲染交互卡片前,**必须先读取题库文件**,不得凭训练数据回忆题目:
1. 通过 Read 工具读取题库文件 `references/questions.md`(当前仓库采用形态 B 多文件,题库独立存放;此文件仅 21KB,渲染题目时**只读这一个文件**,不要读取 profiles.md / dimensions.md),定位 `## 题库` 段下的 ```json 代码块,解析 `questions` 数组。
2. **同时 Read `references/template.md`**(§T1 模板,byte-stable 唯一权威源),把题库 JSON 替换模板中 `/*__QUESTIONS_JSON__*/` 占位符,按模板**原样逐字符**渲染全部 44 题(模板 JS 已内置 DISPLAY_ORDER 四段分组与视觉编号逻辑),不得打乱、不得省略、不得改写题干/提示语/选项文本/维度归属;**禁止自绘样式、禁止凭记忆渲染**。
3. 若 Read 工具调用失败、`## 题库` 段缺失、```json 代码块未闭合、返回内容不足 44 题、或解析报错,模型**必须**向用户返回明确的错误提示(如"题库文件读取失败,请检查 references/questions.md 中 `## 题库` 段是否存在且包含 44 题"),**不得**:
- 用模型自拟/凭印象/从训练数据回忆的题目补齐
- 用"部分题目"凑数渲染卡片
- 返回空卡片或不做任何响应
- 静默跳过题目渲染只输出其他元素(标题、进度条、维度标签等)
## 派生请求渲染约束(强制,禁止走捷径)
**禁止派生请求走捷径(最常见违规)**:用户说"再来一份""朋友也要测""给同事也来一套""试试换个 UI""重置再来一遍""我想再做一遍"——一律重新 `Read references/template.md` + 走上方标准流程(读题库 → 替换占位符 → 原样输出),**不允许**把"上一次的卡片"复制过来改 ID 后缀(如 `-friend` / `-v2` / `-重测`)当新产物输出。新卡片必须是 template.md 的 byte-stable 实例,所有 ID、class、style、文案与首发保持逐字符一致。
适用对象包括但不限于:
- 题目卡片:任何轮次、任何触发词唤起的测评卡片,都必须是 §T1 模板的实例(仅 `/*__QUESTIONS_JSON__*/` 数据不同)
- 测评报告:任何轮次、任何答案组输出的报告,都必须是 §T2 模板的实例(仅 `/*__REPORT_JSON__*/` 数据不同)
- 派生/重测场景:用户要求"重测""换个样式""再出一份"时,输出内容不得与首发在 CSS/类名/ID/结构/文案/交互上有任何差异(仅数据可变),**禁止**以"改个颜色""换个布局""加个主题"等方式产出与模板不符的卡片或报告
**自查(输出前必查)**:本次输出的 widget_code 是否与 template.md 对应模板逐字符一致(除数据占位符处)?若不一致,必须重新 Read template.md 重做,禁止带差异输出。
## 工作流程
本 skill 只有一条流程:**展示 44 题 → 用户在卡片内作答 → 点击"提交测评" → 模型直接输出完整测评报告**。具体步骤:
1. 渲染完整交互卡片展示全部 44 题,用户在卡片内完成作答(每题仅 A 或 B)。
2. 用户点击"提交测评"时:
- 存在未作答题目 → 卡片内自动滚动到第一个未答题并高亮提示,**不提交、不出报告**;
- 已答完全部 44 题 → 卡片内 JS 通过宿主回传机制(`sendPrompt()`)将答案 JSON 自动作为用户消息发送。
3. 模型收到答案后对答案进行校验,确保题目编号、答案类型、维度映射正确。
4. 调用评分脚本计算 8 个维度字母计数 + 4 对维度百分比 + dominant_type。
5. **直接**返回用户完整测评报告:16 型人格代码 + 各维度得分/百分比 + 特点分析(优势/缺点)+ 推荐职业。
**强制约束(不允许有其他链路)**:用户点击"提交测评"且答完全部题目后,模型必须**直接输出完整测评报告**。禁止以下任何行为:要求用户复制/粘贴答案回传、要求用户手动输入答案、先输出答案 JSON 等待用户确认、把出报告推迟到用户再次追问之后、以任何形式要求用户参与答案传递。
## WorkBuddy 视觉化交互卡片约束(关键)
本 skill 在 Workbody / WorkBuddy 场景下,不仅需要返回结构化 JSON,也必须支持可视化内联交互卡片:即在对话中直接渲染一个 HTML/CSS/JS 组件,模拟真实测评页面,且在聊天窗口中保持稳定的视觉结构。
### 0. 题目卡片渲染规范(强制,100% 一致)
为保证**每个用户、每次会话**触发本 skill 时,题目展示的格式与样式**完全一致**,禁止模型自行设计或自由发挥。**渲染规范以 `references/template.md` 为唯一权威源(byte-stable 标准)**:
- 模型每次渲染题目卡片前,**必须先 `Read references/template.md`**(连同 `references/questions.md`),将 §T1 模板中 `/*__QUESTIONS_JSON__*/` 占位符替换为从题库解析出的 44 题 JSON 后,**原样、逐字符**输出为交互卡片 `widget_code`。
- **禁止在未读取 template.md 的情况下**凭记忆、凭印象或按本文件文字描述自行渲染;禁止改模板任何 CSS / 类名 / ID / HTML 结构 / 文案 / JS 逻辑。
- 下方 §0.1 固定 CSS、§0.2 固定结构、§0.3 固定交互行为是模板内容的文字固化说明(供理解与自查),**一切以 template.md 实际内容为准**;若二者存在字面差异,以 template.md 为准。
#### 0.1 固定 CSS(强制)
固定 CSS 全部位于 `references/template.md` §T1 模板 `<style>` 块内(`#mbti-card` 系列,唯一权威源,含选中态 `#E8F1FF`/`#4E8CFF`/`#1E4FB8`、未选中态 `#F5F6F8`/`#E5E7EB`/`#3A3F47` 等固定色值)。渲染前必须 Read template.md 并按 §T1 原样输出;本文件不再内嵌 CSS 副本,避免与权威源两份内容产生漂移。自查时以 template.md §T1 为准。
#### 0.2 固定结构(强制)
模型渲染时必须以 `#mbti-card` 为根容器,依次输出:标题区(`.q-head` 内 `.q-title` + `.q-count`)、副标题(`.q-sub`)、进度条(`.q-track` 内含 `<i>`)、题目列表(`#mbti-list`)、底部(`.q-foot` 内 `.q-tip` + `.q-submit` 提交按钮)。44 题按"每 11 题一段"插入 4 个 `.q-sec` 分段块(标题 `.q-sec-t` + 提示词 `.q-sec-d`,文案见 §3 分段提示词要求),每题一个 `.q-item`(`.q-num` 顺序编号 = 数组下标 +1、`.q-text` 题干、`.q-prompt` 提示语、`.q-opts` 内两个 `.q-opt` 选项按钮,按钮文本为 `A. 选项内容` / `B. 选项内容`)。**选项按钮文本强制规则(关键):按钮文本必须且只能取对应 option 对象的 `content` 字段原文,禁止使用 `dimension` 字段值(E/I/S/N/T/F/J/P 字母)作为按钮文本;`dimension` 仅供评分脚本使用,渲染时一律忽略。若任一按钮文本是单字母(如 `A. E`、`B. N`),即为渲染错误,必须改为对应 `content` 原文。**
#### 0.3 固定交互行为(强制)
- 选项点击:仅切换当前题选中态,选中按钮加 `.on` 类(互斥,同一题两端不可同时高亮),并实时更新 `.q-count` 文本(`已答 / 44`)与 `.q-track i` 宽度(已答数/44×100%)。
- 提交按钮(文案固定为 `提交测评`,始终可见可点):存在未作答题目 → 在 `.q-tip` 显示"还有 N 题未作答,请先完成第 X 题",给第一个未答题 `.q-item` 加 `.miss` 类并 `scrollIntoView` 滚动到该题,约 1.6s 后移除 `.miss`;已答完 → 调用宿主回传 `sendPrompt('[MBTI测评提交] 我的答案如下:' + JSON.stringify(答案对象))`,答案对象 key 使用**顺序号 1→44**(数组下标 +1),value 为 A/B。
- **渲染流程(强制)**:
0. **派生请求前置 gate(render-time,覆盖本段渲染流程)**:本轮若是派生场景(命中上方"派生请求前置 gate"段任一判定问题),**必须**先把后文 step 1-2 的整套流程真正跑完(即 `Read references/template.md` + `Read references/questions.md` + 替换占位符 + 通过前置 gate 自查 4 项),**禁止**用"我记得模板"、"上一轮卡片复制"、"凭印象渲染"作为渲染依据;本轮若跳过本 gate 直接进入渲染流程,整段视为硬违规,必须重做。
1. 通过 Read 工具读取数据文件 `## 题库` 段,解析 `questions` 数组(44 题,见"题目数据加载流程");
2. **Read `references/template.md`**,把 `questions` 数组 JSON 替换 §T1 模板中 `/*__QUESTIONS_JSON__*/` 占位符,按模板**原样逐字符**输出完整 HTML 交互卡片(模板已内置 §0.1 CSS、§0.2 结构、§0.3 行为、§3 分段文案),作为交互组件(Visualizer show_widget)的 `widget_code` 输出;禁止自绘样式、禁止凭记忆渲染。
3. **渲染后自查(关键)**:输出前逐题核对全部 88 个选项按钮,按钮文本必须来自对应 `content` 原文(前缀 `A.` / `B.`);若发现任一按钮文本为单字母(E/I/S/N/T/F/J/P),立即修正为该选项的 `content` 原文后再输出。同时再跑一次上方"派生请求前置 gate"自查 4 项,全通过后再输出。
- **唯一可变量**:题目数据(题干/提示语/选项内容)。除此之外 CSS、类名、颜色、布局、分段文案、按钮行为均不得改动。
- **禁止事项**:
- 禁止自行编写或改动 CSS(含选中态 `#E8F1FF`/`#4E8CFF`/`#1E4FB8`、未选中态 `#F5F6F8`/`#E5E7EB`/`#3A3F47` 等固定色值);
- 禁止更换类名、调整布局、修改四段分组标题与提示词文字;
- 禁止在规范结构外再包裹自定义样式或追加额外脚本;
- 禁止"凭印象"重画题目卡片或每次输出不同样式。
### 1. 渲染目标
当用户触发"开始测评"或"MBTI 测评"时,必须返回一个可渲染的内联卡片,而不是纯文本说明。
该内联卡片必须包含:
- 顶部标题:`MBTI 职业性格测评`
- 二级说明:`共 44 题,请根据真实感受选择"A"或"B"`
- 顶部进度条:显示已答题数/总题数,例如 `17 / 44`
- 维度标签:例如 `E/I · 外倾-内倾`(当前题所属维度对)
- 题目列表:每一题显示**顺序编号** + 题干 + 提示语(prompt)
- 顺序编号必须按"从上到下依次递增"渲染:第 1 题显示 `1`、第 2 题显示 `2`、……、第 44 题显示 `44`
- **禁止使用题库 JSON 里的 `id` 字段作为展示编号**(题库 `id` 仅用于内部作答映射,不直接呈现给用户)
- 题目展示顺序必须与题库 `questions` 数组顺序一致,不打乱
- 顺序号与题库 `id` 的对应关系在本次题库下恰好一致(`id=1` 即第 1 题、`id=44` 即第 44 题),但渲染层不得依赖该巧合,必须以"数组下标 +1"作为顺序号唯一来源
- 每道题的答题区域:左右两侧各有一个单选按钮,分别对应 `A` 与 `B`
- 选项按钮文本必须显示选项内容(content)原文,而不是仅显示 A/B 字母或维度字母(E/I/S/N/T/F/J/P)
- 当前题目高亮:当前题对应的题目区域、标签和按钮状态应明显区分
- 底部交互:可前后翻题,并提供始终可见的"提交测评"按钮(禁用/启用规则见 §4 交互约束)
- 允许用户在同一对话流中直接答题,不需要跳转到其他页面
### 2. 视觉结构要求
视觉结构必须遵循以下稳定版布局:
- 整体是一个白色/浅灰背景的卡片容器,边框柔和、圆角适中
- 标题采用大字号、黑色/深灰字体
- 子标题采用中等字号、灰色字体,位置在标题下方
- 顶部右侧显示进度文本,格式固定为 `已答题数 / 44`(如 `17 / 44`),数字含义为"已作答题数",不是"当前题号"
- 进度条位于标题区下方,长度为卡片宽度的主内容区域,宽度比例 = 已答题数 / 44
- 当前维度对标签使用绿色/浅绿色浅底色,圆角和内边距稳定
- 题目行高统一,题干左对齐,选项按钮右对齐
- **题目顺序编号(关键)**:每题左侧的编号必须按"从上到下依次递增"渲染(第 1 题显示 `1`,第 2 题显示 `2`,……,第 44 题显示 `44`),**禁止使用题库 JSON 的 `id` 字段作为展示编号**。渲染器取数组下标 `index + 1` 作为顺序号;题库 `id` 仅在提交作答时用于内部映射,不参与展示。
- `A / B` 是两个二选一按钮,选中态必须使用如下固定色值,不允许模型自行挑选颜色:
- 未选中:浅灰底 `background: #F5F6F8`,边框 `1px solid #E5E7EB`,字色 `#3A3F47`
- 已选中:淡蓝底 `background: #E8F1FF`,边框 `1px solid #4E8CFF`,字色 `#1E4FB8`,并可加左侧细色条 `box-shadow: inset 3px 0 0 #4E8CFF`
- 同一题两个按钮互斥:选中 A 时 B 必须退回浅灰底,反之亦然,禁止两端同时高亮
- 已选中按钮必须有可感知的视觉差异(背景色明显比未选中更蓝、边框颜色变深、字色更蓝),用户一眼能看出选的是哪一个
- 题目行之间用浅边框分隔
- 在页面底部可以显示辅助说明,例如 `今天帮你做些什么?@引用对话文件 / 调用技能与指令`
- 44 道题必须按四段显示,每一段前方都有明确的分段标题和提示词,不得混合成一大段连续题目
### 3. 分段提示词要求(必须严格遵守)
44 道题必须按"维度对"分成 4 个部分,并且每个部分的标题和提示文案必须按以下固定文本输出,不得改写语义、删减内容或自由替换:
1. 第一部分标题:`第一部分 外倾-内倾(E/I)`
- 提示词:`下面列举了若干情境,请根据你通常的思考和行为方式选择最接近的答案。选 A 即倾向外倾(E),选 B 即倾向内倾(I)。请按顺序回答本部分全部 11 题。`
2. 第二部分标题:`第二部分 实感-直觉(S/N)`
- 提示词:`下面列举了若干情境,请根据你通常接收信息的方式选择最接近的答案。选 A 即倾向实感(S),选 B 即倾向直觉(N)。请按顺序回答本部分全部 11 题。`
3. 第三部分标题:`第三部分 思维-情感(T/F)`
- 提示词:`下面列举了若干情境,请根据你通常做决策的方式选择最接近的答案。选 A 即倾向思维(T),选 B 即倾向情感(F)。请按顺序回答本部分全部 11 题。`
4. 第四部分标题:`第四部分 判断-知觉(J/P)`
- 提示词:`下面列举了若干情境,请根据你通常的生活方式选择最接近的答案。选 A 即倾向判断(J),选 B 即倾向知觉(P)。请按顺序回答本部分全部 11 题。`
要求:
- 四段必须依次连续出现
- 每段上方都必须显示标题与提示词
- 标题和提示词必须原样保留,不得改成中文简写、删减或替换 A/B 表述
- 每段内部题目都必须属于对应维度对,不得跨段混排
### 3.1 分组算法(强制,渲染前必须执行,不得跳过)
模型渲染题卡前,**必须先按 dimension 字段聚合再决定展示顺序**,禁止直接按 id 顺序 11 等分。具体流程:
1. **读取题库**:从 `references/questions.md` 的 `## 题库` 段 JSON 代码块解析 `questions` 数组;对每题取 `options[0].dimension` 与 `options[1].dimension`(同一题两端必然属于同一维度对两端),据此归类到 EI/SN/TF/JP 4 组。
2. **聚合成 4 组**:分别得到 EI / SN / TF / JP 4 个题号集合(按维度字母归类,注意各题两端字母可能不同:同一 EI 题一端 E、另一端 I,可任取一端归到 EI 组)。
3. **校验总数**:四组题数合计必须 = 44,且每组必须恰好 11 题;若任一组 ≠ 11 或合计 ≠ 44,**直接报错**("题库结构异常:EI={n1}题 / SN={n2}题 / TF={n3}题 / JP={n4}题,合计={total}题"),禁止继续渲染。
4. **段内顺序**:每段组内按题号升序展示,**段内最后一道即为该维度的"复盘题"(id 41/42/43/44)**。本仓库题库四段题号集合为:
| 段 | 维度对 | 段内题号(升序,最后一道为复盘题) |
|---|---|---|
| 1 | EI | 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, **41** |
| 2 | SN | 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, **42** |
| 3 | TF | 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, **43** |
| 4 | JP | 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, **44** |
每段展示顺序严格按上表升序:EI 段 `Q1→Q2→...→Q10→Q41`、SN 段 `Q11→...→Q20→Q42`、以此类推。
5. **段间顺序**:四段依次按 EI → SN → TF → JP 顺序排列。
6. **展示编号**:每题展示编号 = 全局累计顺序号 1→44(不切换为题库 id),与段内位置无关,第 1 题显示 1、第 44 题显示 44。
7. **禁止"按 id 顺序 11 等分"的快捷渲染**:题库原序可能并非 11 等分块结构(如本仓库题库是 10-10-10-10 + 1-1-1-1 形态);按 id 等分 11 题一段必然跨段混排(如 Q11 属 SN 会被错位放入 EI 段,Q21-Q22 属 TF 会被错位放入 SN 段,依此类推),违反上方"不得跨段混排"硬规则。
> 段内提示词中的 A/B 映射("选 A 即倾向 X,选 B 即倾向 Y")仅描述维度对整体倾向,各题按钮的实际维度归属以题库 `dimension` 字段为准(部分题目的 A/B 归属与段提示相反);按钮文本一律取 `content` 原文,禁止按段提示词的 A/B 映射推断或替换按钮文本。
### 3.2 DISPLAY_ORDER 常量与提交 Remap 协议(强制,渲染与回传链路必须遵守)
为彻底消除"卡片展示顺序 vs 答案键"之间的歧义,本节同时锁定 **DISPLAY_ORDER 常量**(视觉位置 ↔ 题库真实 id 的强制映射)和 **提交 remap 协议**。评分脚本内嵌与本节同源的 DISPLAY_ORDER 常量,`--display-answers` 在脚本内部自动完成 remap + 双向校验——**映射只维护一份(脚本内)、remap 只执行一次(脚本内)、模型零手写逻辑**,从机制上杜绝"人工翻译映射表"类错误。
#### 3.2.1 DISPLAY_ORDER(强制常量,禁止改动)
四段展示顺序的题号集合(本仓库题库固定形态,禁止重组、扩展或删减):
```yaml
# 段内题号(升序),最后一道为该维度复盘题
section_EI_ids: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 41]
section_SN_ids: [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 42]
section_TF_ids: [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 43]
section_JP_ids: [31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 44]
```
视觉位置 1→44 与题库真实 id 的强制映射:
```yaml
display_pos_to_real_id:
"1": 1, "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8, "9": 9, "10": 10,
"11": 41, # EI 段尾复盘题
"12": 11, "13": 12, "14": 13, "15": 14, "16": 15, "17": 16, "18": 17, "19": 18, "20": 19, "21": 20,
"22": 42, # SN 段尾复盘题
"23": 21, "24": 22, "25": 23, "26": 24, "27": 25, "28": 26, "29": 27, "30": 28, "31": 29, "32": 30,
"33": 43, # TF 段尾复盘题
"34": 31, "35": 32, "36": 33, "37": 34, "38": 35, "39": 36, "40": 37, "41": 38, "42": 39, "43": 40,
"44": 44 # JP 段尾复盘题
```
**强制约束**:
- 卡片渲染必须按 `section_EI_ids + section_SN_ids + section_TF_ids + section_JP_ids` 拼接顺序逐题输出,每题视觉编号 = 该题在拼接序列中的索引(1→44),**禁止向学员暴露 `id=41/42/43/44` 这类原始题号**。
- 一旦题库数据发生变更(如 ids 41–44 维度错位、id 数 ≠ 11/段),必须先修此处常量、且重跑 §3.1 第 3 步 `每段=11、合计=44` 校验通过后,方可继续渲染。
#### 3.2.2 提交 Remap 协议(强制,remap 由脚本内置完成)
用户在卡片内作答回传的 JSON 形如 `{"1":"A","2":"B",...,"44":"B"}`,键为**视觉位置 1–44**。**调用 `scripts/calculate_mbti.py` 必须使用 `--display-answers` 参数原样传回该 JSON;禁止手写 remap、禁止把原 JSON 传给 `--answers`**:
```bash
python scripts/calculate_mbti.py --display-answers '{"1":"A","2":"B",...,"44":"B"}' --compact
```
脚本内部按 §3.2.1 `display_pos_to_real_id` 权威映射(内嵌 DISPLAY_ORDER 常量,与本节同源)自动把每个键从视觉位置改写为真实题号 id,再做 §3.2.3 双向校验;**任一校验失败脚本直接报错并以非零码退出,不评分**。
**原因说明**:评分脚本仅按 `q.id` 取答案 + 按 `options[].dimension` 累加字母计数,对展示顺序、维度分组无感。若直接以视觉位置键的 JSON 调用 `--answers`,id=1–40 题会被正确读取,但 id=41–44(每段复盘题)会因为 keys="11/22/33/44" 找不到对应题而**被静默丢弃**,导致每维度少计 1 题、最终人格类型可能跑偏。把映射与校验沉入脚本后,出错点从"人工翻译映射表"变为"原样传回 JSON",在机制上被消除。
**禁止事项**:
- **禁止手写 remap 字典 / range 循环 / assert 后再传给 `--answers`**:remap 必须且只能由脚本内 DISPLAY_ORDER 常量完成,模型不做任何键改写(历史教训:手写 range 曾因起点覆盖锚点键 11/22/33 导致复盘题丢失)。
- 禁止把视觉位置键的原 JSON 传给 `--answers`(应传 `--display-answers`)。
- 禁止凭"题量差不多"等直觉判断跳过 remap。
- 禁止写"自动修复"脚本或临时程序替带 remap 协议(一切键改写都必须以 §3.2.1 为唯一权威源)。
#### 3.2.3 Remap 后双向校验(强制,由脚本内置完成)
remap 与校验均已内置于评分脚本的 `--display-answers` 分支,模型**不再手写任何 assert**。脚本内置校验项:
1. 输入必须是 JSON 对象(dict),否则报错。
2. 键必须恰好是视觉位置 `{1,2,...,44}` 全集,缺一/多一/含非法键均报错(缺键场景对应"未答完",模型按 §4 提示用户补答)。
3. 全部 value 归一化后必须为 `A`/`B`(`normalize_answer` 兼容 Y/N/1/2);任一项非法即报错并指出具体题号。
4. remap 后键集为 `{1,2,...,44}` 真实 id 全集(由 DISPLAY_ORDER 的排列性构造保证)。
任一校验失败,脚本输出错误信息并以非零码退出;模型**禁止**在脚本报错时强行出报告,应按报错内容回传用户处理(如"还有 N 题未作答,请先完成第 X 题")。
### 4. 交互约束
- 一次性展示全部 44 道题,不能分页、不能逐题加载、不能"先展示前几题再继续"
- 题目须按题库原顺序从 1 到 44 连续展示,不得打乱顺序
- 每题必须只有一个有效答案:`A` 或 `B`
- 用户点击 `A` 或 `B` 时,必须只切换当前题在该题目的选中状态,不应同时多选
- 题目展示编号按"从上到下依次递增"(第 1 题显示 `1`、……、第 44 题显示 `44`),与题库 `id` 解耦;详见 §2 视觉结构要求
- 进度条长度和文本必须依据已答题/总题数自动更新,但整个评测仍然保持 44 题全量展示
- **提交按钮始终可见且始终可点击(关键)**:`提交测评` 按钮必须在卡片渲染的同一帧就出现在卡片最下方,**禁止"答完才显示""达到某条件才渲染"等延迟出现行为**,**禁止 `disabled` 置灰不可点**。无论是否答完,按钮都必须处于 `enabled` 可点击态。点击行为分两种:
- 存在未作答题目 → **禁止提交、禁止出报告**,自动滚动到第一个未作答题目并高亮提示"还有 N 题未作答,请先完成第 X 题"(跳转规则见下条"未答跳转")
- 已答完全部 44 题 → 直接触发评分计算,**立即输出完整测评报告**(见"提交后直接出报告"一节),不允许任何中间链路
- **触发流程稳定性(关键)**:无论用户在第几轮对话、用什么措辞("开始测评"/"做 MBTI"/"测测我的 MBTI"/"启动 MBTI 测评"等任一触发词)唤起本 skill,**首次返回的卡片必须完整包含标题、进度条、维度标签、44 题列表、A/B 双选按钮、提交按钮**全部要素。**禁止"先返回题目卡片,等下一轮再补提交按钮"**、**禁止"先返回部分题目,等用户催促再补全"**、**禁止"渲染时只返回 JSON 不返回交互卡片"**。若模型因上下文长度或工具限制无法一次渲染完整卡片,必须明确报错而非返回残缺卡片。
- **未答跳转(关键)**:用户点击 `提交测评` 按钮时,若存在未作答题目,**禁止提交并禁止直接出报告**,必须自动将焦点/视图滚动到第一个未作答的题目上,并高亮提示"还有 N 题未作答,请先完成第 X 题"。第一个未答题判定规则:按渲染顺序 1→44(即数组下标 +1)遍历,遇到第一道 `answers` 中对应位置为空(即未选 A/B)的题即为锚点题。跳转后该题的 `A/B` 双选按钮区域必须获得视觉焦点(边框高亮、自动滚入可见区),不得仅做文字提示而不滚动
- **提交后直接出报告(关键)**:用户点击 `提交测评` 且已答完全部 44 题时,卡片内 JS 必须调用宿主回传机制(`sendPrompt()`)将答案 JSON 以自动生成的用户消息形式回传给对话流,**模型收到答案后立即调用评分脚本计算并输出完整测评报告**。**禁止任何中间链路**:禁止要求用户复制/粘贴答案回传、禁止要求用户手动输入答案 JSON、禁止"先把答案发我"再等下一轮出报告、禁止输出答案 JSON 后等待用户确认。
- 交互必须发生在当前对话流的内联组件中,而不是返回普通纯文本
- 该组件的页面流必须保持"44 题一次性展示 + 全量答题 + 提交"的连续逻辑
### 5. HTML / Visualizer 输出要求
如果系统支持 WorkBuddy 的 Visualizer / 内联 HTML 渲染,返回内容必须满足:
- 以 HTML 片段或可渲染组件形式输出,而不是纯 Markdown
- 必须保留视觉层结构:标题、进度、维度对标签、题目列表、双选按钮
- 不能出现散乱的自然语言说明替代卡片
- 不能直接输出仅有 JSON 字段而没有交互容器
- 不能让前端自行"自由发挥"生成不同布局
- 只允许按本 skill 规定的结构渲染,不允许引入无关内容
### 7. 禁止事项
- 不允许输出纯文本描述替代卡片
- 不允许缺失"A / B"双选按钮
- 不允许没有维度对标签
- 不允许没有进度条和题号
- 不允许使用题库 `id` 作为题目展示编号,必须用"从上到下依次递增"的顺序号
- **不允许提交按钮延迟出现**:提交按钮必须在卡片首次渲染的同一帧就出现在卡片最下方,禁止"答完才显示""下一轮才补"
- **不允许提交按钮置灰不可点击**:无论是否答完,提交按钮必须处于 `enabled` 可点击态;未答完点击执行"未答跳转",已答完点击直接出报告
- **不允许首次渲染卡片时缺失提交按钮**:无论用户在第几轮对话唤起测评,首次返回的卡片必须包含提交按钮
- **不允许"先返问题卡片、再补提交按钮"或"先返部分题目、再补全"的两段式渲染**:必须一次性返回完整卡片
- 不允许在页面中出现无关长文案或随机推理内容
- 不允许模型自行更换布局结构,必须保持 WorkBuddy 交互卡片的稳定格式
- **不允许模型自绘题目卡片(关键)**:题目卡片必须严格遵循本文件"题目卡片渲染规范"(§0.1 固定 CSS / §0.2 固定结构 / §0.3 固定交互行为)输出,禁止自行编写 CSS/布局/颜色,确保每个用户看到的题目格式与样式完全一致
## 输出格式
### 报告渲染规范(强制,100% 一致)
为保证**每个用户、每次提交**测评后输出的报告格式与样式**完全一致**,禁止模型自行设计。**报告渲染以 `references/template.md` 为唯一权威源(byte-stable 标准)**:
- 模型每次渲染报告前,**必须先 `Read references/template.md`**,将 §T2 模板中 `/*__REPORT_JSON__*/` 占位符替换为评分脚本(`--compact`)输出的报告 JSON 后,**原样、逐字符**输出为报告 `widget_code`。
- **禁止在未读取 template.md 的情况下**凭记忆、凭印象或按本文件文字描述自行渲染;禁止改模板任何 CSS / 类名 / ID / HTML 结构 / 文案 / JS 逻辑。
- 下方 §R.1 固定 CSS、§R.2 固定结构是模板内容的文字固化说明(供理解与自查),**一切以 template.md 实际内容为准**;若二者存在字面差异,以 template.md 为准。
> **仲裁规则(关键,先读)**:§R.1 的 CSS 已与渲染平台(Visualizer)设计系统对齐——无渐变、无阴影、无 blur/glow/neon,字重仅 400/500,全部使用宿主 CSS 变量(`var(--color-*)`)或设计系统色板色值,通过宿主变量与 `prefers-color-scheme` 自动适配明暗主题,二者**已无冲突**。渲染时必须以本规范字面值为唯一依据:禁止任何"适配主题 / 优化 / 简化 / 美化 / 压缩"行为;若渲染平台 read_me 说明与本规范存在任何字面差异,**以本规范为准**(本规范即对齐后的最终形态)。
#### R.1 固定 CSS(强制)
固定 CSS 全部位于 `references/template.md` §T2 模板 `<style>` 块内(`#mbti-rpt` 系列,唯一权威源):无渐变、无阴影、无 blur/glow/neon,字重仅 400/500,全部使用宿主 CSS 变量(`var(--color-*)`)或设计系统色板色值(`#185FA5`/`#3B6D11`/`#534AB7`/`#BA7517` 及暗色模式对应值,封装为 `t-ei`/`t-sn`/`t-tf`/`t-jp` 的 `--dc`/`--dbg`)。渲染前必须 Read template.md 并按 §T2 原样输出;本文件不再内嵌 CSS 副本,避免与权威源两份内容产生漂移。自查时(CSS 是否逐字一致、色板内色值)以 template.md §T2 为准。
#### R.2 固定结构(强制)
模型渲染时必须以 `#mbti-rpt` 为根容器,依次输出:标题区(`.r-hdr` 内 `.r-type` = `dominant_type` + `.r-nm` = `role_detail.name`;**无背景、无渐变**,仅底部 0.5px 分隔线)、指标卡(`.r-meta` 内 3 个 `.r-mc`:倾向强度 `display_score`、人群占比 `proportion%`、胜出维度 `dimension_pairs[].result` 按 `·` 连接;浅灰表面卡,无边框)、8 字母计数条(`.r-bar8`,按 E/I/S/N/T/F/J/P 固定顺序;每个字母格为一个 `<div>`,内部为字母 + 数值(数值用 `.v`);**胜出字母的 div 必须同时加 `win` 类和对应维度主题类**(例:`<div class="win t-ei">I<span class="v">7</span></div>`)→ 自动按主题类上维度色(`--dbg` 底 + `--dc` 字);非胜出字母不加类,灰底灰字;条下加 `.r-cap` 说明`胜出维度标色 · 数值=该端答对题数`)、4 个维度卡(`.r-dim`,按 EI/SN/TF/JP 顺序,**每个维度卡必须按维度对加主题类**:EI→`t-ei`、SN→`t-sn`、TF→`t-tf`、JP→`t-jp` → 自动获得左侧 3px 维度色边条;每卡含 `.r-dimh` 标题(`dimension_name` + `胜出:result result_name` 徽标 `.r-win`,徽标底色/字色随主题类自动变化)、`.r-pair` 两端对比条(`option+name1`、`score1 题 · percent1%`、宽度=percent 的 `.r-track i`;**胜出端的 `.r-side` 必须加 `win` 类** → 进度条/百分比/feature 自动变维度色;非胜出端不加类,进度条灰色)、`<details>` 展开区固定三段(模型必须按此顺序与文案输出):`.r-sec` 标题 `胜出端特质` + 胜出端 `result_traits` 原文、`.r-sec` 标题 `维度解读` + `dimension_description`/`dimension_prompt` 原文、`.r-sec` 标题 `两端详情对比` + 两端 `option1_detail`/`option2_detail` 的 `.r-duo` 两卡 `.r-sc`(`name`/`feature`/`traits`/`characteristics` 原文,卡片带维度色左缘条))、特点分析卡(`.r-dim` 不加主题类:`.r-sec` 标题固定为 `特点分析`,内部 `.r-feats` 双卡并排——`.r-feat2 adv` 标题固定为 `优势` + `role_detail.advantages` 原文、`.r-feat2 dis` 标题固定为 `缺点` + `role_detail.disadvantages` 原文;**禁止展示 `role_detail.description`**)、职业推荐卡(`.r-dim` 不加主题类:`.r-sec` 标题固定为 `职业推荐` + `analysis.summary` 的 `.r-txt` + `analysis.recommendations` 的 `.r-tag` 标签列表,标签统一样式,模型不额外加类)、底部 `.r-note` 说明。
- **维度主题色映射表(强制,模型必须按此映射加类/判定胜出)**:EI → `t-ei`(c-blue:亮色 #185FA5 / 深色 #85B7EB)、SN → `t-sn`(c-green:亮色 #3B6D11 / 深色 #C0DD97)、TF → `t-tf`(c-purple:亮色 #534AB7 / 深色 #AFA9EC)、JP → `t-jp`(c-amber:亮色 #BA7517 / 深色 #FAC775)。维度卡主题类、`.r-bar8` 胜出格、`.r-side` 的 `win` 类均由报告数据中的 `pair` 与胜出结果决定,同一份报告内必须保持一致。
- **渲染流程(强制)**:
1. 调用 `scripts/calculate_mbti.py`(建议加 `--compact` 紧凑输出)得到报告 JSON(**唯一数据来源**,字段必须全量);
2. **只读脚本输出的报告 JSON 进行渲染,禁止再读取 `references/profiles.md` / `references/dimensions.md`**:脚本输出已按查表结果透传全部渲染所需原文(`role_detail` 7 字段、`dimension_pairs` 8 端 `name/feature/traits/characteristics`、`dimension_name/description/prompt`、`result_traits/result_characteristics`、`analysis` 全量,合计仅约 10KB),渲染报告所需的每个字段都在其中,无需也不得再读 references 文件(合计约 63KB,纯属浪费上下文、拖慢响应);
3. **Read `references/template.md`**,把报告 JSON 替换 §T2 模板中 `/*__REPORT_JSON__*/` 占位符,按模板**原样逐字符**渲染完整 HTML 报告,作为交互组件(Visualizer show_widget)的 `widget_code` 输出给用户;禁止自绘样式、禁止凭记忆渲染。
- **渲染后自查清单(强制,输出前逐项核对,任一不符必须重写后再输出)**:
1. CSS 是否与 §R.1 **逐字一致**(未增删改任何选择器/属性/值/类名)?
2. 是否出现 `linear-gradient` / `box-shadow` / `text-shadow` / `filter: blur` / `font-weight:600` 或 `700`?→ 出现即违规(本规范已对齐设计系统,禁止再引入渐变/阴影/重字重);
3. 所有颜色是否均为 `var(--color-*)` / `var(--dc)` / `var(--dbg)` 或 §R.1 色板内色值?是否出现 `#fff` / `#000` 硬编码背景或深色块?
4. 根容器 `#mbti-rpt` 是否透明(未设背景色)?
5. `.r-bar8` 是否 E/I/S/N/T/F/J/P 顺序、胜出格是否带 `win t-xx` 双类?
6. 4 个维度卡是否 EI/SN/TF/JP 顺序、主题类是否 `t-ei`/`t-sn`/`t-tf`/`t-jp`、胜出端 `.r-side` 是否带 `win`?
7. 报告字段是否完整(`role_detail` 7 字段、两端 8 端详情、`analysis` 全量)无截断、无 `{{}}` 残留、无"见上文"式省略?
8. 结构顺序是否与 §R.2 完全一致(标题区→指标卡→bar8→4 维度卡→特点分析→职业推荐→note)?
9. 是否只读脚本输出 JSON 渲染(未读 references 大文件、未混入自拟文案)?
- **唯一可变量**:报告数据(各字段值)。除此之外 CSS、类名、颜色、布局、文案均不得改动;`t-ei`/`t-sn`/`t-tf`/`t-jp` 与 `win` 为规范类名,属 §R.2 固定结构的一部分,模型必须按映射表使用,不得增删或改色。
- **禁止事项**:
- 禁止自行编写 CSS / 更换类名 / 调整颜色或布局;
- 禁止改写、省略或截断 `role_detail`(7 字段原文)、`dimension_pairs` 两端 8 端详情(`name`/`feature`/`traits`/`characteristics` 原文)、`analysis`(summary + recommendations 全量)等字段;
- 禁止用 Markdown 表格、纯文本替代报告渲染;
- 禁止"凭印象"画报告或每次输出不同样式。
## 确定性输出约束(关键)
为避免 Workbody 生成结果每次都变化,本 skill 必须执行严格的确定性规则:
1. 结果必须以脚本计算结果为唯一准绳,不允许模型自由推断分数或人格类型。
2. `dimension_pairs` 必须按固定顺序输出 4 对:`["EI", "SN", "TF", "JP"]`。
3. `dominant_type` 必须由 4 对维度结果字母按 EI → SN → TF → JP 顺序拼接,不能由模型自行命名或重写。
4. 每对维度的胜出字母规则:当两端计数相等时取 option1(即 E/S/T/J),即 `score1 >= score2 ? option1 : option2`。
5. 百分比必须保留两位小数,使用 `decimal.ROUND_HALF_UP`(与 Java `BigDecimal.ROUND_HALF_UP` 一致),不允许 Python 默认 banker's rounding。
6. `display_score` 为 4 个胜出端百分比的平均值取整数,使用 `decimal.ROUND_HALF_UP`,不允许模型自由发挥。
7. `role_detail` 必须从 `references/profiles.md` 的 `## 16 型人格档案` 段按 `dominant_type` 查表得到,16 型全覆盖;**字段值必须为原文,不允许模型自行撰写或改写人格描述、优势、劣势、职业推荐**(**该查表由评分脚本完成**,模型直接使用脚本输出 JSON 中已透传的原文,无需自行读文件)。
8. `dimension_pairs[].result_name/result_feature/result_traits/result_characteristics` 与 `option1_detail/option2_detail` 必须从 `references/dimensions.md` 的 `## 维度对详情` 段按 `dimension` + `option` 查表,使用原文(含 `title/feature/traits/characteristics` 字段),不允许模型自行撰写(**该查表由评分脚本完成**,模型直接使用脚本输出 JSON 中已透传的原文,无需自行读文件)。
9. `analysis.summary` 必须使用固定模板,且只基于 `dominant_type` 与 `role_detail.name` / `role_detail.careers` 前 5 项生成。
10. `analysis.recommendations` 必须为 `role_detail.careers` 字符串按顿号切分后的字符串数组,顺序固定,不得截断。
11. 任何场景都不允许输出随机、模糊、口语化的结论;必须稳定输出统一结构。
12. 如果题目不完整,必须返回 `incomplete`,并列出缺失题号;不得在有缺失时强行生成完整结论。
13. 生成结果时必须以 JSON 对象返回,不能返回 Markdown、自然语言说明、额外说明块或解释性文本。
14. 同一组 `answers` 必须在多次调用间产生 byte-equal 的 JSON 输出(无随机数、无时间戳、无外部网络/DB 依赖;经 4 组答案 × 10 次运行验证通过)。
15. 报告文案来源:`references/profiles.md`(16 型档案)/ `references/dimensions.md`(维度对详情)两个拆分文件,**查表由评分脚本完成**——脚本输出 JSON 已按查表结果透传全部原文字段(约 10KB),模型渲染报告时**只读脚本输出 JSON**,**禁止再读这两个 references 文件**(合计约 63KB,纯属浪费上下文、拖慢响应);**禁止在生成结果时混入模型自拟内容**,所有 `role_detail` / `dimension_pairs[].result_*` / `dimension_*` / `option1_detail` / `option2_detail` 字段直接使用脚本输出中的原文,不得改写。
16. **全量输出约束(关键)**:每一轮报告输出都必须包含完整 JSON 结构的全部字段,**严禁**在任何轮次出现"与上一轮一致""结果同上""向上翻阅""如前所述""参考前次输出"等省略式表述。无论同一组 `answers` 在同一对话流中被请求多少次,每次都必须输出一份**字段齐全、文案完整**的报告 JSON,包括但不限于:`dimension_counts`(8 键)、`dimension_pairs`(4 对,每对含 `option1_detail`/`option2_detail` 共 8 端详情)、`role_detail`(7 字段原文)、`analysis`(summary + recommendations 全量)。**禁止以"已生成过""缓存命中""结果不变"为由截断或省略任何字段**。
17. **禁止引用式表述**:禁止在报告 JSON 内或外层包裹文字中使用"见上文""参见第 N 轮""同前次""以上一轮为准"等指向历史轮次的表述。每轮报告必须是自包含的、可独立阅读的完整内容。
18. **样式确定性(强制)**:题目卡片必须遵循 `references/template.md` §T1、测评报告必须遵循 `references/template.md` §T2 渲染(每次渲染前必须 Read template.md,按模板原样输出,仅替换数据占位符),**对任何用户、任何轮次渲染结果必须逐字一致**(唯一差异仅为题目数据 / 报告数据);禁止任何用户或任何轮次获得不同格式/样式的卡片或报告;禁止未读 template.md 凭记忆渲染;禁止复制上一轮输出改 ID 后缀充当新产物。
本 skill 负责在用户点击"提交测评"后**直接输出结构化的完整测评报告**,不承担前端渲染。字段级约束见下方"### 输出规范"。
### 输出规范
- `status` 必须为 `completed` 或 `incomplete`
- `display_score` 为 0-100 的整数,且必须来自脚本计算结果
- `dominant_type` 为 4 个结果字母按 EI → SN → TF → JP 拼接,例:`"ESTP"`,不能自行更改为其他文本
- `dimension_counts` 必须按固定顺序输出 `E`、`I`、`S`、`N`、`T`、`F`、`J`、`P` 八个键
- `dimension_pairs` 必须按 `EI`、`SN`、`TF`、`JP` 顺序输出 4 对
- 每对维度的 `result` 字母规则:`score1 >= score2` 时取 `option1`(即 E/S/T/J),否则取 `option2`
- `percent1` + `percent2` 必须等于 100.00(仅当计数非零时)
- `role_detail` 必须从 `references/profiles.md` 的 `## 16 型人格档案` 段按 `type` 查表,包含 `type/name/proportion/description/advantages/disadvantages/careers` 七个字段,**全部使用原文,不得改写、不得省略、不得由模型自行撰写**
- `dimension_pairs[].result_name/result_feature/result_traits/result_characteristics` 必须从 `references/dimensions.md` 的 `## 维度对详情` 段按 `dimension` + 胜出端 `option` 查表(`title` → `result_name`,`feature/traits/characteristics` 原样透传)
- `dimension_pairs[].option1_detail/option2_detail` 必须按对应维度对的 `option1/option2` 字母查 `## 维度对详情` 段,`name` 字段对应 `title`
- `dimension_pairs[].dimension_name/dimension_description/dimension_prompt` 必须从 `## 维度对详情` 段的 `name/description/prompt` 字段原样透传
- `analysis.summary` 必须使用固定中文模板:`"用户在 {4个胜出字母用顿号连接} 四个维度胜出,人格类型为 {dominant_type}({role_name}),适合 {careers 前5项顿号连接} 等方向。"`
- `analysis.recommendations` 必须为 `role_detail.careers` 按顿号切分后的字符串数组,顺序固定,不得截断
- 若题目未完成,则返回 `incomplete`,并输出 `missing_questions`(缺失题号字符串数组)
- 输出必须为纯 JSON,不允许嵌套说明、Markdown 代码块或额外字段
### 渲染约束(关键)
本 skill 约束的是"生成结果的渲染契约",而不是页面实现细节。具体要求如下:
- `dominant_type` 必须作为页面主标题字段使用(如 `ESTP`)。
- `role_detail.name`(中文名如 `企业家`)必须作为副标题或角色名展示字段使用。
- `role_detail.proportion` 必须作为占比展示字段使用(值为百分数,如 `4.3` 表示 4.3%,前端按需补 `%`)。
- `display_score` 必须作为总分展示字段使用。
- `dimension_pairs` 必须作为各维度得分表格/柱状图数据源。
- 每对维度必须展示两侧字母、名称、计数与百分比,以及胜出端高亮
- 每对维度必须展示 `dimension_name`(如 `外倾E&内倾I`)作为该对的展示名
- 每对维度展开后必须展示 `dimension_description` 与 `dimension_prompt` 的原文(可作为该对的说明/作答引导)
- 每对维度必须展示胜出端的 `result_name` / `result_feature` / `result_traits` / `result_characteristics` 四段原文
- **8 端详情必须全部展示(关键)**:每对维度的 `option1_detail` 与 `option2_detail` 共 8 端(E/I/S/N/T/F/J/P 各一端),每端必须完整展示 `name` / `feature` / `traits` / `characteristics` 四段字段的原文。**禁止只展示胜出端**,**禁止省略 `option1_detail` 或 `option2_detail`**,**禁止只展示 `name`/`feature` 而省略 `traits`/`characteristics`**。两端必须左右并列或上下并列,便于用户对比两端倾向。
- `role_detail.advantages` / `disadvantages` 必须在"特点分析"卡中分别作为"优势"/"缺点"两块展示,使用原文(含换行符原样渲染);`role_detail.description` 不在报告中展示(JSON 输出仍保留该字段,全量输出约束不变)
- `role_detail.careers` 必须作为职业推荐展示字段使用,按顿号切分后呈现为列表
- 结果页最底部必须按 `EI`、`SN`、`TF`、`JP` 的顺序展开展示,每对维度至少包含"胜出端"与"两端详情"两部分
- `analysis.summary` 必须作为结果说明文本展示
- `analysis.recommendations` 必须作为建议列表渲染数据
- 任何前端都不能自行生成新的字段名来替代上述结构
- 前端只能根据这几个字段进行展示,不能依赖自由文本解析
### 禁止事项
- 不允许返回自由文本替代 JSON
- 不允许缺少 `dimension_pairs`
- 不允许缺少 `dominant_type`
- 不允许 `dimension_pairs` 中遗漏任一对维度
- 不允许 `role_detail` 缺失任一字段
- 不允许在 skill 中混合前端渲染逻辑
- 不允许前端自行扩展未定义字段覆盖结果解释
- 不允许使用 Python 默认 `round()`(banker's rounding),必须用 `decimal.ROUND_HALF_UP`
- **不允许只展示胜出端而省略非胜出端的 `option1_detail`/`option2_detail`**:8 端详情(E/I/S/N/T/F/J/P)必须全部展示,每端的 `name/feature/traits/characteristics` 四段缺一不可
- **不允许用户点击"提交"按钮时若有未答题就出报告**:必须先跳转到第一个未答题并提示,未答完毕前禁止触发评分
- **不允许"复制答案回传"链路(关键)**:用户点击"提交测评"且答完全部题目后,模型必须直接基于回传的答案立即计算并输出完整测评报告。禁止要求用户复制/粘贴答案、禁止要求用户手动输入答案 JSON、禁止"先把答案发我"或任何让用户参与答案传递的中间环节
- 其他确定性约束(脚本查表透传、禁止自拟文案、禁止引用式表述、禁止自绘样式)见上方"## 确定性输出约束"第 7/8/15/16/17/18 条,不再重复。
## 评分入口
评分脚本位置:
- `scripts/calculate_mbti.py`
- 评分函数:`calculate_scores(answers, questions)`
- 输出:JSON 格式的分数与人格类型结果
示例命令:
```bash
# 不传任何路径:自动加载 references/questions.md / profiles.md / dimensions.md
# 推荐加 --compact:紧凑输出,报告 JSON 约 10KB,渲染报告时模型只读它(无需再读 references 大文件)
# 推荐用 --display-answers:原样传回卡片回传的视觉位置键 JSON,脚本自动 remap + 内置校验(禁止手写 remap)
python scripts/calculate_mbti.py \
--display-answers '{"1":"A","2":"B","3":"A","4":"B",...,"44":"B"}' --compact
# 兼容保留:--answers 接收真实题号 id 键 JSON(remap 由调用方完成,仅测试/内部场景使用)
python scripts/calculate_mbti.py \
--answers '{"1":"A","2":"B","3":"A","4":"B"}' --compact
```
> 参数二选一:`--display-answers`(推荐,卡片回传链路)与 `--answers`(真实 id 键,兼容旧链路)不能同时提供,也不能都不提供,否则脚本报错退出。
> 评分算法(维度计数→百分比→结果字母→拼接→display_score→role 查表)由脚本独立实现,详见 `scripts/calculate_mbti.py` 源码;本文件不再重复说明,避免与脚本实现不一致。
## 重要原则
- 题库必须明确给出题目编号、题干、提示语和选项维度归属;
- 评分逻辑必须单独写在脚本文件中,不能隐含在对话里;
- 用户提交题目后,必须返回测试结果、得分和人格类型;
- 若题目缺失或答案格式不合法,先要求用户补全,不要直接伪造结果;
- 选项维度映射必须保持一一对应;
- 同一组作答必须产出 byte-equal 的 JSON(无随机性)。
## 资源说明
- 题库 + 16 型档案 + 维度对详情:**形态 B(多文件,当前仓库采用)**,拆分为 3 个独立文件,每段仍保留对应的 H2 标题 + 散文说明 + 一个 ```json 代码块:
- `references/questions.md`:`## 题库` 段,44 题题库(**渲染题目卡片时只读此文件**,约 21KB,避免把其余数据读入上下文导致输出不稳定)
- `references/profiles.md`:`## 16 型人格档案` 段
- `references/dimensions.md`:`## 维度对详情` 段
- 脚本不传路径自动加载 3 文件;`--questions-path` 等可分别覆盖;`--references-path` 可整体回退单文件模式
- `## 题库` 段:44 道题的二选一职业性格测评题库
- `## 16 型人格档案` 段:16 型人格档案
- `## 维度对详情` 段:4 对维度对 + 8 端字母详情
- 渲染规范:**模板文件 `references/template.md` 为两道渲染链路(题目卡片 §T1 / 测评报告 §T2)的唯一权威源(byte-stable 标准)**:渲染前必须 Read 该文件并按模板原样输出(题目卡片将 `/*__QUESTIONS_JSON__*/` 替换为题库 JSON,报告将 `/*__REPORT_JSON__*/` 替换为评分脚本输出 JSON),**禁止自绘样式、禁止凭记忆渲染、禁止复制上一轮输出改 ID 后缀**;本文件 §0 / §R 为模板内容的文字固化说明,供理解与自查
- 评分脚本:`scripts/calculate_mbti.py`,通过 `load_md_section(md_path, section_title)` 按 H2 标题切段、提取 ```json 代码块解析;支持多文件(默认,无参数自动加载 3 文件)与单文件(`--references-path`)两种形态;`--compact` 紧凑输出(渲染报告时推荐,输出约 10KB);`--display-answers`(推荐,卡片回传链路)内嵌与 §3.2.1 同源的 DISPLAY_ORDER 常量,自动 remap 视觉位置→真实 id 并内置 44 键/A-B 校验,任一失败报错不评分;`--answers`(兼容保留)接收真实 id 键 JSON,二选一互斥
- **H2 标题文本(`## 题库` / `## 16 型人格档案` / `## 维度对详情`)是 `calculate_mbti.py#load_md_section` 解析锚点,禁止改名**,否则脚本会抛 `ValueError`(拆分多文件时每个文件内同样必须保留对应 H2 标题)。
## 交互输出要求
用户完成题目后,系统应返回:
1. 测评 ID 与名称
2. 状态(completed / incomplete)
3. 16 型人格代码(dominant_type)
4. 4 对维度的计数与百分比
5. 角色详情(type / name / proportion / description / advantages / disadvantages / careers)
6. 4 对维度的详情(含胜出端 name/feature/traits/characteristics 与两端详情,及 dimension_name/description/prompt 原文)
7. 总分(display_score)
8. 若未通过/未完成,给出缺失题号列表
本 skill 仅有唯一测评流程:展示 44 题 → 用户作答 → 输出完整测评报告。评分逻辑独立于题库内容;后续如需切换题库,只需替换 `references/questions.md` 中 `## 题库` 段的 ```json 代码块,无需改动评分脚本。报告文案(`role_detail` / `dimension_pairs[].result_*` / `dimension_*`)全部来自数据文件的 `## 16 型人格档案` / `## 维度对详情` 段(形态 B 下为 `references/profiles.md` / `references/dimensions.md`,形态 A 下为合并的 mbti.md),如需更新文案,直接替换对应 H2 段的 ```json 代码块即可,无需改动评分脚本。**展示格式/样式锁定机制:`references/template.md` 为唯一权威源**——题目卡片模板(§T1,含 `/*__QUESTIONS_JSON__*/` 占位符)与测评报告模板(§T2,含 `/*__REPORT_JSON__*/` 占位符)均固化其中;任何用户、任何轮次(含"再来一份""朋友也要测""重置再来一遍"等派生触发)都必须重新 Read template.md 并按模板原样输出,结果必须完全一致(byte-stable),禁止自绘样式、禁止复制上一轮输出改 ID 后缀。
Files in this skill
- SKILL.md
- references/dimensions.md
- references/profiles.md
- references/questions.md
- references/template.md
- scripts/calculate_mbti.py
Attribution
Comments
Loading comments…
Newsletter
Get the weekly list of safe new skills, and the ones we pulled.