从0到1搭建智能家居AI智能体:打造能理解你的智能化居家生活

副标题:基于LangChain+HomeAssistant+本地大模型的实践指南

摘要/引言

你有没有过这样的经历?

  • 下班回家要手动点击“回家模式”,等灯亮、空调开、窗帘动,网络延迟时还要反复刷新APP;
  • 说“我有点冷”,智能音箱只会生硬开空调,却不懂你还想要加湿器和毯子;
  • 周末想睡懒觉,窗帘却准时在8点拉开,惊醒你的美梦……

传统智能家居的痛点在于**“被动执行”:依赖手动设置场景,缺乏对用户习惯的理解,更没有主动服务的能力。而我们需要的是“能懂你的智能”**——它能记住你每天10点要喝热牛奶,能读懂“有点冷”背后的需求,能主动调整周末的懒觉模式。

本文将带你用AI智能体解决这个问题:基于LangChain(AI应用框架)+HomeAssistant(智能家居集成平台)+本地大模型(Llama 3),搭建一个本地化、个性化、主动化的智能家居AI智能体。读完本文,你将:

  1. 掌握AI智能体的核心架构(感知-决策-执行);
  2. 学会用LangChain整合工具(HomeAssistant API、天气、日历);
  3. 实现能理解自然语言、主动服务的智能家居系统;
  4. 规避搭建过程中的常见“坑”。

目标读者与前置知识

适合谁读?

  • 想提升智能家居智能化程度的爱好者
  • 有Python基础、想了解AI智能体落地的初级开发者
  • 厌恶云端依赖、重视隐私的技术极客

前置知识

  1. 基础Python编程(能写函数、调用API);
  2. 了解RESTful API的基本概念(GET/POST请求);
  3. (可选)HomeAssistant的基础使用(本文会补基础)。

文章目录

  1. 引言与基础
  2. 问题背景:传统智能家居的“不智能”痛点
  3. 核心概念:AI智能体如何理解你的需求?
  4. 环境准备:从0搭建开发环境
  5. 分步实现:
    • Step 1:用HomeAssistant连接所有设备
    • Step 2:本地大模型(Llama 3)的配置
    • Step 3:LangChain构建AI智能体(工具调用+决策)
    • Step 4:实现用户交互接口(Flask API)
  6. 关键代码解析:Prompt设计与工具调用逻辑
  7. 结果验证:让智能体“主动服务”的3个场景
  8. 性能优化:从“能用”到“好用”的技巧
  9. 常见问题:避坑指南
  10. 未来展望:智能体的进化方向
  11. 总结

问题背景:传统智能家居的“不智能”痛点

要解决问题,先明确问题——传统智能家居的核心矛盾是**“人的需求是灵活的,系统的逻辑是固化的”**,具体表现为3大痛点:

1. 联动生硬:需要手动“写剧本”

传统系统的场景联动(比如“回家模式”)需要用户手动添加每一个设备的动作:

  • 打开客厅灯(亮度80%)→ 打开空调(25℃)→ 拉开窗帘→ 播放音乐。
    如果想调整其中一个参数(比如夏天把空调降到24℃),需要重新修改整个场景。

2. 缺乏主动:不会“猜你想要”

传统系统不会主动关注你的习惯:

  • 你每天晚上10点要喝热牛奶,但系统不会提醒你;
  • 你周末早上要睡懒觉,但系统还是准时在8点拉开窗帘。

3. 理解局限:听不懂“弦外之音”

传统系统只能处理指令式请求(比如“打开空调”),无法理解意图式需求(比如“我有点冷”):

  • 说“我有点冷”,传统系统只会开空调,但你可能还想要加湿器和毯子;
  • 说“周末想放松”,传统系统不知道要调整灯光、打开投影仪、准备零食。

核心概念:AI智能体如何理解你的需求?

