多代理奇偶游戏系统

MCP奇偶联赛是一个多代理自主游戏系统,代理通过模型上下文协议(MCP)进行通信,参与奇偶猜测游戏的联赛管理。

  • by TalBarda8
  • Python
  • 本地部署
  • 更新于
在 GitHub 查看 TalBarda8/mcp-even-odd-league

使用说明

MCP偶数/奇数联赛

基于模型上下文协议的多智能体游戏系统

课程: 具有模型上下文协议的AI代理 机构: 赖希曼大学 学年: 2024-2025 协议版本: 联赛v2 作者 塔尔·巴达


目录

  1. 概述
  2. 系统架构
  3. 安装
  4. 快速开始
  5. 系统组件
  6. 游戏规则
  7. MCP协议
  8. 管理联盟
  9. 测试
  10. 配置
  11. 故障排除
  12. 项目结构
  13. 文档
  14. 贡献
  15. 许可证

概述

项目描述

MCP偶数/奇数联赛是 多智能体自主游戏系统 其中玩家代理在结构化的联盟格式内进行偶数/奇数猜测游戏。该系统展示了以下内容的实际实施:

  • 模型上下文协议(MCP) 用于代理间通信
  • 多智能体协调 自主决策
  • 联赛管理 循环赛编排
  • 状态机设计 用于鲁棒代理行为
  • RESTful JSON-RPC 2.0 通过HTTP发送消息

什么是偶数/奇数游戏?

每场比赛:

  1. 裁判抽取一个随机数(1-10)
  2. 两位玩家同时选择“偶数”或“奇数”
  3. 正确猜出奇偶校验的玩家获胜
  4. 如果两人猜得一样(都是对的或都是错的),那就打平了

系统目标

学术目标:

  • 按照正式的协议规范实现自治代理
  • 设计可扩展的多智能体系统
  • 为分布式系统实践软件工程最佳实践
  • 展示异步通信协议的能力

技术成果:

  • 完全符合JSON-RPC 2.0的MCP协议
  • 具有状态管理的自主玩家代理
  • 集中的联赛编排和排名跟踪
  • 有公平保障的裁判仲裁
  • 全面的错误处理和超时

系统架构

高级体系结构

┌─────────────────────────────────────────────────────────────┐
│                     League Manager                           │
│  - Orchestrates rounds                                       │
│  - Tracks standings                                          │
│  - Publishes results                                         │
└──────────────────────┬──────────────────────────────────────┘
                       │
        ┌──────────────┴──────────────┐
        │                             │
┌───────▼────────┐           ┌────────▼───────┐
│   Referee      │           │   Referee      │
│   (REF01)      │           │   (REF02)      │
│  - Runs match  │           │  - Runs match  │
│  - Draws num   │           │  - Draws num   │
│  - Declares    │           │  - Declares    │
│    winner      │           │    winner      │
└───┬───────┬────┘           └───┬───────┬────┘
    │       │                    │       │
┌───▼──┐ ┌──▼──┐            ┌───▼──┐ ┌──▼──┐
│ P01  │ │ P02 │            │ P03  │ │ P04 │
│Even  │ │Odd  │            │Even  │ │Odd  │
│Agent │ │Agent│            │Agent │ │Agent│
└──────┘ └─────┘            └──────┘ └─────┘

通信协议

所有组件通过以下方式通信 HTTP POST 请求 /mcp 端点使用 JSON-RPC 2.0 格式。看 docs/architecture/mcp_message_contracts.md 以获取完整的消息规范。

设计原则

  1. 协议优先设计: 由正式消息契约定义的所有交互
  2. 状态机: 每个代理都通过经过验证的转换来维护显式状态
  3. 关注点分离: 联赛编排、比赛仲裁和球员策略是独立的
  4. 故障安全默认值: 内置超时、重试和优雅降级功能
  5. 可扩展性: 未来游戏类型的插件架构

参考: 看 docs/architecture/block_architecture.md 查看详细的组件分解。


安装

系统要求

  • python 3.9或更高
  • 操作系统: macOS、Linux或Windows
  • 猛撞: 最小2GB
  • 网络: 本地主机连接(无需外部网络)

步骤1:克隆存储库

