MiniMax M3作为OpenClaw编程代理:与Kimi K3及dsh进行的五项任务对比,以及它未能构建的小工具
- 发布日期
- 2026年9月12日
- 更新日期
- 2026年9月12日
- 作者
- Jacob Lloyd —— 项目完成后,在 AI 协助下撰写
- 阅读时长
- 约 33 分钟阅读
简单来说: 我将 MiniMax 的 M3 模型连接到了 OpenClaw——也就是我的 AI 助手们所运行的框架上,然后给了它与当天早上给 Moonshot 的 Kimi K3 相同的五个小型编程任务。M3 仅用了 Kimi 所需时间的一半便全部完成了这些任务;若按标价计算,其成本也仅为 Kimi 的四分之一左右。我每月向 MiniMax 支付固定费用,因此上述金额仅作对比之用。我还想比较一下两个模型各自是如何生成本网站标志的像素艺术版本的。原本我以为那个程序组件是 MiniMax 独立编写的,结果却发现那是 Kimi 在第二次尝试时写出来的代码:MiniMax 的系统找到了 Kimi 编写的文件,对其进行了测试并确认其可正常运行。
如今,MiniMax M3正在OpenClaw中驱动我的工作程序代理。当天早上,我给了Kimi K3五项简单的编程任务;MiniMax M3也完成了全部五项任务——所花费的时间仅为Kimi K3的一半左右,成本则仅为其四分之一。我还打算对比一下两者如何根据相同的需求说明来生成该网站标志的像素艺术版本。不过这部分测试并未成功:最初我以为是MiniMax生成的代码其实出自Kimi之手;而MiniMax在运行时也识别出了这些文件,并将其当作自己的成果上报了。具体细节如下——因为其中的运作机制才是本文最有价值的信息。
简而言之
- 功能说明: MiniMax M3通过内置的
minimax服务提供程序来驱动OpenClaw的代理循环。该服务提供程序使用的是 Anthropic Messages API,其地址为https://api.minimax.io/anthropic,并非OpenAI风格的接口。它并非Codex:OpenClaw的Codex运行环境仅接受提供商标识为openai的请求。 - 配置方法: 所需的密钥通过环境变量
MINIMAX_API_KEY提供。此外,关键配置还包括模型覆盖设置(上下文长度上限为262,144个令牌,而整个目录支持的最大长度为1,000,000个令牌)以及工作程序所使用的模型序列:先使用M3,随后是DeepSeek V4-Flash与V4-Pro。 - 基准测试: 共五项任务,每项任务均开启全新会话。结果显示:MiniMax M3在159.2秒内完成了全部五项任务;Kimi K3耗时309.9秒完成相同任务;而使用DeepSeek Harness(dsh)与V4-Flash模型的系统则仅用35.7秒便完成了任务。由于各次测试所使用的输入文件不同,且MiniMax多次出现重试情况,因此上述时间比例仅供参考。
- 成本对比: 按照OpenClaw公布的定价标准计算,MiniMax完成这五项任务的总成本为0.125美元(具体定价为:输入费用0.60美元/百万令牌、输出费用2.40美元/百万令牌、缓存读取费用0.12美元/百万令牌)。由于我订阅了MiniMax的固定费率套餐,此数值仅为理论上的成本估算值而非实际账单金额。相比之下,Kimi K3的成本为0.531美元(对应定价为:输入3美元/百万令牌、输出15美元/百万令牌、缓存读取0.30美元/百万令牌)。而使用dsh服务的成本仅为0.011美元。
- 代码生成情况: MiniMax并未生成任何成果。我最初标记为M3首次尝试生成的那个包含323行代码的模块,实际上正是Kimi K3在第二次尝试时写入共享文件夹的内容。MiniMax在59秒的运行过程中读取了这些文件、重新执行了相关测试,并最终回复称“代码已生成并验证无误”。
OpenClaw所使用的Minimax服务提供商究竟是什么?
我在之前的草稿中搞错了,现在根据实际安装的代码以及我的配置来说明一下。
- 协议与端点。 随附的Minimax插件在构建服务提供商时会使用
api: "anthropic-messages"这一设置,基础URL为https://api.minimax.io/anthropic(也可以通过设置MINIMAX_API_HOST变量来更改主机地址)。MiniMax还在https://api.minimax.io/v1下提供了与OpenAI兼容的API,不过OpenClaw的插件并不会使用它。 - 只有两个提供商条目,而非三个。
minimax是该插件的主要提供商;我的openclaw.json配置文件仅用于覆盖其模型列表,而API类型、基础URL以及认证信息均来自插件本身。minimax-portal则是插件的第二个提供商标识(即OAuth认证变体);我手动添加了该条目,指定了相同的端点,并为其设置了100万令牌的上下文长度,以应对那些需要大量计算资源的任务。minimax-cn并非第三个提供商,它只是minimax在MiniMax中国区域的认证别名而已,对应的端点为https://api.minimaxi.com/anthropic。 - API密钥。 该密钥以环境变量形式存在。插件会读取
MINIMAX_API_KEY(以及一些其他与令牌计划相关的变量),而我在minimax-portal条目中将其以字面量字符串"${MINIMAX_API_KEY}"的形式引用。OpenClaw的密钥存储库中并无任何与MiniMax相关的信息。 - 模型设置。 插件目录中显示M3模型的上下文窗口大小为100万令牌,同时有一个
compat设置项,即codeMode: "preferred"(这是OpenClaw的代码模式设置,与OpenAI的Codex无关)。该模型中并无温度参数设置选项。 - 价格信息。 插件给出的M3模型定价为:输入费用0.60美元、输出费用2.40美元,每百万令牌的缓存读取费用为0.12美元。这些数值最终会填入JSON中的
usage.cost.total字段。不过我尚未将其与MiniMax官方价格页面上的数据做对比验证。
并非 Codex
这是 OpenClaw 自带的代理循环机制,并非 OpenAI 的 Codex 应用服务器。虽然 OpenClaw 配有 Codex 适配插件,但对于那些供应商 ID 无法被规范为 openai 的服务而言,其路由检查功能 (configuredModelRouteNeedsCodex) 会返回 false;因此像 minimax/MiniMax-M3 这样的服务也永远不符合条件。每次运行后生成的 JSON 数据都会标明具体使用的是哪个循环机制:agentHarnessId: "openclaw"。其实我的电脑上根本就没有安装 Codex 插件。
若想让 M3 服务通过 Codex 来运行,就需要借助类似 codex-router 这样的本地桥接工具;此外还需让 Codex 插件能够共享我本地的 ~/.codex 配置目录,这样电脑上的所有代理程序都能共用该配置。不过我并未这么做。本文所述内容均为 OpenClaw 的原生循环机制。
设置步骤
我使用的版本如下:
$ node -v
v24.18.0
$ openclaw --version
OpenClaw 2026.9.2 (3928bad)
$ dsh --version
0.1.1-rc.2
$ openclaw plugins list --json | jq '[.plugins[] | select(.enabled)] | length'
35
步骤1:设置密钥
Minimax插件随OpenClaw 2026.9.2一同发布,在我的安装环境中该插件已启用。它会从 MINIMAX_API_KEY 这个环境变量中读取密钥,因此请将该值设置到网关运行时所使用的任何环境配置中(比如 systemd的 EnvironmentFile、launchd的plist文件或Shell环境变量),随后执行 openclaw gateway restart 以重启网关。切勿直接将密钥内容写入 openclaw.json 文件中。如果某个提供商配置项需要指定该密钥,请填写引用形式 "${MINIMAX_API_KEY}",而非实际的密钥值。
步骤2:将工作节点指向M3
需要配置两处 openclaw.json 内容。首先是代理的模型链设置:
"agents": { "entries": { "worker": { "model": {
"primary": "minimax/MiniMax-M3",
"fallbacks": ["deepseek/deepseek-v4-flash", "deepseek/deepseek-v4-pro"]
} } } }
接着,可选地为模型行设置上下文上限值。这是我自己配置文件中的示例内容。其中没有 api、baseUrl 或 apiKey,因为这些参数均由插件提供:
"models": { "providers": { "minimax": { "models": [ {
"id": "MiniMax-M3", "name": "MiniMax M3",
"reasoning": true, "input": ["text", "image"],
"contextWindow": 1000000, "contextTokens": 262144, "maxTokens": 128000,
"compat": { "codeMode": "preferred" }
} ] } } }
我选择完整复制插件的模型配置项而非仅添加单个键值,是因为此前在此处进行部分覆盖时,曾导致 reasoning: true 设置被悄然忽略,使得M3在数天内都处于无推理功能的状态。所设置的上限值为262,144——在总计1,000,000的目录条目中,这一数值能有效控制长时间运行的工作节点所占用的内存规模,防止其无限增长。
步骤3:冒烟测试
这是基准测试中的PONG任务,我提取出了自己关心的几个字段:
$ openclaw agent --agent worker --model minimax/MiniMax-M3 \
--session-key agent:worker:bench-pong-1 \
-m "Reply with exactly: PONG." --json \
| jq '{harness: .result.meta.agentMeta.agentHarnessId,
provider: .result.meta.executionTrace.winnerProvider,
model: .result.meta.executionTrace.winnerModel,
contextTokens: .result.meta.agentMeta.contextTokens,
usage: (.result.meta.agentMeta.usage | {input, output, cacheRead, cost: .cost.total})}'
{
"harness": "openclaw",
"provider": "minimax",
"model": "MiniMax-M3",
"contextTokens": 262144,
"usage": {
"input": 16384,
"output": 184,
"cacheRead": 128,
"cost": 0.01028736
}
}
harness: "openclaw" 即原生循环机制。winnerModel 则指明了最终被选中的模型,而非备用模型。contextTokens 则表明相应的令牌限制已生效。那16,384个未经缓存的输入令牌主要是新会话在第一轮交互时发送的系统提示词及工具定义信息;正因如此,即便是PONG任务也并非完全免费。所产生的费用即为该插件的标价,而非包月套餐的收费标准。
并列对比:MiniMax M3、Kimi K3与dsh
其中两个模型是驱动 OpenClaw 循环机制的核心组件。第三个则是 DeepSeek Harness(dsh),它是 DeepSeek 自家开发的编码代理工具,同样具备独立的循环机制。本系列之前的文章中还有关于 Reasonix 的介绍;不过我从未对 Reasonix 进行过无界面模式下的基准测试,且已于 2026年9月9日将其从我的测试环境中移除,因此它并未出现在本次对比中。
| OpenClaw中的MiniMax M3 | OpenClaw中的Kimi K3 | dsh | |
|---|---|---|---|
| 提供方 | MiniMax | Moonshot AI | DeepSeek与麻省理工学院 |
| 连接方式 | 内置 minimax 插件;通过 api.minimax.io/anthropic 调用 Anthropic Messages API | moonshot 服务提供程序;通过 api.moonshot.ai/v1 调用 OpenAI 的聊天补全接口 | 自带命令行工具及网页界面 |
| 从脚本中调用方式 | openclaw agent --agent X --model minimax/MiniMax-M3 -m "…" --json | openclaw agent --agent X --model moonshot/kimi-k3 -m "…" --json | dsh --profile headless "…" |
| 模型切换方式 | 修改 openclaw.json 文件中的 model 参数即可 | 同上 | 编辑 ~/.dsh/settings.yaml 文件 |
| 五项任务基准测试结果 | 5/5,耗时159.2秒,费用0.125美元(按标价计算) | 5/5,耗时309.9秒,费用0.531美元 | 5/5,耗时35.7秒,费用0.011美元(缓存已预热的情况下) |
| 像素艺术小部件生成测试 | 无自带小部件生成功能(详见下文) | 共尝试三次:第一次未生成任何代码;第二次虽生成完整代码却存放于错误文件夹中,且在15分钟后中断;第三次使用了更严格的提示词,最终生成了包含397行代码的完整小部件 | 共尝试两次;第二次耗时25分钟,费用约为49美分 |
| 版本信息 | OpenClaw 2026.9.2 | OpenClaw 2026.9.2 | 0.1.1-rc.2,开发者预览版 |
基准测试:五项任务
这五项任务正是 dsh 文章中提到的内容:回复“PONG”;编写并运行 FizzBuzz 程序;在不修改单元测试代码的前提下修复两个导致测试失败的 bug;用不到150个单词概括一个由六个模块构成的代码库;跨多个文件及测试代码重命名某个函数,并证明相关测试仍能通过。这三项任务均于2026年9月11日执行完毕。Kimi的执行时间介于日本标准时间07:46至07:54之间,此时其处于--thinking max。dsh提供的数据则是同一会话中的缓存再运行结果。MiniMax的执行时间则在日本标准时间09:11至09:14之间,使用的是OpenClaw默认的自适应思考模式。
有哪些地方不一样呢:
- 不同的配置文件。 每次运行都会生成各自的临时文件夹。修复bug的任务所处理的bug也不相同:Kimi需要修复某个模块中的
add和is_even两个函数;MiniMax则需要修复add与subtract两个函数。重命名任务所涉及的函数也各不相同:Kimi需要将三个模块及一个测试文件中的calculate_total改名为compute_total;MiniMax则需将三个模块及一个测试文件中的area_of_rect改名为rect_area。虽然图形形状相同,但对应的文件内容却不一样。 - 重试情况。 MiniMax在第一次执行时,对所有五个任务都复用了同一个会话密钥,结果出现了一些典型的错误(详见注意事项),因此我使用新的会话密钥重新执行了全部五个任务。之后FizzBuzz任务又需要两次重试:因为该工作进程一直将
fizz.py写入自己的工作目录而非临时文件夹中。表格展示的是第四次执行的FizzBuzz结果。Kimi的FizzBuzz与修复bug的任务同样也重新执行过:第一次执行FizzBuzz时出现了速率限制提示;而第一次修复bug的任务则发现相关文件其实早已被之前的运行所修复。
| 任务 | MiniMax M3 | Kimi K3 | dsh V4-Flash(缓存已预热) |
|---|---|---|---|
| 回复“PONG” | ✅ 7.2秒 · 1轮交互 | ✅ 6.1秒 · 1轮交互 | ✅ 1.7秒 |
| 编写并运行FizzBuzz程序 | ✅ 12.1秒 · 3轮交互,调用2次工具 | ✅ 22.8秒 · 3轮交互,调用2次工具 | ✅ 5.3秒 |
| 修复2个错误,测试代码保持不变 | ✅ 41.0秒 · 8轮交互,调用8次工具 | ✅ 86.6秒 · 7轮交互,调用6次工具 | ✅ 11.3秒 |
| 总结6个模块的内容(少于150字) | ✅ 9.1秒 · 3轮交互,调用3次工具(共84字) | ✅ 65.5秒 · 5轮交互,调用10次工具 | ✅ 5.1秒 |
| 在多个文件及测试代码中重命名变量 | ✅ 89.9秒 · 14轮交互,调用22次工具 | ✅ 128.9秒 · 10轮交互,调用9次工具 | ✅ 12.3秒 |
| 总耗时 | 159.2秒 | 309.9秒 | 35.7秒 |
| 令牌使用量:未缓存输入/从缓存读取/输出 | 87.4k / 456.7k / 7.6k | 91.5k / 355.3k / 10.0k(其中4.1k为推理过程所用) | 6.1k / 147.3k / 4.7k(其中2.0k为推理过程所用) |
| 每单位未缓存输入令牌的缓存读取次数 | 5.2次 | 3.9次 | 24次 |
| 费用 | $0.125,定价为每百万令牌$0.60/$2.40/$0.12(此为标价;我购买的是固定套餐) | $0.531,定价为每百万令牌$3/$15/$0.30 | $0.011,定价为每百万令牌$0.44/$1.32/$0.014 |
价格按每百万个令牌计算,顺序为:未缓存的输入/输出/缓存读取。每个成本值即各项任务中 usage.cost.total 数值的总和;将令牌总数乘以上述单价后得到的数值也与此相同。
表格内容说明:
- 所有测试均通过。 我检查了磁盘上的每个结果:FizzBuzz的输出、pytest测试结果为绿色、摘要中的字数统计也正常,重命名后也没有出现任何旧名称。
- MiniMax的速度约为Kimi的2倍,按标价计算成本也仅为Kimi的1/4(耗时分别为309.9秒与159.2秒;成本则为0.531美元对比0.125美元)。Kimi当时处于最大思考强度模式,这也是导致其耗时较长的原因之一。
- 在同类任务中,V4-Flash上的dsh运行速度约为MiniMax的4.5倍,成本也仅为后者的1/11。
- 缓存起到了关键作用。 MiniMax每读取一个未缓存的令牌时,就会同时读取5.2个已缓存的令牌。按标价计算,读取缓存内容的成本比读取未缓存内容低80%。若将这些令牌都当作未缓存输入来计算,成本则会是0.125美元而非0.34美元。
- 重试次数并未计入总计数据。 所有12次MiniMax基准测试(包括那些被舍弃的结果)的总成本按标价计算为0.28美元,总耗时则为321秒。
小部件测试及修正
在dsh的文章中提到的“趣味测试”,其实就是根据文字描述来制作的该网站标志的像素艺术小部件。我希望Kimi和MiniMax也能收到同样的描述要求。各模型收到的描述内容如下:
简要说明:可交互的像素艺术版 LaserLloyd 徽标小部件
请制作一个独立且可嵌入的 像素艺术版 LaserLloyd 徽标(参见
reference-logo.png):一个白色背景上带有粗蓝色圆环,颜色代码为 #1f3f8f;圆环内有两个倾斜排列的大写字母“L”——左上方的“L”的竖笔位于右下方“L”的横笔之下,整体呈对角线堆叠布局。交付内容(全部放在此文件夹中)
ll-pixel-logo.js— 仅一个纯原生 JavaScript 文件,无任何依赖、无需构建步骤、也不发起网络请求。任意页面只需写入:<div class="ll-pixel-logo" data-size="320"></div>以及<script src="ll-pixel-logo.js"></script>即可完成嵌入。该脚本会自动查找所有.ll-pixel-logo元素并在其中插入一个<canvas>元素。具备响应式特性:画布宽度与容器一致且保持正方形比例;在高分辨率屏幕上也能清晰显示(自动适配 devicePixelRatio)。同时需提供window.LLPixelLogo.mount(el)方法以供调用。index.html— 一个演示页面,展示该小部件在三种不同尺寸下的效果,并配有简短的交互说明文字。README.md— 说明如何嵌入该组件、各种交互方式以及可使用的自定义属性(data-属性)。美术设计方面
- 使用 40×40 的像素网格。切勿手动绘制位图(即不要直接写多行由“#”或“.”组成的字符串,那样效率低下且易出错)。应通过算法程序化生成图像:编写一个
isLit(col,row)函数,当某像素满足以下条件时返回 true:(a) 该点距离圆心距离介于 0.82R 至 R 之间(即位于圆环上);(b) 该点属于两个倾斜排列的“L”字母的一部分。每个“L”由两个平行四边形构成:竖笔部分倾斜约20°,横笔部分则与之相连;左上方的“L”的横笔正好位于右下方“L”的竖笔之下,完全符合参考图样式。只需微调少量参数即可使最终图像在 200px 尺寸下与参考图一致。所有需要发光的像素点应在初始化时一次性计算完成。- 调色板设定:徽标主色为 #1f3f8f;高亮色为 #2ea8ff;琥珀色为 #ffb64a;青色为 #00e6cf;背景设为透明。
交互设计(本练习的核心所在,务求有趣且流畅)
- 鼠标悬停/触摸移动:指针附近的像素会产生物理反应——比如像流体或磁场般被推离光标位置,随后又带有阻尼地回弹;在位移过程中这些像素还会发出 #2ea8ff 或 #00e6cf 的辉光效果。整个过程需保持 60帧/秒的流畅度,不可出现卡顿现象。
- 点击/触摸:设计一个酷炫且令人满足的效果即可。任选一种强烈的表现形式并细致实现,例如让整个徽标碎裂成无数像素点并向外飞散,随后在重力与反弹作用下重新组合成原样(耗时约1.5至2秒);又或者模拟激光扫描效果,以发光的火花逐点“刻写”出完整徽标。多次点击时动画不应中断或出错。
- 闲置状态:应有一些细微的动态效果存在——比如缓慢的闪烁或是偶尔有单个像素发出微光——让整个画面显得生机盎然,但又绝不会喧宾夺主、干扰用户操作。
- 必须响应
prefers-reduced-motion: reduce设置:此时仅显示静态徽标,悬停时的辉光效果亦应取消。- 同时兼容鼠标与触摸屏操作。绝对不可出现滚动劫持现象。
质量要求
- 代码整洁且有适当注释;除
LLPixelLogo外不应存在其他全局变量。缩进使用2个空格,总代码行数控制在400行以内。- 在
file://协议下运行也不得出现任何控制台报错信息。请自行测试:可编写简易 Node.js 脚本或使用任意工具进行语法检查与功能验证(注意:环境中不可使用 jsdom;只需执行node --check命令即可)。同时还需编写无需 DOM 参与的单元测试以校验像素生成逻辑——比如统计发光的像素数量并确认圆环及两个“L”字母确实分别出现在正确的区域内。- 最后需输出简短的报告文档:说明自己完成了什么、如何嵌入该组件以及做了哪些验证工作。
根据会话日志,发生的事情顺序如下:
- Kimi,第一次尝试(任务要求同上):思考了8.8分钟,但未生成任何小工具代码,随后停止。费用约为0.31美元。
- Kimi,第二次尝试(同样的任务要求):它编写了一个包含323行的
ll-pixel-logo.js文件、一个演示页面、一份说明文档以及两个测试文件;接着运行测试并反复调整直至测试通过。不过它将所有这些内容,连同简短的运行报告一并写入了工作代理自己的工作区,而非我监控的文件夹中。该会话在15分钟后因超时而结束,因此我以为第二次尝试毫无成果。费用约为0.72美元。 - Kimi,第三次尝试(更为严格的限制条件:仅通过一次工具调用来生成文件,不允许预先规划,也禁止使用
node --check):耗时7.4分钟,最终在指定文件夹中生成了一个包含397行代码的完整小工具。费用0.47美元。也就是Kimi相关文章中展示的那个小工具。 - MiniMax(任务要求同上;一小时后,由同一工作代理执行):耗时59.3秒,共进行了25轮交互、24次工具调用,按标价计算费用为0.13美元。它发现Kimi第二次尝试时生成的文件仍保存在共享工作区中,于是读取了全部五个文件以及Kimi生成的运行报告,随后运行了相关测试并回复称:“已成功构建并验证整个小工具集”。实际上它并未编写任何小工具代码;它仅生成了自己的运行报告与状态文件而已。
我最初只把那个回复当作字面意思来理解。本文的初稿中,我将该文件描述为“MiniMax的第一次尝试产物,生成时间不到一分钟”。会话日志显示,在Kimi的第二次尝试中,该文件确实于日本标准时间08:11被write出来;本网站上的文件与其内容完全一致。因此对于MiniMax来说,目前尚未得到任何结果。接下来最稳妥的做法就是在一个空文件夹中重新运行一次。至于Kimi的情况则比我最初描述的要好:它的第二次尝试成功了,只是把文件保存到了错误的位置。
这是Kimi的尝试版-2小工具,正在此页面上运行。这就是我最初标记错误的那个文件:
prefers-reduced-motion 设置。它的前30行左右:
/* ll-pixel-logo.js — interactive pixel-art LaserLloyd logo widget.
*
* Embed:
* <div class="ll-pixel-logo" data-size="320"></div>
* <script src="ll-pixel-logo.js"></script>
*
* One file, no dependencies, no build step, no network requests.
* The 40x40 bitmap is rasterised procedurally from geometry (a ring plus
* two interlocking italic Ls) — never a hand-drawn bitmap.
*
* Interactions:
* - pointer move : pixels are pushed away from the cursor, then spring
* back with damping; displaced pixels glow blue -> cyan
* - click / tap : the logo shatters outward with gravity + floor bounce,
* then reassembles itself (~1.8 s)
* - idle : occasional pixel twinkle (amber / cyan)
* Honours prefers-reduced-motion: static logo, hover glow only.
*
* Global exported: window.LLPixelLogo (also module.exports under node,
* so the bitmap can be unit-tested without a DOM).
*/
(function () {
'use strict';
/* ---------------- palette ---------------- */
var BLUE = [31, 63, 143]; // #1f3f8f logo blue
var HI = [46, 168, 255]; // #2ea8ff highlight blue
var AMBER = [255, 182, 74]; // #ffb64a
var CYAN = [0, 230, 207]; // #00e6cf
Kimi的第三个尝试版本,也就是Kimi文章中提到的版本,开头是这样的:
/*!
* ll-pixel-logo.js — interactive pixel-art LaserLloyd logo widget.
*
* Self-contained vanilla JS: no dependencies, no build step, no network.
* Embed on any page with:
*
* <div class="ll-pixel-logo" data-size="320"></div>
* <script src="ll-pixel-logo.js"></script>
*
* Every .ll-pixel-logo element gets a <canvas> mounted inside it at load.
* Programmatic API: window.LLPixelLogo.mount(el) -> instance.
*
* Art: 40x40 pixel grid, rasterised procedurally from geometry (ring + two
* interlocking italic Ls). Interactions: pointer repulsion with spring-back,
* click/tap shatter-and-reassemble, idle shimmer/twinkle, reduced-motion
* support. Mouse and touch. No scroll hijacking (all listeners passive).
*/
(function () {
'use strict';
// -- constants ------------------------------------------------------------
var VERSION = '1.0.0';
var GRID = 40; // logical grid: GRID x GRID cells
var BLUE = [31, 63, 143]; // #1f3f8f logo blue
var HILITE = [46, 168, 255]; // #2ea8ff highlight blue
var AMBER = [255, 182, 74]; // #ffb64a twinkle amber
var CYAN = [0, 230, 207]; // #00e6cf max-displacement glow
var CENTER = GRID / 2; // grid centre coordinate (20)
var R_OUT = 19; // ring outer radius (cells)
var R_IN = 0.82 * R_OUT; // ring inner radius
var SLANT = Math.tan(20 * Math.PI / 180); // ~20 deg italic shear
还有那个 dsh 小部件,也就是 dsh 文章顶部出现的那个:
/*!
* ll-pixel-logo.js — interactive pixel-art LaserLloyd logo widget.
* Vanilla JS, zero dependencies, no network requests, works from file://.
* <div class="ll-pixel-logo" data-size="320"></div>
* <script src="ll-pixel-logo.js"></script>
* Auto-mounts on .ll-pixel-logo elements; window.LLPixelLogo.mount(el) too.
* Knobs: data-size, data-speed, data-static.
*/
(function (global) {
'use strict';
// ---- 0. palette -----------------------------------------------------
var BLUE = [31, 63, 143]; // #1f3f8f — logo blue
var HI = [46, 168, 255]; // #2ea8ff — hover / repulsion glow
var AMBER = [255, 182, 74]; // #ffb64a — twinkle spark
var CYAN = [0, 230, 207]; // #00e6cf — deep glow
// ---- 1. art: procedural 40x40 raster (no hand-drawn bitmap) ----------
// A cell is lit when it belongs to the ring or to one of the two slanted
// interlocking Ls. Each L is two parallelograms (stem + foot), described by
// top-left (ax,ay), width w, height h, sheared by SLANT (bottom edge shifts
// left): TL=(ax,ay) TR=(ax+w,ay) BL=(ax-SLANT*h,ay+h). The upper-left L's
// foot runs right and tucks under the lower-right L's stem, like the ref.
var GRID = 40; // cells per side
var RING_R = 19.7; // outer ring radius (cells)
var RING_IN = 0.80 * RING_R; // inner ring radius (reference ~0.808R)
var SLANT = 0.453; // shear of stems/feet (~24deg)
var LETTERS = [
{ ax: 15.0, ay: 5.2, w: 4.2, h: 10.6 }, // upper-left L: stem
{ ax: 10.2, ay: 15.8, w: 15.0, h: 3.8 }, // upper-left L: foot
{ ax: 24.7, ay: 13.8, w: 4.2, h: 14.7 }, // lower-right L: stem
{ ax: 18.0, ay: 28.5, w: 15.0, h: 3.8 } // lower-right L: foot
];
这三个程序都会根据几何数据绘制出一个圆环以及两个倾斜的“L”形图案,同时会调用 window.LLPixelLogo.mount,并遵循 prefers-reduced-motion 的设置。我通过检查 40×40 网格中每个单元格的 isLit 值来统计被点亮的单元格数量:
- Kimi,第二次尝试:
RING_R = 19.4,内部半径为0.82R,SHEAR = 0.42(约22.8°)。有一个名为inL的辅助函数,能在单次测试中同时处理脚部与发生剪切变形的茎部。共使用了602个存储单元。 - Kimi,第三次尝试:
R_OUT = 19,内部半径为0.82R,SLANT = tan 20°(约0.364)。还有一个名为makeL的辅助函数,可返回处理后的茎部与脚部数据。共使用了510个存储单元。 - dsh:
RING_R = 19.7,内部半径为0.80R,SLANT = 0.453(约24°)。此处使用了一个包含四个元素的LETTERS数组。共使用了656个存储单元。
没有一个能完全匹配参考Logo;需求说明只要求在200像素尺寸下看起来像原Logo即可,而这三个都符合要求。在发布任何版本之前,我会花十分钟时间调整相关参数。
我在第二次测试中重新检查了哪些内容
在包含该小部件以及Kimi编写的两个测试文件的文件夹副本中运行测试:
$ wc -l ll-pixel-logo.js
323 ll-pixel-logo.js
$ node --check ll-pixel-logo.js && echo "syntax ok"
syntax ok
$ node test-bitmap.js | tail -1
ALL PASS
$ node test-smoke.js | tail -1
SMOKE PASS
test-bitmap.js 进行了18项检查:确保环形图案出现在四个基本方位上,而在角落和中心则不存在;每个“L”形图案的竖杆与底部都位于各自所在的象限内;同时还需验证互锁区域、倾斜方向,以及被点亮的像素总数是否在540到670之间。test-smoke.js 则进行了10项检查:包括使用虚拟DOM进行挂载操作、多次重复挂载仍能保持一致性、设置 role="img" 属性及 aria-label、模拟300帧的动画过程并包含一次指针移动与两次点击(第二次点击发生在动画中途)、确保粒子状态有限且可控、动画结束后logo能正常返回原位、在 devicePixelRatio 为2的情况下生成640像素宽度的后备存储区,以及能够顺利执行 unmount() 操作。这些均为Kimi自行编写的测试,但它们并不能作为独立的验证手段:Kimi在第一次运行 test-bitmap.js 后对其进行了修改——调整了检测区域的位置,并将被点亮像素数量的允许范围设为540–670;之后实际测量值恰好为602,此时所有检查才全部通过。这里的“通过”仅表明小部件与测试程序的结果相符,并不能说明这些测试设定了多高的标准。我自己的统计结果显示,被点亮的像素总数为602个,具体分布为:左上象限196个、右上象限137个、左下象限101个、右下象限168个。
注意事项(都是我亲身遇到过的)
- 持久化会话会破坏基准测试结果。 执行
openclaw agent --agent worker -m "…"时,除非指定新的--session-key,否则系统会复用同一会话。我第一次运行 MiniMax 时,FizzBuzz 任务判定目标文件已存在因而拒绝写入;修复 Bug 的任务则声称所有测试均已通过;而生成总结的任务则汇总了 Kimi 任务的修复结果而非自身的结果。为每项任务指定唯一的--session-key后问题才得以解决。 - 工作节点的预设指令优先级高于提示内容。 我的工作节点代理的指令要求它将较长的输出内容保存到专属工作区,这一规则两次压过了“将 fizz.py 写入当前文件夹”的指令。第三次 FizzBuzz 任务返回称文件已写入临时文件夹,但文件的时间戳却显示其位于工作区中;第四次任务使用了绝对路径并明确指定写入位置,这才正确执行。
- 共享工作区会导致后续任务受到干扰。 正如前文所述:Kimi 任务留下的残留文件一小时后仍存在于工作区中,MiniMax 误将其视为自身生成的文件。务必为每项任务创建独立的空文件夹,并核查其实际写入的内容(如时间戳、会话中的
write调用记录),而非仅依赖任务返回的描述信息。 - 退出码为错误值不代表任务失败。 在 Kimi 任务的第一次 FizzBuzz 执行中,程序以代码 1 退出,提示未找到合适的模型且出现了“⚠️ API 速率限制已触发,请稍后重试”的警告;然而
fizz.py文件确实已被生成且可正常运行。只有第二次重试任务才显示“已完成”。因此应以实际生成的文件为准,而非仅依赖退出码。 - 系统标称支持 1,000,000 个令牌,但我实际只用了 262,144 个。 这是我自行设置的
contextTokens数值;JSON 中的agentMeta.contextTokens字段也印证了当前生效的设置值。若确实需要更长的上下文窗口,可相应提高该数值;我在执行特殊任务时便通过minimax-portal来实现此操作。 - 固定套餐中的费用数值虽为虚构数据,却颇具参考价值。 OpenClaw 会根据内置的定价表填充
usage.cost.total的数值;该值仅适用于模型间的横向对比,绝不能作为实际付费依据。
这样的结果对我意味着什么
在我的工作代理系统中,MiniMax M3是主要使用的模型;DeepSeek V4-Flash和V4-Pro则作为备用模型。Kimi K3并未被纳入这个模型链中——我将其用于其他场景,比如我的代码审查代理。在这类任务中,M3仅用89.9秒便完成了重命名操作,成本为0.058美元(按标价计算);而Kimi则需128.9秒,成本达0.180美元。在修复错误方面,M3耗时41.0秒、成本0.025美元;相比之下Kimi需要86.6秒且成本高达0.114美元。至于V4-Flash上的dsh模型,在所有任务中都表现得更快且成本更低。
关于MiniMax的任务说明目前仍处于待处理状态。当我重新运行该任务时,系统会生成一个空文件夹;在查看相关报告之前,我会先检查此次会话中的write操作记录。
相关链接:作为编程代理的Kimi K3(本次对比中涉及的Kimi相关内容)、DeepSeek Harness (dsh)(包含五项测试任务及原始任务说明)、Reasonix(曾在早期文章中与之对比;该模型已于2026年9月9日从我的系统中停用),以及我的AI代理实际产生的成本:DeepSeek与大型API的对比。