要解决这些痛点,我们需要AI智能体——一个能“感知环境、理解需求、主动决策”的系统。它的核心逻辑是**“感知-决策-执行”循环**:

1. 核心概念拆解

  • AI智能体:具备自主决策能力的软件系统,能与环境交互并实现目标;
  • LangChain:连接大模型与工具的框架,让大模型能调用API(比如HomeAssistant);
  • HomeAssistant:开源智能家居平台,能整合99%的智能设备(小米、华为、飞利浦等);
  • 本地大模型(Llama 3):处理自然语言理解,本地化运行保护隐私。

2. 整体架构图

用户交互

AI智能体(LangChain代理)

工具调用

HomeAssistant API

天气API

日历API

设备执行(灯/空调/窗帘)

感知反馈(设备状态/传感器数据)

简单来说:

  • 用户通过语音/APP说“我有点冷”;
  • AI智能体用Llama 3理解需求,调用HomeAssistant获取室内温度、天气API获取室外温度;
  • 结合你的习惯(冷时要24℃+加湿器),调用HomeAssistant调整设备;
  • 设备执行后,将状态反馈给智能体,完成循环。

环境准备:从0搭建开发环境

1. 硬件要求

  • 一台能运行Docker的电脑(或树莓派4B+);
  • (可选)GPU(比如Nvidia GTX 1660,加速大模型推理)。

2. 软件安装清单

软件/工具 用途 版本
Python 核心开发语言 3.10+
Docker 部署HomeAssistant 最新版
Ollama 运行本地大模型 最新版
LangChain 构建AI智能体 0.1.10+
Flask 实现交互API 2.3.3+

3. 分步安装指南

(1)安装HomeAssistant(Docker方式)

HomeAssistant是所有设备的“中枢”,用Docker安装最方便:

# 拉取HomeAssistant镜像
docker pull homeassistant/home-assistant:stable

# 启动容器(映射端口8123,保存配置到本地)
docker run -d \
  --name homeassistant \
  --privileged \
  --restart=unless-stopped \
  -e TZ=Asia/Shanghai \
  -v /path/to/your/config:/config \
  --network=host \
  homeassistant/home-assistant:stable
  • --network=host:让容器使用主机网络,避免端口映射问题;
  • /path/to/your/config:替换为本地保存配置的路径(比如~/homeassistant/config)。

启动后,访问http://localhost:8123,按照指引完成初始化(设置用户名、密码)。

(2)安装Ollama(运行本地大模型)