git clone https://github.com/TalBarda8/mcp-even-odd-league.git
cd mcp-even-odd-league

步骤2:安装软件包

该项目被构造为一个适当的Python包。在开发模式下安装:

pip3 install -e ".[dev]"

这将安装:

  • 核心依赖关系: flask, requests
  • 开发工具: pytest, pytest-cov, python-dotenv
  • 包裹: mcp-even-odd-league 处于可编辑模式

替代方案(不带开发工具的生产安装):

pip3 install -e .

步骤3:验证安装

python3 -c "import mcp_even_odd_league; print(f'Package installed: v{mcp_even_odd_league.__version__}')"

预期产量:

Package installed: v0.1.0

快速开始

关键: 这个项目有两种运行方式——为你的用例选择正确的一种!

模式 用例 终端 联赛经理 裁判 运行什么
集成测试 ✅ 评分,演示 5 内存(测试) 内存(检测) 自动6场联赛
生产系统 架构研究 6 HTTP服务器 HTTP服务器 需要手动MCP消息

👉 评分/演示:使用集成测试模式(向下滚动)👈


⚡ 推荐:集成测试模式(自动演示)

最适合: 分级、演示、测试 它的作用: 自动运行完整的6场循环赛 所需终端: 5(4名玩家+1个测试脚本)

先决条件

# 1. Install the package
pip3 install -e ".[dev]"

# 2. Kill any stuck processes (if needed)
for p in 8000 8001 8101 8102 8103 8104; do
  lsof -ti :$p | xargs kill -9 2>/dev/null
done

分步说明

终端1-玩家P01:

python3 -m mcp_even_odd_league.agents.player_P01.main P01

等待: * Running on http://127.0.0.1:8101

终端2-玩家P02:

python3 -m mcp_even_odd_league.agents.player_P02.main P02

等待: * Running on http://127.0.0.1:8102

终端3-玩家P03:

python3 -m mcp_even_odd_league.agents.player_P03.main P03

等待: * Running on http://127.0.0.1:8103

终端4-玩家P04:

python3 -m mcp_even_odd_league.agents.player_P04.main P04

等待: * Running on http://127.0.0.1:8104

5号航站楼-运行测试:

# Full Round-Robin league (6 matches, automatic standings)
python3 tests/test_full_league.py

预期输出

测试将自动:

  1. 在内存中创建联盟经理
  2. 在内存中创建裁判
  3. 进行6场比赛(P01 vs P02,P01 vs P0.3,P01 vs.P04,P02 vs.P03,P02 vs P04,P0.03 vs P04)
  4. 每场比赛后显示排名
  5. 宣布联赛冠军

您应该看到:

================================================================================
MCP Even/Odd League - Phase 6 Full League Test
================================================================================
...
🎮 Match 1/6: P01 vs P02 (LEAGUE_MATCH_001)
  Drawn number: 5 (odd)
  Winner: P02
...
🏆 LEAGUE CHAMPION: [Winner] 🏆

🏗️ 高级:生产多代理系统(6个终端)

最适合: 开发、理解架构、生产部署 它的作用: 将所有6个代理作为独立的HTTP服务器运行 所需终端: 6名代理人+人工协调 状态: ⚠️ 需要手动发送MCP消息以触发匹配

建筑

League Manager (port 8000)
      ↓
Referee REF01 (port 8001) ← coordinates matches
      ↓
Player Agents (ports 8101-8104) ← autonomous participants

分步说明

1号航站楼-联赛经理:

python3 -m mcp_even_odd_league.agents.league_manager.main

监听8000端口

2号航站楼-裁判REF01:

python3 -m mcp_even_odd_league.agents.referee_REF01.main REF01

监听端口8001

终端3-玩家P01:

python3 -m mcp_even_odd_league.agents.player_P01.main P01

监听8101端口

4号航站楼-玩家P02:

python3 -m mcp_even_odd_league.agents.player_P02.main P02

监听8102端口

5号航站楼-玩家P03:

python3 -m mcp_even_odd_league.agents.player_P03.main P03

监听8103端口

6号航站楼-玩家P04:

python3 -m mcp_even_odd_league.agents.player_P04.main P04

监听8104端口

验证所有代理是否正在运行:

  • 每个终端应显示: Running on http://...

