MHS、MCP、Agentic Infra,这三个词拆开看每个都懂,合在一起,基本就是当前AI智能体操作物理设备绕不开的技术栈。最近不少朋友在群里问:为什么大模型已经能写代码、能搜网页,但一接硬件就各种幺蛾子?机械臂乱动、传感器状态对不上、一次误操作差点把设备干烧。我自己的体会是,问题往往不在模型本身,而是缺了一套把“意图”安全翻译成“动作”的基础设施。
这篇文章我会把MHS、MCP和Agentic Infra这三层分别是什么、各自解决什么问题、应该怎么协同讲清楚,然后给出一条可以从零跑通的最小链路:大模型通过MCP协议,去调用一个MHS设备服务,最终控制一台模拟小车运动。想入坑Agent硬件控制、或者已经在做智能体应用但被工具调用折磨过的朋友,这篇文章应该能帮你少踩不少坑。
1. 先理解这三层:MHS、MCP 与 Agentic Infra 各管什么
1.1 MHS:设备和智能体之间的“翻译官”
MHS在公开资料里并没有一个绝对官方的定义,至少不像PLC、ROS那样有统一标准。在很多工程团队的内部架构里,MHS通常被写成Machine Handling Service,或者叫Managed Hardware Service,本质是一层把物理设备能力封装成标准服务接口的中间系统。
为什么会需要这一层?你看一个工厂里常见的设备:PLC、伺服驱动器、串口舵机、ModBus传感器,沟通协议五花八门。有的走RS485,有的走CANOpen,有的只有厂商私有SDK。如果让大模型直接读这些底层协议,先不说token开销有多大,光是协议解析就能把一次正常的“打开夹爪”请求变得又慢又危险。模型一旦在某个请求里带了一个越界的坐标值,底层设备可不会跟你商量,执行就是执行。
所以MHS的核心职责有三个。第一,把不同品牌、不同协议的设备抽象成统一的数据模型,上层看到的就是“设备A有这几个属性,可以执行这几个动作”。第二,做实时状态缓存和指令队列,不然智能体每问一次状态都去轮询底层设备,响应时间根本扛不住。第三,也是最重要的,做安全策略控制,包括限位检查、互锁逻辑、权限校验、急停联动。没有MHS这一层,MCP就像一个没有变速箱的发动机,动力再强也不敢直接输出到车轮上。
1.2 MCP:让模型天然会“使用工具”的标准协议
MCP的全称是Model Context Protocol,模型上下文协议,由Anthropic在2024年底开源。它解决的是模型和外部工具之间“连接方式不统一”的问题。在MCP出现之前,每个Agent框架都有自己的function calling格式,你在LangChain里写好的工具,换到别的框架基本要重写。MCP出来以后,服务端只要实现一套标准接口,任何支持MCP协议的客户端都可以直接用,比如Claude Desktop、Cursor、Codex以及各类自研Agent应用。
MCP协议里最核心的是三类原语。Tools,工具,对应可执行的动作;Resources,资源,对应可以读取给模型参考的上下文数据;Prompts,提示模板,对应一些预设好的对话模式。其中tools是我们在控制物理设备时最常用的,模型在推理过程中发现自己需要执行某个动作,就会按工具定义输出一个结构化调用请求,由MCP Server侧完成对应逻辑。
在物理设备场景里,MCP扮演的是“智能体与MHS之间的连接器”。MHS提供设备能力,MCP把这些能力包装成模型能理解的工具。你可以把MCP想象成USB-C接口,MHS是显示器、键盘、鼠标这些外设,模型则是电脑主机。主机不需要知道每个外设底层芯片怎么工作,只要插上同一个标准接口就能用。
1.3 Agentic Infra:真正运行智能体的“地基”
前面两层只解决了“模型能不能调用工具”的问题,但要支撑一个智能体稳定生产运行,还需要更多东西:模型往哪里发请求、任务如何编排、工具调用的结果怎么反馈给模型、每一步操作是否有日志可审计、出错时能不能回滚。这套支撑体系,行业里叫Agentic Infra,智能体基础设施。
你可以把Agentic Infra理解成“大脑之外的神经系统”。模型本身可以理解语言、做出决策,但它需要被赋予记忆、需要知道什么时候用哪个MCP Server、需要有人替它兜底。尤其是操作物理设备的时候,Agentic Infra必须考虑人在回路:高风险动作先暂停,输出说明,让人类确认后再继续。这个机制不是可选项,而是必选项。智能体一旦拿到控制权,系统的可靠性就不只取决于模型聪明不聪明,而取决于整个链路有没有冗余保护。
把三层串起来看:MHS是设备侧的统一访问层,解决“怎么听懂设备的话、怎么安全地指挥设备”;MCP是模型与MHS之间的通信协议,解决“怎么让模型以标准方式调用工具”;Agentic Infra是贯穿上下的运行环境,解决“整个智能休怎么稳定可靠地跑起来”。
2. 为什么非要多一层“中间商”?拆一次真实调用给你看
2.1 没有中间层,模型直接操作设备会出什么问题
不少第一次接触硬件的开发者会问,设备API本来就是HTTP接口,文档写清楚,让大模型直接调不行吗?看起来可以,但做一次就会发现坑比想象多得多。
第一个问题是上下文爆炸。设备状态是持续变化的,机械臂关节角度、小车电量、传感器读数,每秒钟都在刷新。如果你把完整历史全部塞给模型,几轮对话以后上下文窗口就满了;如果只给一个快照,模型又缺少足够信息做出正确判断。MHS在这里的作用是替模型做“状态摘要”,比如把几十个传感器数值整理成一句话:“设备当前电量87%,机械臂坐标在安全区域,无告警”。
第二个问题是并发冲突。模型不是串行工作的,一个任务可能被拆成多个并行子任务,多个子任务同时去操作同一台设备,如果没有消息队列和互斥锁,轻则动作错乱,重则物理碰撞。MHS内部必须维护一个指令队列,同一时刻只有一个控制指令能下发到设备驱动层,其他请求排队等待或者直接拒绝。
第三个问题是安全边界。模型本质上是一个概率推理系统,它对数值的把握并不总是可靠。你让它把电机速度调到3000转,它可能给你输出一个负值或者超出规格的数。我们可以通过prompt约束它,但prompt不是万能的。真正能拦住错误指令的,只有MHS层面的参数校验和物理限位。所以这层“中间商”不是多余,而是安全设计里不可或缺的环节。
2.2 一次“把杯子从左边挪到右边”的完整链路
为了方便理解,我拆一个具体的场景:桌面上有一台六轴机械臂,用户对大模型说“把桌面左边的蓝色杯子挪到右边托盘里”。这句话看起来简单,但背后至少要经过下面这些步骤。
第一步,用户的输入进入Agentic Infra,先做意图识别和任务拆解。模型中会生成一个计划:先确认机械臂和杯子的当前状态,然后规划抓取路径,执行抓取,移动到目标位置,放下杯子。第二步,模型认为需要调用某个工具,于是发出一个MCP工具调用请求,比如get_device_status。这个请求通过MCP协议到达MHS,MHS再向底层PLC或机械臂控制器查询当前状态。第三步,MHS把获取到的数据进行抽象处理,返回一个结构化的状态结果给模型。模型看到当前机械臂坐标、夹爪开合状态、托盘位置,然后决定调用另一个工具move_to_position。
在move_to_position这个工具内部,MHS不是简单地把参数透传给机械臂。它会先检查目标位置是否在工作空间范围内,然后检查夹爪当前有没有夹持物体,再检查路径上有没有障碍物。这些都通过之后,指令才会被放入队列,真正下发给设备。执行过程中MHS会持续监测状态,如果发现机械臂已经碰到限位开关,会立即中断动作并返回错误码。
最后一步,MHS把执行结果返回给MCP Server,再传回给Agent。Agent分析结果后,生成一句话向用户汇报:“杯子已经放好了,夹爪已松开,位置确认正常。”整个过程里,MCP始终不直接操作设备,它只负责传递标准化的请求和响应;真正和物理世界打交道的是MHS。
2.3 边界划分:哪些事归MCP,哪些事归MHS,哪些事归Agentic Infra
实操中我见过很多团队把这三层混在一起用。最常见的是把业务规则写死在MCP Server里,今天模型需要一个新的校验逻辑,就得改一次代码,改完还得重新启动服务。其实MCP Server最适合放的内容是工具协议定义和轻量级的数据格式转换,比如把模型传过来的参数规范化,把底层返回的error code翻译成模型能理解的错误信息。它不应该负责复杂的业务逻辑。
业务逻辑和状态管理应该下沉到MHS。例如校验目标位置是否安全、设备是否处于自动模式、两个动作之间的最小时间间隔,这些都需要MHS掌握实时状态才能判断。MHS更像是懂设备业务的中台,MCP只是它向外提供服务的门面。
Agentic Infra则负责更高层次的决策和编排。比如一个复杂任务需要调用不同的MCP Server,先调用视觉识别服务确认物体位置,再调用MHS执行动作,最后调用一个报表服务生成任务记录,这个流程由谁来调度、如何并行、如何重试,都应该由Agentic Infra层面处理,而不是让某个MCP Server去依赖另一个MCP Server。我自己的经验是,这三层各管各的,界面前置,系统才能活得久。
3. 核心组件与实操时的技术选型思路
3.1 MHS设计从哪几块入手
假设你要自己写一个MHS,不必按工业级标准一步到位,但至少要把下面四个模块规划出来。
第一块是设备接入层,负责连接真实硬件。实际情况里,设备驱动往往需要单独成包。比如一个基于Modbus协议的温控器,你需要写一个driver,通过串口或TCP轮询寄存器,再把寄存器值转成温度。一个基于ROS2的移动机器人,则需要通过ROS的topic和service做通信。驱动层的目标是把各种协议转换成统一的内部事件流。
第二块是设备抽象层,也就是向上暴露的“统一设备模型”。我建议给每类设备定义一份JSON Schema。比如一部AGV小车,属性包括坐标x、坐标y、电量、当前速度、运行状态;动作包括move_to、charge_start、stop。属性只允许特定类型,动作只允许特定枚举参数。模型看到的是这种结构化描述,而不是一串难读的寄存器地址。
第三块是策略引擎,这是MHS和普通API服务的最大区别。每次控制指令下发前,都要在内存里执行一系列策略检查。最简单的是范围检查,比如位置参数X是否在0到5000毫米之间;再高级一点的是互锁逻辑,比如夹爪处于闭合状态时不允许执行旋转动作;再往上还有队列互斥,同一设备同一时间只允许一个写入指令。策略引擎建议独立成一个模块,方便后续增加规则。
第四块是北向接口层。MHS本身不需要知道MCP的存在,它只需要提供RESTful或gRPC接口供外部调用。有些团队的MHS选择了gRPC做内部通信,因为长连接性能好;对外则再包一层WebSocket或SSE用来推送状态事件。我建议先用REST把主流程跑通,后面再考虑性能和推送优化。
3.2 MCP Server的设计骨架:工具、资源、提示词
MCP Server的设计看似简单,写几个tool就行,但要做到让模型“好用”,里面有一些细节值得讲究。
工具命名要有统一前缀。比如机器人场景下,所有设备动作都叫robot.move、robot.grasp、robot.release;温控场景下叫thermostat.get_status、thermostat.set_target。统一前缀的好处是模型在长对话里能更快区分不同模块的工具,减少误调用。
工具描述要写清楚边界。MCP的工具description会完整送给模型,所以写描述不是在写文档,而是写“模型的操作手册”。比如一个move_to_position工具,description应该写明“目标位置必须位于设备的可达范围内,参数单位是毫米,如果返回错误码3001表示目标越界,需要重新规划后再调用”。很多初学者只写一句“移动机器人”,模型根本不知道怎么传参,自然容易出错。
除了tools,MCP Server里的resources在设备场景中也有用处。设备状态是一种典型的资源,它不是动作,不应该放在tool里让模型随意调用。我习惯把设备状态放在resources下,比如mhs://robot/status,模型需要上下文时会自动通过resource读取。这样也能减少模型“为了取状态而调工具”的次数。
实操心法:刚开始不要沉迷于把所有能力都做成tool。先只暴露三五个原子动作,跑通后再逐步增加。工具太多,模型反而会陷入选择困难,经常调错。
3.3 Agentic Infra的技术选型:编排、记忆、可观测
Agentic Infra没有统一的“全家桶”,通常是根据业务场景组合出来的。常见需要关心四个方向。
模型网关,负责统一接入不同模型供应商。为什么要做网关?因为智能体在任务中可能需要多模型协作:复杂规划用能力强一点的模型,简单的状态判断用便宜且快的模型。网关负责路由和成本控制。
编排运行时,我之前在项目中用过LangGraph和Temporal,各有侧重。LangGraph适合把任务定义成状态图,让模型在图节点间跳转;Temporal则更适合长时任务、需要持久化和人工介入的场景。如果项目只是从小成本开始,直接用Python的asyncio加手工状态机也能跑,但后面加需求时重写成本不小,建议早做规划。
记忆与上下文管理,这里不单指向量数据库。连接物理设备时,模型需要记住“上一次移动的坐标是什么”,这些短期记忆如果放在外部数据库,每次都要重新检索,效率低;放在多轮会话里,又有过期风险。我的建议是MHS自己维护一份设备状态的权威快照,Agent的记忆只做任务级记录,比如“任务A已完成移动,目标点是P1”,至于P1是否仍然有效,以MHS实时查到的状态为准。
可观测性是Agentic Infra里最容易被低估的。普通web接口出错,看个status code足够;Agent系统出错,你面对的是“模型决策、工具调用、设备响应”三个环节叠加的问题。没有trace链路,排查起来基本靠猜。我用OpenTelemetry把每个节点的输入输出都记录下来,包括模型调用时的prompt全文、MCP工具请求参数、MHS返回值,发生问题后第一件事就是去翻链路。
3.4 设备侧的真实控制闭环:别把AI决策和控制循环混在一起
硬件控制系统里有一个经典分层:毫秒级的伺服控制、百毫秒级的状态机控制、秒级以上的是任务规划。AI智能体目前只能处在最上层,它的决策速度天然不适合进入底层控制环。
比如一个电机速度环,需要以1kHz到10kHz的频率做PID计算,你不可能等大模型来算。正确做法是:底层实时控制由传统PLC或运动控制器完成,MHS只是把“目标位置”等高层指令下发进去,并订阅设备的实时状态。MHS里的保护逻辑也尽量用独立硬件或独立线程实现,不要和上层服务耦合。否则MHS进程一崩,设备就失控,这在工业场景里是不能接受的。
做实际选型时,你还要想清楚通信方式。控制一台Robot Arm能走TCP/IP就已经很方便;控制一排ModBus传感器,每个轮询周期可能只要几百毫秒;控制需要纳秒级同步的多轴运动,则需要专用总线和工业控制器。MHS能管到什么粒度,取决于底层硬件愿意暴露什么接口。遇到那种底层不支持实时状态反馈的设备,我一般会建议客户加装传感器,而不是硬靠上层逻辑去猜。
4. 实操:5分钟搭一条“大模型到模拟设备”的最小链路
4.1 准备一个最低配的“物理设备”
这一步我们不需要真硬件,但也不搞一个纯文字mock。我在项目中喜欢用物理引擎或高仿模拟器。最省事的办法是写一个Python类,内部维护设备状态,模拟执行动作需要的时间。
下面是一个非常简单的小车模型,它有两项能力:查询状态、执行移动。代码里加了电量消耗和位置边界限制,用来模拟真实设备的基本行为。
import time import threading class SimulatedAGV: def __init__(self): self.x = 0.0 self.y = 0.0 self.battery = 100.0 self.busy = False self.lock = threading.Lock() def status(self): with self.lock: return { "x": round(self.x, 2), "y": round(self.y, 2), "battery": round(self.battery, 2), "busy": self.busy, } def move_to(self, x: float, y: float): with self.lock: if self.busy: return {"ok": False, "error": "device_busy"} if abs(x) > 100 or abs(y) > 100: return {"ok": False, "error": "out_of_bounds"} self.busy = True # 模拟执行时间 time.sleep(0.5) with self.lock: self.x = x self.y = y self.battery -= 1 self.busy = False return {"ok": True, "status": self.status()}你可别小看这个模拟类,它已经包含了真实MHS里很重要的字段:busy表示设备是否忙碌,move_to方法内部用锁保证同一时刻只处理一个动作。后面对接MCP时,智能体多次并发调用就会触发device_busy错误,正好能看到一层防护在起作用。
4.2 写一个MHS服务端,并把状态暴露出来
有了设备对象,下一步要写一个简单的MHS服务。生产环境我通常会做REST接口加权限校验,这里为了演示,直接用FastAPI写两个接口,一个查状态,一个执行移动。
from fastapi import FastAPI, HTTPException from pydantic import BaseModel, Field from simulated_agv import SimulatedAGV app = FastAPI() agv = SimulatedAGV() class MoveRequest(BaseModel): x: float = Field(..., ge=-100, le=100, description="目标x坐标,范围-100到100") y: float = Field(..., ge=-100, le=100, description="目标y坐标,范围-100到100") @app.get("/device/status") def get_status(): return agv.status() @app.post("/device/move") def move_device(req: MoveRequest): result = agv.move_to(req.x, req.y) if not result["ok"]: raise HTTPException(status_code=409, detail=result["error"]) return result这个MHS和普通REST API看起来没什么区别,但有几个隐藏逻辑我是刻意加的。入参的x和y通过pydantic限制必须在-100到100之间;设备忙时会返回409;执行完成后返回完整状态。后续模型如果传一个500的值,还没到设备方法就会被拦截,这就是策略引擎的雏形。
4.3 用FastMCP把MHS包装成MCP Server
真正让大模型能用上这个MHS,需要一个MCP Server把HTTP接口转成工具。官方提供了Python和TypeScript的SDK,社区里还有一个更简洁的FastMCP封装,很适合快速写原型。下面的代码就用FastMCP定义了一个工具robot_move_to。
from fastmcp import FastMCP import httpx mcp = FastMCP("agv-mcp") MHS_BASE = "http://127.0.0.1:8000" @mcp.tool() def get_agv_status() -> dict: """获取AGV小车的当前状态,包括坐标、电量和是否忙碌。""" resp = httpx.get(f"{MHS_BASE}/device/status", timeout=5) resp.raise_for_status() return resp.json() @mcp.tool() def agv_move_to(x: float, y: float) -> dict: """移动AGV小车到指定坐标。 Args: x: 目标点的x坐标,必须在-100到100之间。 y: 目标点的y坐标,必须在-100到100之间。 """ resp = httpx.post(f"{MHS_BASE}/device/move", json={"x": x, "y": y}, timeout=10) if resp.status_code == 409: return {"ok": False, "error": "device_busy"} resp.raise_for_status() return resp.json() if __name__ == "__main__": mcp.run(transport="stdio")注意agv_move_to函数的docstring里,明确写了参数范围。这些信息会自动生成工具的JSON Schema并送给模型。实际项目中,docstring写得越细,模型调用的准确率越高。另外transport="stdio"表示MCP Server以本地进程方式启动,适合和客户端运行在同一台机器上的场景;如果部署在远程,则需要改成streamable-http模式。
4.4 在客户端里配置MCP,让智能体拿到工具
MCP Server写好后,需要在支持MCP的客户端里配置。以Claude Desktop为例,配置文件里添加一个mcpServers节点;如果是在Codex/Cursor这类开发工具里,通常也有类似界面。
{ "mcpServers": { "agv": { "command": "uv", "args": ["run", "agv_mcp_server.py"], "env": {} } } }这里我用了uv启动Python虚拟环境里的脚本,避免依赖环境变量混乱。配置完以后,重启客户端,应该能在工具列表里看到get_agv_status和agv_move_to。如果你发现工具一直注册不上,可以先在终端手动执行一遍启动命令,确认脚本没有报错,再检查客户端配置路径是否正确。
4.5 让模型完成一次多步骤控制任务
接着我们向智能体发一条指令:“检查小车电量,如果电量足够,就把它从当前位置移动到(20, 30)的位置,完成后告诉我新的坐标。”
一个正常工作的Agent会这样执行:先调用get_agv_status得到当前坐标和电量,然后判断电量是否大于0,再调用agv_move_to(20,30),最后根据返回值向你汇报。从后台日志里能看到完整的工具调用链,每一个步骤都有输入和输出。
这条链路之所以能跑通,是因为MCP Server把MHS的REST接口转换成了模型能理解的函数,模型只需要输出一个JSON格式的函数调用意图,剩下的参数校验和状态同步都发生在MHS层。如果MHS返回device_busy错误,模型还能根据错误信息决定是等待重试还是报告异常。这比让模型直接拼HTTP请求可靠得多。
5. 常见问题与排查技巧实录
5.1 MCP工具总是注册不上,多数是服务端启动和环境问题
被问到最多的一个现象是:在Codex里配置了某个MCP Server,比如Figma MCP,但工具列表里始终看不到。这类问题我排查过很多次,大部分原因不外乎三种:一是MCP Server启动就失败了,比如依赖没装、端口被占用、入口文件路径不对;二是配置的启动命令带了交互式参数,导致进程一直挂在等待输入;三是工具函数定义不规范,MCP SDK解析时直接忽略。
遇到这类问题,不要先怀疑客户端。先在终端手动运行一遍MCP Server的启动命令,看进程能不能正常起来,路径对不对。如果服务本身会打印日志,一定要保留。之后再用MCP Inspector这类工具连上去看工具列表,官方调试器能直接列出所有协议消息,比反复重启客户端高效得多。
5.2 MHS和MCP的边界不清,工具粒度越做越乱
我在代码评审时经常看到一种情况:MCP工具里直接写设备驱动逻辑,比如在一个工具函数里访问串口、解析数据、做业务判断。一开始确实跑得通,但后面每次增加一个设备动作都得改动MCP服务,服务重启期间所有Agent都不能对外提供操作能力。
这里我建议一个很朴素的检查标准:MCP工具的函数体里,除了解析参数和调用MHS接口,不应该存在超过20行的业务代码。如果超过了,说明有逻辑没有下沉。另外工具粒度要适中。不要把你的MHS接口一字不差全映射成MCP工具,尤其不要把需要鉴权的管理端接口暴露给模型。只暴露当前任务真正需要的“原子动作”,比如检查状态、执行移动、执行停止。至于路径规划、任务调度这些长逻辑,应该由Agentic Infra去编排,而不是做成一个巨大的工具“一键全包”。
5.3 MCP和Computer Use、Agent Skill、Function Calling的区别
这是最近大家问得比较多的一组概念。MCP是模型与工具之间的通信协议,它定义的是“工具长什么样、怎么被调用”;Function Calling是模型在推理时输出结构化函数调用的原生能力,属于模型侧能力;Agent Skill通常指更高级的可复用技能包,里面可以有提示词、工具调用序列、多步策略,可以理解为“面对某类任务的肌肉记忆”;Computer Use则是模型通过视觉和鼠标键盘操作图形界面的一套能力。
具体到物理设备控制场景,MCP是首选,因为它标准、可观测、适合被编排。Computer Use更适用于操作那些没有API的GUI系统,比如通过截屏识别按钮去点击老旧的工控软件,但它不稳定,不应该用于高实时性控制。Agent Skill适合沉淀经验,比如“启动设备的安全顺序”,它和MCP完全不冲突,Skill内部照样可以通过MCP去调用具体设备工具。
5.4 排查实录:一次设备状态不同步的坑
有一次我在测试中遇到一个问题:模拟小车明明已经移动到了目标点,但Agent汇报时还是旧坐标。一开始我怀疑是MCP Server缓存,排查后也没发现缓存逻辑。最后看trace才发现,模型在执行move动作后并没有立刻调用状态查询,而是直接拿先前状态里的旧坐标开始总结。
这个问题严格说不是Bug,而是模型上下文利用习惯导致的。后来我在MCP工具的返回值里把最新状态直接带上,move成功后的响应中不只是ok:true,还要有坐标、电量等关键字段。这样模型执行完动作后就不需要额外再查一次状态,直接从当前返回里提取信息。这个改动能显著减少状态不一致的问题。
做物理设备控制,日志字段一定要丰富。我自己的记录格式包含:请求ID、Agent会话ID、工具名称、入参、出参、耗时、错误码、设备状态快照。别嫌冗余,每次现场问题排查靠的就是这些痕迹。模型推理过程可以不可复现,但工具调用链必须可回溯,否则真出了责任问题,连证据都拿不出来。
6. 多智能体并发与后续扩展:值得提前规划的几个问题
6.1 并发操作同一个物理设备,MHS必须变成“交通警察”
设备不像接口,不是所有请求都能同时执行。我有一次让两个Agent并行工作,一个负责巡检,一个负责搬运,结果两个Agent同时意图移动同一台AGV,模型都认为自己在独自控制设备。MHS里如果只做简单的“设备忙碌就报错”,会造成大量重试,体验很差。更合适的设计是增加优先级队列,允许Agent提交动作后排队等待,MHS按FIFO或按任务优先级下发,并把预计等待时间返回给Agent。
这种设计和数据库的乐观锁、悲观锁很像。我建议MHS不要实现太复杂的调度算法,先把“同一设备单线程执行”这个基本纪律守住。等设备数量多了、任务并发高了,再引入分布式锁和调度中心也不迟。
6.2 权限链路要从“Agent能操作”延伸到“哪个用户能指使Agent操作”
引入Agent之后,权限模型被重新定义了。以前是人直接按设备启动按钮,现在用户对Agent说要启动设备,Agent去调工具。那么MHS收到的指令来源变成了Agent,传统基于API Key的身份认证不够用了。我们还要区分:这个Agent是由哪个用户会话发起的?该用户有没有权限对这个设备执行这个动作?Agent是否越过了用户原本的受控范围?
我在实际设计里会在每个MCP请求头里带一个caller context,里面包含userId、agentId、taskId。MHS校验时同时看两层:agent是否有工具调用权限,以及userId是否在当前任务授权范围。不要把全部信任交给Agent,因为你永远不知道模型会从哪句话里脑补出一个权限来。
6.3 用模拟环境来设计测试数据集是不错的开局方式
很多学员问AI智能体测试数据集怎么设计,尤其是在硬件场景里,真实设备不适合每天跑几千次测试。我的做法是构建一个仿真环境,把设备状态转换规则描述清楚,然后让Agent在这个环境里完成一批预设任务。任务集里要有成功路径,也要有需要拒绝的路径。比如“设备电量过低时不要执行移动”“目标位置超出安全区域的请求必须被拒绝”,这些用例能验证Agent是瞎执行还是有基本判断力。
我目前自己正在跑的一个实验,是让不同Agent共享同一个MHS去完成一整套仓储模拟任务。同一个任务让Agent重复执行十次,你会发现每次调用的工具顺序和参数都略有差异,但MHS最后把状态拉回同一个合法结果。这正是这套技术栈让我着迷的地方:模型提供的灵活性,被MHS的安全约束框在一个可控范围内,既能发挥智能体的能力,又不会让它把物理世界搞乱。想要真正把AI智能体用起来,这一层边界早晚要建起来,希望这篇文章能帮你少走一段弯路。