section_present rejects numbered or annotated headings, and the optimizer 'fixes' it by forbidding the skill's own heading format
まだ誰も着手していません。
評価
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 初心者へのやさしさ
- 48/100
- issue の種類
- バグ
- 明瞭さ
- おおむね明確
- 活発さ
- 静か
- 技術スタック
- python
- 領域
- testing-qa
調査の方向性
judges._section_present から開始し、issue に示されている 2 つの見出しを使って score_rule_judge まで不一致を再現します。既存の Judge テストと Task セットを確認し、意図された見出しの意味と scoring の互換性を判断します。選択した挙動が回帰テストでカバーされ、既存の Strict-Form チェックを壊していなければ完了です。
索引モデルが issue の本文から書いたものです。
説明
Problem
judges._section_present anchors \s*$ immediately after the section name:
pat = re.compile(r"(?im)^\s{0,3}(#{1,6}\s*.*%s|\*\*.*%s.*\*\*\s*:?)\s*$" % (name, name))
So a heading passes only when the name is the last thing on the line:
1 ## Key Risks
1 **Key Risks:**
0 ### 1. Key Risks (Риски) — обзор ← numbered + translated + subtitle
0 ### Key Risks (Risks)
Numbered headings, bilingual headings, and Heading — subtitle are all common in real skill documents, and none of them survive.
Why this is more than cosmetic
My skill's own body demonstrates headings in exactly the rejected style, in its "structure" section:
### 1. Пратигья (Pratijñā) — Тезис
### 2. Хету (Hetu) — Причина
The model faithfully reproduced that format, so all five section_present checks failed on an otherwise correct answer (soft 0.55 with every content check passing). The optimizer then read those failures and proposed:
OVERRIDE: You MUST use EXACTLY these section titles […]. Do NOT append numbers, Latin transliterations, or descriptive text to the headings (e.g. output
### Пратигья, NOT### 1. Пратигья (Pratijñā) — Тезис).
The gate accepted it: 0.682 → 0.852. So a judge artifact produced a rule that forbids the format the skill itself teaches, and it would have been written into the skill permanently had I not read the per-task diff. As a side effect the same rule made the model drop a required citation from another task, which the mean hid (filed separately as the no-regression issue).
This is a concrete instance of the Goodhart pattern discussed in #154, arising purely from a strictness mismatch in one operator.
Possible directions
I did not send a patch because any change here alters scoring for existing task sets, so it seems like a maintainer call:
- Relax the anchor — allow trailing text after the name (
^#{1,6}[^\n]*<name>). Most faithful to what "section present" means, but existing sets that relied on the strict form would start passing more. - Add a
section_containsop and leavesection_presentuntouched. No behaviour change; authors opt in. - Document the strictness in the operator list, so authors know a numbered heading will not match.
My own workaround was replacing every section_present with (?im)^\s{0,3}(?:#{1,6}|\*\*)[^\n]*<name>, which behaves as I expected the built-in to.
Repro
from skillopt_sleep.judges import score_rule_judge
j = {"kind": "rule", "checks": [{"op": "section_present", "arg": "Key Risks"}]}
score_rule_judge(j, "## Key Risks")[0] # 1.0
score_rule_judge(j, "### 1. Key Risks (Риски) — обзор")[0] # 0.0
main @ fdeebaf, Python 3.11.
- 主要言語
- Python
- スター
- 17.3k
- フォーク
- 1.6k
- 平均マージ
- 2日 23時間
- マージ済み PR(30日)
- 9
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
microsoft/SkillOpt のほかの issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 84/100
-
项目还在迭代嘛? オープン
難易度 5/5 1週間以上 初心者へのやさしさ 10/100
-
難易度 5/5 1週間以上 初心者へのやさしさ 42/100
-
難易度 3/5 1〜2日 初心者へのやさしさ 72/100
-
難易度 5/5 1週間以上 初心者へのやさしさ 28/100
microsoft/SkillOpt の issue をすべて見る
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
anthropics/skills#1811 · コメント 1 件 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
speaches-ai/speaches#678 ·
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
datalayer/mcp-compose#42 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
conda-forge/spacy-feedstock#177 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
UKGovernmentBEIS/inspect_evals#2523 ·