# AI 陪玩系统需求与技术方案 更新时间:2026-08-18 文档状态:需求确认完成,方案待实施 > 本文结合已确认的产品需求与当前项目源码编写。 > > 文中“当前系统”表示仓库已经存在并已核对的行为;“拟新增”表示本次 AI 陪玩系统的设计方案,尚未实现。实时牌局规则始终以当前 `game` 服务为唯一权威。 ## 1. 文档目的与适用对象 本文用于统一 AI 陪玩系统的产品口径、业务边界、技术架构、后台配置、策略能力、开源选型和验收标准,适用于: - 产品与运营:确认 AI 如何配置、何时生效、如何统计和排查。 - 游戏服务研发:确认 AI 在现有牌局中的接入点和安全边界。 - AI 服务研发:确认决策输入、输出、策略组成和性能目标。 - 后台研发:确认管理页面、数据模型和权限范围。 - 测试与验收:确认公平性、异常兜底、强度校准和回归范围。 本文不改变当前比赛报名、分桌、盲注、筹码、淘汰、排名、奖励和结算规则。 ## 2. 已确认的核心结论 | 主题 | 已确认口径 | | --- | --- | | AI 角色 | AI 使用普通参赛账号,直接坐桌并自动打牌 | | 账号来源 | 复用现有用户账号创建方式,AI 页面只绑定已有账号 | | 生效范围 | 账号启用 AI 绑定后,参加任何线上德州扑克赛事时均由 AI 接管操作 | | 业务影响 | AI 只影响打牌和下注决策,不影响报名、分桌、淘汰、排名和奖励 | | 旧 Bot | 新系统独立建设,不复用旧 Bot 字段、规则、策略或控制链路 | | 公平模式 | AI 只读取真人在相同位置可以看到的信息,不读取其他玩家底牌、牌堆或未来公共牌 | | 桌型 | 遵循当前项目规则,单桌最多 9 人;同桌 AI 数量不限制 | | 实时规则 | 合法动作、加注上下限、边池和轮次推进均由当前 `game` 服务计算 | | 策略绑定 | 每个 AI 账号固定绑定一个策略档案 | | 强度配置 | 使用 1~5 档强度,不允许直接填写或保证任意胜率 | | 打法配置 | 松紧度、激进度、诈唬频率、风险偏好、对手适应程度、下注尺度和思考时间 | | 对手分析 | 只统计同一场比赛内的简单对手数据,不建立跨比赛长期画像 | | 随机策略 | 采用可控随机混合策略,并记录随机种子用于复盘 | | 聊天能力 | 首版不接入大模型聊天、语音或语言人格 | | 玩家展示 | 玩家端不显示 AI 标识;内部后台、日志和审计记录需要可识别 | | 配置入口 | 在现有 `poker-web` 管理后台新增配置页面 | | 配置生效 | 策略修改、更换或关闭绑定从下一手牌开始生效 | | 异常兜底 | AI 决策失败时重试一次;仍失败则可过牌时过牌,否则弃牌 | | 首版锦标赛策略 | 使用筹码深度、比赛阶段和剩余人数的简化策略 | | 后续锦标赛能力 | 完整 ICM、泡沫期和奖励结构计算后续迭代 | | 校准方式 | 固定 9 人基准环境中统计第一名率、平均名次、BB/100 和样本数 | | 性能目标 | 同时约 100 个 AI,峰值约 20 次决策/秒 | | AI 技术栈 | 独立 Python 3.11 + FastAPI 服务 | ## 3. 核心业务概览 ### 3.1 AI 账号是什么 AI 账号首先是现有系统中的普通用户账号。运营人员在后台将该账号绑定到一个 AI 策略档案后,账号的报名、分桌、筹码和奖励身份保持不变;只有轮到该账号行动时,系统才将决策交给独立 AI 服务。 AI 账号关闭绑定后恢复为普通真人账号,不需要迁移用户资料,也不改变其历史比赛记录。 ### 3.2 AI 策略档案是什么 策略档案是一组可复用的 AI 打法配置。多个 AI 账号可以绑定同一个策略档案,但由于使用混合策略和独立随机种子,它们在相同局面下不必做出完全相同的动作。 一个策略档案包含: - 1~5 档强度等级。 - 松紧度、激进度、诈唬频率和风险偏好。 - 对手适应程度。 - 下注尺度风格。 - 最短和最长思考时间。 - 启用状态和配置版本。 ### 3.3 “胜率配置”的业务口径 公平模式下不能为 AI 保证单局或单场比赛结果。运营人员配置的是强度和打法,系统通过标准化对局测量其长期表现。 后台展示的参考结果包括: - 固定 9 人测试环境中的第一名率。 - 平均最终名次。 - 每百手筹码收益 `BB/100`。 - 对局样本数。 - 使用的基准对手和盲注场景版本。 这些结果是只读的校准数据,不是实时控牌或结果干预参数。 ## 4. 当前系统实现基础 ### 4.1 当前管理端 当前 `poker-web` 是 Laravel 6 + Poppy Framework 的赛事业务后台和 API 项目,已经具备: - `/mgr-page` 管理后台。 - Poker 模块菜单和权限配置。 - 列表、表单、路由、模型和数据库迁移的既有开发模式。 - 赛事、盲注、奖池、报名、牌桌和比赛记录等管理能力。 因此 AI 配置页面应直接放入 `poker-web/modules/poker`,不新建另一套运营后台。 ### 4.2 当前实时牌局 当前 `game` 服务基于 PHP/Hyperf/Swoole,已经负责: - 单桌最多 9 人及比赛分桌。 - 翻牌前、翻牌、转牌、河牌和摊牌阶段。 - 过牌、跟注、加注、全下和弃牌。 - 盲注、前注、筹码、主池和边池。 - 合法动作、最小加注和最大加注计算。 - 操作倒计时、超时自动过牌或弃牌。 - 比赛阶段、盲注等级、淘汰、排名和牌局记录。 AI 不重新实现上述规则,只消费当前牌局提供的公开状态和合法动作集合。 ### 4.3 当前可复用的接入能力 当前轮到用户操作时,系统会先计算: - 当前动作时间点。 - 允许执行的动作。 - 跟注所需筹码。 - 最小和最大加注额。 - 快捷下注参考值。 普通用户提交动作后,现有动作处理链会再次校验并推进牌局。因此新 AI 系统可以复用同一执行入口,无需模拟一个 WebSocket 客户端。 ## 5. 产品目标与非目标 ### 5.1 首版目标 - 让普通参赛账号在绑定后能够自动完成整场比赛。 - 支持一桌任意数量 AI,并允许 9 个 AI 全自动对局。 - 支持运营配置可辨识的打法和 5 档强度。 - 使用公平可见信息作出决策。 - 支持同场比赛内的轻量对手适应。 - 提供决策日志和标准化强度校准。 - AI 服务异常时不阻塞牌桌,也不会在故障状态下冒险下注。 - 在约 100 个同时参赛 AI、峰值 20 次决策/秒下稳定运行。 ### 5.2 首版非目标 - 不控制发牌、牌堆或最终输赢。 - 不读取其他玩家底牌或未来公共牌。 - 不复用或迁移旧 Bot 策略。 - 不允许运营输入任意目标胜率并要求系统保证结果。 - 不实现完整 ICM、泡沫期和奖励结构计算。 - 不引入 CFR、Deep CFR、深度强化学习或在线模型训练。 - 不接入大模型聊天、语音或自动话术。 - 不保存跨比赛的长期玩家打法画像。 - 不在玩家端增加 AI 标识或专属交互。 - 不让 Python AI 服务直接读取当前游戏 Redis 中的隐藏牌局数据。 ## 6. 总体架构 ```mermaid flowchart LR OPS["poker-web 管理后台
AI账号、策略、日志、校准"] --> DB["现有 MySQL
新增独立 AI 表"] DB --> GAME["game / Hyperf
AI接入适配器"] GAME -->|"公平状态 + 合法动作 + 策略快照"| AI["ai-player-service
Python 3.11 + FastAPI"] AI --> PHE["PokerHandEvaluator
牌型与蒙特卡洛计算"] AI --> AIR["AI Redis 命名空间
单场对手统计、幂等缓存"] AI -->|"动作 + 下注额 + 决策元数据"| GAME GAME -->|"现有 Action Handler"| TABLE["当前牌局状态机"] TABLE -->|"操作完成事件"| GAME GAME -->|"异步公开动作事件"| AI BENCH["校准命令行工具"] --> AI BENCH --> DB ``` ### 6.1 `poker-web` 职责 - 管理策略档案。 - 将已有普通用户账号绑定为 AI。 - 启用、关闭或更换账号策略。 - 查看决策记录和异常记录。 - 发起或查看标准化校准结果。 - 管理菜单、权限和操作审计。 ### 6.2 `game` 职责 - 继续作为实时牌局唯一权威。 - 在每手牌开始时生成 AI 策略快照。 - 轮到账号操作时检查独立 AI 绑定。 - 组装公平可见的 AI 决策输入。 - 调用 Python AI 服务并控制思考延迟。 - 校验返回动作仍属于当前合法动作。 - 使用现有动作处理链执行动作。 - 记录决策日志和异常兜底结果。 - 将公开动作事件异步发送给 AI 服务用于单场统计。 ### 6.3 `ai-player-service` 职责 - 校验决策请求格式和幂等键。 - 计算手牌胜率、底池赔率和筹码压力。 - 执行翻牌前范围、翻牌后规则和混合策略。 - 维护当前比赛内的对手统计。 - 根据策略档案和强度等级返回动作。 - 返回结构化决策原因、随机种子和耗时。 - 不负责发牌、合法性最终判断、底池结算或比赛状态推进。 ### 6.4 数据存储原则 - AI 配置和审计记录使用新增独立表,不修改旧 Bot 表和字段。 - Python 服务不直接访问游戏运行态 Redis Key。 - 当前比赛的对手统计使用独立 `ai-player:` Redis 前缀;可先复用现有 Redis 集群,后续按容量拆分实例。 - 策略配置由 `game` 读取并作为版本化快照发送给 AI 服务,减少 Python 服务对主业务数据库的耦合。 ## 7. 核心业务流程 ### 7.1 账号绑定 ```text 运营选择已有普通用户账号 → 选择一个已启用策略档案 → 保存 AI 绑定 → 账号后续正常报名和参赛 → 下一手牌开始时由游戏服务识别为 AI ``` 业务规则: - 同一用户账号只能存在一个有效 AI 绑定。 - 一个策略档案可以绑定多个 AI 账号。 - 被禁用的策略档案不能新增绑定。 - 账号绑定不改变用户资料、报名资格、筹码或奖励资格。 - 玩家端不展示 AI 身份。 ### 7.2 每手牌策略快照 每手牌开始时,游戏服务为当前参赛 AI 账号保存: - AI 绑定 ID。 - 策略档案 ID。 - 策略版本。 - 本手牌使用的完整策略参数。 同一手牌中始终使用同一版本。运营在牌局中修改策略、更换档案或关闭绑定时,从下一手牌开始生效。 ### 7.3 AI 决策 ```text 轮到某账号操作 → 当前项目计算合法动作和下注范围 → 检查本手牌 AI 策略快照 → 组装公平决策状态 → 请求 Python AI 服务 → AI 返回动作和下注额 → 等待配置的思考时间 → 再次校验动作时间点和合法范围 → 调用现有动作处理链 → 记录决策结果 ``` ### 7.4 对手统计更新 每次玩家完成公开动作后,游戏服务异步发送: - 比赛、房间和手牌标识。 - 当前阶段。 - 玩家位置。 - 公开动作和下注额。 - 当时底池、盲注和有效筹码。 - 是否到达摊牌,以及摊牌公开结果。 AI 服务按比赛维度更新对手数据。比赛结束或数据超过有效期后自动清理。 ### 7.5 关闭 AI - 普通关闭:当前手牌继续使用已有快照,下一手牌恢复真人操作。 - 全局紧急停用:立即停止新的 AI 决策请求;轮到 AI 时直接执行安全兜底。 - 已经返回但动作时间点过期的结果必须丢弃,不能作用于新一轮操作。 ## 8. 后台配置方案 ### 8.1 菜单规划 建议在 `在线选拔` 下新增 `AI 陪玩` 分组: - AI 账号 - 策略档案 - 决策记录 - 校准结果 ### 8.2 AI 账号页面 列表字段建议: | 字段 | 说明 | | --- | --- | | 用户 ID | 现有普通用户账号 ID | | 昵称/手机号 | 用于运营检索与确认账号 | | 策略档案 | 当前绑定的策略名称和版本 | | 强度等级 | 1~5 档 | | 状态 | 启用或关闭 | | 最近决策时间 | 判断账号是否正在被 AI 接管 | | 最近异常 | 最近一次超时、非法返回或兜底信息 | | 更新时间/操作人 | 审计信息 | 支持操作: - 绑定已有账号。 - 更换策略档案。 - 启用或关闭 AI。 - 查看账号决策记录。 - 查看当前策略的校准结果。 首版不在此页面创建普通用户账号。 ### 8.3 策略档案页面 固定配置字段: | 字段 | 范围 | 业务含义 | | --- | ---: | --- | | 策略名称 | 文本 | 运营识别名称,如“稳健型” | | 强度等级 | 1~5 | 决策质量和允许误差的总体档位 | | 松紧度 | 0~100 | 起手范围和边缘牌参与程度 | | 激进度 | 0~100 | 主动下注和加注倾向 | | 诈唬频率 | 0~100 | 满足牌面条件后的诈唬概率上限 | | 风险偏好 | 0~100 | 面对大底池和筹码压力时的承受程度 | | 对手适应程度 | 0~100 | 当前比赛对手统计对决策的影响权重 | | 下注尺度 | 枚举 | 小注、标准、大注、混合 | | 最短思考时间 | 毫秒 | 玩家端看到的最短等待时间 | | 最长思考时间 | 毫秒 | 玩家端看到的最长等待时间 | | 状态 | 开关 | 是否允许新增绑定和后续使用 | | 备注 | 文本 | 运营说明 | 页面提供预设: - 稳健型 - 松凶型 - 紧凶型 - 娱乐型 - 大师型 预设只负责填充固定参数,保存后仍形成普通策略档案,不引入独立逻辑分支。 ### 8.4 决策记录页面 建议支持按比赛、房间、用户、策略、动作、异常类型和时间筛选。 详情包括: - 当时合法动作及加注范围。 - AI 可见的公共状态。 - 手牌胜率、底池赔率和有效筹码 BB。 - 对手统计摘要。 - 候选动作权重和最终动作。 - 随机种子。 - 策略 ID、版本和参数摘要。 - 请求、计算和整体耗时。 - 是否重试、是否兜底、失败原因。 底牌和完整决策详情仅在该手牌结束后允许展示。 ### 8.5 权限建议 | 权限 | 作用 | | --- | --- | | `backend:poker.ai_player.manage` | 管理 AI 账号绑定 | | `backend:poker.ai_strategy.manage` | 管理策略档案 | | `backend:poker.ai_decision.view` | 查看决策记录 | | `backend:poker.ai_benchmark.run` | 发起校准任务 | | `backend:poker.ai_emergency.disable` | 全局紧急停用 AI | ## 9. 拟新增数据模型 ### 9.1 策略档案表 `poker_ai_strategy_profile` | 字段 | 类型建议 | 说明 | | --- | --- | --- | | `id` | bigint | 主键 | | `name` | varchar | 策略名称 | | `strength_level` | tinyint | 1~5 档强度 | | `looseness` | tinyint | 松紧度 0~100 | | `aggression` | tinyint | 激进度 0~100 | | `bluff_frequency` | tinyint | 诈唬频率 0~100 | | `risk_tolerance` | tinyint | 风险偏好 0~100 | | `opponent_adaptation` | tinyint | 对手适应程度 0~100 | | `bet_sizing_style` | varchar | small/standard/large/mixed | | `think_time_min_ms` | int | 最短思考时间 | | `think_time_max_ms` | int | 最长思考时间 | | `version` | int | 每次有效修改递增 | | `enabled` | tinyint | 是否启用 | | `remark` | varchar/text | 备注 | | `created_by/updated_by` | bigint | 操作人 | | `created_at/updated_at` | datetime | 时间 | ### 9.2 AI 账号绑定表 `poker_ai_player_binding` | 字段 | 类型建议 | 说明 | | --- | --- | --- | | `id` | bigint | 主键 | | `user_id` | bigint unique | 已有普通用户账号 | | `strategy_profile_id` | bigint | 绑定策略档案 | | `enabled` | tinyint | 是否启用 AI 接管 | | `created_by/updated_by` | bigint | 操作人 | | `created_at/updated_at` | datetime | 时间 | ### 9.3 决策记录表 `poker_ai_decision_log` 关键字段建议: - 唯一请求 ID、比赛 ID、房间 ID、手牌序号和动作时间点。 - AI 用户 ID、策略 ID 和策略版本。 - 阶段、位置、底池、盲注、有效筹码和公共牌。 - 合法动作、加注上下限和输入快照。 - 估算胜率、底池赔率、候选动作权重。 - 最终动作、下注额和随机种子。 - 服务耗时、是否重试、是否兜底和错误码。 - 创建时间。 输入快照可以使用 JSON 存储,但必须由后台权限控制展示,并配置保留周期。 ### 9.4 校准结果表 `poker_ai_benchmark_result` 关键字段建议: - 策略 ID 和策略版本。 - 基准场景版本。 - 基准对手集合版本。 - 样本手数和比赛场数。 - 第一名率、平均名次、BB/100。 - 开始时间、完成时间和任务状态。 - 运行环境、代码版本和备注。 ### 9.5 AI Redis 数据 建议使用独立前缀: ```text ai-player:race:{raceId}:player:{userId}:stats ai-player:race:{raceId}:recent-actions ai-player:decision:{requestId} ai-player:emergency-disabled ``` 对手统计只在当前比赛内有效,比赛结束时清理,并额外设置 TTL 防止异常残留。 ## 10. 决策接口契约 ### 10.1 决策请求 建议内部接口: ```http POST /v1/decisions ``` 请求结构示例: ```json { "request_id": "r123:42:pre_flop:1:10001", "race_id": 9001, "room_id": "r123", "hand_id": 42, "action_time_point": "42pre_flop1", "street": "pre_flop", "hero": { "user_id": 10001, "seat": 5, "position": "CO", "hole_cards": ["As", "Kd"], "stack": 18200, "round_bet": 400 }, "table": { "max_players": 9, "active_players": 7, "small_blind": 200, "big_blind": 400, "ante": 50, "pot": 1650, "side_pots": [], "board": [] }, "players": [], "action_history": [], "legal_actions": { "actions": ["fold", "call", "raise", "allin"], "call_amount": 800, "raise_min": 1600, "raise_max": 18200 }, "tournament": { "remaining_players": 51, "hero_rank": 23, "phase": "middle" }, "strategy": { "profile_id": 7, "version": 12, "strength_level": 3, "looseness": 45, "aggression": 60, "bluff_frequency": 18, "risk_tolerance": 42, "opponent_adaptation": 50, "bet_sizing_style": "mixed" } } ``` `game` 应在适配层将当前内部对象转换为稳定契约,避免 Python 服务直接依赖 PHP 类结构或 Redis 序列化格式。 ### 10.2 决策响应 ```json { "request_id": "r123:42:pre_flop:1:10001", "action": "raise", "amount": 2000, "random_seed": "5d17...", "equity": 0.612, "pot_odds": 0.327, "reason_codes": ["POSITION_RANGE", "EQUITY_EDGE", "MIXED_RAISE"], "compute_ms": 146 } ``` 玩家端不展示 `reason_codes`。它们只用于后台排查、策略调优和验收。 ### 10.3 游戏服务的最终校验 收到响应后必须再次确认: - `request_id` 与当前请求一致。 - `action_time_point` 仍然有效。 - 当前操作者仍是该 AI 账号。 - 返回动作属于当前合法动作集合。 - 跟注、加注或全下金额符合当前项目的最新范围。 - 重复响应不会重复执行动作。 任何校验失败都视为 AI 决策失败,不允许绕过现有动作处理链。 ## 11. 公平信息边界 ### 11.1 允许提供给 AI 的信息 - AI 自己的两张底牌。 - 已公开的公共牌。 - 玩家位置、剩余筹码和本轮下注。 - 当前底池和公开边池。 - 盲注、前注和当前阶段。 - 已公开的动作历史。 - 当前合法动作及下注范围。 - 当前比赛剩余人数、AI 自己的排名和简化比赛阶段。 - 当前比赛内形成的对手公开行为统计。 ### 11.2 禁止提供给 AI 的信息 - 其他未摊牌玩家的底牌。 - 牌堆剩余顺序。 - 尚未发出的公共牌。 - 发牌随机数、内部控牌字段或隐藏运营信息。 - 当前项目旧 Bot 的配置、命中结果或控制字段。 - 其他正常玩家无法获得的服务端隐含状态。 建议为 AI 决策输入建立独立 DTO 和自动化测试,避免直接序列化完整房间、用户或发牌对象。 ## 12. 首版策略引擎 ### 12.1 翻牌前策略 翻牌前使用 9 人桌位置范围和有效筹码分层: - 位置:UTG、UTG+1、MP、HJ、CO、BTN、SB、BB。 - 局面:无人入池、有人平跟、面对一次加注、面对多次加注、面对全下。 - 有效筹码:短筹码、中短筹码、中筹码、深筹码。 - 动作:弃牌、跟注、加注、再加注、全下。 松紧度控制起手牌范围宽度;激进度和诈唬频率控制主动加注与轻量再加注概率;风险偏好控制边缘全下和大底池参与程度。 ### 12.2 翻牌后策略 翻牌后综合: - 蒙特卡洛胜率。 - 底池赔率。 - 有效筹码和 SPR。 - 公共牌结构,如同花、顺子、成对牌面和高张压力。 - 对手数量和位置。 - 当前比赛内的对手统计。 - 当前合法下注范围。 候选下注额使用有限尺度,再裁剪到当前项目给出的合法范围: - 小注。 - 标准注。 - 大注。 - 最小合法加注。 - 全下。 首版不生成任意连续下注公式,避免运营配置和策略调试复杂化。 ### 12.3 简化锦标赛策略 首版纳入: - 以大盲为单位的筹码深度。 - 短筹码 push/fold 倾向。 - 比赛前期、中期和后期的风险调整。 - 剩余人数和自身相对排名的轻量修正。 首版不纳入: - 完整 ICM。 - 泡沫期精确计算。 - 奖励阶梯和奖金跳跃计算。 - 跨桌全部玩家筹码分布求解。 ### 12.4 强度等级 | 等级 | 定位 | 策略能力 | | ---: | --- | --- | | 1 | 入门 | 基础起手范围、较高决策噪声、弱对手适应 | | 2 | 休闲 | 基础位置意识、简单胜率和底池赔率判断 | | 3 | 稳健 | 完整首版规则、正常混合策略和单场对手统计 | | 4 | 高手 | 更细范围、更低误差、更强下注尺度和对手调整 | | 5 | 大师 | 使用首版规则引擎的最佳参数、最低人为误差和更充分计算 | 蒙特卡洛样本数、误差注入和动作混合范围属于内部调优参数,不直接暴露给运营。具体值以容量测试和校准结果确定。 ### 12.5 可控随机混合策略 AI 不以固定阈值机械地选择唯一动作,而是为合法候选动作生成权重后抽样。 随机种子至少包含: - 比赛 ID。 - 房间 ID。 - 手牌序号。 - 动作时间点。 - AI 用户 ID。 - 策略 ID 和版本。 每次决策保存最终种子,使同一输入能够在测试环境中重放。 ## 13. 单场对手分析 ### 13.1 首版指标 | 指标 | 业务含义 | | --- | --- | | VPIP | 翻牌前主动投入筹码的手牌比例 | | PFR | 翻牌前主动加注比例 | | 加注频率 | 各阶段主动下注或加注倾向 | | 面对加注弃牌率 | 遇到压力后弃牌的倾向 | | 摊牌率 | 进入摊牌的比例 | | 摊牌胜率 | 已公开摊牌中的获胜比例 | | 近期激进度 | 最近若干手的动作趋势 | ### 13.2 使用规则 - 只使用当前比赛内数据。 - 样本不足时向默认人群参数收缩,不能因一两手牌形成极端判断。 - `opponent_adaptation` 决定统计对最终决策的最大影响权重。 - Redis 不可用时降级为基础策略,不阻塞牌局。 - 比赛结束后清理;不写入长期玩家画像。 ## 14. 思考时间与异常兜底 ### 14.1 思考时间 AI 计算时间和玩家端思考时间分开: 1. Python 服务尽快完成计算。 2. 游戏服务根据策略档案随机生成展示等待时间。 3. 等待时间不得超过当前操作倒计时的安全余量。 4. 等待结束前再次确认动作时间点有效。 ### 14.2 失败处理 | 场景 | 处理方式 | | --- | --- | | AI 服务超时 | 短暂重试一次 | | 第二次仍超时 | 可以过牌则过牌,否则弃牌 | | 返回非法动作 | 记录异常并执行安全兜底 | | 返回金额越界 | 不自动修正为冒险下注,执行安全兜底 | | 动作时间点已变化 | 丢弃结果,不执行 | | 策略配置缺失 | 告警并执行安全兜底 | | 对手统计 Redis 故障 | 使用无对手适应的基础策略 | | 决策日志写入失败 | 记录服务错误,但不阻塞合法动作执行 | | 全局紧急停用 | 停止新请求并执行安全兜底 | 错误情况下绝不自动跟注、加注或全下。 ## 15. 性能与部署目标 ### 15.1 首版容量 - 同时参赛 AI:约 100 个。 - 决策峰值:约 20 次/秒。 - 单桌 AI 数量:不限制,最多可为 9 个。 - AI 决策服务:多进程 worker,允许后续水平扩容。 ### 15.2 性能原则 - 请求链路中不执行模型训练、CFR 求解或大模型调用。 - 预先加载翻牌前范围和固定规则表。 - 复用牌型查表和牌组编码。 - 蒙特卡洛样本数按强度、阶段和剩余时间自适应。 - CPU 密集计算使用多进程隔离,不依赖单个 Python 事件循环吞吐。 - 建议首版以单次正常计算 P95 小于 500 毫秒为目标,并设置独立硬超时。 - 服务可以通过无状态实例扩容;当前比赛对手统计保存在 Redis。 ### 15.3 部署建议 ```text ai-player-service ├── FastAPI API 层 ├── 策略与范围模块 ├── 胜率计算模块 ├── 对手统计模块 ├── 决策解释与日志模块 └── 校准命令行工具 ``` 首版可以单独部署一组 Python 服务实例,与 `game` 通过内网 HTTP 通信。接口应配置: - 服务间认证。 - 请求签名或短期令牌。 - 内网访问控制。 - 请求 ID 和幂等校验。 - 健康检查和就绪检查。 ## 16. 决策日志、监控与排查 ### 16.1 关键监控指标 - 决策请求总量、成功率和失败率。 - P50/P95/P99 计算耗时。 - 重试率和安全兜底率。 - 非法返回和过期响应数量。 - 各策略档案动作分布。 - 各强度等级的校准结果变化。 - AI Redis 命中率和故障次数。 - 游戏服务因 AI 产生的额外等待时间。 ### 16.2 运营排查顺序 当出现“AI 操作异常”反馈时: 1. 确认账号在该手牌是否存在有效 AI 策略快照。 2. 检查当时合法动作、加注范围和动作时间点。 3. 查看 AI 输入中是否只包含公平信息。 4. 查看策略版本、胜率、底池赔率和候选动作权重。 5. 查看随机种子并在测试环境重放。 6. 确认是否发生超时、重试、兜底或过期响应。 7. 最后核对现有动作处理链是否拒绝或修改了动作。 ## 17. 强度校准方案 ### 17.1 校准原则 - 实际线上牌局规则以当前 `game` 服务为准。 - 主要集成校准应使用测试环境中的当前游戏服务和普通 AI 账号完成。 - PokerKit 可以用于离线场景生成、快速回归和策略单元测试,但不替代线上规则。 - 每次校准固定策略版本、基准对手版本、盲注结构和代码版本。 - 校准结果只描述历史样本,不自动控制后续比赛结果。 ### 17.2 标准基准场景 建议至少建立: - 固定 9 人单桌场景。 - 固定初始筹码和盲注结构。 - 多组基准对手:入门、休闲、稳健和混合对手。 - 足够数量的随机种子和比赛样本。 - 5 个强度等级之间的交叉对局。 ### 17.3 结果展示 后台显示: - 第一名率。 - 平均最终名次。 - BB/100。 - 比赛场数和手牌数。 - 基准场景版本。 - 置信区间或波动提示。 - 最近一次完成时间。 验收重点是不同强度在足够样本下形成稳定区分,而不是要求每档达到一个被保证的固定胜率。 ## 18. 开源项目调研与选型 调研时间:2026-08-18。仓库活跃度和许可证以调研时 GitHub 信息为准。 ### 18.1 推荐结论 | 项目 | 许可证 | 适用部分 | 首版结论 | | --- | --- | --- | --- | | [PokerHandEvaluator](https://github.com/HenryRLee/PokerHandEvaluator) | Apache-2.0 | 5~7 张牌型评估、蒙特卡洛底层计算 | **直接采用** Python 包 `phevaluator` | | [PokerKit](https://github.com/uoftcprg/pokerkit) | MIT | 多变体模拟、牌型评估、离线测试 | **用于离线模拟与回归**,不接管线上规则 | | [PyPokerEngine](https://github.com/ishikota/PyPokerEngine) | MIT | AI 回调格式、合法动作与牌局状态输入设计 | **借鉴接口设计**,不直接嵌入当前牌局 | | [rosbo/texas-holdem-poker-ai](https://github.com/rosbo/texas-holdem-poker-ai) | MIT | 手牌强度、翻牌前模拟、简单对手建模 | **借鉴轻量策略思路**,不直接复制架构 | | [OpenSpiel](https://github.com/google-deepmind/open_spiel) | Apache-2.0 | CFR、强化学习、自博弈和研究评估 | **后续研究**,首版不引入 | | [RLCard](https://github.com/datamllab/rlcard) | MIT | 卡牌强化学习环境、动作抽象和训练示例 | **后续研究**,与当前 9 人锦标赛状态不直接匹配 | | [PokerRL](https://github.com/EricSteinberger/PokerRL) | MIT | 多智能体 Deep RL、Deep CFR 框架 | **后续研究**,依赖和训练复杂度过高 | | [Slumbot2019](https://github.com/ericgjackson/slumbot2019) | MIT | CFR+/MCCFR、部分多人支持 | **算法参考**,不进入首版运行链路 | | [River Poker Solver](https://github.com/noambrown/poker_solver) | MIT | 河牌子博弈 CFR 变体 | **专项参考**,范围不足以支持完整 9 人实时 AI | | [TexasSolver](https://github.com/bupticybee/TexasSolver) | AGPL-3.0/商业许可说明 | 高性能德州扑克 GTO 求解 | **不直接集成**,许可证和求解复杂度不适合首版服务 | | [postflop-solver](https://github.com/b-inary/postflop-solver) | AGPL-3.0 | Rust 翻牌后 DCFR 求解 | **不直接集成**,开源开发已暂停且许可证限制较强 | ### 18.2 用户提供链接的具体判断 #### PokerKit 优点: - Python 3.11+ 纯 Python 库。 - 支持无限注德州扑克及多种扑克变体。 - 提供牌局模拟、牌型评估和统计分析能力。 - MIT 许可证,测试覆盖和维护活跃度较好。 使用方式: - 用于策略单元测试和离线场景生成。 - 用于校验某些公开牌局序列和策略回归。 - 不用它替换当前 `game` 服务的发牌、下注或底池规则。 #### OpenSpiel 优点: - 支持多玩家、不完全信息游戏和多种 CFR/RL 算法。 - C++ 核心并提供 Python 接口。 - 研究生态成熟,适合后续自博弈和算法评估。 首版不采用原因: - 当前目标是可配置、低复杂度、可快速接入的 9 人锦标赛 AI。 - 需要重新适配当前项目状态、下注树和锦标赛流程。 - 训练、评估和部署成本显著高于规则策略方案。 #### PokerHandEvaluator 优点: - 支持 5、6、7 张牌评估。 - Python 包可直接安装。 - 牌型查表速度适合作为蒙特卡洛核心。 - Apache-2.0 许可证。 使用方式: - 首版 Python AI 服务直接依赖 `phevaluator`。 - 在服务启动和 CI 中固定版本并执行牌型回归测试。 #### GitHub `poker-ai` Topic Topic 页面适合发现项目,但不能直接作为选型依据。调研中发现部分近期仓库存在以下情况: - 没有明确许可证。 - 只有说明、演示或商业联系方式,缺少完整实现。 - Star 和使用样本很少。 - 声称支持实时强 AI,但缺少测试、训练数据和可复现实验。 因此 Topic 中的新项目只能进入候选池,必须逐个核对源码、测试、许可证和可复现性后再采用。 ## 19. 实施阶段 ### 阶段 1:数据与管理后台 - 新增策略档案、账号绑定、决策记录和校准结果表。 - 新增后台菜单、权限、列表和表单。 - 支持选择已有普通用户账号并绑定策略。 - 实现配置版本和下一手牌生效机制。 ### 阶段 2:AI 服务最小闭环 - 创建 Python 3.11 + FastAPI 服务。 - 集成 PokerHandEvaluator。 - 实现翻牌前范围、基础翻牌后胜率和底池赔率策略。 - 实现 5 档强度、固定参数和混合随机策略。 - 实现健康检查、幂等和结构化日志。 ### 阶段 3:当前游戏服务接入 - 新增独立 AI 绑定检查和手牌策略快照。 - 组装公平决策 DTO。 - 调用 AI 决策接口。 - 复用现有合法动作计算和动作处理链。 - 实现思考延迟、重试、安全兜底和决策记录。 - 保证真人用户原有操作链不受影响。 ### 阶段 4:对手统计与校准 - 基于公开动作事件维护单场对手统计。 - 实现标准 9 人校准命令。 - 建立基准对手和场景版本。 - 在后台展示校准结果和决策详情。 - 完成 100 AI、20 决策/秒容量验证。 ### 后续迭代 - 完整 ICM、泡沫期和奖励结构计算。 - 更精细的范围推断和牌面抽象。 - CFR/子博弈求解或强化学习策略实验。 - 长期模型评估体系。 - 如产品需要,再独立评估大模型聊天和语音能力。 ## 20. 验收标准 ### 20.1 业务验收 - 已有普通账号可绑定和关闭 AI,不改变账号其他业务行为。 - AI 账号正常报名、分桌、淘汰、排名和领奖。 - 同桌可存在任意数量 AI,包括 9 个 AI。 - 玩家端不显示 AI 标识。 - 策略修改和关闭绑定从下一手牌生效。 ### 20.2 公平性验收 - 决策请求中不存在其他玩家隐藏底牌、未来公共牌或牌堆顺序。 - AI 返回动作只能在当前合法动作和金额范围内执行。 - AI 服务不能直接读取游戏运行态隐藏 Redis 数据。 - 决策日志可以追溯实际输入、策略版本和随机种子。 ### 20.3 策略验收 - 调整松紧度、激进度、诈唬率等参数后,动作分布存在可测差异。 - 同一策略在相同局面中允许按权重做出不同动作。 - 5 档强度在足够样本的固定基准环境中形成稳定区分。 - 单场对手统计会影响高适应度策略,但不会跨比赛保留。 ### 20.4 稳定性验收 - AI 服务超时、非法返回和 Redis 故障不会阻塞牌桌。 - 失败后只执行过牌或弃牌的安全兜底。 - 过期响应和重复响应不会重复执行动作。 - 支持约 100 个同时参赛 AI 和峰值 20 次决策/秒。 - AI 日志故障不会破坏正常牌局推进。 ### 20.5 回归验收 - 未绑定 AI 的真人账号操作行为与改造前一致。 - 当前项目的合法动作、加注、全下、边池和轮次测试继续通过。 - 旧 Bot 代码和数据不作为新 AI 的依赖。 ## 21. 主要风险与控制措施 | 风险 | 控制措施 | | --- | --- | | 决策输入误带隐藏信息 | 独立公平 DTO、字段白名单和自动化测试 | | Python 计算耗时过高 | PHE 查表、有限蒙特卡洛、缓存、多进程和硬超时 | | AI 动作与当前状态过期 | 使用动作时间点、请求 ID 和执行前二次校验 | | 多个 AI 行为过于一致 | 混合策略、独立种子和策略参数扰动 | | 策略参数难以解释 | 固定参数、结构化原因码和决策日志 | | 强度等级名不副实 | 固定基准场景、大样本校准和版本化结果 | | 对手小样本误判 | 最小样本门槛和向默认值收缩 | | AI 服务故障拖慢牌桌 | 非阻塞调用、一次重试和安全兜底 | | 开源许可证风险 | 首版仅直接采用 Apache-2.0/MIT 组件;AGPL 项目只作研究参考 | | 配置中途变化导致行为不一致 | 每手牌策略快照和版本记录 | ## 22. 当前代码依据 以下文件用于确认当前实现,不表示其中已经存在本方案的新 AI 能力。 | 当前事实 | 代码依据 | | --- | --- | | 单桌人数上限为 9 | `game/app/Service/User/Calculator.php:13`、`game/app/Service/Constants/PositionConst.php:14` | | 比赛包含盲注、报名截止等级、结束等级和初始筹码 | `game/app/Model/PokerRace.php:15`、`:26`、`:27`、`:31` | | 当前模型记录国际扑克玩法 | `game/app/Model/PokerRace.php:20`、`:70` | | 牌局阶段包含翻牌前、翻牌、转牌、河牌和摊牌 | `game/app/Service/Constants/RoundConst.php:15` 至 `:19` | | 动作包含过牌、加注、跟注、全下和弃牌 | `game/app/Service/Constants/ActionConst.php:11` 至 `:15` | | 轮到用户时计算合法动作并安排超时过牌/弃牌 | `game/app/Service/Action/Policy/NormalProcessorPolicy.php:32`、`:45`、`:48` | | 合法动作结果带动作时间点和权限集合 | `game/app/Service/Privilege/Calculator.php:184` 至 `:185` | | 加注权限提供最小和最大加注额 | `game/app/Service/Privilege/Raise.php:93` 至 `:94` | | 用户动作通过统一 Handler 执行并推进牌局 | `game/app/Service/Action/Handler.php:56`、`:87` 至 `:102` | | 房间信息包含公共牌、底池和筹码信息 | `game/app/Service/Information/RoomInformation.php:26` 至 `:29` | | 用户信息包含自己的手牌、筹码和操作权限 | `game/app/Service/Information/UserInformation.php:124`、`:157`、`:184` | | 操作完成后存在统一事件对象 | `game/app/Event/AfterAction.php` | | 操作完成后保存房间、用户和公开动作记录 | `game/app/Listener/AfterAction/DataSaveListener.php` | | 当前管理后台采用 Poker 模块菜单、权限、路由、列表和表单模式 | `poker-web/modules/poker/configurations/menus.yaml`、`permissions.yaml`、`src/http/routes/backend.php` | | 管理后台技术栈和模块结构 | `poker-web/README.md` | ## 23. 最终方案结论 首版采用“当前 PHP 牌局权威 + 独立 Python 决策服务 + 现有管理后台配置”的组合: ```text 普通账号和现有赛事流程保持不变 + 独立 AI 账号绑定与策略档案 + 当前项目输出公平状态和合法动作 + Python 规则策略与蒙特卡洛决策 + 当前项目最终校验并执行动作 + 单场对手统计、决策审计和标准化校准 ``` 该方案优先保证规则一致、公平可审计和较低实现复杂度,同时为后续 ICM、CFR、强化学习和更高级策略保留清晰扩展边界。