拆解官方智能家居 demo:从意图到设备动作
先说结论
- 这个 demo 不是“大模型直接控制设备”,而是用 TypeSafe 的 System One 模型先做一组窄而结构化的判断:请求类别、作用域、设备类型、动作;代码再根据这些答案决定是否执行设备动作,官方原句是“a smart home assistant that uses TypeSafe to evaluate user requests”。
- 它的核心模式是 speculative fan-out:即使不知道用户会请求什么,也一次性并行评估大量可能相关的问题,让代码事后过滤不相关结果;官方明确说顺序 API 调用“much slower and more expensive”。
- demo 里明确用 Noul 类型判断“是否复合请求”,再调用 LLM 把复合请求拆成原子命令;当用户是通用对话或信息查询时,回退到 LLM 生成自由回复。
- Choice、Score、Noul 三种原语分别返回
choice/probabilities/confidence、score/legend/probabilities/confidence、noul (0 to 1);官方建议用概率和置信度决定“执行、人工复核或升级”,但具体阈值是工程选择。 - 把这套思路搬到客服工单分派是可行的类推,但不是官方示例;核心是先把设备/动作集合或工单/处理动作集合枚举清楚,并显式设计失败/回退路径。
证据与过程
官方 demo 到底演示了什么
我先把官方页面第一句话摆出来。在 Smart home assistant demo 页面,官方写的是:
“Demo code: a smart home assistant that uses TypeSafe to evaluate user requests.”
这句话可以理解为:demo 展示的并不是一个能自由聊天的助手,而是一个用 TypeSafe 评估用户请求、再交给代码执行的软件工作流。它更接近 How to build with TypeSafe 文档所说的“AI-powered software”:代码拥有控制流,模型只做窄判断。官方原文说:
“System One is TypeSafe’s model for building AI-powered software, not agents. It does not generate code or choose its own next action. It provides AI primitives that embed into software, so code remains in control while the model handles common-sense judgments over unstructured data.”
也就是说,这个 demo 演示的是“代码在控制流里,模型在圈内做判断”的结构,而不是让智能体决定下一步动作。
一次请求的链路:从意图到设备动作
官方 demo 页面给了具体例子,用户说:
“Turn off all of the lights in the house”
要处理这个请求,只需要四个问题的答案:
- “What category of request is this?” →
smarthome command - “What domain is this request targeting?” →
whole house - “What type of device is this request targeting?” →
lights - “What action should be taken on the lights?” →
turn off
注意,最后一个问题“对灯执行什么动作”在还不知道用户请求的是什么之前就被提出来了。官方把这种问题称为 speculative question,并解释:
“we ask it before we even know if it’s relevant, allowing us to evaluate all questions in parallel and rely on code to filter out the irrelevant results after the fact.”
所以实际链路是:用户意图 → 并行问很多可能相关的问题 → TypeSafe 返回每个问题的结构化答案 + 概率/置信度 → 代码筛掉无关问题、组合相关答案 → 执行设备动作。路由不由模型直接决定,而是由代码根据一组判断结果决定。这种“判断/路由”是代码主导的。
关键设计点:Choice、Noul、Score 分别干什么
demo 页面本身没有逐条列出每个问题用的是 Choice、Score 还是 Noul,但明确提到了 Noul 的一个用法:判断用户请求是否包含多个不同动作。官方原文:
“One of the questions in this demo is a Noul question identifying if the user request is asking for more than one distinct action. If this is true, the system uses an LLM to split the request into a list of atomic commands. The split requests are then evaluated by TypeSafe individually.”
Noul 在 Primitives (Questions) 文档中的定义是回答“这个说法是真的吗?”,返回 noul 值(0 到 1)。这正是复合请求判断所需的是/否答案。
至于 Choice 和 Score,demo 页没有像 Noul 那样给出具体示例问题,但根据 Primitives 文档,它们的分工很清晰:
| 类型 | 回答的问题 | 返回 |
|---|---|---|
| Choice | Which of these options? | choice, probabilities, confidence |
| Score | Which level? | score, legend, probabilities, confidence |
| Noul | Is this true? | noul (0 to 1) |
在智能家居这种场景,类别、域、设备类型、动作这类判断天然适合 Choice,因为它们都是从一个已知集合里选一个;如果要对紧急程度、温度偏好等做等级判断,则可能用到 Score。但这是我从 Primitives 文档做的推断,官方 demo 页面没有把每个问题的类型逐项披露。我在文末再标一次未能核实。
置信度不足时怎么办?官方 how-to 文档的建议是:
“Use probabilities and confidence to act, ask for review, or escalate.”
这是一个通用原则,不是具体阈值。demo 页给出的一个路径是当 TypeSafe 判断用户请求是通用信息或对话时,系统调用 LLM 生成自由回复。官方原文:
“When TypeSafe determines that the user query is a request for general information or conversation, the system calls an LLM to generate a freeform response.”
这里要注意:官方说的是“判断为通用信息或对话”时回退 LLM,并没有说“置信度低于某值就回退 LLM”。实际工程中,开发者可以根据 Choice 返回的 confidence 或 Noul 的 noul 值自行设定门控,比如低置信度时走人工确认或 LLM 兜底;这是实现选择,不是官方明示的阈值规则。下面是一个实践中的分支示意:
# 工程上的一个分支示意(伪代码,非官方代码;阈值为示意值)
def handle_smarthome(user_request, answers):
# answers 是 TypeSafe 返回的带概率/置信度的结构
if answers["category"].choice == "general_info":
return llm_freeform_reply(user_request)
if answers["is_compound"].noul > 0.7:
atomic_requests = llm_split_compound(user_request)
return [handle_smarthome(r, evaluate(r)) for r in atomic_requests]
if answers["action"].confidence < 0.6:
return ask_for_review()
return execute_device_action(answers)
与通用助手方案的对比
这是本文自己的分析,不是官方直接对比。
通用 LLM 助手最常见的做法是:把用户语音/文本直接发给大模型,模型生成一段自然语言回复,比如“好的,我已关闭所有灯”。如果要对接设备,还需要从回复里解析意图和参数,或者再套一层函数调用。这种方案的好处是对话体验自然,能处理边界问题;缺点是每次都要生成一段文本,延迟、成本和可测性不如返回结构化字段。
这个 demo 的方案正好相反:大多数请求在第一次 TypeSafe 调用中就走完结构化判断,代码直接得到 category、domain、device_type、action 这样的字段,不需要解析自然语言。只有当需要拆复合请求或回退到对话时,才调用 LLM。官方在 demo 页也强调这种配合的好处:结构化判断先行,生成式 LLM 只在需要字符串生成时介入。这种结构的好处是可测试、可追踪、可针对每个问题单独调优。
延迟方面,How to build with TypeSafe 给了一个关键官方数据:
“Most queries complete in about 100 ms. System One is fast enough for real-time request paths and user interfaces.”
这是官方数据。但它没有给出该 demo 端到端延迟的实测值,所以不能把它等同于“智能家居 demo 总延迟 100ms”。demo 页只说 TypeSafe 响应比 LLM 响应快很多,没有给出具体数字。这个对比是我根据官方架构描述和 100ms 数据做的合理推断,不是官方实测。
移植到别的场景要注意什么
如果要把它搬到客服工单分派、维修工单、销售线索路由等场景,第一个门槛是设备/动作集合必须枚举清楚。这不只是经验之谈,Primitives 文档对 Choice 类型的说明就要求给全选项,并建议在可能覆盖不全时加 other 或 none of the above 选项。官方原文:
“Choice fits when the answer is one of a known set of options with no order between them: routing a ticket to a department, classifying a document type, detecting a programming language. Give the full list of options, and add an
otherornone of the aboveoption when the list might not cover every input.”
这里其实已经点出“routing a ticket to a department”这种工单场景。所以把 smart home 的思路类推到工单分派,底层模式是相通的。
第二个门槛是失败路径要显式设计。官方 how-to 说“Use probabilities and confidence to act, ask for review, or escalate”,这意味着代码需要预先定义:高置信度直接执行、中置信度进入人工复核、低置信度走 LLM 兜底或转人工。不能等模型给出意外结果后再打补丁。在 demo 中,失败/兜底路径之一就是 LLM 回退;在工单场景中,对应的是“非结构化咨询转知识库或人工客服”。
类推:客服工单分派最小映射表
以下映射是我自己的类推,不是官方示例。它借用了 Example use cases 中 Customer support 类别的一些官方描述,例如“Classify incoming tickets by issue, product area, and customer intent”和“Route cases to the right team, queue, or automated workflow”。
| 智能家居 demo | 客服工单分派 |
|---|---|
| 用户请求:“Turn off all lights” | 客户提交工单:“无法登录账号” |
| Choice: category → smarthome command | Choice: issue_type → login / billing / bug_report |
| Choice: domain → whole house | Choice: product_area → account / payment / mobile_app |
| Choice: device_type → lights | Choice: module → authentication / checkout / push_notification |
| Choice: action → turn off | Choice: action → reset_password / refund / escalate |
| Noul: 是否复合请求?若真,LLM 拆成原子命令 | Noul: 是否一个工单含多个问题?若真,按问题拆分 |
| TypeSafe 判断为通用信息/对话 → LLM 自由回复 | TypeSafe 判断为非结构化咨询 → 知识库或人工坐席 |
这个表只覆盖最小路径。真正落地时要按照自己的产品和业务把 criteria 细化,不能直接照搬。
自己的判断与清单
这套方案最适合满足以下条件的场景:
- 请求意图可以用有限集合覆盖;
- 错误路径的代价可见,且可以预先定义;
- 希望避免每次请求都产生长文本生成的延迟和成本;
- 需要强可测性:每个窄问题能单独回归、单独设阈值。
不适合的场景包括:意图太开放、需要多轮推理、用户期望自由对话、动作集合经常变且难以枚举。
落地前可以做一个清单:
- 列出所有可能意图和动作,形成 Choice 的 criteria。
- 为每个 Choice 定义保守选项
other或none_of_the_above。 - 确定需要 Noul 的判断点,比如“是否包含多个动作”“是否要求人工处理”。
- 确定置信度/概率的读取点,并用代码显式分支:执行、复核、升级。
- 设计 LLM 兜底条件,明确什么时候回退到自由文本,避免无效兜底。
这次没核实的
- demo 页没有给出 Choice 和 Score 的具体配置清单,只明确提到 Noul;具体哪些问题用 Choice、哪些用 Score,需要等官方 GitHub release 源码或运行 demo 确认。
- demo 页没有提供端到端延迟、成本、准确率等实测数据;官方提到“Most queries complete in about 100 ms”是 System One 模型层面数据,不是该 demo 的总延迟。
- demo 页面说“The full source code will be available on GitHub at release”,但我未能核实当前是否已经放出完整代码。
- “Machine Native Intelligence”这个术语在我引用的几个页面里没有直接出现,因此本文没有把它写成 demo 的官方主张表述,而用“AI-powered software”相关原句替代。
参考来源
评论区
登录后可评论。