You now have a fully functional Agent Development Kit in C# following A.D.D V3 five-layer architecture, 100% compatible with the Abstract Driven spec.
E:\repos\adk-csharp/
├── src/
│ ├── NTG.Adk.Boundary/ # Layer 1: DTOs, Events ✅
│ ├── NTG.Adk.CoreAbstractions/ # Layer 2: Ports (IAgent, ILlm, ITool) ✅
│ ├── NTG.Adk.Implementations/ # Layer 3: Adapters (MockLlm, Sessions) ✅
│ ├── NTG.Adk.Operators/ # Layer 4: Business Logic (BaseAgent, SimpleLlmAgent) ✅
│ └── NTG.Adk.Bootstrap/ # Layer 5: Composition (Runner) ✅
├── samples/
│ └── HelloWorldAgent/ # Working demo ✅
├── README.md # Full documentation ✅
├── ARCHITECTURE.md # A.D.D V3 detailed guide ✅
└── GETTING_STARTED.md # This file ✅
cd E:\repos\adk-csharp\samples\HelloWorldAgent
dotnet runOutput:
=== NTG.Adk Hello World Agent ===
A.D.D V3 Five-Layer Architecture Demo
User: Hello, how are you?
Agent Response:
Mock response to: Hello, how are you?
=== Architecture Layers ===
✅ Boundary: Event DTOs
✅ CoreAbstractions: IAgent, ILlm ports
✅ Implementations: MockLlm adapter
✅ Operators: SimpleLlmAgent orchestrator
✅ Bootstrap: Runner composition root
using NTG.Adk.Bootstrap;
using NTG.Adk.Implementations.Models;
using NTG.Adk.Operators.Agents;
// Create LLM adapter (Layer 3: Implementations)
var llm = new MockLlm();
// Create agent orchestrator (Layer 4: Operators)
var agent = new SimpleLlmAgent(llm)
{
Name = "MyAgent",
Instruction = "You are a helpful assistant."
};
// Create runner (Layer 5: Bootstrap)
var runner = new Runner(agent);
// Execute
var response = await runner.RunAsync("Hello!");
Console.WriteLine(response);Layer 1: Boundary (NTG.Adk.Boundary)
- Pure DTOs:
Event,Content,Part,FunctionCall - No dependencies
- Serializable across boundaries
Layer 2: CoreAbstractions (NTG.Adk.CoreAbstractions)
- Ports:
IAgent,ILlm,ITool,ISession - No dependencies (pure interfaces)
- Enables Dependency Inversion Principle
Layer 3: Implementations (NTG.Adk.Implementations)
- Adapters:
MockLlm,InMemorySession,EventAdapter - Depends on: CoreAbstractions + Boundary
- Technology-specific implementations
Layer 4: Operators (NTG.Adk.Operators)
- Business logic:
BaseAgent,SimpleLlmAgent - Depends on: CoreAbstractions + Boundary (+ Implementations for helpers)
- Orchestrates agent workflows
Layer 5: Bootstrap (NTG.Adk.Bootstrap)
- Composition root:
Runner - Depends on: All layers (for wiring only)
- DI setup and entry point
// Easy to swap MockLlm with real LLM:
// var llm = new GeminiLlm(apiKey); // Future: Real Google Gemini
// var llm = new OpenAILlm(apiKey); // Future: Real OpenAI
var agent = new SimpleLlmAgent(llm); // Same agent code!-
Real LLM Adapters (Layer 3: Implementations)
src/NTG.Adk.Implementations/Models/ ├── GeminiLlm.cs # Google Gemini adapter ├── OpenAILlm.cs # OpenAI adapter └── AzureOpenAILlm.cs # Azure OpenAI adapter -
LlmAgent (Full Version) (Layer 4: Operators)
src/NTG.Adk.Operators/Agents/ └── LlmAgent.cs # Full-featured agent with tools, sub-agents -
Workflow Agents (Layer 4: Operators)
src/NTG.Adk.Operators/Workflows/ ├── SequentialAgent.cs # Execute sub-agents sequentially ├── ParallelAgent.cs # Execute sub-agents in parallel └── LoopAgent.cs # Loop execution with max iterations -
Tool System (Layers 3 & 4)
src/NTG.Adk.Implementations/Tools/ ├── FunctionTool.cs # Wrap C# functions as tools ├── GoogleSearchTool.cs # Google Search implementation └── HttpTool.cs # HTTP client tool
-
Flow System (Layer 4: Operators)
AutoFlow: Multi-agent auto-delegationSingleFlow: Simple LLM call flow- Streaming support
-
Memory & State (Layer 3: Implementations)
- Vector store integration
- Persistent sessions
- Context caching
-
A2A Protocol (Layer 3: Implementations)
- Agent-to-agent communication
- gRPC support
-
ASP.NET Core Integration (Layer 5: Bootstrap)
- Minimal APIs for agents
- WebSocket streaming
- Middleware
-
Testing
tests/ ├── NTG.Adk.Operators.Tests/ # Unit tests (mock ports) └── NTG.Adk.Integration.Tests/ # Integration tests (real adapters) -
NuGet Packages
NTG.Adk(meta-package)NTG.Adk.Core(Boundary + CoreAbstractions)NTG.Adk.Gemini(Gemini LLM adapter)
-
Create adapter in Implementations layer:
// src/NTG.Adk.Implementations/Models/GeminiLlm.cs public class GeminiLlm : ILlm { public async Task<ILlmResponse> GenerateAsync(ILlmRequest request, CancellationToken ct) { // Call Google Gemini API // Return ILlmResponse } }
-
Register in Bootstrap:
services.AddSingleton<ILlm, GeminiLlm>();
-
Use in Operators:
var agent = new SimpleLlmAgent(llm); // ILlm port, not concrete!
✅ Operators call Ports, NEVER Implementations
// GOOD (Operator using Port)
public class SimpleLlmAgent : BaseAgent
{
private readonly ILlm _llm; // ✅ Port dependency
}
// BAD (Operator depending on Implementation)
public class SimpleLlmAgent : BaseAgent
{
private readonly GeminiLlm _llm; // ❌ BREAKS DIP!
}✅ Dependencies flow correctly:
- Bootstrap → All (composition only)
- Operators → CoreAbstractions + Boundary
- Implementations → CoreAbstractions + Boundary
- CoreAbstractions → NONE
- Boundary → NONE
- README.md: Project overview and quick start
- ARCHITECTURE.md: Deep dive into A.D.D V3 implementation
- Python ADK: Original reference
- A.D.D V3 Spec: Architecture pattern
To add new features:
-
Determine the layer:
- DTO/Event? → Boundary
- Interface? → CoreAbstractions
- Technology implementation? → Implementations
- Business logic? → Operators
- DI wiring? → Bootstrap
-
Follow dependency rules:
- Check
ARCHITECTURE.mdfor allowed dependencies - Never make Operators depend on Implementations directly
- Keep CoreAbstractions and Boundary dependency-free
- Check
-
Test with ports:
- Unit tests mock ports (ILlm, IAgent)
- Integration tests use real implementations
- ✅ Run the sample (
HelloWorldAgent) - 📖 Read
ARCHITECTURE.mdto understand A.D.D V3 - 🔧 Add a new tool (follow pattern in Implementations/Tools)
- 🤖 Implement real LLM adapter (GeminiLlm or OpenAILlm)
- 🔀 Create SequentialAgent (orchestrate multiple agents)
- 🚀 Build your own agent system!
You now have a production-grade C# ADK following enterprise architecture patterns! 🏗️✨
Next: Start with Phase 1, Step 1 - implement GeminiLlm.cs adapter.