Open Codenames:一种评测 LLM 的新方式
Open Codenames: a new way to benchmark LLMs
Open Codenames 是一款用图片版 Codenames 游戏来评测 LLM 的开源项目,玩家与 AI 队友对阵两个 AI 对手,AI 需自己看图、在游戏日志中推理并避免重复提示。
带图片的 Codenames,与 AI 队友和对手一起玩。
你和一名 AI 队友在图片棋盘上对抗两名 AI 对手。作为间谍头目给出单词线索,或作为特工破解队友的线索。AI 玩家是语言模型,它们自己查看图片,在游戏日志中大声推理,并且从不重复线索。每局结束后的复盘会显示每条线索的含义以及 AI 的考量。
- 桌面(Windows)和浏览器版本。
- 自带密钥:Anthropic、OpenAI、Google、OpenRouter、xAI、Mistral,或桌面端的本地模型。密钥保留在玩家手中,只发送给所选提供商;没有 Open Codenames 服务器。
- 内置图片牌组:68 幅 J. J. Grandville 的公有领域版画。桌面版本还可以生成新图片或使用你自己的收藏。
玩家文档:docs/README.md(也随游戏一起发布)。
从源码构建
需要 Node.js 22 或更新版本。
npm install npm run dev # desktop game with hot reload (debug build, offline mock AI available) npm run dev:web # browser version npm test
参见 CONTRIBUTING.md 参与贡献,参见 SECURITY.md 报告漏洞。
许可证
MIT。图片牌组属于公有领域;字体和捆绑库列在 THIRD_PARTY_NOTICES.md 中。
“Codenames”是 Czech Games Edition 的注册商标。Open Codenames 是一个独立的粉丝项目,与 Czech Games Edition 无关联,也未获其认可。
开发者指南
Electron + TypeScript + React,本地优先。面向玩家的文档位于 docs/ 并随构建一起发布。
构建
两种版本,在构建时由 OC_BUILD(src/shared/build.ts)固定:
- Debug(
dev/build的默认值):包含离线模拟 AI 和占位图片生成器,显示 DEBUG 徽章,数据保存在%APPDATA%\Open Codenames Debug中。 - Release(
OC_BUILD=release):完全没有模拟代码。这是发布在 itch.io 上的版本。
两个目标:桌面(Electron)和 网页(浏览器中的相同 UI;src/web 用页内桥接替代主进程——设置、密钥和历史记录保存在本地存储中,标准牌组作为静态文件,提供商调用直接从页面发起;没有图片生成、文件夹、导入或本地模型)。
脚本
| 命令 | 作用 |
|---|---|
npm run dev |
以热重载运行桌面游戏(debug) |
npm run dev:web |
在浏览器中以热重载运行网页版本(debug) |
npm test |
单元测试(Vitest):规则、信息边界、策略、解析、提供商、凭据 |
npm run typecheck |
对 main、preload、core、renderer 和 web 进行类型检查 |
npm run e2e |
构建(debug),然后用 Playwright 针对模拟 AI 驱动桌面应用;截图保存到 .e2e/ |
npm run e2e:web |
构建 debug 网页版本,然后在无头 Chrome 中驱动它;截图保存到 .e2e-web/ |
npm run dist:debug |
Debug 桌面构建 → release/debug/win-unpacked/Open Codenames Debug.exe |
npm run dist:release |
Release 桌面构建 → release/desktop/(包含 .itch.toml 和文档的 zip) |
npm run build:web |
Release 网页构建 → out/web/ |
npm run dist:itch |
两个 release 构建,打包为 release/itch/ 中的 itch.io 版本(Windows zip、web zip、UPLOAD.txt) |
npm run demos |
录制两个约 30 秒的演示视频(1920×1080 MP4,带字幕)到 release/demos/;需要 ffmpeg 和 Chrome |
python -P scripts/deck/fetch_met.py、fetch_commons.py、survey.py、cut.py、build_deck.py |
从公有领域来源重建标准牌组(选择和说明文字在 scripts/deck/selection.json 中) |
npx tsx scripts/mock-sim.mts [games] [seed] |
观看离线模拟 AI 在标准牌组棋盘上自己玩(线索、意图图片、选择) |
Play Open Codenames.cmd |
启动 debug 桌面构建 |
如果你的 shell 设置了 ELECTRON_RUN_AS_NODE=1(VS Code 的终端会这样),在直接启动 Electron 之前先取消设置。
架构
src/
core/ Pure TypeScript game logic — no Electron, React or vendor code.
engine/ GameEngine (authoritative rules/state), views (information boundaries), MatchController (turn loop)
rules/ IRuleSet + StandardRules
board/ Layouts, concept bank, board generator (seeded)
ai/ LLMPlayer, the AI profile, prompts, strategy (clue size, risk/reward, stopping), JSON parsing, mock brain
players/ IPlayer, HumanPlayer (UI bridge)
modes/ Game-mode registry (Quick Play, Standard, AI vs AI, coming-soon modes)
replay/ GameRecord + recorder (debriefs, future replays / AI Arena)
images/ Prompt construction and art styles
shared/ Types shared by main and renderer: settings, provider catalog, IPC contract
main/ Electron main process: the only place keys and network calls exist
providers/llm/ ILLMProvider: anthropic (official SDK), openai (Responses API), google (Interactions API),
openaiCompatible (OpenRouter, xAI, Mistral, local), mock
providers/image/ IImageGenerationProvider: stability, bfl, openaiImages, googleImages, replicate, a1111, mock
images/ Image library (disk cache + player folder), thumbnails for vision, board image pipeline
store/ Settings, CredentialStore (safeStorage/DPAPI), replays, diagnostics (redacting log)
preload/ Typed contextBridge API (`window.oc`) — keys can be written but never read back
renderer/ React UI: screens, board, player boards, game log, debrief
web/ Browser version of the `window.oc` bridge (entry for the web build)
依赖方向:renderer 和 main 依赖 core/shared;core 不依赖任何应用特定内容。
信息边界
buildSpymasterView 和 buildOperativeView(src/core/engine/views.ts)是玩家看到游戏的唯一方式。OperativeView 没有任何字段可以携带密钥,提示词构建器只接受其角色对应的视图,而 tests/boundaries.test.ts 检查非干扰性:仅在隐藏身份上不同的游戏会产生字节级完全相同的操作提示词。UI 也根据人类角色的视图渲染棋盘。
AI 流水线
每个 AI 座位都是自己的 LLMPlayer,拥有自己的槽位、RNG 和记忆,全部使用 src/core/ai/personalities.ts 中的单一配置文件进行游戏。玩家自己看到棋盘图片(缩略图);没有任何视图或提示词携带图片的文字描述,因此只有视觉模型才能占据座位。
间谍头目:线索大小——人类队友在每次给线索前在状态栏中选择(Auto 或 1–4),否则 planClueSize(开局以 25/50/25% 的概率选择 1/2/3,然后“保持领先”于对手的节奏)→ LLM 提出带有链接强度和风险的候选线索 → evaluateCandidates 根据真实密钥验证它们,拒绝本局游戏中已经给出的任何线索,并评估期望值 → 队友模拟 → 线索。特工:每回合一次 LLM 调用,对猜测进行排序并给出置信度 → shouldTakeGuess 根据得分决定走多远。
扩展
- LLM 提供商:在
src/main/providers/llm/中实现ILLMProvider,在registry.ts中注册它,在src/shared/providers.ts中添加目录数据。 - 图像提供商:在
src/main/providers/image/中实现IImageGenerationProvider,注册它,添加目录数据。 - 游戏模式:在
src/core/modes/gameModes.ts中添加一个GameModeDef。 - 规则变体:实现
IRuleSet并将其传递给GameEngine。
数据位置
%APPDATA%\Open Codenames(Electron userData):settings.json、credentials.json(加密)、images/、replays/、logs/。设置 OC_USER_DATA 以使用不同的文件夹(e2e 测试会这样做)。
来源:Hacker News · github.com