Ollama是运行本地大模型的“瑞士军刀”,支持Llama 3、Mistral等模型:

  • Linux/Mac
    curl -fsSL https://ollama.com/install.sh | sh
    
  • Windows:下载exe安装包(https://ollama.com/download)。

安装完成后,拉取Llama 3模型:

ollama pull llama3

测试模型:

ollama run llama3
# 输入“Hello”,会返回友好回复
(3)安装Python依赖

创建requirements.txt

langchain==0.1.10
langchain-community==0.0.25
python-dotenv==1.0.0
flask==2.3.3
homeassistant-api==2.0.0
requests==2.31.0

安装依赖:

pip install -r requirements.txt

分步实现:搭建你的智能家居AI智能体

接下来进入核心环节——从0到1搭建AI智能体。我们将实现3个核心功能:

  1. 连接所有设备(HomeAssistant);
  2. 理解自然语言(Llama 3);
  3. 主动决策(LangChain代理)。

Step 1:用HomeAssistant连接所有设备

HomeAssistant的核心价值是**“把所有设备变成API”**——不管是小米的灯、华为的空调,还是飞利浦的窗帘,都能通过统一的API调用。

(1)添加模拟设备(测试用)

如果没有真实设备,可以先添加Demo设备(HomeAssistant内置的模拟设备):

  1. 打开HomeAssistant→配置→设备与服务→添加集成;
  2. 搜索“Demo”→选择“Demo Integration”→点击“提交”;
  3. 完成后,你会看到模拟的灯、空调、传感器(比如light.demo_light_1climate.demo_climate_1)。
(2)获取HomeAssistant API令牌

AI智能体需要通过API控制设备,因此需要获取Long-Lived Access Token

  1. 点击HomeAssistant右上角的“头像”→“Long-Lived Access Tokens”;
  2. 输入令牌名称(比如“AI_Agent”)→点击“创建”;
  3. 复制令牌(只显示一次,保存好!)。

Step 2:本地大模型(Llama 3)的配置

大模型是AI智能体的“大脑”,负责理解自然语言。我们用Ollama运行Llama 3,本地化处理用户需求,保护隐私。

在Python中调用Llama 3:

from langchain_community.llms import Ollama

# 初始化Llama 3模型
llm = Ollama(
    model="llama3",
    temperature=0.1  # 温度越低,输出越稳定
)

# 测试模型
response = llm.predict("介绍一下你自己")
print(response)
# 输出:我是Llama 3,由Meta开发的开源大模型...

Step 3:LangChain构建AI智能体(核心)

LangChain的核心是**“链(Chain)”“代理(Agent)”**:

  • 链:将多个步骤串联(比如“理解需求→调用工具→生成回复”);
  • 代理:让大模型自主决定调用哪些工具。
(1)加载HomeAssistant工具

LangChain-Community提供了HomeAssistantToolkit,可以快速生成控制设备的工具:

from langchain_community.tools.home_assistant import HomeAssistantToolkit
from langchain_community.utilities.home_assistant import HomeAssistantAPIWrapper

# 配置HomeAssistant API
ha_wrapper = HomeAssistantAPIWrapper(
    homeassistant_url="http://localhost:8123",
    homeassistant_token="你的Long-Lived令牌"
)

# 生成HomeAssistant工具(比如获取设备状态、调用服务)
ha_toolkit = HomeAssistantToolkit.from_ha_api_wrapper(ha_wrapper)
ha_tools = ha_toolkit.get_tools()

# 查看可用工具
print([tool.name for tool in ha_tools])
# 输出:['homeassistant_get_entity_state', 'homeassistant_call_service', ...]
  • homeassistant_get_entity_state:获取设备状态(比如灯是否开着);
  • homeassistant_call_service:调用设备服务(比如打开灯、调整空调温度)。
(2)添加其他工具(天气、日历)

为了让智能体更“聪明”,我们需要添加外部工具:

  • 天气工具:调用OpenWeatherMap API获取室外温度;
  • 日历工具:调用Google Calendar API获取用户日程(本文用模拟数据)。

以天气工具为例,定义自定义工具:

from langchain_core.tools import tool
import requests

@tool
def get_weather(city: str) -> str:
    """获取指定城市的天气信息(温度、描述)"""
    api_key = "你的OpenWeatherMap API密钥"  # 注册地址:https://openweathermap.org/
    url = f"http://api.openweathermap.org/data/2.5/weather?q={city}&appid={api_key}&units=metric"
    response = requests.get(url)
    data = response.json()
    return f"温度:{data['main']['temp']}℃,天气:{data['weather'][0]['description']}"

# 将天气工具加入工具列表
other_tools = [get_weather]
(3)设计Prompt:让智能体“懂规矩”

Prompt是智能体的“说明书”,决定了它的行为逻辑。一个好的Prompt需要包含:

  • 智能体的角色(比如“私人助手”);
  • 可用的工具列表
  • 处理需求的规则(比如“先获取温度再决策”);
  • 用户的习惯数据(比如“每天10点喝热牛奶”)。

完整Prompt示例

system_prompt = """你是用户的智能家居私人助手,名字叫小居。你的任务是理解用户的需求,结合用户的习惯、环境数据和设备状态,提供个性化、主动的服务。你可以调用以下工具:

{tools}

工具的使用格式如下(必须用<|FunctionCallBegin|>和<|FunctionCallEnd|>包裹):
<|FunctionCallBegin|>[{"name":"工具名称","parameters":{"参数1":"值1","参数2":"值2"}}]<|FunctionCallEnd|>

注意事项:
1. 主动考虑用户习惯:比如用户每天晚上10点要喝热牛奶,周末早上9点起床;
2. 先检查信息完整性:比如用户说“我有点冷”,要先获取室内外温度;
3. 用自然语言回复:避免技术术语,比如不说“调用了homeassistant_call_service”,而是说“已为你打开空调”;
4. 工具调用失败时,要告知用户并询问是否重试。

用户的习惯数据:
- 每天晚上10点喝热牛奶,用微波炉加热2分钟(温度80℃);
- 周末早上9点起床,窗帘从9点开始慢慢打开(30分钟完全打开);
- 冷的时候喜欢空调24℃+加湿器50%;
- 回家时喜欢客厅灯亮度80%、空调25℃、播放爵士乐。

当前上下文:
- 时间:{current_time}(格式:YYYY-MM-DD HH:MM);
- 室内温度:{indoor_temp}℃;
- 设备状态:{device_states}(比如“灯:关闭,空调:关闭”);
- 天气:{weather}(比如“北京,15℃,多云”);
- 日历:{calendar}(比如“周六无安排”)。

用户的输入:{input}
"""
(4)创建LangChain代理

create_structured_chat_agent创建支持工具调用的代理:

from langchain.agents import AgentExecutor, create_structured_chat_agent
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder

# 整合所有工具
all_tools = ha_tools + other_tools

# 创建Prompt模板
prompt = ChatPromptTemplate.from_messages([
    ("system", system_prompt),
    ("user", "{input}"),
    MessagesPlaceholder(variable_name="agent_scratchpad"),  # 保存代理的思考过程
])

# 创建代理
agent = create_structured_chat_agent(
    llm=llm,  # 之前初始化的Llama 3模型
    tools=all_tools,
    prompt=prompt
)

# 创建代理执行器(负责运行代理)
agent_executor = AgentExecutor(
    agent=agent,
    tools=all_tools,
    verbose=True  # 打印思考过程(调试用)
)

Step 4:实现用户交互接口(Flask API)

智能体需要和用户交互——我们用Flask实现一个简单的API,接收用户输入并返回结果。

(1)编写Flask代码

创建app.py

from flask import Flask, request, jsonify
from dotenv import load_dotenv
import datetime

# 加载环境变量(比如HomeAssistant令牌、天气API密钥)
load_dotenv()

# 初始化Flask app
app = Flask(__name__)

# 导入之前创建的agent_executor(需要放在Flask初始化之后)
from agent import agent_executor

# 模拟获取当前上下文(实际可以从HomeAssistant/API获取)
def get_current_context():
    return {
        "current_time": datetime.datetime.now().strftime("%Y-%m-%d %H:%M"),
        "indoor_temp": "22",  # 实际从HomeAssistant获取:ha_wrapper.get_entity_state("sensor.indoor_temp")
        "device_states": "灯:关闭,空调:关闭,窗帘:关闭",
        "weather": "北京,15℃,多云",
        "calendar": "周六无安排"
    }

@app.route("/chat", methods=["POST"])
def chat():
    try:
        # 获取用户输入
        user_input = request.json.get("user_input")
        if not user_input:
            return jsonify({"error": "请输入内容"}), 400
        
        # 获取当前上下文
        context = get_current_context()
        
        # 运行代理
        response = agent_executor.run({
            "input": user_input,
            **context  # 将上下文传入Prompt
        })
        
        return jsonify({"response": response})
    except Exception as e:
        return jsonify({"error": str(e)}), 500

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000, debug=True)
(2)测试API

