*** id: 74fe63c2-2aee-4450-9afb-012b4b2b0478 title: Understanding Skills sidebar-title: Understanding Skills slug: /python/guides/understanding-skills max-toc-depth: 3 ---------------- # Skills Skills are modular, reusable capabilities that add functions, prompts, and integrations to your agents without custom code. ## What You'll Learn This chapter covers the skills system: 1. **Understanding Skills** - What skills are and how they work 2. **Built-in Skills** - Pre-built skills available in the SDK 3. **Adding Skills** - How to add skills to your agents 4. **Custom Skills** - Creating your own skills 5. **Skill Configuration** - Parameters and advanced options ## What Are Skills? Skills are pre-packaged capabilities that add: * **Functions** - SWAIG tools the AI can call * **Prompts** - Instructions for how to use the skill * **Hints** - Speech recognition keywords * **Global Data** - Variables available throughout the call | Without Skills | With Skills | | ---------------------- | --------------------------- | | Write weather function | `self.add_skill("weather")` | | Add API integration | | | Write prompts | Done! | | Add speech hints | | | Handle errors | | ## Quick Start Add a skill in one line: ```python from signalwire_agents import AgentBase class MyAgent(AgentBase): def __init__(self): super().__init__(name="my-agent") self.add_language("English", "en-US", "rime.spore") # Add datetime capability self.add_skill("datetime") # Add math capability self.add_skill("math") self.prompt_add_section( "Role", "You are a helpful assistant that can tell time and do math." ) ``` ## Available Built-in Skills | Skill | Description | | ---------------------- | --------------------------------- | | `datetime` | Get current date and time | | `math` | Perform calculations | | `web_search` | Search the web (requires API key) | | `wikipedia_search` | Search Wikipedia | | `weather_api` | Get weather information | | `joke` | Tell jokes | | `play_background_file` | Play audio files | | `swml_transfer` | Transfer calls to SWML endpoints | | `datasphere` | Search DataSphere documents | | `native_vector_search` | Local vector search | ## Chapter Contents | Section | Description | | ------------------------------------------------------------------ | -------------------------------- | | [Built-in Skills](/docs/agents-sdk/python/guides/builtin-skills) | Reference for included skills | | [Adding Skills](/docs/agents-sdk/python/guides/adding-skills) | How to use skills in your agents | | [Custom Skills](/docs/agents-sdk/python/guides/custom) | Creating your own skills | | [Skill Configuration](/docs/agents-sdk/python/guides/skill-config) | Parameters and advanced options | ## Skills vs Functions | Aspect | SWAIG Function | Skill | | ----------------- | --------------- | ------------------------------------ | | **Scope** | Single function | Multiple functions + prompts + hints | | **Reusability** | Per-agent | Across all agents | | **Setup** | define\_tool() | add\_skill() | | **Customization** | Full control | Parameters only | | **Maintenance** | You maintain | SDK maintains | ## When to Use Skills ### Use Built-in Skills When: * Standard capability needed (datetime, search, etc.) * Want quick setup without custom code * Need tested, maintained functionality ### Create Custom Skills When: * Reusing capability across multiple agents * Want to share functionality with team/community * Packaging complex integrations ### Use SWAIG Functions When: * One-off custom logic * Agent-specific business rules * Need full control over implementation ## Complete Example ```python #!/usr/bin/env python3 # assistant_agent.py - Agent with multiple skills from signalwire_agents import AgentBase class AssistantAgent(AgentBase): def __init__(self): super().__init__(name="assistant") self.add_language("English", "en-US", "rime.spore") # Add multiple skills self.add_skill("datetime") self.add_skill("math") self.prompt_add_section( "Role", "You are a helpful assistant named Alex." ) self.prompt_add_section( "Capabilities", body="You can help with:", bullets=[ "Telling the current date and time", "Performing math calculations" ] ) if __name__ == "__main__": agent = AssistantAgent() agent.run() ``` Let's start by understanding how skills work internally. ## Skill Architecture ### SkillBase (Abstract Base Class) **Required Methods:** * `setup()` - Initialize the skill * `register_tools()` - Register SWAIG functions **Optional Methods:** * `get_hints()` - Speech recognition hints * `get_global_data()` - Session data * `get_prompt_sections()` - Prompt additions * `cleanup()` - Resource cleanup ### SkillRegistry (Discovery & Loading) * Discovers skills from directories * Loads skills on-demand (lazy loading) * Validates requirements (packages, env vars) * Supports external skill paths ## How Skills Work Skills are a convenience layer built on top of SWAIG functions. When you add a skill, it registers one or more SWAIG functions with the agent, adds relevant prompts, and configures hints—all from a single `add_skill()` call. Understanding this helps when debugging: a skill's function behaves exactly like a SWAIG function you'd define yourself. The only difference is that the skill packages everything together. When you call `add_skill()`: Skill Loading Process. ## Skill Directory Structure Built-in skills live in the SDK: Each skill directory contains: | File | Purpose | | ------------------ | --------------------------- | | `skill.py` | Skill class implementation | | `__init__.py` | Python package marker | | `requirements.txt` | Optional extra dependencies | ## SkillBase Class All skills inherit from `SkillBase`: ```python from signalwire_agents.skills import SkillBase from signalwire_agents.core.function_result import SwaigFunctionResult class MySkill(SkillBase): # Required class attributes SKILL_NAME = "my_skill" SKILL_DESCRIPTION = "Does something useful" SKILL_VERSION = "1.0.0" # Optional requirements REQUIRED_PACKAGES = [] # Python packages needed REQUIRED_ENV_VARS = [] # Environment variables needed # Multi-instance support SUPPORTS_MULTIPLE_INSTANCES = False def setup(self) -> bool: """Initialize the skill. Return True if successful.""" return True def register_tools(self) -> None: """Register SWAIG tools with the agent.""" self.define_tool( name="my_function", description="Does something", parameters={}, handler=self.my_handler ) def my_handler(self, args, raw_data): """Handle function calls.""" return SwaigFunctionResult("Result") ``` ## Skill Lifecycle ``` Discover → Load → Setup → Register → Active → Cleanup ``` | Stage | Description | | ------------ | ------------------------------------------------------- | | **Discover** | Registry finds skill class in directory | | **Load** | Skill class is imported and validated | | **Setup** | `setup()` validates requirements, initializes resources | | **Register** | `register_tools()` adds functions to agent | | **Active** | Skill is ready, functions can be called | | **Cleanup** | `cleanup()` releases resources on shutdown | ## Skill Contributions Skills can contribute to the agent in multiple ways: ### 1. Tools (Functions) ```python def register_tools(self) -> None: self.define_tool( name="get_time", description="Get current time", parameters={ "timezone": { "type": "string", "description": "Timezone name" } }, handler=self.get_time_handler ) ``` ### 2. Prompt Sections ```python def get_prompt_sections(self): return [ { "title": "Time Information", "body": "You can tell users the current time.", "bullets": [ "Use get_time for time queries", "Support multiple timezones" ] } ] ``` ### 3. Speech Hints ```python def get_hints(self): return ["time", "date", "clock", "timezone"] ``` ### 4. Global Data ```python def get_global_data(self): return { "datetime_enabled": True, "default_timezone": "UTC" } ``` ## Skill Discovery Paths Skills are discovered from multiple locations in priority order: | Priority | Source | Example | | -------- | ------------------------------------- | --------------------------------------------------------------------- | | 1 | Already registered skills (in memory) | - | | 2 | Entry points (pip installed packages) | `entry_points={'signalwire_agents.skills': ['my_skill = pkg:Skill']}` | | 3 | Built-in skills directory | `signalwire_agents/skills/` | | 4 | External paths | `skill_registry.add_skill_directory('/opt/custom_skills')` | | 5 | Environment variable paths | `SIGNALWIRE_SKILL_PATHS=/path1:/path2` | ## Lazy Loading Skills are loaded on-demand to minimize startup time: ```python # Skill NOT loaded yet agent = MyAgent() # Skill loaded when first referenced agent.add_skill("datetime") # datetime skill loaded here # Already loaded, reused agent.add_skill("datetime") # Uses cached class ``` ## Multi-Instance Skills Some skills support multiple instances with different configurations: ```python class MySkill(SkillBase): SUPPORTS_MULTIPLE_INSTANCES = True def get_instance_key(self) -> str: # Unique key for this instance tool_name = self.params.get('tool_name', self.SKILL_NAME) return f"{self.SKILL_NAME}_{tool_name}" ``` Usage: ```python # Add two instances with different configs agent.add_skill("web_search", { "tool_name": "search_news", "search_engine_id": "NEWS_ENGINE_ID", "api_key": "KEY" }) agent.add_skill("web_search", { "tool_name": "search_docs", "search_engine_id": "DOCS_ENGINE_ID", "api_key": "KEY" }) ``` ## Parameter Passing Parameters flow through skills in a structured way: **At add\_skill() time:** ```python self.add_skill("web_search", { "api_key": "your-key", "tool_name": "custom_search", "max_results": 5 }) ``` The skill receives these in `self.params` during setup: ```python def setup(self) -> bool: self.api_key = self.params.get("api_key") self.max_results = self.params.get("max_results", 3) return True ``` **At function call time:** The AI calls the function with arguments: ```python def search_handler(self, args, raw_data): query = args.get("query") # From AI's function call max_results = self.max_results # From skill config # ... ``` ## Result Handling Skill handlers return `SwaigFunctionResult` just like regular SWAIG functions: ```python def my_handler(self, args, raw_data): # Success case return SwaigFunctionResult("The result is 42") # With actions return ( SwaigFunctionResult("Updated your preferences") .update_global_data({"preference": "value"}) ) # Error case - still return a result for the AI return SwaigFunctionResult("I couldn't complete that request. Please try again.") ``` The result goes back to the AI, which uses it to formulate a response to the user. ## Error Handling and Propagation Skills should handle errors gracefully and return meaningful messages: ```python def api_handler(self, args, raw_data): try: result = self.call_external_api(args) return SwaigFunctionResult(f"Result: {result}") except requests.Timeout: return SwaigFunctionResult( "The service is taking too long to respond. Please try again." ) except requests.RequestException as e: self.agent.log.error(f"API error: {e}") return SwaigFunctionResult( "I'm having trouble connecting to the service right now." ) except Exception as e: self.agent.log.error(f"Unexpected error: {e}") return SwaigFunctionResult( "Something went wrong. Please try again." ) ``` **Error handling principles:** * Always return a `SwaigFunctionResult`, even on errors * Make error messages user-friendly (the AI will relay them) * Log technical details for debugging * Don't expose internal errors to users ## Debugging Skills When skills don't work as expected: **1. Check if the skill loaded:** ```python # In your agent print(f"Skills loaded: {list(self._skill_manager._skills.keys())}") ``` **2. Verify functions are registered:** ```bash swaig-test your_agent.py --dump-swml | grep -A 5 "functions" ``` **3. Test the function directly:** ```bash swaig-test your_agent.py --function skill_function_name --args '{"param": "value"}' ``` **4. Check for missing requirements:** Skills log warnings if required packages or environment variables are missing. Check your logs during agent startup. **5. Look at skill source:** Built-in skills are in the SDK source. Examine them to understand how they work: ```bash pip show signalwire-agents # Find location, then look in signalwire_agents/skills/ ```