触发比赛

在所有6个代理都运行的情况下,您需要手动发送MCP消息以协调匹配。看 docs/architecture/mcp_message_contracts.md 用于消息规范。

注: 计划使用一个协调器脚本来自动化这一过程,但尚未实现。目前,使用集成测试模式进行演示。


附加集成测试

一旦你有了4名球员,你也可以尝试这些测试:

单场比赛测试(仅限2名球员):

# Requires only P01 and P02 running
python3 tests/test_match.py

迷你联赛测试(2名球员):

# Requires only P01 and P02 running
python3 tests/test_league.py

集成测试预期输出

跑步时 python3 tests/test_full_league.py,您应该看到:

================================================================================
MCP Even/Odd League - Phase 6 Full League Test
================================================================================

📋 Test Setup:
  - League Manager: Tracking standings
  - Referee REF01: Orchestrating matches
  - 4 Players:
    • P01: port 8101 (prefers EVEN)
    • P02: port 8102 (prefers ODD)
    • P03: port 8103 (prefers EVEN)
    • P04: port 8104 (prefers ODD)
  - Format: Round-Robin (6 matches total)

🏆 Starting League: league_2025_even_odd
   Format: Round-Robin
   Players: P01, P02, P03, P04
   Total matches: 6

🎮 ============================================================================
Match 1/6: P01 vs P02 (LEAGUE_MATCH_001)
==============================================================================
...

集成测试协调 6场比赛 (每个玩家玩一次其他玩家)并显示:

  • 实时比赛结果
  • 每场比赛后的排名
  • 最终联赛冠军

重要提示: 此输出来自自动化集成测试。在生产环境中,比赛将通过MCP消息触发到正在运行的League Manager服务器。


系统组件

1.联赛经理

目的: 协调联盟,跟踪排名,协调裁判。

责任:

  • 注册玩家
  • 安排循环赛
  • 保持排名(胜、负、平、分)
  • 向玩家发布排名更新
  • 宣布联赛冠军

端点: http://localhost:8000/mcp

状态机: IDLE → 注册中→ ROUND_IN_PROGRESS→ 圆形完成→ 联盟_完成

参考: docs/architecture/interface.md#leaguemanagerace


2.裁判

目的: 完全公正地仲裁个人比赛。

责任:

  • 邀请玩家参加比赛
  • 从两名玩家那里收集对等选择
  • 随机数(1-10)
  • 根据平价确定获胜者
  • 处理超时和技术损失
  • 向联盟经理报告结果

端点: 每场比赛即时化(无持久HTTP服务器)

比赛流程:

  1. 发送 GAME_INVITATION 对于两位玩家
  2. 等待 GAME_JOIN_ACK (5秒超时)
  3. 发送 CHOOSE_PARITY_CALL 对于两位玩家
  4. 等待 CHOOSE_PARITY_RESPONSE (30秒超时)
  5. 随机抽取数字,确定获胜者
  6. 发送 GAME_OVER 通知两名玩家
  7. 发送 MATCH_RESULT_REPORT 联盟经理

参考: 文档/作业/章节_08_game_flow.md


3.玩家代理

目的: 与战略决策相匹配的自主参与者。

责任:

  • 接受/拒绝游戏邀请
  • 根据要求选择“偶数”或“奇数”
  • 在比赛中保持内部状态
  • 处理比赛结果并更新策略
  • 在协议超时内响应

终点:

  • 玩家P01: http://localhost:8101/mcp
  • 玩家P02: http://localhost:8102/mcp
  • 玩家P03: http://localhost:8103/mcp
  • 玩家P04: http://localhost:8104/mcp

状态机: IDLE → 受邀→ 选择→ 等待结果→ IDLE

当前战略:

  • P01、P03:始终选择“偶数”
  • P02、P04:始终选择“奇数”

注: 策略故意简化协议演示。先进的战略可以在 agents/player_*/strategy.py (未来扩展点)。

参考: docs/architecture/state_machines.md#播放器状态机


4.共享图书馆

目的: 所有代理共享的通用实用程序。

组件:

