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",
…