| author | Nexu |
|---|
ๆ ธๅฟๆดๅฏ๏ผ Skill ไธๆฏ Toolโโๅฎๆฏไธ็ป็ธๅ ณ Toolใๆๆกฃๅ่กไธบ่งๅๆๅ ๆ็่ฝๅๅๅ ใSkill ็ณป็ปๆ"100 ไธช Tool ๅก่ฟๆฏไธช Prompt"ๅๆไบ"ๆ้ๅ ่ฝฝ็่ฝๅ่ๅ"๏ผ่็ๆฐๅ Token ๅนถๅคงๅน ๆๅ Tool ้ๆฉๅ็กฎ็ใ
Tool ๆฏๆจกๅๅฏไปฅ่ฐ็จ็ๅไธชๅฝๆฐใSkill ๆฏไธไธชๆๅ ็่ฝๅๅๅ ๏ผๅ ๅซ๏ผ
- Tool โโ ไธไธชๆๅคไธช็ธๅ ณ็ๅฝๆฐ Schema ๅๅค็ๅจ
- ๆๆกฃ โโ ไธไธช SKILL.md ๆไปถ๏ผ่ฏดๆไฝๆถไปฅๅๅฆไฝไฝฟ็จ่ฟไธช Skill
- ่กไธบ่งๅ โโ ๆจกๅ้่ฆ้ตๅพช็็บฆๆใๆจกๅผๅๆฏไพ
skill/
โโโ SKILL.md # Documentation: when to use, how to use, constraints
โโโ tools.py # Tool implementations
โโโ schema.json # Tool schemas (or generated from code)
ไพๅฆ๏ผไธไธช git Skill ไธๆฏๆด้ฒไธไธชๅไธ็ git Toolโโๅฎๆๅ
ไบ git_statusใgit_diffใgit_commitใgit_pushใgit_log๏ผๅนถๅ
ๅซไบ commit message ่ง่ใๅๆฏๅฝๅๅไฝๆถ้่ฆ็กฎ่ฎคๅ push ็ๆๆกฃใ
| Tool | Skill | |
|---|---|---|
| ่ๅด | ๅไธชๅฝๆฐ | ไธ็ป็ธๅ ณๅฝๆฐ |
| ๆๆกฃ | ๅๆฐๆ่ฟฐ | ๅฎๆด็ SKILL.md๏ผๅซ็คบไพๅๆฏไพ |
| ๅ ่ฝฝๆนๅผ | ๅง็ปๅญๅจๆไธๅญๅจ | ไป่ๅๆ้ๅ ่ฝฝ |
| Context ๆๆฌ | ๆฏไธช Schema ็บฆ 100โ200 Token | ่ๅ้กน็บฆ 200 Token + ๅ ่ฝฝๅ็บฆ 1,000 Token |
| ่กไธบ่งๅ | ๆ | ๅฏๅ ๅซ็บฆๆใๅทฅไฝๆตใๆจกๅผ |
่ฟไธชๅบๅซๅฏน Token ็ปๆตๅพ้่ฆใไธไธชๆ 80 ไธช Tool ็ Harness ๆฏๆฌก API ่ฐ็จไป Schema ๅฐฑ่ฆ่ฑ็บฆ 12,000 Tokenใไธไธชๆ 15 ไธช Skill ๅ 300 Token ่ๅ็ Skill ็ณป็ปๅชๅ ่ฝฝ้่ฆ็้จๅใ
SKILL.md ๆไปถๆฏ Skill ็ไฝฟ็จๆๅใๆจกๅๅจ Skill ่ขซๅ ่ฝฝๆถ่ฏปๅๅฎ๏ผ
# Git Operations
## When to Use
- User asks to check, commit, or push code changes
- You need to inspect file history or diffs
- Resolving merge conflicts
## Available Tools
- `git_status` โ Show working tree status
- `git_diff` โ Show changes (staged or unstaged)
- `git_commit` โ Commit staged changes with a message
- `git_push` โ Push commits to remote
- `git_log` โ Show recent commit history
## Conventions
- Always run `git_status` before committing
- Use conventional commit messages (feat:, fix:, docs:)
- Never force-push without explicit user approval
- Commit message should be under 72 characters
## Examples
To commit and push:
1. `git_status` โ review what's changed
2. `git_diff` โ verify the changes are correct
3. `git_commit("feat: add user auth middleware")`
4. `git_push`่ฟไธชๆ ผๅผ็ปไบๆจกๅ่ถณๅค็ไธไธๆๆฅๆญฃ็กฎไฝฟ็จ Skill๏ผ่ไธ้่ฆๆๆๆ็ฅ่ฏๅก่ฟ Tool ๆ่ฟฐ้ใ
ไธ่ฆๅจๅฏๅจๆถๅ ่ฝฝๆๆ Tool๏ผ่ๆฏ็ปๆจกๅๅ็ฐไธไธช็ดงๅ็ๅฏ็จ Skill ่ๅใๆจกๅ่ฏปๅ่ๅ๏ผๅณๅฎ้่ฆๅชไธช Skill๏ผ็ถๅๅ ่ฝฝๅฎ๏ผ
SKILL_MENU = """Available skills (use load_skill to activate):
- file_ops: Read, write, search, and edit files in the workspace
- git: Version control โ status, diff, commit, push, log
- web: HTTP requests, web search, URL fetching
- shell: Execute shell commands in a sandbox
- database: SQL queries, schema inspection, migrations
- calendar: Create events, check availability, manage schedules
- email: Read inbox, send emails, search messages
- image: Generate and analyze images
"""่ๅๅช่ฑ็บฆ 150 Tokenใๅ ่ฝฝไธไธช Skill ๅขๅ ๅ ถ SKILL.md๏ผ็บฆ 500โ1,000 Token๏ผๅ Tool Schema๏ผ็บฆ 200โ800 Token๏ผใๅฏนๆฏ้ขๅ ๅ ่ฝฝๆๆ Tool๏ผ
็ญ็ฅ Token ๆฐ (8 ไธช Skill๏ผ็บฆ 60 ไธช Tool)
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
ๅ
จ้จ้ขๅ
ๅ ่ฝฝ: ~12,000 tokens (ๆฏๆฌก้ฝๆฏ)
Skill ่ๅ + ๅ ่ฝฝ 2 ไธช: ~150 + ~2,400 = ~2,550 tokens
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
่็: ๆฏ่ฝฎ็บฆ 9,450 tokens (78%)
ๅจ 30 ่ฝฎ Session ไธญ๏ผ่็็บฆ 280K Tokenโโๆ API ๅฎไปท็ฎๆฏๅฎๆๅฎ็้ฑใ
import json
from pathlib import Path
from dataclasses import dataclass, field
@dataclass
class Skill:
name: str
description: str
doc: str # Contents of SKILL.md
tools: list[dict] = field(default_factory=list) # Tool schemas
handlers: dict = field(default_factory=dict) # name โ callable
class SkillRegistry:
"""Registry with on-demand skill loading."""
def __init__(self, skills_dir: str):
self.skills_dir = Path(skills_dir)
self._catalog: dict[str, Skill] = {}
self._active: dict[str, Skill] = {}
self._scan()
def _scan(self):
"""Scan the skills directory and build the catalog."""
for skill_dir in self.skills_dir.iterdir():
if not skill_dir.is_dir():
continue
skill_md = skill_dir / "SKILL.md"
schema_file = skill_dir / "schema.json"
if not skill_md.exists():
continue
doc = skill_md.read_text()
# Extract first line after "# " as description
first_heading = ""
for line in doc.splitlines():
if line.startswith("# "):
first_heading = line[2:].strip()
break
schemas = []
if schema_file.exists():
schemas = json.loads(schema_file.read_text())
self._catalog[skill_dir.name] = Skill(
name=skill_dir.name,
description=first_heading,
doc=doc,
tools=schemas,
)
def get_menu(self) -> str:
"""Generate the skill menu for the model."""
lines = ["Available skills (use load_skill to activate):\n"]
for name, skill in self._catalog.items():
status = " [loaded]" if name in self._active else ""
lines.append(f"- {name}: {skill.description}{status}")
return "\n".join(lines)
def load_skill(self, name: str) -> str:
"""Load a skill, making its tools available."""
if name not in self._catalog:
return f"Error: Unknown skill '{name}'. Check the skill menu."
if name in self._active:
return f"Skill '{name}' is already loaded."
skill = self._catalog[name]
self._active[name] = skill
tool_names = [t["name"] for t in skill.tools]
return (
f"Loaded skill '{name}' with {len(skill.tools)} tools: "
f"{', '.join(tool_names)}\n\n"
f"Documentation:\n{skill.doc}"
)
def unload_skill(self, name: str) -> str:
"""Unload a skill to free up context space."""
if name not in self._active:
return f"Skill '{name}' is not loaded."
del self._active[name]
return f"Unloaded skill '{name}'."
def get_active_schemas(self) -> list[dict]:
"""Return tool schemas for all currently loaded skills."""
schemas = []
for skill in self._active.values():
schemas.extend(skill.tools)
# Always include the meta-tools
schemas.append({
"name": "load_skill",
"description": "Load a skill by name to activate its tools",
"parameters": {
"type": "object",
"properties": {
"name": {"type": "string", "description": "Skill name from the menu"}
},
"required": ["name"],
},
})
return schemas
def dispatch(self, tool_name: str, arguments: dict) -> str:
"""Dispatch a tool call to the appropriate skill handler."""
if tool_name == "load_skill":
return self.load_skill(arguments["name"])
for skill in self._active.values():
if tool_name in skill.handlers:
try:
return str(skill.handlers[tool_name](**arguments))
except Exception as e:
return f"Error: {type(e).__name__}: {e}"
return f"Error: Tool '{tool_name}' not found. Is the skill loaded?"ๆถๆๅๅ๏ผHarness ๅบ่ฏฅๆฏ่็โโๅชๆ Agentic LoopใContext ็ป่ฃ ๅ Skill ๆณจๅ่กจใๆๆ้ขๅไธไธ็ฅ่ฏ้ฝๆพๅจ Skill ไธญ๏ผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Harness๏ผ่๏ผ โ
โ โโโโโโโโโโโโ โโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โ
โ โ Agentic โ โ Context โ โ Skill โ โ
โ โ Loop โ โ Assembler โ โ Registry โ โ
โ โโโโโโโโโโโโ โโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ๆ้ๅ ่ฝฝ
โโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโ
โผ โผ โผ
โโโโโโโโโโโ โโโโโโโโโโโโโ โโโโโโโโโโโโโ
โ git โ โ file_ops โ โ web โ
โ skill โ โ skill โ โ skill โ
โโโโโโโโโโโ โโโโโโโโโโโโโ โโโโโโโโโโโโโ
่ฟ็งๅ็ฆปๆๅฎ้ ๅฅฝๅค๏ผ
- Skill ๅฏ็งปๆค โโ ไธบไธไธช Harness ๅ็ Skill ๅจๅฆไธไธชไธญไน่ฝ็จ
- Skill ๅฏๆต่ฏ โโ ็ฌ็ซๆต่ฏ Tool ๅ Schema
- Skill ๅฏ็ปๅ โโ ๆจกๅ่ช็ถๅฐๅ็ฐๅฆไฝ็ปๅๅทฒๅ ่ฝฝ็ Skill
- Harness ไฟๆ็ฎๅ โโ ้่ฟๆทปๅ Skill ๆฅๅขๅ ่ฝๅ๏ผ่ไธๆฏไฟฎๆนๆ ธๅฟ
- ๅฏๅจๆถๅ ่ฝฝๆๆ Skill โโ ่ฟ่ไบ Skill ็ณป็ป็ๅ่กทใ็จ่ๅๆจกๅผๆ้ๅ ่ฝฝใ
- ๅทจๅ Skill โโ ไธไธชๆ 30 ไธช Tool ็"ไธ่ฝ" Skill ๅชๆฏๆขไบไธช้ฉฌ็ฒ็ๅ จ้ๅ ่ฝฝ้ฎ้ขใไฟๆ Skill ่็ฆ๏ผๆฏไธช 3โ8 ไธช Toolใ
- ็ผบๅฐ SKILL.md โโ ๆฒกๆๆๆกฃ็ Tool ่ฟซไฝฟๆจกๅ็ๆตไฝฟ็จๆฏไพใSKILL.md ไธๆฏๅฏ้้กน๏ผๅฎๆฏ Skill ็ๅคง่ใ
- ๆฒกๆๅธ่ฝฝๆบๅถ โโ ๅฆๆๆจกๅๅ ่ฝฝไบไบไธช Skill ๅดๆ ๆณๅธ่ฝฝ๏ผContext ไผๅพๅฟซๅกซๆปกใๅง็ปๅจ
load_skillๆๆไพunload_skillใ - Skill ๅ Tool ๅฝๅๆททๆท โโ ๅฆๆ Skill ๅซ
gitไธๅ ๅซไธไธชๅซgit็ Tool๏ผๆจกๅๅฏ่ฝไผๆ Skill ๅๅฝ Tool ๅๆฅ่ฐ็จใ็จไธๅ็ๅฝๅ๏ผSkill ๅซgit๏ผTool ๅซgit_statusใgit_diff็ญใ
- OpenClaw Skills Architecture โ ไธไธช็ไบง็บง Skill ็ณป็ป๏ผๅซ Skill ่ๅๅๆ้ๅ ่ฝฝ
- Anthropic: Tool Use Guide โ Tool ่ฎพ่ฎกๆไฝณๅฎ่ทต๏ผๅๆ ท้็จไบ Skill
- Model Context Protocol: Tools โ ่ทจ Harness Tool/Skill ไบๆไฝ็ๅผๆพๆ ๅ