Skip to content

Commit 6a6f481

Browse files
committed
FEAT: 添加skills_hub 模块
1 parent 73655ab commit 6a6f481

35 files changed

Lines changed: 4713 additions & 30 deletions

docs/mkdocs/en/skill.md

Lines changed: 53 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2143,17 +2143,56 @@ The **Dynamic Tool Selection** mechanism has been fully implemented and verified
21432143
- ❌ All tools need to be available simultaneously
21442144
- ❌ Token cost is not a primary concern
21452145

2146-
## References and Examples
2147-
2148-
- Background:
2149-
- Blog:
2150-
https://www.anthropic.com/engineering/equipping-agents-for-the-real-world-with-agent-skills
2151-
- Open repository: https://github.com/anthropics/skills
2152-
- This repository:
2153-
- Interactive demo: [examples/skills/run_agent.py](../../../examples/skills/run_agent.py)
2154-
- Dynamic tool selection full example: [examples/skills_with_dynamic_tools/run_agent.py](../../../examples/skills_with_dynamic_tools/run_agent.py)
2155-
- Example structure guide: [examples/skills/README.md](../../../examples/skills/README.md)
2156-
- Example skills:
2157-
- [examples/skills/skills/python-math/SKILL.md](../../../examples/skills/skills/python-math/SKILL.md)
2158-
- [examples/skills/skills/file_tools/SKILL.md](../../../examples/skills/skills/file_tools/SKILL.md)
2159-
- [examples/skills/skills/user_file_ops/SKILL.md](../../../examples/skills/skills/user_file_ops/SKILL.md)
2146+
## Skill Hub - Discovering and Fetching Skills from Remote Sources
2147+
2148+
**Skill Hub** (`trpc_agent_sdk.skills.hub`) is a set of adapters (`SkillSource`) for discovering and fetching skills from remote sources. It provides three capabilities: searching for available skills from a source (GitHub, ClawHub, skills.sh, and others), inspecting metadata for a specific skill, and downloading the complete file contents for that skill. Users can also implement the `SkillSource` interface to integrate their own skill source.
2149+
2150+
### `SkillSource` Contract
2151+
2152+
Every adapter implements the same four-method interface:
2153+
2154+
```python
2155+
from trpc_agent_sdk.skills.hub import SkillSource, SkillMeta, SkillBundle
2156+
2157+
class SkillSource(ABC):
2158+
def source_id(self) -> str: ...
2159+
def search(self, query: str, limit: int = 10) -> list[SkillMeta]: ...
2160+
def inspect(self, identifier: str) -> SkillMeta | None: ...
2161+
def fetch(self, identifier: str) -> SkillBundle | None: ...
2162+
```
2163+
2164+
- `SkillMeta` - lightweight search/inspect result (`name`, `description`, `source`, `identifier`, plus optional `repo`/`path`/`tags`/`extra`)
2165+
- `SkillBundle` - the downloaded skill (`name`, `files: dict[str, str | bytes]`, `source`, `identifier`, `metadata`)
2166+
2167+
`fetch()` only returns an in-memory `SkillBundle`. Writing it to disk (including overwrite policy, atomic writes, and concurrency safety) is the **caller's** responsibility, because different harnesses have different installation semantics. For this purpose, the SDK also exports three path validation functions:
2168+
2169+
```python
2170+
from trpc_agent_sdk.skills.hub import validate_skill_name, validate_category_name, validate_bundle_rel_path
2171+
```
2172+
2173+
### Built-in Adapters
2174+
2175+
| Adapter | Source | Identifier format |
2176+
| --- | --- | --- |
2177+
| `GitHubSource` | GitHub repos, via the Contents / Git Trees API | `"owner/repo/path/to/skill-dir"` |
2178+
| `WellKnownSkillSource` | Any domain exposing `/.well-known/skills/index.json` | `well-known:{base_url}/{skill_name}` or a raw HTTPS URL |
2179+
| `HermesIndexSource` | A centralized, pre-crawled skills catalog | Same identifiers as the underlying `GitHubSource` entries |
2180+
| `SkillsShSource` | [skills.sh](https://skills.sh) | `skills-sh/{owner}/{repo}/{skill_path}` |
2181+
| `ClawHubSource` | [ClawHub](https://clawhub.ai) | slug, e.g. `"notion"` |
2182+
| `ClaudeMarketplaceSource` | Claude Code marketplace repos (`.claude-plugin/marketplace.json`) | Resolves to a `GitHubSource` identifier |
2183+
| `LobeHubSource` | LobeHub agent marketplace (converted to synthetic `SKILL.md`) | `lobehub/{agent_id}` |
2184+
2185+
### Minimal Usage
2186+
2187+
```python
2188+
from trpc_agent_sdk.skills.hub import GitHubAuth, GitHubSource
2189+
2190+
source = GitHubSource(GitHubAuth()) # no authentication is required for public repositories
2191+
meta = source.inspect("anthropics/skills/skills/skill-creator")
2192+
bundle = source.fetch("anthropics/skills/skills/skill-creator")
2193+
# bundle.files: {"SKILL.md": "...", "scripts/...": "...", ...}
2194+
```
2195+
2196+
### Full Example
2197+
2198+
See the complete Skill Hub usage example: [examples/skills_hub/run_agent.py](../../../examples/skills_hub/run_agent.py)

docs/mkdocs/zh/skill.md

Lines changed: 66 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2141,17 +2141,69 @@ Tools:
21412141
- ❌ 所有工具都需要同时可用
21422142
- ❌ Token 成本不是主要考虑因素
21432143

2144-
## 参考和示例
2145-
2146-
- 背景:
2147-
- 博客:
2148-
https://www.anthropic.com/engineering/equipping-agents-for-the-real-world-with-agent-skills
2149-
- 开放仓库:https://github.com/anthropics/skills
2150-
- 本仓库:
2151-
- 交互式演示:[examples/skills/run_agent.py](../../../examples/skills/run_agent.py)
2152-
- 动态工具选择完整示例:[examples/skills_with_dynamic_tools/run_agent.py](../../../examples/skills_with_dynamic_tools/run_agent.py)
2153-
- 示例结构说明:[examples/skills/README.md](../../../examples/skills/README.md)
2154-
- 示例技能:
2155-
- [examples/skills/skills/python-math/SKILL.md](../../../examples/skills/skills/python-math/SKILL.md)
2156-
- [examples/skills/skills/file_tools/SKILL.md](../../../examples/skills/skills/file_tools/SKILL.md)
2157-
- [examples/skills/skills/user_file_ops/SKILL.md](../../../examples/skills/skills/user_file_ops/SKILL.md)
2144+
## Skill Hub —— 从远程来源发现并获取 Skill
2145+
2146+
**Skill Hub**`trpc_agent_sdk.skills.hub`)是一组用于从远程来源发现和获取 skill 的适配器(`SkillSource`)。它能做三件事:搜索某个来源(GitHub、ClawHub、skills.sh 等)上有哪些 skill、查看某个 skill 的元信息、下载它的完整文件内容。用户也可以实现SkillSource 接口来对接自己的skill source.
2147+
2148+
### `SkillSource` 契约
2149+
2150+
每个适配器都实现同样的四方法接口:
2151+
2152+
```python
2153+
from trpc_agent_sdk.skills.hub import SkillSource, SkillMeta, SkillBundle
2154+
2155+
class SkillSource(ABC):
2156+
def source_id(self) -> str: ...
2157+
def search(self, query: str, limit: int = 10) -> list[SkillMeta]: ...
2158+
def inspect(self, identifier: str) -> SkillMeta | None: ...
2159+
def fetch(self, identifier: str) -> SkillBundle | None: ...
2160+
```
2161+
2162+
- `SkillMeta` —— 轻量的 search/inspect 结果(`name``description``source``identifier`,以及可选的 `repo`/`path`/`tags`/`extra`
2163+
- `SkillBundle` —— 下载到的 skill(`name``files: dict[str, str | bytes]``source``identifier``metadata`
2164+
2165+
`fetch()` 只会返回内存中的 `SkillBundle`。如果要使用远程 skill,需要先安装到本地目录。SDK 提供了 `SkillSpec``create_default_skill_repository(remote_skills=..., install_root=...)` 的联动入口:构造 repository 时先把远程 skill 原子写入 `install_root`,再像普通本地 skill 一样扫描索引。SDK 也导出了三个路径校验函数,供自定义安装逻辑复用:
2166+
2167+
```python
2168+
from trpc_agent_sdk.skills.hub import validate_skill_name, validate_category_name, validate_bundle_rel_path
2169+
```
2170+
2171+
### 内置适配器
2172+
2173+
| 适配器 | 来源 | 标识符格式 |
2174+
| --- | --- | --- |
2175+
| `GitHubSource` | GitHub 仓库,如 https://github.com/anthropics/skills | `owner/repo/path/to/skill-dir`,例如 `"anthropics/skills/skills/skill-creator"` |
2176+
| `WellKnownSkillSource` | 暴露 `/.well-known/skills/index.json` 的站点,如 https://www.mintlify.com/docs/.well-known/skills/index.json | HTTPS URL,例如 `"https://example.com/.well-known/skills/plan"` |
2177+
| `HermesIndexSource` | [Hermes Skills Index](https://hermes-agent.nousresearch.com/docs/api/skills-index.json) | `owner/repo/path`,例如 `"anthropics/skills/skills/skill-creator"` |
2178+
| `SkillsShSource` | [skills.sh](https://skills.sh) | `skills-sh/{owner}/{repo}/{skill_path}`,例如 `"skills-sh/owner/repo/plan"` |
2179+
| `ClawHubSource` | [ClawHub](https://clawhub.ai) | `{slug}`,例如 `notion` |
2180+
| `ClaudeMarketplaceSource` |`.claude-plugin/marketplace.json` 的 GitHub marketplace 仓库,如 https://github.com/anthropics/skills | `owner/repo/path`,例如 `"anthropics/skills/plugins/docx"` |
2181+
| `LobeHubSource` | [LobeHub agent marketplace](https://chat-agents.lobehub.com/index.json) | `lobehub/{agent_id}`,例如 `lobehub/writer-bot` |
2182+
2183+
### 最小用法
2184+
2185+
```python
2186+
from trpc_agent_sdk.skills import SkillSpec
2187+
from trpc_agent_sdk.skills import SkillToolSet
2188+
from trpc_agent_sdk.skills import create_default_skill_repository
2189+
from trpc_agent_sdk.skills.hub import GitHubAuth, GitHubSource
2190+
2191+
source = GitHubSource(GitHubAuth()) # 拉取公开仓库无需认证
2192+
meta = source.inspect("anthropics/skills/skills/skill-creator")
2193+
2194+
repository = create_default_skill_repository(
2195+
remote_skills=[
2196+
SkillSpec(
2197+
source=source,
2198+
identifier="anthropics/skills/skills/skill-creator",
2199+
name="skill-creator",
2200+
),
2201+
],
2202+
install_root="data/skills/.downloaded",
2203+
)
2204+
skill_toolset = SkillToolSet(repository=repository)
2205+
```
2206+
2207+
### 完整示例
2208+
2209+
查看完整的 Skill Hub 使用示例:[examples/skills_hub/run_agent.py](../../../examples/skills_hub/run_agent.py)

examples/skills_hub/.env

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Set TRPC_AGENT_API_KEY、TRPC_AGENT_BASE_URL、TRPC_AGENT_MODEL_NAME
2+
TRPC_AGENT_API_KEY=your-api-key
3+
TRPC_AGENT_BASE_URL=your-base-url
4+
TRPC_AGENT_MODEL_NAME=your-model-name
5+
6+
# Optional: a GitHub personal access token (raises the unauthenticated
7+
# 60 req/hr GitHub API limit to 5,000/hr). Not required to run this demo.
8+
# GITHUB_TOKEN=

examples/skills_hub/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
data

examples/skills_hub/README.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Skill Hub 示例
2+
3+
本示例演示 `trpc_agent_sdk.skills.hub`(Skill Hub):在启动 `LlmAgent` 之前,通过 `SkillSpec` + `create_default_skill_repository(remote_skills=...)` 从 GitHub 上按需拉取一个技能(Anthropic 官方的 `skill-creator`),写入本地技能目录,再像本地技能一样交给 `SkillToolSet` 使用。
4+
5+
## 什么是 Skill Hub
6+
7+
Skill Hub(`trpc_agent_sdk.skills.hub`)把"从各种来源发现并获取 skill"统一到同一个接口后面。每个来源都是一个 `SkillSource` 适配器,对外提供一致的 `search` / `inspect` / `fetch` 三种能力:
8+
9+
| 适配器 | 来源 |
10+
| --- | --- |
11+
| `GitHubSource` | GitHub 仓库目录(本示例使用) |
12+
| `WellKnownSkillSource` | 站点 `.well-known/skills` |
13+
| `HermesIndexSource` | Hermes 内置 skill index |
14+
| `SkillsShSource` | skills.sh |
15+
| `ClawHubSource` | ClawHub registry |
16+
| `ClaudeMarketplaceSource` | Claude Skills Marketplace |
17+
| `LobeHubSource` | LobeHub |
18+
19+
`SkillSource.fetch()` 只返回内存中的 `SkillBundle``name` + `files` + `metadata`)。SDK 提供 `SkillSpec` 声明和 `create_default_skill_repository(remote_skills=..., install_root=...)`,在构造 repository 时把远程 skill 原子写入本地 `install_root`,再交给标准 `FsSkillRepository` 扫描。
20+
21+
## 关键特性
22+
23+
- `GitHubSource(GitHubAuth(token))` 无需认证即可拉取公开仓库(60 次/小时限额,足够本示例使用;设置 `GITHUB_TOKEN` 可提升到 5000 次/小时)
24+
- 安装逻辑内部复用 SDK 导出的路径校验,避免恶意 `SkillBundle` 写出到目标目录之外
25+
- 已安装的技能会被跳过,除非 `SkillSpec(replace_if_exists=True)`
26+
- 拉取完成后,技能通过标准的 `create_default_skill_repository` + `SkillToolSet` 链路对 agent 可见,和本地技能没有区别
27+
28+
## Agent 层级结构说明
29+
30+
- 根节点:`LlmAgent``skill_hub_demo_agent`),挂载 `SkillToolSet``skill_repository`
31+
- 无子 Agent;单智能体通过 `skill_load` / `skill_list_docs` 等技能工具完成任务
32+
33+
## 关键代码解释
34+
35+
- `agent/hub.py`
36+
- `create_skill_tool_set()`:通过 `SkillSpec` 声明 GitHub skill,并调用 `create_default_skill_repository(remote_skills=..., install_root=...)` 完成安装 + 索引
37+
- `agent/agent.py``create_agent(skills_dir)` 把返回的 `skill_repository` / `skill_tool_set` 绑定到 `LlmAgent`
38+
- `run_agent.py`:清空 `data/` 目录(保证每次都重新走一遍 Skill Hub 拉取流程),创建 agent,跑一轮 `skill_load` + 总结的对话,并打印实际下载到的文件列表
39+
40+
## 环境与运行
41+
42+
- Python 3.10+;仓库根目录执行 `pip install -e .`
43+
- 配置 `TRPC_AGENT_API_KEY``TRPC_AGENT_BASE_URL``TRPC_AGENT_MODEL_NAME`(可用 `.env`
44+
- 可选:`GITHUB_TOKEN`,用于提高 GitHub API 限额(本示例只读取公开仓库,不设置也能跑)
45+
46+
```bash
47+
cd examples/skills_hub
48+
python3 run_agent.py
49+
```
50+
51+
运行后会在 `data/skills/.downloaded/hub/skill-creator/` 下看到从 GitHub 拉取的真实文件(`SKILL.md``scripts/``references/` 等)。
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Tencent is pleased to support the open source community by making tRPC-Agent-Python available.
2+
#
3+
# Copyright (C) 2026 Tencent. All rights reserved.
4+
#
5+
# tRPC-Agent-Python is licensed under Apache-2.0.

examples/skills_hub/agent/agent.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Tencent is pleased to support the open source community by making tRPC-Agent-Python available.
2+
#
3+
# Copyright (C) 2026 Tencent. All rights reserved.
4+
#
5+
# tRPC-Agent-Python is licensed under Apache-2.0.
6+
""" Agent that demonstrates fetching a skill from the Skill Hub before running. """
7+
8+
from pathlib import Path
9+
10+
from trpc_agent_sdk.agents import LlmAgent
11+
from trpc_agent_sdk.models import LLMModel
12+
from trpc_agent_sdk.models import OpenAIModel
13+
14+
from .config import get_model_config
15+
from .hub import create_skill_tool_set
16+
from .prompts import INSTRUCTION
17+
18+
19+
def _create_model() -> LLMModel:
20+
""" Create a model"""
21+
api_key, url, model_name = get_model_config()
22+
model = OpenAIModel(model_name=model_name, api_key=api_key, base_url=url)
23+
return model
24+
25+
26+
def create_agent(skills_dir: Path) -> LlmAgent:
27+
"""Fetch a skill from GitHub via the Skill Hub, then build an agent that can use it.
28+
29+
Args:
30+
skills_dir: Local directory to install fetched skills into. Populated
31+
by `create_default_skill_repository(remote_skills=...)` before the
32+
agent is constructed.
33+
"""
34+
skill_tool_set, skill_repository = create_skill_tool_set(skills_dir)
35+
36+
return LlmAgent(
37+
name="skill_hub_demo_agent",
38+
description="An assistant that fetches skills on demand from the Skill Hub.",
39+
model=_create_model(),
40+
instruction=INSTRUCTION,
41+
tools=[skill_tool_set],
42+
skill_repository=skill_repository,
43+
)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Tencent is pleased to support the open source community by making tRPC-Agent-Python available.
2+
#
3+
# Copyright (C) 2026 Tencent. All rights reserved.
4+
#
5+
# tRPC-Agent-Python is licensed under Apache-2.0.
6+
""" Agent config module"""
7+
8+
import os
9+
10+
11+
def get_model_config() -> tuple[str, str, str]:
12+
"""Get model config from environment variables"""
13+
api_key = os.getenv('TRPC_AGENT_API_KEY', '')
14+
url = os.getenv('TRPC_AGENT_BASE_URL', '')
15+
model_name = os.getenv('TRPC_AGENT_MODEL_NAME', '')
16+
if not api_key or not url or not model_name:
17+
raise ValueError('''TRPC_AGENT_API_KEY, TRPC_AGENT_BASE_URL,
18+
and TRPC_AGENT_MODEL_NAME must be set in environment variables''')
19+
return api_key, url, model_name

examples/skills_hub/agent/hub.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Tencent is pleased to support the open source community by making tRPC-Agent-Python available.
2+
#
3+
# Copyright (C) 2026 Tencent. All rights reserved.
4+
#
5+
# tRPC-Agent-Python is licensed under Apache-2.0.
6+
"""Skill Hub glue: declare a remote skill and build a repository for it."""
7+
8+
from __future__ import annotations
9+
10+
import os
11+
from pathlib import Path
12+
13+
from trpc_agent_sdk.code_executors import create_local_workspace_runtime
14+
from trpc_agent_sdk.skills import BaseSkillRepository
15+
from trpc_agent_sdk.skills import SkillToolSet
16+
from trpc_agent_sdk.skills import create_default_skill_repository
17+
from trpc_agent_sdk.skills.hub import GitHubAuth
18+
from trpc_agent_sdk.skills.hub import GitHubSource
19+
from trpc_agent_sdk.skills.hub import SkillSpec
20+
21+
# `skill-creator` is Anthropic's own skill for building and iterating on
22+
# skills -- a fitting "meta" skill to fetch through the Skill Hub for a demo.
23+
GITHUB_SKILL_IDENTIFIER = "anthropics/skills/skills/skill-creator"
24+
GITHUB_SKILL_NAME = "skill-creator"
25+
26+
27+
def create_skill_tool_set(skills_dir: Path) -> tuple[SkillToolSet, BaseSkillRepository]:
28+
"""Build a `SkillToolSet` backed by a GitHub skill installed through the repository factory."""
29+
workspace_runtime = create_local_workspace_runtime()
30+
# Unauthenticated requests are capped at 60 req/hr, which is plenty for
31+
# this demo. Set GITHUB_TOKEN to raise that limit for repeated runs.
32+
source = GitHubSource(GitHubAuth(os.getenv("GITHUB_TOKEN") or None))
33+
repository = create_default_skill_repository(
34+
remote_skills=[
35+
SkillSpec(
36+
source=source,
37+
identifier=GITHUB_SKILL_IDENTIFIER,
38+
name=GITHUB_SKILL_NAME,
39+
on_error="raise",
40+
),
41+
],
42+
install_root=str(skills_dir / ".downloaded"),
43+
workspace_runtime=workspace_runtime,
44+
)
45+
skill_toolset = SkillToolSet(repository=repository)
46+
return skill_toolset, repository
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Tencent is pleased to support the open source community by making tRPC-Agent-Python available.
2+
#
3+
# Copyright (C) 2026 Tencent. All rights reserved.
4+
#
5+
# tRPC-Agent-Python is licensed under Apache-2.0.
6+
""" prompts for agent"""
7+
8+
INSTRUCTION = """
9+
Be a concise, helpful assistant that can use Agent Skills.
10+
11+
A skill named "skill-creator" was just fetched on demand from GitHub via the
12+
Skill Hub (`trpc_agent_sdk.skills.hub`) and installed locally before you were
13+
started, so it is available like any other local skill.
14+
15+
When asked about a skill, call skill_load to load its documentation, then
16+
skill_list_docs to see what documentation and files are available. Summarize
17+
what you find concisely; do not run any of the skill's scripts unless
18+
explicitly asked to.
19+
"""

0 commit comments

Comments
 (0)