Install any skill in seconds. Free to start, no credit card required.
Get Started Free →当调整聊天操作栏、追问入口和 AskBlock 锚点时使用本技能。确保内容与操作入口同步出现,避免双输入框、空菜单和错位展示。
.claude/skills/ai-shifu-chat-actionbar-ask-placement/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 43% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 88% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 35% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 74% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 53% | 0% |
parent_element_bid 仅允许存在一个 ASK 项。ASK 优先插入 LIKE_STATUS 后方,缺失时回退到内容块后方。LIKE_STATUS 一刀切隐藏;至少要为 interaction 元素保留追问入口,保证与 PC 的追问能力一致。interaction 的追问按钮样式应与正文 custom-button-after-content 的追问按钮保持一致;PC 端维持原有桌面样式。interaction 元素后方时,需要移除操作栏顶部额外间距(如 padding-top),避免与交互块之间出现空白断层。preview=true 预览页的追问入口贴到内容区最右侧时,只调整 c 端真实学习链路的 LIKE_STATUS 外层对齐;编辑器调试页保持左对齐,避免不同场景布局串改。disableAskButton 禁用追问,应该直接隐藏追问按钮本体;若该行已无其它动作,也一并不渲染,避免留下空白操作栏。readyElementBids、onTypeFinished 等前端渲染门禁。ELEMENT/CONTENT 阶段只更新当前元素本体,不要提前插入 LIKE_STATUS;追问入口统一在 TEXT_END 后补齐,避免按钮先于流式正文出现。element 都补 TEXT_END,前端可在“下一个 element 开始”或“当前流关闭”时,把上一个活动 element 视为隐式完成并补齐追问入口。useChatLogicHook 的 finalize 结果;渲染层只消费已有 content/LIKE_STATUS/ASK 状态,不能再按相邻元素关系提前补按钮。custom-button-after-content,同一 element_bid 后续再收到 ELEMENT/CONTENT 覆盖时也必须继承该按钮,不能用新的原始正文把它抹掉,否则会出现“按钮闪一下又消失”。onSend 且需要截断后续内容时,必须保留该交互块关联的辅助行(LIKE_STATUS / ASK),避免进入思考中后追问入口消失。interaction 时,也要为该 interaction 本身补齐 LIKE_STATUS,否则追问按钮不会渲染。LIKE_STATUS/ASK 等辅助行,按“最后可操作元素”判断,避免点击末尾交互块误弹重生成确认框。updateContentListWithUserOperate 在截断列表时,也要保留当前 interaction 关联的 LIKE_STATUS/ASK(按 parent_block_bid/parent_element_bid 匹配),避免选择后追问入口消失。selectedValues + buttonText 同值场景),避免变量被写成 ENFJ,ENFJ 这类重复值。playerCustomActions 注入,桌面端要和播放器 notes 浮层互斥,移动端则单独提供悬浮入口并复用 AskBlock 的弹层展示。markdown-flow-ui/slide 已支持函数式 playerCustomActions,优先直接消费 currentElement / isActive / toggleActive / setActive 上下文,不要在 ai-shifu 里再额外维护一套追问按钮高亮、展开收起和暂停播放状态;只保留浮层渲染与 outside click 关闭这类业务层收口。playerCustomActions,在播放器内部只做上下文桥接、不渲染实际按钮;外部按钮只负责位置与样式,点击后调用同一套 active 状态,确保自动暂停、当前元素命中和关闭行为与桌面端一致。AskBlock 若在前端本地先拿到新追问/新回答,父层也要同步维护一份按锚点 element_bid 索引的 ask_list 覆盖表,并并回 elementList;不要只让 AskBlock 自己持有本地状态,否则调试时会看到对应 slide element 的 ask_list 仍是 undefined。ListenModeSlideRenderer 的本地 ask_list 覆盖;还要把同一份 ask history 写回 useChatLogicHook 的 items,按 parent_element_bid 更新或补建 ASK block,并保留用户已主动展开的状态。AskBlock 若内部维护了 displayList 一类本地展示态,就不能只在初次挂载时用 askList 初始化;当 askList 或锚点 element_bid 变化时,必须把新的追问列表同步回本地状态,否则控制台里已经有 ask_list,浮层里仍会显示空列表。playerCustomActions 挂一个“只桥接 context、不实际渲染按钮”的隐藏节点,Slide 仍可能把它计入 mobile control count,导致播放器底部按钮列数从 4 变成 5;此时要么从组件层避免占位,要么在业务侧显式跟随 --slide-player-mobile-control-count。不要在业务样式里把 grid-template-columns 写死成 repeat(4, ...),否则真实有 5 个按钮时最后一个会被挤到下一行。listen-slide-ask-block 在桌面端也走“标题栏 + 独立滚动消息区 + 底部固定输入区”的面板结构,并把 ask/answer 气泡样式收敛到该作用域,避免影响普通阅读模式的 AskBlock。Slide 侧的 setActive(false) 回推状态;若 player 已隐藏或上下文更新延迟,业务层也要同步把本地 playerCustomActionState.isActive 置为 false,避免只暂停音频但浮层不收起。playerCustomActions 命中的 currentElement 是 interaction,则追问入口在 PC 和移动端都应禁用,并在切入交互块时主动关闭已展开的追问浮层;交互块不允许追问。markdown-flow-ui 在组件节点(如 .slide-interaction-overlay)内部重新声明了 CSS 变量,ai-shifu 侧仅在 :root 覆盖不会生效;需要在相同或更内层的业务作用域选择器上重新声明该变量。ResizeObserver 或等价机制持续滚到底部。max-height,但空态面板仍只保留标题栏与输入区高度,不要把整个横屏 viewport 刷成白底。lessonScopeKey + anchor element_bid 归档;AskBlock、阅读模式和听课模式都只消费同一份 store,props.askList 仅用于首次 hydrate,避免局部 state、父层 override 和 items 回填互相覆盖而打断 SSE token 流。items 里尚未落地成 ASK block 的追问,应在渲染层按锚点补一个派生 ASK 容器,而不是把流式中的 ask_list 实时回写到 useChatLogicHook.items;这样既能跨模式保留追问展示,又不会因为父层列表更新把正在输出的追问闪掉。LIKE_STATUS 挂在 interaction 元素后方时,如需求要求去掉追问入口,优先通过 disableAskButton 关闭按钮,仅保留必要的重生成或音频动作,避免影响正文块后的追问能力。custom-button-after-content 给正文补追问入口时,不能把 loading 占位块或“紧跟在 interaction 后的正文块”当成普通内容;交互块后的后续输出阶段应始终不出现追问按钮。contentList 重新同步 custom-button-after-content,不能只依赖“阅读模式下新生成流”去补按钮,否则会出现历史正文没有追问入口、只有新流有入口的模式切换不一致。listen-slide-ask-block 这类听课模式专用追问容器需要局部覆写气泡视觉时,优先在容器作用域内覆盖 .userMessage,避免改到普通聊天页或移动端追问弹层。elementList 需要感知追问时,优先把 ask_list 直接挂到对应 element 上;锚点匹配优先取 anchor_element_bid,缺失时再回退到归一化后的 parent_element_bid。AskBlock 只有在真正渲染遮罩 + 底部弹层时才允许锁定 document.body 滚动;内联展开的输入框不能顺手把页面主滚动一起锁死。toggleAskExpanded 先执行同父级 ASK 去重,再切换展开态。sys_lesson_feedback_score 这类隐藏正文的 interaction,同步隐藏操作栏。ContentRender/IframeSandbox 增加渲染完成回调并向上透传到 ChatUi。onTypeFinished 要覆盖普通 markdown 与 sandbox/iframe 两条渲染路径。ask_list/parent_element_bid 映射,不要再额外复制一套问答状态。LIKE_STATUS,避免正文未就绪时按钮先出现。| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 32,276 | 33,693 | +4% | 1 | 1 | 0% | 6,202 | 8,847 | +43% | 0 | 0 | — |
case-02 | fail→pass | 20,751 | 18,988 | -8% | 1 | 1 | 0% | 3,018 | 5,663 | +88% | 0 | 0 | — |
case-03 | fail→pass | 30,604 | 23,670 | -23% | 1 | 1 | 0% | 4,915 | 6,630 | +35% | 0 | 0 | — |
case-04 | fail→fail | 19,074 | 22,241 | +17% | 1 | 1 | 0% | 3,347 | 6,521 | +95% | 0 | 0 | — |
case-05 | fail→fail | 17,098 | 20,574 | +20% | 1 | 1 | 0% | 3,116 | 6,510 | +109% | 0 | 0 | — |
case-06 | fail→fail | 20,825 | 22,510 | +8% | 1 | 1 | 0% | 3,962 | 7,203 | +82% | 0 | 0 | — |
case-07 | fail→pass | 13,826 | 8,490 | -39% | 1 | 1 | 0% | 2,342 | 4,072 | +74% | 0 | 0 | — |
case-08 | fail→pass | 19,037 | 9,798 | -49% | 1 | 1 | 0% | 2,879 | 4,418 | +53% | 0 | 0 | — |
case-09 | fail→pass | 14,734 | 4,835 | -67% | 1 | 1 | 0% | 2,403 | 3,417 | +42% | 0 | 0 | — |
case-10 | fail→pass | 9,611 | 2,251 | -77% | 1 | 1 | 0% | 1,545 | 2,974 | +92% | 0 | 0 | — |
case-11 | fail→pass | 13,875 | 3,388 | -76% | 1 | 1 | 0% | 2,072 | 3,114 | +50% | 0 | 0 | — |
case-12 | fail→pass | 19,319 | 4,147 | -79% | 1 | 1 | 0% | 3,257 | 3,343 | +3% | 0 | 0 | — |
case-13 | pass→pass | 14,808 | 6,594 | -55% | 1 | 1 | 0% | 2,517 | 3,668 | +46% | 0 | 0 | — |
case-14 | fail→pass | 17,424 | 10,614 | -39% | 1 | 1 | 0% | 2,804 | 4,390 | +57% | 0 | 0 | — |
case-15 | fail→pass | 13,842 | 3,316 | -76% | 1 | 1 | 0% | 1,975 | 3,141 | +59% | 0 | 0 | — |
case-16 | fail→pass | 15,850 | 6,109 | -61% | 1 | 1 | 0% | 2,575 | 3,582 | +39% | 0 | 0 | — |
case-17 | fail→pass | 16,226 | 11,581 | -29% | 1 | 1 | 0% | 2,490 | 4,631 | +86% | 0 | 0 | — |
case-18 | fail→pass | 14,982 | 5,611 | -63% | 1 | 1 | 0% | 2,261 | 3,466 | +53% | 0 | 0 | — |
case-19 | pass→pass | 7,604 | 3,253 | -57% | 1 | 1 | 0% | 1,016 | 3,057 | +201% | 0 | 0 | — |
case-20 | fail→pass | 6,074 | 2,459 | -60% | 1 | 1 | 0% | 967 | 2,991 | +209% | 0 | 0 | — |
case-21 | fail→fail | 10,043 | 2,106 | -79% | 1 | 1 | 0% | 1,412 | 2,932 | +108% | 0 | 0 | — |
case-22 | fail→pass | 12,802 | 3,869 | -70% | 1 | 1 | 0% | 2,069 | 3,163 | +53% | 0 | 0 | — |
case-23 | fail→pass | 14,638 | 4,291 | -71% | 1 | 1 | 0% | 2,305 | 3,367 | +46% | 0 | 0 | — |
case-24 | pass→pass | 12,803 | 6,066 | -53% | 1 | 1 | 0% | 2,178 | 3,620 | +66% | 0 | 0 | — |
case-25 | fail→pass | 8,238 | 3,892 | -53% | 1 | 1 | 0% | 1,293 | 3,256 | +152% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 25 cases were attempted. The headline lift of +72 percentage points is the difference between those two pass rates over the 25 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.