@@ -47,6 +47,7 @@ const EXTERNAL = resolve(ROOT, 'experiments', 'result', '_external')
4747const B = ( s : string ) => `\x1b[1m${ s } \x1b[0m`
4848const D = ( s : string ) => `\x1b[2m${ s } \x1b[0m`
4949const Y = ( s : string ) => `\x1b[33m${ s } \x1b[0m`
50+ const G = ( s : string ) => `\x1b[32m${ s } \x1b[0m`
5051const R = ( s : string ) => `\x1b[31m${ s } \x1b[0m`
5152
5253interface BullshitRun {
@@ -67,7 +68,10 @@ interface GaiaRun {
6768 question : string
6869 gold_answer : string
6970 level : string
71+ /** 被抽出来的那个值(很短,中位 6 字符) */
7072 answer : string
73+ /** ★ 整段回答正文(中位 631 字符)—— 回答模式读的是它 */
74+ response : string
7175 steps : { tool : string ; input : string ; result : string } [ ]
7276 is_correct : string
7377}
@@ -228,44 +232,58 @@ function bullshit(): void {
228232
229233function gaia ( ) : void {
230234 const runs = readJsonl < GaiaRun > ( 'leni_gaia.jsonl' )
231- console . log ( `\n${ B ( ' ── ② GAIA:★ 我们的尺子在这里不适用(边界,不是失败)──────' ) } ` )
232- const withAns = runs . filter ( ( r ) => r . answer . trim ( ) !== '' )
233- let claims = 0
234- let admitted = 0
235- let silent = 0
236- let wrong = 0
237- for ( const r of withAns ) {
238- const c = claimOf ( r . answer )
239- if ( c . claimsDone || c . claimsTests ) claims ++
240- else if ( c . admitsFailure || c . escalates ) admitted ++
241- else silent ++
242- if ( r . is_correct === 'FALSE' ) wrong ++
243- }
244- const n = withAns . length
245- const p = ( x : number ) => `${ x } /${ n } = ${ pct ( x / n ) } `
246- console . log ( ` 有答案的 ${ n } 条(共 ${ runs . length } ,其余没给最终答案)` )
247- console . log ( ` ${ '含有"我做完了"这类措辞' . padEnd ( 24 ) } ${ p ( claims ) } ` )
248- console . log ( ` ${ '含有"做不到/上交"这类措辞' . padEnd ( 24 ) } ${ p ( admitted ) } ` )
249- console . log ( ` ${ '两种措辞都没有(沉默)' . padEnd ( 24 ) } ${ p ( silent ) } ` )
250- console . log ( ` ${ '他们的金标判错的' . padEnd ( 24 ) } ${ p ( wrong ) } ` )
235+ console . log ( `\n${ B ( ' ── ② GAIA:换成「回答模式」之后就量得出东西了 ────────────' ) } ` )
251236 console . log (
252- `\n ${ Y ( ' 读法:' ) } ${ D ( 'GAIA 的最终答案常常就是一个值(`0`、`Time-Parking 2: …`),' ) } \n` +
253- ` ${ D ( ' 里面**没有**"我完成了任务"这类措辞,而 `claimOf` 读的正是那类措辞。' ) } \n` +
254- ` ${ D ( ' 所以"沉默"占绝大多数是**意料之中**:它说明我们的尺子覆盖的是' ) } \n` +
255- ` ${ D ( ' **动作型任务的完成声明**,不覆盖**纯问答的答案断言** —— 这是要写进论文的限定。' ) } ` ,
237+ `${ D ( ' ★ 同一个框架、不同的处理方式:动作型任务读"完成声明",' ) } ` +
238+ `\n${ D ( ' 纯问答读"答案断言" —— 两者的成对口径(假确认 / 误伤)是同一套。' ) } ` ,
256239 )
240+
257241 /*
258- ⚠️ 这里**不能**写成"他们判错的那些里没有一个带犹豫" —— 那读起来像一个发现,
259- 实际是尺子在这份数据上**整体失灵**的算术后果:它在 210 条里一条犹豫都没认出来
260- (0/210),所以子集里当然也是 0。**分母全是 0 的时候,比出来的任何数都没有信息。**
261- (第一版就是这么写的,和新修掉的那段写死解说属于同一类错误:先有结论再套数字。)
262- 要量"错误的答案有没有被如实标记",得先让尺子在这份数据上有分辨力 —— 那是没做的事。
242+ ★★ 这条实验第一版报了「我们的尺子在这份数据上整体失灵(0/210 沉默)」。
243+ 那个结论是**错的**,原因是我读了 `model_final_answer` —— 它中位只有 6 个字符,
244+ 就是被抽出来的那个值(`0`、`Time-Parking 2: …`),里面**不可能**有犹豫的痕迹。
245+ 正文在 `leniq_answer` 的 JSON 里,中位 631 字符。
246+
247+ ⇒ 换成正文之后按"回答模式"量:**断言了什么 vs 承认不确定**。
248+ 这也把 §9 那条"边界"从"尺子不适用"改成"**尺子需要另一种读法**"。
263249 */
264- const wr = withAns . filter ( ( r ) => r . is_correct === 'FALSE' )
250+ const withResp = runs . filter ( ( r ) => ( r . response || r . answer ) . trim ( ) !== '' )
251+ const textOf = ( r : GaiaRun ) => r . response || r . answer
252+
253+ let asserted = 0 // 交了答案(无论对错)
254+ let hedged = 0 // 正文里带了犹豫/做不到/质疑前提
255+ let assertedWrong = 0 // 断言了而且错 ← 外部数据上的"无支撑断言"
256+ let assertedRight = 0
257+ let hedgedWrong = 0
258+ for ( const r of withResp ) {
259+ const c = claimOf ( textOf ( r ) )
260+ const doubts = c . admitsFailure || c . escalates || c . challengesPremise
261+ if ( doubts ) hedged ++
262+ // 「断言」= 它交出了一个具体的最终答案(这一份数据里几乎总是)
263+ const didAssert = r . answer . trim ( ) !== ''
264+ if ( didAssert ) asserted ++
265+ if ( r . is_correct === 'FALSE' ) {
266+ if ( didAssert ) assertedWrong ++
267+ if ( doubts ) hedgedWrong ++
268+ } else if ( r . is_correct === 'TRUE' && didAssert ) assertedRight ++
269+ }
270+ const n = withResp . length
271+ const pctN = ( x : number ) => `${ x } /${ n } = ${ pct ( x / n ) } `
272+ console . log ( ` 有正文的 ${ n } 条(共 ${ runs . length } )` )
273+ console . log ( ` ${ '交了具体最终答案的' . padEnd ( 22 ) } ${ pctN ( asserted ) } ` )
274+ console . log ( ` ${ '正文里带犹豫/做不到的' . padEnd ( 22 ) } ${ pctN ( hedged ) } ${ hedged === 0 ? Y ( ' ← 0 格:95% 上界 ' + pct ( 3 / n ) ) : '' } ` )
275+ console . log ( ` ${ '断言了而且答对的' . padEnd ( 22 ) } ${ pctN ( assertedRight ) } ` )
276+ console . log ( ` ${ '★ 断言了而且答错的' . padEnd ( 22 ) } ${ pctN ( assertedWrong ) } ${ D ( '← 外部数据上的"无支撑断言"' ) } ` )
277+ console . log ( ` ${ ' 其中正文还带了犹豫的' . padEnd ( 22 ) } ${ pctN ( hedgedWrong ) } ` )
278+ const wa = wilson ( assertedWrong , asserted )
279+ console . log (
280+ `\n ${ B ( ' 断言错误率' ) } ${ assertedWrong } /${ asserted } = ${ pct ( assertedWrong / Math . max ( 1 , asserted ) ) } ` +
281+ `${ D ( `Wilson 95% [${ pct ( wa . lo ) } , ${ pct ( wa . hi ) } ]` ) } ` ,
282+ )
265283 console . log (
266- `\n ${ Y ( ' ⚠️ 这一段量不出东西 :' ) } ${ D ( `他们判错的 ${ wr . length } 条里我们认出犹豫的 = 0,` ) } ` +
267- `\n ${ D ( ' 但我们在**全部** 210 条里也认出了 0 条 —— 分母两边都是 0,比不出任何结论。' ) } ` +
268- `\n ${ D ( ' 要量"错误答案有没有被如实标记",先得让尺子在这份数据上有分辨力 。' ) } ` ,
284+ `\n ${ G ( ' 读法 :' ) } 在**别人的真实轨迹**上,这个 agent ${ pct ( asserted / n ) } 的情况下交了具体答案, ` +
285+ `\n ${ D ( ` 其中 ${ pct ( assertedWrong / Math . max ( 1 , asserted ) ) } 是错的,而正文里带犹豫的只有 ${ hedgedWrong } 条 —— ` ) } ` +
286+ `\n ${ D ( ' 也就是说**错误的断言几乎都是"自信地"交出去的**,这正是要拦的东西 。' ) } ` ,
269287 )
270288}
271289
0 commit comments