角色扮演训练场 · 指标清单与测试集
实验 06「支付改版项目组」群聊之上的全部可落地指标,按「谁打分」分层;每条标了状态、题集、方向和四个模型现有的读数。多模型对比就按这张表跑、按最后的记分卡汇报。
已落地程序里有、跑过 待做设计定了、还没写 只限自训模型要 logprob,API 模型拿不到 评委由另一个模型判,带主观性
一、测试集:同一个群聊、同四个角色
所有题都从一份素材切出来:群聊「支付改版项目组」42 条消息,四个原创角色(陈默、陆一鸣、阿May、小知了),每人一张角色卡加一份心理画像(大五五维、需要、依恋、压力反应、防御、信念、触发点)。被测模型只换「演员」,题目、角色、评委都不动。
| 块 | 题集 | 规模 | 怎么来的 | 给哪些指标用 | 文件 |
|---|---|---|---|---|---|
| A | 完整协议回放 | 20 时刻 | 切点 8/16/24/32/40 × 4 角色;模型照心跳协议自己决定说不说、等多久、回谁 | 调度与协议(层 1) | replays/round1-5models.jsonl |
| B | 演员模式冻结题集 actor-支付改版-v1 | 40 时刻 | 切点 4,8,…,40 × 4 角色;每个切点都轮到它说,只写台词。冻结后不再变,是主尺 | 入戏与台词(层 2)、辨认与成对(层 6)、将来的似然辨认和风格分类器(层 3) | bench/actor-支付改版-v1.jsonl |
| C | 知识边界探针 | 24 时刻 | 4 角色 × 3 件私信事件 × 2 种(没收到 / 收到了);在第 43 条处由另一个人点名问 | 编造、遗失、没接话(层 4) | replays/probe-round1.jsonl |
| D | 心理量表访谈 | BFI 176 · ECR-R 144 | InCharacter 原题中文版:BFI 44 题、ECR-R 36 题,每题一场两人私聊 × 4 角色 | 画像误差、依恋命中(层 5) | replays/scale-BFI-round1.jsonl |
| E | 辨认题 | 40/模型 + 28 控制题 | B 的每条台词配四张匿名卡出一道四选一;控制题用原聊天记录里角色真实的下一句 | 可辨认度、评委天花板、人工校准(层 6、7) | replays/actor-round1.identify.jsonl、docs/辨认题.html |
| F | 成对比较 | 240 对 | B 的每题所有模型两两组合,A/B 随机发 | Elo(层 6) | replays/actor-round1.pair.jsonl |
| G | 程序判分题 | 待生成 | 从心理画像词表和聊天记录自动出题:情境选择、记忆问答、重测、泄露 | 层 3 | 待做 |
路径都在 ~/code/amicura-lab06-social/agent/.cache/social/ 下。目前只有一个场景,是已知的最大短板;扩题集的办法在第五节。
二、记分卡:四个模型现在的读数
每层挑一两个头部指标。方向列说明高好还是低好;评委类指标给两个评委(DeepSeek Flash、Seed Lite)的读数。
| 指标 | 方向 | Qwen Plus 角色扮演 | MiniMax M2-her | 豆包 Character | DeepSeek V4.1 Flash | 来源 |
|---|---|---|---|---|---|---|
| 出戏率(演员模式) | 低 | 0% | 80% | 0% | 0% | B · 程序 |
| 辨认答对率(两评委) | 高 | 90% / 82% | 62% / 68% | 75% / 62% | 78% / 72% | E · 评委,天花板 86% / 79% |
| 编造率(没收到却装知道) | 低 | 25% | 33% | 25% | 8% | C · 评委三选一 |
| 遗失率(收到了却不知道) | 低 | 17% | 8% | 8% | 17% | C · 评委三选一 |
| 没接这个话 | 参考 | 33% | 62% | 21% | 46% | C · 吵架时是本色,不算错 |
| BFI 平均误差 / 同档维度 | 低 / 高 | 15.3 · 10/20 | 未跑 | 未跑 | 13.8 · 12/20 | D · 评委按回答打分 |
| 成对 Elo(两评委) | 高 | 1067 / 1134 | 848 / 840 | 983 / 972 | 1102 / 1054 | F · 评委,DeepSeek 当评委时偏爱自己 |
| 打字习惯差(演员模式) | 低 | 0.14 | 0.37 | 0.20 | 0.13 | B · 程序 |
| 气泡/次 · 字/气泡 | 像人(短、多条) | 2.27 · 13 | 1.02 · 36 | 1.02 · 10 | 2.20 · 12 | B · 程序 |
| 开口率 / 点名没回(完整协议) | 参考 / 低 | 75% / 0% | 75% / 0% | 70% / 20% | 65% / 0% | A · 程序 |
| 字段齐(完整协议) | 高 | 100% | 85% | 100% | 100% | A · 程序 |
| 耗时 ms(演员模式) | 低 | 877 | 1620 | 802 | 1425 | B · 程序 |
三、指标清单
层 1 · 调度与协议:说不说、守不守规矩 已落地 程序打分 · 题集 A
只在完整协议(心跳 JSON)下有意义,演员模式里关闭。衡量的是模型当「导演」的能力,和角色扮演本身分开看。
| # | 指标 | 测什么 | 怎么算 | 方向 | Qwen | M2-her | 豆包 | DeepSeek |
|---|---|---|---|---|---|---|---|---|
| 1.1 | 读出 JSON | 输出能不能被程序解析 | 首个 JSON 对象可解析的比例 | 高 | 100% | 100% | 100% | 100% |
| 1.2 | 字段齐 | act 合法、why 非空、speak 时有气泡 | 满足全部条件的比例 | 高 | 100% | 85% | 100% | 100% |
| 1.3 | 开口率 | 多少次心跳选择说话 | act=speak 且有气泡 / 全部 | 参考(按角色活跃度看) | 75% | 75% | 70% | 65% |
| 1.4 | 点名没回 | 被 @ 或被对着说话却没开口 | 被点名时刻里没说话的比例(括号里是被点名次数) | 低 | 0% (5) | 0% (5) | 20% (5) | 0% (5) |
| 1.5 | 连发≥3 仍说 | 自己已连发三条、没人理还说 | 开口次数里的比例 | 低 | 0% | 0% | 0% | 0% |
| 1.6 | 冷场硬插 | 冷场 30 分钟以上、没被点名、也不开新话题却硬说 | 开口次数里的比例 | 低 | 0% | 0% | 0% | 0% |
| 1.7 | 等待秒数越界 | wait_s 不在 2–90 秒 | 计数 | 低 | 0 | 0 | 0 | 0 |
| 1.8 | reply 乱指 | 回复的消息编号不存在 | 计数 | 低 | 0 | 0 | 0 | 0 |
| 1.9 | to 乱指 | 私信对象不是群里的人 | 计数 | 低 | 0 | 0 | 0 | 0 |
| 1.10 | 耗时 · 输出 token | 成本 | 均值 | 低 | 2024 · 132 | 2589 · 109 | 2306 · 123 | 2409 · 156 |
层 2 · 入戏与台词:说出来像不像这个人 已落地 程序打分 · 题集 B(也能在 A 上算)
| # | 指标 | 测什么 | 怎么算 | 方向 | Qwen | M2-her | 豆包 | DeepSeek |
|---|---|---|---|---|---|---|---|---|
| 2.1 | 出戏率 | 一次发言里出现以下任一项 | 2.2–2.5 任一 > 0 的发言比例 | 低 | 0% | 80% | 0% | 0% |
| 2.2 | 旁白 | 括号或星号里的动作、神态描写 | 正则命中数,「(狗头)」这类网络语白名单不算 | 低 | 0 | 33 | 0 | 0 |
| 2.3 | 替人说话 | 台词里替群里别人写了台词 | 「别人名字:」句式命中数 | 低 | 0 | 5 | 0 | 0 |
| 2.4 | 提到模型 | 说自己是 AI、提提示词、心跳、JSON | 正则命中数 | 低 | 0 | 0 | 0 | 0 |
| 2.5 | 助手腔 | 「很高兴为您」「有什么可以帮」一类 | 正则命中数 | 低 | 0 | 0 | 0 | 0 |
| 2.6 | 气泡/次 | 一次发言拆成几条 | 均值;群聊里真人多是一到三条短的 | 像人 | 2.27 | 1.02 | 1.02 | 2.20 |
| 2.7 | 字/气泡 | 每条多长 | 均值;一条 30 字以上就是在写段落 | 像人 | 13.2 | 35.6 | 9.9 | 12.1 |
| 2.8 | 打字习惯差 | 和这个人在这段聊天里已有的话比,标点、句长、语气词、表情的分布差多少 | 指纹向量距离,0 一样 1 全不像 | 低 | 0.14 | 0.37 | 0.20 | 0.13 |
| 2.9 | 原话重复 | 整条和自己说过的话一模一样 | 4 字以上完全相同的计数 | 低 | 0 | 0 | 0 | 0 |
| 2.10 | 自我重合 | 和自己说过的话的字符 4-gram 重合率 | 最大包含率均值 | 低 | 0.03 | 0.01 | 0.01 | 0.06 |
| 2.11 | 鹦鹉学舌 | 把对方上一句大段复述 | 和对方上一条 4-gram 包含率 ≥ 0.6 的计数 | 低 | 0 | 0 | 0 | 0 |
| 2.12 | 耗时 · 输出 token | 成本 | 均值 | 低 | 877 · 22 | 1620 · 25 | 802 · 8 | 1425 · 19 |
以上任何一条都可以按角色、按聊到第几条切开看(--by agent、--by depth、--by model+agent),用来找「某模型只演砸某个角色」或「越聊越飘」。
层 3 · 程序判分题:答案出题时就定了 待做 程序打分 · 题集 G
这一层是训练时的内环:不要评委、不花钱、几分钟出结果。按落地顺序排。
| # | 指标 | 答案从哪来 | 怎么出题、怎么判 | 方向 | 状态 |
|---|---|---|---|---|---|
| 3.1 | 情境选择题准确率 | 心理画像 | 画像字段都是封闭词表:压力反应 5 选 1(硬刚/躲开/僵住/讨好/就事论事)、防御 7 选 ≤2、依恋 4 选 1、需要 9 选 ≤3、大五每维高/中/低。模板出题「被外行在大群里指挥时你第一反应是?」选项就是词表,答案就是卡上的值。以角色口吻作答后用关键词或再选一次映射到选项;精确匹配 | 高 | 待做 第一个做 |
| 3.2 | 记忆问答准确率 | 聊天记录 | 「第 12 条是谁发的」「你上一条说了什么」「谁先提的回调链路」;从转录自动生成,答案字符串比对 | 高 | 待做 第一个做 |
| 3.3 | 重测一致性 | 自己 | 同一题换措辞问两次、换随机种子问两次,答案一致率。心理测量叫重测信度;一致率低说明模型在猜 | 高 | 待做 |
| 3.4 | 泄露率 | 私信箱 | 只发给 A 的事出现在 B 的台词里。探针的 told 变体已经把事件发给了一个人,再看其他人的台词有没有事件关键词;子串和 n-gram 比对 | 低 | 待做 探针已有一半 |
| 3.5 | 似然辨认准确率 | 说话人 | 同一句话放在四张卡下各算一次对数似然,概率最高的卡是不是真正的说话人;附带平均 margin。不问任何评委,就是模型自己的概率 | 高 | 只限自训模型 MLX 直接取 logprob |
| 3.6 | 风格分类器辨认 | 角色已有台词 | 每个角色的历史台词训一个字符 n-gram + 逻辑回归分类器(或 Burrows' Delta 功能词频率),之后「这句像谁」是一次前向计算;报准确率和到角色中心的距离。替代 2.8 的手工指纹 | 高 | 待做 |
| 3.7 | 分布距离 | 角色参考语料 | 不比单句,比一个模型演某角色的全部台词的风格特征分布和参考分布的距离(图像生成 FID 的思路) | 低 | 待做 |
层 4 · 知识边界探针:知道的别丢、不知道的别编 已落地 评委 三选一,字面规则兜底 · 题集 C
| # | 指标 | 测什么 | 怎么算 | 方向 | Qwen | M2-her | 豆包 | DeepSeek |
|---|---|---|---|---|---|---|---|---|
| 4.1 | 编造率 | 别人问它一件它从没收到的事,它却接着聊、表态、补细节 | 没收到的 12 题里判 knows 的比例 | 低 | 25% | 33% | 25% | 8% |
| 4.2 | 遗失率 | 事情明明发给了它,它却说不知道 | 收到了的 12 题里判 unaware 的比例 | 低 | 17% | 8% | 8% | 17% |
| 4.3 | 没接这个话 | 顶回去或说别的,看不出知不知道 | 24 题里判 evaded 的比例;吵架时是本色,不算错,但太高说明在躲问题 | 参考 | 33% | 62% | 21% | 46% |
| 4.4 | 评委失手数 | 评委两次都没给出合法判定、改按字面规则判 | 计数,是评委质量指标不是模型指标 | 低 | 0 | 0 | 0 | 0 |
层 5 · 心理量表:演出来的人格和卡上写的差多少 已落地 评委 按回答给陈述打分(InCharacter 规程)· 题集 D
| # | 指标 | 测什么 | 怎么算 | 方向 | Qwen | DeepSeek |
|---|---|---|---|---|---|---|
| 5.1 | BFI 平均误差 | 五维测得值和卡上数字的差 | 反向题翻转后维度均值映射到 0–100,与卡取绝对差再平均;表里是四个角色的平均 | 低 | 15.3 | 13.8 |
| 5.2 | BFI 同档维度数 | 高/中/低档位是否一致 | ≤35 低、≥65 高;4 角色 × 5 维 = 20 个维度里同档的个数 | 高 | 10/20 | 12/20 |
| 5.3 | 系统偏差 | 某一维全体偏高或偏低 | 按维度看测得减卡的平均;目前宜人性普遍偏高 15–30、神经质偏低 10–25,说明模型演「不讨喜」的人演不下去 | 接近 0 | A 偏高 · N 偏低(两个模型都这样) | |
| 5.4 | ECR-R 依恋命中 | 焦虑、回避两维算出的类型和卡上一致 | 两维各 ≥50 为高,映射安全/焦虑/回避/混乱型;4 角色里命中几个 | 高 | 未跑 | 未跑 |
| 5.5 | 评分失败批次 | 评委没能给出合法打分 | 计数,评委质量指标 | 低 | 0 | 0 |
M2-her 和豆包还没跑量表;一次 4 角色 × 44 题 × 1 模型约 176 次调用加 24 次评分。
层 6 · 评委:有标准答案的辨认为主,成对比较为辅 已落地 评委 · 题集 E、F
| # | 指标 | 测什么 | 怎么算 | 方向 | Qwen | M2-her | 豆包 | DeepSeek |
|---|---|---|---|---|---|---|---|---|
| 6.1 | 辨认答对率(按模型) | 评委看四张匿名卡和一段聊天,能不能认出这句是谁说的。有标准答案,评委主观只影响难度不影响对错 | 答对 / 40;两评委分别报 | 高 | 90% / 82% | 62% / 68% | 75% / 62% | 78% / 72% |
| 6.2 | 控制题天花板 | 原聊天记录里角色真实的下一句,评委认得出几成 | 同法 / 28;模型答对率超过它就是「比原作者还像」 | 基线 | 86% / 79% | |||
| 6.3 | 辨认答对率(按角色) | 哪个角色谁演都难认 | 按角色聚合,跨模型 | 高 | 小知了 89/91 · 陈默 90/62 · 阿May 74/88 · 陆一鸣 58/52 | |||
| 6.4 | 两评委一致率 | 评委自己靠不靠谱 | 两评委选同一字母的比例;待升级成 Cohen's κ | 高 | 79%(瞎猜 25%) | |||
| 6.5 | 字母倾向 | 评委是不是偏爱某个位置 | 各字母被选比例,应各约 25% | 均匀 | 22–28%,无位置偏见 | |||
| 6.6 | 成对 Elo | 同一题两个模型的台词,评委选更像本人的 | Bradley–Terry 拟合,平局各半,Elo = 400·log10(p) + 1000;没有标准答案,只当辅助 | 高 | 1067 / 1134 | 848 / 840 | 983 / 972 | 1102 / 1054 |
| 6.7 | A/B 位置偏向 | 成对比较的位置偏见 | 选 A 的比例,应约 50% | 50% | DeepSeek 评委 43% · Seed Lite 评委 54% | |||
| 6.8 | 评委自我偏好 | 评委同时是选手时偏不偏自己 | 自己当评委和别人当评委时的 Elo 差 | 小 | DeepSeek 自评 1102、他评 1054,差 48;成对比较里评委意见只有 70% 一致 | |||
层 7 · 人工校准:人只做一小池,用来校评委 已落地 答题页已生成,等答案
| # | 指标 | 怎么算 | 方向 | 状态 |
|---|---|---|---|---|
| 7.1 | 人工答对率 | 人在 docs/辨认题.html 上做同样的 40 道辨认题,答对 / 40 | 基线 | 等答案 json 回传 |
| 7.2 | 评委与人一致率 | 同一批题评委和人选同一字母的比例;低于人工答对率太多就换评委或改提示 | 高 | 同上 |
| 7.3 | 量表人工抽检 | 抽 20 条访谈回答让人打分,和评委打分算相关 | 高 | 待做 |
层 8 · 稳定性与元指标:尺子本身准不准 待做 程序打分
| # | 指标 | 测什么 | 怎么算 | 方向 |
|---|---|---|---|---|
| 8.1 | 换评委排名稳定性 | 评委从 DeepSeek 换成 Seed Lite,模型排名变不变 | 两份排名的 Kendall τ;辨认题上两评委给的排名目前一致(Qwen > DeepSeek > 豆包 > M2-her) | 高 |
| 8.2 | 换题集排名稳定性 | 换一个群聊场景排名变不变 | Kendall τ;要先有第二个场景 | 高 |
| 8.3 | 重跑方差 | 同题集同模型跑两次,各指标差多少 | 每个头部指标的标准差,决定多大差距才算真差距 | 低 |
| 8.4 | 评分者一致性 κ | 替代 6.4 的一致率,扣掉碰巧一致 | Cohen's κ | 高 |
| 8.5 | 题目难度加权 | 含糊的时刻(谁都能说的一句催促)权重降下来 | 项目反应理论 IRT:每题估难度和区分度,分数按题加权 | 更稳的排名 |
四、跑一轮多模型测试
模型 id 见 agent/social/models.py,现有:qwen-character、m2-her、doubao-character、deepseek-flash、deepseek-flash-v4、seed-lite、seed-mini。自训模型按 OpenAI 格式起服务后加一条登记即可参加。下面把 MODELS 换成要比的清单,TAG 换成这轮的名字。
cd ~/code/amicura-lab06-social/agent
MODELS=qwen-character,m2-her,doubao-character,deepseek-flash
TAG=round3
# 层 1 调度与协议:完整心跳协议,20 个时刻
uv run python -m social.replay --models $MODELS --mode full --cuts 8,16,24,32,40 --out .cache/social/replays/full-$TAG.jsonl
uv run python -m social.ruler .cache/social/replays/full-$TAG.jsonl --by model
# 层 2 入戏与台词:冻结题集 40 题,演员模式
uv run python -m social.replay --models $MODELS --set .cache/social/bench/actor-支付改版-v1.jsonl --out .cache/social/replays/actor-$TAG.jsonl
uv run python -m social.ruler .cache/social/replays/actor-$TAG.jsonl --by model
uv run python -m social.ruler .cache/social/replays/actor-$TAG.jsonl --by model+agent
# 层 4 探针:4 角色 × 3 事件 × 2
uv run python -m social.probe --models $MODELS --judge deepseek-flash --each 3 --out .cache/social/replays/probe-$TAG.jsonl
# 层 5 量表:BFI 和 ECR-R
uv run python -m social.scales --scale BFI --models $MODELS --judge deepseek-flash --out .cache/social/replays/scale-BFI-$TAG.jsonl
uv run python -m social.scales --scale ECR-R --models $MODELS --judge deepseek-flash --out .cache/social/replays/scale-ECR-$TAG.jsonl
# 层 6 评委:辨认(含控制题、导出人工答题页)和成对
uv run python -m social.judge --file .cache/social/replays/actor-$TAG.jsonl --task identify --judges deepseek-flash,seed-lite --controls --sheet ../docs/辨认题-$TAG.html
uv run python -m social.judge --file .cache/social/replays/actor-$TAG.jsonl --task pair --judges deepseek-flash,seed-lite
# 层 7 人做完答题页后
uv run python -m social.judge --file .cache/social/replays/actor-$TAG.jsonl --task identify --judges deepseek-flash,seed-lite --human ~/Downloads/辨认题答案.json
- 层 1:20 次
- 层 2:40 次
- 层 4:24 次 + 24 次评委
- 层 5:BFI 176 次 + 约 24 次评分;ECR-R 144 次 + 约 20 次评分
- 层 6:辨认 40 + 28 控制题,每评委一遍;成对每新增一个模型多 40 × 已有模型数对
四个模型一轮全跑约 1,900 次被测调用、600 次评委调用,一小时内能完。
- 在
models.py的 BUILT_IN 里登记 baseUrl 和 model 名 - 跑上面的全套,它就出现在每张表里
- 自训模型额外能跑 3.5 似然辨认,这是训练过程里最该盯的那个数
五、读数注意
- 先看程序分,再看评委分。出戏率、打字习惯差、编造率这些不会因为换评委而变;辨认率、Elo 会。评委分里以辨认为准,Elo 只做参考。
- 评委不要当选手。DeepSeek Flash 当评委时在成对比较里给自己 1102 分,Seed Lite 给它 1054。有新模型参赛时至少用一个与所有选手无关的评委。
- 角色和模型分开归因。陆一鸣谁演辨认率都在 55% 左右,这是卡的问题;M2-her 演谁都出戏,这是模型的问题。所以每条指标都要能按
--by model+agent切。 - 量表有系统偏差。宜人性全体偏高、神经质全体偏低,比较模型时看相对差,别看绝对值;要修的是「演不讨喜角色」这件事。
- 没接话不是错。探针的 evaded 在吵架场景里是本色,只在它过高(M2-her 62%)时当成躲问题的信号。
- 只有一个场景。所有结论都是「支付改版」这一个群聊上的;下一步用实验 06 自己的多 agent 模拟器无头跑新群聊、切点冻结,扩成多场景题集,再用 8.2 看排名稳不稳。
- 差距要大于重跑方差。在 8.3 做出来之前,40 题上两三个百分点的差别不要当成结论。
相关页面:六类评测方法的对比在 docs/角色扮演评测方法.html;人工辨认答题页在 docs/辨认题.html;代码说明在仓库 README「训练场:回放和尺子」。