夜雨聆风学习资料网

ARTICLE · 1184867

OpenClaw + Nimble 本地决策模型搭建全记录

OpenClaw + Nimble 本地决策模型搭建全记录

环境:Mac mini(Gateway 宿主)+ Windows LEGION 节点 | 全程零 API 费用

一、背景与目标

OpenClaw 原生支持"决策模型"(decisionModel)角色:agent 获得 decision_evaluate 核心工具,把结构化判断题(分类路由、是否判断、多级评分)交给专门的决策模型,返回带概率的类型化答案,而不是让主 LLM 生成自由文本。

官方推荐路径是 TypeSafe AI 插件 + 托管 Jev API($0.01/次)。目标是改用局域网内 Windows 节点(LEGION)Ollama 上的 nimble 决策模型,数据不出门、零费用。

二、调研结论

  • nimble:Bespoke Labs 出品,9B(Qwen3.5-9B LoRA 微调),Apache 2.0。只读 logprobs 选答案,从不生成文本,无推理步骤。
  • Ollama 0.35+ 通过 /v1/systemone 端点暴露决策模型,请求/响应与 TypeSafe Jev API 同构,可作 drop-in 替换。LEGION 上是 Ollama 0.40.3。
  • 没有现成的 OpenClaw 决策模型技能/插件;node_inference 工具只列 chat 类模型——这就是最初"看不到 nimble"的原因(决策/嵌入模型都被过滤)。
  • TypeSafe 插件限制:baseUrl 仅接受 loopback(localhost / 127.0.0.1 / [::1]),不接受局域网地址,也不带 /v1 后缀(插件自动拼 /v1/systemone)。

三、最终架构

