Multi-Agent实践第3期:看智能体下五子棋

本文涉及的产品
交互式建模 PAI-DSW,每月250计算时 3个月
模型在线服务 PAI-EAS,A10/V100等 500元 1个月
模型训练 PAI-DLC,100CU*H 3个月
简介: 智能五子棋

前言

在上一期的文章《Multi-Agent实践第2期: @智能体 你怎么看?》中,我们简要介绍了如何使用AgentScope快速构建一个多智能体聊天场景以及可以直接"@"提及某个智能体的群聊功能。本期,我们将带你体验如何实现用AgentScope如何快速实现一个游戏向应用:试试让两个智能体下五子棋~ 因为有些功能性代码比较琐碎,为了文章简洁可能被部分隐去;完整的代码可以参见(https://github.com/modelscope/agentscope/tree/main/examples/game_gomoku

欢迎大家关注AgentScope,在github上(https://github.com/modelscope/agentscope) 为我们star 🌟。我们会在接下来几天,继续推出一系列教程,让大家每天花5~10分钟,搭建出不同的由简单到复杂的有趣的多智能体应用!

开始构建应用

首先,我们还是需要载入模型配置。因为下五子棋的例子需要大模型有较强的服从指令的能力和逻辑推理能力,我们在这个例子里默认会用到gpt-4的模型。关于怎么配置模型,欢迎大家回顾我们前两期的内容;这里我们会从model_configs.json中读入取模型配置。

import agentscope
agentscope.init(model_configs="./model_configs.json")
# 替换成自己的model config name
YOUR_MODEL_CONFIGURATION_NAME = "{YOUR_MODEL_CONFIGURATION_NAME}"

除此之外,我们也需要先给出一些固定的提示词模板和游戏设定,包括:

  1. CURRENT_BOARD_PROMPT_TEMPLATE:当前游戏情况和哪个玩家的回合;
  2. Alice执黑(表示为“o”),Bob执白(表示为“x”)
import numpy as np
from agentscope.message import Msg
from typing import Tuple
from agentscope.agents import AgentBase
CURRENT_BOARD_PROMPT_TEMPLATE = """The current board is as follows:
{board}
{player}, it's your turn.
)"""
NAME_BLACK = "Alice"
NAME_WHITE = "Bob"
# The mapping from name to piece
NAME_TO_PIECE = {
    NAME_BLACK: "o",
    NAME_WHITE: "x",
}
EMPTY_PIECE = "0"
piece_black = NAME_TO_PIECE[NAME_BLACK]
piece_white = NAME_TO_PIECE[NAME_WHITE]

创建一个棋盘智能体记录情况、维护全局

下五子棋,我们肯定需要一个棋盘。在多智能体的环境里,我们首先可以创建一个棋盘“智能体”。我们默认会把棋盘的大小设置成15x15。需要注意的是,这个棋盘智能体并不需要连接大模型,它的功能主要是rule-based的判断,包括了接受新的落子,检查智能体/玩家的落子是否合法(是不是在棋盘内?格子是不是已经被占据了?),判断落子之后是否带来胜利或者平局,以及将棋盘信息转化成文字分享给其他智能体。

class BoardAgent(AgentBase):
    
    def __init__(self, name):
        super().__init__(name=name, use_memory=False)
        
        # Init the board
        self.size = 15
        self.board = np.full((self.size, self.size), 0)
        
        # Record the status of the game
        self.game_end = False
        
    def reply(self, x: dict = None) -> dict:
        if x is None:
            # 开始游戏
            content = "Welcome to the Gomoku game! Black player goes first. Please make your move." 
        else:
          # 在游戏过程中
          # 1. 检查落子是否合法;
          # 2. 检查落子是否能带来胜利或平局
          # 3. 若游戏继续,更新棋盘信息
          # 4. 打印当前棋局 (依赖完整代码中的board2img函数)
          # 代码参见文章开头链接
          # ...
    # 是否合法落子
    def assert_valid_move(self, x: int, y: int) -> bool:
        return 0 <= x < self.size and 0 <= y < self.size and self.board[x, y] is None
    #检查胜利与否
    def check_win(self, move: Tuple[int, int], piece: str) -> bool:
        # 代码参见代码参见文章开头链接
        # ...
    #检查平局
    def check_draw(self) -> bool:
        return np.all(self.board != None)
    #棋盘状态to文字
    def board2text(self) -> str:
        return "\n".join([str(_)[1:-1].replace(", ", " ") for _ in self.board])

创建下五子棋的智能体

下五子棋,起码需要智能体返回一个明确的落子位置(x, y)。除此之外,根据CoT的思想,如果让大模型同时返回一段分析(智能体的想法thought),可能可以让回答更加合理。

这种具有明确格式的需求,我们除了可以在给大模型的提示词中明确要求,也同时可以用上AgentScope里面处理大模型返回的接口,用一个parse_func去解析大模型的结构化回答、提取有效信息。

import json
from agentscope.models import ModelResponse
from typing import Optional
# 说明游戏规则和agent回答规则 (样例)
SYS_PROMPT_TEMPLATE = """
You're a skillful Gomoku player. You should play against your opponent according to the following rules:
Game Rules:
1. This Gomoku board is a 15*15 grid. Moves are made by specifying row and column indexes, with [0, 0] marking the top-left corner and [14, 14] indicating the bottom-right corner.
2. The goal is to be the first player to form an unbroken line of your pieces horizontally, vertically, or diagonally. 
3. If the board is completely filled with pieces and no player has formed a row of five, the game is declared a draw.
Note: 
1. Your pieces are represented by '{}', your opponent's by '{}'. 0 represents an empty spot on the board. 
2. You should think carefully about your strategy and moves, considering both your and your opponent's subsequent moves. 
3. Make sure you don't place your piece on a spot that has already been occupied. 
4. Only an unbroken line of five same pieces will win the game. For example, "xxxoxx" won't be considered a win. 
5. Note the unbroken line can be formed in any direction: horizontal, vertical, or diagonal.
"""
# 提示词(样例)
HINT_PROMPT = """You should respond in the following format, which can be loaded by json.loads in Python:
{{
    "thought": "what you thought",
    "move": [row, col]
}}
"""
# 提取大模型回答中的格式化/有效信息
def parse_func(response: ModelResponse) -> ModelResponse:
    res_dict = json.loads(response.text)
    if "move" in res_dict and "thought" in res_dict:
        return ModelResponse(raw=res_dict)
    else:
        raise ValueError(f"Invalid response format in parse_func with response: {response.text}")
# 下五子棋的智能体
class GomokuAgent(AgentBase):
    """A Gomoku agent that can play the game with another agent."""
    
    def __init__(self, name, sys_prompt, model_config_name):
        super().__init__(name=name, sys_prompt=sys_prompt, model_config_name=model_config_name)
        
        self.memory.add(Msg("system", sys_prompt, role="system"))
        
    def reply(self, x: Optional[dict] = None) -> dict:
        if self.memory:
            self.memory.add(x)
        
        msg_hint = Msg("system", HINT_PROMPT, role="system")
        # 组织prompt
        prompt = self.model.format(
            self.memory.get_memory(),
            msg_hint,     
        )
        
        response = self.model(
            prompt,
            parse_func=parse_func,
            max_retries=3,
        ).raw
        
        self.speak(Msg(self.name, json.dumps(response, indent=4, ensure_ascii=False), role="assistant"))
        
        if self.memory:
            self.memory.add(Msg(self.name, response, role="assistant"))
        
        # 隐去想法(thought)
        return Msg(self.name, response["move"], "assistant")

在开发的时候,大家可以自己尝试调整SYS_PROMPT_TEMPLATE,看能不能有更好的效果~

游戏主逻辑

我们现在可以创建我们需要的三个智能体:一个棋盘,两个五子棋玩家。

black = GomokuAgent(
    NAME_BLACK,
    model_config_name=YOUR_MODEL_CONFIGURATION_NAME,
    sys_prompt=SYS_PROMPT_TEMPLATE.format(piece_black, piece_white),
)
                    
white = GomokuAgent(
    NAME_WHITE,
    model_config_name=YOUR_MODEL_CONFIGURATION_NAME,
    sys_prompt=SYS_PROMPT_TEMPLATE.format(piece_white, piece_black),
)
board = BoardAgent(name="Host")

创建好了智能体,可以把他们都放进一个群聊的环境中,让他们的沟通更加高效(一名五子棋玩家分享的落子信息可以被另一名玩家和棋盘同时获取)。

from agentscope import msghub
MAX_STEPS = 10
msg = None
i = 0
# Use a msg hub to share conversation between two players, e.g. white player can hear what black player says to the board
with msghub(participants=[black, white, board]):
    while not board.game_end and i < MAX_STEPS:
        for player in [black, white]:
            # receive the move from the player, judge if the game ends and remind the player to make a move
            msg = board(msg)
            
            # end the game if draw or win 
            if board.game_end:
                break
                
            # make a move
            msg = player(msg)
            
            i += 1

效果展示图

大家可以尝试我们的完整版代码(https://github.com/modelscope/agentscope/tree/main/examples/game_gomoku),可以看到在jupyter notebook上打印出每一步以及智能体的想法。

image.png

总结

这个五子棋小游戏可以作为一个抛砖引玉的例子,但是我们可以看到大模型的表现其实并没有很智能。我们也会和大家一起,持续探索如何能让大模型在下五子棋方面更加“聪明”。接下来几期,我们会介绍如何在AgentScope里用上让智能体更全能、更聪明的技术(比如ReAct, RAG),敬请期待!

欢迎大家关注AgentScope,在github上为我们star 🌟。

延伸阅读和资源

比赛

看到这里,如果你有好玩的想法,不如实践起来,还可以顺便参加下面的比赛~

image.png

点击即可跳转~

Create @ AI 创客松第四季 (aliyun.com)

相关文章
|
2月前
|
Arthas 监控 Java
拥抱 OpenTelemetry:阿里云 Java Agent 演进实践
本文介绍了阿里云 Java Agent 4.x 版本在基于 OTel Java Agent 二次开发过程中的实践与思考,并重点从功能、性能、稳定性、兼容性四个方面介绍了所做的工作。同时也介绍了阿里云可观测团队积极参与开源建设取得的丰厚成果。
244 7
拥抱 OpenTelemetry:阿里云 Java Agent 演进实践
|
24天前
|
人工智能 API 数据库
Qwen-Agent功能调用实践探索
本文详细解析了Qwen-Agent的核心功能——功能调用,涵盖其定义、工作流程、重要性和实际应用,通过实例展示了如何在Qwen-Agent中利用此功能与外部工具和API互动,扩展AI应用范围。
|
1月前
|
人工智能 自然语言处理 数据挖掘
田渊栋团队新作祭出Agent-as-a-Judge!AI智能体自我审判,成本暴跌97%
田渊栋团队提出Agent-as-a-Judge框架,利用智能体自身评估其他智能体的性能,不仅关注最终结果,还能提供中间反馈,更全面准确地反映智能体的真实能力。该框架在DevAI基准测试中表现出色,成本效益显著,为智能体的自我改进提供了有力支持。
46 7
|
2月前
|
存储 人工智能 算法
卷起来!让智能体评估智能体,Meta发布Agent-as-a-Judge
Meta(原Facebook)提出了一种名为Agent-as-a-Judge的框架,用于评估智能体的性能。该框架包含八个模块,通过构建项目结构图、定位相关文件、读取多格式数据、搜索和检索信息、询问要求满足情况、存储历史判断、以及规划下一步行动,有效提升了评估的准确性和稳定性。实验结果显示,Agent-as-a-Judge在处理复杂任务依赖关系方面优于大型语言模型,但在资源消耗和潜在偏见方面仍面临挑战。
47 1
|
2月前
|
传感器 机器学习/深度学习 自然语言处理
智能代理(Agent)在工具调用与协作中的应用实践
随着人工智能技术的飞速发展,智能代理(Agent)技术已成为解决复杂任务的关键手段。本文深入探讨了如何设计灵活的工具调用机制和构建高效的单/多Agent系统以提升任务执行效率。文章不仅涵盖了相关的理论知识,还提供了丰富的实践案例和代码实现,旨在帮助读者深入理解和应用智能代理技术。
188 2
|
2月前
|
Prometheus 监控 Java
深入探索:自制Agent监控API接口耗时实践
在微服务架构中,监控API接口的调用耗时对于性能优化至关重要。通过监控接口耗时,我们可以识别性能瓶颈,优化服务响应速度。本文将分享如何自己动手实现一个Agent来统计API接口的调用耗时,提供一种实用的技术解决方案。
62 3
|
3月前
|
人工智能 API 决策智能
swarm Agent框架入门指南:构建与编排多智能体系统的利器 | AI应用开发
Swarm是OpenAI在2024年10月12日宣布开源的一个实验性质的多智能体编排框架。其核心目标是让智能体之间的协调和执行变得更轻量级、更容易控制和测试。Swarm框架的主要特性包括轻量化、易于使用和高度可定制性,非常适合处理大量独立的功能和指令。【10月更文挑战第15天】
470 6
|
3月前
|
机器学习/深度学习 人工智能 算法
打造你的超级Agent智能体——在虚拟迷宫中智斗未知,解锁AI进化之谜的惊心动魄之旅!
【10月更文挑战第5天】本文介绍了一个基于强化学习的Agent智能体项目实战,通过控制Agent在迷宫环境中找到出口来完成特定任务。文章详细描述了环境定义、Agent行为及Q-learning算法的实现。使用Python和OpenAI Gym框架搭建迷宫环境,并通过训练得到的Q-table测试Agent表现。此项目展示了构建智能体的基本要素,适合初学者理解Agent概念及其实现方法。
119 9
|
24天前
|
机器学习/深度学习 人工智能 自然语言处理
Gemini 2.0:谷歌推出的原生多模态输入输出 + Agent 为核心的 AI 模型
谷歌最新推出的Gemini 2.0是一款原生多模态输入输出的AI模型,以Agent技术为核心,支持多种数据类型的输入与输出,具备强大的性能和多语言音频输出能力。本文将详细介绍Gemini 2.0的主要功能、技术原理及其在多个领域的应用场景。
132 20
Gemini 2.0:谷歌推出的原生多模态输入输出 + Agent 为核心的 AI 模型
|
24天前
|
人工智能 API 语音技术
TEN Agent:开源的实时多模态 AI 代理框架,支持语音、文本和图像的实时通信交互
TEN Agent 是一个开源的实时多模态 AI 代理框架,集成了 OpenAI Realtime API 和 RTC 技术,支持语音、文本和图像的多模态交互,具备实时通信、模块化设计和多语言支持等功能,适用于智能客服、实时语音助手等多种场景。
132 15
TEN Agent:开源的实时多模态 AI 代理框架,支持语音、文本和图像的实时通信交互

热门文章

最新文章