Agent-Harnesses

Ein Agent-Gerüst ist das Gerüst, das ein Sprachmodell in einen Agent verwandelt, der tatsächlich Aufgaben ausführen kann. Ein Modell allein kann nur Text generieren. Damit es Tools aufrufen, mehrstufige Aufgaben bearbeiten, sich merken kann, was es bereits getan hat, und so lange weiterarbeitet, bis die Aufgabe erledigt ist, benötigen Sie eine Runtime, die das Modell umgibt – und diese Runtime ist das Harness.

Ein Harness steuert den Agent: Er führt die Schleife aus, die das Modell aufruft und die vom Modell angeforderten Tools ausführt, verwaltet die Unterhaltung und den Kontext, damit das Modell innerhalb seiner Grenzen bleibt, wendet Genehmigungs- und Sicherheitsrichtlinien an, bevor Maßnahmen ergriffen werden, und sorgt dafür, dass der Agent kontinuierlich auf die Erledigung der Aufgabe hinarbeitet. Programmierassistenten und autonome Agenten basieren alle auf einer Art „Harness“ – es handelt sich dabei um den Motor, der das Modell umgibt.

Agent Framework stellt ein vorgefertigtes Grundgerüst bereit, sodass Sie dieses nicht selbst aufbauen müssen. Es handelt sich um einen meinungsvollen, akkubasierten Agent, der einen Chat-Client mit einer vollständigen agentischen Pipeline umschließt – Funktionsaufrufe, Kontextverwaltung und eine kuratierte Gruppe von Tools und Anbietern – abgestimmt auf langfristige, autonome Arbeit wie Forschung, Codierung, Datenanalyse und allgemeine Aufgabenautomatisierung.

Sie geben weiterhin Ihren eigenen Chatclient an und konfigurieren nur die Teile, die Sie ändern möchten. Alles andere verfügt über einen sinnvollen Standardwert, den Sie deaktivieren oder anpassen können.

