6.1 KiB
Implementierung
Bisher ist das hier noch eher eine Sammlung von Tipps.
Grundsätzlich
Dieses Git-Repository ist so erstellt, dass es als Template dienen kann.
Die Agenten sollten im Ordner ./src/
und damit dem Paket src
implementiert werden.
Aktuell ist es so angelegt, dass alle Agenten sich das Paket src
teilen, d.h., auch wenn man zwei Agenten implementiert, dann ist aller Code in src
und je nach Agent z.B. jeweils in Unterpaketen.
Über AGENTS_LIST
wird beim Start eines Containers dann jeweils spezifiziert, welchen Agenten der Container laden/ ausführen soll.
Es ist theoretisch auch möglich, alle Agenten in einem Docker-Container auszuführen (wenn AGENTS_LIST
Klassen für Typen von Agenten enthält), dabei wird aber die Performance und Nebenläufigkeit leiden.
Dinge nachinstallieren
Eigene Programme, Bibliotheken etc. können in Docker installiert werden, dazu liegt eine Dockerfile
im Repository, diese wird auf die Agenten angewandt.
Zum Beispiel würde ein RUN pip3 install super-duper-toll
das Pakete super-duper-toll
dann auch im Docker-Container des Agenten verfügbar machen.
Nach Änderungen an der Dockerfile
baut man mit docker compose build
das Docker-Image für die Agenten neu.
Einzelne Teile Ausführen
Manchmal kann es nervig sein, beim Arbeiten an einer Komponente eines Agenten immer das ganze System mit Management etc. nutzen zu müssen und jedes mal auch noch Nachrichten ans Management senden zu müssen. Zur Abhilfe gibt es die Möglichkeit einzelne Tasks per Terminal direkt an an einzelne Agenten zu senden, siehe http://localhost:8080/docs/ums/agent.html#run-single-task (Link zu Dokumentation im Management, Dokumentation auch als HTML unter https://git.chai.uni-hamburg.de/UMS-Agenten/Agenten-Plattform/src/branch/master/web/public/docs).
Z.B. eine Dummy-Message an den agent_solve
senden, wenn der Container selbst nicht läuft:
docker compose run --rm --entrypoint "" agent_solve python -m ums.agent -d
Agent handle
Die Methode handle
ist die Hauptmethode eines Agenten, das Framework kümmert sich darum, dass handle
aufgerufen wird.
Genauere Spezifikationen finden sich hier http://localhost:8080/docs/ums/agent/agent.html.
Bei der Ausführung von handle
kann ein Agent entscheiden, eine Unteraufgabe (via http://localhost:8080/docs/ums/agent/agent.html#BasicAgent.sub_riddle) zu erstellen. Eine solche Unteraufgabe wird wie eine normale Aufgabe an das Management gesendet und gelöst.
Auch der Agent, der die Unteraufgabe erstellt hat, kann/ wird seine eigene Unteraufgabe zum Lösen bekommen.
Das ist in soweit nützlich, dass der Agent z.B. eine andere Datenauswahl getroffen haben kann und nun bei der Unteraufgabe andere Extraktionen bekommt.
Möchte der Agent das Gesamtergebnis einer Unteraufgabe sehen, so muss das Management angefragt werden (siehe ↓)
Insbesondere bei Aufgabe, die der Agent nicht lösen kann, kann der Agent die Antwort an das Management stoppen (via http://localhost:8080/docs/ums/agent/agent.html#BasicAgent.before_response). Damit wird das Lösung des Rätsels (zumindest von diesem Agenten) aufgegeben. Sollte z.B. der Agent zur Extraktion von Bilder keine Antwort geben und gibt aber der Agent zur Extraktion von Audio eine Antwort, so wird die Lösung des Rätsels nicht aufgegeben, aber es sind nur die Daten des Typs Audio extrahiert vorhanden und nutzbar genutzt werden.
Hieraus lässt sich auch ablesen, dass ein Agent evtl. das selbe Rätsel mehrfach bekommt, jeweils mit unterschiedlichen Daten die bereits extrahiert sind. Dadurch kann ein Agent direkt versuchen ein Rätsel zu lösen und falls die Daten nicht reichen, dies später mit mehr Daten wiederholen. Das Framework führt die verschiedenen Extraktionen der verschiedenen Agenten zu Audio, Image, Text zusammen, d.h., das Framework stellt immer alle vorhandenen Extraktionen für ein Datensatz in den Nachrichten zusammen (dabei gilt ein Datensatz als gleich, wenn Datei, Typ und Prompt übereinstimmen.) Die Zusammenführung findet nur innerhalb von Rätseln mit der gleichen ID statt.
Über den Parameter REQUIRE_FULL_EXTRACT
kann das Management angewiesen werden, zuerst alle Extraktionen aller Agenten abzuwarten, bevor das Rätsel zum Lösen weitergegeben wird.
Falls REQUIRE_FULL_EXTRACT=true
so muss sichergestellt werden, dass auch alle Agenten (also für jeden Datensatz) irgendwann eine Extraktion bestimmt wird, andernfalls wartet das Management ewig.
Bei REQUIRE_FULL_EXTRACT=false
bekommt der Agent zum Lösen ein Rätsel dann evtl. doppelt, jeweils mit weiteren Extraktionen.
Mit REQUIRE_FULL_SOLVE
kann (ähnlich zu REQUIRE_FULL_EXTRACT
) das Management angewiesen werden, von allen Agenten (in AGENTS_SOLVE
) eine Lösung abzuwarten, bevor diese Lösungen (gebündelt) an den Gatekeeper zum Prüfen weitergeleitet werden.
Auch hier muss bei REQUIRE_FULL_SOLVE=true
sichergestellt werden, dass alle Agenten auch (in AGENTS_SOLVE
) irgendwann eine Lösung ausgeben.
Außerdem darf die Lösung von zwei Agenten nicht komplett identisch sein, d.h., wenn Lösung, Erklärung und benutzte Dateien einer Lösung gleich sind, so wird sie als die selbe Lösung angesehen und das Management würde z.B. auf eine weitere Lösung warten.
Ein Agent kann eine Antwort aber auch nicht nur stoppen, sondern auch für später aufheben (via http://localhost:8080/docs/ums/agent/agent.html#BasicAgent.before_response). So kann ein Agent z.B. auf die Lösung einer Unteraufgabe warten und erst anschließend seine Antwort an das Management senden.
Requests an das Management
Eigentlich sendet das Framework alle Request an das Management. Sollte ein Agent beim Lösen einer Aufgabe weiter Unteraufgabe erstellen möchten, so kann http://localhost:8080/docs/ums/agent/agent.html#BasicAgent.sub_riddle benutzt werden. In seltenen Fällen, möchte ein Agent aber vielleicht auf die Liste aller Nachrichten im Management zugreifen (Inhalte der Tabelle). Dazu kann http://localhost:8080/docs/ums/utils/request.html#ManagementRequest benutzt werden.