# ADK Project Overview and Architecture

Google Agent Development Kit (ADK) for Python

## Core Philosophy & Architecture

- Code-First: Everything is defined in Python code for versioning, testing, and IDE support. Avoid GUI-based logic.

- Modularity & Composition: We build complex multi-agent systems by composing multiple, smaller, specialized agents.

- Deployment-Agnostic: The agent's core logic is separate from its deployment environment. The same agent.py can be run locally for testing, served via an API, or deployed to the cloud.

## Foundational Abstractions (Our Vocabulary)

- Agent: The blueprint. It defines an agent's identity, instructions, and tools. It's a declarative configuration object.

- Tool: A capability. A Python function an agent can call to interact with the world (e.g., search, API call).

- Runner: The engine. It orchestrates the "Reason-Act" loop, manages LLM calls, and executes tools.

- Session: The conversation state. It holds the history for a single, continuous dialogue.

- Memory: Long-term recall across different sessions.

- Artifact Service: Manages non-textual data like files.

## Canonical Project Structure

Adhere to this structure for compatibility with ADK tooling.

```
my_adk_project/
└── src/
    └── my_app/
        ├── agents/
        │   ├── my_agent/
        │   │   ├── __init__.py   # Must contain: from . import agent \
        │   │   └── agent.py      # Must contain: root_agent = Agent(...) \
        │   └── another_agent/
        │       ├── __init__.py
        │       └── agent.py\
```

agent.py: Must define the agent and assign it to a variable named root_agent. This is how ADK's tools find it.

`__init__.py`: In each agent directory, it must contain `from . import agent` to make the agent discoverable.

### Nested Agent Directories (Dev Mode / `adk web`)

In the local development server (`adk web` / `dev_server`), ADK supports deeply nested agent directories (e.g., sub-packages or structured folders).

- **Recursive Discovery**: The loader recursively walks directories to discover all valid agent applications containing an `agent.py`, `root_agent.yaml`, or `__init__.py` file.
- **Dot Naming Convention**: Nested agents are represented in the system and referenced inside the Web UI using a standard dot-separated namespace notation (e.g., `agent_samples.empty_agent` or `workflow_samples.fan_out_fan_in`).
- **Isolation**: Production environments (`adk api_server`) only support flat single-level agent directories for maximum security and isolation.

## Local Development & Debugging

Interactive UI (adk web): This is our primary debugging tool. It's a decoupled system:

Backend: A FastAPI server started with adk api_server.

Frontend: An Angular app that connects to the backend.

Use the "Events" tab to inspect the full execution trace (prompts, tool calls, responses).

CLI (adk run): For quick, stateless functional checks in the terminal.

Programmatic (pytest): For writing automated unit and integration tests.

## The API Layer (FastAPI)

We expose agents as production APIs using FastAPI.

- get_fast_api_app: This is the key helper function from google.adk.cli.fast_api that creates a FastAPI app from our agent directory.

- Standard Endpoints: The generated app includes standard routes like /list-apps and /run_sse for streaming responses. The wire format is camelCase.

- Custom Endpoints: We can add our own routes (e.g., /health) to the app object returned by the helper.

```Python

from google.adk.cli.fast_api import get_fast_api_app
app = get_fast_api_app(agent_dir="./agents")

@app.get("/health")
async def health_check():
    return {"status": "ok"}
```

### Default Application Resolution (`ADK_DEFAULT_APP_NAME`)

By default, the ADK API server expects an explicit application context in all requests (e.g., via the `/apps/{app_name}/...` path or in the payload body).

However, if the environment variable `ADK_DEFAULT_APP_NAME` is set, or if the server is running in **single agent mode** (when pointing directly to a directory containing an agent instead of a directory of agents), the server will automatically resolve and fall back to that agent as the default application whenever a request lacks an explicit app name. In single agent mode, the local agent takes precedence over the `ADK_DEFAULT_APP_NAME` environment variable.

- **URL Path-Rewriting (Production Endpoints)**: Requests to production endpoints that omit the `/apps/{app_name}` prefix (such as `/users/{user_id}/sessions` or `/app-info`) are automatically rewritten by an internal ASGI middleware to target the default application. (Note: `/dev` and `/builder` endpoints are excluded from rewriting).
- **Agent Execution & Streaming**: Requests to `/run`, `/run_sse`, or `/run_live` that omit the `app_name` parameter in their payload body or query string will automatically resolve to the default application.

## Deployment to Production

The adk cli provides the "adk deploy" command to deploy to Google Vertex Agent Engine, Google CloudRun, Google GKE.

## Testing & Evaluation Strategy

Testing is layered, like a pyramid.

### Layer 1: Unit Tests (Base)

What: Test individual Tool functions in isolation.

How: Use pytest in tests/test_tools.py. Verify deterministic logic.

### Layer 2: Integration Tests (Middle)

What: Test the agent's internal logic and interaction with tools.

How: Use pytest in tests/test_agent.py, often with mocked LLMs or services.

### Layer 3: Evaluation Tests (Top)

What: Assess end-to-end performance with a live LLM. This is about quality, not just pass/fail.

How: Use the ADK Evaluation Framework.

Test Cases: Create JSON files with input and a reference (expected tool calls and final response).

Metrics: tool_trajectory_avg_score (does it use tools correctly?) and response_match_score (is the final answer good?).

Run via: adk web (UI), pytest (for CI/CD), or adk eval (CLI).
