Skip to main content

A developer-friendly framework for building AI agents with Google ADK

Project description

FastADK

FastADK is an open‑source Python framework that makes building LLM-powered agents simple, efficient, and production-ready. It offers declarative APIs, comprehensive observability, and powerful scaling capabilities that enable developers to go from prototype to production with the same codebase.

Features

Core Features

  • Declarative Agent Development: Build agents with @Agent and @tool decorators
  • Multi-Provider Support: Easily switch between OpenAI, Anthropic, Google Gemini, and custom providers
  • Token & Cost Tracking: Built-in visibility into token usage and cost estimation
  • Memory Management: Sliding window, summarization, and vector store memory backends
  • Async & Parallelism: True async execution for high performance and concurrency
  • Plugin Architecture: Extensible system for custom integrations and tools
  • Context Policies: Advanced context management with customizable strategies
  • Configuration System: Powerful YAML/environment-based configuration

Developer Experience

  • CLI Tools: Interactive REPL, configuration validation, and project scaffolding
  • Debugging & Observability: Structured logs, metrics, traces, and verbose mode
  • Testing Utilities: Mock LLMs, simulation tools, and test scenario decorators
  • IDE Support: VSCode snippets and type hints for better autocompletion
  • Hot Reload: Development mode with auto-reload for rapid iteration

Integration & Extension

  • HTTP API: Auto-generated FastAPI endpoints for all agents
  • Workflow Orchestration: Build complex multi-agent systems with sequential and parallel execution
  • System Adapters: Ready-made Discord and Slack integrations
  • Fine-tuning Helpers: Utilities for model customization and training
  • Batch Processing: Tooling for high-volume processing

Quick Start

from fastadk import Agent, BaseAgent, tool

@Agent(model="gemini-1.5-pro", description="Weather assistant")
class WeatherAgent(BaseAgent):
    @tool
    def get_weather(self, city: str) -> dict:
        """Fetch current weather for a city."""
        # This would typically come from an actual weather API
        return {
            "city": city,
            "current": {
                "temp_c": 22.5,
                "condition": "Partly cloudy",
                "humidity": 65,
                "wind_kph": 15.3
            },
            "forecast": {
                "tomorrow": {"temp_c": 24.0, "condition": "Sunny"},
                "day_after": {"temp_c": 20.0, "condition": "Light rain"}
            }
        }

# Run the agent
if __name__ == "__main__":
    import asyncio
    
    async def main():
        agent = WeatherAgent()
        response = await agent.run("What's the weather in London?")
        print(response)
    
    asyncio.run(main())

Installation

pip install fastadk

For development, we recommend using UV for faster package management:

# Install uv
pip install uv

# Install FastADK with uv
uv pip install fastadk

# Run examples with uv
uv run -m examples.basic.weather_agent

Workflow Examples

Context Management with Memory

from fastadk import Agent, BaseAgent
from fastadk.memory import VectorMemoryBackend
from fastadk.core.context_policy import SummarizeOlderPolicy

@Agent(model="gemini-1.5-pro")
class MemoryAgent(BaseAgent):
    def __init__(self):
        super().__init__()
        # Set up vector-based memory
        self.memory = VectorMemoryBackend()
        # Summarize older messages when context gets too large
        self.context_policy = SummarizeOlderPolicy(
            threshold_tokens=3000,
            summarizer=self.model
        )

Parallel Tool Execution with Workflow

from fastadk.core.workflow import Workflow, step

@step
async def fetch_weather(city: str):
    # Implementation details...
    return {"city": city, "weather": "sunny"}

@step
async def fetch_news(city: str):
    # Implementation details...
    return {"city": city, "headlines": ["Local event", "Sports update"]}

async def get_city_info(city: str):
    # Run steps in parallel
    results = await Workflow.parallel(
        fetch_weather(city),
        fetch_news(city)
    ).execute()
    
    return {
        "city": city,
        "weather": results[0]["weather"],
        "news": results[1]["headlines"]
    }

Token Usage and Cost Tracking

from fastadk import Agent, BaseAgent
from fastadk.tokens import TokenBudget

@Agent(model="gpt-4")
class BudgetAwareAgent(BaseAgent):
    def __init__(self):
        super().__init__()
        # Set budget constraints
        self.token_budget = TokenBudget(
            max_tokens_per_session=100000,
            max_cost_per_session=5.0,  # $5.00 USD
            on_exceed="warn"  # Other options: "error", "log"
        )
    
    async def run(self, prompt: str):
        response = await super().run(prompt)
        # Check usage after run
        usage = self.last_run_token_usage
        print(f"Used {usage.total_tokens} tokens (${usage.estimated_cost:.4f})")
        return response

HTTP API with FastAPI

# api.py
from fastapi import FastAPI
from fastadk import Agent, BaseAgent, tool, registry

@Agent(model="gemini-1.5-pro")
class CalculatorAgent(BaseAgent):
    @tool
    def add(self, a: float, b: float) -> float:
        """Add two numbers."""
        return a + b
    
    @tool
    def multiply(self, a: float, b: float) -> float:
        """Multiply two numbers."""
        return a * b

# Register the agent and create FastAPI app
registry.register(CalculatorAgent)
app = FastAPI()

# Include auto-generated FastADK router
from fastadk.api.router import get_router
app.include_router(get_router(), prefix="/api/agents")

# Run with: uv run -m uvicorn api:app --reload

Discord or Slack Integration

from fastadk import Agent, BaseAgent, tool
from fastadk.adapters.discord import DiscordAdapter

