Erfahren Sie, wie Sie einen Agenten erstellen, der den Kontext Ihres Zuhauses versteht, Ihre Vorlieben lernt und mit Ihnen und Ihrem Zuhause interagiert, um Aktivitäten durchzuführen, die Sie für wertvoll halten.

12 Min. Lektüre

Vor 15 Stunden

Foto von Igor Omilaev An Unsplash

Dieser Artikel beschreibt die Architektur und das Design eines Heimassistent (HA) Integration namens House-Generative-Agent. Dieses Projekt verwendet LangChain Und LangGraph eine erstellen generativer KI-Agent das mit einer HA-Good-House-Umgebung interagiert und Aufgaben darin automatisiert. Der Makler versteht den Kontext Ihres Zuhauses, lernt Ihre Vorlieben kennen und interagiert mit Ihnen und Ihrem Zuhause, um Aktivitäten durchzuführen, die Sie für wertvoll halten. Zu den Hauptfunktionen gehören die Erstellung von Automatisierungen, die Analyse von Bildern und die Verwaltung von Heimatzuständen mithilfe verschiedener LLMs (Massive Language Fashions). Die Architektur umfasst sowohl cloudbasierte als auch Edge-basierte Modelle für optimale Leistung und Kosteneffizienz. Installationsanweisungen, Konfigurationsdetails und Informationen zur Architektur des Projekts und den verschiedenen verwendeten Modellen sind enthalten und können auf der Web site gefunden werden House-Generative-Agent GitHub. Das Projekt ist Open Supply und freut sich über Beiträge.

Dies sind einige der derzeit unterstützten Funktionen:

  • Erstellen Sie komplexe House Assistant-Automatisierungen.
  • Bildszenenanalyse und -verständnis.
  • Heimatzustandsanalyse von Entitäten, Geräten und Bereichen.
  • Vollständige Agentenkontrolle über zulässige Einheiten im Haus.
  • Kurz- und Langzeitgedächtnis mittels semantischer Suche.
  • Automatische Zusammenfassung des Heimatstatus zur Verwaltung der LLM-Kontextlänge.

Dies ist mein persönliches Projekt und ein Beispiel für das, was ich nenne lerngesteuertes Hacken. Das Projekt steht in keinem Zusammenhang mit meiner Arbeit bei Amazon, noch stehe ich in irgendeiner Weise mit den für House Assistant oder LangChain/LangGraph verantwortlichen Organisationen in Verbindung.

Das Erstellen eines Agenten zur Überwachung und Steuerung Ihres Zuhauses kann zu unerwarteten Aktionen führen und möglicherweise Ihr Zuhause und sich selbst aufgrund von LLM-Halluzinationen und Datenschutzbedenken einem Risiko aussetzen, insbesondere wenn Heimzustände und Benutzerinformationen cloudbasierten LLMs ausgesetzt werden. Ich habe vernünftige architektonische und gestalterische Entscheidungen getroffen, um diese Risiken zu mindern, aber sie können nicht vollständig beseitigt werden.

Eine wichtige frühe Entscheidung battle, auf einen Hybrid-Cloud-Edge-Ansatz zu setzen. Dies ermöglicht die Verwendung der ausgefeiltesten verfügbaren Argumentations- und Planungsmodelle, die dazu beitragen sollen, Halluzinationen zu reduzieren. Zur weiteren Minimierung von LLM-Fehlern werden einfachere, stärker aufgabenorientierte Kantenmodelle eingesetzt.

Eine weitere wichtige Entscheidung bestand darin, die Funktionen von LangChain zu nutzen, die es ermöglichen, vertrauliche Informationen vor LLM-Instruments zu verbergen und nur zur Laufzeit bereitzustellen. Die Software-Logik erfordert beispielsweise möglicherweise die Verwendung der ID des Benutzers, der eine Anfrage gestellt hat. Allerdings sollten solche Werte grundsätzlich nicht vom LLM kontrolliert werden. Die Manipulation der Benutzer-ID durch das LLM könnte Sicherheits- und Datenschutzrisiken mit sich bringen. Um dies zu mildern, habe ich das genutzt InjectedToolArg Anmerkung.

