live1,247 agents deployed
← All skillsSign up to install

tool-design-pattern

General↓ 0 installsUpdated 105d ago
Curatedmajiayu000

Automatically applies when creating AI tool functions. Ensures proper schema design, input validation, error handling, context access, and comprehensive testing.

SKILL.md preview

---
name: tool-design-pattern
description: Automatically applies when creating AI tool functions. Ensures proper schema design, input validation, error handling, context access, and comprehensive testing.
---

# AI Tool Design Pattern Enforcer

When creating tools for AI agents (LangChain, function calling, etc.), follow these design patterns.

## ✅ Standard Tool Pattern

```python
from langchain.tools import tool
from pydantic import BaseModel, Field
from typing import Optional
import logging

logger = logging.getLogger(__name__)

# 1. Define input schema
class SearchInput(BaseModel):
    """Input schema for search tool."""

    query: str = Field(..., description="Search query string")
    max_results: int = Field(
        default=10,
        ge=1,
        le=100,
        description="Maximum number of results to return"
    )
    filter_type: Optional[str] = Field(
        None,
        description="Optional filter type (e.g., 'recent', 'popular')"
    )

# 2. Implement tool function
@tool(args_schema=SearchInput)
def search_database(query: str, max_results: int = 10, filter_type: Optional[str] = None) -> str:
    """
    Search database for relevant information.

    Use this tool when user asks to find, search, or look up information.
    Returns JSON string with search results.

    Args:
        query: Search query string
        max_results: Maximum number of results (1-100)
        filter_type: Optional filter (recent, popular)

    Returns:
        JSON string with results or error message
    """
    request_id = str(uuid.uuid4())

    try:
        # Log tool invocation
        logger.info(
            f"TOOL_CALL: search_database | "
            f"query={query[:50]} | "
            f"request_id={request_id}"
        )

        # Validate inputs
        if not query or not query.strip():
            return json.dumps({
                "error": "Query cannot be empty",
                "request_id": request_id
            })

        # Execute search
        results = _execute_search(query, max_results, filter_type)

        # Return structured response
        return json.dumps({
            "results": results,
            "total": len(results),
            "request_id": request_id
        })

    except Exception as e:
        logger.error(f"Tool error | request_id={request_id}", exc_info=True)
        return json.dumps({
            "error": "Search failed",
            "request_id": request_id,
            "timestamp": datetime.now().isoformat()
        })

# 3. Helper implementation
def _execute_search(query: str, max_results: int, filter_type: Optional[str]) -> List[dict]:
    """Internal search implementation."""
    # Actual search logic
    pass
```

## Tool Schema Design

```python
from pydantic import BaseModel, Field, field_validator
from typing import Literal, Optional

class EmailToolInput(BaseModel):
    """Well-designed tool input schema."""

    recipient: str = Field(
        ...,
        description="Email address of recipient (e.g., user@example.com)"
    )

    subject: str = Field(
        ...,
        description="Email subject line",
        min_length=1,
        max_length=200
    )

    body: str = Field(
        ...,
        description="Email body content",
        min_length=1
    )

    priority: Literal["low", "normal", "high"] = Field(
        default="normal",
        description="Email priority level"
    )

    attach_invoice: bool = Field(
        default=False,
        description="Whether to attach invoice PDF"
    )

    @field_validator('recipient')
    @classmethod
    def validate_email(cls, v: str) -> str:
        if '@' not in v:
            raise ValueError('Invalid email address')
        return v.lower()

    class Config:
        json_schema_extra = {
            "example": {
                "recipient": "customer@example.com",
                "subject": "Order Confirmation",
                "body": "Thank you for your order!",
                "priority": "normal",
     

…