如何让机器人学会打牌?陪伴机器人接入牌类AI决策API的技术方案

0 阅读5分钟

如何让机器人学会打牌?陪伴机器人接入牌类AI决策API的技术方案

陪伴机器人是近两年硬件赛道的热门方向,尤其是面向老年人的陪伴场景。其中一个高频需求是**"陪老人打牌"**——麻将、掼蛋、斗地主是中国老年人最常见的娱乐活动。

但让机器人"会打牌"不是一个简单的问题。本文分享我们为机器人陪伴场景设计的牌类AI决策API方案,包括技术架构、接口设计、端云协同策略和实际部署经验。


一、机器人打牌的技术挑战

挑战具体问题
决策能力机器人需要实时计算最优出牌,不能只随机出
多品类不同老人喜欢不同牌:麻将、掼蛋、斗地主
算力限制机器人端侧算力有限(通常是 ARM 芯片)
延迟要求出牌不能太慢(>2秒用户体验差),也不能太快(<0.5秒不像人)
难度适配AI太强老人没兴趣,太弱没挑战

核心矛盾:高质量的博弈AI需要 GPU 推理,但机器人端侧没有 GPU。


二、端云协同架构

我们的方案是端侧识别 + 云端决策

┌──────────────────────────────┐
│  陪伴机器人(端侧)            │
│                               │
│  摄像头 → 牌面识别(本地CV)    │
│  麦克风 → 语音交互              │
│  机械臂 → 出牌执行              │
│                               │
│  状态管理器:维护当前对局状态    │
│       ↓ HTTP/WebSocket         │
└──────────────────────────────┘
              ↓
┌──────────────────────────────┐
│  云端AI决策服务                │
│                               │
│  POST /api/v1/decision        │
│  输入:game_state              │
│  输出:最优出牌 + 置信度        │
│                               │
│  延迟:<300ms                  │
│  支持:麻将×8 + 掼蛋 + 斗地主  │
└──────────────────────────────┘

为什么不做端侧推理?

我们测试过在 RK3588(机器人常用芯片)上跑 ONNX 推理:

方案延迟准确率部署难度
端侧 FP321200ms100%高(每台都要部署)
端侧 INT8 量化450ms92%
云端 API180ms + 80ms网络 = 260ms100%低(一次集成)

云端方案在延迟、准确率和部署成本上都更优。端侧只需要做牌面识别和状态维护。


三、API 调用流程

3.1 一次出牌的完整流程

import requests
import time

API_URL = "https://api.example.com/api/v1/decision"
API_KEY = "your_api_key"

def robot_play_turn(game_state):
    """机器人出牌:调用云端API获取决策"""
    
    # 1. 调用决策API
    resp = requests.post(API_URL, json={
        "game_type": "sichuan_mahjong",
        "game_state": game_state,
        "options": {
            "temperature": 1.5,   # 中等难度,让老人能赢
            "top_k": 3,
            "include_analysis": False  # 机器人场景不需要分析
        }
    }, headers={"Authorization": f"Bearer {API_KEY}"})
    
    result = resp.json()
    action = result["action"]
    
    # 2. 模拟思考时间(太快不像人)
    think_time = random.uniform(1.0, 3.0)
    time.sleep(think_time)
    
    # 3. 控制机械臂出牌
    robot_arm.play_tile(action["tile"])
    
    # 4. 可选:语音播报
    if action["type"] == "hu":
        tts.speak("我胡啦!")
    elif action["type"] == "peng":
        tts.speak("碰!")
    
    return action

3.2 难度自适应

一个重要的产品细节:AI 不能一直赢。我们通过动态调整 temperature 实现难度自适应:

class DifficultyAdapter:
    """根据老人的胜率动态调整AI难度"""
    
    def __init__(self, target_win_rate=0.45):
        self.target = target_win_rate  # 目标:老人赢45%
        self.history = []              # 近20局胜负记录
        self.temperature = 1.5         # 初始中等难度
    
    def update(self, human_won: bool):
        self.history.append(human_won)
        if len(self.history) > 20:
            self.history.pop(0)
        
        current_rate = sum(self.history) / len(self.history)
        
        # 老人赢太少 → 降低AI强度(升高temperature)
        if current_rate < self.target - 0.1:
            self.temperature = min(self.temperature + 0.3, 5.0)
        # 老人赢太多 → 提高AI强度(降低temperature)
        elif current_rate > self.target + 0.1:
            self.temperature = max(self.temperature - 0.2, 0.5)
    
    def get_temperature(self):
        return self.temperature

四、WebSocket 方案(低延迟场景)

对于延迟敏感的实时对局,HTTP 轮询不够高效。我们也支持 WebSocket 长连接:

import asyncio
import websockets
import json

async def robot_game_session():
    """WebSocket 长连接方案"""
    async with websockets.connect("wss://api.example.com/ws/game") as ws:
        # 认证
        await ws.send(json.dumps({"type": "auth", "api_key": API_KEY}))
        
        # 创建对局
        await ws.send(json.dumps({
            "type": "create_game",
            "game_type": "guandan",
            "players": 4
        }))
        
        # 游戏循环
        async for message in ws:
            data = json.loads(message)
            
            if data["type"] == "your_turn":
                # 轮到机器人出牌
                decision = data["suggested_action"]
                await asyncio.sleep(random.uniform(1, 3))
                await ws.send(json.dumps({
                    "type": "play",
                    "action": decision
                }))
            
            elif data["type"] == "game_over":
                print(f"Game ended. Winner: {data['winner']}")
                break

五、实际部署数据

我们与某款陪伴机器人做了小批量测试(50台设备,持续2个月):

指标数据
日均对局次数3.2 局/台
API 平均延迟187ms
API P99 延迟340ms
用户满意度82%(满意/非常满意)
最受欢迎品类四川麻将 > 长沙麻将 > 掼蛋

核心发现:老人更在意"机器人像不像真人"而非"AI强不强"。模拟思考时间和语音播报对体验的影响大于决策质量。


六、踩坑记录

  1. 网络中断处理:机器人 WiFi 不稳定时 API 调用超时。解决:端侧缓存一个简单的规则引擎做 fallback,网络恢复后切回云端
  2. 牌面识别准确率:摄像头角度和光线影响 OCR。解决:加了牌面状态校验,识别结果与历史不一致时请求用户确认
  3. 出牌速度:AI 秒出让老人感觉"不真实"。加了 1-3 秒随机延迟后用户满意度提升了 15 个百分点

七、小结

机器人陪打牌的技术核心是端云协同:端侧做感知和交互,云端做决策。关键 takeaway:

  1. 云端 API 比端侧推理在延迟、准确率、部署成本上都更优
  2. 难度自适应比固定难度的用户体验好得多
  3. "像人"比"AI强"更重要——模拟思考时间和语音播报是关键

作者团队:长沙赢麻哒文化传播 | malinguo.com