GameGenerator 根据用户描述生成 HTML5 游戏。

创建一个名为 game_generator.py 的文件,其中包含以下代码:

game_generator.py
import json
from pathlib import Path
from typing import Iterator

from agno.agent import Agent, RunResponse
from agno.models.openai import OpenAIChat
from agno.run.response import RunEvent
from agno.storage.workflow.sqlite import SqliteWorkflowStorage
from agno.utils.log import logger
from agno.utils.pprint import pprint_run_response
from agno.utils.string import hash_string_sha256
from agno.utils.web import open_html_file
from agno.workflow import Workflow
from pydantic import BaseModel, Field

games_dir = Path(__file__).parent.joinpath("games")
games_dir.mkdir(parents=True, exist_ok=True)
game_output_path = games_dir / "game_output_file.html"
game_output_path.unlink(missing_ok=True)


class GameOutput(BaseModel):
    reasoning: str = Field(..., description="解释你的推理过程")
    code: str = Field(..., description="游戏的 HTML5 代码")
    instructions: str = Field(..., description="游戏玩法说明")


class QAOutput(BaseModel):
    reasoning: str = Field(..., description="解释你的推理过程")
    correct: bool = Field(False, description="游戏是否通过了你的标准检查?")


class GameGenerator(Workflow):
    # This description is only used in the workflow UI
    description: str = "单页 HTML5 游戏生成器"

    game_developer: Agent = Agent(
        name="游戏开发者代理",
        description="你是一名游戏开发者,负责制作可运行的 HTML5 代码。",
        model=OpenAIChat(id="gpt-4o"),
        instructions=[
            "根据用户的提示创建一个游戏。该游戏应为 HTML5,完全独立,并且只需在浏览器中打开即可运行。",
            "确保游戏在用户死亡时弹出一个提示框,并允许用户重新开始或退出游戏。",
            "确保游戏说明显示在 HTML 页面上。",
            "使用用户友好的颜色,并使游戏画布足够大,以便在更大的屏幕上也能玩。",
        ],
        response_model=GameOutput,
    )

    qa_agent: Agent = Agent(
        name="QA 代理",
        model=OpenAIChat(id="gpt-4o"),
        description="你是一名游戏 QA,负责评估 HTML5 代码的正确性。",
        instructions=[
            "你将获得一些 HTML5 代码。"
            "你的任务是阅读代码,评估其正确性,并确保它符合原始任务描述。",
        ],
        response_model=QAOutput,
    )

    def run(self, game_description: str) -> Iterator[RunResponse]:
        logger.info(f"游戏描述: {game_description}")

        game_output = self.game_developer.run(game_description)

        if (
            game_output
            and game_output.content
            and isinstance(game_output.content, GameOutput)
        ):
            game_code = game_output.content.code
            logger.info(f"游戏代码: {game_code}")
        else:
            yield RunResponse(
                run_id=self.run_id,
                event=RunEvent.workflow_completed,
                content="抱歉,无法生成游戏。",
            )
            return

        logger.info("正在对游戏代码进行 QA")
        qa_input = {
            "game_description": game_description,
            "game_code": game_code,
        }
        qa_output = self.qa_agent.run(json.dumps(qa_input, indent=2))

        if qa_output and qa_output.content and isinstance(qa_output.content, QAOutput):
            logger.info(qa_output.content)
            if not qa_output.content.correct:
                raise Exception(f"QA 失败的代码: {game_code}")

            # Store the resulting code
            game_output_path.write_text(game_code)

            yield RunResponse(
                run_id=self.run_id,
                event=RunEvent.workflow_completed,
                content=game_output.content.instructions,
            )
        else:
            yield RunResponse(
                run_id=self.run_id,
                event=RunEvent.workflow_completed,
                content="抱歉,无法对游戏进行 QA。",
            )
            return


# Run the workflow if the script is executed directly
if __name__ == "__main__":
    from rich.prompt import Prompt

    game_description = Prompt.ask(
        "[bold]描述您想制作的游戏(保持简单)[/bold]\n✨",
        # default="An asteroids game."
        default="一个街机风格的躲避游戏。玩家控制一个在屏幕底部左右移动的小方块,需要躲避从屏幕顶部随机出现的下落方块。当玩家被方块击中时,游戏结束,并显示得分。尝试随机生成方块的颜色和大小,增加难度。考虑加入一个简单的得分系统。",
    )

    hash_of_description = hash_string_sha256(game_description)

    # Initialize the investment analyst workflow
    game_generator = GameGenerator(
        session_id=f"game-gen-{hash_of_description}",
        storage=SqliteWorkflowStorage(
            table_name="game_generator_workflows",
            db_file="tmp/workflows.db",
        ),
    )

    # Execute the workflow
    result: Iterator[RunResponse] = game_generator.run(
        game_description=game_description
    )

    # Print the report
    pprint_run_response(result)

    if game_output_path.exists():
        open_html_file(game_output_path)

用法

1

创建虚拟环境

打开 Terminal 并创建一个 python 虚拟环境。

python3 -m venv .venv
source .venv/bin/activate
2

安装库

pip install openai agno
3

运行代理

python game_generator.py.py