league_sdk/:

  • config_loader.py -加载JSON配置文件
  • config_models.py -用于类型化配置的Pydantic模型
  • logger.py -JSON结构化日志记录
  • mcp_client.py -用于发送MCP消息的HTTP客户端
  • repositories.py -数据持久层

data/config/:

  • system_config.json -系统范围设置(端口、超时)
  • league_config.json -联赛参数(轮次、得分)

共享数据:

  • /SHARED/data/ -共享数据库文件
  • /SHARED/logs/ -集中式JSON日志

游戏规则

比赛机制

  1. 初始化:

    • 裁判邀请两名球员
    • 玩家必须在5秒内接受
  2. 奇偶校验选择:

    • 两位玩家都选择“偶数”或“奇数”
    • 同时做出选择(无信息泄露)
    • 每位玩家超时30秒
  3. 图纸编号:

    • 裁判从1-10(含)中随机抽取整数
    • 数字奇偶校验决定正确性
  4. 获胜者决定:

玩家A选择 玩家B选择 开奖号码 结果
偶数 奇数 4(偶数) A获胜
偶数 奇数 7(奇数) B获胜
偶数 偶数 4(偶数) 平局(均正确)
偶数 偶数 7(奇数) 平局(均错)
奇数 奇数 4(偶数) 平局(均为错误)
odd odd 7(奇数) 平局(均正确)

评分系统

  • 赢: 3分
  • 绘图: 各得1分
  • 损失: 0分
  • 技术损失: 0分(对手得3分)

技术损失

如果玩家出现以下情况,他们将遭受技术损失:

  • 5秒内未响应邀请
  • 未能在30秒内提交奇偶校验选项
  • 发送格式错误的JSON
  • 发送无效的奇偶校验选项(不是“偶数”或“奇数”)
  • 比赛中撞车

联赛形式

循环赛:

  • 每个玩家只与其他玩家玩一次
  • 有N名球员:N(N-1)/2场比赛
  • 示例:4名球员=6场比赛

支架断铁器(按顺序):

  1. 总分
  2. 正面交锋记录
  3. 获胜次数
  4. 按字母顺序排列的玩家ID

MCP协议

协议概述

系统使用 JSON-RPC 2.0 超过 HTTP POST 用于所有代理间通信。

标准请求格式:

{
  "jsonrpc": "2.0",
  "method": "handle_game_invitation",
  "params": {
    "protocol": "league.v2",
    "message_type": "GAME_INVITATION",
    "sender": "referee:REF01",
    "timestamp": "2025-01-19T10:30:00Z",
    "match_id": "MATCH_001",
    "player_id": "P01",
    "opponent_id": "P02",
    "referee_endpoint": "http://localhost:9000/mcp",
    "league_id": "league_2025_even_odd",
    "round_id": 1,
    "role_in_match": "player_A"
  },
  "id": "req-123"
}

标准响应格式:

{
  "jsonrpc": "2.0",
  "result": {
    "protocol": "league.v2",
    "message_type": "GAME_JOIN_ACK",
    "sender": "player:P01",
    "timestamp": "2025-01-19T10:30:01Z",
    "match_id": "MATCH_001",
    "player_id": "P01",
    "arrival_timestamp": "2025-01-19T10:30:00.5Z",
    "accept": true
  },
  "id": "req-123"
}

消息类型

裁判→ 玩家:

  1. GAME_INVITATION -邀请匹配
  2. CHOOSE_PARITY_CALL -请求奇偶校验选择
  3. GAME_OVER -比赛结果通知

玩家→ 裁判:

  1. GAME_JOIN_ACK -接受/拒绝邀请
  2. CHOOSE_PARITY_RESPONSE -提交奇偶校验选择
  3. GAME_OVER_ACK -确认比赛结果

裁判→ 联盟经理:

  1. MATCH_RESULT_REPORT -报告比赛结果

联盟经理→ 玩家:

  1. ROUND_ANNOUNCEMENT -即将到来的比赛
  2. LEAGUE_STANDINGS_UPDATE -当前排名
  3. ROUND_COMPLETED -圆形完成
  4. LEAGUE_COMPLETED -联赛结束

完整规格: docs/architecture/mcp_message_contracts.md

超时

消息类型 最大响应时间
GAME_JOIN_ACK 5秒
CHOOSE-PARITY_RESPONSE 30秒
所有其他 10秒

