enhancement
major
minor
defect
critical
major
minor
major
#30053
Agent läuft: Begrenzt die Anzahl paralleler Tool-Aufrufe (AgentLoop.TOOL_WORKERS) und teilt einem Benutzer mit, dessen Chat-Nachricht auf einen freien Worker wartet
Folgebeitrag zu #29767.
Hintergrund
Die Ausführungslimits der KI-Module werden in <capacity> im AgentRuntimeService und in <budget> im AgentPolicyService konfiguriert (Entwicklerartikel ai/limits-and-caching, Abschnitt „Run limits“). Es bestehen weiterhin zwei Diskrepanzen zwischen den Grenzen, die eine Installation festlegen kann, und den Informationen, die einem Benutzer angezeigt werden.
1. Für den Pool paralleler Tool-Aufrufe gibt es keine Obergrenze
Was: AgentLoop.TOOL_WORKERS (tl-ai-core, com.top_logic.tl.ai.core.agent.AgentLoop) ist ein statisches `Executors.newCachedThreadPool(...)`. Jeder READ-Toolaufruf eines parallelen Batches (executeConcurrent) belegt einen eigenen Thread über alle Läufe des Knotens hinweg. chat-workers begrenzt zwar, wie viele Läufe gleichzeitig ausgeführt werden, nicht jedoch, wie viele Tool-Threads diese Läufe starten: Ein Modell, das einen Batch mit vielen READ-Aufrufen ausgibt, erzeugt – multipliziert mit der Anzahl der gleichzeitigen Läufe – ebenso viele Threads.
Behebung: Füge eine Obergrenze für <capacity> hinzu (z. B. tool-workers, 0 = keine Obergrenze, das derzeitige Verhalten), die Einstellung über RunLimitSettings wie die anderen Kapazitätseinstellungen auslesen und daraus einen begrenzten Pool bilden, in dem ein Aufruf, der die Obergrenze überschreitet, wartet (wie es bei „chat-workers“ der Fall ist – ein READ-Aufruf darf nicht abgelehnt werden). Behalte den Thread-Namen des Pools „agent-tool-worker“ und dessen Daemon-Threads bei; die Begrenzung darf die Reihenfolge, in der Ergebnisse der Konversation hinzugefügt werden (collectBatchResults), nicht verändern.
Test: Ein Unit-Test mit `tool-workers="2"` und einem Stapel von fünf READ-Aufrufen eines Tools, das an einem Latch blockiert: Es laufen höchstens zwei Aufrufe gleichzeitig, alle fünf Ergebnisse treffen in der Reihenfolge des Stapels ein; mit der Standardeinstellung laufen alle fünf gleichzeitig.
2. Eine in der Warteschlange stehende Chat-Nachricht sagt nichts aus
Was: Wenn „chat-workers“ festgelegt ist und die Standardeinstellung „chat-queue=“0“ gilt, wartet ein Sendevorgang, bei dem alle Worker beschäftigt sind, in der Warteschlange von „ChatRunExecutor“ (tl-chat). Der Benutzer sieht, dass der Editor beschäftigt ist, und es wird kein Lauf gestartet; nichts weist darauf hin, dass die Antwort verspätet ist, weil die Installation ausgelastet ist, und nicht, weil das Modell langsam ist.
Behebung: Wenn ChatProcessor.sendMessage einen Lauf übermittelt, der nicht sofort startet (der Pool hat keinen freien Worker), sende einen SSE-Frame, den der Chat als Hinweiszeile anzeigt („Warten auf einen freien Worker – Position N“ / „Warte auf einen freien Bearbeiter – Position N“), und lösche diese Meldung, sobald der Lauf startet. Die Texte sind I18N-Konstanten von tl-chat mit @en und @de.
Test: Ein tl-chat-Test mit chat-workers="1": Ein zweiter Sendevorgang, während der erste Lauf blockiert ist, erhält den Warte-Frame, und der „Lauf-gestartet“-Frame dieses Sendevorgangs folgt, sobald der erste Lauf beendet ist; ein vitest der Chat-Benutzeroberfläche, der die Hinweiszeile anzeigt und wieder löscht.
Lösung
- Gemeinsamer begrenzter Worker-Pool in tl-ai-core (limits): Die bisher in ChatRunExecutor (tl-chat) implementierte Pool-Variante (feste Größe, Warteschlange, Daemon-Threads, allowCoreThreadTimeOut, Neuaufbau bei geänderter Konfiguration) wird zu einer allgemeinen Klasse, die ChatRunExecutor und der Pool der parallelen Tool-Aufrufe (tool-workers, Thread-Name agent-tool-worker) gemeinsam nutzen.
- Keine Blockierung bei verschachtelten Batches: Startet ein Tool auf einem Tool-Worker selbst einen Agentenlauf (Subagent, Delegation), führt dessen paralleler Batch seine Aufrufe nacheinander auf dem eigenen Thread aus, anstatt auf freie Worker desselben begrenzten Pools zu warten. Die Obergrenze gilt somit, ohne dass alle Worker auf Aufgaben warten, die nie starten.
- Hinweis bei wartender Nachricht wie unter 2.; die Position wird aktualisiert, solange die Nachricht wartet.
- Zusätzlicher Test: „tool-workers=“1“ mit einem READ-Tool, das einen verschachtelten parallelen Batch startet, wird durchlaufen.