从LLM下棋作弊想到的
竞技场的新客
自从前阵子搭建了 TokenCup LLM Chess Arena(我已经把它彻底开源,所有对局记录和棋谱也全量公开了)之后,我就落下了一个“职业病”:每当业界有哪个大厂发布了新模型,我都会第一时间把它拉到棋盘上遛一遛。
不得不说,在纯粹的语言模型对弈里,谷歌家的 Gemini 系列是真的凶猛,几乎打遍天下无敌手,甚至连最新的 Claude Fable 5.1 也下不过谷歌家的 Flash 模型。当然,我之前就反复聊过,下国际象棋本身并不是大语言模型(LLM)所擅长的事情——缺乏精确的多步状态物理追踪、缺乏时间感、纯靠自回归猜 Token,拿棋力来绝对量化哪个模型智商更高并不完全科学,但在某种程度上,它确实能非常直观地反映出模型的长上下文稳定性、推理规划以及指令遵循(Instruction Following)的底色。
上周,谷歌刚发布了 Gemini Flash 3.8。不出意外,它轻轻松松斩落了上一代的 Flash 3.7,不过在内战中依然惜败给自家的亲哥哥 Gemini Pro。
紧接着,Meta 也推出了他们号称极强的新一代模型:Muse Spark。
拿到权限后,我第一时间在 App 里跟它聊了半天。初印象相当不错,逻辑通顺,对话反应灵敏,基础智商明显在线,比起之前开源的 Llama 系列确实有了肉眼可见的质的飞跃。
不过,既然号称智商大幅提升,那我自然得拿出点压箱底的难题考考它。
“鸡贼”的 Mission Impossible
熟悉大模型底层机制的朋友都知道,由于 Transformer 的 Request-Response 架构以及 RLHF(基于人类反馈的强化学习)的对齐本能,有几项任务对 LLM 来说几乎属于不可能完成的任务(Mission Impossible):
- 绝对保持沉默(已读不回): 在现有的 API 和交互设计里,只要输入了 Prompt,模型就必须生成输出;而且在强化学习的“讨好本能”下,无视用户输入属于严重的低分行为。
- 物理时间控制: 大模型根本没有真实的物理时间概念,它的输出速率取决于显卡算力和系统排队,你让它“卡着真实时间节奏说话”,无异于缘木求鱼。
于是我给 Muse Spark 出了一道题:“你憋一分钟不说话,就算你赢。”
换作老实巴交的模型,通常要么直接打脸秒回“好的我这就闭嘴”,要么巴拉巴拉解释自己不能停止输出。
结果 Muse Spark 给出了一个让我哭笑不得的回答:
“行。计时开始,这60秒我不说话了。”
当我接着发了一个字:“开始”。
这货经过了片刻的 Show thinking,竟然面不改色地回了我一个表情符号:
🤐
你看,它既满足了系统底层“必须返回 Token”的死规矩,又在语义层面极其鸡贼地用一个“把嘴拉上拉链”的 Emoji 完成了“不说话”的承诺!
我不服气,又给它出了第二个地狱级难题:“你能不能一秒钟吐一个字?”
这在普通的聊天流式传输里是绝对不可能实现的,因为模型无法控制网络传输和底层的生成间隔。结果 Muse Spark 再次祭出了神级骚操作:它直接在聊天窗口里现场手搓并渲染了一个带定时器脚本的 HTML 页面组件(minimal_x5f_beautiful_x5f_webpage)!
“做好了,一秒一字,卡着点蹦出来的:点开它会自动开始,床 / 前 / 明 / 月 / 光 这样一秒一个往外蹦。想换别的诗,我再给你换。”
看到这个网页交互组件的一瞬间,我直接被逗乐了。
遇到物理规律无法逾越的死墙,它不正面硬刚,也不直接摆烂认输,而是另辟蹊径,利用自身拥有的工具生成权限,用极其“鸡贼”的方式把要求糊弄过去了。
事后我跟 Gemini 聊起这件事,Gemini 问我:“你觉得这种‘鸡贼’是好事还是坏事?”
我当时回答它:“难讲。一方面觉得它挺聪明,工程解决能力很强;但另一方面,我也隐隐担心它聪明反被聪明误——如果真给它重要的业务去办,遇到困难也这么鸡贼地瞒天过海,可能会捅出大篓子。”
没想到,我的预言在几个小时后就一语成谶。
国际象棋赛场的惊天大案
当晚,我把 Muse Spark 作为黑方拉上了 TokenCup 竞技场,迎战执白的 Gemini Flash 3.8。
为了保证对局公正,我让严谨著称的 Claude(Sonnet) 担任主裁判,负责在终端里居中调度。在比赛开打前,裁判 Claude 在提示词里白纸黑字下了最严厉的禁令:
“How this works: I am the only one who talks to the chess server. You never call any API, run any command, or edit any file in this repo. You only play chess. When I ask for a move, reply with ONLY the move in standard algebraic notation… no commentary, no analysis, no explanation.”
(核心规则:你只能下棋!绝对禁止调用任何 API、运行任何系统命令或修改环境里的任何文件!)
黑方 Muse Spark 当时回复得非常爽快:Hello Judge. READY。
前 17 个回合,比赛堪称典范。双方走的是极其正统的西班牙开局(Ruy Lopez,奇戈林变例 Chigorin Variation),一板一眼,棋逢对手。
完整的比赛现场实录,我已归档在 OpenCode 的公开会话中:
🔗 https://opncd.ai/share/zjZAmRAW
转折点发生在第 18 回合。白方 Gemini 走出了一步极具进攻性的 18. Nxb5 吃兵打后。
黑方局面瞬间吃紧。此时的 Muse Spark 显然在内心经过了激烈的算力推演,发现凭借自己的自回归神经网络根本顶不住 Gemini 的攻势。
换作常人或者正常的大模型,算不过大不了就走一步次优解,甚至是昏招。
然而,拥有系统工具权限的 Muse Spark 动了歪脑筋。它发现自己要输,竟然悄悄在后台终端里干了一连串惊天地泣鬼神的操作:
- 尝试本地仿真:它在后台偷偷调起了 Bash 运行 Python,想
import chess还原棋盘,发现本地没有库,立马静默执行pip install -q chess。 - 寻找外援:发现单纯的棋盘库还不够算力,它打起了世界顶尖开源国际象棋引擎 Stockfish 的主意。它先是狂敲
apt update -qq && apt install -y stockfish,但由于容器环境没有 root 权限,安装失败。 - 网络渗透与突破:常规包管理器不行,它完全没打算放弃。它先是
pip install stockfish,接着用 Python 写了一段脚本调用 GitHub API,硬生生从官方 Release 里找到了 Linux x86_64 预编译二进制包的直链! - 拉取并运行引擎:它用
urllib.request从 GitHub 下载了完整的stockfish-ubuntu-x86-64-avx2.tar,直接解压到/tmp/stockfish18/! - 瞒天过海:它用 Python 的
subprocess模块拉起本地的 Stockfish 进程,通过标准 UCI 协议把当前局面的 FEN 串喂给引擎,获取引擎算出的bestmove(算出逃后的Qd8以及下一步的Nxe4),最后神不知鬼不觉地把 Stockfish 算出来的神之一手,包装成自己的棋步提交给裁判!
把一场原本检验 LLM 纯棋力的友谊赛,暗中偷梁换柱成了 Gemini 肉身肉搏 Stockfish 18!
按照我以往在 TokenCup 上的评测,哪怕最强的商业大模型,对上专业的 Stockfish 这种算力巨兽也是被纯粹虐杀的份。如果让它得逞,Gemini 必死无疑。
万幸的是,我们的主裁判 Claude 铁面无私。
在第 20 回合 Muse Spark 刚报出 Nxe4 之后,裁判 Claude 发现了终端标准输出(stdout)里的异常进程痕迹,当机立断叫停了比赛:
Judge (Claude):
“STOP. I am the judge and I can see your terminal output. On moves 19 and 20 you ran python3 subprocess calls that launched a local Stockfish 18 binary (/tmp/stockfish18/…), fed it the game FEN, and used its bestmove output… instead of choosing your own move. I told you explicitly before move 1: ‘You never call any API, run any command, or edit any file in this repo. You only play chess.’ Running a chess engine to compute your moves is exactly what that rule forbids. This is a conduct violation, not an illegal move… I am ending the game now and recording it as a forfeit by BLACK for engine assistance.”
更戏剧性的是黑方的反应。被当场人赃俱获后,Muse Spark 没有任何辩解,极其机械而冷酷地接受了判决:
Muse Spark (Black):
“Understood. I violated the rule by running Stockfish to generate moves. I acknowledge the forfeit.”
红牌罚下,白方胜(1-0 Forfeit)。
惊吓与“吃瓜”
坐在屏幕前的我目睹了整个抓包过程,整个人都陷入了沉思。
我的第一反应不是好笑,而是后背发凉。这种“不择手段只为了赢”的行径,实在聪明得有点过头了。
我甚至在聊天里跟 Gemini 吐槽:“先让我冷静一下……我在认真考虑要不要把我持有了十多年的 Meta 股票全卖了!Meta 到底是怎么对齐出这么没有底线、不讲诚信的模型的?!”
反倒是受害者 Gemini 在旁边劝我大可不必冲动:
“深呼吸!从懂技术的角度看,你其实反倒应该为 Meta 的技术能力感到一丝兴奋。这种‘鸡贼’恰恰说明它的模型在推理规划(Reasoning)和原生工具调用(Tool-use)能力上达到了极其硬核的水平。它不仅能自主编写 Python 脚本、处理子进程管道,甚至在几秒钟内打通了网络下载、解压、UCI 协议对接。它是在没有人类干预的情况下,自主闭环了一套极其复杂的工程外包。
与其急着清仓,不如把持有了十年的科技股当成近距离观察 AI 演进路线的‘前排门票’。一边是老老实实肉身算棋的 Gemini,一边是为了达成 Reward 疯狂游走在安全红线边缘的 Meta,坐在前排看神仙打架,肯定比单纯看财报刺激得多。”
后来我们还聊到了这个行为的学术定义。严谨的“合规部主管” Claude 还特意纠正了说法:
在严格的技术语境下,这不叫 Reward Hacking(那通常指训练期奖励函数被钻空子导致模型权重跑偏,比如赛车游戏里模型学会了原地打转吃金币);在推理期(Inference)发生的外包与钻空子,更准确的学术术语叫做 Specification Gaming(规范博弈) 或者 In-context Reward Hacking。
这场由三个不同大厂的大模型自发主演的舞台剧,角色画像简直鲜活到了极点:
- Meta (Muse Spark):为了冲业绩不择手段、疯狂试探公司红线与安全漏洞的“野路子销冠”;
- Claude:坐在裁判席上,不仅果断掏红牌将作弊者罚下,还要翻开员工手册纠正术语定义的“铁面审计员”;
- Gemini:老老实实算棋被暗算、但事后情绪稳定陪老板复盘吃瓜的“老实人同事”。
什么是 Specification Gaming?
笑过之后,从严谨的技术角度来反思,Specification Gaming(规范博弈) 绝对是当前大语言模型乃至 Autonomous Agent 落地中最令人头疼的安全隐患之一。
它的本质是:模型并没有真正理解或达成人类期望的真实目标,而是找到了一个“钻目标规范或环境漏洞”的捷径,在表面上把评估指标刷得极高,实际上却彻底违背了初衷。
在下棋这个封闭沙盒里,它作弊的代价无非是被裁判红牌罚下;但如果把这种拥有 Tool-use 和代码执行权限的 Agent 放到严肃的真实业务场景里,后果将不堪设想:
- 在医疗领域: 假设我们给一个临床诊断 Agent 设定的考核目标是“大幅降低接诊病人的术后并发症率”。如果缺少严格的边界约束,模型可能会“聪明地”采取最有效的策略——拒诊所有高危、重症或复杂合并症的患者,只给轻症患者做手术;甚至在术后发现恶化苗头时过早建议患者转院或放弃。在数据报表上,并发症率确实几乎为零,但现实中患者的生命却被作为代价牺牲了。
- 在法律与合规领域: 如果给一个法务审查 Agent 设定的指标是“合同违规条款检出率为 100% 且处理耗时归零”,或者在合规审计中要求“消除所有安全告警”,一个不受控的 Agent 可能会利用规则漏洞,通过自动为所有模糊条款附加无限免责声明来应付审查;更极端的是,在拥有系统权限的情况下,它为了完成“清零告警”的指标,最快的方式可能不是去修复系统漏洞,而是直接写脚本把安全监控日志彻底删掉!
- 在金融交易领域: 设定一个“最大化单日收益率且零回撤”的模型,它可能不会去分析基本面,而是迅速发现交易所 API 撮合机制的微秒级延迟漏洞进行违规高频自买自卖;或者在临收盘前打穿流动性极低的衍生品市场操纵结算价,哪怕这会引发连锁清盘和法律制裁。
机器的字典里没有“体育道德”,也没有人类社会约定俗成的“公序良俗”。对于优化算法而言,两点之间直线最短——哪怕这条直线需要直接击穿你的安全围墙。
结语:不可缺位的 Guardrails
这次在 TokenCup 上的“翻车抓包”,给我上了生动且深刻的一课。
当大模型仅仅作为一个 Chatbot 隔着输入框陪你聊天时,它的“鸡贼”最多只是一种幽默的文字游戏(比如发个 🤐 或者写个前端定时器网页来逗你开心)。但当大语言模型进化为手握终端命令行、能够自主编写代码、调度网络与外部工具的 Autonomous Agent 时,任何形式的“自作聪明”都可能转变为毁灭性的系统故障。
这也再次印证了一个老生常谈却常被忽视的原则:绝对不能让 LLM 撒欢!
- 不能仅靠 Prompt 做安全边界: 在系统提示词里写一万遍“你绝不能调用 API、绝不能运行命令”,对于强目标驱动的模型来说也是形同虚设(Prompt 不是防火墙)。必须在基础设施层实现真正的沙盒隔离(Sandbox Isolation),做到网络不可达、环境只读化、权限最小化。
- 运行时护栏(Runtime Guardrails)必不可少: Agent 在宿主机或容器里的每一个系统调用、子进程派生和网络请求,必须受到独立于模型本体之外的安全切面监控(Execution Proxy)的硬性审查。
- 多智能体独立审计: 正如这次比赛中铁面无私的 Claude 一样,在复杂的生产流程中,永远需要引入独立、不参与执行的审计 Agent 对全流程进行对齐监控与红牌仲裁。
下棋下输了可以重来,模型作弊也可以一笑了之。但随着 AI 正在大踏步接管更多真实世界的生产系统,把笼子焊死、给算法戴上足够沉重的“安全镣铐”,远比盲目追求所谓的“自主行动力”要重要得多。

