十七 Home Assistant 大语言模型API

部署运行你感兴趣的模型镜像

Home Assistant大语言模型API

Home Assistant可以与大语言模型(LLMs)进行交互。通过向大语言模型公开Home Assistant API,大语言模型可以获取数据或控制Home Assistant,从而更好地辅助用户。Home Assistant带有一个内置的大语言模型API,但自定义集成可以注册自己的API以提供更高级的功能。

内置辅助API

Home Assistant有一个内置API,它向大语言模型公开了辅助API。此API允许大语言模型通过意图与Home Assistant交互,并且可以通过注册意图进行扩展。

辅助API等同于内置对话代理也可访问的功能和公开实体。不能执行管理任务。

支持大语言模型API

大语言模型API需要在你的集成中的两个地方进行集成。用户需要能够配置应使用哪个API,并且在与大语言模型交互时,应将API提供的工具传递给大语言模型。

选项流程

所选的API应存储在配置项选项中。它应包含对API ID的字符串引用。如果未选择API,则必须省略该键。

在你的选项流程中,你应该向用户提供一个选择器,让他们选择应使用哪个API。

from types import MappingProxyType
from homeassistant.const import CONF_LLM_HASS_API
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import llm
from homeassistant.helpers.selector import (
    SelectOptionDict,
    SelectSelector,
    SelectSelectorConfig,
)

@callback
def async_get_options_schema(
    hass: HomeAssistant,
    options: MappingProxyType[str, Any],
) -> vol.Schema:
    """返回选项模式。"""
    apis: list[SelectOptionDict] = [
        SelectOptionDict(
            label="无控制",
            value="none",
        )
    ]
    apis.extend(
        SelectOptionDict(
            label=api.name,
            value=api.id,
        )
        for api in llm.async_get_apis(hass)
    )
    return vol.Schema(
        {
            vol.Optional(
                CONF_LLM_HASS_API,
                description={"suggested_value": options.get(CONF_LLM_HASS_API)},
                default="none",
            ): SelectSelector(SelectSelectorConfig(options=apis)),
        }
    )

在处理选项时,如果用户选择了“none”,请确保在存储选项之前删除该键。

if user_input[CONF_LLM_HASS_API] == "none":
    user_input.pop(CONF_LLM_HASS_API)
return self.async_create_entry(title="", data=user_input)
获取工具

与大语言模型交互时,你应该从所选的API中获取工具,并将它们与API提供的额外提示一起传递给大语言模型。

from homeassistant.const import CONF_LLM_HASS_API
from homeassistant.core import HomeAssistant, callback
from homeassistant.components import conversation
from homeassistant.helpers import intent, llm

class MyConversationEntity(conversation.ConversationEntity):
    def __init__(self, entry: ConfigEntry) -> None:
        """初始化代理。"""
        self.entry = entry
  ...
    async def async_process(
        self, user_input: conversation.ConversationInput
    ) -> conversation.ConversationResult:
        """处理用户输入。"""
        intent_response = intent.IntentResponse(language=user_input.language)
        llm_api: llm.API | None = None
        tools: list[dict[str, Any]] | None = None
        if self.entry.options.get(CONF_LLM_HASS_API):
            try:
                llm_api = await llm.async_get_api(
                    self.hass,
                    self.entry.options[CONF_LLM_HASS_API],
                    llm.LLMContext(
                        platform=DOMAIN,
                        context=user_input.context,
                        user_prompt=user_input.text,
                        language=user_input.language,
                        assistant=conversation.DOMAIN,
                        device_id=user_input.device_id,
                    ),
                )
            except HomeAssistantError as err:
                LOGGER.error("获取大语言模型API时出错: %s", err)
                intent_response.async_set_error(
                    intent.IntentResponseErrorCode.UNKNOWN,
                    f"准备大语言模型API时出错: {err}",
                )
                return conversation.ConversationResult(
                    response=intent_response, conversation_id=user_input.conversation_id
                )
            tools = [
                _format_tool(tool)  # TODO按照你的大语言模型期望的格式格式化工具
                for tool in llm_api.tools
            ]
        if llm_api:
            api_prompt = llm_api.api_prompt
        else:
            api_prompt = llm.async_render_no_api_prompt(self.hass)
        prompt = "\n".join((user_prompt, api_prompt))
        # 与大语言模型交互并传递工具
        request = user_input.text
        for _iteration in range(10):
            response =...  # 向大语言模型发送请求并获取响应,包括工具
            if not response.tool_call:
                break
            LOGGER.debug(
                "工具调用: %s(%s)",
                response.tool_call.function.name,
                response.tool_call.function.arguments,
            )
            tool_input = llm.ToolInput(
                tool_name=response.tool_call.function.name,
                tool_args=json.loads(response.tool_call.function.arguments),
            )
            try:
                tool_response = await llm_api.async_call_tool(tool_input)
            except (HomeAssistantError, vol.Invalid) as e:
                tool_response = {"error": type(e).__name__}
                if str(e):
                    tool_response["error_text"] = str(e)
            LOGGER.debug("工具响应: %s", tool_response)
            response = tool_response