@Agent(model="gemini-1.5-pro")
class HelpfulAssistant(BaseAgent):
    @tool
    def search_knowledge_base(self, query: str) -> str:
        """Search internal knowledge base for information."""
        # Implementation details...
        return "Here's what I found about your question..."

# Connect to Discord
adapter = DiscordAdapter(
    agent=HelpfulAssistant(),
    bot_token="YOUR_DISCORD_BOT_TOKEN",
    channels=["general", "help-desk"],
    prefix="!assist"
)

# Start the bot
if __name__ == "__main__":
    import asyncio
    asyncio.run(adapter.start())

Advanced Features

Custom Context Policies

from fastadk.core.context_policy import ContextPolicy
from typing import List, Any

class CustomContextPolicy(ContextPolicy):
    """Custom policy that prioritizes questions and important information."""
    
    def __init__(self, max_tokens: int = 3000):
        self.max_tokens = max_tokens
        self.important_keywords = ["urgent", "critical", "important"]
    
    async def apply(self, history: List[Any]) -> List[Any]:
        # Implementation that keeps important messages and removes less relevant ones
        # when context size exceeds max_tokens
        # ...
        return filtered_history

Pluggable Provider System

from fastadk.providers.base import ModelProviderABC
from fastadk import registry

class MyCustomProvider(ModelProviderABC):
    """Custom LLM provider implementation."""
    
    def __init__(self, api_key: str, model: str):
        self.api_key = api_key
        self.model = model
        # Other initialization...
    
    async def generate(self, prompt: str, **kwargs):
        # Implementation for text generation
        # ...
        return response
    
    async def stream(self, prompt: str, **kwargs):
        # Implementation for streaming response
        # ...
        yield chunk

# Register custom provider
registry.register_provider("my_provider", MyCustomProvider)

# Use custom provider
@Agent(model="my-model", provider="my_provider")
class CustomAgent(BaseAgent):
    # Agent implementation...

Telemetry and Observability

from fastadk.observability import configure_logging, configure_metrics

# Configure structured JSON logging
configure_logging(
    level="INFO",
    format="json",
    redact_sensitive=True,
    log_file="agent.log"
)

# Configure Prometheus metrics
configure_metrics(
    enable=True,
    port=9090,
    labels={"environment": "production", "service": "agent-api"}
)

# Track custom metrics
from fastadk.observability.metrics import counter, gauge, histogram

# Increment counter when agent is used
counter("agent_calls_total", "Total number of agent calls").inc()

# Record latency of operations
with histogram("agent_latency_seconds", "Latency of agent operations").time():
    # Operation to measure
    result = await agent.run(prompt)

Configuration

FastADK supports configuration through YAML files and environment variables:

# fastadk.yaml
environment: production

model:
  provider: gemini
  model_name: gemini-1.5-pro
  api_key_env_var: GEMINI_API_KEY
  timeout_seconds: 30
  retry_attempts: 3

memory:
  backend_type: redis
  connection_string: ${REDIS_URL}
  ttl_seconds: 3600
  namespace: "my-agent"

context:
  policy: "summarize_older"
  max_tokens: 8000
  window_size: 10

observability:
  log_level: info
  metrics_enabled: true
  tracing_enabled: true
  redact_patterns:
    - "api_key=([a-zA-Z0-9-_]+)"
    - "password=([^&]+)"

Testing

FastADK provides comprehensive testing tools:

from fastadk.testing import AgentTest, test_scenario, MockModel

class TestWeatherAgent(AgentTest):
    agent = WeatherAgent()
    
    def setup_method(self):
        # Replace real model with mock for testing
        self.agent.model = MockModel(responses=[
            "The weather in London is currently sunny with a temperature of 22°C."
        ])
    
    @test_scenario("basic_weather_query")
    async def test_basic_weather_query(self):
        response = await self.agent.run("What's the weather in London?")
        
        # Assertions
        assert "sunny" in response.lower()
        assert "22°c" in response.lower()
        assert self.agent.tools_used == ["get_weather"]
        assert self.agent.total_tokens < 1000

CLI Commands

FastADK includes a powerful CLI for development and testing:

# Start interactive REPL with an agent
fastadk repl agent_file.py

# Validate configuration
fastadk config validate

# Initialize a new agent project
fastadk init my-new-agent

# Run an agent with a prompt
fastadk run agent_file.py "What's the weather in London?"

# Start development server with hot reload
fastadk serve agent_api.py --reload

Documentation

License

FastADK is released under the MIT License.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fastadk-0.2.0.tar.gz (313.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fastadk-0.2.0-py3-none-any.whl (150.5 kB view details)

Uploaded Python 3

File details

Details for the file fastadk-0.2.0.tar.gz.

File metadata

  • Download URL: fastadk-0.2.0.tar.gz
  • Upload date:
  • Size: 313.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.8

File hashes

Hashes for fastadk-0.2.0.tar.gz
Algorithm Hash digest
SHA256 af2a84298eb22259eeb5571e3082a81212983eeec6ff855a010ec60c01869163
MD5 047c374d783093adb79347b43460b1c7
BLAKE2b-256 b16de4cbac209d7445555dc9bc02abaa991d8206a08985bb4c4a44bc4f5b36c4

See more details on using hashes here.

File details

Details for the file fastadk-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: fastadk-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 150.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.8

File hashes

Hashes for fastadk-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 56359e1aaca4d0faafc480f50dcca495037b4aafe02b2c93cc726965637c2474
MD5 894ecc9e4d49d30835d9cf870f1d6865
BLAKE2b-256 1d75410c745be2e58d52c8b819f322dcb61264ff3e3a7bf1b4e21f250fd81492

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page