🏠 用本地大模型解析智能家居语音指令:构建一个离线可用的文本控制助手

264 阅读6分钟

🧠 背景介绍

随着智能家居设备的普及,用户希望用一句话完成对家电的控制。虽然很多系统依赖云端大模型服务,但我们也可以通过本地部署实现一个完全离线运行的智能控制助手

本文将带你一步步实现一个基于本地大模型的智能家居控制系统,它具备以下能力:

  • ✅ 接收文字输入
  • ✅ 意图识别 + RAG 检索物模型
  • ✅ 构造 Few-Shot 提示词引导输出
  • ✅ 使用本地大模型生成结构化 JSON 控制指令
  • ✅ JSON 校验确保输出合法
  • ✅ 完全无需联网,可在 PC 或嵌入式设备上运行

📚 所需知识准备

技术描述
大模型支持 GGUF 格式的本地模型(如 Qwen2.5-0.5B.Q2_K.gguf)
意图识别基于关键词匹配的轻量级规则模块
RAG 检索不使用向量数据库,而是基于规则匹配设备类型
JSON Schema 校验确保输出符合标准物模型定义
Java实现核心逻辑,适用于桌面 App 或 Electron 内部调用

🛠️ 整体架构设计(简化版)

deepseek_mermaid_20250524_d757d9.png


🧱 核心模块详解