启动Flask app:

python app.py

curl测试:

curl -X POST -H "Content-Type: application/json" -d '{"user_input":"我回家了"}' http://localhost:5000/chat

预期返回:

{
    "response": "已为你打开客厅灯(亮度80%)、空调(25℃)、窗帘(打开),并播放你喜欢的爵士乐~"
}

关键代码解析:Prompt设计与工具调用逻辑

(1)为什么用StructuredChatAgent?

create_structured_chat_agent是LangChain中最适合工具调用的代理类型——它要求大模型用结构化的格式返回工具调用(比如{"name":"get_weather","parameters":{"city":"北京"}}),避免歧义。

(2)Prompt中的“用户习惯”有多重要?

用户习惯是智能体“个性化”的核心。比如Prompt中的“每天晚上10点喝热牛奶”,会让智能体在21:50主动提醒用户——这是传统系统做不到的。

(3)代理的思考过程是怎样的?

通过verbose=True,我们可以看到代理的思考过程(以“我有点冷”为例):

> Entering new AgentExecutor chain...
我现在需要处理用户“我有点冷”的请求。首先,根据规则,我需要先获取室内外温度和用户习惯。
首先调用homeassistant_get_entity_state工具获取室内温度:
<|FunctionCallBegin|>[{"name":"homeassistant_get_entity_state","parameters":{"entity_id":"sensor.indoor_temp"}}]<|FunctionCallEnd|>
工具返回:{"state":"22","attributes":{"unit_of_measurement":"℃"}}
接下来调用get_weather工具获取室外温度:
<|FunctionCallBegin|>[{"name":"get_weather","parameters":{"city":"北京"}}]<|FunctionCallEnd|>
工具返回:"温度:15℃,天气:多云"
现在结合用户习惯(冷时喜欢空调24℃+加湿器50%),调用homeassistant_call_service工具调整空调:
<|FunctionCallBegin|>[{"name":"homeassistant_call_service","parameters":{"domain":"climate","service":"set_temperature","entity_id":"climate.demo_climate_1","temperature":24}}]<|FunctionCallEnd|>
工具返回:{"success":true}
然后调用加湿器:
<|FunctionCallBegin|>[{"name":"homeassistant_call_service","parameters":{"domain":"humidifier","service":"turn_on","entity_id":"humidifier.demo_humidifier_1","humidity":50}}]<|FunctionCallEnd|>
工具返回:{"success":true}
最后回复用户:已为你调整空调到24℃,打开加湿器,需要我帮你拿毯子吗?
> Exiting chain.