超时行为:

  • 裁判超时重试一次
  • 秒暂停→ 技术损失
  • 默认情况下,对手获胜

管理联盟

先决条件

在参加联赛之前,请确保您已经:

  1. 已安装软件包 (参见 安装):

    pip3 install -e ".[dev]"
    
  2. 无需手动修改代码 -下面的所有命令都可以开箱即用

  3. 了解命令格式 -所有代理都使用Python的模块语法运行:

    python3 -m mcp_even_odd_league.agents.<agent_name>.main [arguments]
    

逐步执行

执行顺序:

  1. 首发联赛经理(1号航站楼)
  2. 开始裁判REF01(终端2)
  3. 启动所有玩家代理(终端3-6)- 等待每个程序完全启动后再继续

注: 所有6个代理必须在其端口上运行和监听。然后,联盟经理可以通过向裁判发送比赛分配来协调比赛,裁判会与玩家协调游戏。

1.启动联赛经理

python3 -m mcp_even_odd_league.agents.league_manager.main

预期产量:

League Manager initialized for league: league_2025_even_odd
Starting League Manager on port 8000

=== League Manager Starting ===
League ID: league_2025_even_odd
Port: 8000
Endpoint: http://localhost:8000/mcp
================================

 * Serving Flask app 'main'
 * Running on http://127.0.0.1:8000

2.开始裁判

python3 -m mcp_even_odd_league.agents.referee_REF01.main REF01

预期产量:

Referee initialized: REF01
Starting Referee REF01

=== Referee Starting ===
Referee ID: REF01
Port: 8001
Endpoint: http://localhost:8001/mcp
========================

 * Serving Flask app 'main'
 * Running on http://127.0.0.1:8001

3.启动玩家代理

在单独的终端中:

# Terminal 3
python3 -m mcp_even_odd_league.agents.player_P01.main P01

# Terminal 4
python3 -m mcp_even_odd_league.agents.player_P02.main P02

# Terminal 5
python3 -m mcp_even_odd_league.agents.player_P03.main P03

# Terminal 6
python3 -m mcp_even_odd_league.agents.player_P04.main P04

预期产量(每位玩家):

Player initialized: P01
Starting Player P01

=== Player Starting ===
Player ID: P01
Port: 8101
Endpoint: http://localhost:8101/mcp
=======================

 * Serving Flask app 'main'
 * Running on http://127.0.0.1:8101

4.触发比赛

当所有6个代理都在运行时,可以通过以下方式触发匹配:

选项A:集成测试(自动化)

python3 tests/test_full_league.py

注意:这绕过了正在运行的League Manager/Referee服务器,并以编程方式实例化它们以进行自动化测试。

选项B:手动MCP消息(生产) 将JSON-RPC请求发送到League Manager端点:

  1. 注册玩家
  2. 创建日程表
  3. 触发轮执行

看 docs/architecture/mcp_message_contracts.md 用于消息规范。


测试

测试套件概述

该项目包括两个层面的综合测试:

单元测试

核心业务逻辑测试(无需Flask服务器):

测试文件 目的 测试模块 覆盖范围
tests/unit/test_game_logic.py 偶数/奇数游戏机制 game_logic.py 100%
tests/unit/test_config_loader.py 配置加载 config_loader.py, config_models.py 84.78%, 94.59%

集成/系统测试

使用正在运行的代理进行端到端测试:

测试文件 目的 测试组件
tests/test_skeleton.py 基本组件实例化 所有代理
tests/test_mcp_layer.py MCP消息格式化 MCPClient,JSON-RPC
tests/test_match.py 单场比赛执行 裁判,2名球员
tests/test_league.py 多场比赛联赛 联赛经理、裁判、2名球员
tests/test_full_league.py 完成循环赛 所有组件,4名玩家
tests/test_timeout.py 超时和错误处理 裁判超时逻辑

运行测试

安装测试依赖项

pip3 install -e ".[dev]"

这将在开发模式下安装带有pytest、pytest-cov和其他开发依赖项的包。

仅运行单元测试

pytest tests/unit/ -v

运行集成测试

# Run all integration tests
pytest tests/ --ignore=tests/unit/ -v

# Run specific integration test
pytest tests/test_match.py -v