Darüber hinaus verursacht die Verwendung großer cloudbasierter LLMs erhebliche Cloud-Kosten, und die für die Ausführung von LLM-Edge-Modellen erforderliche Edge-{Hardware} kann teuer sein. Die kombinierten Betriebs- und Installationskosten dürften für den durchschnittlichen Benutzer derzeit unerschwinglich sein. Es bedarf einer branchenweiten Anstrengung, „LLMs so günstig wie CNNs zu machen“, um heimische Agenten auf den Massenmarkt zu bringen.

Es ist wichtig, sich dieser Risiken bewusst zu sein und zu verstehen, dass wir uns trotz dieser Abhilfemaßnahmen noch im Anfangsstadium dieses Projekts und der Hausmakler im Allgemeinen befinden. Es bleibt noch viel zu tun, um diese Agenten zu wirklich nützlichen und vertrauenswürdigen Assistenten zu machen.

Unten finden Sie eine allgemeine Ansicht der House-Generative-Agent-Architektur.

Diagramm von Lindo St. Angel

Die allgemeine Integrationsarchitektur folgt den Finest Practices, wie in beschrieben House Assistant Core und ist konform mit House Assistant Group Retailer (HACS) Veröffentlichungsanforderungen.

Der Agent wird mit LangGraph erstellt und nutzt die HA Gespräch Komponente zur Interaktion mit dem Benutzer. Der Agent verwendet die House Assistant LLM-API, um den Zustand des Hauses abzurufen und die ihm zur Verfügung stehenden nativen HA-Instruments zu verstehen. Alle anderen dem Agenten zur Verfügung stehenden Instruments habe ich mit LangChain implementiert. Der Agent verwendet mehrere LLMs, ein großes und sehr genaues Primärmodell für Excessive-Stage-Argumentation, kleinere spezialisierte Hilfsmodelle für die Kamerabildanalyse, eine Primärmodell-Kontextzusammenfassung und eine Einbettungsgenerierung für die langfristige semantische Suche. Das Primärmodell ist cloudbasiert und die Hilfsmodelle sind Edge-basiert und laufen unter dem Ollama Framework auf einem Laptop zu Hause installieren.

Nachfolgend sind die derzeit verwendeten Modelle zusammengefasst.

LangGraph-basierter Agent

LangGraph unterstützt den Konversationsagenten und ermöglicht es Ihnen, so schnell wie möglich zustandsbehaftete Multi-Akteur-Anwendungen unter Verwendung von LLMs zu erstellen. Es erweitert die Fähigkeiten von LangChain und bietet die Möglichkeit, zyklische Diagramme zu erstellen und zu verwalten, die für die Entwicklung komplexer Agentenlaufzeiten unerlässlich sind. Ein Diagramm modelliert den Agenten-Workflow, wie im Bild unten dargestellt.

Diagramm von Lindo St. Angel

Der Agenten-Workflow verfügt über fünf Knoten, wobei jedes Python-Modul den Standing des Agenten ändert, eine gemeinsame Datenstruktur. Die Kanten zwischen den Knoten stellen die zulässigen Übergänge zwischen ihnen dar, wobei durchgezogene Linien bedingungslos und gestrichelte Linien bedingt sind. Knoten erledigen die Arbeit und Kanten sagen, was als nächstes zu tun ist.

Der __Start__ Und __Ende__ Knoten informieren den Graphen darüber, wo er beginnen und enden soll. Der Agent Der Knoten führt das primäre LLM aus, und wenn er sich für die Verwendung eines Instruments entscheidet, wird das Aktion Der Knoten führt das Software aus und gibt dann die Kontrolle an den zurück Agent. Der summary_and_trim Der Knoten verarbeitet den Kontext des LLM, um das Wachstum zu verwalten und gleichzeitig die Genauigkeit beizubehalten Agent verfügt über kein Software zum Anrufen und die Anzahl der Nachrichten erfüllt die unten genannten Bedingungen.

LLM-Kontextmanagement

