This page looks best with JavaScript enabled

The Concepts Anatomy of OpenClaw

 ·  ☕ 5 min read

the-matrix-architect

OpenClaw is the most populated self-hosted personal AI assistant in the world right now. From the perspective of an AI Agent developer, it is not only a AI tool, but also one of the best real-world references for agent design patterns. It helps us create more sophisticated designs when building our agents. In this article, I will go down the rabbit hole and ultimately build a conceptual model.

Conceptual Model

The following diagram is the conceptual model I built.

OpenClaw conceptual model

OpenClaw Conceptual Model (Open with Draw.io)

I built the model from two sources of truth:

  • The official documentation at https://docs.openclaw.ai/ . To verify the source of truth, You can open the diagram in draw.io and click the links to the documentation.
  • Tracing LLM prompt and tools-calling logs from a running OpenClaw

Documentation Analysis

The official documentation is rich in content. However, the pages are not organized as a step-by-step guide for building up concepts. As a result, I often get lost when navigating the documentation website. It lacks a conceptual map and the explicit relationships between concepts. After going though the pages, I tried my best to extract the relationships between concepts.

Mastering Prompt Inspection

The “secret sauce” of most AI applications lies within their LLM prompts. However, tracing LLM traffic can feel like falling down a rabbit hole of unstructured data.

Effective observability typically relies on two primary methos: tracing and sampling. In this setup, I use OpenRouter as the LLM gateway. It supports a tracing replication mechanism called Broadcast. I configured it sent tracing data to my publicly accessible self-hosted Langfuse service.

Environment Setup

To demonstrate prompt inspection, we need a scenarios where OpenClaw executes specific Skills. I used my self-hosted Home Assistant instance, which manages my smart home devices, as the target environment. To integrate the two, I installed the necessary skills from https://clawhub.ai/dbhurley/homeassistant into following directory:

~/.openclaw/workspace/skills/homeassistant .

Don’t forgot to set the environment variables. It may be configuared at ~/.openclaw/.env

HA_URL=http://your-ha-host:8123
HA_TOKEN=your_ha_token

Understanding Agent Skill Magic

Open the OpenClaw Dashboard and start a new chat session with the following prompt:

Any smart home device in my study room?

Why use OpenClaw Dashboard other than IM client? While OpenClaw supports popular IM clients like Telegram or WhatsApp, the native Dashboard is superior for development and debugging. Unlike standard chat interfaces, the dashboard provides a high-visibility “inspection mode”. It displays the exact tool-calling parameters the agent is preparing and the raw results returned by the system in real-time. The transparency is crucial for verifying.

Next, open the Langfuse Dashboard and navigate to the Tracing page, you will see a list of captured traces; let’s analysis the first two traces in chronological order. The analysis help us to understand the magic of agent skill discovery, loading and tool calling.

1. Skill Discovering

LLM Input - Messages:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
You are a personal assistant running inside OpenClaw.
...
## Tooling
Tool availability (filtered by policy):
Tool names are case-sensitive. Call tools exactly as listed.

- read: Read file contents
- write: Create or overwrite files
...
## Skills (mandatory)
Before replying: scan <available_skills> <description> entries.
- If exactly one skill clearly applies: read its SKILL.md at <location> with `read`, then follow it.
- If multiple could apply: choose the most specific one, then read/follow it.
- If none clearly apply: do not read any SKILL.md.
Constraints: never read more than one skill up front; only read after selecting.
The following skills provide specialized instructions for specific tasks.
Use the read tool to load a skill's file when the task matches its description.

<available_skills>
...
  <skill>
    <name>homeassistant</name>
    <description>Control Home Assistant - smart plugs, lights, scenes, automations.</description>
    <location>~/.openclaw/workspace/skills/homeassistant/SKILL.md</location>
  </skill>
</available_skills>

LLM Input - tools declare:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
tools: [
  {
    type: "function",
    function: {
      name: "read",
      description: "Read the contents of a file...",
      parameters: {
        type: "object",
        properties: {
          path: { "type": "string" },
...
          file_path: { "type": "string" }
        }
      }
    }
  }
]

LLM Output:

1
2
3
4
completion: "read{"path": "~/.openclaw/workspace/skills/homeassistant/SKILL.md"}"
reasoning: "The user is asking about smart home devices in their study room. This seems like it would relate to Home Assistant, which I can see is available as a skill. Let me check if this matches the homeassistant skill description: "Control Home Assistant - smart plugs, lights, scenes, automations." - yes, this seems like a perfect match.

According to the skills instructions, I should read the SKILL.md file when a task matches a skill's description, and this clearly does."

The LLM initiates a tool call to read the skill documentation: "read{"path": "~/.openclaw/workspace/skills/homeassistant/SKILL.md"}"

2. Skill Loading

Upon receiving the tool call from LLM, the agent executes the read function to load the contents of ~/.openclaw/workspace/skills/homeassistant/SKILL.md and sends it back.

LLM Input:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
messages: [
    ...
    {
role: "tool"
content: "---
name: homeassistant
description: Control Home Assistant - smart plugs, lights, scenes, automations.
homepage: https://www.home-assistant.io/
metadata: {"clawdis":{"emoji":"🏠","requires":{"bins":["curl"],"env":["HA_TOKEN"]},"primaryEnv":"HA_TOKEN"}}
---

# Home Assistant

Control smart home devices via Home Assistant API.

## Setup

Set environment variables:
- `HA_URL`: Your Home Assistant URL (e.g., `http://192.168.1.100:8123`)
- `HA_TOKEN`: Long-lived access token (create in HA → Profile → Long-Lived Access Tokens)

## Quick Commands

### List entities by domain
```bash
curl -s "$HA_URL/api/states" -H "Authorization: Bearer $HA_TOKEN" | \
  jq -r '.[] | select(.entity_id | startswith("switch.")) | .entity_id'
```
...

LLM output:

1
completion: "exec{"command": "curl -s \"$HA_URL/api/states\" -H \"Authorization: Bearer $HA_TOKEN\" | jq -r '.[] | select(.attributes.area_name // .attributes.room // .entity_id | contains(\"study\")) | {entity_id: .entity_id, name: .attributes.friendly_name, state: .state, area: (.attributes.area_name // \"N/A\")}' | head -20"}"

After learning from the documentation of homeassistant skill, the LLM initiates an exec tool call to access the Home Assistant HTTP API. What is particularly clever here is the security design: the agent does not pass literal tokens or credentials to the LLM. Instead, the skill utilizes environment variables, ensuring that sensitive secrets are never exposed within the LLM’s context or stored in the trace history.

Share on

Mark Zhu
WRITTEN BY
Mark Zhu
我在找工作 | I'm open to work