结果验证:让智能体“主动服务”的3个场景

现在测试3个核心场景,验证智能体的“主动服务”能力:

场景1:主动提醒喝热牛奶(时间触发)

当前上下文

  • 时间:2024-05-10 21:50;
  • 室内温度:22℃;
  • 设备状态:微波炉关闭;
  • 日历:周六无安排。

智能体的行为
主动发送通知:“你通常晚上10点要喝热牛奶,需要我帮你打开微波炉加热吗?”
用户回复“好的”后,智能体调用微波炉服务(加热2分钟,80℃)。

场景2:理解“有点冷”的弦外之音(意图理解)

用户输入:“我有点冷”
智能体的决策

  1. 获取室内温度(22℃)、室外温度(15℃);
  2. 结合习惯(冷时要24℃+加湿器);
  3. 执行:打开空调(24℃)+ 打开加湿器(50%);
  4. 回复:“已为你调整空调到24℃,打开加湿器,需要我帮你拿毯子吗?”

场景3:周末懒觉模式(主动调整)

当前上下文

  • 时间:2024-05-11 08:00(周六);
  • 设备状态:窗帘关闭;
  • 日历:无安排。

智能体的行为

  1. 检查日历(周六)→ 确认是周末;
  2. 检查习惯(周末9点起床)→ 窗帘保持关闭;
  3. 9点时,调用窗帘服务(慢慢打开,30分钟完全打开);
  4. 发送通知:“周末懒觉模式已开启,窗帘将在9点慢慢打开~”