Sie müssen die Kontextlänge von LLMs sorgfältig verwalten, um Kosten, Genauigkeit und Latenz auszugleichen und das Auslösen von Ratenbegrenzungen wie der Token-pro-Minute-Beschränkung von OpenAI zu vermeiden. Das System steuert die Kontextlänge des Primärmodells auf zwei Arten: Es kürzt die Nachrichten im Kontext, wenn sie einen maximalen Parameter überschreiten, und der Kontext wird zusammengefasst, sobald die Anzahl der Nachrichten einen anderen Parameter überschreitet. Diese Parameter sind in konfigurierbar const.py; Ihre Beschreibung finden Sie weiter unten.

  • CONTEXT_MAX_MESSAGES | Nachrichten, die vor dem Löschen im Kontext bleiben | Commonplace = 100
  • CONTEXT_SUMMARIZE_THRESHOLD | Nachrichten im Kontext vor der Zusammenfassungsgenerierung | Commonplace = 20

Der summary_and_trim Der Knoten im Diagramm schneidet die Nachrichten erst nach der Inhaltszusammenfassung ab. Sie können den diesem Knoten zugeordneten Python-Code im folgenden Snippet sehen.

async def _summarize_and_trim(
state: State, config: RunnableConfig, *, retailer: BaseStore
) -> dict(str, listing(AnyMessage)):
"""Coroutine to summarize and trim message historical past."""
abstract = state.get("abstract", "")

if abstract:
summary_message = SUMMARY_PROMPT_TEMPLATE.format(abstract=abstract)
else:
summary_message = SUMMARY_INITIAL_PROMPT

messages = (
(SystemMessage(content material=SUMMARY_SYSTEM_PROMPT)) +
state("messages") +
(HumanMessage(content material=summary_message))
)

mannequin = config("configurable")("vlm_model")
choices = config("configurable")("choices")
model_with_config = mannequin.with_config(
config={
"mannequin": choices.get(
CONF_VLM,
RECOMMENDED_VLM,
),
"temperature": choices.get(
CONF_SUMMARIZATION_MODEL_TEMPERATURE,
RECOMMENDED_SUMMARIZATION_MODEL_TEMPERATURE,
),
"top_p": choices.get(
CONF_SUMMARIZATION_MODEL_TOP_P,
RECOMMENDED_SUMMARIZATION_MODEL_TOP_P,
),
"num_predict": VLM_NUM_PREDICT,
}
)

LOGGER.debug("Abstract messages: %s", messages)
response = await model_with_config.ainvoke(messages)

# Trim message historical past to handle context window size.
trimmed_messages = trim_messages(
messages=state("messages"),
token_counter=len,
max_tokens=CONTEXT_MAX_MESSAGES,
technique="final",
start_on="human",
include_system=True,
)
messages_to_remove = (m for m in state("messages") if m not in trimmed_messages)
LOGGER.debug("Messages to take away: %s", messages_to_remove)
remove_messages = (RemoveMessage(id=m.id) for m in messages_to_remove)

return {"abstract": response.content material, "messages": remove_messages}

Latenz

Die Latenz zwischen Benutzeranfragen oder dem zeitnahen Handeln des Agenten im Namen des Benutzers ist für Sie von entscheidender Bedeutung und muss beim Entwurf berücksichtigt werden. Ich habe mehrere Techniken verwendet, um die Latenz zu reduzieren, einschließlich der Verwendung spezieller, kleinerer Hilfs-LLMs, die am Edge ausgeführt werden, und der Erleichterung des Zwischenspeicherns von Eingabeaufforderungen für primäre Modelle, indem ich die Eingabeaufforderungen so strukturiert habe, dass sie statische Inhalte wie Anweisungen und Beispiele im Voraus und variable Inhalte wie benutzerspezifisch bereitstellen Informationen am Ende. Diese Techniken reduzieren auch die Nutzungskosten des Primärmodells erheblich.

Unten sehen Sie die typische Latenzleistung.

  • HA-Absichten (z. B. ein Licht einschalten) | < 1 Sekunde
  • Kamerabild analysieren (erste Anfrage) | < 3 Sekunden
  • Automatisierung hinzufügen | < 1 Sekunde
  • Speicheroperationen | < 1 Sekunde

Werkzeuge