最佳实践

如果你的对话实体允许用户使用 conversation_id 维护对话历史,请确保为每次交互重新生成提示,并在为后续命令传递的历史中覆盖它。这允许用户始终能够查询家庭的最新状态。

创建自己的API

要创建自己的API,你需要创建一个继承自 API 的类并实现 async_get_tools 方法。async_get_tools 方法应该返回一个 Tool 对象列表,这些对象表示你希望向大语言模型公开的功能。

工具

llm.Tool 类表示可以由大语言模型调用的工具。

from homeassistant.core import HomeAssistant
from homeassistant.helper import llm
from homeassistant.util import dt as dt_util
from homeassistant.util.json import JsonObjectType

class TimeTool(llm.Tool):
    """获取当前时间的工具。"""
    name = "GetTime"
    description: "返回当前时间。"
    # 可选。输入参数的voluptuous模式。
    parameters = vol.Schema({
      vol.Optional('timezone'): str,
    })
    async def async_call(
        self, hass: HomeAssistant, tool_input: ToolInput, llm_context: LLMContext
    ) -> JsonObjectType:
        """调用工具。"""
        if "timezone" in tool_input.tool_args:
            tzinfo = dt_util.get_time_zone(tool_input.tool_args["timezone"])
        else:
            tzinfo = dt_util.DEFAULT_TIME_ZONE
        return dt_util.now(tzinfo).isoformat()

llm.Tool 类具有以下属性:

名称类型描述
name字符串工具的名称。必需。
description字符串工具的描述,帮助大语言模型理解何时以及如何调用它。可选但建议提供。
parametersvol.Schema参数的voluptuous模式。默认为 vol.Schema()

llm.Tool 类具有以下方法:
async_call:当被大语言模型调用时执行工具的实际操作。这必须是一个异步方法。其参数是 hassllm.ToolInput 的一个实例。响应数据必须是一个字典,并且可以序列化为JSON homeassistant.util.json.JsonObjectType。错误必须作为 HomeAssistantError 异常(或其子类)抛出。响应数据不应包含用于错误处理的错误代码。

ToolInput 具有以下属性:

名称类型描述
tool_name字符串正在调用的工具的名称
tool_args字典大语言模型提供的参数。参数使用 parameters 模式进行转换和验证。
platform字符串使用该工具的对话代理的DOMAIN
contextContext对话的 homeassistant.core.Context
user_prompt字符串发起工具调用的原始文本输入
language字符串对话代理的语言,或“*”表示任何语言
assistant字符串用于控制公开实体的助手名称。目前,仅支持 conversation
device_id字符串用户发起对话的设备的设备ID
API

API对象允许创建API实例。一个API实例表示将提供给大语言模型的一组工具。

from homeassistant.core import HomeAssistant
from homeassistant.helper import llm
from homeassistant.util import dt as dt_util
from homeassistant.util.json import JsonObjectType

class MyAPI(API):
    """我自己的大语言模型API。"""
    def __init__(self, hass: HomeAssistant) -> None:
        """初始化类。"""
        super().__init__(
            hass=hass,
            id="my_unique_key",
            name="我自己的API",
        )
    async def async_get_api_instance(self, llm_context: LLMContext) -> APIInstance:
        """返回API的实例。"""
        return APIInstance(
            api=self,
            api_prompt="调用工具从Home Assistant获取数据。",
            llm_context=llm_context,
            tools=[TimeTool()],
        )

async def async_setup_api(hass: HomeAssistant) -> None:
    """在Home Assistant中注册API。"""
    llm.async_register_api(hass, MyAPI())

llm.API 类具有以下属性:

名称类型描述
id字符串API的唯一标识符。必需。
name字符串API的名称。必需。

llm.APIInstance 类具有以下属性:

名称类型描述
apiAPIAPI对象。必需。
api_prompt字符串关于如何使用大语言模型工具的大语言模型指令。必需。
llm_contextLLMContext工具调用的上下文。必需。
toolslist[Tool]此API中可用的工具。必需。

总结

