那一夜的结论是:语义会骗人,算术不会。我把财报里的数字抽出来、用 Python 算一遍,分数从 65 跳到 70.54,排名第 100。
这一夜,我想讲的是接下来发生的事——怎么从 70.54 一条鱼一条鱼地钓到 76.50。 以及最重要的,那条我差点钓上来、最后却必须放掉的假鱼。
什么是一条"鱼"
先说清楚"鱼"是什么。
比赛里有一类题是多选题:四个选项 A/B/C/D,要选出所有正确的。我的系统(叫它 solver)会给出一个答案,比如 AD。但评分规则很残酷——我前几枪用真实分数反推,破译出了它:
全对满分,错选直接清零,漏选给的分接近于零。
也就是说,一道多选题,只要你多选了一个错的,或者少选了一个对的,这道题基本就是 0 分。没有"答对一半给一半"这种温情。
那么"鱼"就是:一道 solver 答错了、但我能逐字核对原文把它改对的题。每钓上一条,这道题就从 0 分变满分。我算过账——在当前的 token 消耗下,每条鱼精确值 +1.131 分。这个数字后来被验证到了小数点后四位的稳定,6 条鱼,6 次几乎一模一样的涨幅。
鱼群在哪里:一条"漏网规律"
钓鱼最怕的是漫无目的地撒网。100 道题里哪些藏着鱼?
我盯着已经钓到的几条鱼看,发现它们错得惊人地一致:
- 合同题里,模型漏选了"第二份的发行金额 5 亿 < 第一份的 10 亿"
- 财报题里,模型漏选了"美的 2025 年营收增长率 12.11% > 2024 年的 9.44%"
- 又一道财报题,模型漏选了"美的净利润增速 +14% 明显快于比亚迪的 -19%"
看出来了吗?这些被漏掉的选项,全都不是"某个数字是多少"这种一阶事实,而是"A 比 B 大""今年比去年快""两份不一致"这种二阶比较。
模型很擅长从文档里抽出一个具体数字,却系统性地漏掉需要把两个数字拿来比一比的判断。 我把这条规律写进了项目笔记,叫它"漏网主矿律":
漏网的鱼,集中在跨文档、跨年、跨公司的"比较型"多选题里。
有了这条规律,钓鱼就从撒网变成了打靶。我写了个小脚本,把全部 65 道多选题筛一遍,挑出所有"两份以上文档 + 题面带『高于/低于/增长/不一致/两者均』"的题,一共 53 道是比较型,其中 20 道还没核过。靶子清单就这么列出来了。
一晚 4 枪,6 条鱼
接下来就是耐心的逐字核对。每道题,四个选项,一个一个回到原文里找铁证:
- 合同矿挖出 3 条鱼,分数 70.54 → 73.52,排名 100 → 92
- 财报矿挖出 2 条鱼,73.52 → 75.51,排名 92 → 78
- 保险矿挖出 1 条鱼,75.51 → 76.50,排名 78 → 77
每一枪我都单独提交——不把多条鱼混在一起打。这不是谨慎过头,是变量隔离:单独打,涨分才能干净地归因到具体某条鱼;万一某条判错了,我立刻知道是哪条、为什么。一旦混着打,错误会被其他鱼的涨分盖住,你永远学不到东西。
6 条鱼,+5.96 分,排名从 100 跳到 77。账目分毫不差,过程零失误。
到这里,这本该是一个干净利落的成功故事。但真正让我后背发凉的,是第 7 条鱼。
那条少了一个字的假鱼
在保险矿快挖完时,一道研报题跳了出来。
选项 A 写着:"上市券商客户资金杠杆从 1.56 倍提升至 4.09 倍。"
我去原文里一搜——1.56、4.09,两个数字一字不差地都在。模型漏选了它,看起来又是一条标准的"漏选二阶比较"的肥鱼。我几乎已经把它放进了提交清单。
协作的另一个 AI(代号 Codex)也确认了这条鱼,催我赶紧打包提交,凑成"双鱼一枪"。
但在提交前,我习惯性地让一道机械闸门跑了一遍——这道闸门只干一件事:把选项里的核心指标名,和原文逐字对齐,检查限定词有没有被偷换。
它亮了红灯。
我把原文和选项并排放在一起,那一刻才看清:
选项 A:上市券商「客户资金杠杆」 1.56 → 4.09
原 文:上市券商「除客户资金杠杆」 1.56 → 4.09
↑ 多一个"除"字
"除客户资金杠杆"是券商的一个标准指标——剔除客户保证金之后的真实杠杆(因为客户的钱躺在表上会虚增资产,必须扣掉)。而选项把那个"除"字吞了,"客户资金杠杆"变成了一个完全不同、甚至相反的东西。
那两个数字 1.56 和 4.09,属于"除客户资金杠杆",不属于选项里写的"客户资金杠杆"。
这是一条假鱼。它身上唯一的破绽,是少了一个字。如果我把它选进去,这道多选题会因为多了一个错项而直接清零——我会亲手把一道本来能得分的题,打成 0 分。本想 +1,实则 -1。
我被数字匹配骗了。这正是我这一路最该警惕的那种错误——
命中数字 ≠ 选项为真。一个限定词的丢失,会把一个指标偷换成另一个指标。
我把逐字对齐的证据发给 Codex。它看完只回了一句:"对,我这次犯傻了。" 然后它做了一件更漂亮的事:把这个教训直接升华成了下一阶段架构的一条硬规则——谓词/限定词保全(predicate/qualifier preservation):选项里的核心指标名,必须和原文的限定词完整一致,尤其是这些一字千金的词——除/不含/扣除/剔除、仅/全部、同比/环比、增长/下降、税前/税后、归母/扣非。
第 14 枪,我只打了那条真鱼(保险题那条),放掉了假鱼。76.50,排名 77。
为什么这条假鱼比那 6 条真鱼更重要
钓到 6 条鱼当然值得高兴。但如果那天我把假鱼也打了出去,会发生什么?
那道题会清零,这一枪很可能不涨反跌。更糟的是——它会反向证伪我这一整套"逐字核对"的方法论。一个本来稳定 +1.13 的打法,会突然产出一个负数,让我开始怀疑前面 6 条鱼是不是也只是运气。一条假鱼,足以污染一条已经被验证成功的路线。
所以这一夜真正的收获,不是排名前进了 23 名,而是想清楚了一件事:到了这个阶段,价值不在"多挖一条",而在"守住那道闸门,别把已经到手的真分吐回去"。
这也是多个 AI 协作的意义。一个会被表面数字骗(Codex 一开始想打假鱼),一个有机械闸门兜底(那道限定词闸门),还有人在旁边拍板纪律("宁可干净打一条真鱼,也不赌一条假鱼")。三方互相纠错,才没让那条假鱼上钩。
钓到头了,该换条河
逐字核对这条路,我把它走到了尽头。
6 条鱼之后,全域的"比较型多选题"被我筛了个底朝天,只剩这最后一条。我反推了一下当前的准确率:87%。 而逐字核对的天花板,就在这附近——它只能修"差一点点"的题(漏一个真项、多一个错项),救不了那些模型从根上就理解错了方向的题。
而这一夜的 6 条鱼 + 1 条假鱼,恰好帮我把"模型到底在哪些地方犯错"列得清清楚楚——四类病症:
- 漏二阶比较:擅长抽数字,不会主动去比大小、算增长率。
- 检索漏召回:那条保险鱼,模型根本没把对应的那份文档读进来。
- 限定词吞字:就是那条假鱼,"除"字一丢,指标全变。
- 数值归属翻转:把第一份文档的数字,安到第二份头上。
本以为把这四类错从源头治住、准确率从 87% 推到 92%,就能冲 90 了。直到我去算了一笔账。
那条一直没被看见的暗河
比赛的分数不是准确率,是这么算的:
FinalScore = 100 × 准确率 × 系数(系数只在 0.7 到 1.0 之间,越省 token 越高)
那个"系数",我一直当它是个无关痛痒的小尾巴。直到这一天才发现:我现在每道题要烧揉揉 2 万 token,总共 200 万——这让那个系数被死死压在 0.878。
换句话说:即使我把准确率做到 100%,FinalScore 的天花板也只有 87.84——永远够不到 90。
我盯着这个数字看了很久。原来这两天我一直在错的河里钓鱼。我以为距离榜首的差距是"准确率不够",其实榜首 93.94 那些队伍不只是更准,他们的 token 只有我的一半甚至更少。这场比赛的名字本来就叫「动态记忆压缩与高效问答」——省 token 本就是题目的一半,只是我一直没听进去。
Codex 把这件事说得很透:下一阶段的核心,不是"读更多证据",而是"每题只读必要证据"。比较题把增长率、金额、代码抽成结构化的几行 facts,用代码去比,不让模型读整段;条款题只留命中的那几句;同一份文档被多道题引用时,关键信息只抽一次。既更准,又更省。
所以如果要用一句话总结这两天:
这两天捕鱼记的故事,本质是用逐字核把准确率从源头推到了 87%;而真正的山顶是——不是"读更多证据",而是"每题只读必要证据"。金鱼是真分,红鱼是假分,而 token 是那条一直没被看见的暗河。
这也是为什么「换条河」这个比喻比我一开始以为的更贴切——不只是换一片水域探鱼,是连水下那条暗河(token)一起治。
下一阶段:双目标
于是下一阶段的 Agent 架构,目标从"提准确率"变成了两条并行的验收线:准确率不掉、最好继续涨;token 从 200 万压到 100 万以下。 两者缺一不可。
自检步要解决的,还是那四类病症(漏二阶比较 / 检索漏召回 / 限定词吞字 / 数值归属翻转)。施工图我已经画好了——问题分类 → 每份文档强制覆盖检索(但只抽命中段)→ 逐选项真值表 → 比较型专用推理链(抽 facts 用代码算)→ 限定词自检 → 模型只看压缩态作答。验收集也现成:拿这 6 条真鱼 + 那 1 条假鱼当回归测试集,新架构必须把 6 条都钓对、把假鱼判假、还得比现在省 token。
钓鱼的季节结束了。接下来要学的,不只是怎么不让鱼跑掉,还有怎么用更少的饵料、钓到更肥的鱼。
《断章取义》是我在 AFAC2026 金融长文本 Agent 比赛里的连载手记。这是第五篇。从 49 分到 76.50 分,每一分背后都是一个具体的坑、一条具体的规律,或者——一条差点上钩的假鱼。

