有钛度的 AI 观察 — 每周更新 EST. 2026 · WWW.GETAITI.COM
深度 · 原创 · 周更 WEEKLY · 有钛度

归档 / NO.015 · 本地 AI · AIHub · 语音助手 · MCP · Rex · LoRA

我给本地 AI 接上了工具,结果它开始乱调用

从一个能本地对话的语音助手,到会调用 MCP 的 AIHub;为什么让小模型学会“不调用”,比学会调用更难。

作者 Jeffrey Hu 2026.11.07 约 3,700 字 阅读 12 分钟
本文章节 · CONTENTS 06
  1. 01 为什么要专门用一个小模型判断意图
  2. 02 第一个坑:一句普通的话,被当成了执行命令
  3. 03 第二个坑:上下文不带不行,带多了也不行
  4. 04 第三个坑:MCP 工具不断增加,不可能每次都训练一遍
  5. 05 越往下做,越觉得「不做」也是一种能力
  6. 06 项目源码与参考

以 Cyberwing 赛博机为中心的本地语音 AI 助手,连接多种终端与 MCP 工具

第十二篇写喵伴时,我主要折腾的是让一只 ESP32 小猫听懂我说话,再用电脑上的本地模型回答。那时的重点是让它真正开口说话。后来我把这套东西继续做成了 AIHub:一个可以在自己电脑或局域网服务器上运行的语音助手,语音识别、对话模型、语音合成都能放在本地,不必把日常对话送去云端处理。

它不再只服务于一只小猫。电脑上打开网页就能聊天、录音;ESP32 喵伴可以作为带麦克风和扬声器的终端;我还做了命令行客户端,在终端里打字、说话或者发起录音。它们可以连到局域网里同一个 AIHub 服务,模型和工具能力集中在服务端,使用时不要求每台终端都具备 AI 算力。以后有需要,还可以接手机 App,不过眼下我更想先把这几种入口用顺手。

模型与工具集中在一台本地主机,网页、ESP32 和命令行客户端通过局域网接入

部署上我也希望它不绑定某一台 Mac。现在可以在 Mac 上原生运行,也有支持 macOS 和 x86 Linux 的 Docker 部署方式。需要说明的是,Docker 管的是服务,不意味着所有推理都塞进容器:Mac 上的 MLX 模型仍由宿主机运行,x86 机器则可以对接本地部署、通过 HTTP 提供接口的 ASR、LLM、TTS 服务。这里的“本地”说的是模型和私有数据由自己掌控;天气、新闻等 MCP 工具是否访问外网,则取决于具体工具。

听、想、说这条链路跑通以后,我自然想再往前走一步:既然能聊天,能不能顺便帮我查天气、设个计时器、看电脑状态,或者通过 MCP 调用别的工具?

把工具接上并不算难。真正开始天天和它说话,我反而遇到一个意料之外的问题:有时候我根本没让它做事,它却自作主张去调工具了。

比如刚问过天气,接着说一句「嗯,好的」,它可能还惦记着上一个天气问题;又或者我只是想聊聊「天气查询工具怎么工作」,它却把这句话当作一次查询。天气多查一次,大不了浪费一点时间。如果以后接的是文件操作、消息发送、日程修改,误调用就不能算小毛病了。

我想解决的不是「AI 怎么学会更多工具」,而是先让它知道:什么时候应该什么都不做。

普通聊天被错误判断为天气查询,机器人调用了不需要的工具

为什么要专门用一个小模型判断意图

最简单的方案,是让负责聊天的 4B 大模型同时看工具列表,自己决定要不要调用、调用哪个、传什么参数。这样开发快,新增工具也方便。但本地语音对话有个要求:用户说完一句,最好尽快有反应。如果所有话都再交给 4B 做一遍完整工具规划,响应速度和稳定性就更难控制。

所以我在 AI Hub 里尝试了另一条路线:使用一个已有的中文 Rex 基座模型,通过 LoRA 微调做意图分类和参数提取。它不负责陪聊,主要判断这句话是普通交流,还是天气、新闻、系统信息、购物清单、计时器或物品位置等请求。像「查一下上海明天的天气」,它要识别天气查询,并把「上海」「明天」提取出来,再由代码检查参数是否合法。

这和让大模型直接生成一大段工具调用 JSON 不一样。小模型只做一个边界清晰的判断,符合条件才把任务交出去;其余对话仍由大模型回答。

但实测很快让我意识到:真实聊天不像训练样本那样规整。

第一个坑:一句普通的话,被当成了执行命令

训练时最好理解的例子是「查天气」「查询内存」「启动计时器」。真实使用却有大量句子不该触发任何工具:「天气不错」「你会查天气吗」「刚才那几个工具响应有点慢」「不用查天气,讲个笑话」。这些句子包含工具关键词,意图却完全不同。

这次我特别回头检查了训练集。仓库中的 router-everyday-v5 一共有 9,206 条训练数据、1,230 条验证数据和 853 条测试数据,标签里专门保留了 null,代表「无需工具」。后来又针对真实对话中容易误触发的口语,补充了唤醒词、寒暄、评价、否定、讨论工具但不要求执行等硬负例。它们不教模型多做事,反而教它克制一点。