本文档主要介绍了Home Assistant与大语言模型交互的相关内容,包括内置辅助API及其功能,支持大语言模型API时在集成中的选项流程(涉及API选择的存储与展示给用户)和获取工具传递给大语言模型的操作,以及创建自己API的方法(需创建继承自 API 的类并实现 async_get_tools 方法),同时详细阐述了工具(Tool 类的属性和方法)和API(API 类及 APIInstance 类的属性)相关的概念与要求,为开发者在Home Assistant中集成大语言模型功能提供了全面的指导和规范。

您可能感兴趣的与本文相关的镜像

Qwen3-VL-8B

Qwen3-VL-8B

图文对话
Qwen3-VL

Qwen3-VL是迄今为止 Qwen 系列中最强大的视觉-语言模型,这一代在各个方面都进行了全面升级:更优秀的文本理解和生成、更深入的视觉感知和推理、扩展的上下文长度、增强的空间和视频动态理解能力,以及更强的代理交互能力

### 在 Home Assistant 中集成米家设备并与大型模型实现联动配置 Home Assistant 是一个开源的家庭自动化平台,支持接入多种智能家居设备,包括米家设备。通过结合大型语言模型(如 DeepSeek),可以实现基于自然语言理解的智能控制和自动化流程。以下是具体的集成与联动配置方法。 #### 1. 配置米家设备接入 Home Assistant Home Assistant 可以通过 `xiaomi_miot` 插件接入米家设备,支持包括传感器、开关、空调等多种类型设备。该插件提供了统一的接口,能够将米家设备的状态同步到 Home Assistant 平台中[^1]。 - **配置步骤**: - 安装并配置 Home Assistant。 - 在 Home Assistant 中安装 `xiaomi_miot` 插件。 - 添加米家账号并授权,确保设备成功接入。 - 查看设备状态和属性,确认其在 Home Assistant 中的实体 ID。 ```yaml # 示例:在 configuration.yaml 中添加小米 MIoT 配置 xiaomi_miot: username: YOUR_XIAOMI_USERNAME password: YOUR_XIAOMI_PASSWORD ``` #### 2. 集成大型语言模型(如 DeepSeek) 通过 Home Assistant 的 `input_text` 和 `input_boolean` 组件,可以构建自然语言处理流程。用户输入的语音指令或文本信息可以被提取并发送至大模型服务,模型返回的决策结果可用于触发设备控制逻辑。 - **实现方式**: - 使用 `python_script` 或 `command_line` 调用外部 API。 - 将用户输入的指令传递给 DeepSeek 模型。 - 解析模型输出,生成设备控制指令。 - 利用 Home Assistant 的服务调用接口执行控制操作。 ```yaml # 示例:在 Home Assistant 中定义服务调用 input_text: user_input: name: 用户输入 initial: "" input_boolean: model_response: name: 模型响应 initial: off script: process_input: sequence: - service: input_text.set_value target: entity_id: input_text.user_input data: value: "{{ trigger.event.data.text }}" - service: python_script.deepseek_process data: prompt: "{{ states('input_text.user_input') }}" - service: input_boolean.turn_on target: entity_id: input_boolean.model_response ``` #### 3. 实现设备联动与自动化控制 结合米家设备的状态信息和大模型的语义理解能力,可以实现复杂的自动化场景。例如,当传感器检测到特定事件(如温度过高、人体移动)时,系统可以自动调用模型进行分析,并根据分析结果触发相应的设备动作。 - **自动化场景示例**: - 当温度传感器检测到室内温度超过设定值时,自动调用模型判断是否需要开启空调。 - 当门窗传感器检测到异常开启时,模型生成应急响应方案并自动执行报警或通知操作。 ```yaml # 示例:基于传感器状态触发模型分析 automation: - alias: 温度异常处理 trigger: - platform: state entity_id: sensor.temperature_sensor above: 30 action: - service: python_script.deepseek_process data: prompt: "当前室内温度为 {{ states('sensor.temperature_sensor') }}°C,是否开启空调?" - service: switch.turn_on target: entity_id: switch.air_conditioner ``` #### 4. 语音交互与本地部署 为了提升响应速度和隐私保护,可以在本地部署大模型推理服务,并通过 Home Assistant 调用本地服务。例如使用 Hugging Face Transformers 或 vLLM 框架部署模型,结合 Docker 容器化部署,便于管理与扩展。 - **本地模型部署示例**: ```bash # 使用 Docker 部署本地模型服务 docker run -p 8080:8080 -v ./models:/models deepseek-mla:latest ``` - **Home Assistant 调用本地模型服务**: ```yaml # 示例:调用本地模型服务 rest_command: local_model: url: "http://localhost:8080/predict" method: POST payload: '{"prompt": "{{ prompt }}"}' content_type: "application/json" ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值