运行所有测试

pytest tests/ -v

带超时保护运行

pytest tests/ --timeout=60

测试覆盖率

项目实现 核心逻辑的总体覆盖率为92.52% 根据提交指南的要求。

生成覆盖率报告

终端输出:

pytest tests/unit/ --cov=src/mcp_even_odd_league --cov-report=term-missing

HTML报告(推荐):

pytest tests/unit/ --cov=src/mcp_even_odd_league --cov-report=html
open htmlcov/index.html

覆盖结果

总体覆盖率:92.52% (147份陈述,11份遗漏)

涵盖的核心逻辑模块:

  • game_logic.py: 100% (24个陈述,0个遗漏)✓
  • config_loader.py: 84.78% (46项陈述,7项遗漏)✓
  • config_models.py: 94.59% (74项陈述,4项遗漏)✓
  • 包裹 __init__.py 文件夹: 100% ✓

覆盖范围配置

覆盖范围在中配置 pyproject.toml 仅用于测量 确定性核心逻辑:

涵盖的模块:

  • game_logic.py -偶数/奇数游戏机制(纯函数)
  • config_loader.py -配置加载(确定性)
  • config_models.py -数据模型(Pydantic模型)

模块不在覆盖范围内 (通过集成测试进行测试):

  • */main.py -Flask入口点和服务器
  • */handlers.py -HTTP/MCP请求处理程序
  • mcp_client.py -HTTP客户端网络
  • logger.py -IO操作
  • repositories.py -数据库/文件IO
  • strategy.py, scheduler.py -Stub模块

理论基础: 覆盖率衡量单元可测试的确定性逻辑。集成层(HTTP、IO、Flask)通过中的端到端集成测试进行验证 tests/test_*.py.

解读承保报告

HTML覆盖率报告(htmlcov/index.html)提供:

  • 逐行覆盖可视化
  • 缺失的线条以红色突出显示
  • 每个模块的覆盖百分比
  • 分行覆盖率分析

要查看包含/排除哪些模块: 检查 pyproject.toml [tool.coverage.run] 部分为 omit 列表。

有关全面的测试文档,请参阅 测试.md.


配置

系统配置

文件: SHARED/data/config/system_config.json

{
  "league_manager": {
    "port": 8000,
    "host": "localhost"
  },
  "players": [
    {"id": "P01", "port": 8101},
    {"id": "P02", "port": 8102},
    {"id": "P03", "port": 8103},
    {"id": "P04", "port": 8104}
  ],
  "timeouts": {
    "game_join_ack": 5,
    "parity_choice": 30,
    "default": 10
  },
  "retry_policy": {
    "max_attempts": 2,
    "backoff_seconds": 1
  }
}

联盟配置

文件: SHARED/data/config/league_config.json

{
  "league_id": "league_2025_even_odd",
  "format": "round_robin",
  "scoring": {
    "win": 3,
    "draw": 1,
    "loss": 0,
    "technical_loss": 0
  },
  "match_settings": {
    "number_range": [1, 10],
    "random_seed": null
  }
}

环境变量

创建 .env 文件 (可选,用于生产部署):

# Server Configuration
LEAGUE_MANAGER_HOST=localhost
LEAGUE_MANAGER_PORT=8000

# Logging
LOG_LEVEL=INFO
LOG_FILE=logs/league.log

# Database
DB_PATH=SHARED/data/league.db

# Timeouts (seconds)
TIMEOUT_GAME_JOIN=5
TIMEOUT_PARITY_CHOICE=30
TIMEOUT_DEFAULT=10

注: .env 文件被标记为无效。使用 example.env 作为模板(待创建)。


故障排除

快速入门问题

运行测试时出现“ModuleNotFoundError”

错误:

ModuleNotFoundError: No module named 'mcp_even_odd_league'

解决方案:

# Install the package in development mode
pip3 install -e ".[dev]"

测试文件中的“FileNotFoundError”

错误:

FileNotFoundError: [...]/tests/agents/referee_REF01/main.py

解决方案: 这在最新版本中已修复。拉取最新更改:

git pull origin main

如果仍然看到此错误,则测试文件的导入路径不正确。他们应该从 mcp_even_odd_league.agents.* 不是从本地路径。

