Skill (Agent Skills)
Agent Skills let you package reusable workflows into folders containing a SKILL.md specification file along with optional documentation and scripts. During a conversation, the agent first injects low-cost "overview" information, then loads the full body content and documentation only when truly needed, and safely runs scripts in an isolated workspace.
Background references:
- Engineering blog: https://www.anthropic.com/engineering/equipping-agents-for-the-real-world-with-agent-skills
- Open Skills repository (reference structure): https://github.com/anthropics/skills
Overview
🎯 Features
- 🔎 Overview injection (name + description) to guide selection
- 📥
skill_loadfetchesSKILL.mdbody and selected documentation on demand, automatically loading tools defined in the skill - 📋
skill_listlists all available skill names - 🔧
skill_list_toolslists tool names defined in a specified skill'sSKILL.md - ⚙️
skill_select_toolsdynamically selects skill tools (add/replace/clear modes) for token optimization - 📚
skill_select_docsadds/replaces/clears documentation - 🧾
skill_list_docslists available documentation - 🏃
skill_runexecutes commands and returns stdout/stderr and output files - 🗂️ Collects output files with MIME type detection support
- 🧩 Pluggable local or container workspace executors (local by default)
- 🧱 Custom working directory where skill run input files, output files, and skill files can be placed
- 🎯 Dynamic tool loading that automatically provides relevant tools based on skill selection, saving LLM tokens
Three-Layer Information Model
Agent Skills adopt a three-layer information model that enables on-demand loading while keeping prompts concise:
1) Initial "Overview" Layer (extremely low cost)
- Only injects the
nameanddescriptionfromSKILL.mdinto the system message - Lets the model know which skills are available without loading full content
2) Full Body Layer (loaded on demand)
- When a task truly requires a skill, the model calls
skill_load - The framework then injects the complete
SKILL.mdbody content for that skill
3) Documentation/Script Layer (selective + isolated execution) / Tool Invocation
- Documentation is included only when explicitly requested
- Scripts are not inlined into the prompt but executed in an isolated workspace
- Only execution results and output files are returned, without exposing script source code
- Parses user-configured available tools
File Layout
skills/
demo-skill/
SKILL.md # YAML (name/description) + Markdown body
USAGE.md # optional docs (.md/.txt)
scripts/build.sh
reference/ # Reference documentation
...
Repository and parsing: trpc_agent_sdk/skills/_repository.py
Quick Start
1) Requirements
- Python3.12
- Model provider API key (OpenAI-compatible)
- Optional Docker (for container executor)
Common environment variables:
export TRPC_AGENT_API_KEY="your-api-key"
export TRPC_AGENT_BASE_URL="your-base-url"
export TRPC_AGENT_MODEL_NAME="your-model-name"
# Optional: specify the skills directory, supports local paths or URLs (see "URL-based Skills Root")
export SKILLS_ROOT=/path/to/skills
# Optional: override the cache directory for URL-based Skills Root
export SKILLS_CACHE_DIR=/path/to/cache
Alternatively, you can use a .env file (examples automatically load it via python-dotenv):
# .env file
TRPC_AGENT_API_KEY=your-api-key
TRPC_AGENT_BASE_URL=your-base-url
TRPC_AGENT_MODEL_NAME=your-model-name
SKILLS_ROOT=./skills
# Optional: SKILLS_ROOT can also be a URL, for example:
# SKILLS_ROOT=https://example.com/my-skills.tar.gz
# SKILLS_CACHE_DIR=/custom/cache/path
2) Enabling Skills in an Agent
Create a skill repository and a workspace executor. If no executor is specified, the local executor is used by default for development convenience.
import os
from trpc_agent_sdk.agents import LlmAgent
from trpc_agent_sdk.models import OpenAIModel
from trpc_agent_sdk.skills import SkillToolSet
from trpc_agent_sdk.skills import create_default_skill_repository
from trpc_agent_sdk.skills.tools import LinkSkillStager
from trpc_agent_sdk.code_executors import create_local_workspace_runtime
from trpc_agent_sdk.code_executors import create_container_workspace_runtime
# Cube is an optional extra (`pip install 'trpc-agent-py[cube]'`); import lazily.
# from trpc_agent_sdk.code_executors.cube import CubeCodeExecutor, CubeCodeExecutorConfig
# from trpc_agent_sdk.code_executors.cube import create_cube_workspace_runtime
# Create workspace runtime (local, container, or cube)
workspace_runtime = create_local_workspace_runtime()
# Or use container: workspace_runtime = create_container_workspace_runtime()
# Or use a remote Cube/E2B sandbox:
# executor = await CubeCodeExecutor.create(CubeCodeExecutorConfig())
# workspace_runtime = create_cube_workspace_runtime(executor)
# Create skill repository
repository = create_default_skill_repository("./skills", workspace_runtime=workspace_runtime, use_cached_repository=True)
# Create skill tool set with optional artifact save options
skill_tool_set = SkillToolSet(
repository=repository,
skill_stager=LinkSkillStager(),
# run_tool_kwargs is an optional tool parameter
run_tool_kwargs={
"save_as_artifacts": True, # Whether to save as artifact files
"omit_inline_content": False,
}
)
# Create an agent with skills
agent = LlmAgent(
name="skill_run_agent",
description="A professional skill run assistant that can use Agent Skills.",
model=_create_model(),
instruction=INSTRUCTION, # Prompt containing skill usage guidance
tools=[skill_tool_set],
skill_repository=repository,
)
Note: Starting after version 1.1.10, skill loading and injection were optimized to support caching skill content and symlink-based staging in the local sandbox, avoiding full directory copies.
Prompt example:
The INSTRUCTION should include complete skill usage workflow guidance:
INSTRUCTION = """
You are an AI assistant with access to Agent Skills.
## Complete Skill Workflow
When handling user requests:
1. **Discover** → Call skill_list() to see available skills
2. **Inspect** → Call skill_list_tools(skill_name="...") to preview tools
3. **Load** → Call skill_load(skill_name="...") to load the skill
4. **Optimize** → Call skill_select_tools(...) to select only needed tools (saves tokens)
5. **Document** → Call skill_list_docs(...) and skill_select_docs(...) if more info needed
6. **Execute** → Call skill_run(...) to execute commands or use skill's tools directly
Example Complete Flow:
User: "What's the weather in Beijing?"
→ skill_list() → see "weather-tools"
→ skill_list_tools(skill_name="weather-tools") → see available tools
→ skill_load(skill_name="weather-tools") → load full content
→ skill_select_tools(skill_name="weather-tools", tools=["get_current_weather"]) → optimize
→ get_current_weather(city="Beijing") → execute
Always use environment variables in commands:
- $WORKSPACE_DIR, $SKILLS_DIR, $WORK_DIR, $OUTPUT_DIR, $RUN_DIR, $SKILL_NAME
"""
Key points:
- Automatic tool registration: The following tools are automatically registered via
SkillToolSet, requiring no manual wiring:skill_list: Lists all available skillsskill_list_tools: Lists tools of a skillskill_load: Loads skill contentskill_select_tools: Selects specific tools (token optimization)skill_list_docs: Lists available documentationskill_select_docs: Selects specific documentationskill_run: Executes skill commands
- Intelligent prompt guidance: Explicitly describe the workflow in the prompt to guide the LLM to call tools in the correct order
- Token optimization: Use
skill_select_toolsto load only the needed tools, significantly reducing context size - Code location:
- Package entry (aggregated exports): trpc_agent_sdk/skills/tools/init.py
skill_runimplementation: trpc_agent_sdk/skills/tools/_skill_run.py (for other tools, see Declaration location in each section below)
3) Running the Example
Full interactive demo: examples/skills/run_agent.py
The example is organized in a modular structure:
agent/agent.py- Agent creationagent/tools.py- Skill tool set creationagent/config.py- Model configuration from environment variablesagent/prompts.py- Agent instruction promptsrun_agent.py- Main entry file
cd examples/skills
# Set environment variables
export TRPC_AGENT_API_KEY="your-api-key"
export TRPC_AGENT_BASE_URL="your-base-url"
export TRPC_AGENT_MODEL_NAME="your-model-name"
export SKILLS_ROOT="./skills" # Optional, defaults to ./skills
# Run the example
python3 run_agent.py
Or use a .env file:
# Create .env file
cat > .env << EOF
TRPC_AGENT_API_KEY=your-api-key
TRPC_AGENT_BASE_URL=your-base-url
TRPC_AGENT_MODEL_NAME=your-model-name
SKILLS_ROOT=./skills
EOF
# Run (automatically loads .env)
python3 run_agent.py
Example skill (excerpt): examples/skills/skills/python-math/SKILL.md
Tips:
- Describe the task you want to accomplish; the model will decide whether a skill is needed based on the overview.
- When needed, the model will call
skill_loadto fetch the body/documentation, then callskill_runto execute and return output files.
Example run output
Using user-file-ops as an example:
🆔 Session ID: be355f8f...
📝 User:
I have a text file at /tmp/skillrun-notes.txt.
Please use the user-file-ops skill to summarize it, you can use command `cp` to copy it to the workspace,
then mapping it to `work/inputs/user-notes.txt` and writing the summary to `out/user-notes-summary.txt`
🤖 Assistant:
🔧 [Invoke Tool:: skill_load({'skill_name': 'user-file-ops'})]
📊 [Tool Result: {'result': "skill 'user-file-ops' loaded"}]
🔧 [Invoke Tool:: skill_list_docs({'skill_name': 'user-file-ops'})]
📊 [Tool Result: {}]
🔧 [Invoke Tool:: skill_run({'skill': 'user-file-ops', 'command': 'cp /tmp/skillrun-notes.txt work/inputs/user-notes.txt && bash scripts/summarize_file.sh work/inputs/user-notes.txt out/user-notes-summary.txt', 'output_files': ['out/user-notes-summary.txt']})]
📊 [Tool Result: {'stdout': '', 'stderr': '', 'exit_code': 0, 'timed_out': False, 'duration_ms': 0, 'output_files': [{'name': 'out/user-notes-summary.txt', 'content': 'File: work/inputs/user-notes.txt\nLines: 2\nWords: 7\nBytes: 41\n\nFirst 20 non-empty lines:\n 1\thello from skillrun\n 2\tthis is another line\n', 'mime_type': 'text/plain'}], 'artifact_files': []}]
The file `/tmp/skillrun-notes.txt` has been summarized successfully. Here are the details:
### Summary of `user-notes.txt`:
- **Lines**: 2
- **Words**: 7
- **Bytes**: 41
### Preview (First 20 non-empty lines):
- hello from skillrun
- this is another line
The summary has been saved to `out/user-notes-summary.txt`. Let me know if you'd like to perform any further actions!
Run Directory
Default working directory name: /tmp/ws_<session_id>-<time>/, files under the directory:
├── metadata.json
├── out
│ └── user-notes-summary.txt
├── runs
│ ├── run_20260116T201918.239930
│ ├── run_20260116T201918.322124
│ └── run_20260116T201918.402214
├── skills
│ └── user-file-ops
│ ├── inputs -> ../../work/inputs
│ ├── out -> ../../out
│ ├── scripts
│ │ └── summarize_file.sh
│ ├── SKILL.md
│ └── work -> ../../work
└── work
└── inputs
└── user-notes.txt
- out: Result output directory
- work: Temporary shared working directory
- runs: Current program run path
- skills: Storage directory for all skills
Advanced Usage
Custom Working Directory
By default, a workspace is created in a temporary directory (e.g., /tmp/ws_<session_id>-<time>/) when skills are executed. If you need to customize the output directory location, you can do so by setting environment variables.
Method 1: Specify in Code
def create_skill_tool_set(workspace_runtime_type: str = "local") -> SkillToolSet:
"""Create a new skill tool set."""
tool_kwargs = {
"save_as_artifacts": True,
"omit_inline_content": False,
}
if workspace_runtime_type == "local":
workspace_runtime_args = {"work_root": "/tmp/ws_abc123"}
else:
workspace_runtime_args = {}
# workspace_runtime = _create_workspace_runtime(workspace_runtime_type="container", **workspace_runtime_args)
# Create workspace runtime based on the specified type (local/container)
workspace_runtime = _create_workspace_runtime(workspace_runtime_type=workspace_runtime_type, **workspace_runtime_args)
skill_paths = _get_skill_paths()
repository = create_default_skill_repository(skill_paths, workspace_runtime=workspace_runtime)
return SkillToolSet(repository=repository, run_tool_kwargs=tool_kwargs), repository
Specify in the workspace_runtime_args parameter.
The working directory then becomes: /{custom_dir}/ws_{session_id}_{time}, for example:
/tmp/ws_abc123/ws_env_var_demo_1768564372436142924/
├── metadata.json
├── out
│ ├── fibonacci_data.txt
│ └── fibonacci_summary.txt
├── runs
│ ├── run_20260116T195252.438049
│ ├── run_20260116T195252.518753
│ ├── run_20260116T195252.597016
│ ├── run_20260116T195257.562621
│ └── run_20260116T195304.315245
├── skills
│ └── python-math
│ ├── inputs -> ../../work/inputs
│ ├── out -> ../../out
│ ├── scripts
│ │ └── fib.py
│ ├── SKILL.md
│ └── work -> ../../work
└── work
└── inputs
Method 2: Specify in the Prompt
output_instruction = f"""
IMPORTANT: When calling skill_run, you MUST pass env={{'OUTPUT_DIR': '{custom_output_dir}'}} parameter
to use the custom output directory. Write all output files to $OUTPUT_DIR (which will be '{custom_output_dir}').
"""
You can also use this approach when you expect skill execution commands to pass other environment variables.
Dynamic Tool Loading
Full example reference: skills_with_dynamic_tools/run_agent.py
URL-based Skills Root
SKILLS_ROOT supports not only local directory paths but also URL formats. The framework automatically downloads remote archive packages, extracts and caches them locally. Subsequent calls hit the cache directly without re-downloading.
Related implementation: trpc_agent_sdk/skills/_url_root.py
Supported Input Formats
| Format | Example | Description |
|---|---|---|
| Local path | /path/to/skills or ./skills |
Directly uses a local directory (default behavior, no caching involved) |
file:// URL |
file:///path/to/skills |
Explicit file URL, only supports localhost or empty host |
http:// / https:// URL |
https://example.com/skills.tar.gz |
Automatically downloads, extracts, and caches locally |
Supported archive formats for remote URLs:
| Extension | Format |
|---|---|
.zip |
ZIP archive |
.tar |
Uncompressed tar archive |
.tar.gz / .tgz |
gzip-compressed tar archive |
SKILL.md (direct link) |
Single bare skill file |
When the format cannot be determined from the extension, the framework reads magic bytes from the file header for automatic identification (ZIP: PK\x03\x04; gzip: \x1f\x8b).
Usage
Configure via environment variables:
# HTTPS + tar.gz archive
export SKILLS_ROOT="https://example.com/my-skills.tar.gz"
# HTTPS + ZIP archive
export SKILLS_ROOT="https://example.com/my-skills.zip"
# Point directly to a single SKILL.md file
export SKILLS_ROOT="https://example.com/SKILL.md"
# Explicit file URL (equivalent to a local path)
export SKILLS_ROOT="file:///home/user/my-skills"
Use directly in code:
# Directly configure the skill path
skill_path = "https://example.com/skills.tar.gz"
repository = create_default_skill_repository(skill_path, workspace_runtime=workspace_runtime)
Download Caching Mechanism
When using a URL-based SKILLS_ROOT for the first time, the framework automatically performs the following steps:
1. Download the archive to a temporary directory
{cache_dir}/tmp-skill-root-XXXXXX/download
2. Extract to a temporary extraction directory
{cache_dir}/tmp-skill-root-XXXXXX/root/
3. Write a sentinel file (marks extraction as successful)
{cache_dir}/tmp-skill-root-XXXXXX/root/.ready
4. Atomically rename to the final cache directory (named by SHA-256 hash of the URL)
{cache_dir}/{sha256_of_url}/
5. Clean up temporary directories
On subsequent calls, if the {cache_dir}/{sha256_of_url}/.ready file exists, the cached directory is returned directly, skipping download and extraction. If the cache directory exists but the .ready file is missing (e.g., a previous download was interrupted), it is automatically cleaned up and re-downloaded.
In concurrent scenarios where multiple processes download the same URL simultaneously, the framework ensures through atomic rename operations that only the first process's result is written. Other processes detect the .ready file and return immediately.
Default cache directory locations:
| Platform | Default Path |
|---|---|
| Linux | $XDG_CACHE_HOME/trpc-agent-py/skills/ or ~/.cache/trpc-agent-py/skills/ |
| macOS | ~/Library/Caches/trpc-agent-py/skills/ |
| Windows | %LocalAppData%/trpc-agent-py/skills/ |
Override via environment variable:
export SKILLS_CACHE_DIR="/custom/cache/path"
Security Restrictions
To guard against malicious archives (e.g., zip bombs) and oversized downloads, the framework enforces the following hard limits:
| Restriction | Default Value | Description |
|---|---|---|
| Maximum download size per request | 64 MiB | Includes both Content-Length pre-check and streaming write verification |
| Maximum individual extracted file size | 64 MiB | ZIP uses dual verification of header declaration and actual read |
| Total size of all extracted files | 256 MiB | Cumulative byte count limit for all entries |
Exceeding any limit raises a RuntimeError, and downloaded temporary files are automatically cleaned up.
Additionally, archive path safety is strictly enforced:
- Rejects absolute paths (e.g.,
/etc/passwd) - Rejects path traversal (e.g.,
../../etc/passwd) - Rejects Windows drive letters (e.g.,
C:foo) - Rejects symbolic links and hard link tar entries (prevents sandbox escape)
SKILL.md File Structure
The SKILL.md file uses YAML front matter (metadata) + Markdown body format:
---
name: python-math
description: Small Python utilities for math and text files.
---
Overview
Run short Python scripts inside the skill workspace...
Examples
1) Print the first N Fibonacci numbers
Command: python3 scripts/fib.py 10 > out/fib.txt
Output Files
- out/fib.txt
Writing guidelines:
- Keep it concise: The
nameanddescriptionfields should be brief and clear, used for overview display - Provide details: In the body, include when to use, steps/commands, output file paths, etc.
- Organize scripts: Place scripts in the
scripts/directory and reference them in commands
For more examples, see: https://github.com/anthropics/skills
Skill Tools Explained
skill_list
Declaration location: trpc_agent_sdk/skills/tools/_skill_list.py
Input parameters: None
Return value:
- An array of all available skill names
Behavior:
- Returns a list of all available skill names in the skill repository
- Used for discovering and browsing available skills
Prompt guidance:
This tool is automatically called by the LLM. The agent's prompt should include guidance similar to:
INSTRUCTION = """
## Skill Discovery Workflow
When a user asks for a task that might require skills:
1. **First, always check available skills**:
- Call skill_list() to see what skills are available
- This shows you all skill names like ["file-tools", "python-math", "weather-tools"]
Example:
User: "Can you help me with weather information?"
Assistant: Let me check what skills are available.
→ Call skill_list()
→ See result: ["file-tools", "python-math", "weather-tools"]
→ Notice "weather-tools" is relevant
"""
Use cases:
- User asks "What skills are available?"
- When exploring available capabilities
- When unsure which skill to use, list all skills first
skill_list_tools
Declaration location: trpc_agent_sdk/skills/tools/_skill_list_tool.py
Input parameters:
skill_name(required): Skill name
Return value:
- An array of tool names defined in the
Tools:section of the skill'sSKILL.md - Returns an empty array if the skill defines no tools
Behavior:
- Returns the list of tools declared in the specified skill's
SKILL.md - Used to preview the tools provided by a skill before loading it
- Note: Only returns tools explicitly listed in
SKILL.md, not all tools in the actual code
Prompt guidance:
This tool is called by the LLM before loading a skill. The prompt should include:
INSTRUCTION = """
## Skill Inspection Workflow
Before loading ANY skill, you MUST inspect its tools:
2. **Preview skill tools before loading**:
- Call skill_list_tools(skill_name="skill-name")
- This shows what tools the skill provides
- Verify the skill has the tools you need
Example:
Assistant: I found "weather-tools" skill. Let me check what it provides.
→ Call skill_list_tools(skill_name="weather-tools")
→ See result: ["get_current_weather", "get_weather_forecast", "search_city_by_name"]
→ Confirm it has "get_current_weather" which I need
→ Proceed to load the skill
**Why this step matters**:
- Avoids loading unnecessary skills
- Confirms the skill has required capabilities
- Saves tokens by loading only relevant skills
"""
Use cases:
- Verify a skill provides the required tools before calling
skill_load - User asks "What tools does this skill have?"
- When choosing the appropriate skill
Definition in SKILL.md:
Tools are declared in the Tools: section of the SKILL.md file:
---
name: weather-tools
description: Weather information query tools
---
Tools:
- get_current_weather
- get_weather_forecast
- search_city_by_name
# comment: this tool is deprecated
# - old_weather_api
Overview
...
skill_select_tools
Declaration location: trpc_agent_sdk/skills/tools/_skill_select_tools.py
Input parameters:
skill_name(required): Skill nametools(optional): Array of tool namesinclude_all_tools(optional): Boolean, whether to include all toolsmode(optional): String, operation modeadd: Add tools to the existing listreplace: Replace the existing tool list (default)clear: Clear all tools
Return value:
SkillSelectToolsResultobject containing:selected_tools: Array of selected tool namesinclude_all_tools: Whether all tools are included
Behavior:
- Optimizes LLM context: activates only the tools needed for the current conversation
- Updates the
temp:skill:tools:<name>session key - When used with
DynamicSkillToolSet, only selected tools are loaded into the LLM context
Prompt guidance:
This tool is called by the LLM after loading a skill to optimize token usage. The prompt should include:
INSTRUCTION = """
## Tool Selection for Token Optimization
After loading a skill, you SHOULD refine tool selection:
4. **Optimize tool selection** (RECOMMENDED):
- After skill_load(), all tools from SKILL.md are auto-selected
- If you only need specific tools, call skill_select_tools() to reduce tokens
- This is especially important for skills with many tools
Example 1: Select specific tools
User: "What's the current weather in Beijing?"
Assistant:
→ skill_load(skill_name="weather-tools") # Auto-selects all 3 tools
→ skill_select_tools(
skill_name="weather-tools",
tools=["get_current_weather"], # Only need current weather
mode="replace"
)
→ Result: Only 1 tool active instead of 3 (saves ~60% tokens)
Example 2: Multi-tool task
User: "Get current weather and 3-day forecast for Shanghai"
Assistant:
→ skill_load(skill_name="weather-tools")
→ skill_select_tools(
skill_name="weather-tools",
tools=["get_current_weather", "get_weather_forecast"],
mode="replace"
)
→ Result: 2 out of 3 tools active (saves ~30% tokens)
Example 3: Add more tools later
Assistant:
→ skill_select_tools(
skill_name="weather-tools",
tools=["search_city_by_name"], # Need to search city
mode="add" # Add to existing selection
)
**Token Savings**:
- A skill with 10 tools → select 2 → saves ~80% tool definition tokens
- Especially valuable for skills with complex tools
"""
Use cases:
- Optimize tool selection after
skill_loadto reduce token consumption - When a task only requires a subset of a skill's tools
- Dynamically adjust available tools during the conversation
Relationship with skill_load:
skill_loadautomatically selects all tools defined inSKILL.mdskill_select_toolsis used for further refinement to achieve token optimization
skill_load
Declaration location: trpc_agent_sdk/skills/tools/_skill_load.py
Input parameters:
skill_name(required): Skill namedocs(optional): Array of document file names to loadinclude_all_docs(optional): Boolean, whether to include all documentation
Return value:
- A success message string, e.g.:
"skill 'python-math' loaded"
Behavior:
- Writes temporary session keys (per turn):
temp:skill:loaded:<name>= "1" (marks the skill as loaded)temp:skill:docs:<name>= "*" (all documentation) or JSON array (specified document list)temp:skill:tools:<name>= JSON array (tool list automatically parsed fromSKILL.md)
- The request processor injects the
SKILL.mdbody content and selected documentation into the system message - Automatically selects all tools defined in the
Tools:section ofSKILL.md
Prompt guidance:
This tool is called by the LLM after confirming a skill is needed. The prompt should include:
INSTRUCTION = """
## Skill Loading Workflow
After confirming a skill is appropriate:
3. **Load the skill**:
- Call skill_load(skill_name="skill-name")
- This injects the full SKILL.md body content into context
- Automatically selects all tools defined in the skill's SKILL.md
- Optionally load specific docs or all docs
Example 1: Load skill without docs
Assistant:
→ skill_load(skill_name="python-math")
→ Result: Full SKILL.md content loaded, all tools auto-selected
→ Can now use the skill's tools or run commands
Example 2: Load skill with specific docs
Assistant:
→ skill_load(
skill_name="weather-tools",
docs=["API_REFERENCE.md"] # Load specific documentation
)
Example 3: Load skill with all docs
Assistant:
→ skill_load(
skill_name="data-analysis",
include_all_docs=True # Load all available docs
)
**What happens after loading**:
- SKILL.md body is injected into your context (Overview, Examples, etc.)
- All tools listed in SKILL.md Tools: section are automatically selected
- You can now see detailed usage instructions and examples
- You can call skill_run or use the skill's tools
**Multiple loads**:
- Safe to call multiple times on the same skill
- Subsequent calls can add/replace docs
- Tool selection persists until modified by skill_select_tools
"""
Use cases:
- Load a skill after confirming the requirement via
skill_listandskill_list_tools - Need to view detailed usage instructions and examples for a skill
- Preparing to use a skill's tools or execute commands
Usage notes:
- Can be safely called multiple times to add or replace documentation
- First load automatically selects all tools; use
skill_select_toolsfor further optimization
skill_select_docs
Declaration location: trpc_agent_sdk/skills/tools/_skill_select_docs.py
Input parameters:
skill_name(required): Skill namedocs(optional): Array of document file namesinclude_all_docs(optional): Boolean, whether to include all documentationmode(optional): String, operation modeadd: Add documents to the existing listreplace: Replace the existing document list (default)clear: Clear all documents
Return value:
SkillSelectDocsResultobject containing:selected_docs: Array of selected document namesinclude_all_docs: Whether all documents are included
Behavior:
- Updates the
temp:skill:docs:<name>session key:*: Indicates all documents are included- JSON array: Indicates an explicitly specified document list
- On the next LLM request, the selected document content is injected into the system message
Prompt guidance:
This tool is called by the LLM when additional documentation is needed. The prompt should include:
INSTRUCTION = """
## Documentation Selection
If the SKILL.md body is not sufficient, you can load additional docs:
5. **Select additional documentation** (when needed):
- Call skill_select_docs() to load reference documentation
- Use this when you need API details, configuration info, etc.
Example 1: Load specific docs
Assistant: I need more details about the API.
→ skill_select_docs(
skill_name="weather-tools",
docs=["API_REFERENCE.md", "CONFIGURATION.md"],
mode="replace"
)
Example 2: Load all docs
Assistant: Let me load all available documentation.
→ skill_select_docs(
skill_name="data-analysis",
include_all_docs=True
)
Example 3: Add more docs
Assistant: I need additional reference.
→ skill_select_docs(
skill_name="weather-tools",
docs=["TROUBLESHOOTING.md"],
mode="add" # Add to existing docs
)
**When to use**:
- SKILL.md Overview is insufficient
- Need detailed API reference
- Need configuration examples
- Troubleshooting specific issues
"""
Use cases:
- The
SKILL.mdbody content is insufficient to complete the task - Need to view API reference documentation
- Need configuration examples or troubleshooting guides
skill_list_docs
Declaration location: trpc_agent_sdk/skills/tools/_skill_list_docs.py
Input parameters:
skill_name(required): Skill name
Return value:
- An array of available document file names (e.g.,
["API_REFERENCE.md", "CONFIGURATION.md", "TROUBLESHOOTING.md"])
Behavior:
- Lists all available document files for the specified skill
- Used to view available documentation before calling
skill_select_docs
Prompt guidance:
This tool is called by the LLM when it needs to view available documentation. The prompt should include:
INSTRUCTION = """
## Documentation Discovery
Before selecting docs, you can check what's available:
**Check available docs**:
→ skill_list_docs(skill_name="skill-name")
→ Returns: ["API_REFERENCE.md", "USAGE_EXAMPLES.md", ...]
Example workflow:
User: "I need help configuring the weather API"
Assistant: Let me check what documentation is available.
→ skill_list_docs(skill_name="weather-tools")
→ Result: ["API_REFERENCE.md", "CONFIGURATION.md", "FAQ.md"]
→ I see there's a CONFIGURATION.md, let me load it.
→ skill_select_docs(
skill_name="weather-tools",
docs=["CONFIGURATION.md"]
)
**When to use**:
- Before calling skill_select_docs
- User asks "what documentation is available?"
- Need to find specific reference materials
"""
Use cases:
- View available documentation before calling
skill_select_docs - User asks "What documentation does this skill have?"
Note: These session keys are automatically managed by the framework; in the natural conversation flow, you typically do not need to manipulate them directly.
skill_run
Declaration location: trpc_agent_sdk/skills/tools/_skill_run.py
Input parameters:
skill(required): Skill namecommand(required): Shell command to executeoutput_files(optional): Array of glob patterns for output files (e.g.,["out/*.txt", "$OUTPUT_DIR/result.json"])env(optional): Dictionary of custom environment variables (e.g.,{"CUSTOM_VAR": "value"})timeout(optional): Timeout in seconds
Return value:
WorkspaceRunResultobject containing:stdout: Standard outputstderr: Standard errorexit_code: Exit codetimed_out: Whether it timed outduration_ms: Execution duration in millisecondsoutput_files: Array of collected output files (each containingname,content,mime_type)artifact_files: Artifact file information
Behavior:
- Executes shell commands in an isolated workspace
- Automatically injects standard environment variables (
$WORKSPACE_DIR,$SKILLS_DIR,$WORK_DIR,$OUTPUT_DIR,$RUN_DIR,$SKILL_NAME) - Collects specified output files and returns them
- Supports custom environment variable overrides
Prompt guidance:
This tool is called by the LLM when ready to execute actual commands. The prompt should include detailed usage guidelines:
INSTRUCTION = """
## Skill Execution
After loading a skill, you can execute commands:
6. **Execute skill commands**:
- Call skill_run(skill="skill-name", command="...", output_files=[...])
- Commands run in the skill's directory
- Use environment variables for portable paths
Example 1: Simple command execution
Assistant:
→ skill_run(
skill="python-math",
command="python3 scripts/fib.py 10 > $OUTPUT_DIR/fib.txt",
output_files=["$OUTPUT_DIR/fib.txt"]
)
Example 2: Multiple output files
Assistant:
→ skill_run(
skill="data-analysis",
command="python3 scripts/analyze.py $WORK_DIR/inputs/data.csv",
output_files=[
"$OUTPUT_DIR/*.txt",
"$OUTPUT_DIR/charts/*.png"
]
)
Example 3: Custom environment variables
Assistant:
→ skill_run(
skill="weather-tools",
command="python3 scripts/fetch.py",
env={
"API_KEY": "user-provided-key",
"REGION": "asia"
},
output_files=["$OUTPUT_DIR/weather.json"]
)
Example 4: Complex multi-step command
Assistant:
→ skill_run(
skill="file-tools",
command='''
mkdir -p $OUTPUT_DIR/processed &&
cp $WORK_DIR/inputs/*.txt $OUTPUT_DIR/processed/ &&
ls -la $OUTPUT_DIR/processed
''',
output_files=["$OUTPUT_DIR/processed/*"]
)
**Environment Variables Available**:
- $WORKSPACE_DIR: Root workspace directory
- $SKILLS_DIR: Skills directory (contains skill folders)
- $WORK_DIR: Shared working directory
- $WORK_DIR/inputs: User input files (read-only)
- $OUTPUT_DIR: Output directory (write final results here)
- $RUN_DIR: Current run's directory (unique per execution)
- $SKILL_NAME: Current skill name (e.g., "python-math")
**Best Practices**:
1. Always use environment variables (not hard-coded paths)
2. Write final outputs to $OUTPUT_DIR
3. Read user files from $WORK_DIR/inputs
4. Include output_files parameter to collect results
5. Use descriptive output file names
**Common Patterns**:
# Generate output file
command="python3 scripts/process.py > $OUTPUT_DIR/result.txt"
# Process input and generate output
command="bash scripts/transform.sh $WORK_DIR/inputs/data.csv $OUTPUT_DIR/output.csv"
# Multiple commands
command="mkdir -p $OUTPUT_DIR/reports && python3 scripts/generate.py && ls $OUTPUT_DIR"
# Use SKILL_NAME for context
command="echo 'Processed by $SKILL_NAME' > $OUTPUT_DIR/metadata.txt"
**Error Handling**:
- Check exit_code in the result (0 = success)
- Read stderr for error messages
- Adjust timeout if command takes too long
"""
Use cases:
- Execute scripts or commands within a skill
- Process files and generate output
- Run data analysis, transformation, and other tasks
Execution flow
LLM calls skill_run(skill="python-math", command="python3 scripts/fib.py 10")
↓
1. Create an isolated workspace
/tmp/ws_<session_id>/
├── skills/python-math/ (skill root directory, read-only)
│ ├── SKILL.md
│ ├── scripts/
│ │ └── fib.py
│ ├── out/ → ../../out (symbolic link)
│ └── work/ → ../../work (symbolic link)
├── out/ (output directory)
├── work/ (working directory)
└── run/ (run directory)
↓
2. Inject environment variables
WORKSPACE_DIR=/tmp/ws_<session_id>
SKILLS_DIR=/tmp/ws_<session_id>/skills
WORK_DIR=/tmp/ws_<session_id>/work
OUTPUT_DIR=/tmp/ws_<session_id>/out
RUN_DIR=/tmp/ws_<session_id>/run
SKILL_NAME=python-math
↓
3. Execute command (in skill root directory)
cd /tmp/ws_<session_id>/skills/python-math
bash -lc "python3 scripts/fib.py 10"
↓
4. Collect output files
Collect files based on the output_files parameter
e.g.: out/*.txt → /tmp/ws_<session_id>/out/*.txt
↓
5. Return results
{
"stdout": "...",
"stderr": "...",
"exit_code": 0,
"output_files": [...]
}
Runtime Environment
Interface definition: trpc_agent_sdk/code_executors/_base_workspace_runtime.py
Implementations:
- Local executor: trpc_agent_sdk/code_executors/local/_local_ws_runtime.py
- Executes commands directly on the local system, suitable for development and testing
- Container executor (Docker): trpc_agent_sdk/code_executors/container/_container_ws_runtime.py
- Executes in Docker containers, providing better isolation
- Cube executor (remote E2B sandbox): trpc_agent_sdk/code_executors/cube/_runtime.py
- Executes inside a remote Cube/E2B sandbox; suitable for environments without local Docker, or when strong remote isolation is required
- Construct via
create_cube_workspace_runtime(executor, workspace_cfg=...); see code_executor.md for details - Requires the optional
[cube]extra (pip install 'trpc-agent-py[cube]') and theE2B_API_URL/E2B_API_KEY/CUBE_TEMPLATE_IDenvironment variables (or equivalent cfg fields)
Container executor notes:
- The run base directory is writable; when
$SKILLS_ROOTis set, it is mounted in read-only mode - Network access is disabled by default for reproducibility and security
Cube executor notes:
- File and directory transfers use a tar-based protocol so directory upload/download stays a single round-trip and preserves symlinks/permissions
- The remote workspace root defaults to
/workspace/cube_agent; per-execution subtrees follow thews_<exec_id>_<suffix>naming convention and are recreated lazily on everycreate_workspacecall (so external sandbox cleanup heals transparently) - The same Cube sandbox can back both the bare
CubeCodeExecutorand the workspace runtime; commands shareexecute_timeoutfromCubeCodeExecutorConfig
Security and resource limits:
- **W
…(truncated)