任何 agent(配置了 decisionModel)  → decision_evaluate 核心工具    → typesafe 插件(baseUrl = http://127.0.0.1:18009)      → Mac 本地 TCP 转发器(launchd 常驻)        → Windows LEGION Ollama 0.40.3(legion.local:11434)          → nimble 9B(别名 kev-latest)

四、分步配置过程

第 1 步:Windows 节点建模型别名

插件发送的模型标签是 host 侧选择的(如 kev-latest),在 LEGION 的 Ollama 上为 nimble 建别名(两个都建,兼容任意标签格式):

curl -X POST http://legion.local:11434/api/copy \  -H 'Content-Type: application/json' \  -d '{"source":"nimble","destination":"kev-latest"}'curl -X POST http://legion.local:11434/api/copy \  -H 'Content-Type: application/json' \  -d '{"source":"nimble","destination":"typesafe/kev-latest"}'

第 2 步:Mac 写本地 TCP 转发器

~/.openclaw/workspace/scripts/legion-ollama-forward.mjs(Node 内置 net 模块,每连接重新解析 DNS,容忍 LEGION 换 IP):

import net from"node:net";const server = net.createServer((socket) => {const upstream = net.connect({ host: "legion.local", port: 11434 });  socket.pipe(upstream).pipe(socket);constcleanup = () => { socket.destroy(); upstream.destroy(); };  socket.on("error", cleanup);  upstream.on("error", cleanup);  socket.on("close", () => upstream.destroy());  upstream.on("close", () => socket.destroy());});server.listen(18009, "127.0.0.1", () =>console.log("forwarding 18009 -> legion.local:11434"));

第 3 步:launchd 常驻(开机自启 + 崩溃拉起)

~/Library/LaunchAgents/com.openclaw.legion-ollama-forward.plist:

<dict><key>Label</key><string>com.openclaw.legion-ollama-forward</string><key>ProgramArguments</key><array><string>/opt/homebrew/bin/node</string><string>/Users/lishewen/.openclaw/workspace/scripts/legion-ollama-forward.mjs</string></array><key>RunAtLoad</key><true/><key>KeepAlive</key><true/><key>StandardOutPath</key><string>/tmp/legion-forward-launchd.log</string><key>StandardErrorPath</key><string>/tmp/legion-forward-launchd.log</string></dict>

加载:launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.openclaw.legion-ollama-forward.plist

第 4 步:安装并配置 typesafe 插件

openclaw plugins install @openclaw/typesafe

配置(无需 API key):

openclaw config set plugins.entries.typesafe.config.baseUrl "http://127.0.0.1:18009"

第 5 步:启用 decisionModel + 独立决策 agent

# 所有 agent 默认获得 decision_evaluateopenclaw config set agents.defaults.decisionModel "typesafe/kev-latest"# 独立"决策官"子代理openclaw config set agents.entries.decision '{"model":"zai/glm-5.3","decisionModel":"typesafe/kev-latest","name":"决策官","identity":{"name":"决策官","theme":"决策分析","emoji":"⚖️"}}'# 加入 main 的可 spawn 列表(在原数组上追加 "decision")openclaw config set agents.entries.main.subagents.allowAgents '[...原列表...,"decision"]'

第 6 步:写技能文件

~/.openclaw/workspace/skills/nimble-decision/SKILL.md:何时用(分类路由/是否判断/评分分级)、三种问题类型(boolean=noul、choice、score)、rubric 设计原则、结果解读(probabilityTrue 阈值、confidence 是分布集中度不是准确率)、故障排查表。

五、验证结果

直连测试(curl → legion.local)

中文工单测试:is_urgent noul 0.993、department=billing (0.885)、frustration 1.90/2。首次调用加载模型较慢,后续 <100ms。

端到端测试(decision_evaluate → 插件 → 转发器 → nimble)

英文 500 错误工单,三问并发:

问题
结果
解读
escalate (boolean)
P(true)=0.99
99% 需要人工应急响应
route (choice)
support 52% / sales 34%
低置信度,分裂分布=不确定
severity (score)
2.37 / 3
概率加权,介于"重要流程中断"~"大范围事故"

boolean 判断非常果断;choice/score 在信息不足时表现出合理犹豫——这正是 confidence 的用途。

六、踩坑记录

  1. node_inference 看不到 nimble:discovery 只列 chat 模型。决策模型要用 ollama list(节点上)或直接调 /v1/systemone 确认。
  2. nohup & 后台进程会被回收:exec 会话结束后进程死掉。持久服务用 exec(background=true) 或 launchd。
  3. openclaw plugins install 返回 SIGTERM 不代表失败:以 openclaw plugins list 为准。
  4. 新建 agents.entries 条目会校验整棵模型树:失效的模型引用(如已下架的 zai/GLM-5.1 在 fallbacks 里)会挡住写入,错误信息里的位置可能不准确。修复或绕开(给新条目显式指定 model)。
  5. spawn 授权用旧快照:allowAgents 改动后本会话内 spawn 仍按旧列表拒绝;网关重启/下轮对话后生效。
  6. questions 必须是 object 不是 array:decision_evaluate 实测。
  7. 新模型名要先注册:把 deepseek/deepseek-flash 写进 fallbacks 报"Unknown model",即使 models list --refresh 能看到。需要先在 models.providers.deepseek.models[] 注册 {"id":"deepseek-flash","name":"..."},再改引用。
  8. 长耗时 config set 会被前台超时 SIGTERM:agents.defaults.model.* 的写入可能触发慢校验,用 exec(background=true) + 轮询执行;SIGTERM 后要核实是否已写入再重试。

七、日常使用

  • 直接对 agent 说:"判断这条消息该路由给谁"、"给这个回答打个分"——agent 自动走 decision_evaluate。
  • rubric 要点:选项描述具体可判定;choice 给全选项加 "other" 兜底;score 各级写行为锚点;同一 state 的问题一次问全(≤32 个)。
  • 结果阈值建议:≥0.9 行动、0.6–0.9 人工复核、<0.6 视为否;confidence <0.1 说明分布平坦,升级人工。
  • nimble 空闲 5 分钟卸载,下次调用等 30–60 秒加载;高频场景请求加 keep_alive。
  • LEGION 关机时决策返回 unavailable(正常降级,不会误判)。

八、故障排查

症状
检查
decision 返回 unavailable
lsof -nP -iTCP:18009 -sTCP:LISTEN
;LEGION 是否在线
转发器死了
launchd KeepAlive 会自动拉起;查 /tmp/legion-forward-launchd.log
模型 not found
LEGION 上 ollama list 确认 kev-latest 别名
首次调用慢
模型加载中(9.5GB),属正常

相关学习资料