玩家在集成测试期间没有响应

症状:

  • 测试挂起或超时
  • “连接被拒绝”错误

解决方案:

  1. 在开始测试之前,确保所有必需的玩家代理都在运行
  2. 检查每个玩家终端显示: Running on http://...
  3. 验证端口8101、8102、8103、8104是否未被阻塞

杀死卡住的进程

# Kill all agents on their ports
for p in 8000 8001 8101 8102 8103 8104; do
  lsof -ti :$p | xargs kill -9 2>/dev/null
done

常见问题

1.端口已在使用中

错误:

OSError: [Errno 48] Address already in use

解决方案:

# Find and kill process on port 8101
lsof -ti:8101 | xargs kill -9

# Verify port is free
lsof -ti:8101

2.玩家没有回应

症状:

  • 裁判报告“等待响应超时”
  • 技术损失比赛结果

调试步骤:

  1. 验证玩家进程是否正在运行: lsof -ti:8101
  2. 检查玩家日志: tail -f logs/player_P01.log
  3. 测试玩家端点:
    curl -X POST http://localhost:8101/mcp \
      -H "Content-Type: application/json" \
      -d '{"jsonrpc":"2.0","method":"ping","params":{},"id":"test"}'
    

3.JSON解析错误

错误:

json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

原因:

  • 请求/响应中的JSON格式错误
  • 空响应体
  • 内容类型标头不正确

解决方案:

  • 使用以下方式验证JSON: python3 -m json.tool < message.json
  • 确保所有MCP消息包括 "jsonrpc": "2.0"
  • 设置标题: Content-Type: application/json

4.违反国家机器

错误:

Invalid state for GAME_INVITATION: current state is CHOOSING, expected IDLE

原因: 玩家收到的消息状态错误(可能是由于之前的比赛未完成)。

解决方案:

  1. 重新启动玩家代理
  2. 验证中的匹配完成逻辑 handlers.py
  3. 检查状态转换日志: grep "State transition" logs/player_*.log

调试模式

启用详细日志记录:

在播放器main.py中:

import logging
logging.basicConfig(level=logging.DEBUG)

使用调试输出运行:

python3 -m mcp_even_odd_league.agents.player_P01.main P01 --debug

项目结构

mcp-even-odd-league/
├── src/                             # Python package source (src layout)
│   └── mcp_even_odd_league/         # Main package
│       ├── __init__.py              # Package root
│       ├── agents/                  # Autonomous agent implementations
│       │   ├── league_manager/      # League orchestration
│       │   │   ├── main.py          # Entry point, Flask server
│       │   │   ├── handlers.py      # MCP message handlers
│       │   │   └── scheduler.py     # Round-robin scheduling
│       │   ├── referee_REF01/       # Match arbitration
│       │   │   ├── main.py          # Referee logic
│       │   │   ├── game_logic.py    # Even/Odd game mechanics
│       │   │   └── handlers.py      # MCP message handlers
│       │   ├── player_P01/          # Player agent (EVEN strategy)
│       │   │   ├── main.py          # Entry point, Flask server
│       │   │   ├── handlers.py      # MCP message handlers
│       │   │   └── strategy.py      # Parity choice strategy
│       │   ├── player_P02/          # Player agent (ODD strategy)
│       │   ├── player_P03/          # Player agent (EVEN strategy)
│       │   └── player_P04/          # Player agent (ODD strategy)
│       └── league_sdk/              # Common SDK for all agents
│           ├── config_loader.py     # Configuration management
│           ├── config_models.py     # Pydantic data models
│           ├── logger.py            # JSON structured logging
│           ├── mcp_client.py        # MCP HTTP client
│           └── repositories.py      # Data persistence
│
├── tests/                           # Test suite
│   ├── unit/                        # Unit tests (core logic)
│   │   ├── test_game_logic.py       # Game mechanics tests (100% coverage)
│   │   └── test_config_loader.py    # Configuration tests (84.78% coverage)
│   ├── test_skeleton.py             # Component instantiation tests
│   ├── test_mcp_layer.py            # MCP protocol tests
│   ├── test_match.py                # Single match integration test
│   ├── test_league.py               # Multi-match league test
│   ├── test_full_league.py          # Full round-robin test
│   └── test_timeout.py              # Timeout handling tests
│
├── SHARED/                          # Shared data and configuration
│   ├── data/                        # Shared data directory
│   │   └── config/                  # Configuration files
│   │       ├── system_config.json   # System-wide settings
│   │       └── league_config.json   # League parameters
│   └── logs/                        # Centralized log directory
│
├── docs/                            # Comprehensive documentation
│   ├── assignment/                  # Assignment specifications
│   │   ├── chapter_06_requirements.md  # Assignment requirements
│   │   ├── chapter_08_game_flow.md     # Game flow and rules
│   │   └── chapter_09_protocol.md      # MCP protocol details
│   └── architecture/                # Architecture documentation
│       ├── interfaces.md            # Formal interface contracts
│       ├── state_machines.md        # State machine diagrams
│       ├── mcp_message_contracts.md # Complete message specs
│       ├── block_architecture.md    # Component breakdown
│       ├── class_map.md             # Class relationships
│       └── project_tree_mapping.md  # Directory structure guide
│
├── pyproject.toml                   # Package metadata and build config
├── .gitignore                       # Git exclusions
└── README.md                        # This file

