跳到主要内容

图 7 - MCP 工具调用时序

用户对 LLM 说"把音量调到 80",LLM 是怎么真的控制到设备的喇叭的?

如果上方图无法显示,点这里看 PNG 版本

MCP 是什么

Model Context Protocol —— 让 LLM 和"外部能力(工具)"之间用统一接口通信的协议。基于 JSON-RPC 2.0,跨厂商通用(不绑定特定大模型平台)。

在小智项目里,设备就是 MCP Server,云端 LLM(通过 MCP Client)来调用设备能力。

三个阶段

阶段 1:工具发现(连接后一次性)

LLM 接入设备后第一件事是问"你能干啥?":

  1. MCP Client 发 tools/list 请求
  2. McpServer 返回所有已注册的工具描述(含名字、参数、范围)
  3. LLM 把这些工具描述塞进自己的 system prompt

优化: 工具描述可能很长,McpServer 做了分页cursor 字段)和按优先级排序(常用的放前面,提高 LLM prompt 缓存命中率)。

阶段 2:工具调用(按需)

用户对 LLM 说:"把音量调到 80"

  1. LLM 推理决定调 self.set_volume 工具,参数 {volume: 80}
  2. tools/call JSON-RPC 请求
  3. McpServer 解析、找工具、校验参数范围(必须 0-100)
  4. 不直接执行——而是 Schedule 一个回调到主循环(避免协议线程做硬件操作)
  5. 主循环里调用 codec.SetOutputVolume(80)
  6. 操作结果回 JSON-RPC reply

关键设计:MCP 工具 callback 在主循环执行,保证硬件操作的线程安全——所有 GPIO / I²C 操作都串行化在一个线程里。

阶段 3:主动推送(反向)

设备也可以主动给云端发消息——比如摄像头拍完照片、按键被按、电池低电量等。这些不是 JSON-RPC 调用,而是设备主动发的状态更新。

设备端有哪些工具

AddCommonTools() 注册的(所有设备都有):

  • self.get_device_status — 报设备状态
  • self.set_volume — 调音量
  • self.set_brightness — 调亮度(屏幕背光)
  • self.set_theme — 切主题
  • self.take_photo — 拍照(有摄像头才有效)

AddUserOnlyTools()(只对用户客户端可见,LLM 看不到):

  • self.reboot
  • self.upgrade_firmware
  • self.screen.snapshot
  • self.assets.set_download_url

加上 board 自己注册的(比如 LampController 注册的 lamp.turn_on/off),LLM 就能"说话控物联网"。

一句话讲清

"MCP 是 LLM 和设备能力之间的标准协议;设备实现 MCP Server 暴露工具,LLM 通过 MCP Client 调;调用走主线程保证硬件线程安全;分两层:通用工具 LLM 可见,敏感工具只有客户端可见。"

关联章节

  • /06-mcp-server 整章