当用户提到MBTI、职业性格、性格测试或性格特征时调用本Skill,用于分析性格倾向及其在工作环境中的表现。
Scanned 9/12/2026
Install to Claude Code
npx -y skills add ahang1598/doubao-workbuddy-qwenwork-skills --skill career-personality --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Career Personality?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/ahang1598-career-personality)More formats (shields.io, HTML) on the badges page.
---
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 后缀。
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!