主要结构特征:

  • src/布局:现代Python打包最佳实践(PEP 518/PEP 517)
  • 合适的包装:可通过以下方式安装 pip install -e .
  • 单独测试:单元测试 tests/unit/,集成测试 tests/
  • 配置:集中在 SHARED/data/config/
  • 可编辑安装:对源代码的更改会立即反映出来,无需重新安装

详细地图: 看 docs/architecture/project_tree_mapping.md


文档

学术文件

所有文件均按照任务规范进行结构化:

任务要求

架构设计

其他资源

原始作业PDF:

  • chapter_06_assignment.pdf -任务概述
  • chapter_08_game_flow.pdf -游戏规则和流程
  • chapter_09_protocol.pdf -协议规范
  • chapter_10_classes.pdf -班级设计
  • chapter_11_project_structure.pdf -项目组织机构
  • software_submission_guidelines (1).pdf -提交要求

贡献

这是一个获得课程学分的学术项目。不接受外部捐款。然而,鼓励同一课程的学生:

  1. 协议合规性测试: Exchange播放器代理验证互操作性
  2. Bug报告: 报告协议违规或崩溃
  3. 战略讨论: 分享决策方法的见解(不共享代码)

代码风格

  • 语言: Python 3.9+
  • 风格指南: PEP 8
  • 线路长度: 最多100个字符
  • 文档字符串: 所有公共方法的谷歌风格文档字符串
  • 类型提示: 在有益的地方使用类型注释

Git工作流

# Create feature branch
git checkout -b feature/player-advanced-strategy

# Make changes and commit
git add agents/player_P01/strategy.py
git commit -m "Implement adaptive parity selection strategy"

# Push to remote
git push origin feature/player-advanced-strategy

提交消息格式:

<type>: <subject>

<body>

<footer>

类型: 壮举、修复、文档、测试、重构、杂务


许可证

仅供学术使用

本项目作为学术课程的一部分提交 具有模型上下文协议的AI代理 当然。作者保留所有权利。

被允许:

  • 出于教育目的查看源代码
  • 在本地运行以进行测试和学习
  • 学术引文中的参考文献

禁止:

  • 商业用途
  • 无归属的再分配
  • 抄袭或作为自己的作品提交

引用:

Tal Barda. (2025). MCP Even/Odd League: Multi-Agent Game System
with Model Context Protocol. AI Agents with Model Context Protocol, Reichman University.
https://github.com/TalBarda8/mcp-even-odd-league

学分

课程: 具有模型上下文协议的AI代理 教练: 约拉姆·塞加尔博士 机构: 赖希曼大学 学年: 2024-2025

技术:

特别感谢:

  • 作业设计和协议规范课程讲师
  • 互操作性测试同学
  • 优秀库Python社区

联系

作者 塔尔·巴达 github: https://github.com/TalBarda8/mcp-even-odd-league

项目问题: https://github.com/TalBarda8/mcp-even-odd-league/issues


文件版本: 1.0 最后更新时间: 2025-01-20 状态: 积极发展