DanKS 掼蛋智能体:金山AI开源SOTA,三代技术路线完整透明
DanKS 掼蛋智能体:金山AI开源SOTA,三代技术路线完整透明
绝大多数"开源掼蛋 AI"给你一个黑盒 Demo,或者只放论文不开源码。金山 AI Product Center 反其道而行:一个仓库把三代完整技术路线全放出来,从结构化召回、ONNX 选择器、到 PPO 自博弈训练全部可读可跑可比较,还有配套的 CardKS 论文和在线对战入口。
2026 年 8 月 21 日创建、GitHub 190 Star / 4 Forks、Apache-2.0 协议、Python 3.10+。Calix-L/DanKS 是金山 AI Product Center 发起的掼蛋(Guandan / 108 张四人组队对抗扑克)SOTA 级强化学习智能体。仓库的核心卖点非常干脆:一个仓库三代全开源,每一代单独包,特征和 checkpoint 命名空间一致可直接逐代对比;昇腾 NPU + NVIDIA CUDA 双硬件路径全给;配套 CardKS 论文可查实验结果,在线 Demo 真能挑战它。
还有一个"反向带货"点:DanKS 选择把高度结构化的动作空间不直接交给 RL 学,而是先通过检索做结构化候选压缩,再让策略网络在有界的 Top-K 候选里评分。这种"不拿强化学习硬啃组合爆炸"的工程思路,是所有做复杂组合动作空间的项目都值得借鉴的。
本文提纲
- 项目总览:谁做的、为什么叫 DanKS、三个"第一次做掼蛋开源才敢给你"的东西
- 总体架构:状态编码 → 结构化候选召回 → Actor-Critic 评分 → PPO 自博弈
- 三代技术路线逐代对比:V1/V2/V3 到底改了什么
- 延迟结果为什么难:"眼前最优"和"全局最优"的结构信用分配
- 共享规则引擎(guandan.engine):108 张四人掼蛋规则 Python 原生实现
- V3 PPO 训练全链路:记忆、候选覆盖、队伍信念、自博弈服务器
- 硬件与部署:CPU / CUDA 12.8 / 昇腾 910B2C + C++ 加速内核
- 快速上手:从零 8 条命令跑起 CPU 版 V3 推理
- 你能用 DanKS 做什么:个人学习掼蛋 AI 进阶、团队做 Card Game RL 参考基准、企业二次开发
1. 项目总览:三个"掼蛋开源圈第一次给你"的东西
DanKS 之前的开源掼蛋 AI 项目有两个典型:一类是给你在线 Demo + 论文,核心代码只到"能跑一个 baseline 模型";另一类是规则引擎 + 启发式(比如纯 minimax + alpha-beta,人类高手两个星期就能把它摸透并轻松打爆)。DanKS 给了三个前两者都没给的东西:
① 三代完整代码,逐代可对比
V1 → V2 → V3 不是在同一 branch 里向前推进,而是分别作为 versions/v1 / v2 / v3 三个独立 install package 存在。每个版本 DanKS 导入名、特征 schema、checkpoint 格式统一,所以你可以为每个版本建一个 venv,装完直接并排跑对比——这在"进化型"RL 项目中非常罕见,大部分团队只会给你最终的 V3,不会让你看它是怎么踩坑爬到 V3 的。
② 双硬件路径都给了(含昇腾 NPU 实测参考配置)
不是写一句"理论上支持各种硬件"。README 给了 V3 在 NVIDIA H100 (CUDA 12.8 + PyTorch 2.8.0) 和 昇腾 910B2C (CANN 8.5.0 + torch_npu 2.7.1.post2 + PyTorch 2.7.1) 两套已验证的参考配置。昇腾 NPU 的虚拟环境、CAN 环境变量 TORCH_DEVICE_BACKEND_AUTOLOAD=0、专用 requirements-training-npu.txt 全写明了。
③ 一张"延迟结果结构图"揭示了掼蛋比其他扑克难的根本原因
掼蛋一张 3 当下打出去是正收益还是负收益,不取决于 3 这张牌的绝对值,而取决于它和剩余 26 张手牌的结构关系——打掉它之后你是补全了一个顺子,还是拆了仅剩的对子?这种"短期损益 vs 长期结构损益"的权衡在德州和斗地主里弱得多,在掼蛋里是决策核心。DanKS 把这个问题用四张 README 图讲透了。
另外几个硬数据:
- 仓库 9.3 MB,纯 Python 为主,V3 附了 C++ 加速内核(pybind11 绑定)
- Topics:card-games、game-ai、guandan、pytorch、reinforcement-learning
- 还有一个配套 AtomGit 国内镜像(atomgit.com/Calix_Lin/DanKS)方便国内访问
- 配套论文仓库:github.com/Calix-L/CardKS,有完整的 Main Results 实验表格
- 在线对战:calixlin.com/CardKS/,无需安装,1 个人类 + 3 个 Bot 座位,支持中英文界面
2. 总体架构:状态编码 → 结构化候选召回 → Actor-Critic 评分 → PPO 自博弈
MERMAID_BLOCK_0
DanKS 的总体架构图贯穿三代,每代都是在这条流水线上换零件升级:
- 状态编码 State Encoding:策略网络接收可见手牌、公开出牌历史、合法动作集合、以及座位相关的对局上下文(谁是对家、当前等级、当前主牌花色等)。V3 在此基础上加了记牌、候选覆盖率和队伍信念(Team Belief)三个维度的状态向量。
- 结构化候选召回 Structured Candidate Retrieval:用有预算的拆牌搜索(Budgeted partition search)生成具有代表性的出牌候选方案,并概括每个候选的结构特征——牌数、对子、序列、花色、缺口以及打完之后剩余手牌结构。注意这里不是枚举所有合法动作(掼蛋合法动作空间经常爆到几千种),而是通过
partitioner.py+ranker.py+scoring.py三个结构化模块筛到一个有代表性的候选集,再交给策略网络评分。 - Top-K 评分 Actor-Critic:共享编码器融合"状态 + 候选动作 + 结构特征"三路信息,Actor 对合法候选排序,Critic 估计当前状态价值。V1 是 NumPy 手写规则选择器、V2 是 ONNX 轻量选择器、V3 才是完整的 EfficientTeamBeliefTop10Selector 神经网络。
- 自博弈学习 PPO + GAE:轨迹数据为裁剪 PPO 更新提供 GAE(Generalized Advantage Estimation)优势估计,在不增加推理阶段候选预算的前提下改进选择器。这是 DanKS 工程上很聪明的一点:推理成本主要花在候选召回上,你不会让推理变得更慢,而是让同一个 Top-K 候选池里"选对的概率更高"。
3. 三代技术路线逐代对比:V1/V2/V3 到底改了什么
| 版本 | 核心思路 | 关键词 | 入口文件 | 典型大小 |
|---|---|---|---|---|
| V1 | 结构化检索 + NumPy 选择器 | 候选评分、NumPy 手工特征、无学习 | retrieval/ranker.py(87.8 KB) |
NumPy 2.4.6 纯 CPU |
| V2 | 学习型选择 + ONNX | 更广动作生成、ONNX 推理选择器 | retrieval/action_generator.py + training/onnx_phase14_selector.py |
ONNX Runtime 1.27.0 纯 CPU |
| V3 | 记忆感知策略 + PPO | 记牌 card_memory、候选覆盖 candidate_coverage、队伍信念 team_belief、PPO 自博弈、昇腾 NPU 支持 | training/model.py(51.9 KB)+ training/train_ppo.py(64.4 KB) |
PyTorch 2.8.0 · H100 / 910B2C |
每一代的 retrieval 子系统都是"同一个三板斧 + 升级":
partitioner.py:拆牌分区搜索(V1 85.7 KB → V2 89.2 KB → V3 95.7 KB)ranker.py:候选排序(V1 87.8 KB → V2 88.2 KB → V3 88.8 KB,几乎没大改——说明召回这层在 V1 就已经相对稳定了)scoring.py:结构化评分(V1 61.6 KB → V2 61.7 KB → V3 62.3 KB)
这三个核心文件尺寸三代只增了几 KB,也印证了上面的架构观点:DanKS 的三代进化主要发生在选择器策略上,而不是"候选怎么拆"这个结构化组件。
那选择器三代怎么变的?这是最有教学价值的部分:
- V1 直接把 NumPy 选择器写在
training/numpy_selector.py里——完全手工写的规则和阈值。优点是可解释、可单步跟踪、可调试,缺点是调阈值天花板低。 - V2 引入了
onnx_phase14_selector.py(2.8 KB)——把一个经过训练的选择器导出成 ONNX,CPU 推理快、部署简单,但训练过程本身不在仓库里(训练脚本是 V3 才给全的)。 - V3 直接给你完整的
model.py(51.9 KB 神经策略)+train_ppo.py(64.4 KB PPO 训练入口)+persistent_ppo_server.py/transport.py(持久自博弈的服务器-传输协议)+accelerator.py(CUDA/昇腾加速后端抽象)+team_belief.py(对家信念学习)+type_suppression.py(类型抑制,防止策略偏科),真正意义上把完整自博弈训练链路给你端到端了。
4. 延迟结果为什么难:结构感知的长程信用分配
DanKS README 专门放了一节"Why Delayed Outcomes Matter"(为什么要关注延迟结果?)+ 一张彩色结构感知图,我觉得这是整个仓库产品思维最到位的地方:
当下代价很低的动作,可能破坏手中唯一有用的组合;而主动消耗一张高价值牌,反而可能保留整体牌型结构,并带来更干净的后续出完路径。
翻译成代码职责拆分:
- Retrieval(召回层):把组合动作空间组织成具策略多样性的候选集(不是把所有合法动作一股脑端给策略)
- 结构特征(Scoring / Structural Calibration):显式表达每个候选会消耗什么、保留什么、打完之后剩下什么
- Actor:在当前状态 + 结构特征下为合法候选打分
- Critic + GAE:从后续轨迹结果中分配信用,使 PPO 能够偏好价值需要数次决策后才体现的动作
这四个角色各司其职,你就会理解为什么 DanKS 不拿 RL 直接硬啃动作空间:动作数量太大、长期价值依赖结构,RL 在全动作空间上学习需要指数级更多样本。而"召回+结构化特征+Top-K策略评分"这套三板斧,把 RL 的学习空间从几万维合法动作压缩到了 10 维(TOPK = 10,从 schema 里 TOPK 常量可见,V3 模型名叫 EfficientTeamBeliefTop10Selector,Top10PPOAgent)。
Top10 这个数不是随便拍脑袋的——在掼蛋的合法动作空间里,如果你想让人类高手也能一眼看完所有备选动作,10 是一个比较合理的认知上限,同时又保留了足够的策略多样性。DanKS 直接就用这个做 RL 的动作维度,工程直觉非常准。
5. 共享规则引擎 guandan.engine:108 张四人掼蛋 Python 原生实现
guandan/engine/ 是三代共用的掼蛋规则引擎,与三代 DanKS 智能体解耦安装:
guandan/engine/
├── environment.py # 对局环境抽象(67B,接口极简)
├── moves.py # 动作枚举(1.1 KB)
├── python_rules.py # 掼蛋规则实现(22.4 KB)
├── table.py # 牌桌状态机(31.1 KB)
└── types.py # 牌/动作/状态类型定义(10.8 KB)
关键意义:
1. 108 张牌、四人组队、完整晋级协议:不是简化版斗地主,是完整的掼蛋规则(含级牌、红桃级牌百搭、贡牌/抗贡、升两级、三级 A 不过不下等)。
2. 可单独 pip 安装:pip install -e '.[dev]' 只装规则引擎,不装任何 V1/V2/V3 的 RL 部分。团队想自己做别的掼蛋 AI 方案(比如纯 LLM、纯 Tree Search),可以直接复用这个引擎。
3. CI 全过引擎和仓库检查:.github/workflows/ci.yml 运行 tests/test_engine.py(仓库和规则引擎一致性验证)+ tests/test_examples.py(示例冒烟)+ tests/test_repository.py(代码结构和文件分布)。对于开源教学项目,这能非常好地防止"文档更新了但示例没更新、示例跑不起来"的问题。
快速体验引擎的示例 examples/engine_quickstart.py 可以直接跑通牌桌初始化。
6. V3 PPO 训练全链路:记忆、候选覆盖、队伍信念、自博弈服务器
V3 是 DanKS 的集大成版本,也是最值得花时间读的部分。挑几个关键模块展开:
6.1 记牌 card_memory.py(13.6 KB)
不同于德州扑克 public betting history,掼蛋的出牌牌张是具体的牌(S3、HK、etc.),而且对门四人的已出牌、贡牌、抗贡信息对推断剩余牌分布极其重要。card_memory.py 把每一张"谁出过什么、哪些花色已经打过、哪些点数已经绝张"的计数信息编码进状态向量。
6.2 候选覆盖 candidate_coverage.py(2.3 KB)+ b5_trace.py(8.2 KB)
一个很有意思的"训练前自查"组件:候选召回池覆盖了合法动作空间的多少代表性结构?如果召回池系统性漏掉了某一类动作(比如总是不选"顺子"类候选),再怎么训 PPO 也不会打出顺子。DanKS 显式度量、记录并修正候选覆盖的偏差——这是很多 RL 项目忽略的,但在"RL 学的是 Top-K 候选的条件分布"框架下,召回偏差会直接变成策略永久偏差。
6.3 队伍信念 Team Belief(team_belief.py · 15.1 KB)
掼蛋是四人两两组队对抗,你和对友是一伙的,另两家是对手。DanKS V3 训练了一个 Team Belief 头:基于历史轨迹预测对家/对手的隐含手牌分布。训练标签来自自博弈轨迹中其他三个人的真实手牌(训练时有上帝视角可获得),推理时不可见,只是用这个任务作为辅助监督来预训练共享编码器。效果等价于让策略网络在 Transformer/MLP 中隐式记住"现在对家大概率手里还有对 K、对手右家大概只剩一张 2"。
Schema 里有具体维度:
TEAM_BELIEF_SEAT_COUNT = 3 # 其他三个座位
TEAM_BELIEF_TARGET_DIM = ... # 每个座位的手牌分布维度
6.4 PPO 配置 + 持久自博弈服务器
ppo.py 定义了标准裁剪 PPO(PPO-Clip,目标 KL 控制 target_kl)、masked categorical(因为合法候选数量每步不一样,需要 mask 掉非法选择)。persistent_ppo_server.py + persistent_ppo_transport.py 实现了自博弈的基础设施:Actor Worker 不跟 Learner 绑死,而是通过传输层把轨迹异步传给 learner 做一次或多次更新。这是你要把自博弈横向扩展到多台机器上的标准做法。
6.5 快速跑一次 PPO 冒烟的代码(来自 examples/v3_ppo_smoke.py)
from DanKS.training.model import EfficientTeamBeliefTop10Selector
from DanKS.training.ppo import PPOConfig, Top10PPOAgent, masked_categorical
from DanKS.training.schema import (CANDIDATE_DIM, HISTORY_EVENT_DIM,
HISTORY_LENGTH, STATE_DIM, TEAM_BELIEF_SEAT_COUNT,
TEAM_BELIEF_TARGET_DIM, TOPK)
model = EfficientTeamBeliefTop10Selector(
STATE_DIM, CANDIDATE_DIM,
hidden_dim=32, candidate_hidden_dim=24,
)
optimizer = torch.optim.AdamW(model.parameters(), lr=1.0e-3)
agent = Top10PPOAgent(model, optimizer,
PPOConfig(train_iters=1, target_kl=1.0))
# feed fake batch → 验证 PPO update 会真的改变参数
info = agent.update({
"state": state, "candidates": candidates, "mask": mask,
"history": history, "action": action, "logp": old_logp,
"advantage": torch.tensor([1.0, -1.0]),
"returns": torch.tensor([0.5, -0.5]),
"team_belief_labels": labels, "team_belief_mask": tb_mask,
})
# 验证 loss 有限且参数变了
assert all(math.isfinite(v) for v in info.values())
跑通这一段 = V3 PPO 环境配置 100% 正确。python examples/v3_ppo_smoke.py 如果通过,python -m DanKS.training.train_ppo --help 就能正常启动正式训练。
7. 硬件与部署:CPU / CUDA 12.8 / 昇腾 910B2C + C++ 加速内核
7.1 已验证参考配置(README 原文列出,是团队自己跑通的)
| 目标 | 系统 | Python | 关键硬件/SDK |
|---|---|---|---|
| V1(结构化召回) | CPU | 3.11+ | NumPy 2.4.6 |
| V2(学习型选择) | CPU | 3.11+ | NumPy 2.4.6 + ONNX Runtime 1.27.0 |
| V3 NVIDIA 训练 | H100,驱动 575.57.08 | 3.11.14 | PyTorch 2.8.0 + CUDA 12.8,pybind11 3.0.4 |
| V3 昇腾训练 | Ubuntu 22.04.5,910B2C,驱动 24.1.0,CANN 8.5.0 | 3.10.12 | PyTorch 2.7.1 + torch_npu 2.7.1.post2,NumPy 1.26.0 |
7.2 C++ 原生加速内核
V3 附带了 retrieval/native_cpp/build.py + setup.py,danks-build-native 一条命令在 V3 环境中构建两个优化过的检索内核(cover + actor):
- Linux:自动开 -march=native 编译优化
- macOS:universal2 二进制
- Windows:自动回退 Python 实现,不强制 C++ 工具链
构建完后会打印 cover=True, actor=True,表示两个原生内核都已生效。对于 V3 推理阶段,候选召回的拆牌搜索是最热路径,C++ 加速通常能拿到 2~5x 的单步延迟提升,对于自博弈 rollout 吞吐是决定性的。
7.3 昇腾 NPU 独有的 TORCH_DEVICE_BACKEND_AUTOLOAD=0
TORCH_DEVICE_BACKEND_AUTOLOAD=0 这个环境变量是昇腾用户很熟,但对一般 PyTorch 开发者非常陌生的开关。关掉自动后端加载可以避免 CANN 与某些 pip 安装的 PyTorch CPU wheel 的 ABI 冲突。DanKS 把它写进了 README,说明是真在 910B2C 上踩过坑。
8. 快速上手:从零 8 条命令跑起 CPU 版 V3 推理
用户想不读论文、不装 CUDA,看一眼智能体到底怎么给自己的 5 张手牌评分选最优动作?下面是从仓库 README 精简出来的最短路径(CPU + V3,2~3 分钟跑完):
# 1. 克隆 & 建环境
git clone https://github.com/Calix-L/DanKS.git
cd DanKS
python3.11 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
# 2. 安装 V3 包 + CPU 版 PyTorch 2.8.0
python -m pip install -e versions/v3
python -m pip install torch==2.8.0 --index-url https://download.pytorch.org/whl/cpu
# 3. 跑 retrieval 冒烟:给手牌+合法动作,输出Top动作和分数
python examples/retrieval_quickstart.py --version v3
# 预期输出(大意):
# DanKS V3 retrieval ready
# Top action: Pair [S3 H3] score=2.xx
# 4. (可选)跑一次 PPO 冒烟:确认 PPO 会更新参数
python examples/v3_model_smoke.py
# DanKS V3 PPO ready: iters=1, loss=0.xxx
一旦这四个命令都过了,你就进入了"可以开始自己玩掼蛋 AI"的阶段。再往下的三条路径分别是:
- 自己和 AI 打:直接开浏览器进 https://calixlin.com/CardKS/ (1 人类 + 3 Bot)
- 用共享引擎自己写规则 Agent:从 guandan.engine 写启发式 baseline,和 DanKS V3 跑胜率对比
- 训自己的 V3 变体:改 training/featurizer.py(特征)、training/model.py(结构)、training/train_ppo.py(超参数)跑自博弈训练
9. 你能用 DanKS 做什么:个人学习 / 团队基准 / 企业二次开发
个人学习掼蛋 AI 进阶
DanKS 把"如何把强化学习放到一个结构复杂、四人组队、延迟收益、动作爆炸的卡牌游戏里"这个问题,用三代代码完整展示了一遍。学习路径建议:
- 先跑通 retrieval_quickstart,理解 candidate 召回和评分的粒度
- 读 V1 的
numpy_selector.py(3.3 KB,纯规则)——理解"选择器"这个概念最具体的起点 - 读 V3 的
training/schema.py(9.3 KB)——把STATE_DIM、CANDIDATE_DIM、HISTORY_LENGTH、TEAM_BELIEF_SEAT_COUNT、TOPK这几个核心维度搞清楚,等于把整个 V3 策略网络的输入输出接口全看透 - 跑 v3_ppo_smoke,验证 PPO update 真会改参数
- 最后读 train_ppo 的全部 CLI 参数,理解自博弈的训练循环
团队 Card Game RL 基准
对于想做其他卡牌游戏(升级、德州、桥牌、斗地主)的 RL 团队,DanKS 的架构骨架 1:1 平移即可:
- 共享规则引擎 / 合法动作生成
- 结构化候选召回代替全动作空间枚举
- 结构特征 + Actor-Critic 的 Top-K 评分器
- GAE + PPO 的自博弈训练
- C++ 原生加速的热路径内核
- 持久自博弈 Worker/Learner 分离的传输协议
都是卡牌 RL 的通用骨架,直接换牌种规则模块 + 特征 schema 就能套。
企业二次开发
对棋牌/娱乐类 AI 产品的企业团队而言,DanKS 的工程质量(GitHub Actions CI、三版本包隔离、双硬件参考配置、C++ 加速内核的 pybind11 集成)已经相当接近生产项目的水平。Apache-2.0 协议允许商业使用,只要你遵守:
- 保留 DanKS 项目版权声明
- 注明你修改了哪些部分
- 你的衍生产品里不要用金山 / Kingsoft 的商标做背书
二次开发的常见方向:自己的玩家数据训练 warm-start、与现有掼蛋 App 的服务器集成做 AI 陪练、接入用户分级的 AI 难度梯度(V1=入门级、V2=挑战级、V3=大师级)、以及把 Team Belief 扩展成"对手建模"做人类风格识别和针对性策略。
作者: itech001
来源: 公众号:AI人工智能时代(the-ai-era)
网站: https://www.theaiera.top/
关注每日最新AI新闻和技术博客,主页有更多的文章的AI 技术参考:https://www.theaiera.top
本文首发于 AI人工智能时代,转载请注明出处。

浙公网安备 33010602011771号