十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

LLM剑士物理仿真对战:盲投评测推理能力与决策质量

LLM剑士物理仿真对战:盲投评测推理能力与决策质量 这次我们来看一个很有意思的 Show HN 项目Two LLMs sword-fight in a physics SIM, humans blind-vote who reasoned。翻译过来就是两个大语言模型各自操控一名剑士在物理仿真环境里真刀真枪打一场人类观众只能看到对战画面和决策过程在不知道哪个模型是谁的情况下盲投谁更会推理。这个项目最吸引人的地方不是“用 LLM 打游戏”这个噱头而是它把两件事放在一起做评测物理仿真给了一个客观胜负结果人类盲投给了一个主观推理质量评分。赢的不一定被公认为更会推理输的未必逻辑更差。这种设计比单纯问“LLM 回答对不对”要复杂得多也更有参考价值。对做 LLM Agent、RAG 评测、模型对比选型的同学来说它相当于一个“竞技场版”的推理评测实验。从技术实现上看这类项目通常会涉及物理仿真引擎、LLM 决策循环、动作空间设计、WebSocket 实时通信、投票系统和对局回放几个模块。硬件和显存取决于你用云端 LLM API 还是本地模型如果走本地推理输出长度和上下文越长显存占用量就越高具体数字必须以模型版本和本机实测为准不能拍脑袋。项目本身没有给出明确要求之前一切以仓库说明为准。这篇文章我会从项目概念、评测设计、系统架构、部署流程、功能验证、API 与批量任务、性能观察、常见问题几个方向展开。即使你还没拿到完整源码也可以对照一套通用实现思路把类似的“LLM 对抗物理仿真”项目跑起来并建立自己的评测数据集。1. 核心能力速览先给一张能力速览表后面再逐步拆解。能力项说明项目类型LLM 对抗评测 / 物理仿真对战实验发布渠道Show HNHacker News 社区投稿项目核心玩法两个 LLM 各控制一名剑士在物理仿真中实时对战评测方式人类观众盲投判断哪一个 LLM 的推理质量更高物理仿真能力由物理引擎驱动具体引擎类型需以项目源码为准LLM 接入方式可能支持远程 API、本地模型或两者结合以仓库说明为准显存需求不确定本地模型取决于参数量、上下文长度、量化精度批量任务多场对局、回放录制、投票汇总、批量评测可按通用流程扩展接口能力LLM 调用本身依赖 API项目是否暴露自有 HTTP 接口需以仓库为准适合场景LLM 推理质量评测、Agent 决策研究、类竞技场对抗实验、A/B 模型对比从标题能确定的核心事实是对局发生在物理仿真环境里两个 LLM 要做出“剑士”级别的实时决策最后人类以盲投方式评判推理水平。其余细节包括物理引擎选型、模型列表、投票口径、前端框架都需要看仓库源码才能下结论。这篇文章里的部署命令和接口示例属于这一类项目普遍成立的通用的实现模板落地时要按实际项目替换路径和参数。2. 项目到底在做什么这个项目的本质是把 LLM 从“聊天窗口”搬到“物理世界”。传统评测里我们给 LLM 一道题它输出一段推理过程我们判断推理是否正确。但在这里LLM 的推理必须作用于一个连续变化的物理环境剑士有位置、速度、血量、体力、攻击冷却时间敌我双方的距离每一帧都在变。模型必须基于当前状态给出一个可执行的动作然后物理仿真推进世界产生新的状态。整个循环是这样的物理仿真引擎运行一场剑士对战。每一轮决策前系统把当前战局状态序列化成文本或 JSON。两个 LLM 分别拿到状态和自己的系统提示词输出下一步动作。动作被解析成一个或多个物理引擎能执行的指令比如移动、攻击、防御、闪避。物理仿真按动作执行一段时间更新战局。循环回到第 2 步直到一方被击败或时间结束。对局全过程录制下来人类观众观看并在不知道哪个模型对应哪一方的情况下投票。这里的“推理”不是空对空的逻辑题。模型要考虑距离、体力、CD、进攻窗口还要判断对手下一秒可能做什么。这就把一个非常重要的问题推到了台前LLM 在静态文本上表现出的推理能力迁移到动态实时决策场景后还能不能成立这也是它值得写一篇博客的原因。它不是又一个“LLM 跑分”项目而是一个把 LLM 当作最小 Agent 放进物理环境、再引入人类主观评估的实验框架。3. 为什么“人类盲投谁更会推理”是个聪明的评测设计先看为什么需要人类来判断而不是只看谁赢了。物理仿真给了一个客观的胜负结果但胜负并不等于推理质量。一个模型可能连续乱出招但碰巧命中关键一击赢了另一个模型每一步决策都有清晰意图却因为动作执行误差输了。如果只用胜负来评判 LLM 的决策能力样本噪声太大而且无法告诉开发者模型到底哪里想错了。人类盲投补上的正是这个缺口。观众能看到决策过程能感知到一个模型是在“有目的性地移动、试探、抓机会”还是在“随机出招”。这种评估维度和胜负结果放在一起能给出更完整的信息一个模型可能胜率不高但人类认为它的推理过程更合理也可能赢了很多场但人类认为它只是动作收益高策略深度不足。盲投本身也很关键。如果观众知道左边是模型 A、右边是模型 B很自然会带入对模型品牌的先验判断。盲投把模型身份隐藏掉只展示行为观众就只能根据对局内容打分。这和 Chatbot Arena 的匿名对抗思路一致只不过把“文本回答质量”换成了“物理环境中的推理与决策质量”。当然这种评测也有明显的坑样本量不够时个别观众的偏好会严重影响结果。观众可能被“打得好看”吸引而不是“想得清楚”吸引。模型输出里的措辞、总结风格会影响人对推理质量的观感。如果观众知道其中一个模型“更强”即使盲投也可能通过行为风格认出来。所以在实际落地时需要设计足够多的对局、随机交换左右位置、在投票页隐藏任何可识别的风格特征并且把“推理过程展示”标准化。这个项目最值得借鉴的其实是这套评估方法论而不仅仅是打斗本身。4. 系统架构推演与核心技术点由于项目原始信息有限下面是一套这类项目通常成立的技术架构不代表仓库的最终实现。你可以把它当作复刻类似项目时的设计参考。整个系统可以分成五层层级职责常见选型物理仿真层管理剑士角色、碰撞、血量、体力、攻击判定Box2D、PyBullet、Unity、GodotAgent 适配层把游戏状态序列化为文本解析 LLM 输出为动作Python / TypeScript 脚本LLM 服务层提供推理能力接收状态文本返回动作文本OpenAI 兼容 API、Ollama、vLLM、本地模型通信与调度层连接仿真、LLM、前端控制决策频率WebSocket、FastAPI、Redis 队列展示与投票层实时播放对战、展示推理文本、接收盲投Vue / React 前端后端数据库最核心的技术点是“实时控制循环”。物理仿真通常以 50 到 60 帧运行但 LLM 不可能每帧都做一次推理一次 API 调用往往要几百毫秒到几秒。通用的做法是降低决策频率每隔 1 到 2 秒让 LLM 决策一次把输出动作放进一个动作队列物理引擎在这个时间段内平滑执行。这样既保留 LLM 的策略性又不被物理帧率拖垮。下面是一个极简的决策循环伪代码import json import time decision_interval 1.5 # 每 1.5 秒让 LLM 决策一次 action_queue [] def serialize_state(game_state): return json.dumps({ player_hp: game_state[player_hp], enemy_hp: game_state[enemy_hp], player_pos: game_state[player_pos], enemy_pos: game_state[enemy_pos], player_stamina: game_state[player_stamina], attack_cooldown: game_state[attack_cooldown] }, ensure_asciiFalse) while match_running: if time.time() - last_decision_time decision_interval: state_text serialize_state(game.get_state()) response llm_chat(system_prompt, state_text) action parse_llm_action(response) action_queue.append(action) last_decision_time time.time() game.step(action_queue)动作空间的设计同样重要。如果让 LLM 自由输出自然语言指令解析会非常不可控。更稳妥的做法是把动作限制成一个小型 JSON Schema例如{ action: attack, direction: [1, 0], reason: 对方体力较低血量剩余 20%适合主动进攻 }这个设计里reason字段是给人类盲投时展示的“推理过程”action和direction才是真正交给物理引擎执行的指令。这样既保留模型推理的可解释性也保证物理层能稳定执行。状态文本的序列化格式也很重要。信息太少模型做不出有效决策信息太多token 开销大推理延迟上升。建议只保留关键战局要素双方血量、位置、体力、攻击 CD、距离、时间。硬塞一堆无关属性反而会稀释模型的注意力。5. 本地部署环境准备与前置条件跑这种项目前置条件要分两条线看一条是物理仿真和前端一条是 LLM 服务。如果 LLM 走远程 API你的本地机器主要负担物理仿真、Web 服务和投票数据库压力不大如果 LLM 走本地模型就需要单独准备推理服务并重点观察显存。先给一个通用环境检查清单操作系统Windows / Linux / macOS 均可但本地 LLM 推理在 Linux 下驱动兼容性最好。编程环境Python 3.10 以上Node.js 18 以上具体以项目要求为准。物理仿真依赖如果项目基于 Python 物理库需要安装对应的 wheel 包如果基于游戏引擎需要对应运行时。LLM 服务远程 API 需要 API Key 和网络本地模型需要 Ollama、vLLM、llama.cpp 或类似推理框架。GPU 与显存本地推理时显存占用随模型参数量、上下文长度、量化精度变化建议先跑一次小参数对话用nvidia-smi确认峰值。磁盘空间模型文件、对局回放、前端构建产物都需要空间建议至少预留 20GB 以上以仓库说明为准。端口占用物理服务、LLM 服务、前端服务通常各占一个端口启动前先检查 7860、8000、3000 一类常见端口是否冲突。这里顺便说一个经常被问到的问题这类 LLM 对战项目和 ComfyUI 与 LLM 是否必须同一台电脑的问题类似核心都是“部署拓扑”。如果 LLM 走远程 API仿真机与模型服务完全分离跨机器也能跑如果走本地模型并且对延迟敏感最好让仿真服务和推理服务在同一台机器或同一内网。到底怎么选取决于你对决策延迟的容忍度和显存预算。6. 本地部署一键启动与服务访问思路由于原项目源码细节未公开这里给一套通用部署路径。核心思路是先装依赖再启动后端再启动前端最后检查端口连通性。假设项目克隆到本地后第一件事是创建虚拟环境并安装依赖git clone 项目仓库地址 cd 项目目录 python -m venv .venv source .venv/bin/activate # Windows 用 .venv\\Scripts\\activate pip install -r requirements.txt后端服务启动通常是一个 FastAPI 或 Flask 应用python server.py --host 127.0.0.1 --port 8000如果你想通过局域网访问比如让其他人在同一网络下参与投票可以改为python server.py --host 0.0.0.0 --port 8000前端如果是 Node 项目cd frontend npm install npm run dev启动完成后先确认三个地址能否访问前端对战页、后端健康检查接口、LLM 服务地址。如果页面打不开优先看终端日志里有没有端口绑定失败、模型文件缺失、API Key 无效这几类错误。需要特别提醒如果服务绑定了0.0.0.0局域网内所有人都能访问投票接口。为了安全建议加一层简单的访问令牌或者只在信任网络内开放。6.1 配置文件的组织方式这类项目一般会把模型名、决策间隔、最大回合数、是否录制回放、投票开关等参数放进一个 JSON 配置。一个通用的示例配置如下{ match: { max_rounds: 60, decision_interval: 1.5, record_replay: true }, llm_left: { provider: openai_compatible, model: local-model-name, base_url: http://127.0.0.1:11434/v1, temperature: 0.2 }, llm_right: { provider: openai_compatible, model: remote-model-name, base_url: , temperature: 0.2 }, voting: { enabled: true, anonymous: true, require_voter_id: false } }每次对局前系统读取配置把两个模型的标识随机分配到左右位置。这样同一场对局里模型 A 可能在左边下一场就可能在右边避免观众因位置产生固定偏好。这也是盲投设计里很重要的一环。7. 功能测试与效果验证项目跑起来之后不要直接开几十场对局。先把功能一条一条验证清楚每一层都确认稳定再进入批量评测。下面是一套可复用的测试顺序。7.1 基础对战连通性测试测试目的确认两个 LLM 能成功接入物理仿真并且对局可正常开始。操作步骤启动后端、前端和 LLM 服务。在前端页面创建一场测试对局。观察两边模型是否在约定时间内返回动作。观察物理仿真是否持续推进血量是否变化。预期结果两边模型都能输出合法动作物理仿真正常步进没有出现“模型不回复”或“动作全部解析失败”的情况。如果模型完全不出招先看 LLM 服务日志确认请求是否到达、返回是否超时。再看提示词里的动作格式是否足够明确。很多情况不是模型不会玩而是它不知道应该输出 JSON或者对动作字段理解有歧义。7.2 推理质量抽查测试目的判断模型的对局决策是否合理而不只是“能输出动作”。输入示例人为构造一个战局状态直接发给模型测试不走完整对局。你是一名剑士 AI。当前状态 你血量 30体力 50位置 (2, 3)攻击冷却剩余 4 秒。 对手血量 80体力 50位置 (4, 3)正在向你移动。 可选动作move(x,y)、attack(direction)、defend、dodge(direction)、wait。 请用 JSON 输出下一步动作并给出 30 字以内的推理理由。判断标准模型是否给出了符合战况的动作。血量低、CD 长的时候选择撤退或防御比选择硬拼更合理。如果模型在明显劣势时仍然无脑冲锋说明它没有真正理解状态数值之间的关系。这个测试可以一次性跑几十条不同的状态文本用来做批量评估不需要真开一局游戏。7.3 动作解析稳定性测试测试目的确认模型输出能被稳定解析成物理引擎可执行的动作。操作步骤连续发起 100 次决策请求统计成功解析的比例。预期结果解析成功率应该在 95% 以上。如果低于这个值说明提示词里的动作格式约束不够强或者模型对 JSON 的遵循能力不足。一个实用策略是“解析失败就重试一次再失败就给一个默认的 wait 动作”。这样可以避免一次解析错误导致整个对局崩溃def parse_llm_action(response_text): parsed json.loads(response_text.strip()) if parsed and parsed.get(action) in VALID_ACTIONS: return parsed return {action: wait, reason: parse fallback}7.4 盲投流程测试测试目的确认人类观众能正常观看对局、查看推理过程、提交投票并且看不到模型身份。操作步骤打开投票页面确认左右模型的标识是隐藏的。观看一场对局或回放。提交投票。检查后端数据库确认投票记录与对局 ID 关联正确。预期结果匿名投票字段不包含任何可识别模型名的信息。如果页面泄露了模型名盲投就失效了。7.5 回放与数据落盘测试测试目的确认对局数据、模型推理文本、人类投票都能被记录用于后续分析。操作步骤打一场完整对局检查输出目录是否生成回放文件和投票结果。预期结果目录结构清晰每一场对局有唯一 ID回放文件、双方模型名、推理记录、投票记录能对应起来。没有回放后面所有评测结论都缺乏可追溯性。8. 接口 API 调用与批量任务这个项目天然依赖 LLM API同时如果要做批量评测最好把“发起对局”“拉取结果”“提交投票”都做成 HTTP 接口这样可以用脚本批量跑实验。8.1 通用 LLM API 调用模板假设项目的 LLM 服务是 OpenAI 兼容协议调用的核心逻辑如下import requests import json def llm_decision(state_text, system_prompt, api_key, base_url, model): payload { model: model, messages: [ {role: system, content: system_prompt}, {role: user, content: state_text} ], temperature: 0.2, max_tokens: 200 } headers { Authorization: fBearer {api_key}, Content-Type: application/json } resp requests.post(f{base_url}/chat/completions, jsonpayload, headersheaders, timeout30) resp.raise_for_status() return resp.json()[choices][0][message][content]如果不用 Pythoncurl 也能验证curl http://127.0.0.1:8000/v1/chat/completions \ -H Content-Type: application/json \ -d { model: your-model-name, messages: [ {role: system, content: 你是一名剑士 AI根据状态输出 JSON 动作。}, {role: user, content: {\player_hp\: 30, \enemy_hp\: 80}} ], temperature: 0.2 }这里127.0.0.1:8000只是示例实际地址取决于你的 LLM 服务端口。8.2 批量任务设计这类实验最有价值的阶段是批量跑对局。批量任务不能只是“循环开几十局”必须提前设计好数据记录和失败重试。一个可行的批量配置{ batch: { total_matches: 50, permute_sides: true, interleave_match: true, max_retries_per_match: 2, output_dir: ./eval_results } }设计要点两两模型的左右位置要随机交换消除位置偏差。单场对局失败要自动重试重试仍失败则记录原因不能静默跳过。每一场的结果都要保存成独立 JSON 文件包含模型名、配置、状态序列、动作序列、推理文本、胜负、投票结果。全部跑完后用汇总脚本生成胜率、推理评分均值、投票人数等指标。这样收集出来的数据才能真正回答“谁更会推理”这个问题而不是只停留在“谁打赢了”。8.3 投票接口示例投票接口一般是一个很简单的 POST 请求。下面是一个通用模板curl -X POST http://127.0.0.1:8000/api/vote \ -H Content-Type: application/json \ -d {match_id: match_001, choice: left, voter_id: }后端收到后先把choice映射到真实模型名再把匿名投票记录写入数据库。注意投票结果里不应该出现模型名的可推断信息。9. 资源占用与性能观察这类项目的性能瓶颈几乎都集中在 LLM 推理环节而不是物理仿真。物理仿真本身对 CPU 要求不高真正的变量是模型响应速度和并发请求。如果你把对局决策间隔设为 1.5 秒而 LLM 单次推理需要 3 秒那么决策就会持续堆积对局体验会明显卡顿。观察性能时建议重点看四个指标指标说明观察方式LLM 单次推理延迟从发出请求到拿到动作结果的时间日志时间戳、API 返回耗时动作解析成功率模型输出可被物理层执行的占比批量解析统计物理仿真帧耗时一帧仿真计算耗时后端日志帧率WebSocket 连接数前端观众与后端的长连接数量服务监控本地模型推理时显存占用是另一个重点。用nvidia-smi -l 1可以实时观察。显存不够时优先做三件事使用更小的模型或量化版本。降低max_tokens避免模型生成长篇大论。减小上下文里拼接的历史战况条数。如果模型开了流式输出虽然首 token 更快但完整动作可能还是慢。对于这类“必须拿到完整 JSON 才能执行动作”的场景非流式反而更简单。另外提醒一个容易踩的坑模型服务和物理仿真服务如果都跑在同一台机器上GPU 显存和 CPU 内存会互相挤占。建议先用free -h和nvidia-smi确认资源余量再调整决策间隔。不要一上来就把并发拉满先跑一场小对局记录基准延迟。10. 常见问题与排查方法下面是这类项目运行过程中比较常见的问题可以直接对照排查。问题现象可能原因排查方式解决方案对局开始后 LLM 不出招LLM 服务未启动、API Key 无效、提示词没有要求输出格式查看 LLM 服务日志手动调用一次接口补全 API 配置修正提示词补一个默认 wait 动作模型输出解析失败JSON 格式不规范、动作名不在允许列表打印原始返回文本增强格式约束增加重试与 fallback 解析动作延迟过高对局卡顿模型推理慢、决策间隔设置过短统计单次推理耗时调大决策间隔换成更小模型或走量化本地模型显存不足模型参数超过显存容量上下文过长用 nvidia-smi 观察峰值占用换小模型、降低 max_tokens、清理上下文页面打不开端口被占用、前端未构建或未启动检查进程占用和终端日志换端口重新 npm run dev投票提交失败投票接口地址错误、对局 ID 不存在查看后端接口返回错误确认前端配置和后端路由一致回放文件缺失数据落盘逻辑未触发、目录权限不足检查输出目录和日志创建输出目录检查写入权限盲投票数异常集中某个观看者刷票、样本量太小查看投票时间戳和 voter_id限制投票频率增加对局场次其中“模型输出解析失败”是最常见、也最影响体验的问题。治理思路是提示词里给一个明确的输出示例解析层做一次字符串清洗重试一次之后用默认动作兜底三层防护下来基本不会因为一次解析失败中断对局。11. 最佳实践与使用建议这类 LLM 对抗评测项目工程上不难难在评测结论是否可信。下面几条建议是我认为最有价值的。第一先小后大。第一场对局先把决策间隔调大、把模型换成小参数版本跑通之后再上正式模型。不要第一轮就开 50 场否则配置错了要重跑成本很高。第二保留最小可运行配置。把验证过的模型名、端口、提示词、决策间隔整理成一份固定配置作为基准。后面任何改动都基于这个基准对照方便定位性能变化。第三数据文件分类管理。模型文件、输入素材、对局回放、投票结果分开目录存放每场对局以match_id命名。批量评测之后用脚本汇总而不是手动翻日志。第四批量任务必须加日志和失败重试。批量跑的时候任何一场崩溃都不应该影响整体队列。每个任务要记录开始时间、结束时间、返回状态、异常原因。没有日志的批量任务出了问题很难回看。第五接口服务要控制访问范围。如果投票和对局接口绑定了0.0.0.0至少要加访问令牌不要裸奔到公网。涉及模型名称、API Key 的配置不要提交到公开仓库。第六涉及人脸、声音、版权素材的场景必须获得授权。这个项目本身是 LLM 与物理仿真结合但如果后续你把它扩展成真人形象代言、真实语音对战、直播带货式评测就必须确认使用对象已获授权避免肖像权、声音权和版权风险。第七发布或商用前要做效果复核。LLM 生成的“推理理由”可能听起来合理但实际是错误策略。不要因为模型输出了一段流畅的推理文本就认为它的决策质量高。最终的评测结论要结合胜率、推理评分、人类投票一起看。12. 总结与下一步这个 Show HN 项目值得尝试的点是把 LLM 推理评测从静态文本搬进了动态物理仿真并用人类盲投来做主观质量判断。它本质上是一个最小但完整的 LLM Agent 实验框架状态序列化、动作空间约束、实时决策循环、回放录制、匿名投票这些能力在真实业务里都能迁移。建议你先验证三件事第一两个 LLM 能否稳定接入并对战第二模型输出的动作解析成功率能否达到 95% 以上第三盲投流程是否真的隐藏了模型身份。这三件事跑通之后再考虑批量跑对局、汇总投票、生成评测报告。最容易踩的坑是两类一类是模型输出解析不稳定导致对局中断另一类是性能调优方向错误用更贵的模型来解决延迟问题而不是先调决策间隔和上下文长度。先做小规模基准测试再放量能把大部分坑提前避开。如果你对 LLM Agent 评测、模型 A/B 对比、物理仿真交互感兴趣这个项目就是一套很轻的参考实现。下一步可以沿着三个方向扩展把对战结果和推理评分打通做一个可量化的推理质量榜单把回放做成可视化数据面板展示每个决策时刻的状态与模型理由或者接入更多模型跑一场更大规模的匿名对抗看人类投票和模型胜率之间到底有多大偏差。建议收藏备用。等仓库源码公开后照着部署一遍你会更清楚 LLM 在实时决策场景里的真实下限在哪里。
返回列表