开发线上版Builder Cards游戏,Q负责生成代码、Bedrock基于RAG数据优化游戏策略

使用Amazon Q开发线上版Builder Cards游戏,并用Bedrock生成数据优化游戏策略

使用Amazon Bedrock、Amazon Q、EC2、S3等多个产品来开发AWS Builder Cards线上游戏,让AWS粉丝在娱乐的同时掌握AWS产品服务和架构。

通过这个应用的开发,串联多个AWS产品的最佳实践,也能够为开发者提供思路和借鉴。

概述

大纲

  • 使用Amazon Bedrock提炼AWS知识库,实现RAG以及效果测评和改进

  • 使用Amazon Bedrock提供模型API、Prompt

  • 使用Amazon Q开发Builder Cards游戏

  • 评测RAG命中和优化效果,并持续改进

AWS产品电子卡牌游戏

  • 线下纸质版Builder Cards需要玩家线下相聚,现在开发线上版Builder Cards,大家联网就可以参与

  • 一个平台4个玩家,暂时没有设置不同玩家登录和选座,优先实现了核心功能

  • 点击“发牌”可以为每位玩家分6张AWS产品卡牌

  • 每个玩家依次出牌,如果当前卡牌中出现的产品能够组成AWS架构则可以“申请获胜”,不能组合成AWS架构时则“出牌”并随机补充一张新牌

  • 直到有产品能组合成AWS架构并“申请获胜”,这时可以获得积分并继续打牌

  • 提供新手级别(会提示当前产品卡牌是否能组合成AWS架构、会提示详细游戏规则)、高级玩家级别(系统不会提示当前产品卡牌是否能组合成AWS架构,需要人工来判断)

技术实现

Bedrock选择模型

  • 通过模型来选择新手玩家、高级玩家等不同级别难度下的卡片数量、类别

  • 通过模型来判断当前产品组合是否符合AWS架构

  • 选择生图的模型

Bedrock知识库RAG处理数据

  • 数据获取:先获取AWS产品和架构数据,获取微信文章、博客等文章信息

  • 数据清洗:将获取到的数据进行清洗并加工为知识库RAG

  • 设置重排序和分块策略

使用Bedrock API生成玩家头像

  • 使用Bedrock生图模型服务生成玩家头像,并保存到AWS S3

安全性考虑

通过Bedrock Guadrial来进行敏感信息检测

优化改进:记录RAG命中记录并进行优化

  • 记录数据到RDS,并且验证命中率,根据命中率优化产品卡片数量

通过Q来实现代码开发

基础开发

  • 通过Q来实现基础代码开发

  • 通过Q调用Amazon Bedrock API来获取模型服务能力

Agentic AI开发范式

  • 先拆解需求、明确需求文档

  • 和Amazon Q进行对话来对齐需求

  • 让Amazon Q来生成TODO List

  • 再进行开发

生成测试案例和文档

  • 通过Amazon Q来进行测试

  • 生成README.md文档

发布到EC2

  • 将生成的代码发布到AWS EC2,对外提供IP的方式访问

代码实现

洗牌

// 洗牌
function shuffleDeck() {
    for (let i = gameState.deck.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [gameState.deck[i], gameState.deck[j]] = [gameState.deck[j], gameState.deck[i]];
    }
}

发牌

// 发牌
function dealCards() {
    if (gameState.gameStarted) {
        alert("游戏已经开始!");
        return;
    }
    
    // 清空所有玩家的卡片和公共区域
    gameState.players.forEach(player => {
        player.cards = [];
    });
    gameState.publicCards = [];
    
    // 给每个玩家发6张牌
    for (let i = 0; i < 6; i++) {
        for (let player of gameState.players) {
            if (gameState.deck.length > 0) {
                const card = gameState.deck.pop();
                player.cards.push(card);
            }
        }
    }
    
    // 设置游戏状态
    gameState.gameStarted = true;
    gameState.currentPlayerIndex = 0;
    $("#play-btn").prop("disabled", false);
    $("#claim-win-btn").prop("disabled", true);
    $("#deal-btn").prop("disabled", true);
    
    // 更新UI
    updateUI();
    highlightCurrentPlayer();
    
    // 更新操作提示
    const currentPlayer = gameState.players[gameState.currentPlayerIndex];
    updateOperationTip(`${currentPlayer.name}请选择一张卡片出牌,尝试组建有效的AWS架构`);
    
    // 提供当前玩家的架构建议
    suggestNextMove(currentPlayer);
}

// 创建卡片元素
function createCardElement(card) {
    const cardElement = document.createElement('div');
    cardElement.className = 'card';
    cardElement.dataset.cardId = card.id;
    
    const cardImage = document.createElement('div');
    cardImage.className = 'card-image';
    
    const img = document.createElement('img');
    img.src = card.image;
    img.alt = card.name;
    cardImage.appendChild(img);
    
    const cardContent = document.createElement('div');
    cardContent.className = 'card-content';
    
    const cardTitle = document.createElement('div');
    cardTitle.className = 'card-title';
    cardTitle.textContent = card.name;
    
    const cardDescription = document.createElement('div');
    cardDescription.className = 'card-description';
    cardDescription.textContent = card.description;
    
    cardContent.appendChild(cardTitle);
    cardContent.appendChild(cardDescription);
    
    cardElement.appendChild(cardImage);
    cardElement.appendChild(cardContent);
    
    return cardElement;
}

出牌