Der Agent kann HA-Instruments wie in angegeben verwenden LLM-API und andere im LangChain-Framework integrierte Instruments, wie in definiert instruments.py. Darüber hinaus können Sie die LLM-API auch mit eigenen Instruments erweitern. Der Code gibt dem primären LLM die Liste der Instruments, die er aufrufen kann, zusammen mit Anweisungen zu deren Verwendung in seiner Systemmeldung und im Dokumentstring der Python-Funktionsdefinition des Instruments. Ein Beispiel für Docstring-Anweisungen finden Sie im Code-Snippet unten für get_and_analyze_camera_image Werkzeug.

@device(parse_docstring=False)
async def get_and_analyze_camera_image( # noqa: D417
camera_name: str,
detection_keywords: listing(str) | None = None,
*,
# Cover these arguments from the mannequin.
config: Annotated(RunnableConfig, InjectedToolArg()),
) -> str:
"""
Get a digital camera picture and carry out scene evaluation on it.

Args:
camera_name: Title of the digital camera for scene evaluation.
detection_keywords: Particular objects to search for in picture, if any.
For instance, If consumer says "examine the entrance porch digital camera for
containers and canines", detection_keywords could be ("containers", "canines").

"""
hass = config("configurable")("hass")
vlm_model = config("configurable")("vlm_model")
choices = config("configurable")("choices")
picture = await _get_camera_image(hass, camera_name)
return await _analyze_image(vlm_model, choices, picture, detection_keywords)

Wenn sich der Agent für die Verwendung eines Instruments entscheidet, wird der LangGraph-Knoten verwendet Aktion wird eingegeben und der Code des Knotens führt das Software aus. Der Knoten verwendet einen einfachen Fehlerwiederherstellungsmechanismus, der den Agenten auffordert, im Falle eines Fehlers erneut zu versuchen, das Software mit korrigierten Parametern aufzurufen. Der folgende Codeausschnitt zeigt den damit verbundenen Python-Code Aktion Knoten.

async def _call_tools(
state: State, config: RunnableConfig, *, retailer: BaseStore
) -> dict(str, listing(ToolMessage)):
"""Coroutine to name House Assistant or langchain LLM instruments."""
# Software calls would be the final message in state.
tool_calls = state("messages")(-1).tool_calls

langchain_tools = config("configurable")("langchain_tools")
ha_llm_api = config("configurable")("ha_llm_api")

tool_responses: listing(ToolMessage) = ()
for tool_call in tool_calls:
tool_name = tool_call("identify")
tool_args = tool_call("args")

LOGGER.debug(
"Software name: %s(%s)", tool_name, tool_args
)

def _handle_tool_error(err:str, identify:str, tid:str) -> ToolMessage:
return ToolMessage(
content material=TOOL_CALL_ERROR_TEMPLATE.format(error=err),
identify=identify,
tool_call_id=tid,
standing="error",
)

# A langchain device was known as.
if tool_name in langchain_tools:
lc_tool = langchain_tools(tool_name.decrease())

# Present hidden args to device at runtime.
tool_call_copy = copy.deepcopy(tool_call)
tool_call_copy("args").replace(
{
"retailer": retailer,
"config": config,
}
)

strive:
tool_response = await lc_tool.ainvoke(tool_call_copy)
besides (HomeAssistantError, ValidationError) as e:
tool_response = _handle_tool_error(repr(e), tool_name, tool_call("id"))
# A House Assistant device was known as.
else:
tool_input = llm.ToolInput(
tool_name=tool_name,
tool_args=tool_args,
)

strive:
response = await ha_llm_api.async_call_tool(tool_input)

tool_response = ToolMessage(
content material=json.dumps(response),
tool_call_id=tool_call("id"),
identify=tool_name,
)
besides (HomeAssistantError, vol.Invalid) as e:
tool_response = _handle_tool_error(repr(e), tool_name, tool_call("id"))

LOGGER.debug("Software response: %s", tool_response)
tool_responses.append(tool_response)
return {"messages": tool_responses}

Die LLM-API weist den Agenten an, Instruments immer über HA aufzurufen Integrierte Absichten beim Steuern von House Assistant und zum Verwenden der Absichten „HassTurnOn“ zum Sperren und „HassTurnOff“ zum Entsperren einer Sperre. Eine Absicht beschreibt die Absicht eines Benutzers, die durch Benutzeraktionen generiert wird.