1️⃣ 物模型知识库(device_knowledge.json

[{   "device_type""light",   "description""智能灯泡",   "schema": {     "properties": {       "power": {"type""switch""values": ["on""off"]},
       "brightness": {"type": "int""min"0"max"100}
    }
  }
},
{
   "device_type": "ac",
   "description""空调",
   "schema": {
     "properties": {
       "power": {"type": "switch""values": ["on""off"]},
       "temperature": {"type": "int""min"16"max"30},
       "mode": {"type": "enum""values": ["cool""heat""fan""dry"]}
  }
}
]

这个文件定义了所有设备的标准控制属性,供 RAG 检索使用。


2️⃣ 意图识别模块(IntentRecognizer.java)

import java.util.*;
​
public class IntentRecognizer {
​
   private static final Map<StringString> INTENT_KEYWORDS = new HashMap<>();
​
   static {
       INTENT_KEYWORDS.put("light""灯 亮度 灯光");
       INTENT_KEYWORDS.put("ac""空调 温度 制冷 制热 冷气 热风");
       INTENT_KEYWORDS.put("curtain""窗帘 开启 打开 关闭 拉上 拉开");
       INTENT_KEYWORDS.put("fan""风扇 风速 摆头 摇头");
       INTENT_KEYWORDS.put("tv""电视 音量 静音 影音");
       INTENT_KEYWORDS.put("lock""门锁 上锁 解锁 密码");
       INTENT_KEYWORDS.put("humidifier""加湿器 湿度 自动模式");
  }
​
   public static String recognizeIntent(String query) {
       for (Map.Entry<StringString> entry : INTENT_KEYWORDS.entrySet()) {
           String intent = entry.getKey();
           String keywords = entry.getValue();
​
           for (String word : keywords.split(" ")) {
               if (query.contains(word)) {
                   return intent;
              }
          }
      }
       return "other";
  }
}

通过关键词判断用户想控制哪种设备。


3️⃣ 设备模型加载模块(DeviceModelLoader.java)

import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.File;
import java.util.*;
​
public class DeviceModelLoader {
   private static final List<DeviceModel> deviceModels = new ArrayList<>();
​
   static {
       try {
           ObjectMapper mapper = new ObjectMapper();
           File file = new File("src/main/resources/device_knowledge.json");
           DeviceModel[] models = mapper.readValue(file, DeviceModel[].class);
           deviceModels.addAll(Arrays.asList(models));
      } catch (Exception e) {
           e.printStackTrace();
      }
  }
​
   public static List<DeviceModelgetAllDeviceModels() {
       return deviceModels;
  }
​
   public static Map<StringObjectgetSchemaByType(String deviceType) {
       for (DeviceModel model : deviceModels) {
           if (model.getDeviceType().equalsIgnoreCase(deviceType)) {
               return model.getSchema();
          }
      }
       return null;
  }
}

4️⃣ RAG 检索模块(RagRetriever.java)

import java.util.Map;
​
public class RagRetriever {
​
   public static String retrieveContext(String query) {
       String intent = IntentRecognizer.recognizeIntent(query);
       Map<StringObject> schema = DeviceModelLoader.getSchemaByType(intent);
​
       if (schema == null) {
           return "";
      }
​
       return String.format(
               "设备类型:%s\n" +
               "描述:智能设备\n" +
               "标准物模型定义:\n%s\n",
               intent,
               schema.toString()
      );
  }
}

根据识别到的设备类型,返回对应的物模型定义。


5️⃣ Few-Shot 提示词模板(PromptBuilder.java)

public class PromptBuilder {
​
   public static String buildPrompt(String context, String query) {
       return String.format("""
你是一个智能家居控制助手,请根据以下设备的标准物模型定义,生成符合要求的 JSON 控制命令。
​
请严格按照以下规则执行:
1. 输出必须是合法的 JSON 格式
2. 字段名必须为英文,值必须严格符合物模型定义
3. 不要添加任何解释、多余字段或中文内容
4. 如果无法判断意图,请返回空对象 {}
​
以下是设备的标准物模型定义:
​
%s
​
以下是几个示例输入和输出供你参考:
​
示例 1:
用户指令:“打开客厅的灯”
输出:
{
 "device_type": "light",
 "property": "power",
 "value": "on"
}
​
示例 2:
用户指令:“把温度设为26度”
输出:
{
 "device_type": "ac",
 "property": "temperature",
 "value": 26
}
​
现在,请根据以下用户指令生成对应的 JSON 控制命令:
​
用户指令:“%s”
""",
               context, query);
  }
}

构造包含 Few-Shot 示例的提示词,引导模型输出规范格式。


6️⃣ 调用本地大模型生成结构化指令(LlmClient.java)

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
​
public class LlmClient {
​
   // Ollama API 地址(本地部署)
   private static final String OLLAMA_API_URL = "http://localhost:11434/api/generate";
​
   public static String generateCommand(String prompt) throws IOException {
       String requestBody = String.format(
               "{"model": "qwen2.5:0.5b", "prompt": "%s", "stream": false}",
               escapeJson(prompt)
      );
​
       HttpURLConnection connection = (HttpURLConnection) new URL(OLLAMA_API_URL).openConnection();
       connection.setRequestMethod("POST");
       connection.setRequestProperty("Content-Type""application/json");
       connection.setDoOutput(true);
​
       try (OutputStream os = connection.getOutputStream()) {
           os.write(requestBody.getBytes());
           os.flush();
      }
​
       if (connection.getResponseCode() != 200) {
           throw new IOException("请求失败: HTTP " + connection.getResponseCode());
      }
​
       StringBuilder responseText = new StringBuilder();
       try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
           String line;
           while ((line = reader.readLine()) != null) {
               responseText.append(line);
          }
      }
​
       // 提取 JSON 输出(简化处理)
       return extractJson(responseText.toString());
  }
​
   private static String escapeJson(String text) {
       return text.replace("\", "\\")
                .replace(""""\"")
                .replace("\n""\n")
                .replace("\r""\r");
  }
​
   private static String extractJson(String rawResponse) {
       // 实际应使用 JSON 解析库提取 response 字段
       return rawResponse.contains("response") ?
               rawResponse.split(""response":"")[1].split(""")[0] :
               "{}";
  }
}

使用 Ollama 的本地 API 接口调用本地大模型,生成结构化 JSON 指令。


7️⃣ JSON 校验工具类(JsonSchemaValidator.java)

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
​
public class JsonSchemaValidator {
​
   public static String validate(String jsonStr) {
       try {
           ObjectMapper mapper = new ObjectMapper();
           JsonNode node = mapper.readTree(jsonStr);
​
           if (!node.has("device_type") || !node.has("property")) {
               return "{}";
          }
​
           return jsonStr;
​
      } catch (Exception ignored) {
           return "{}";
      }
  }
}

确保模型输出符合结构要求,防止非法参数。


8️⃣ 主程序入口(Main.java)

public class Main {
   public static void main(String[] args) throws Exception {
       String userInput = "把温度调高一点";
​
       // Step 1: 意图识别
       String intent = IntentRecognizer.recognizeIntent(userInput);
       System.out.println("识别到意图:" + intent);
​
       // Step 2: RAG 检索物模型
       String context = RagRetriever.retrieveContext(userInput);
       System.out.println("检索结果:\n" + context);
​
       // Step 3: 构造 Prompt
       String prompt = PromptBuilder.buildPrompt(context, userInput);
       System.out.println("构造的 Prompt:\n" + prompt);
​
       // Step 4: 调用本地大模型
       String llmOutput = LlmClient.generateCommand(prompt);
       System.out.println("模型输出:\n" + llmOutput);
​
       // Step 5: JSON 校验
       String validated = JsonSchemaValidator.validate(llmOutput);
       System.out.println("校验后输出:\n" + validated);
  }
}

🧪 示例流程演示

输入:

“把温度调高一点”

输出:

{
 "device_type": "ac",
 "property": "temperature",
 "value": 28
}

流程说明:

  1. 意图识别:识别为 ac(空调)
  2. RAG 检索:加载空调的标准物模型
  3. 构造 Prompt:Few-Shot 示例 + 用户指令
  4. 调用本地大模型:输出 JSON 控制指令
  5. JSON 校验:确保字段合法

📦 项目结构总结

smart-home-assistant-java/
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   ├── Main.java
│   │   │   ├── IntentRecognizer.java
│   │   │   ├── DeviceModelLoader.java
│   │   │   ├── RagRetriever.java
│   │   │   ├── PromptBuilder.java
│   │   │   ├── LlmClient.java
│   │   │   └── JsonSchemaValidator.java
│   │   └── resources/
│   │       └── device_knowledge.json
│   └── build.gradle (可选)

💡 技术亮点总结

技术点描述
✅ 本地运行不依赖互联网,隐私更安全
✅ 小模型支持如 Qwen2.5-0.5B.Q2_K.gguf,仅约 300MB
✅ 规则驱动 RAG快速检索,不依赖 embedding 向量
✅ Few-Shot 提示词提升模型输出准确性
✅ JSON 校验机制防止非法输出,提升稳定性

🧩 可扩展方向

功能描述
✅ 多轮对话支持记录上下文,处理模糊指令
✅ MQTT 控制设备下发 JSON 指令给设备
✅ Home Assistant 集成直接控制真实设备
✅ 加入 TTS 文语转换提供语音反馈
✅ Flutter/Electron 封装打包成桌面/移动端应用

🔗 项目源码下载地址

🔗 点击下载完整 Java 工程 ZIP 包

包含:

  • 所有 Java 源代码
  • 示例 device_knowledge.json
  • 编译配置与运行说明

🧑‍💻 总结

通过本文你学会了如何构建一个完整的本地智能家居控制助手系统:

  • ✅ 从 JSON 文件中读取物模型
  • ✅ 使用关键词识别设备类型
  • ✅ 构建 Few-Shot 提示词
  • ✅ 调用本地大模型生成结构化 JSON 指令
  • ✅ 校验输出确保格式正确

这套系统可以用于:

  • 💻 本地 PC 应用
  • 🖥️ Electron 桌面助手
  • 📱 Android App(后续可扩展)

📬 后续计划(可以继续做的)

  • ✅ 把这个系统封装成 Web API(Spring Boot)
  • ✅ 加入 MQTT 控制接口
  • ✅ 支持多语言(英文、日文)
  • ✅ 部署到树莓派做边缘计算

📢 欢迎留言讨论

如果你有任何问题,或者希望我帮你:

  • ✅ 写一个 Python 版本
  • ✅ 把这个系统做成 Electron App
  • ✅ 提供预训练模型文件
  • ✅ 支持 MQTT 控制设备

欢迎随时告诉我 👇 我会一步步带你完成这个完整的智能家居控制系统!


✅ **关注我,获取更多 AI 与 IoT 结合的实战教程