A progressive tutorial demonstrating AI agent patterns in C# — from basic chat to multi-agent orchestration, RAG, observability, and a PostgreSQL DBA agent.
Each numbered project builds on the previous one. All .cs files are self-contained top-level programs using #:package directives — no .csproj or .sln files needed.
| # | Project | Description |
|---|---|---|
| 01 | ConsoleChat | Basic streaming console chat with OpenAI |
| 02 | WebChat | Stateless web API chat with tool support (ASP.NET Minimal API) |
| 03 | AgentLoop | Autonomous agent loop: call model → execute tools → feed results → repeat |
| 04 | HumanInTheLoop | Agent loop gated by user approval before tool execution |
| 05 | WebHumanInTheLoop | Web agent with dual execution (JS + C# Roslyn), skill persistence, approval UI |
| 06 | AgentToAgent | Multi-agent orchestration via A2A protocol (JSON-RPC 2.0) with SSE streaming |
| 07 | RagObservability | RAG with Qdrant vector DB + full OpenTelemetry instrumentation + Grafana |
| 08 | A2UI | Agent-to-UI dashboard: agent calls tools, frontend renders live widgets |
| 09 | PgDba | PostgreSQL DBA agent with monitoring, diagnostics, and approval-gated operations |
- .NET 9+
- Docker & Docker Compose
OPENAI_API_KEYenvironment variable
export OPENAI_API_KEY=sk-...
# Console chat
dotnet run --file 01_ConsoleChat/Chat.cs
# Web projects (open http://localhost:5000)
dotnet run --file 02_WebChat/Api.cs./pipeline.sh # Start PostgreSQL on port 5488, load ~15GB pgbench data
./pipeline.sh small # ~7GB variant
./teardown.sh # Stop and clean upcd 07_RagObservability && docker compose up -d && cd ..
dotnet run --file 07_RagObservability/Api.cs
# App: http://localhost:5000 | Grafana: http://localhost:3000 | Qdrant: http://localhost:6333cd 08_A2UI/app && npm install && npm run dev # http://localhost:5173
cd 09_PgDba/app && npm install && npm run dev # http://localhost:5173The problems/ directory contains scripts that simulate real PostgreSQL performance issues:
| Script | Issue |
|---|---|
01-slow-queries.sh |
Sequential scans, high query duration |
02-lock-contention.sh |
Row-level locks, waiter pileup |
03-connection-exhaustion.sh |
Max connections reached |
04-table-bloat.sh |
Dead tuples accumulation |
05-cache-miss.sh |
Low buffer cache hit ratio |
06-temp-files.sh |
Disk spillover, high I/O |
07-xid-wraparound.sh |
Transaction ID approaching limit |
08-idle-in-transaction.sh |
Long-held idle transactions |
09-checkpoint-spikes.sh |
Heavy checkpoint load |
10-unused-indexes.sh |
Indexes with zero scans |
source problems/common.sh
bash problems/01-slow-queries.sh
bash problems/monitor.sh # live dashboard
bash problems/reset.sh # clean up[Description("Fetches content from a URL")]
static async Task<string> Curl([Description("target URL")] string url)
=> await new HttpClient().GetStringAsync(url);
var tools = new[] { AIFunctionFactory.Create(Curl) };while (true) {
var response = await chatClient.GetResponseAsync(messages, new ChatOptions { Tools = tools });
messages.AddRange(response.Messages);
var toolCalls = response.Messages
.SelectMany(m => m.Contents.OfType<FunctionCallContent>()).ToList();
if (toolCalls.Count == 0) break;
foreach (var call in toolCalls) {
var tool = tools.First(t => t.Name == call.Name);
var result = await tool.InvokeAsync(new AIFunctionArguments(call.Arguments!));
messages.Add(new(ChatRole.Tool, [new FunctionResultContent(call.CallId, result)]));
}
}- Microsoft.Extensions.AI — Chat client abstraction
- Microsoft.Agents.AI.OpenAI — Agent framework with approval gates
- Microsoft.Agents.AI.Hosting.A2A — Agent-to-Agent protocol
- OpenAI SDK v2.9.1 — Direct API client
- Qdrant.Client — Vector database for RAG
- Npgsql — PostgreSQL driver
- OpenTelemetry — Traces, metrics, instrumentation
- Microsoft.CodeAnalysis.CSharp.Scripting — Roslyn eval (project 05)
- CopilotKit — React dashboard widgets (projects 08, 09)
| Variable | Required | Used by |
|---|---|---|
OPENAI_API_KEY |
Yes | All projects |
GITHUB_TOKEN |
No | 07 (GitHub repo indexing) |
PG_CONNECTION |
No | 09 (default: localhost:5488) |
- 01–02 — Chat basics + tool calling
- 03–04 — Agent loops + human approval
- 05 — Skill persistence + dual execution
- 06 — Multi-agent orchestration
- 07 — RAG + observability
- 08–09 — Dashboard rendering + domain specialization
MIT