Unten sehen Sie die Liste der LangChain-Instruments, die der Agent verwenden kann.

  • get_and_analyze_camera_image | Führen Sie eine Szenenanalyse für das Bild einer Kamera durch
  • upsert_memory | einen Speicher hinzufügen oder aktualisieren
  • add_automation | Erstellen und registrieren Sie eine HA-Automatisierung
  • get_entity_history | Fragen Sie die HA-Datenbank nach dem Entitätsverlauf ab

{Hardware}

Ich habe die HA-Set up auf einem Raspberry Pi 5 mit SSD-Speicher, Zigbee und LAN-Konnektivität erstellt. Ich habe die Edge-Modelle unter Ollama auf einem Ubuntu-basierten Server mit einer AMD 64-Bit-CPU mit 3,4 GHz, einer Nvidia 3090-GPU und 64 GB System-RAM bereitgestellt. Der Server befindet sich im selben LAN wie der Raspberry Pi.

Ich verwende dieses Projekt seit einigen Wochen zu Hause und finde es nützlich, aber in einigen Bereichen, an denen ich arbeiten werde, frustrierend. Nachfolgend finden Sie eine Liste der Vor- und Nachteile meiner Erfahrungen mit dem Agenten.

Vorteile

  • Die Kamerabild-Szenenanalyse ist sehr nützlich und flexibel, da Sie quick alles abfragen können und sich nicht wie bei einem herkömmlichen ML-Ansatz um den richtigen Klassifikator kümmern müssen.
  • Automatisierungen sind sehr einfach einzurichten und können recht komplex sein. Es ist überwältigend, wie intestine das primäre LLM bei der Generierung von HA-konformem YAML ist.
  • Die Latenz ist in den meisten Fällen durchaus akzeptabel.
  • Mit LangChain und LangGraph ist es sehr einfach, zusätzliche LLM-Instruments und Diagrammzustände hinzuzufügen.

Nachteile

  • Die Kamerabildanalyse scheint weniger genau als herkömmliche ML-Ansätze. Beispielsweise ist es für das Modell sehr schwierig, Pakete zu erkennen, die teilweise verdeckt sind.
  • Die Kosten für die Primärmodellierung sind hoch. Der Betrieb eines einzelnen Paketdetektors alle 30 Minuten kostet etwa 2,50 US-Greenback professional Tag.
  • Die Verwendung strukturierter Modellausgaben für die Hilfs-LLMs, die die nachgelagerte LLM-Verarbeitung erleichtern würden, verringert die Genauigkeit erheblich.
  • Der Agent muss proaktiver sein. Durch das Hinzufügen eines Planungsschritts zum Agentendiagramm wird dieses Drawback hoffentlich behoben.

Hier sind einige Beispiele dafür, was Sie mit der House-Generative-Agent (HGA)-Integration tun können, wie durch Screenshots des Help-Dialogs veranschaulicht, die ich während der Interaktionen mit meiner HA-Set up gemacht habe.

Bild von Lindo St. Angel
  • Erstellen Sie eine Automatisierung, die regelmäßig ausgeführt wird.
Bild von Lindo St. Angel

Der folgende Ausschnitt zeigt, dass der Agent YAML basierend auf dem, was er generiert und als HA-Automatisierung registriert hat, fließend beherrscht.

alias: Verify Litter Field Waste Drawer
triggers:
- minutes: /30
set off: time_pattern
circumstances:
- situation: numeric_state
entity_id: sensor.litter_robot_4_waste_drawer
above: 90
actions:
- knowledge:
message: The Litter Field waste drawer is greater than 90% full!
motion: notify.notify
Bild von Lindo St. Angel
  • Überprüfen Sie mehrere Kameras (Video vom Autor).

https://github.com/user-attachments/property/230baae5-8702-4375-a3f0-ffa981ee66a3

  • Fassen Sie den Heimatstaat zusammen (Video des Autors).

https://github.com/user-attachments/property/96f834a8-58cc-4bd9-a899-4604c1103a98

  • Langzeitgedächtnis mit semantischer Suche.

Von admin

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert