Core Concept
The central idea is prompt composition:- Agents define “who” the AI is (personality, specialization, tone).
- Skills define “what” it must know/obey (rules, knowledge, compliance).
Benefits
Reuse
Skills can be shared across multiple agents.
Versioning
.md files can be versioned in Git.Collaboration
Teams can share agents and skills.
Consistency
Coding style rules applied automatically.
Specialization
Create agents for Go, Python, DevOps, etc.
Dispatch as Worker
Custom agents are automatically registered in the multi-agent system and can be dispatched via
agent_call by the LLM orchestrator.Skill Auto-activation
Skills with
triggers: or paths: in their frontmatter are automatically injected into the system prompt when detected in the user’s message.Per-Agent Model & Effort
Each skill and each agent can declare ideal
model: and effort: — the dispatcher routes correctly without changing the user’s active choice.Directory Structure
Files live under~/.chatcli/:
Agent File Format
Agents are Markdown files with YAML frontmatter:tools Field — Multi-Agent Integration
The tools field in the YAML frontmatter is the key to integration with the multi-agent orchestration system. It defines which commands the agent can use when dispatched as a worker by the LLM orchestrator.
| Tool in YAML | @coder Command(s) | Description |
|---|---|---|
Read | read | Read file contents |
Grep | search | Search patterns in files |
Glob | tree | List directories |
Bash | exec, test, git-status, git-diff, git-log, git-changed, git-branch | Command execution and git operations |
Write | write | Create/overwrite files |
Edit | patch | Precise edits (search/replace) |
MultiEdit | multipatch | Transactional multi-file edit with all-or-nothing rollback |
Example without tools
This agent will be registered as read-only in the multi-agent system (only
read, search, tree).Advanced Agent Frontmatter
Recent releases bring full parity between agents and skills for LLM preference fields. Both are optional and backwards compatible — agents without these fields keep working exactly as before.| Field | Type | Default | Description |
|---|---|---|---|
model | string | — | Preferred model when this agent runs as a worker. If the user is on a different model/provider, the dispatcher attempts a transparent swap (same provider → catalog → family; cross-provider when available). |
effort | string | — | Effort level: low, medium, high, max. Maps to extended thinking (Anthropic) / reasoning_effort (OpenAI) on supported providers. |
category | string | — | Category for organization (e.g., devops, security, review). |
version | string | — | Agent version (SemVer recommended). |
author | string | — | Agent author. |
tags | list|string | — | Tags for search and classification. Accepts YAML list or comma-separated string. |
How the Dispatcher Applies Model/Effort
When the orchestrator LLM dispatches an agent via<agent_call>, the dispatcher:
Reads `agent.Model()` and `agent.Effort()`
For custom agents these come from the frontmatter. For built-ins they come from
BuiltinAgentMeta (defaults + env var override).If `Model()` is non-empty, runs the Model Router
The resolver tries, in order: API cache of the active provider → static catalog → family heuristic (
claude-*, gpt-*, gemini-*, etc.) → optimistic fallback on the user’s provider. If the target provider is not configured (no API key), it gracefully falls back to the user’s client and logs a clear warning.If `Effort()` is non-empty, attaches to the worker `ctx`
Providers read the hint via
client.EffortFromContext(ctx) inside SendPrompt and inject thinking.budget_tokens (Anthropic) or reasoning.effort / reasoning_effort (OpenAI) into the request body — only on models that support it.Example: Custom Agent with Ideal Model
Skill File Format
Skills contain pure knowledge or compliance rules:Skills V2 — Packages with Subskills and Scripts
Beyond V1 skills (single.md file), ChatCLI supports V2 Skills: directories with multiple documents and executable scripts.
V2 Skill Structure
Subskills
.md files inside the skill directory (except SKILL.md) are registered as subskills. When the agent is dispatched as a worker, subskill paths appear in the worker’s system prompt, which can read them as needed.
Scripts
Files inscripts/ are registered as executable skills on the worker. The system automatically infers the run command from the extension:
| Extension | Inferred Command |
|---|---|
.sh | bash script.sh |
.py | python3 script.py |
.js | node script.js |
.ts | npx ts-node script.ts |
.rb | ruby script.rb |
| Others | ./script (direct execution) |
@coder exec command and their results return to the worker.
Advanced Skill Frontmatter
Beyond the basic fields (name, description, allowed-tools), skills support advanced frontmatter for fine-grained behavior control. All advanced fields are optional and backwards compatible — existing skills keep working unchanged.
Automatic Activation: triggers
Keywords that activate the skill automatically when detected in the user message. Case-insensitive, substring match.
pkg/persona/manager.go#FindTriggeredSkills. Detection runs on every chat turn and once at the start of agent/coder mode.
Automatic Activation: paths
File globs that activate the skill when matching files are being discussed. Supports *, ** (recursive doublestar), and ?.
@file path/..., @path/to/file.go, or bare tokens like pkg/foo/bar_test.go and main.go) and matches each against the paths: patterns of every installed skill.
Examples that trigger *_test.go:
"run the tests in pkg/foo/bar_test.go""@file pkg/foo/bar_test.go""@pkg/foo/bar_test.go"
pkg/persona/types.go#MatchesPath (with a custom doublestar matcher, zero external deps) and pkg/persona/manager.go#FindPathMatchedSkills. Path extraction from input is in cli/skill_activation.go#extractFilePaths.
model and effort Propagation
When a skill auto-activates (via triggers or paths), is pinned (/skill pin), or is manually invoked, its model: and effort: are propagated to the current turn:
model:— the dispatcher/resolver swaps the LLM client for this turn. Works within the same provider (e.g.,sonnet→opuson Claude) or cross-provider (e.g., user on Claude, skill wantsgpt-5on OpenAI). If the target provider is not configured, it falls back to the user’s client with a visible notice.effort:— mapped tothinking.budget_tokens(Anthropic, Opus 4.x / Sonnet 4.x / 3.7 models) orreasoning_effort/reasoning.effort(OpenAI, o1/o3/o4/gpt-5 models). Unsupported models silently ignore.
model: in this order wins; subsequent conflicts are logged as warnings but don’t force additional swaps.
Manual Invocation via /<skill-name>
Skills with user-invocable: true are available as direct slash commands:
/<skill-name> ahead of the default router, validates that the skill exists with user-invocable: true, loads its content, displays the argument-hint (when args are empty), and fires the turn with the skill injected as a ”# Manually Invoked Skill” block in the system prompt — taking precedence over auto-activated skills.
The protected command list (/agent, /coder, /run, /switch, /help, /skill, etc.) can never be shadowed by a skill — even a skill named agent won’t shadow the built-in command.
Slash command autocomplete also includes all user-invocable: true skills, showing description and argument-hint side by side.
Invocation Control
| Field | Type | Default | Description |
|---|---|---|---|
user-invocable | bool | false | Enables invocation via /skill-name |
disable-model-invocation | bool | false | Blocks automatic activation via triggers/paths (user can still invoke manually if user-invocable: true) |
argument-hint | string | — | Text shown in autocomplete and as a hint when invoked without args |
disable-model-invocation: true together with user-invocable: true = the skill only runs when the user types /skill-name, never through automatic detection. Useful for destructive or highly specific skills.Pin a Skill for the Session (/skill pin)
When you need a skill to apply to every turn of the session — not only those that match triggers:/paths: — pin it:
# Pinned Skills block in the system prompt, cacheable via cache_control: ephemeral. On hint conflicts, pinned beats auto-activation but loses to a manual /<skill-name> invocation.
Skills with disable-model-invocation: true cannot be pinned — the flag exists precisely to forbid automatic injection. Use manual /<skill-name> for those.
Full details, examples, and the precedence table: Pin Skills in Skill Registry.
/agent Without Context
Before: typing /agent alone entered agent mode immediately and sent an empty message to the LLM.
Now: typing /agent (or /run) without an inline task prints the persona handler help plus a usage hint and does not start the ReAct loop. Same applies to /coder. This avoids token burn on empty messages and makes the UX more predictable.
Skills from Remote Registries
Besides creating skills manually, you can search and install skills from remote registries via the/skill command:
Skills installed via registry are saved in
~/.chatcli/skills/<name>/SKILL.md as V2 packages and are immediately available for agents. ChatCLI supports multiple registries simultaneously (ChatCLI.dev, ClawHub, corporate registries) with fan-out parallel search. See Skill Registry for full details.Dispatch as Worker (Multi-Agent)
When starting/coder or /agent, all custom agents are automatically registered in the multi-agent orchestration system. The LLM orchestrator can then dispatch them via <agent_call>:
What the worker gets
When dispatched, CustomAgent runs with:Personalized system prompt
Includes agent content (markdown body), loaded skills, subskill paths, script commands, and tool_call instructions.
Per-turn resolved client
If the agent declares
model:, the dispatcher calls ResolveModelRouting to obtain the correct client before each mini-ReAct turn.Effort applied to ctx
If the agent declares
effort:, the worker’s ctx receives WithEffortHint, read by the provider inside SendPrompt.End-to-End Example
Management Commands
All management commands are integrated under/agent:
| Command | Description |
|---|---|
/agent | Shows active agent status and help (does not enter agent mode without a task) |
/agent list | Lists all available agents |
/agent status | Lists only attached agents (short) — alias: attached, list-attached |
/agent load <name> | Loads a specific agent |
/agent attach <name> | Attaches an additional agent to the session |
/agent detach <name> | Removes an attached agent |
/agent skills | Lists all available skills |
/agent show [--full] | Shows the active agent with example prompts (use --full for everything) |
/agent off | Deactivates all currently active agents |
/agent <task> | Executes a task in agent mode |
Prompt Assembly Order
When an agent is loaded, the system prompt is assembled in this order:
This ordering ensures the AI receives context in a structured way, with explicit user intent (manual) taking precedence over auto-activation.
Full Practical Example
1. Create an agent
Create the file~/.chatcli/agents/python-data.md:
2. Use the agent
Agent and Skill Precedence (Project > Global)
Both agents and skills support per-project directories with precedence over the globals. ChatCLI auto-detects the project root by looking for a.agent/ or .git/ directory upward from the current directory.
Search Order
| Resource | 1. Project (priority) | 2. Global (fallback) |
|---|---|---|
| Agents | ./.agent/agents/*.md | ~/.chatcli/agents/*.md |
| Skills | ./.agent/skills/ | ~/.chatcli/skills/ |
Project Structure
Integration with /coder
When an agent is loaded:
/agent <task>— Uses the agent’s persona./coder <task>— Combines the agent’s persona with the coder prompt.
@coder tools to edit files, run tests, etc. The agent’s model: and effort: preferences are honored in both modes.
Tips
Start Simple
Create agents with a few skills and add more as needed.
Version on Git
Keep your agents and skills in a repo.
Share with the Team
Coding-style skills enforce consistency.
Use Clear Descriptions
Helps understand each agent/skill’s purpose.
Test the Prompt
Use
/agent show to inspect the assembled prompt.Assign `effort` Carefully
effort: high costs more tokens. Reserve it for agents that truly need deep reasoning (reviewers, planners, diagnostics).Useful Skill Examples
- clean-code — Clean code principles
- error-handling — Error handling patterns
- testing-patterns — Automated testing patterns
- docker-master — Dockerfile best practices
- clean-scripts — Safe Bash scripting patterns
- aws-security — AWS security rules
- team-conventions — Team-specific conventions
Remote Agents and Skills
When connected to a ChatCLI server viachatcli connect, the client automatically discovers agents and skills available on the server. They are transferred to the client and composed locally, allowing merge with local resources.
Since the recent update, the gRPC wire (pb.AgentInfo) carries all the advanced fields — model, effort, category, version, author, tags — so remote agents behave exactly like local ones for routing purposes.
Provisioning via Kubernetes
- Helm
- Operator
ConfigMaps are mounted at
/home/chatcli/.chatcli/agents/ and /home/chatcli/.chatcli/skills/, and are available for remote discovery automatically. Advanced frontmatter fields (model, effort, category, etc.) are read by the chatcli binary inside the pod — the CRD and operator do not need changes to support them.Next steps
Multi-Agent Orchestration
How multiple custom agents run in parallel via
<agent_call>.Skill Registry
Publish and discover skills shared across teams.
Subagent Delegation
Focused delegation for concentrated analysis over a large payload.
Server Mode
Distribute agents via ConfigMap to the entire team.