性能优化:从“能用”到“好用”的技巧

(1)缓存工具结果(减少API调用)

用LangChain的缓存机制,避免重复调用同一工具:

from langchain.cache import InMemoryCache
from langchain.globals import set_llm_cache

# 设置内存缓存(重启后失效)
set_llm_cache(InMemoryCache())

比如同一城市的天气,10分钟内的调用会直接返回缓存结果,减少API费用和延迟。

(2)用GPU加速大模型(提升响应速度)

如果你的电脑有GPU(比如Nvidia GTX 1660以上),可以用Ollama的GPU加速:

# 查看GPU是否可用
ollama list
# 运行模型时指定GPU
ollama run llama3 --gpu 0

GPU加速能将Llama 3的响应时间从5秒缩短到1秒

(3)错误处理(避免崩溃)

在工具调用中添加错误处理,比如:

@tool
def get_weather(city: str) -> str:
    try:
        # 原逻辑
    except Exception as e:
        return f"获取天气失败:{str(e)},请检查城市名称或网络"

常见问题:避坑指南

(1)HomeAssistant API调用失败

  • 原因:URL错误/令牌错误/实体ID错误;
  • 解决:用curl测试API:
    curl -X GET -H "Authorization: Bearer 你的令牌" http://localhost:8123/api/states/light.demo_light_1
    
    如果返回设备状态,说明API可用。

(2)大模型不调用工具

  • 原因:Prompt中没有明确工具使用规则;
  • 解决:在Prompt中添加“必须调用工具的场景”,比如“用户说‘我有点冷’,必须先获取室内外温度”。

(3)智能体做出错误决策

  • 原因:用户习惯数据不准确;
  • 解决:优化Prompt中的习惯数据,比如添加“用户之前拒绝过热牛奶的提醒,下次不再主动提醒”。

未来展望:智能体的进化方向

当前的智能体已经能“主动服务”,但还有很大的进化空间:

1. 多模态交互(语音+视觉)

加入摄像头识别(比如识别用户皱眉头→询问是否需要调整环境)、语音合成(用TTS将回复转为语音)。

2. 强化学习(从反馈中学习)

让智能体从用户的反馈中学习——比如用户拒绝了热牛奶的提醒,下次就不再主动提醒。

3. 跨场景联动(家庭+工作)

比如用户在公司发消息说“今天加班”,智能体调整家里的模式:推迟“回家模式”到21点,准备热饭菜。

总结

本文带你从0搭建了一个能理解、会主动、个性化的智能家居AI智能体,核心要点是:

  • AI智能体的本质是“感知-决策-执行”的循环;
  • LangChain是连接大模型与工具的桥梁;
  • 用户习惯是智能体“个性化”的核心;
  • 本地化是保护隐私的关键。

现在,你可以将这个智能体部署到树莓派上,连接真实设备,体验“能懂你的智能家居”——比如下班回家时,灯自动亮起,空调调整到你喜欢的温度,音乐缓缓响起,就像一个懂你的管家在等你回家。

最后,送给你一句话:“智能的本质,是理解人的需求。” 希望你搭建的智能体,能让你的居家生活更温暖、更省心。

参考资料

  1. LangChain官方文档:https://python.langchain.com/
  2. HomeAssistant API文档:https://developers.home-assistant.io/docs/api/rest/
  3. Ollama官方文档:https://ollama.com/docs
  4. Llama 3模型介绍:https://ai.meta.com/blog/meta-llama-3/

附录:完整代码

GitHub仓库:https://github.com/yourname/smart-home-ai-agent
包含:

  • 完整的Python代码;
  • HomeAssistant配置示例;
  • 详细的安装指南。

(注:将yourname替换为你的GitHub用户名)


作者:XX
公众号:XX技术笔记
说明:本文为原创实践指南,转载请注明出处。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