Intern ist das Agent-Framework-Harness ein auf einem Chatclient basierender Agent (Agent in Python und ChatClientAgent in C#), dem eine Reihe von Agent-Framework-Funktionen hinzugefügt wurden. Alle diese Features sind auch als eigenständige Features im Agent Framework verfügbar.

Woraus besteht das Agent Framework-Gerüst?

Das Agent Framework Harness bündelt die folgenden Funktionen in einem einzigen Agenten. Jede ist standardmäßig aktiviert (sofern nicht als optional angegeben) und kann einzeln deaktiviert oder angepasst werden.

Fähigkeit Beschreibung
Funktionsaufruf Automatische Toolanrufschleife mit konfigurierbarem Iterationsgrenzwert.
Persistenz des Anrufverlaufs pro Dienst Der Chatverlauf wird nach jedem einzelnen Modellaufruf gespeichert, sodass eine Absturzwiederherstellung und eine Überprüfung während der Ausführung möglich sind.
Verdichtung Die Kontextfensterkomprimierung verhindert, dass lange Toolaufrufschleifen das Kontextfenster überlaufen. Aktiv, wenn ein Tokenbudget (oder eine benutzerdefinierte Strategie) bereitgestellt wird.
Todo-Bereitsteller Eine dauerhafte To-do-Liste, die der Agent verwendet, um mehrstufige Pläne zu verfolgen.
Anbieter für den Agentmodus Nachverfolgung des Planungs-/Ausführungs-/benutzerdefinierten Modus, mit der strukturiert wird, wie der Agent arbeitet.
Dateispeicheranbieter Dateibasierter Sitzungsspeicher für Notizen und Artefakte, die übergreifend beibehalten werden.
Dateizugriffsanbieter Dateitools mit Lese-/Schreibzugriff auf ein Arbeitsverzeichnis.
Toolgenehmigung „Nicht erneut fragen“-Regeln für die dauerhafte Genehmigung sowie eine heuristische automatische Genehmigung für eine sichere, unbeaufsichtigte Ausführung.
OpenTelemetry Integrierte Observability gemäß den semantischen Konventionen für generative KI.
Websuche Standardmäßig wurde ein gehostetes Websuchtool hinzugefügt.
Kompetenzanbieter(optional) Entdeckt und lädt Agent-Fähigkeiten schrittweise aus dem Dateisystem.
Hintergrund-Agents(optional) Delegieren Sie parallele Arbeit an Hintergrundunter-Agents.
Shell-Umgebung(optional) Ausführung von Shell-Befehlen sowie Prüfung von Betriebssystem, Shell und Arbeitsverzeichnis.
Schleifen(optional) Rufen Sie den Agent erneut auf, bis eine Abschlussbedingung erfüllt ist.

Erstellen eines Harness-Agents

Das Harness ist als die HarnessAgent-Klasse im Namespace Microsoft.Agents.AI verfügbar (dem Paket Microsoft.Agents.AI.Harness). Am einfachsten erstellen Sie eine aus jedem IChatClient mit der Erweiterungsmethode AsHarnessAgent:

using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;

// chatClient is any IChatClient implementation (Foundry, Azure OpenAI, OpenAI, Anthropic, ...).
AIAgent agent = chatClient.AsHarnessAgent();

AgentResponse response = await agent.RunAsync("Plan a weekend trip to Seattle.");
Console.WriteLine(response.Text);

Sie können den Agent auch direkt konstruieren:

AIAgent agent = new HarnessAgent(chatClient);

Stellen Sie ein HarnessAgentOptions bereit, das Anweisungen und Tools bereitstellt. Anweisungen auf Harness-Ebene (HarnessAgentOptions.HarnessInstructions) beschreiben allgemeine Betriebsrichtlinien, während aufgabenspezifische Anweisungen unter ChatOptions.Instructions stehen. HarnessAgent wird mit standardmäßigen Anweisungen auf Harness-Ebene (HarnessAgent.DefaultInstructions) geliefert, Sie können diese jedoch über HarnessAgentOptions.HarnessInstructions durch eigene überschreiben.

AIAgent agent = chatClient.AsHarnessAgent(new HarnessAgentOptions
{
    Name = "research-agent",
    ChatOptions = new ChatOptions
    {
        Instructions = "You are a research assistant focused on academic sources.",
        Tools = [AIFunctionFactory.Create(GetStockPrice)],
    },
});

Komprimierung aktivieren

Komprimierung verhindert, dass lange Toolaufrufschleifen das Kontextfenster überlaufen. Wenn der im Inference-Service gespeicherte Chatverlauf nicht verwendet wird, wird für den Standardwert InMemoryChatHistoryProvider ebenfalls derselbe Komprimierungsanbieter bereitgestellt, sodass auch der in der Sitzung gespeicherte Chatverlauf komprimiert wird. Stellen Sie sowohl eine maximale Kontextfenstergröße als auch eine maximale Ausgabegröße bereit, um die standardmäßige tokenbudget-fähige Strategie zu aktivieren:

AIAgent agent = chatClient.AsHarnessAgent(new HarnessAgentOptions
{
    MaxContextWindowTokens = 128_000,
    MaxOutputTokens = 16_384,
});

Um Ihre eigene Strategie zu verwenden, legen Sie fest HarnessAgentOptions.CompactionStrategy; um die Komprimierung zu deaktivieren, legen Sie fest DisableCompaction = true.

Anpassen und Deaktivieren von Features

Jede Standardfunktion verfügt über ein entsprechendes Deaktivierzeichen HarnessAgentOptions, sodass Sie die gewünschte Pipeline beibehalten und den Rest ablegen können:

AIAgent agent = chatClient.AsHarnessAgent(new HarnessAgentOptions
{
    HarnessInstructions = "Custom operating guidelines here.",
    DisableTodoProvider = true,      // No todo list
    DisableAgentModeProvider = true, // No plan/execute modes
    DisableWebSearch = true,         // No hosted web search tool
    DisableFileMemory = true,        // No file-based session memory
});

Weitere Flags sind : DisableFileAccess, DisableAgentSkillsProvider, , DisableToolAutoApprovalund DisableOpenTelemetry. Sie können außerdem über AIContextProviders eigene Kontextanbieter hinzufügen und den Skills-Anbieter über AgentSkillsSource auf benutzerdefinierte Speicherorte verweisen.

Wiederholen, bis abgeschlossen

Standardmäßig läuft die Testumgebung bei jedem Aufruf einmal. Geben Sie eine oder mehrere LoopEvaluator-Instanzen an, um den Agenten automatisch erneut aufzurufen, bis die Evaluatoren entscheiden, dass der Vorgang abgeschlossen ist (z. B. wenn eine Abschlussmarkierung erscheint, ein Prädikat erfüllt ist oder ein KI-Prüfer zustimmt):

AIAgent agent = chatClient.AsHarnessAgent(new HarnessAgentOptions
{
    LoopEvaluators = [new CompletionMarkerLoopEvaluator("DONE")],
});

Die Schleife wird als äußerster Agent-Dekorator angewendet, sodass jede Iteration einen vollständigen, unabhängig vom Tool validierten und nachverfolgbaren Agent-Lauf ausführt.

Shell- und Hintergrund-Agents

Um dem Agent das Ausführen von Shellbefehlen zu ermöglichen, übergeben Sie eine ShellExecutor. Dies fügt ein genehmigungspflichtiges Tool zur Ausführung von Shell-Befehlen sowie einen Provider hinzu, der Informationen zu Betriebssystem, Shell und Arbeitsverzeichnis in den Kontext einspeist:

using Microsoft.Agents.AI.Tools.Shell;

// A shell confined to a working directory. Commands require approval by default;
// the deny-list is a UX pre-filter, not a security boundary.
await using var shell = new LocalShellExecutor(new LocalShellExecutorOptions
{
    WorkingDirectory = workingDir,
    ConfineWorkingDirectory = true,
    Policy = new ShellPolicy(denyList: [@"\brm\s+-rf\b", @"\bsudo\b"]),
});

AIAgent agent = chatClient.AsHarnessAgent(new HarnessAgentOptions
{
    ShellExecutor = shell,
});

Um die parallele Delegierung zu aktivieren, übergeben Sie eine Gruppe von Hintergrund-Agenten. Der Agent kann Unteraufgaben für die gleichzeitige Ausführung aushändigen:

AIAgent agent = chatClient.AsHarnessAgent(new HarnessAgentOptions
{
    BackgroundAgents = [webSearchAgent, codeAgent],
});

Erstellen eines Harness-Agents

Das Harness ist als die Factory-Funktion create_harness_agent verfügbar, die aus einem Chat-Client ein vollständig konfiguriertes Agent erstellt. Das einfachste Formular erfordert nur einen Client:

from agent_framework import create_harness_agent
from agent_framework.openai import OpenAIChatClient

agent = create_harness_agent(
    OpenAIChatClient(model="gpt-4o"),
)

session = agent.create_session()
response = await agent.run("Plan a weekend trip to Seattle.", session=session)
print(response.text)

Anweisungen auf Harness-Ebene beschreiben allgemeine Betriebsrichtlinien, während aufgabenspezifische Anweisungen unter agent_instructions zu finden sind. Das Harness wird mit Standardanweisungen auf Harness-Ebene (DEFAULT_HARNESS_INSTRUCTIONS) ausgeliefert, die Sie über harness_instructions überschreiben können. Sie können auch zusätzliche Tools übergeben:

agent = create_harness_agent(
    client=client,
    name="research-agent",
    agent_instructions="You are a research assistant focused on academic sources.",
    tools=get_stock_price,
)

Komprimierung aktivieren

Komprimierung verhindert, dass lange Toolaufrufschleifen das Kontextfenster überlaufen. Stellen Sie sowohl die maximale Kontextfenstergröße des Modells als auch eine maximale Ausgabegröße bereit, um die standardmäßigen Tokenbudget-fähigen Strategien zu ermöglichen:

agent = create_harness_agent(
    client=client,
    max_context_window_tokens=128_000,
    max_output_tokens=16_384,
)

Wenn weder tokenparameter noch eine benutzerdefinierte Strategie bereitgestellt werden, wird die Komprimierung automatisch deaktiviert. Um Ihre eigenen Strategien zu verwenden, übergeben Sie before_compaction_strategy und/oder after_compaction_strategy; um die Kompaktierung explizit zu deaktivieren, setzen Sie disable_compaction=True.

Anpassen und Deaktivieren von Features

Jede Standardfunktion verfügt über ein entsprechendes disable_* Schlüsselwortargument, sodass Sie die gewünschten Teile beibehalten und den Rest ablegen können:

agent = create_harness_agent(
    client=client,
    harness_instructions="Custom operating guidelines here.",
    disable_todo=True,         # No todo list
    disable_mode=True,         # No plan/execute modes
    disable_web_search=True,   # No hosted web search tool
    disable_file_memory=True,  # No file-based session memory
)

Zu den anderen Flags gehören disable_file_access, disable_tool_auto_approvalund disable_compaction. Sie können Skillermittlung mit skills_paths auf benutzerdefinierte Speicherorte verweisen und mit context_providers eigene Anbieter hinzufügen.

Wiederholen, bis abgeschlossen

Standardmäßig läuft die Testumgebung bei jedem Aufruf einmal. Übergeben Sie ein loop_should_continue Prädikat, um den Agenten automatisch wiederholt aufzurufen, bis das Prädikat feststellt, dass der Vorgang abgeschlossen ist. Verwenden Sie loop_next_message, um den Prompt für jede Folgeiteration zu steuern, und loop_max_iterations, um die Anzahl der Durchläufe zu begrenzen:

from agent_framework import create_harness_agent, todos_remaining

agent = create_harness_agent(
    client=client,
    loop_should_continue=todos_remaining(),
    loop_max_iterations=10,
)

Das Prädikat wird mit Schlüsselwortargumenten (iteration, last_result, session, agentusw.) aufgerufen. todos_remaining Führt den Agent erneut aus, während die Todoliste weiterhin geöffnete Elemente enthält. Um eine eigene zu schreiben, akzeptieren Sie diese Schlüsselwortargumente – zum Beispiel lambda *, last_result, **kwargs: "DONE" not in last_result.text.

Shell- und Hintergrund-Agents

Um dem Agenten das Ausführen von Shell-Befehlen zu ermöglichen, geben Sie ein shell_executor an (zum Beispiel LocalShellTool aus agent-framework-tools). Dies fügt ein genehmigungspflichtiges Tool zur Shell-Ausführung sowie einen Provider hinzu, der das Betriebssystem und die Shell-Umgebung untersucht. Der Aufrufer besitzt den Lebenszyklus des Executors:

from agent_framework_tools.shell import LocalShellTool, ShellPolicy

# A shell confined to a working directory. Commands require approval by default;
# the deny-list is a UX pre-filter, not a security boundary.
async with LocalShellTool(
    workdir="./working",
    confine_workdir=True,
    policy=ShellPolicy(denylist=[r"\brm\s+-rf\b", r"\bsudo\b"]),
) as shell:
    agent = create_harness_agent(
        client=client,
        shell_executor=shell,
    )

Um die parallele Delegierung zu aktivieren, übergeben Sie eine Sequenz von Hintergrund-Agents. Der Agent kann Unteraufgaben für die gleichzeitige Ausführung aushändigen:

agent = create_harness_agent(
    client=client,
    background_agents=[web_search_agent, code_agent],
)

Note

Unterstützung für Agent-Gurtzeuge wird in Kürze verfügbar sein. Den neuesten Status finden Sie im Agent Framework Go-Repository .

Planen und Ausführen von Workflows

Der Agentmodusanbieter ermöglicht einen zweistufigen Arbeitsstil, der natürlich mit der Todoliste kombiniert wird:

  1. Planmodus – interaktiv. Der Agent stellt klärende Fragen, entwirft eine To-do-Liste und einen Plan und holt Ihre Zustimmung ein, bevor er umfangreichere Arbeiten ausführt.
  2. Ausführungsmodus – autonom. Der Agent arbeitet die Aufgaben eigenständig ab und meldet dabei laufend den Fortschritt.

Der Modusanbieter verfügt zwar über Plan- und Ausführungsmodi als Standardmodi, kann jedoch durch andere Modi und benutzerdefinierte Anweisungen für jeden Modus ersetzt werden, falls erforderlich.

Eine beispielhafte Terminal-UX

Der Gurt bietet Ihnen einen fähigen Agenten, schreibt aber nicht vor, wie Menschen damit interagieren. Um die Funktionsweise des Harness von Anfang bis Ende zu veranschaulichen, haben wir ein Beispiel-Endgerät UX integriert – eine interaktive Konsole (TUI), die die Ausgabe des Agents überträgt, dessen Aufgabenliste und den aktuellen Modus anzeigt, Prompts zur Tool-Freigabe einblendet und Slash-Befehle wie /todos, /mode und /exit unterstützt.

Important

Diese Konsolenprojekte sind Beispiele, nicht Teil des ausgelieferten Frameworks. Sie sind bewusst in sich abgeschlossen, sodass Sie sie direkt ausführen können, um das Testgerüst kennenzulernen, oder sie als Ausgangspunkt für die Erstellung Ihrer eigenen Terminal-Umgebung in Ihr eigenes Projekt kopieren.

Die .NET Beispielkonsole ist das Harness.Shared.Console Projekt. Als Einstiegspunkt dient HarnessConsole.RunAgentAsync, das Ihren Agenten, einen Platzhalter-Prompt und optional HarnessConsoleOptions (Beobachter, Handler für Slash-Befehle, Modusfarben) entgegennimmt:

using Harness.Shared.Console;

await HarnessConsole.RunAgentAsync(agent, userPrompt: "Ask me anything to get started.");

Passen Sie sie mit Ihren eigenen Beobachtern, Tool-Formatierern und Befehls-Handlern an – oder forken Sie sie als Grundlage für Ihr eigenes Terminal-Erlebnis. Sehen Sie sich die .NET-Harness-Beispiele an.

Die Python-Beispielkonsole ist das console-Paket neben den Harness-Beispielen. Der Einstiegspunkt ist run_agent_async, der eine textbasierte App ausführt:

from console import run_agent_async

await run_agent_async(agent)

Es ist rund um Observer, UI-Komponenten und Slash-Befehle aufgebaut, die alle über die Basisklassen ConsoleObserver, ToolCallFormatter und CommandHandler erweitert werden können (abhängig von textual und rich). Führen Sie es unverändert aus, oder verwenden Sie es als Grundlage für Ihre eigene Terminal-Umgebung. Sehen Sie sich die Beispiele für Python Gurtzeug an.

Nächste Schritte

Mehr erfahren