AI PC驱动智慧家庭:从端侧推理到本地场景联动实战 1. 背景AI PC 与智慧家庭为什么走到了一起1.1 从联想 × 海尔合作说起近期联想集团与海尔集团签署了战略合作协议宣布围绕联想 AI PC 与海尔智慧家庭场景展开深度融合。这条新闻看似只是商业层面的一次握手但站在开发者视角它背后其实是一个非常明确的技术趋势AI PC 不再只是一台性能更强的电脑它正在向“家庭场景中的本地算力中心”转变而智慧家庭设备则成为这个算力中心可以调度的执行单元。联想 AI PC 的核心特征是“端侧 AI”也就是在本地完成推理不依赖云端算力。海尔智慧家庭则积累了大量的家居设备控制能力覆盖安防、空气、用水、饮食等多个生活场景。两者的结合本质上是把“会思考的电脑”和“能执行的家居设备”连接成一套完整的闭环系统。对于正在做物联网、智能家居或者端侧 AI 应用的开发者来说这种合作模式提供了一种非常典型的落地范本本地算力如何与家庭设备协同端云任务如何划分设备协议如何统一。1.2 AI PC 到底是什么AI PC 是指集成了专门 AI 加速硬件NPUNeural Processing Unit神经网络处理单元的个人电脑。与传统 PC 相比它具备三个非常显著的特征。第一是本地推理能力。AI PC 可以在不联网的情况下运行大语言模型、图像识别、关键词唤醒等 AI 应用推理过程全部发生在本机。第二是低功耗持续感知能力。NPU 的能效比远高于 CPU 和独立显卡适合长时间运行语音唤醒、环境感知这类“常驻型”任务不会造成明显的发热和耗电问题。第三是隐私保护能力。因为数据不出本机用户的语音、文本、家庭作息习惯等敏感信息不需要上传到云端从源头降低了隐私泄露的风险。这里需要把这个概念和普通“预装了 AI 软件的电脑”区分开。真正的 AI PC 必须有硬件级的 AI 算力支持NPU 是核心标志之一。没有 NPU 的电脑虽然也能跑 AI 软件但性能和功耗表现完全不同尤其是在长时间后台运行的场景下差距非常明显。1.3 智慧家庭的现状与痛点智慧家庭这个概念已经发展了多年但很多用户家里的设备并没有真正“智慧”起来。从开发者的角度看当前智慧家庭领域存在三个非常核心的痛点。第一是控制碎片化。灯具、空调、窗帘、电视往往来自不同品牌每个品牌都有自己的 App、账号体系和交互逻辑。用户想实现一个跨品牌的场景联动需要同时维护多个控制端体验非常割裂。第二是智能程度有限。大多数场景停留在“定时触发”或“简单联动”阶段比如日落开灯、湿度升高就打开除湿机很难做到真正理解用户意图更谈不上主动服务。第三是数据处理方式单一。很多智能家居设备依赖云端 AI 判断导致响应存在明显延迟而且在网络不稳定或者断网时设备控制能力会大打折扣。AI PC 进入智慧家庭场景之后恰好可以针对性地解决这三类问题。它作为家庭内的本地算力节点可以做统一交互入口运行跨设备场景引擎还能承载本地大模型做更自然的意图理解。这也是联想与海尔这次合作在技术层面最大的想象空间。2. 融合落地的整体技术架构2.1 四层架构模型联想 AI PC 与海尔智慧家庭的融合从技术角度可以拆解成四个层次。每一层职责单一层与层之间通过标准接口通信这样无论是做原型验证还是生产级落地结构都比较清晰。层级核心职责代表组件交互层接收语音、文本、按键等输入完成基础识别本地语音模型、意图识别引擎决策层理解用户意图结合设备状态编排场景动作场景引擎、规则引擎、端侧大模型连接层完成设备发现、指令下发、状态上报MQTT、Matter、Wi-Fi、蓝牙 Mesh设备层末端执行设备真正完成物理动作灯具、空调、窗帘、安防传感器这四层并不是简单的单向调用。交互层产生意图后交给决策层决策层根据当前设备状态和用户习惯生成指令序列再通过连接层下发到设备。设备执行完毕后反过来把状态变化上报到连接层决策层收到状态后更新本地快照整个流程形成闭环。这个闭环设计决定了系统是“死板的遥控器”还是“真正的智能家庭大脑”。2.2 端云协同的分工需要明确的一点是AI PC 加智慧家庭并不等于要把所有计算都放在本地。更合理的做法是端云协同各自承担适合自己的任务。本地负责实时性要求高、隐私敏感的任务比如语音唤醒、家庭成员回家判断、本地场景联动、关键词指令识别。云端负责需要大规模模型参数支撑的复杂任务比如多轮自由对话、开放域知识问答、复杂场景的语义理解。这里有一个关键设计原则默认本地按需云端。只要本地模型能处理的需求就不要把数据送到云端。这样既能保证响应速度也能大幅降低隐私风险。在联想与海尔合作的场景里这个原则特别重要因为家庭环境中的语音数据、设备状态数据都非常敏感能留在本地处理就尽量留在本地。2.3 互联互通协议怎么选设备互联是智慧家庭融合最现实的一步也是开发者最先接触到的技术选型问题。当前主流方案主要有三类。MQTT 是物联网场景中使用最广泛的轻量消息协议适合设备状态上报和指令下发需要依赖一个 Broker 消息代理对局域网和云端都支持生态成熟客户端库丰富。Matter 是智能家居行业推动的统一应用层标准目标是打破品牌壁垒如果设备支持 Matter理论上可以跨品牌直接互通。品牌私有协议则是海尔智家等平台长期积累的协议体系通常在自家设备生态内表现最稳定但对外部开发者不够友好。实际落地中建议采用“MQTT 适配层”的组合方式。下层屏蔽品牌差异把不同协议设备统一抽象成标准设备模型上层业务只面向设备和场景不关心底层具体协议是什么。这种方式扩展性最好后续无论接入新品牌还是新协议都不需要改动核心逻辑。3. 环境准备搭建 AI PC 智慧家庭开发环境3.1 硬件与系统要求开发调试环境的硬件配置建议如下实际可以根据手头设备灵活调整。CPU 建议使用支持 AVX2 指令集的 x86 处理器目前主流的 AI PC 一般搭载 Intel Core Ultra 或 AMD Ryzen AI 系列这两类处理器都集成了 NPU。内存方面 16GB 起步如果要在本地运行 7B 参数级别的大模型建议直接上 32GB。NPU 主要用于加速模型推理开发阶段可以通过任务管理器或厂商提供的工具查看 NPU 的占用情况确认模型是否真正跑到了 NPU 上。操作系统方面Windows 11 和 Ubuntu 22.04 LTS 都可以Windows 下可以配合 WSL2 使用调试 Linux 环境下的 IoT 工具链会更方便。版本需要根据你的项目实际情况调整本文示例以常见环境为例重点是演示技术思路不绑定某个厂商的固定版本。3.2 开发工具链本文实战项目主要依赖以下工具链Python 3.10 及以上版本paho-mqttPython 的 MQTT 客户端库onnxruntime本地模型推理引擎Flask用于搭建本地 REST 控制服务Mosquitto本地 MQTT Broker模型转换工具如需在 NPU 上推理需要把 PyTorch 或 TensorFlow 模型转换为 ONNX 格式安装命令示例# Ubuntu/Debian 或 WSL2 环境 sudo apt update sudo apt install -y mosquitto mosquitto-clients # Python 依赖 pip install paho-mqtt onnxruntime flask这里要提醒一个细节Mosquitto 默认只监听 localhost如果希望局域网内的设备都能接入 Broker需要修改监听地址以及访问认证配置。开发调试阶段可以先放开限制但生产环境必须配置账号密码和 TLS 加密后面会在安全相关章节详细说明。3.3 示例项目结构为了让后续实战部分更清晰这里先定义一下项目的目录结构。这个结构虽然简单但体现了很好的分层思想后续扩展新设备、新场景时不需要改动整体架构。smart-home-hub/ ├── src/ │ ├── main.py # 主入口启动控制中心 │ ├── device/ │ │ ├── mqtt_client.py # MQTT 设备接入层 │ │ └── model.py # 设备数据模型 │ ├── nlp/ │ │ ├── intent_engine.py # 意图识别规则引擎 │ │ └── llm_local.py # 本地模型推理入口 │ ├── scene/ │ │ └── scene_engine.py # 场景联动引擎 │ └── api/ │ └── app.py # 本地 REST API ├── config/ │ └── settings.yaml # 配置文件 └── requirements.txt目录分层对应前面的四层架构device 负责连接层nlp 负责交互层scene 负责决策层api 是对外暴露的服务入口。理解了这个映射关系后面写代码时就知道每个文件该放在哪一层、该承担什么职责。4. 实战在 AI PC 上构建智慧家庭控制中心4.1 需求拆分本文的示例项目做一个“智慧家庭控制中心”核心能力包括四个方面。第一通过 MQTT 接入家庭设备实时接收设备状态上报。第二接收用户的文本指令解析出意图和参数。第三根据意图执行对应的设备操作或者场景联动。第四通过简单的 REST 接口对外提供控制能力方便前端或其他系统调用。整个项目不追求完整商用核心是把“交互层 → 决策层 → 连接层 → 设备层”这条链路完整打通。这个链路一旦跑通后续无论加什么设备、加什么场景都是在这个骨架上做扩展。4.2 设备接入层MQTT 消息通道先实现设备接入层。这里假设家中设备通过 MQTT 上报状态状态主题格式为home/{房间}/{设备}/state指令主题为home/{房间}/{设备}/command。主题命名一旦确定尽量不要频繁改动因为所有设备和场景逻辑都依赖这个约定。# 文件路径src/device/mqtt_client.py import json import paho.mqtt.client as mqtt BROKER_HOST 127.0.0.1 BROKER_PORT 1883 STATE_TOPIC home///state class DeviceGateway: def __init__(self, on_state_change): self.on_state_change on_state_change self.client mqtt.Client(mqtt.CallbackAPIVersion.VERSION2) def _on_connect(self, client, userdata, flags, reason_code): if reason_code 0: print(MQTT 连接成功等待设备上报状态) client.subscribe(STATE_TOPIC) else: print(fMQTT 连接失败{reason_code}) def _on_message(self, client, userdata, msg): topic msg.topic payload json.loads(msg.payload.decode(utf-8)) # topic 示例home/living_room/light/state parts topic.split(/) if len(parts) 4: room, device parts[1], parts[2] self.on_state_change(room, device, payload) def start(self): self.client.on_connect self._on_connect self.client.on_message self._on_message self.client.connect(BROKER_HOST, BROKER_PORT, keepalive60) self.client.loop_start() def send_command(self, room, device, command): topic fhome/{room}/{device}/command self.client.publish(topic, json.dumps(command, ensure_asciiFalse)) print(f下发指令{topic} - {command})这段代码里有几个值得注意的设计。loop_start()会启动一个后台线程循环处理 MQTT 消息因此主线程可以做其他事情比如同时启动 REST API。消息回调中做了主题解析把home/living_room/light/state解析成 room、device 和 payload这样上层拿到的是结构化数据而不是需要自己再去切分原始字符串。send_command方法统一封装了指令下发逻辑业务层不需要关心 topic 是怎么拼的只需要告诉方法“哪个房间的哪个设备执行什么命令”。这也是分层设计带来的直接好处。4.3 意图识别规则与本地模型相结合设备接入之后接下来的核心问题是用户说了一句话系统怎么知道要干什么。在 AI PC 场景中最理想的方案是使用本地大模型做完整意图识别但考虑到工程落地的成本和响应速度更务实的做法是“规则优先 模型兜底”的组合方案。先用正则规则覆盖高频指令。这类指令结构简单、重复度高用规则匹配准确率非常高而且响应几乎是零延迟不消耗 NPU 算力。# 文件路径src/nlp/intent_engine.py import re RULES [ (r(打开|开启).{0,4}(灯|照明), light_on), (r(关闭|关掉).{0,4}(灯|照明), light_off), (r空调.{0,6}(\d{2})度, ac_set_temp), (r(回家|到家).{0,3}(模式)?, scene_home), (r(睡觉|睡眠).{0,3}(模式)?, scene_sleep), (r(温度|湿度).*多少, query_env), ] def parse_intent(text: str) - dict: for pattern, intent in RULES: if re.search(pattern, text): match re.search(r(\d{2}), text) params {} if match and intent ac_set_temp: params[temperature] int(match.group(1)) return {intent: intent, params: params} return {intent: unknown, params: {}}这段识别逻辑不复杂但已经覆盖了灯具开关、空调调温、场景切换和环境查询几个最核心的家庭场景。parse_intent返回统一结构包含 intent 和 params后续场景引擎可以直接消费不需要再关心文本细节。对于规则覆盖不到的长句、口语化表达可以再接入本地大模型做兜底。AI PC 上的 NPU 可以加速这种推理代码层面可以使用 ONNX Runtime 加载量化后的模型# 文件路径src/nlp/llm_local.py核心片段 import onnxruntime as ort # 优先使用 OpenVINO 加速CPU 兜底 providers [OpenVINOExecutionProvider, CPUExecutionProvider] session ort.InferenceSession(intent_model.onnx, providersproviders) def classify_intent_with_model(text: str) - str: inputs tokenize(text) outputs session.run(None, inputs) return postprocess(outputs)需要说明的是这只是示例思路实际的 tokenize 和 postprocess 逻辑需要根据你选用的模型来编写。模型转换到 ONNX 之后务必在目标机器的 NPU 上验证推理速度和精度不能默认“转换成功就等于能跑满 NPU 算力”。4.4 场景联动引擎有了设备接入和意图识别接下来就是决策层。场景引擎负责把“用户意图”翻译成“设备指令序列”这是整个控制中心最核心的模块。# 文件路径src/scene/scene_engine.py class SceneEngine: def __init__(self, gateway): self.gateway gateway self.state {} def update_state(self, room, device, payload): self.state.setdefault(room, {})[device] payload print(f当前设备状态{self.state}) def execute(self, intent: str, params: dict): if intent light_on: self.gateway.send_command(living_room, light, {action: on}) elif intent light_off: self.gateway.send_command(living_room, light, {action: off}) elif intent ac_set_temp: temp params.get(temperature, 26) self.gateway.send_command(living_room, ac, {action: set_temp, value: temp}) elif intent scene_home: self._coming_home() elif intent scene_sleep: self._sleep_mode() else: print(未识别意图暂不执行任何操作) def _coming_home(self): self.gateway.send_command(living_room, light, {action: on, brightness: 60}) self.gateway.send_command(living_room, ac, {action: set_temp, value: 26}) self.gateway.send_command(bedroom, curtain, {action: close}) def _sleep_mode(self): self.gateway.send_command(bedroom, light, {action: off}) self.gateway.send_command(living_room, tv, {action: off}) self.gateway.send_command(bedroom, ac, {action: set_temp, value: 25})场景引擎的核心价值在于“编排”。当用户说“回家”时系统不需要用户一条条控制灯、空调、窗帘而是一次性把多个指令按顺序下发这才能真正提升智慧家庭的体验。代码里有一个容易被忽略但非常重要的设计update_state维护了当前各设备的状态快照。这个状态对场景联动非常关键因为好的场景联动不是“无条件执行”而是“根据当前状态决定是否执行”。比如“开灯”指令如果灯本身就是开的就可以跳过下发避免产生无意义的网络流量和重复执行。4.5 本地 REST API 与主入口为了让控制中心对外可用需要提供一个简单的接口。用 Flask 封装一个/api/command接口外部系统或者前端页面可以通过 POST 请求发送文本指令。# 文件路径src/api/app.py from flask import Flask, request, jsonify def create_app(intent_engine, scene_engine): app Flask(__name__) app.post(/api/command) def handle_command(): data request.get_json() text data.get(text, ) parsed intent_engine.parse_intent(text) scene_engine.execute(parsed[intent], parsed[params]) return jsonify({code: 0, parsed: parsed}) return app主入口文件负责把各模块组装起来这是整个项目的“装配车间”# 文件路径src/main.py from device.mqtt_client import DeviceGateway from nlp.intent_engine import parse_intent from scene.scene_engine import SceneEngine from api.app import create_app gateway DeviceGateway(on_state_changeNone) scene_engine SceneEngine(gateway) gateway.on_state_change scene_engine.update_state gateway.start() app create_app(parse_intent, scene_engine) app.run(host0.0.0.0, port8000)启动后可以用 curl 模拟用户指令进行验证curl -X POST http://127.0.0.1:8000/api/command \ -H Content-Type: application/json \ -d {text: 打开客厅灯}预期流程是意图识别判断为light_on场景引擎向home/living_room/light/command主题下发{action: on}真正的设备或模拟设备收到指令后执行开灯动作。如果手头没有真实设备可以用 Mosquitto 客户端订阅指令主题观察指令是否正常下发mosquitto_sub -t home///command -v看到home/living_room/light/command {action: on}输出说明整条链路已经打通。5. 关键技术点拆解5.1 端侧模型推理与 NPU 调度AI PC 与传统 PC 相比最大的差异就是 NPU。NPU 擅长低精度、大规模并行的神经网络计算在智慧家庭场景中非常适合跑语音唤醒、关键词识别、轻量意图分类这类“常驻型”任务。为什么特意强调 NPU因为这类任务通常需要全天候运行。如果用 CPU 跑功耗和发热都不理想如果用独立显卡跑功耗更高对台式机或者笔记本都是负担。NPU 的低功耗特性让它成为“一直在线”感知任务的最佳选择。开发时要特别注意不是所有模型都能直接在 NPU 上跑。通常需要经过量化和格式转换比如转成 INT8 精度、ONNX 或 OpenVINO IR 格式。转换之后还要做精度对比测试因为量化可能带来精度损失需要评估业务场景能否接受。另外模型能不能真正用上 NPU需要通过工具观察 NPU 占用率不能只看代码里配置了 NPU provider 就认为已经生效。5.2 家庭隐私数据保护智慧家庭设备会采集大量生活数据这些数据的敏感性比普通互联网应用高得多。AI PC 本地化方案的最大价值点就在这里本地推理可以保证语音文本、设备状态、家庭作息等数据不出局域网从源头上降低隐私泄露风险。工程实现上要始终坚持最小权限和最小数据原则。只采集场景联动必需的数据不要为了所谓的“大数据”盲目采集音频数据在本地完成处理后原始音频应尽快删除或者只保留特征值MQTT 通信建议启用 TLS 加密禁止明文口令设备鉴权不要用固定口令优先使用证书或者动态 Token。这些看似基础的安全措施在智慧家庭项目中往往最容易被忽视。很多开发者做完功能联调就认为大功告成直到设备被异常控制才意识到安全设计缺失那时排查成本已经很高了。5.3 场景引擎的状态管理场景引擎在代码层面看起来只是 if-else 分支但生产环境远没有这么简单。真实家庭中普遍存在设备离线、指令丢失、状态上报延迟等问题。如果场景引擎不维护状态连续收到两次“打开灯”就会下发两次重复指令一些不友好的设备甚至会出现闪烁或者频繁通断。因此状态管理是场景引擎设计的重点。建议的做法是维护一份设备状态的本地快照所有指令下发前先检查当前状态下发后根据设备的确认回报更新快照。如果设备长时间没有确认要把它标记为异常状态避免后续场景联动基于错误状态做决策。这套机制叫“状态同步 确认机制”是物联网应用和普通 Web 应用一个很大的区别。6. 常见问题与排查思路开发过程中最容易遇到的几类问题这里整理成一张表格方便快速定位。问题现象常见原因解决思路MQTT 客户端连不上 BrokerBroker 监听地址只绑定了 localhost修改 Mosquitto 配置监听 0.0.0.0设备订阅不到指令主题命名不一致统一 topic 格式使用通配符订阅意图识别结果不准确规则覆盖不足或正则写错增加规则或接入本地模型兜底模型在 NPU 上速度反而更慢模型未量化或未转换格式转换为 INT8 模型检查 NPU 驱动设备收到重复指令场景引擎未做状态判断增加状态快照和幂等判断断网后设备全部失控链路全部依赖云端把核心控制链路放到局域网本地以“MQTT 连不上 Broker”为例排查步骤可以按下面的顺序展开。第一步确认 Broker 进程是否存活执行ps -ef | grep mosquitto。第二步确认端口是否在监听执行netstat -tlnp | grep 1883。第三步检查 Mosquitto 配置文件重点看listener和allow_anonymous两个配置项。第四步让客户端连接 Broker 所在机器的实际 IP而不是默认的 localhost。这里要特别强调一个问题调试阶段为了方便很多人会直接开启 MQTT 的allow_anonymous匿名访问。这在开发环境没问题但生产环境非常危险。开启匿名意味着局域网内任何设备都能连接 Broker 并订阅所有主题相当于把整个家庭的控制权暴露给了网络里的每一台设备。生产环境一定要关闭匿名访问配置独立账号并按设备分配最小权限。7. 最佳实践与工程建议7.1 接口设计先于编码动手写代码之前先把设备模型和主题协议定下来。MQTT 主题建议遵循home/{空间}/{设备}/{属性}的结构属性用state表示状态上报、command表示指令下发。主题结构稳定之后后续扩展新设备时只需要按同一套约定接入不需要改动核心场景逻辑。设备模型也要提前抽象。无论是灯、空调还是窗帘在系统内部都应该有统一的设备标识、属性和指令格式。这样上层场景引擎面向的是“抽象设备”而不是“某个品牌的某个具体型号”可维护性会高很多。7.2 指令下发要做幂等控制设备控制命令必须具备幂等性。所谓幂等就是同一个指令执行多少次结果都和执行一次相同。比如“开灯”如果灯已经是开的系统应该直接返回成功而不是再向总线发一遍开灯指令。配合状态快照可以避免重复指令造成的设备抖动也能减少局域网内的无效流量。更重要的是幂等控制在设备 ACK 丢失、网络重试等异常场景下能避免很多连锁问题这是物联网开发中非常基础但也很容易被忽略的工程能力。7.3 本地模型要持续评测AI PC 上的本地模型不是部署完就结束了它是一个需要持续维护的组件。建议从第一天就建立一套简单的评测集每次升级模型或者调整量化参数之后用同一批测试文本跑一遍完整流程记录意图识别的准确率和单次推理耗时。如果没有这套评测机制模型换了一版之后可能某个场景的识别效果突然下降而这个问题在开发环境很难被第一时间发现往往要等到真实用户反馈才会暴露。评测集不需要很大每个场景准备几十条典型说法就够用关键是保证评测方法的稳定性。7.4 日志与可观测性家庭场景的故障往往很难在开发环境复现因为涉及真实网络环境、真实设备和真实用户习惯。建议从第一天就做好结构化日志至少记录以下信息哪个房间、什么设备、下发了什么指令、设备是否确认、整个流程耗时多少。日志格式统一为 JSON便于后续检索和分析。日志级别也要合理划分日常运行时只输出必要信息排查问题时可以通过调整日志级别输出更详细的调试信息避免日志文件无限增长淹没关键信息。7.5 安全边界不容忽视智慧家庭控制中心一旦接入外网就会暴露在攻击面之下。这里给出几条明确的安全建议。不要把 REST API 直接暴露到公网必要时通过安全的远程访问通道使用。MQTT 必须启用 TLS 加密重要设备之间的通信建议使用证书双向认证。设备凭据要使用环境变量或密钥管理服务保存绝对不能硬编码在代码仓库里。涉及生产环境的任何变更都要先在小范围灰度验证再逐步推送到全部设备。安全不是最后才考虑的功能而是从架构设计第一天就要纳入的设计约束。8. 总结与下一步学习方向联想 AI PC 与海尔智慧家庭的融合为开发者提供了一个很典型的端云协同落地场景。核心思路可以归纳为一句话AI PC 做家庭的本地大脑智慧家庭设备做大脑的双手MQTT、Matter 这类协议做两者之间的神经网络。通过本文的实战项目你应该已经掌握了设备接入层的 MQTT 写法、意图识别层的规则设计、场景联动层的状态管理以及如何用 Flask 把整套能力封装成可调用的本地服务。整套代码虽然精简但链路完整可以在此基础上改造出自己的家庭控制中心。下一步建议从三个方向继续深入。第一把规则意图识别升级为本地大模型驱动深入研究 ONNX 格式转换和 NPU 量化调优这是 AI PC 差异化价值最大的技术点。第二把单机控制中心扩展为支持多用户的服务加入用户偏好学习让同样的“回家模式”在不同家庭成员面前呈现不同效果。第三研究 Matter 协议考虑如何把非 MQTT 体系的设备接入统一模型进一步扩大设备兼容范围。最后一个实用建议开发智慧家庭项目时先用 Mosquitto 和模拟设备把完整链路跑通再接入真实硬件。否则一旦出现问题很难判断是网络故障、协议问题还是设备本身的问题。链路通了后续每一步都会顺利很多。如果这篇文章对你有帮助可以先收藏起来等搭建 AI PC 智慧家庭项目时再对照实践。