2026年10月,报名参加Datawhale当月组队学习里的共学,从0开始入门、了解jev,本篇记载我的 Task05 学习笔记,主要内容是智能家居实验。
【教程地址】https://github .com/datawhalechina/jev-cookbook
Task 05 智能家居实验
上一篇我们把 18 个实战 Notebook 按四条路线梳理了一遍,而这一篇的智能家居实验室,就是这条路线最完整的一次工程落地:从一句自然语言指令进来,系统要判断意图、识别设备、决定动作,还要处理复合命令和知识问答,但每一步都不是让 LLM 自由发挥,而是用 Jev 在代码预先画好的边界里做选择题。
场景:实验用一个 Three.js 搭的 3D 房子做模拟器:5 个房间(客厅、厨房、书房、卧室、玄关),11 个设备(5 盏灯、1 台风扇、1 个音箱、1 台咖啡机、2 把门锁)。用户在输入框里说"把咖啡烧上",右侧面板会把整条决策链展开,咖啡机随即亮起来。
支撑这个演示的有三块代码:
01_智能家居实验.ipynb:核心实验,验证 Jev 三种用法——投机提问、复合命令拆分、路由守卫。serve_smart_home.py:一个本地代理服务,把 Jev 的 typesafe 接口、ASR(语音识别)、传统 LLM 聊天统一封装成 HTTP 接口,顺便解决浏览器跨域和密钥不能暴露在前端的问题。smart_home_playground.html:3D 交互页面,支持"Jev 投机 / 传统 LLM / 双路对比"三种管线切换,还能接麦克风语音输入。
健康检查会告诉你当前配了哪些能力:jev=true, asr=false, chat=false表示只有 Jev 可用,语音和聊天模型没配 key——这时候页面会自动降级到本地模拟,不影响看决策流程。
核心实验一:投机提问——一次调用问完所有问题
智能家居最朴素的做法是串行:先问意图,再问设备类别,再问动作,一问一答好几轮;但每多一轮调用就多一次网络往返和一次出错概率。所以这一篇的第一个实验就是把所有可能要问的问题打包进一次/v1/systemone调用,让 Jev 一次性回答。
拿"把咖啡烧上"举例,一次调用里塞了 6 个 question:意图判断、是否复合、设备类别、以及五种设备各自的动作预测(灯/风扇/音箱/电器/门锁)。关键代码长这样:
questions = [ {"name": "intent", "type": "choice", "instructions": "判断用户意图", "criteria": ["smart_home_command", "information_request", "ambient"]}, {"name": "is_compound", "type": "noul"}, {"name": "category", "type": "choice", "criteria": ["light", "fan", "speaker", "appliance", "lock"]}, {"name": "light_action", "type": "choice", "criteria": ["turn_on", "turn_off", "leave_unchanged"]}, {"name": "appliance_action", "type": "choice", "criteria": ["turn_on", "turn_off", "leave_unchanged"]}, # ...风扇、音箱、门锁同理 ]真实 API 实测(上游耗时 777 ms)返回的结果是:
question | 结果 | top 概率 | 是否采纳 |
intent | smart_home_command | 1.00 | ✅ |
is_compound | 否 | 0.09 | 剪枝(投机) |
category | appliance | 1.00 | ✅ |
appliance_action | turn_on | 1.00 | ✅ |
light_action | leave_unchanged | 0.97 | 剪枝(投机) |
lock_action | leave_unchanged | 0.97 | 剪枝(投机) |
Jev 老老实实把 6 个问题都答了,但代码只采纳 category 对应的那个设备动作。咖啡机的指令里,灯和门锁的动作虽然也被预测为"不变",但这是投机算出来的,因为代码端知道主目标是 appliance,就把其他分支直接剪掉,根本不进入后续执行逻辑。
这就是"投机提问"的精髓:用一次调用的成本,换来所有分支的答案;用代码的领域知识,决定哪些答案该被当真。零额外往返,也没让 Jev 承担它不该承担的编排责任。
核心实验二:复合命令——Noul 判断、小模型拆分、依赖排序
"关掉厨房的灯,然后锁上书房的门"这种一句话两个动作的指令,投机提问就不够用了——需要先判断是不是复合命令,再拆成子任务,还要保证顺序。
实验分三步:
Noul 判断是否复合:Jev 用
noul原语回答"是/否"。如果是复合,进入拆分流程;如果不是,走单命令的投机分支。小LLM拆分:让一个轻量模型把复合句切成原子指令列表,例如
[{"room": "厨房", "device": "light", "action": "turn_off"}, {"room": "书房", "device": "lock", "action": "lock"}]。依赖排序与并行/串行:用
noul判断子任务之间有没有"必须先后"的依赖关系。有依赖就串行执行,没有就并行。
这里的理论根基是偏序(partial order)和幂等性:每个动作带action_id做幂等去重,失败时回滚已完成的动作,避免半执行状态。README 里明确说了一条纪律——复合命令的执行顺序、权限校验、失败补偿都由代码负责,Jev 只做"这是不是复合""这两个动作有没有依赖"这种语义判断。
核心实验三:路由守卫——常识问题别让 Jev 硬猜
用户可能突然问一句"1989 年世界大赛冠军是谁?"。这不是设备控制,让 Jev 硬猜只会瞎编。路由守卫的做法是:
Jev 把意图判成
information_request;代码检测到这个意图,直接把请求转发给通用 LLM(如
step-5-preview)回答;确定性的设备控制走 Jev,开放性的知识问答走 LLM。
页面里还有个"双路对比"模式,同一句话同时跑 Jev 投机管线和传统 LLM 管线,面板上并排展示两边的耗时、token、决策路径。实测下来,Jev 管线因为是结构化选择,速度更快、结果可预测;LLM 管线更灵活但成本高、输出不稳定。这个对比本身就是实验的一部分——不是为了证明谁更强,而是让你看到什么场景该用谁。
服务端与前端:为什么要套一层代理
serve_smart_home.py本身没什么魔法,就做了四件事:
/api/jev:转发到 typesafe 的 systemone 接口;/api/asr:SSE 流式转发 stepfun 的语音识别,麦克风音频边录边出文字;/api/chat:转发到 stepfun 聊天模型;/api/health:返回当前配了哪些 key。
套这层代理有两个原因:一是浏览器直接调第三方接口会跨域;二是 API key 绝对不能写在前端 HTML 里。如果TYPESAFE_API_KEY没配,页面会自动降级到本地模拟模式,让你不花一分钱也能看完整个决策流程。
前端的 3D 场景和右侧决策追踪面板是演示的核心。你说一句话,右侧会按顺序展示:耗时阶梯 → 意图 Choice → 复合 Noul → 投机提问列表 → 最终动作 JSON。整个决策链透明可查,这是和传统 LLM 黑盒输出最大的区别。
如果说前面的实战 Notebook 是在练"单项动作",智能家居实验室就是把这些动作串成一套能跑的流程。它最值得带走的一句话是:Jev 只做它擅长的语义判断,执行链路上的设备白名单、动作映射、顺序编排、失败补偿,全都是代码的活。这条边界划清楚了,你的智能家居系统才不会因为模型一次幻觉就把门锁打开。
学习总结
以上就是这次组队学习所有的任务学习,以下分享我的学习心得。
模型不是执行者,是判断者
学之前总觉得大模型应该"端到端"地把活干了,给一句话,直接吐出执行结果。但 Jev 把这个边界划得很死:模型只输出概率,不做任何执行动作。"转人工""开锁""退款"这些事,由业务代码直接完成。
这个划分乍看是限制,实际是保护。模型的概率是群体统计意义上的校准值,单次调用哪怕 0.99 也可能翻车。把执行权留在代码手里,才能配上阈值、人工兜底、回滚补偿这些真正能兜底的东西。智能家居实验里那句"把咖啡烧上",Jev 只负责说"我觉得是开电器",真正去操作咖啡机的是代码,这种分工让我对"AI 应用"的架构有了更务实的理解。
投机提问是性价比最高的一招
第三章讲架构模式时看到"投机扇出",第五章智能家居一用就懂了:一次调用把意图、设备类别、五种设备的动作全问了,花一轮调用的钱,拿到所有分支的答案,再用代码的领域知识剪掉无关分支。
它没有追求"让模型更聪明",而是在调用成本和信息完备性之间找到了最优解。模型多答几个问题的边际成本很低,但能省掉好几轮往返。工程优化没有去刷模型能力,而是在调用方式上做文章。
结构化处理是对抗幻觉的根本办法
第四章把 18 个实战 Notebook 归成四条路线,其中"结构化处理"这条线让我印象最深:代码先把候选范围定死(比如设备只能是灯/风扇/音箱/电器/门锁,动作只能是开/关/不变),再让 Jev 在这个有限集合里做选择。
这其实是在用工程手段约束模型的自由度。LLM 自由生成容易跑偏,但如果让它在你给的选项里挑,正确率和可控性都会上一个台阶。所谓"Prompt Engineering",很多时候不是写更花哨的提示词,而是设计更合理的选择题。
校准思维是一种工程素养。
第一章讲校准,说概率 0.8 意味着长期频率约 80%,不保证单次正确。这句话看似平淡,实则是整个 Jev 体系的地基。
过去容易把模型输出的置信度当成"正确率"来用,看到 0.95 就放心执行。但校准告诉你:这只是个统计量。高风险场景(金融、医疗、智能家居里的门锁)必须设阈值、必须有 fallback、必须能人工接管。把"概率"和"确定性"分开,是从"用模型"到"用好模型"的关键一步。
这五章学下来,最大的收获是建立了一套务实的 AI 应用观: 让模型做它擅长的语义判断,把确定性、安全性、可维护性留给代码和工程流程 。Jev 不是来替代工程师的,而是把工程师从"写一堆 prompt 调参"里解放出来,去设计更稳健的系统边界。