用Gemini 2.5开发象棋应用
上周,谷歌发布了Gemini 2.5 Pro。据报道特别擅长编码和推理。让我们用它来构建一个国际象棋应用来检验这些说法。

上周,谷歌发布了Gemini 2.5 Pro。它在各个基准测试中表现出色,并据报道特别擅长编码和推理。那么,还有什么比用它来构建一个国际象棋应用并用这个应用与AI对弈更好的方式来检验这些说法呢?
在这篇博客文章中,我将分享使用Gemini 2.5 Pro构建国际象棋应用的过程。虽然在IDE中集成它作为代码助手是可行的,但为了展示其简单性,我主要在这个项目中使用了Google的AI Studio。核心想法是创建一个功能齐全的国际象棋应用,连接到LLM,允许人类用户与模型对弈。
你可以从GitHub 下载这个应用程序。
为什么我们应该关心?
自大型语言模型(LLMs)问世以来,它们就被应用于编码任务。这并不是什么秘密;我在与公司合作时经常看到这一点。几乎每家公司似乎都有某种形式的LLM集成代码开发工作流。通过这样一个实际的编码项目测试Gemini 2.5 Pro提供了超越标准基准的见解。
此外,与LLMs对弈国际象棋已经成为一种流行的探紟能力和娱乐的方式,正如这个视频中看到的一样,一位Youtuber组织了一场LLMs之间的锦标赛(当时Gemini的表现不太好 ☹️)。
这个项目触及了由AI辅助软件开发的未来,并提供了一个窗口,让我们了解当前LLMs的推理能力。这种结合使其成为一个值得探索的相关主题。
1、制定计划
首先,我想感受一下实际使用Gemini构建这样的应用程序会是什么样子。我的背景主要是Python,前端开发知识有限。因此,保持架构简单至关重要,这样我可以理解、阅读并可能调试代码。
我的初始提示旨在与Gemini合作制定计划:
我想从头开始构建一个连接LLM的国际象棋应用。
用户可以通过鼠标进行自己的移动,当轮到计算机时,将调用LLM以获取下一步。
我没有太多前端开发经验,因此希望尽可能简化。
我对AI工程非常熟悉,使用的LLM有Python SDK,我对此非常了解。
但如果更简单/更容易,我们也可以使用REST API。
建议一个架构和技术栈来构建这个应用。
我希望在浏览器中运行它,简洁性和最少行数对我来说最重要。
Gemini提出了以下建议:
我们将使用Python后端(Flask)来处理游戏逻辑、状态管理和LLM通信。前端将主要使用HTML,并增强少量JavaScript用于棋盘界面(chessboard.js)以及htmx来处理与后端的通信,而无需编写复杂的前端JavaScript逻辑。
这听起来是一个合理的计划。由于前端涉及我不太熟悉的技朮,我想要先解决这个问题,确保它是可行的,然后再构建后端逻辑。
以下是建议的架构:

2、设计UI
接下来,我要求Gemini构建一个非常基础的独立Web应用。目标是一个功能齐全的棋盘UI,用户可以在其中为双方做出移动,而不需要任何后端或LLM连接。
好的,让我们坚持使用js + html。
好吧,让我们开始吧。你能先构建前端/UI吗?
我希望看到它并也能使用它(没有LLM,只是由用户进行所有移动)。
告诉我如何运行它,我也使用VS Code作为我的IDE。
Gemini回应了必要的HTML、CSS和JavaScript代码,以及以下解释和设置说明:
好的,让我们先构建静态前端。这个版本将允许您在本地浏览器中玩国际象棋,为白方和黑方都进行移动,使用chessboard.js库进行UI和基本的chess.js库进行客户端的移动验证。
不包括后端或LLM交互。
项目结构:
在您的项目文件夹(例如chess-llm-app)中,创建以下三个文件:
1. index.html
2. style.css
3. script.js
它还建议安装VS Code Live Server扩展以便在浏览器中轻松预览。
Gemini解释了这个初始UI的工作原理:
chessboard.js负责绘制棋盘、放置棋子并管理拖放交互。当棋子被放下(onDrop函数)时:
script.js捕获移动(源和目标方块)。
它使用chess.js库(在客户端运行)来验证该移动是否合法(game.move(...))。
如果合法,chess.js更新其内部游戏状态。script.js然后更新显示的状态(FEN,PGN)。
chessboard.js视觉上更新棋盘位置(board.position(game.fen()))以反映新状态。
如果非法,chess.js返回null,棋子会弹回到原来的位置。
因为onDragStart函数只检查根据本地chess.js状态的回合,您可以手动为白方和黑方进行移动在这个版本中。
3、第一次小插曲
运行Gemini生成的代码后,应用加载了,但棋子不见了:

Gemini建议原因可能是暂时的网络问题、CDN问题或浏览器扩展阻止外部资源——这些都是合理的解释。它建议下载棋子图像并在本地提供它们。这感觉对于可部署的应用程序来说是一个更健壮的解决方案。

然而,提供的GitHub链接(404错误)是错误的。它指向 …/img/chesspieces/wikipedia
,而正确的路径应该是 …/website/img/chesspieces/wikipedia
。经过快速手动修正和下载后,棋子出现了!