仓库文档记录了一次很有意义的对比:验证集准确率为 98.2%,null 类误触发率 0.16%;但在 378 轮真实对话日志的评估里,整体准确率只是从 87.9% 提升到 89.6%,无工具轮次的误触发率从 7.6% 降到 3.6%。这些是项目当时的评估记录,不是我今天重新跑出来的生产数据,也不能把验证集 98.2% 当成日常真实使用的可靠性。

它给我的提醒很直接:离线测试集上的高分,不代表把麦克风打开以后就不会乱调。对语音助手来说,哪怕绝大多数轮次都判断正确,偶尔一次莫名其妙的工具调用也很破坏体验。

第二个坑:上下文不带不行,带多了也不行

这件事比单句分类更麻烦。第一轮我说「查一下上海今天的天气」,第二轮说「那明天呢?」——显然还在问天气,应该继承上海这个城市。可如果第二轮变成「嗯,不错啊」,或者「刚才你回答得有点慢」,它就不应该把天气意图带过来。

我以前容易把「让模型看到更多上下文」当成提升理解的办法。做工具路由之后才发现,聊天上下文和执行上下文最好不要混为一谈。回答问题时可以参考历史;决定是否启动工具时,上一轮的意图反而可能构成干扰。

天气话题残留在下一轮闲聊里,造成意图判断偏差

现在代码里已经加了一层限制:Rex 默认只判断当前用户这句话,只有遇到看起来像续问的短句,才附上上一轮用户输入。纯唤醒词、寒暄、告别,以及讨论工具本身的反馈,还有规则层的保护。上下文不会无条件把整段聊天塞给 Rex。

不过我还不能说问题解决了。比如中文的「呢」「继续」「那」本身就很模糊;而且上一轮工具参数又是独立保存的状态。只隔离历史文本还不够,还得确认什么时候允许继承工具参数、什么时候该清掉它。下一轮我准备集中测试「先查天气再闲聊」「先设计时器再换话题」「真正续问」这三类连续对话,看不同策略的误调用和漏调用分别是多少。

第三个坑:MCP 工具不断增加,不可能每次都训练一遍

Rex 很适合处理固定、高频、边界明确的意图,但它并不知道未来用户会装什么 MCP 工具。今天是天气、计时器,明天可能是外部日程服务,后天又多了一个文件或知识库工具。固定分类标签的模型不可能凭空认识这些新能力。

现在的 AIHub 采用的是一个混合方案:部分明确命令走规则,Rex 管已训练的核心意图;用户新启用的 MCP 扩展,则还会由 4B 模型读取当前这一句和工具定义,做受约束的动态规划。扩展工具的参数还要经过 schema 校验,并不是一句话匹配上名称就能直接执行。

赛博机上的 AIHub 连接语音模型与多种可调用工具

所以现在不能说「新增 MCP 完全不用大模型」,更不能说「新增工具已经会被 Rex 自动学会」。这正是我后面想优化的地方:能否让小模型先可靠判断这轮有没有执行意图,再从可用工具里选出候选,而不是把所有新增工具都纳入下一轮固定标签训练?

再往后一步,则是上线后的本地后训练。如果用户发现某句话被误判了,能不能在自己的设备上留下一个经确认的纠错样本,定期训练一个新的 LoRA?我希望新版本不是直接覆盖旧版本,而是先和一套固定测试集比较,至少确认旧工具没有被学坏,才能切换;出了问题还能回滚。

但这目前仍然是研究方向,不是已经上线的「自动进化」功能。难点也不仅是训练速度,而是怎么获得可靠标签。不能把模型自己做出的工具选择直接当正确答案,再拿来训练自己。

越往下做,越觉得「不做」也是一种能力

这次折腾让我对本地 AI 助手有了一个新的判断。语音识别再快、大模型回答再顺畅,如果工具判断不可靠,它还是只能当一个演示。真正给用户长期使用,系统必须能分清普通聊天、连续追问和执行命令;面对不明确的请求,宁可先问清楚,也不要猜着去做。

我还会继续试 Rex 的训练方法、上下文状态隔离,以及部署后的 LoRA 更新。尤其想看看,能不能让一个小模型在用户自己的设备上,随着可靠的纠错样本积累,慢慢变得更准。等这几组对照实验跑完,再单独写下一篇。


项目源码与参考

AIHub 核心项目:github.com/zhiwehu/aihub

网页客户端:github.com/zhiwehu/aihub-client-web

ESP32 喵伴固件:github.com/zhiwehu/aihub-firmware

命令行客户端:github.com/zhiwehu/aihub-client-cli

Rex 路由实现:rex_planner.py

工具调用实现:tool_chat.py

上下文判断和动态工具路由:extension_routing.py

Rex v5 训练集与测试记录:router-everyday-v5

Docker 部署说明:deploy/docker/README.md

上一篇文章:从 ESP32 到 Mac 本地 VoiceHub

订阅 · SUBSCRIBE

扫码关注公众号

文章每周更新,网站和公众号「AITi智能」同步发布。想在微信里第一时间看到,扫码关注。

  1. 01 微信搜索「AITi智能」
  2. 02 关注并加星标
  3. 03 每周更新,不见不散
公众号「AITi智能」二维码

扫码关注 · 每周一篇