@adelie/mc-agent
v1.1.0
Published
Minecraft × LLM Agent:参考 Voyager 的自动课程 + 技能库 + 自我验证
Maintainers
Readme
Minecraft × LLM Agent(Voyager 式)
在这台主机上装好了 Minecraft Java 版服务端,并配了一个参考 MineDojo/Voyager 思路实现的 LLM 自主玩家:自动课程 → 现场写代码 → 执行 → 自我验证 → 技能入库,跑完把结果发到飞书。
组成
mc-agent/
├── server/ # Minecraft 1.20.4 官方服务端(Java 17 可跑,离线模式)
│ ├── server.jar
│ ├── server.properties # 端口 25565,online-mode=false,生存模式
│ └── eula.txt
├── src/
│ ├── index.js # 入口:连接 → 跑任务 → 出报告 → 发飞书
│ ├── voyager.js # 主循环:课程 / 生成代码 / 沙箱执行 / 验收 / 技能库
│ ├── prompts.js # 三类提示词(课程、代码、验收)+ 目标解析
│ ├── perception.js # 把机器人状态压成 JSON 观察
│ ├── primitives.js # 动作原语(走、挖、合成、放工作台、熔炼……)
│ ├── skills.js # 技能库(成功代码持久化 + 关键词检索复用)
│ ├── safety.js # 生存看门狗(血少反击、饿了吃饭、死亡重生)
│ ├── llm.js # Ollama 原生接口 / OpenAI 兼容接口
│ ├── report.js # Markdown 报告 + 飞书摘要
│ └── feishu.js # 飞书自建应用发消息
├── data/
│ ├── skills.json # 技能库
│ ├── skills/ # 每个技能的 .js 存档
│ └── runs/<时间>/ # 每次运行的 agent.log、trace.jsonl、report.md
├── panel/ # 可视化控制台(不用敲命令)
│ ├── server.js # 本地面板后端:起服务端 / 跑机器人 / 日志流
│ └── index.html # 面板界面
├── scripts/
│ ├── send-feishu.js # 单独把报告发飞书
│ ├── patch-viewer.js # 给 3D 视图打补丁(相机补间 / 地下渲染 / 1.20.4 版本直通)
│ └── gen-viewer-assets.js # 生成 1.20.4 的方块状态与贴图集(json 与 png 同一次生成)
├── start-panel.bat # 双击打开控制台
└── .env.example最省事:双击 start-panel.bat
会打开一个本地网页控制台(http://127.0.0.1:3100,端口被占会自动顺延),上面能:
- 看服务端在不在线,一键启动;点「开始运行」时如果服务端没开,面板会自己先把它拉起来。
- 选「自动课程」或「我只想做一件事」,填任务描述、任务数量。
- 勾第一人称 / 3D 画面 / 视野半径,点开始。
- 左边实时日志、右边 3D 画面(iframe),跑完点最近运行里的报告直接看总结。
- 右上角月亮/太阳切换深色、浅色主题(会记住);报告弹窗按标题、列表、代码块排版,不再是原始 Markdown。
- 3D 画面右上角「放大」把画面铺满整个窗口(按 Esc 或点「还原」退出,画面不会重新加载)。
- 设置项(模式、任务数、视野、三个开关)也会本地记住,下次打开还是上次的样子。
命令行方式
npm install
# 可视化用到的 canvas 需要原生二进制,npm 11 默认跳过安装脚本,补一下:
(cd node_modules/canvas && npx --yes prebuild-install -r napi)
# 1. 起服务端(第一次会生成世界,约 15 秒)
bash start-server.sh
# 2. 另开一个终端跑机器人
node src/index.js --task "砍 3 个原木" # 单个任务
node src/index.js --auto --tasks 5 # 自动课程连续做 5 个任务
node src/index.js --auto --viewer # 同时开 http://127.0.0.1:3007 可视化
node src/index.js --auto --viewer --first-person # 第一人称视角
node src/index.js --auto --viewer --viewer-distance 2 # 更低视野,渲染更快
node src/index.js --auto --no-feishu # 不发飞书--viewer 用的是 prismarine-viewer,可在浏览器里实时看机器人操作:
- 默认第三人称、视野 3 个区块(上游默认 6,机器弱时很卡,这里降到 3;可用
VIEWER_DISTANCE或--viewer-distance调)。 --first-person(或--fp)切换到第一人称,镜头跟着机器人的头和俯仰角走。- 3007 被占用时会自动顺延到 3008、3009……,可视化起不来也不会影响任务执行。
- 相机转向做了补间(原版是每个位置包直接“啪”地转过去):
node scripts/patch-viewer.js应用,--revert还原;它改的是node_modules/prismarine-viewer/public/index.js,npm install后重跑一次即可, 控制面板每次启动也会自动补。 - 同一支补丁还把 1.20.4 加进 viewer 的版本表:上游只认到 1.20.1,会把 1.20.4 降级成 1.20.1,
于是浏览器用 1.20.1 的数据解码 1.20.4 世界的方块、地下整片变成灰底问号。配套的
node scripts/gen-viewer-assets.js会生成布局一致的blocksStates/1.20.4.json与textures/1.20.4.png(-f强制重生成),面板启动时自动补齐。
它和 Voyager 的对应关系
| Voyager 论文组件 | 本实现 |
| --- | --- |
| Automatic Curriculum | voyager.js: proposeTask(),模型根据状态+历史提议任务;重复则重提,最后退化到按背包推进的阶梯 |
| Skill Library | skills.js:成功代码命名入库(data/skills/*.js),下次用关键词检索,直接 skills.xxx() 调用 |
| Iterative Prompting | 每次失败把错误信息和日志回灌给模型重写,最多 MAX_CODE_RETRIES 次 |
| Environment Feedback | perception.js 把背包/位置/附近方块/实体压成 JSON 喂给模型 |
| Self-Verification | 先用「任务→目标物品」的确定性背包核对,再让模型复核(VERIFY_SYSTEM) |
| 代码生成 | 模型输出 JS 函数体,在 AsyncFunction 沙箱里只能调用动作原语,带超时和中断 |
与原版的差异:原版依赖 MineRL + Fabric 客户端(需要 GPU 渲染和特制环境),这里用 mineflayer 直接以协议客户端登录服务端,8 GB 显卡的机器上也能跑,无需开游戏窗口。
模型
当前用云端 DeepSeek(deepseek-chat),配置写在 .env(已加入 .gitignore,不要提交):
LLM_PROTOCOL=openai
LLM_BASE_URL=https://api.deepseek.com/v1
LLM_API_KEY=sk-...
LLM_MODEL=deepseek-chat换回本机 Ollama:把上面四行改成
LLM_PROTOCOL=ollama
LLM_BASE_URL=http://127.0.0.1:11434/v1
LLM_MODEL=qwen3-8B:latest
LLM_NUM_CTX=8192llm.js 检测到 11434 端口会自动走 Ollama 原生 /api/chat(关思考、限上下文,8 GB 显存能整块进 GPU,
7 tok/s → 70 tok/s);其它地址走标准 /v1/chat/completions。
换成任何 OpenAI 兼容服务只需改 LLM_BASE_URL / LLM_API_KEY / LLM_MODEL。
配置
全部通过环境变量覆盖,见 .env.example:MC_HOST/MC_PORT/MC_VERSION/MC_USERNAME、
LLM_*、MAX_CODE_RETRIES、MAX_TASKS、TASK_TIMEOUT_MS、VIEWER_PORT、
FEISHU_APP_ID/FEISHU_APP_SECRET/FEISHU_RECEIVE_ID/FEISHU_RECEIVE_ID_TYPE。
本机实测结果(2026-10-21)
- 服务端:Minecraft 1.20.4,
127.0.0.1:25565,离线模式,和平难度、固定白天(避免怪物打断自动课程,和 Voyager 的实验环境一致)。 - 云端 DeepSeek(
deepseek-chat):自动课程连续 5 个任务 5/5 成功,包括挖煤矿石、石镐挖石头、复用已有技能; 单任务平均 30~90 秒,一次 LLM 调用约 1~3 秒。 - 本机 Ollama
qwen3-8B同样链路:5 个任务成功 2 个,主要错在代码顺序(先挖石头再造镐子)。 - 机器人已自己走完「砍树 → 木板 → 工作台 → 木镐 → 挖石头 → 石镐 → 挖煤」这条早期主线。
- 技能库已积累 15 个技能(
data/skills/),新任务会优先复用。
结论:链路对模型能力很敏感,8B 本地模型适合离线试验,正式跑建议用 DeepSeek 这类云端模型。
发飞书
node scripts/send-feishu.js --to ou_xxxxxxxx --type open_id --file data/runs/<时间>/report.md
# 群聊用 --type chat_id飞书自建应用只能给「已知的 open_id / chat_id」发消息:应用需要先被你加为联系人(或拉进群),
或者开通 im:chat:readonly 让应用自己列出会话;否则接口会返回 invalid receive_id。
服务端小贴士
- 关掉死亡掉落(
/gamerule keepInventory true)能让自动课程连跑更稳。 - 服务端控制台可以
time set day、difficulty normal等。 - 机器人默认离线模式(
online-mode=false),只绑本机使用,不要暴露到公网。
