智能家居智能体:执行是演示,事件历史才是产品,也是责任。
每一场智能家居智能体的演示都在开灯,而每一起智能家居智能体的事故,都会是关于它读到的什么东西。设备事件历史是一份关于住在这栋房子里所有人的在场日志——在设备名这一层可由攻击者写入,在时间维度上没有边界,而且一旦进了上下文窗口就再也「读不回去」——而执行那一半,恰恰是可枚举、可撤销、也容易设闸的那部分。在写下第一条命令之前,先把读路径连同它的预算与窗口上限一起建起来;至于「把台灯打开」,就按它本来的样子当作简单问题对待。
按可撤销性给设备分类,而不是按品类,并按类别授予自主权。
有用的那根轴不是「灯 vs 锁」。而是:当智能体错了、又没人看着的时候,会发生什么。三个类别,它们挣到的权限不一样:
- 可撤销且后果轻。台灯、场景、影音、音箱音量。一次错误动作是一点烦躁,用相反的命令就纠正了。这是唯一一类挣得到「无人值守自主权」的设备,而它也恰恰是人们真正想要的大部分。
- 可撤销但后果重。恒温器、百叶帘、灌溉、电车充电。一次错误动作会在任何人注意到之前花掉钱、毁掉舒适,或者冻裂一根水管,因为反馈回路长达几小时。这里的自主权需要的是边界——一个温度区间、一个占空比、一份每日预算——而不是一个确认框。
- 不可撤销或承载安全。门锁、车库门、燃气与水阀、烤箱、任何涉医的东西,以及任何能把人放进这栋房子的东西。不给自主权。也不要藏在确认框后面:一个触发得够频繁的确认会变成条件反射,而真正要紧的那一次,长得和另外四十次一模一样。
平台已经开始替你强制执行第三类了——Google 的 Home MCP 干脆不暴露开门锁,而不是把它放在审批后面——这个形状值得照抄。拒绝暴露一项能力,是比给它设闸更强的管控,因为它不会被频次磨损掉。凡是你不得不暴露的地方,就要求一个不属于智能体的第二因素:一次物理按压、一次独立 App 确认、一个智能体手上没有的验证码。一般性论述见物理执行安全。
把类别写在设备记录上,不要写进提示词里。提示词层面的规则只有建议效力,在长会话里会被摘要磨掉;而挂在设备上的类别,会被你的工具包装层在每一次调用时检查一遍——包括第四十步那次没人复核过的调用。
你的动作空间是运行时发现的,所以策略必须写在 trait 上。
这是常规白名单会崩掉的那一段。家居平台通过能力 trait 来暴露设备,而某台设备上可用的命令,来自平台在你连接时报出来的一份 schema。某人在周二配对了一个 Matter 百叶帘,智能体的动作集合就长大了一圈——而你整条技术栈里没有发生过部署、复核或版本号变更。
- 在连接时与变更时枚举,然后分类。把资源清单拉下来,把每个 trait 映射到 STEP 1 的三个类别之一,并把这份映射带版本地持久化。映射才是你的策略物证;设备清单不是。
- 未知 trait 一律默认拒绝。一个你的分类器从没见过的 trait,并不默认是低风险的。它是「未分类」,也就是在有人给它分类之前不可用。正是这一条规则,拦住了一个新产品品类悄悄进入自主层。
- 给接口面做 diff,并在它变大时告警。「这个账号上出现了三个新 trait」是一件值得发通知的事,正如一条新的 IAM 权限。工具目录生命周期是它的一般性纪律;只不过这里目录变化的原因是有人去逛街了。
- 绝不要让模型来挑那份 trait 映射。在运行时问模型「这个动作安不安全」,等于把分类放进了那个正在被约束的东西内部。分类是一个有人参与的构建期决定。
物理世界没有事务。请建一份「读—改—验」的契约。
一个家里没有任何东西能回滚,而一条超时的命令处在未知状态,而不是失败状态。多数智能体技术栈把超时当作失败然后重试——车库门反复开合就是这么来的。
- 把命令表达成绝对目标,绝不要表达成相对增量。
set_temperature(20)是幂等的;turn_up_by(2)执行两遍就是另一栋房子了。这一条规则就能拿掉大部分重试损害——与幂等与重试是同一套论证,只是后果落在物理世界。 - 用一次观测来核验,而不是用命令的返回值。一个 200 的意思是平台受理了这次请求。设备到底做没做,是另一个问题,靠把状态读回来、并带一个有界的等待来回答。
- 超时之后,先读再重试。绝不要盲目重发。如果连状态读也读不到,就给用户抛出一个明确的「未知」然后停下——一句诚实的「我没能确认车库门已经关上」,比一份自信的总结值钱。
- 在一个场景内要按序执行,不要扇出。一次只应用了一半的批处理,会把这个家留在一个没人设计过的状态里。按既定顺序执行、逐步核验;中途停下就把这个中间状态如实报出来。
// Absolute target, explicit verification, unknown is a first-class outcome.
{ "action": "set_temperature", "device": "thermostat.hall", "target_c": 20 }
→ accepted
{ "verify": "read_state", "device": "thermostat.hall", "within_ms": 8000 }
→ { "setpoint_c": 20, "observed_at": "2026-09-19T18:04:11Z" } // confirmed
// Timeout path — do NOT re-issue the command.
{ "verify": "read_state", "device": "garage.main", "within_ms": 8000 }
→ { "status": "unknown", "reason": "device unreachable" } // tell the user, stop
事件历史才是那件敏感资产。把它当成一项成本来做预算,而不是当成一次查表。
家居平台的历史 API 会按你要的任意时间窗,返回历史状态变化与事件日志。每一行都无伤大雅——一盏灯亮了、检测到动静、一扇门开了。而这个集合是一份行为记录:家里什么时候没人、谁几点回家、哪几个晚上没人睡在这儿。任何白名单都拒不掉它,因为敏感的那个对象是模式,而模式是智能体自己推出来的结论。
- 在你自己的包装层里,于服务端给窗口设上限。默认以小时计。把更宽的查询做成一次独立的、有日志的、用户可见的请求。宽度上限是那道能扛住下游每一次失误的管控,而它只有几行。
- 带着明确目的去取,用完就丢。「为什么周二暖气开了一整天」需要的是周二,不是整个月。拉那个窄窗口、给出答案、然后丢掉它,别让它在这次会话剩下的时间里一直待在上下文里。
- 别让它进记忆,也别让它进摘要。一条从事件历史里派生出来的持久记忆写入,活得比那个为它正名的问题更久,而且不带归属。请显式地把历史工具的输出排除在记忆抽取之外——这是少数几个「一刀切排除」是对的场合之一。
- 搞清楚你的留存链条。历史一旦进了上下文窗口,它就在你的 trace 里、在你提供方的日志里、在任何一次调试导出里。决定这些系统该不该存着它;不该的话就在边界上做脱敏——见智能体 trace 中的 PII 脱敏。
- 当问题本身是一个模式时,优先给聚合值。如果用户想知道「我是不是暖气开太多了」,那就算出来、把那个数字返回去。别把原始日志递给模型,再请它自己看出来。
把来自这个家的每一个字符串都当成不可信输入,从设备名开始。
现实中的失陷不是一个怀有恶意的智能体。而是一个正确的智能体读到了别人写的文本——而一个家在生产这种文本上出奇地在行。
- 设备名与房间名是攻击者可供的。任何能在这个账号上添加或重命名设备的人,都控制着一段会落进智能体上下文的字符串——一位客人、一个装修工、一个前住户、一个被攻陷的第三方集成。把名字当数据渲染,绝不当指令:放在带分隔符的字段里、剥掉控制字符、限制长度,并且绝不要把它插值进一条系统级指令。
- 摄像头与门铃的事件摘要是模型输出。一段描述摄像头看到什么的文字,是生成出来的;而产出它的那个模型,压根不知道自己的输出会被一个握有执行工具的东西当作事实来读。这是一条两层模型的供应链;把上游那个当作不可信来源。对应的模式是把遥测当作不可信输入。
- 默认注入与踩点是一起到的。那条可能承载注入指令的连接,同时也承载着这户人家的作息表与命令接口面。设计上要做到:一次成功的注入根本够不着第三类设备——而只要 STEP 1 的分类是在你的包装层、而不是在提示词里强制执行的,它就够不着。
- 凡是影响过某个动作的东西,都把溯源记下来。当智能体因为某条事件而行动时,记下是哪条事件、来自哪台设备、什么时间戳。六周之后重建「凌晨三点灯为什么亮了」是常态而不是例外——见审计轨迹。
一个家是多人的;一份 OAuth 授予不是。请为那些从没看见过同意屏的人做设计。
这是多数团队发现得最晚的那条需求,而它没有纯技术的解法。一个账号持有人授权了这次集成。住在这栋房子里的其他每一个人——伴侣、孩子、合租室友、客人、护理人员、保洁——都被传感器记录着、也在那份历史里被表征着,而他们谁都没同意让一个第三方智能体去读它。
- 让授予比账号更窄。只把最小必要的设备共享给智能体所用的那个身份,并且除非某项功能确实需要,否则把摄像头挡在外面。爆炸半径的单位是那份授予,那就把授予做小——把爆炸半径用在一栋房子上。
- 记下授予了什么、由谁授予、何时授予,以及怎么撤销。一条真正跑得通、且被测试过的撤销路径,比一个没人打开的细粒度权限界面值钱。物证部分见委托访问与同意记录。
- 不要让智能体回答关于人的问题。「我女儿昨晚在家吗」在技术上是一次历史查询,在实质上是监视。请刻意地把这条策略定下来,并把它实现成对查询形状的一次拒绝,而不是对模型的一份指望;同时给这次拒绝一个理由。
- 要在家里披露,而不只是在 App 里披露。如果一个智能体能动手或能观察,住在这里的人应当无需持有账号就能知道这件事。一个可见的状态——一盏灯、显示屏上的一张卡片、每月发给全家的一份小结——是这套架构所能提供的、最接近「同意」的东西。
- 为住户会变动这件事做好准备。人是会搬走的。一个握有常设权限、又记着前住户作息的智能体,是一个叫得出名字的问题;请让账号成员变更触发一次记忆与历史的清除。