4、后端
有了基本的UI正常工作后,是时候构建后端——处理游戏状态和与Gemini通信的Flask应用程序了。
首先,我想确认前端结构可以容纳LLM生成的移动,而不仅仅是用户的拖动。
问题:如果LLM响应的是移动而不是拖动,这个UI还能工作吗?例如,如果我下e4,LLM响应e5,我们将如何让棋盘执行e5?
Gemini的解释清晰且令人放心:

它确认我们可以基于LLM的响应程序化地更新棋盘状态。
接下来,Gemini指导我为Flask后端构建项目结构,建议在静态文件夹中放置前端资产和一个主app.py文件。

它还提出了一项重要的架构调整:不是前端的script.js使用chess.js验证移动,而是前端将用户的移动发送到Flask后端。后端(app.py)将成为游戏状态的唯一真实来源,验证移动、更新棋盘,并最终触发LLM调用。这与我保持前端简单并集中逻辑的目标完全一致。
5、第二次小插曲
在添加LLM集成之前,我测试了更新的UI与基本Flask后端(现在处理移动验证)之间的连接。立即遇到了一个错误:白方移动后,尝试移动黑方棋子时会出现“不是你的回合”的错误,即使确实是黑方的回合。

我将错误消息和描述反馈给Gemini。起初,它的建议未能解决问题。有一次,它生成的响应完美地反映了我自己的调试挫败感:

“这很奇怪” 确实如此!调试有时就是这样 😅
Gemini仍然很有帮助:

在添加更多日志记录后,Gemini终于找到了问题并提供了正确的修复。

我在这个阶段并没有深入挖掘根本原因。我们已经接近完成线,我很急切地想连接最后一部分:Gemini生成棋步的集成。
6、连接Gemini
集成Gemini调用实际上相对简单。关键在于制作一个良好的提示。为了最小化大型语言模型(LLM)产生非法棋步的可能性,我决定不仅提供当前棋盘状态(以FEN表示法),以及走棋历史,还提供一个明确的合法棋步列表。
legal_moves_uci = [move.uci() for move in board.legal_moves]
legal_moves_str = " ".join(legal_moves_uci)
prompt = (
"你是一个正在下棋的国际象棋引擎,扮演黑方。\n"
"当前棋盘状态以FEN表示法为:\n"
f"{current_fen}\n"
"走棋历史以UCI格式为:" + " ".join([m.uci() for m in board.move_stack]) + "\n"
f"可用的合法棋步:{legal_moves_str}\n" # 添加了合法棋步
"你的任务是从提供的列表中选择黑方的最佳合法棋步。\n"
"仅需以UCI表示法(例如,'g8f6'、'e7e5')回应所选棋步。不要添加任何其他文字。"
)
print(f"LLM提示(示例):\n{prompt}")
# 使用全局初始化的客户端
if not client:
print("LLM客户端不可用。无法生成棋步。")
llm_response_text = None # 表示失败
else:
try:
response = client.models.generate_content(
model=model_id, contents=prompt
)
print(response.text)
llm_response_text = response.text # 确保如果LLM调用不活跃时初始为空
except Exception as e:
print(f"LLM API调用错误:{e}")
llm_response_text = None
这基本上就是核心LLM集成的内容了。我最初使用Gemini 2.0 Flash作为默认模型,但后来在UI中添加了一个下拉菜单,允许选择不同的模型,包括Gemini 2.5 Pro。

7、游戏时间
随着应用程序完全正常运行,是时候开始玩了!我用Gemini 2.0 Flash开始了第一局游戏。作为一名初学者到中级玩家(大约在chess.com上的快速模式1200分左右),我觉得我有不错的胜算。
与2.0 Flash的对局相对轻松。该模型经常错过简单的威胁,比如悬空棋子和明显的将杀威胁。
接下来,我将模型切换为Gemini 2.5 Pro。区别立刻显现——对局感觉更加具有挑战性。
点击这里查看视频。
直到中局,Gemini才开始丢子,我很高兴它这样做了——我认为那时我的局面并不太好😅
注意:在我录制的视频中,Gemini丢掉更多棋子后,下午的响应时间变长了——可能是由于美国地区使用量增加(“救命啊,我们的TPU快熔化了”🤣)。所以你得相信我,我能转换这个残局😉
8、再加一个功能
为了更深入了解LLM的“思考”过程,我添加了一个最终功能:我修改了提示,要求Gemini不仅要给出棋步,还要在提供棋步之前对其当前局面的推理或想法进行说明。这非常有洞察力,偶尔Gemini还会表现出一些个性:

你可以在这里找到这个版本。
9、结束语
通过Gemini 2.5 Pro构建这个国际象棋应用是一次揭示性的AI辅助开发实验。尽管我前端经验有限,但我可以大量依赖Gemini进行架构建议、代码生成,甚至棘手的调试会话——包括共享的“奇怪”时刻!
由此产生的应用程序,允许直接与LLM对弈,是一个具体的成果。或许更重要的是,这一过程突显了像Gemini这样的AI工具如何显著降低障碍,赋予开发者挑战超出其舒适区的项目的能力,并可能弥合技能差距。这次经历为我们提供了未来软件创建方式的一瞥。
原文链接:Build a chess app with Gemini 2.5 Pro
汇智网翻译整理,转载请标明出处
