第12章:终章(构建一个游戏)

Nanocode真的能构建些什么吗?

“零代码挑战”:使用Python和Pygame构建一个经典的贪吃蛇游戏。规则很简单——你不允许编写任何Python代码。你只能用英语与代理对话。

An icon of a info-circle1

**附注:**这个演示涉及许多API调用。如果你遇到速率限制(HTTP 429),代理会自动重试。对于较长的会话,考虑使用Ollama的本地模型来完全避免限制。

第1步:准备工作

从你的项目根目录(包含nanocode.py.env的目录)开始,创建一个游戏的工作目录:

1 mkdir -p snake_game
2 cp nanocode.py snake_game/
3 cp .env snake_game/
4 cd snake_game

如果你正在使用本书的代码仓库,请从 ch11 复制:

1 mkdir -p snake_game
2 cp resources/code/ch11/nanocode.py snake_game/
3 cp .env snake_game/
4 cd snake_game

安装 Pygame:

1 pip install pygame
An icon of a info-circle1

旁注: 在 Windows 上,这应该可以直接使用。在 macOS 上,你可能需要先安装 SDL 库:brew install sdl2 sdl2_image sdl2_mixer sdl2_ttf。在 Linux 上,安装 SDL 开发包:sudo apt install libsdl2-dev libsdl2-image-dev libsdl2-mixer-dev libsdl2-ttf-dev

第2步:设计师(规划模式)

启动代理程序。我们从规划模式开始,因为在开始砌砖之前,我们需要一份蓝图。

1 python nanocode.py

提示语:

1 Build a classic Snake game using Pygame. Include a score counter and Game Over screen with a restart option. Put ALL code in ONE file: snake.py. Write the plan in PLAN.md.

代理将使用 write_file 来创建 PLAN.md。阅读它。它应该在单个文件中概述蛇类、食物类和游戏循环。

如果看起来没问题,就批准它。

第3步:构建器(执行模式)

切换到执行模式:

1 /mode act

提示词:

1 Implement the plan in snake.py. All code in one file.

查看终端:

1   → Writing snake.py

代理程序正在基于存储在 PLAN.md 中的上下文生成代码。

第4步:现实检查

在运行游戏之前,需要增加超时时间。打开 nanocode.py 并在 RunCommand.execute() 中将 timeout=30 改为 timeout=300——默认的30秒不足以完成一局游戏。(这是零代码挑战的唯一例外。)

提示:

1 Run the game with: python snake.py

代理执行 run_command。一个窗口弹出。你开始玩贪吃蛇游戏。

**如果游戏崩溃:**大语言模型的输出是非确定性的。你的代理在第一次尝试时可能会产生bug。如果游戏出现类似 AttributeError: 'Snake' object has no attribute 'draw' 这样的错误而崩溃,不要自己修复它。让代理看到stderr的输出。

提示:

1 The game crashed. Read the error and fix it.

代理程序将读取回溯信息,使用 read_file 找到程序错误,使用 edit_file 进行修复,然后重新运行。

第5步:转折点(功能蔓延)

游戏可以运行,但看起来很粗糙。蛇只是由绿色方块组成。让我们来测试一下代理程序重构代码的能力。

提示语:

1 The game looks boring. Make the snake change color as it eats food, increase speed every 5 points, and search the web for 'cool retro game color palettes' to apply.

代理应该:

  1. 使用 search_web 查找调色板
  2. 使用 read_file 理解当前的渲染逻辑
  3. 使用 edit_file 注入新功能
  4. 运行游戏进行验证

可能出现的问题

你的结果会与我的不同——LLM具有非确定性。但以下是通常会发生的情况,以及需要注意的事项。

首次运行时的常见失败:

  • ModuleNotFoundError: No module named 'pygame' — 代理忘记了你需要安装它,或者它在不同的环境中运行脚本。告诉它先运行 pip install pygame
  • 在调用点上出现代理定义但拼写错误的方法时会产生 AttributeError。一旦代理看到回溯信息就会快速修复这些问题。
  • 碰撞检测中的差一错误。蛇会穿过墙壁或过早死亡。这些问题需要2-3次编辑-运行-修复的迭代。

典型会话流程:

在我的测试中,代理通常在2-4次迭代后就能得到一个可运行(但不够美观)的游戏。第一次编写会产生崩溃的代码。第二或第三次修复后能让它运行起来。功能扩展步骤(颜色变化、速度调整)会再增加3-5次迭代,因为代理需要阅读自己的代码,进行精确的编辑,并验证每个更改。

到最后,对话通常会深入到15-20轮。如果你使用Claude,要注意压缩触发器——在第12-15轮左右,当令牌数接近75%阈值时,你会看到“(正在压缩对话…)“。压缩后,代理会失去一些早期回合的细节,但仍能继续工作。这正是第9章中的系统发挥作用的地方。

代理的困难之处:

Pygame的坐标系统和事件循环比较棘手。代理有时会写出能正确渲染但无法正确处理键盘输入的代码,或者以错误的顺序绘制蛇导致蛇头出现在身体后面。这些是人类一眼就能发现但代理看不到的错误——它没有视觉反馈,只有标准输出和标准错误。如果游戏运行时没有错误但看起来不对,你需要描述视觉问题:“蛇的渲染是反的——蛇头应该在前面。”

关键不在于第一次就要完美。重要的是代理能够收敛——写代码、运行、读取错误、修复、重复——使用我们在十一章中构建的每一个工具。

总结

计划、实现、崩溃、调试、修复、再运行——这体现了每一章的价值。

那么接下来会如何发展?

结语

整个项目大约有750行Python代码。没有框架。nanocode.py 是你的了。你可以用它做任何事:

  • 在测试通过后自动提交的Git集成
  • 基于截图的前端工作调试(Claude可以读取图像)
  • 通过Whisper进行语音输入,这样你可以说话而不是打字
  • 用于连接团队已在使用的外部服务的MCP

像Claude Code、Cursor和Copilot这样的生产级代理能做的更多——流式响应、并行工具执行、tree-sitter解析、沙盒执行环境、跨越数千文件的多文件上下文窗口。从750行到750,000行的差距是真实存在的。但架构是相同的:一个大脑、一个循环、工具、内存和安全防护机制。现在你知道幕后是什么了。

模型会继续改进。而防护机制——循环、工具、安全检查——那部分是工程。那部分不会消失。