// 出牌
function playSelectedCard() {
    if (!gameState.gameStarted) {
        alert("请先发牌!");
        updateOperationTip("点击'发牌'开始游戏");
        return;
    }
    
    if (!gameState.selectedCard) {
        alert("请先选择一张卡片!");
        updateOperationTip("请先选择一张要出的卡片");
        return;
    }
    
    const currentPlayer = gameState.players[gameState.currentPlayerIndex];
    const playedCardName = gameState.selectedCard.name;
    const playedCardCategory = getCardCategory(gameState.selectedCard);
    
    // 从玩家手牌中移除选中的卡片
    const cardIndex = currentPlayer.cards.findIndex(card => card.id === gameState.selectedCard.id);
    if (cardIndex !== -1) {
        currentPlayer.cards.splice(cardIndex, 1);
    }
    
    // 将卡片添加到公共区域
    if (gameState.publicCards.length < 3) {
        gameState.publicCards.push(gameState.selectedCard);
    } else {
        // 如果公共区域已满,替换第一张卡片
        gameState.publicCards.shift();
        gameState.publicCards.push(gameState.selectedCard);
    }
    
    // 重置选中的卡片
    gameState.selectedCard = null;
    
    // 出牌后自动从牌堆获取一张牌
    let newCardInfo = "";
    if (gameState.deck.length > 0) {
        const newCard = gameState.deck.pop();
        currentPlayer.cards.push(newCard);
        newCardInfo = `获得了新卡片: ${newCard.name}`;
    } else {
        newCardInfo = "牌堆已空,无法获得新卡片";
    }
    
    // 切换到下一个玩家
    gameState.currentPlayerIndex = (gameState.currentPlayerIndex + 1) % gameState.players.length;
    const nextPlayer = gameState.players[gameState.currentPlayerIndex];
    
    // 检查是否还有足够的牌继续游戏(但不自动判断获胜)
    checkGameEnd();
    
    // 更新UI
    updateUI();
    highlightCurrentPlayer();
    
    // 更新操作提示
    updateOperationTip(`${currentPlayer.name}出了${playedCardCategory ? playedCardCategory + '类别的' : ''}${playedCardName},${newCardInfo}。现在轮到${nextPlayer.name}出牌`);
    
    // 为下一个玩家提供建议
    suggestNextMove(nextPlayer);
}

为玩家提供下一步建议

// 为玩家提供下一步建议
function suggestNextMove(player) {
    // 分析当前架构状态
    const playerCards = player.cards;
    const analysis = analyzeArchitecture(playerCards);
    let suggestion = "";
    
    if (analysis.categoryCount < 3) {
        const missingCategories = Object.keys(awsCategories).filter(c => !Object.keys(analysis.categorizedCards).includes(c));
        suggestion = `<span style="color: #2ecc71;">建议: 尝试获取这些缺失类别的卡片: ${missingCategories.slice(0, 3-analysis.categoryCount).join(", ")}</span>`;
    } else if (analysis.isValid) {
        // 架构已经有效
        if (playerCards.length === 6) {
            suggestion = '<span style="color: #f1c40f;">🎉 恭喜!你已经可以获胜了!</span>';
        } else {
            suggestion = '<span style="color: #2ecc71;">✓ 架构有效!可以继续收集卡片或申请验证</span>';
        }
    } else {
        // 检查是否有重复类别过多的情况
        let maxCategory = "";
        let maxCount = 0;
        
        for (const category in analysis.categorizedCards) {
            const count = analysis.categorizedCards[category].length;
            if (count > maxCount) {
                maxCount = count;
                maxCategory = category;
            }
        }
        
        if (maxCount > 2) {
            suggestion = `<span style="color: #f1c40f;">建议: ${maxCategory}类别有${maxCount}张卡片,考虑出掉一些以获取其他类别</span>`;
        } else {
            suggestion = '<span style="color: #2ecc71;">建议: 继续收集不同类别的AWS服务卡片</span>';
        }
    }
    
    // 显示未分类卡片信息(仅作提示)
    if (analysis.uncategorizedCards.length > 0) {
        suggestion += `<br><span style="color: #3498db;">💡 你有${analysis.uncategorizedCards.length}张未分类卡片,不影响架构有效性</span>`;
    }
    
    // 更新架构指南中的建议
    $(".architecture-guide").append(`<div class="move-suggestion">${suggestion}</div>`);
    
    // 10秒后移除建议
    setTimeout(() => {
        $(".move-suggestion").remove();
    }, 10000);
}

检查是否是AWS架构

可以使用模型来判断是否AWS架构,并且解析推荐架构方案、最佳实践

// 定义AWS架构类别
const awsCategories = {
    compute: ["Amazon EC2", "AWS Lambda", "Amazon ECS", "Amazon EKS", "AWS Fargate", "AWS Batch"],
    storage: ["Amazon S3", "Amazon EBS", "Amazon EFS", "Amazon FSx", "AWS Storage Gateway"],
    database: ["Amazon RDS", "Amazon DynamoDB", "Amazon ElastiCache", "Amazon Redshift", "Amazon Aurora", "Amazon Neptune"],
    networking: ["Amazon VPC", "Amazon CloudFront", "Amazon Route 53", "AWS Direct Connect", "Elastic Load Balancing"],
    security: ["AWS IAM", "Amazon Cognito", "AWS Shield", "AWS WAF", "Amazon GuardDuty", "AWS KMS"],
    integration: ["Amazon SNS", "Amazon SQS", "Amazon EventBridge", "AWS Step Functions", "Amazon API Gateway"]
};

// 检查卡片是否可以组成有效的AWS架构
function isValidAwsArchitecture(cards) {
    // 检查是否至少包含3个不同类别的服务
    const cardCategories = new Set();
    
    // 检查每张卡片属于哪个类别
    for (let card of cards) {
        for (let category in awsCategories) {
            if (awsCategories[category].includes(card.name)) {
                cardCategories.add(category);
                break;
            }
        }
    }
    
    // 只要有至少3个不同类别的AWS服务就算有效架构
    // 即使有非AWS服务卡片也不影响
    return cardCategories.size >= 3;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值