docs/v2/en/docs/harness/SKILL.md
Four-layer skill composition, skill marketplaces, the self-learning loop
npx skillsauth add agentscope-ai/agentscope-java docs/v2/en/docs/harnessInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
A skill is a packaged capability: a directory with a SKILL.md (purpose + instructions the agent reads), optional reference docs, scripts, samples. Hand it to the agent and it will use it when relevant.
Harness lets you install skills from two places:
workspace/skills/ is shared by everyone; <userId>/skills/ isolates per userBoth sources are active simultaneously — no need to choose one. On top of that you can enable a self-learning loop: the agent drafts skills → review gate → background curator tidies up.
A skill directory looks like:
code-reviewer/
├── SKILL.md # required — YAML frontmatter (name + description) + instructions for the agent
├── references/ # optional — long-form docs the agent reads on demand
│ └── style-guide.md
└── scripts/ # optional — executable scripts the agent can shell out to
└── run-checks.sh
SKILL.md format:
---
name: code-reviewer
description: Use when the user asks for code review, style feedback, or PR audits.
---
# Code Reviewer
Steps:
1. Read `references/style-guide.md` for project conventions.
2. Run `scripts/run-checks.sh <target-path>` and summarize the output.
Plug in your team's skill repo and the agent can use it immediately:
HarnessAgent agent = HarnessAgent.builder()
.name("assistant")
.model(model)
.workspace(workspace)
.skillRepository(new GitSkillRepository("https://github.com/your-org/team-skills.git"))
.build();
During reasoning, the agent sees skills from the repo and calls load_skill_through_path for whichever one it needs.
skillRepository(...) is the unified entry point — pass any backend.
<dependency>
<groupId>io.agentscope</groupId>
<artifactId>agentscope-extensions-skill-git-repository</artifactId>
<version>${agentscope.version}</version>
</dependency>
.skillRepository(new GitSkillRepository("https://github.com/your-org/team-skills.git"))
By default, each read does a lightweight remote check, pulling only when HEAD changed. If the repo has a skills/ subdirectory, that's the root; otherwise the repo root is. To control sync timing yourself: new GitSkillRepository(url, false), then call repo.sync() manually.
<dependency>
<groupId>io.agentscope</groupId>
<artifactId>agentscope-extensions-nacos-skill</artifactId>
<version>${agentscope.version}</version>
</dependency>
NacosSkillRepository market = new NacosSkillRepository(aiService, "namespace");
HarnessAgent.builder()
.skillRepository(market)
.build();
Best for online distribution + change subscription. market is AutoCloseable; close it on shutdown to release subscriptions.
MysqlSkillRepository registry = MysqlSkillRepository.builder(dataSource)
.databaseName("agentscope")
.skillsTableName("skills")
.createIfNotExist(true)
.writeable(true)
.build();
HarnessAgent.builder()
.skillRepository(registry)
.build();
Common for platform-side skill management. writeable(true) lets agents write back; pass false for read-only distribution.
Ship skills inside your JAR:
src/main/resources/skills/
└── code-reviewer/
└── SKILL.md
.skillRepository(new ClasspathSkillRepository("skills"))
Works with both standard JARs and Spring Boot fat JARs.
Call skillRepository(...) multiple times; later ones win:
HarnessAgent.builder()
.skillRepository(communityMarket)
.skillRepository(internalRegistry)
.skillRepository(teamGitRepo)
.build();
Workspace skills need no registration; just put the directory in place.
workspace/skills/
└── code-reviewer/
├── SKILL.md
├── references/
│ └── style-guide.md
└── scripts/
└── run-checks.sh
Best for project-specific rules, internal conventions.
To install a skill for a single user, or to override a shared one, place it under a directory named after their userId:
workspace/
├── skills/code-reviewer/SKILL.md ← shared version
└── alice/
└── skills/
└── code-reviewer/
└── SKILL.md ← visible only to Alice; overrides the shared version
This requires the caller to pass userId="alice" in RuntimeContext.
All four sources can yield a same-named skill. Priority from low to high:
| Priority | Source | How to configure |
|----------|--------|------------------|
| 1 (lowest) | Project-global dir | projectGlobalSkillsDir(Path), e.g. ~/.agentscope/skills/ |
| 2 | Marketplaces | skillRepository(...); later registrations win |
| 3 | Workspace shared | workspace/skills/ |
| 4 (highest) | Per-user | <userId>/skills/ |
Non-conflicting skills from lower layers still show up; they're only shadowed on name collision.
Example: the team Git has a generic code-reviewer; the project's workspace/skills/code-reviewer/ overrides it for this codebase; Alice's <alice>/skills/code-reviewer/ overrides that for Alice only — other users still see the project version.
| Method | Notes |
|--------|-------|
| skillRepository(repo) | Append a marketplace; callable multiple times |
| skillRepositories(list) | Replace all marketplaces at once |
| projectGlobalSkillsDir(path) | Enable the project-global dir; skipped if missing |
| disableDynamicSkills() | Turn off "re-merge before each reasoning"; merge once at build |
Subagents inherit the parent's marketplaces and project-global dir automatically.
When to use disableDynamicSkills(): one-shot tasks; or slow marketplace backends you don't want to refetch per turn. Usually don't touch it.
Harness stitches together a loop that lets the agent draft / curate / archive skills on its own. Each stage is independently opt-in:
HarnessAgent.builder()
...
.enableSkillManageTool(SkillManageConfig.defaults())
.build();
Once enabled, the agent gets two tools:
propose_skill — write a new skill as a draft to skills/_drafts/<name>/, pending reviewskill_manage — edit existing skills (create / edit / add ancillary files / delete)Skip the "draft → review" two-step and let the agent's writes go live directly: .enableSkillManageTool(true) (autoPromote=true). Not recommended for production.
The framework also auto-bumps a usage counter every time the agent calls load_skill_through_path / read_skill, kept in skills/.usage.json — data that powers cleanup and canary rollout below.
.enableSkillPromotionGate(
new LocalApprovalGate(LocalApprovalGate.defaultPrompter()), // who reviews
new CompositeFilter(List.of( // how to expose
new EnvironmentFilter("prod", skillUsageStore),
new CanaryFilter(0.10, skillUsageStore)
)))
.environment("prod")
.enableSkillCurator(SkillCuratorConfig.builder()
.intervalHours(7 * 24) // weekly
.minIdleHours(2) // only when call-gap ≥ 2h
.staleAfterDays(30)
.archiveAfterDays(90)
.build())
A throttled background job runs: skills unused for 30+ days become stale; for 90+ days move into skills/.archive/. An optional LLM "umbrella merge" pass can also run (dry-run by default — emits reports, doesn't actually change files).
From application code:
List<SkillAuditLog.Entry> entries = agent.queryAudit(LocalDate.now(), e -> true);
agent.runCuratorOnce() // run a curation now (bypasses throttle)
.subscribe(report -> System.out.println(report));
agent.promoteSkill("notes-taker", "alice") // manually promote a draft
.subscribe(result -> System.out.println(result));
When the agent reasons, it sees an <available_skills> block in the system prompt listing every skill currently in scope:
<available_skills>
<skill>
<name>code-reviewer</name>
<description>Use when the user asks for code review, style feedback, or PR audits.</description>
<skill-id>code-reviewer_workspace-namespaced</skill-id>
<files-root>/workspace/skills/code-reviewer</files-root>
</skill>
...
</available_skills>
Each entry carries just enough metadata for the agent to decide whether to load it. <files-root>, when present, is the absolute path the agent uses for shell execution (see below).
To activate a skill the agent calls a built-in tool — load_skill_through_path:
load_skill_through_path(skillId, path="SKILL.md") returns the markdown bodyload_skill_through_path(skillId, path="references/style-guide.md") returns any other file under the skill directoryHow the file gets fetched depends on where the skill came from:
| Skill source | How path is resolved |
|--------------|------------------------|
| Project-global dir (Layer 1) | preloaded into memory at registration |
| Marketplace — Git / MySQL / Nacos / classpath (Layer 2) | preloaded into memory by the backend |
| workspace/skills/ shared (Layer 3) | preloaded into memory at registration |
| <userId>/skills/ per-user (Layer 4) | SKILL.md preloaded; other files read on demand through AbstractFilesystem (per-user namespace + sandbox routing honored automatically) |
The agent doesn't see this difference — load_skill_through_path always works the same way. The fallback chain is "in-memory hit → filesystem read → error with an enumeration of every path actually available," so a wrong path returns a useful list rather than a dead end.
<files-root> and shell executionWhen a skill ships scripts (e.g. scripts/run-checks.sh), the agent needs an absolute path to invoke them via execute_shell_command. That path comes from the <files-root> element on each skill entry. Resolution depends on the filesystem mode:
| FS mode (shell available?) | Workspace skill <files-root> | Marketplace skill <files-root> |
|----------------------------|--------------------------------|-----------------------------------|
| Sandbox | /workspace/skills/<name> | /workspace/.skills-cache/<source>/<name> |
| Local-with-shell | <wsRoot>/skills/<name> | <wsRoot>/.skills-cache/<source>/<name> |
| Local without shell / Composite | (not rendered — no shell tool registered) | (not rendered) |
So the agent's shell call is always execute_shell_command("python3 <files-root>/scripts/foo.py") — no path guessing, no per-source variations to remember.
Marketplace skill resources start as in-memory bytes. For shell execution to work, harness materializes them to <wsRoot>/.skills-cache/<source>/<name>/ before each reasoning step:
.skills-cache is in the default workspace projection roots, so the staged tree is hydrated into the sandbox alongside workspace/skills/ at sandbox start time (and on content change)Workspace skills (Layer 3 / Layer 4) need no staging — they already live in the workspace tree.
If two repositories report the same getSource(), the second is auto-suffixed (<source>_2, <source>_3, …) with a warning log, so paths and skill-ids never collide.
description decides whether the agent uses your skill. The agent only sees name + description initially and decides whether to load details. "Data-analysis tool" is much less useful than "Use when the user asks for stats, reports, or trend charts".
Keep SKILL.md lean. Aim for ≤ 2k tokens; put reference material under references/, scripts under scripts/. The agent reads them on demand.
General capability in marketplaces, project-specific in the workspace. Code review, table analysis → team Git for shared maintenance. Internal RPC conventions, project naming rules → workspace/skills/ so they version with the code.
Per-user dirs are for "override + augment", not primary storage. Keep critical skills visible to every user.
Enable self-learning in order: no point running curator before anyone writes new skills. Start with enableSkillManageTool, then add the promotion gate, then the curator.
skills/tools
Expert Java developer skill for AgentScope Java framework - a reactive, message-driven multi-agent system built on Project Reactor. Use when working with reactive programming, LLM integration, agent orchestration, multi-agent systems, or when the user mentions AgentScope, ReActAgent, Mono/Flux, Project Reactor, or Java agent development. Specializes in non-blocking code, tool integration, hooks, pipelines, and production-ready agent applications.
documentation
四层技能合成、技能市场、自学习闭环
tools
# 技能(Skill) 一个 skill 就是一份写好的能力包:一个目录里放一份 `SKILL.md`(说明用途、给 agent 看的指令),可以再带一些参考文档、脚本或样例。写好后丢给 agent,它会在合适的时候自己用。 harness 让你从两个地方装 skill: - **接 skill 市场**:Git 仓库、Nacos、MySQL、classpath、或者自己写的后端 - **放在工作区**:项目里 `workspace/skills/` 下的就所有人共用;放在 `<userId>/skills/` 下的只有那个用户看得到 两类来源同时生效,不需要二选一。 > 关于 skill 自身的结构、`SKILL.md` 写法、资源加载、tool 绑定、代码执行这些通用概念,见 [Agent Skill](../task/agent-skill.md)。本文只讲 harness 这一层的用法。 --- ## 一个例子 把团队的 skill 仓库接进来,agent 立刻就能用: ```java HarnessAgent agent = HarnessAgent.bui
data-ai
Answer a quantitative business question by writing a SQL query against the data warehouse, validating it, and presenting the result. Use when the user asks "how many...", "what's the trend of...", "compare X vs Y over...", "what's our top N...", or anything that resolves to a query against tabular data. Produces a small result table plus the underlying query.