Dieses Repo ist ein kleiner, lokaler Spielplatz für das Microsoft Agent Framework. Es ist aus einer Twitch-Stream-Mitschrift entstanden und wurde danach in eine erweiterbare Struktur überführt.
Der Playground nutzt standardmäßig LM Studio über einen OpenAI-kompatiblen lokalen Endpoint:
http://localhost:1234/v1
Das Projekt soll Agent-Konzepte sichtbar und nachvollziehbar machen:
- Wie sieht ein Agent-Loop mit Text, Tool-Call und Tool-Ergebnis aus?
- Wie funktionieren sichere Datei-Tools als Dry-Run?
- Wie arbeitet ein Agent mit strukturiertem JSON?
- Wie nutzt ein Agent einen anderen Agenten als Tool?
- Wie sieht ein echter ApprovalRequired-Tool-Flow aus?
- Wie kann lokale Repo-Suche als einfacher RAG-Kontext dienen?
- Wie kann derselbe Playground in Console und Web-UI ausprobiert werden?
- .NET SDK mit
net10.0-Unterstützung - LM Studio oder ein anderer OpenAI-kompatibler Server auf
http://localhost:1234/v1 - Ein geladenes Modell, z. B.
qwen/qwen3.5-9b
Auf diesem Rechner wurde verifiziert:
/opt/homebrew/bin/dotnet --version
# 10.0.301Hinweis: Der Nutzer arbeitet mit fish. In manchen Codex-Shells fehlt Homebrew im PATH; dann explizit /opt/homebrew/bin/dotnet verwenden.
Dependencies wiederherstellen:
/opt/homebrew/bin/dotnet restoreBuild:
/opt/homebrew/bin/dotnet buildConsole-Playground:
/opt/homebrew/bin/dotnet runWeb-Playground:
/opt/homebrew/bin/dotnet run -- --web --urls http://localhost:5062Danach im Browser öffnen:
http://localhost:5062
Das Console-Menü bietet aktuell sieben Demos:
-
Agent-Loop sichtbar machen
Zeigt Textausgabe, Tool-Aufruf, Tool-Ergebnis und Tool-Iterationszähler. -
Mini-Datei-Buddy als Dry-Run
Listet Dateien, liest kleine Textdateien und prüft Umbenennungen ohne echte Dateiänderung. -
Zwei-Agenten-Workflow
Führt Scanner- und Reviewer-Agent sequenziell aus. -
Structured Output Datei-Buddy
Erzwingt eine maschinenlesbare JSON-Antwort alsFileBuddyPlan. -
Agent-as-Tool Workflow
Nutzt einen Spezialagenten als Function Tool eines Orchestrator-Agenten. -
ApprovalRequired Tool Flow
Wickelt ein Tool mitApprovalRequiredAIFunctionein und führt danach Approve/Reject aus. -
Lokales Repo-RAG
Durchsucht lokale Repo-Dateien und stellt Treffer überTextSearchProviderals Kontext bereit.
Wichtige Seiten:
/und/dashboard— Blazor/Radzen-Dashboard mit Metriken, KI-Erreichbarkeit, Demo-Aktionen, Approval-Grid und Timeline/chat— persistenter Chat mit OpenAI-kompatiblem Endpoint oder Ollama/terminal— terminalartige Simulation des Console-Agent-Loops mit Session-Memory/advanced— Structured Output, ApprovalRequired und lokales Repo-RAG/approvals— Human-in-the-loop Approval-Store/webhooks— Webhook-Spielplatz/memories— lokal gespeicherte Chat-Erinnerungen anzeigen und löschen/logs— In-Memory-Log anzeigen, filtern und löschen/settings—appsettings.jsonbearbeiten; Neustart nötig, damit Singleton-Services alle Änderungen übernehmen
Wichtige API-Endpunkte:
GET /healthPOST /demo/loopGET /demo/loop/stream?message=...&sessionId=...POST /demo/workflowPOST /demo/filebuddy/structuredPOST /demo/approval-requiredPOST /demo/ragPOST /api/approvalsGET /api/approvalsPOST /webhooks/file-event
- LM Studio starten.
- Im Bereich
Developer > Local Serverden Server aktivieren. - Ein Modell laden, z. B.
qwen/qwen3.5-9b. - Prüfen, ob der Server unter
http://localhost:1234/v1erreichbar ist.
Optional kann Ollama parallel laufen. Der Standardprovider für den Chat wird in appsettings.json oder über /settings gesetzt.
- Web-App starten:
/opt/homebrew/bin/dotnet run -- --web --urls http://localhost:5062http://localhost:5062öffnen.- Dashboard prüfen: OpenAI-kompatibel sollte
Erreichbaranzeigen, wenn LM Studio läuft. /chatöffnen, einen neuen Chat anlegen und eine kurze Nachricht senden./terminalverwenden, um Tool-Aufrufe und Agent-Loop wie in der Console zu sehen./advancedverwenden, um Structured Output, ApprovalRequired und lokales RAG auszuprobieren./logsöffnen, wenn etwas unerwartet wirkt.
Lokale Modelle können langsam sein. Der Chat zeigt deshalb während der Anfrage KI arbeitet...; eine Antwort kann je nach Modell mehrere Sekunden oder länger dauern.
Die Seite /settings schreibt Werte nach appsettings.json. Da viele Services als Singletons registriert sind, sollte die Web-App nach Änderungen neu gestartet werden.
Wichtige Felder:
Endpoint,Model,ApiKeyfür LM Studio oder andere OpenAI-kompatible ServerOllama.EndpointundOllama.Modelfür OllamaDefaultProviderfür den Chat- Tool- und Trace-Limits
- JSON-Dateipfade für Approvals, Chats und Memories
Im Chat erzeugen Formulierungen wie diese automatisch eine Memory:
Merk dir: Ich nutze fish shell.
Die gespeicherten Memories erscheinen unter /memories und werden bei späteren Chat-Anfragen als zusätzlicher Systemkontext mitgegeben.
App/ Console-Menü und Demo-Auswahl
Agent/ kleine Agent-Demo-Klassen, Prompts, Tools und Trace-Ausgabe
Components/ Blazor/Radzen-Seiten, Layout und Shared-UI-Bausteine
Configuration/ appsettings.json Mapping und technische Limits
Features/ fachliche Bausteine für AI-Health, Chat, Memories, Approvals, FileBuddy, LocalRag und Terminal
Infrastructure/ OpenAI-kompatible Client-Erzeugung
Logging/ eigener Console-/Web-Logger mit In-Memory-Journal
Services/ PromptLoader für Markdown-Instructions
Utilities/ kleine Schutz- und Erkennungsfunktionen
Web/ Hosting, Minimal API, Endpoints und Web-Services
wwwroot/ Dashboard-CSS und statische Assets
Backup/ gesicherte Originaldateien aus dem Stream-Kontext
Agent/Demos/AgentDemos.cs ist bewusst nur eine Fassade. Die konkrete Logik liegt in kleineren Klassen wie AgentLoopDemo, FileBuddyDemo, WorkflowDemos, ApprovalDemo und LocalRagDemo.
Web/Services/WebAgentRunner.cs ist ebenfalls nur eine Fassade. Loop/SSE, Web-Workflow und Advanced-Demos sind in WebLoopRunner, WebWorkflowRunner und WebAdvancedDemoRunner getrennt.
Wiederverwendete UI-Elemente wie Seitenkopf, Demo-Karte, Metric-Karte und Playground-Timeline liegen unter Components/Shared/.
Zentrale Konfiguration steht in appsettings.json:
{
"AgentPlayground": {
"Endpoint": "http://localhost:1234/v1",
"Model": "qwen/qwen3.5-9b",
"ApiKey": "lm-studio",
"MinimumLogLevel": "Information",
"FunctionInvocation": {
"MaximumIterationsPerRequest": 8,
"MaximumConsecutiveErrorsPerRequest": 2,
"TerminateOnUnknownCalls": true
},
"ToolLimits": {
"MaximumWorkspaceFiles": 80,
"MaximumTextFileCharacters": 4000
},
"Trace": {
"MaximumPreviewCharacters": 500
},
"ApprovalStore": {
"FilePath": "Data/approvals.json"
},
"Ollama": {
"Endpoint": "http://localhost:11434",
"Model": "llama3.2"
},
"ChatStore": {
"FilePath": "Data/chats.json",
"DefaultProvider": "OpenAiCompatible"
},
"MemoryStore": {
"FilePath": "Data/memories.json"
}
}
}Umgebungsvariablen können mit dem Prefix AGENT_PLAYGROUND__ gesetzt werden.
Beispiel:
AGENT_PLAYGROUND__AgentPlayground__MinimumLogLevel=Trace /opt/homebrew/bin/dotnet runDie Blazor-Seite /settings kann die Werte in appsettings.json ändern. Environment-Overrides und appsettings.Development.json können weiterhin Vorrang haben; nach dem Speichern ist ein Neustart der Web-App sinnvoll.
Agent-Instructions liegen unter Agent/Prompts/ als Markdown-Dateien. Dadurch kann das Verhalten der Agenten angepasst werden, ohne C#-Code zu ändern.
Beispiele:
Agent/Prompts/LoopInspector.mdAgent/Prompts/FileBuddy.mdAgent/Prompts/StructuredFileBuddy.mdAgent/Prompts/LocalRepoRagAgent.md
Wenn eine Prompt-Datei fehlt oder nicht lesbar ist, verwendet der Code einen kleinen Fallback-Prompt.
IPlaygroundLogger schreibt nach Leveln Trace, Debug, Information, Warning und Error. ConsolePlaygroundLogger gibt die Einträge farbig in der Console aus und hält zusätzlich die letzten Log-Zeilen im Speicher. Die Blazor-Seite /logs zeigt diese Einträge an und kann das In-Memory-Log löschen.
Chats werden lokal in Data/chats.json gespeichert. Der Chat kann den OpenAI-kompatiblen Endpoint aus AgentPlayground:Endpoint oder Ollama aus AgentPlayground:Ollama nutzen. Formulierungen wie Merk dir: Ich nutze fish shell speichern automatisch eine Memory in Data/memories.json; die Seite /memories zeigt diese Einträge an.
Lokale Modelle und lokale OpenAI-kompatible Server setzen nicht jedes Feature gleich zuverlässig um. Bei LM Studio/Qwen kann ResponseFormat = JsonSchema leeren oder nicht exakt JSON-kompatiblen Text liefern. Der Structured FileBuddy fängt das ab und gibt dann einen gültigen Fallback-FileBuddyPlan mit Hinweis aus, statt eine JsonException bis in die UI durchzureichen.
Die Datei-Tools sind bewusst defensiv:
- Pfade dürfen den Workspace nicht verlassen.
bin/,obj/,.gitundBackup/werden ignoriert.- Dateiänderungen laufen als Dry-Run.
- ApprovalRequired demonstriert Freigabe, führt aber weiterhin keine echte Umbenennung aus.
- Approval-Anfragen werden mit
System.Text.JsoninData/approvals.jsongespeichert.
Das ist Absicht: Der Playground soll Agent-Verhalten zeigen, ohne unkontrolliert Dateien zu verändern.
- Structured Output mit Reparaturparser oder Modell-Kompatibilitätsmodus erweitern.
- Chat-Antworten per Streaming anzeigen, statt auf die komplette Antwort zu warten.
- RAG-Suche von Token-Zählung auf Embeddings/Vektorsuche erweitern.
- Approval-Store und Logs optional persistent machen.
- MCP-Server als weiteres lokales Experiment ergänzen.
- Dashboard-Metriken um echte Laufzeit- und Fehlerzähler erweitern.
- echte Dateioperationen nur mit ApprovalRequired und klaren Pfadgrenzen ergänzen.