
本篇要做的东西
第一阶段的成果不是华丽的模型,而是一张一页纸的设计表。围棋AI需要推荐着法的模型、判定规则的引擎、保存对局的服务器以及用户落子的界面一起协同运作。如果不先划定这些边界就开始训练模型,很容易把非法着法和保存错误误判为模型性能问题。
- 使用19×19标准棋盘。
- 人执黑,AI执白。
- 人的落子不设时间限制。
- 模型的回答由规则引擎再次检查。
- 每一手的盘面和着法顺序都保存到服务器。
第1步:把模型和规则引擎分开
模型的职责仅限于看当前盘面并给出下一手的候选坐标。该点是否为空、是否为自杀、是否是重复上一盘面的劫,都由规则引擎判定。如果模型回答了一个已经有棋子的点,就拒绝该候选并重新请求。如果重新请求也失败,不会换成随机着法,而是记录错误。
这种分离之所以重要,是因为可复现性。当某个盘面出现问题时,可以分别确认是模型选得不好,还是规则代码写错了。规则用测试固定下来,模型则作为可替换的部件保留。
第2步:把对局状态定义为一个对象
最小状态包括19×19棋盘、下一手轮到谁、提子数、劫禁止坐标、完整着法顺序以及最后保存时间。不要试图只凭界面来恢复状态,服务器必须保存原始数据。要想重新打开浏览器后继续同一局,还需要对局代码和访问密钥。
第3步:写下完成条件
第一个版本的完成条件不是“强大的AI”。只要人能合法落子、AI的非法回答会被拒绝、刷新后着法顺序依然保留、连续两次停一手就结束对局,就可以了。通过这个标准之后再去改进训练数据和棋力,才能一次一个地追踪问题的原因。
下一篇将讲解如何把一局SGF棋谱拆分为训练用输入和正确坐标。
这一步的实际代码
MariaGO网页对局把第2步所说的“对局状态作为一个对象”以下面的GameRow类型保存到服务器。棋盘、下一手、劫的坐标、提子、连续停一手的次数和完整着法顺序都放在一行里,同时还保存用于在其他设备上继续对局的访问密钥。
mariago-web/lib/gameTypes.ts
export type MoveRec = {
ply: number;
color: 1 | 2;
pass?: boolean;
r?: number;
c?: number;
};
export type GameWinner = "black" | "white" | "draw";
export type GameRow = {
code: string;
guest_id: string;
/** 비공개 키 — 다른 기기 이어두기용. 남에게 코드만 공유하면 안 됨 */
access_key: string;
board: number[];
to_play: number;
ko: { r: number; c: number } | null;
last_move: { r: number; c: number } | null;
move_no: number;
cap_b: number;
cap_w: number;
pass_streak: number;
epoch: number;
started: boolean;
status: "playing" | "ended";
end_text: string | null;
winner: GameWinner | null;
moves: MoveRec[];
created_at: string;
updated_at: string;
};使用的模型:Qwen3-VL-8B-Instruct + LoRA适配器(lora_mix_qwen_r5)。完整源代码和模型说明可以在“8. 完整源代码与使用的模型”一文中查看。
COMMENTS · CHAPTER 01
先确定围棋AI的范围 评论 0
还没有评论。阅读时有疑问或想补充的内容,欢迎留言。
发表评论前,请用 Google 开始并登记昵称和邮箱。
用 Google 开始