Development Guide¶
This guide provides comprehensive instructions for developing with the LLM Tool System Foundation, including creating new tools, testing, and deployment.
Development Workflow¶
Setting Up Development Environment¶
# Install development dependencies
uv sync --dev
# Run code quality checks
uv run black .
uv run ruff check .
uv run mypy app/
# Run tests
python run_tests.py --unit
python run_tests.py --integration
Creating New Tools¶
1. Implement BaseTool Interface¶
from app.core.tools import BaseTool
class NewTool(BaseTool):
@property
def name(self) -> str:
return "new_tool"
@property
def description(self) -> str:
return "Description of the new tool"
async def execute(self, **kwargs) -> Any:
# Tool implementation
return {"result": "success"}
2. Register the Tool¶
# In app/core/tools/__init__.py or tool initialization module
from .new_tool import NewTool
tool_registry.register(NewTool())
3. Write Tests¶
@pytest.mark.asyncio
async def test_new_tool():
tool = NewTool()
result = await tool.execute(param="value")
assert result["result"] == "success"
Code Standards¶
- Use type hints throughout
- Follow Black code formatting
- Write comprehensive docstrings
- Include unit tests for new features
- Update documentation for changes
Testing¶
Running Tests¶
# Run all tests
python run_tests.py
# Run specific test types
python run_tests.py --unit
python run_tests.py --integration
python run_tests.py --coverage
# Run with verbose output
python run_tests.py --verbose
Test Structure¶
tests/
├── test_main.py # Unit tests
├── test_integration.py # Integration tests
├── test_routes.py # API route tests
├── test_monitoring.py # Monitoring tests
└── test_caching/ # Caching system tests
├── test_base.py
├── test_caching_system.py
└── test_memory_cache.py
Example Test¶
@pytest.mark.asyncio
async def test_tool_execution():
from app.core.tools.examples import CalculatorTool
tool = CalculatorTool()
result = await tool.execute(expression="10 + 15")
assert result == 25
Deployment¶
Production Deployment¶
# Install production dependencies
uv sync
# Start production server
uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 4
Docker Deployment¶
FROM python:3.12-slim
WORKDIR /app
COPY . .
RUN uv sync --dev
EXPOSE 8000
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
Environment Configuration¶
# Production environment
ENVIRONMENT=production
DEBUG=false
RELOAD=false
# Enable Redis for production caching
REDIS_CACHE_ENABLED=true
REDIS_URL=redis://redis-server:6379
# Monitoring and logging
MONITORING_ENABLED=true
LOG_LEVEL=INFO
Examples & Best Practices¶
Tool Integration Example¶
# Complete tool integration example
from app.core.tools import BaseTool, tool_registry
from app.core.agents import ToolAgent
class WebSearchTool(BaseTool):
@property
def name(self) -> str:
return "web_search"
@property
def description(self) -> str:
return "Search the web for current information"
async def execute(self, query: str, max_results: int = 5) -> List[Dict]:
# Implementation using SearX or other search engine
return search_results
# Register and use
tool_registry.register(WebSearchTool())
agent = ToolAgent(llm, tool_registry)
response = await agent.process_message("Current news about AI")
Caching Best Practices¶
# Use caching for expensive operations
async def get_user_data(user_id: str):
cache_key = f"user:{user_id}:profile"
cached_data = await cache_get(cache_key)
if cached_data:
return cached_data
# Expensive operation
user_data = await database.get_user(user_id)
await cache_set(cache_key, user_data, ttl=3600)
return user_data
Error Handling¶
try:
result = await tool.execute_with_timeout(**parameters)
if result.success:
return result.data
else:
logger.error(f"Tool failed: {result.error}")
return fallback_response
except ToolTimeoutError:
logger.warning("Tool execution timed out")
return timeout_response
Monitoring & Observability¶
Key Metrics¶
- Tool execution times and success rates
- Cache hit/miss ratios
- Agent response times
- System resource usage
Health Checks¶
# Check system health
curl http://localhost:8000/health
# Get metrics
curl http://localhost:8000/metrics
Logging Configuration¶
import logging
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
Configuration¶
Environment Variables¶
# Core Settings
OPENROUTER_API_KEY=your_openrouter_api_key
DEFAULT_MODEL=anthropic/claude-3.5-sonnet
HOST=127.0.0.1
PORT=8000
# Tool System
TOOL_CALLING_ENABLED=true
MAX_TOOLS_PER_QUERY=3
TOOL_TIMEOUT_SECONDS=30
# Caching
MEMORY_CACHE_ENABLED=true
REDIS_CACHE_ENABLED=false
CACHE_COMPRESSION_ENABLED=true
# Monitoring
MONITORING_ENABLED=true
METRICS_COLLECTION_ENABLED=true
Tool-Specific Configuration¶
from app.core.tools.config import tool_settings
# Access tool configuration
print(f"Calculator enabled: {tool_settings.calculator_tool_enabled}")
print(f"Default timeout: {tool_settings.tool_timeout_seconds}")