3
0

Einstieg Doku

This commit is contained in:
Magnus Bender 2024-10-30 22:12:51 +01:00
parent 807e7cefb6
commit ebe4a58f90
Signed by: bender
GPG Key ID: 5149A211831F2BD7
15 changed files with 204 additions and 144 deletions

16
.gitignore vendored
View File

@ -1,4 +1,14 @@
/data/
.DS_Store
__pycache__
# data of containers
/data/
!/data/share/example/*.txt
# ignore local venv
/bin/
/lib/
/include/
/pyvenv.cfg
# ignore ums source
/ums/

3
Example.md Normal file
View File

@ -0,0 +1,3 @@
# Beispiel: Rätsel & Agent
TODO

3
Implement.md Normal file
View File

@ -0,0 +1,3 @@
# Implementierung
TODO

View File

@ -1,4 +1,51 @@
# Template für ein Agentensystem
# Template für das Agentensystem
## Einstieg
0. Rechner vorbereiten
1. Docker Desktop installieren <https://docs.docker.com/desktop/>
2. Editor (IDE) installieren (freie Auswahl, Beispiele für <https://code.visualstudio.com/>)
1. Repository einrichten
1. Template laden `git clone -o UHH https://git.chai.uni-hamburg.de/UMS-Agenten/Agenten-Plattform.git`
2. *Eigenes* Repository hinzufügen `git remote add UMS https://git.uni-muenster.de/example/my-group.git`
3. In *eigenes* Repository pushen `git push UMS master`
4. Später dann auch immer `git push UMS ...`, `git pull UMS ...`
5. Updates vom Template `git pull UHH master` (Achtung: Merge-Konflikt)
2. Lokale Umgebung (kann übersprungen werden, mach aber das Entwickeln netter; nur für VS Code)
- Python-Paket `src`: Eigene Implementierung
- Python-Paket `ums`: Agenten-Plattform ([Quelle](https://git.chai.uni-hamburg.de/UMS-Agenten/Agenten-Plattform/src/branch/master/ums))
- VS Code kann leider kein Autocomplete/ IntelliSense im Docker Container anbieten, daher müssen die Quellen auch auf dem Host verfügbar sein.
- VS Code erkennt das Verzeichnis `./src/` als Paket `src`
- Wir brauchen zusätzlich ein paar Abhängigkeiten und `ums`
1. Virtuelles Env. erstellen `python3 -m venv .`
2. Virtuelles Env. aktivieren `source ./bin/activate`
3. Pakete installieren `pip install requests fastapi pdoc` (evtl. später weitere, damit diese auch IntelliSense unterstützen)
4. In VS Code (in einer Python-Datei unten rechts) das Virtuelle Env. auswählen (`./bin/...`)
5. Verzeichnis `ums` aus dem Docker Container extrahieren:
```bash
docker create --name "management" "git.chai.uni-hamburg.de/ums-agenten/management:arm64" # oder :amd64
docker cp "management:/ums-agenten/plattform/ums/" ./ums/
docker rm "management"
```
- Virtuelles Env. und das Verzeichnis `./ums` werden von git ignoriert (siehe `./.gitignore`)
3. Agenten und Management starten
- Die Konfiguration des Managements und er verschiedenen Agenten erfolgt über die Datei `docker-compose.yml`
- Es ist sehr sinnvoll die Datei einmal durchzugehen und die Kommentare dort anzusehen.
1. Für jeden Container/ Service die Images prüfen und anpassen (`:arm64` or `:amd64`, siehe [&darr;](#docker-images))
2. `docker compose up` startet alle Container wie in der `docker-compose.yml` angegeben
- Anschließend hängt das Terminal an der Ausgabe der verschiedenen Container
- Fehler erscheinen dort im Terminal oder/ und in `./data/persist-*/ums.log`
3. Das Management kann über <http://localhost:8080> erreicht werden, es bietet:
- Dokumentation: <http://localhost:8080/docs/ums.html>
- Übersicht der Nachrichten zwischen Agenten und Management: <http://localhost:8080/app/table>
- Senden von Nachrichten/ Erstellen von Rätseln: <http://localhost:8080/app/new>
- Web API: <http://localhost:8080/api> (siehe auch <http://localhost:8080/docs/ums/utils/request.html>)
4. Im Ordner `src` ist ein sehr einfaches Agentensystem implementiert [&rarr; Beispiel: Rätsel & Agent](./Example.md)
5. Die Implementierung kann auf dem Beispiel aufbauen [&rarr; Implementierung](./Implement.md)
> **Generell gilt:**
> Die Images sind größtenteils neu.
> Auch das Management und Agenten-Framework wurde neu entworfen, d.h., es können (und werden) noch ein paar Käfer irgendwo lauern.
> Bugs also bitte melden und bei Problemen mit dem System nachfragen (magnus.bender@uni-hamburg.de).
## Docker Images
Es gibt unter <https://git.chai.uni-hamburg.de/UMS-Agenten/-/packages> viele verschiedene Docker Images.
@ -24,18 +71,6 @@ Folgende Images sind verfügbar:
- Dieses Repository bildet einen einfachen und beispielhaften Agenten ab und soll als Basis dienen.
> **Generell gilt:**
> Die Images sind größtenteils neu.
> Auch das Management und Agenten-Framework wurde neu entworfen, d.h., es können (und werden) noch ein paar Käfer irgendwo lauern.
> Bugs also bitte melden und bei Problemen mit dem System nachfragen (magnus.bender@uni-hamburg.de).
Es wird im Laufe der Zeit sicherlich Updates der verschiedenen Images geben.
Aus diesem Grund gibt bei den Tags Suffixe wie z.B. `2024-10-04` mit dem Datum des Build eines Images.
Somit bleiben auch alte Versionen erreichbar, auch wenn am Ende die aktuelle Version ohne Suffix genutzt werden soll.
## Struktur einen Agenten
> Dieses Repository ist so konzipiert, dass es geclont werden kann und dann zu einem Angenten *umgebaut* wird.
...
TODO

View File

@ -1,37 +0,0 @@
# Agenten Plattform
#
# (c) 2024 Magnus Bender
# Institute of Humanities-Centered Artificial Intelligence (CHAI)
# Universitaet Hamburg
# https://www.chai.uni-hamburg.de/~bender
#
# source code released under the terms of GNU Public License Version 3
# https://www.gnu.org/licenses/gpl-3.0.txt
from ums.agent import ExtractAudioAgent, ExtractImageAgent
from ums.utils.types import RiddleData
"""
Examples for simple agents.
Each agent is represented by its own class. The handling of tasks is done by `handle()` in each agent.
Finally `AGENT_CLASSES` contains the classes of the agents in a list. Via environmental variables this list is specified to the ums.agent system.
"""
class MyExtractAudioAgent(ExtractAudioAgent):
def handle(self, data: RiddleData) -> RiddleData:
print("Audio Process:", data.file_plain)
return data
class MyExtractImageAgent(ExtractImageAgent):
def handle(self, data: RiddleData) -> RiddleData:
print("Image Process:", data.file_plain)
return data
AGENT_CLASSES = [
MyExtractAudioAgent, MyExtractImageAgent
]

View File

@ -1,15 +0,0 @@
ARG IMAGE_FROM
FROM $IMAGE_FROM
# become root
USER root
# do somthing as root, e.g. install packages, set up things ...
# RUN ...
# copy the source of the agent in this repo
COPY --chown=user:user ./src/ /ums-agenten/project/src/
# fix permissions
RUN chown -R user:user /ums-agenten
# switch back to user
USER user

View File

@ -1,59 +0,0 @@
# Agenten Plattform
#
# (c) 2024 Magnus Bender
# Institute of Humanities-Centered Artificial Intelligence (CHAI)
# Universitaet Hamburg
# https://www.chai.uni-hamburg.de/~bender
#
# source code released under the terms of GNU Public License Version 3
# https://www.gnu.org/licenses/gpl-3.0.txt
from typing import Callable
from ums.agent import ExtractTextAgent, SolveAgent, GatekeeperAgent
from ums.utils.types import AgentMessage, Riddle, RiddleData, RiddleSolution, RiddleStatus
"""
Examples for simple agents.
Each agent is represented by its own class. The handling of tasks is done by `handle()` in each agent.
Finally `AGENT_CLASSES` contains the classes of the agents in a list. Via environmental variables this list is specified to the ums.agent system.
"""
class MyExtractTextAgent(ExtractTextAgent):
def before_response(self, response: AgentMessage, send_it: Callable[[], None]) -> bool:
print("The response will be:", response)
return True
def handle(self, data: RiddleData) -> RiddleData:
print("Text Process:", data.file_plain)
return data
class MySolveAgent(SolveAgent):
def handle(self, riddle: Riddle, data: RiddleData) -> RiddleSolution:
if self.message().id == "test":
status = RiddleStatus()
status.extract.required = False
self.sub_riddle(riddle=Riddle(context="Haha", question="Blubber"), status=status)
return RiddleSolution(solution="Huii", explanation="Blubb")
class MyGatekeeperAgent(GatekeeperAgent):
def handle(self, solution: RiddleSolution, riddle: Riddle) -> RiddleSolution:
solution.accepted = True
solution.review = "Ok"
return solution
AGENT_CLASSES = [
MyExtractTextAgent,
MySolveAgent,
MyGatekeeperAgent
]

View File

@ -1,5 +1,8 @@
services:
# first the management
management:
# select the correct one base on platform this is running on
image: git.chai.uni-hamburg.de/ums-agenten/management:arm64
@ -11,12 +14,16 @@ services:
environment:
# limit number of trials for solving a riddle
- SOLUTION_MAX_TRIALS=5
# limit to prevent messages in never ending cycles
- MESSAGE_MAX_CONTACTS=100
# how to access management (the host name is the name of the service in this file)
- MANAGEMENT_URL=http://management
# *register* the agents to the management
- AGENTS_PROCESS=http://agent_extract_1:8000,http://agent_extract_2:8000
- AGENTS_PROCESS=http://agent_extract:8000
- AGENTS_SOLVE=http://agent_solve:8000
- AGENTS_GATEKEEPER=http://agent_gatekeeper:8000
# divide multiple agents of same type by comma
#- AGENTS_PROCESS=http://agent_extract_1:8000,http://agent_extract_2:8000
volumes:
# all data is bind-mounted from ./data on the host into the containers
# the folder *share* is shared with all agents, it can be used to pass the data via files
@ -24,10 +31,12 @@ services:
# the folder *persist* is different for each container and is used to store data permanently
- ./data/persist-management/:/ums-agenten/persist/
agent_solve:
# afterwards the agents
agent_extract:
# this allow to do installs etc. in the docker image (a new image will be built on top of the provided one)
build:
context: ./agent-solve
context: .
dockerfile: Dockerfile
args:
# select the correct one base on platform this is running on
@ -39,28 +48,20 @@ services:
- 8081:8000
environment:
# python package:variable_name of the list of agents implemeted here
- AGENTS_LIST=src.agent:AGENT_CLASSES
- AGENTS_LIST=src.extract.agent:AGENT_CLASSES
# tell the agent where the management is accessible
- MANAGEMENT_URL=http://management
volumes:
- ./data/share/:/ums-agenten/share/
- ./data/persist-solve/:/ums-agenten/persist/
- ./data/persist-extract/:/ums-agenten/persist/
# this is for development (s.t. the changes in ./src/ are directly applied)
- ./agent-solve/src/:/ums-agenten/project/src/:ro
- ./src/:/ums-agenten/project/src/:ro
# for development: will detect file changes and reload server with new source
entrypoint: bash -c "SERVE=true uvicorn ums.agent.main:app --host 0.0.0.0 --port 8000 --reload --reload-dir /ums-agenten/project/src/"
networks:
# this is a trick: we add multiple host names to the same container
# later, each agent will get its own container, but for testing, by this
# one container can become *all* agents
default:
aliases:
- agent_extract_2
- agent_gatekeeper
agent_extract_1:
agent_solve:
build:
context: ./agent-extract
context: .
dockerfile: Dockerfile
args:
- IMAGE_FROM=git.chai.uni-hamburg.de/ums-agenten/base-agent:cpu-arm64
@ -69,9 +70,30 @@ services:
ports:
- 8082:8000
environment:
- AGENTS_LIST=src.agent:AGENT_CLASSES
- AGENTS_LIST=src.solve.agent:AGENT_CLASSES
- MANAGEMENT_URL=http://management
volumes:
- ./data/share/:/ums-agenten/share/
- ./data/persist-extract/:/ums-agenten/persist/
- ./agent-extract/src/:/ums-agenten/project/src/:ro
- ./data/persist-solve/:/ums-agenten/persist/
- ./src/:/ums-agenten/project/src/:ro
entrypoint: bash -c "SERVE=true uvicorn ums.agent.main:app --host 0.0.0.0 --port 8000 --reload --reload-dir /ums-agenten/project/src/"
agent_gatekeeper:
build:
context: .
dockerfile: Dockerfile
args:
- IMAGE_FROM=git.chai.uni-hamburg.de/ums-agenten/base-agent:cpu-arm64
#- IMAGE_FROM=git.chai.uni-hamburg.de/ums-agenten/base-agent:cpu-amd64
#- IMAGE_FROM=git.chai.uni-hamburg.de/ums-agenten/base-agent:gpu-amd64
ports:
- 8083:8000
environment:
- AGENTS_LIST=src.validate.agent:AGENT_CLASSES
- MANAGEMENT_URL=http://management
volumes:
- ./data/share/:/ums-agenten/share/
- ./data/persist-validate/:/ums-agenten/persist/
- ./src/:/ums-agenten/project/src/:ro
entrypoint: bash -c "SERVE=true uvicorn ums.agent.main:app --host 0.0.0.0 --port 8000 --reload --reload-dir /ums-agenten/project/src/"

41
src/extract/agent.py Normal file
View File

@ -0,0 +1,41 @@
# Agenten Plattform
#
# (c) 2024 Magnus Bender
# Institute of Humanities-Centered Artificial Intelligence (CHAI)
# Universitaet Hamburg
# https://www.chai.uni-hamburg.de/~bender
#
# source code released under the terms of GNU Public License Version 3
# https://www.gnu.org/licenses/gpl-3.0.txt
from typing import Callable
from ums.agent import ExtractAudioAgent, ExtractImageAgent, ExtractTextAgent
from ums.utils.types import RiddleData, AgentMessage
class SimpleExtractAudioAgent(ExtractAudioAgent):
def handle(self, data: RiddleData) -> RiddleData:
print("Audio Process:", data.file_plain)
return data
class SimpleExtractImageAgent(ExtractImageAgent):
def handle(self, data: RiddleData) -> RiddleData:
print("Image Process:", data.file_plain)
return data
class SimpleExtractTextAgent(ExtractTextAgent):
def before_response(self, response: AgentMessage, send_it: Callable[[], None]) -> bool:
print("The response will be:", response)
return True
def handle(self, data: RiddleData) -> RiddleData:
print("Text Process:", data.file_plain)
return data
AGENT_CLASSES = [
SimpleExtractAudioAgent, SimpleExtractImageAgent, SimpleExtractTextAgent
]

30
src/solve/agent.py Normal file
View File

@ -0,0 +1,30 @@
# Agenten Plattform
#
# (c) 2024 Magnus Bender
# Institute of Humanities-Centered Artificial Intelligence (CHAI)
# Universitaet Hamburg
# https://www.chai.uni-hamburg.de/~bender
#
# source code released under the terms of GNU Public License Version 3
# https://www.gnu.org/licenses/gpl-3.0.txt
from ums.agent import SolveAgent
from ums.utils.types import Riddle, RiddleData, RiddleSolution, RiddleStatus
class SimpleSolveAgent(SolveAgent):
def handle(self, riddle: Riddle, data: RiddleData) -> RiddleSolution:
if self.message().id == "test":
status = RiddleStatus()
status.extract.required = False
self.sub_riddle(riddle=Riddle(context="Haha", question="Blubber"), status=status)
return RiddleSolution(solution="Huii", explanation="Blubb")
AGENT_CLASSES = [
SimpleSolveAgent
]

0
src/validate/__init__.py Normal file
View File

27
src/validate/agent.py Normal file
View File

@ -0,0 +1,27 @@
# Agenten Plattform
#
# (c) 2024 Magnus Bender
# Institute of Humanities-Centered Artificial Intelligence (CHAI)
# Universitaet Hamburg
# https://www.chai.uni-hamburg.de/~bender
#
# source code released under the terms of GNU Public License Version 3
# https://www.gnu.org/licenses/gpl-3.0.txt
from ums.agent import GatekeeperAgent
from ums.utils.types import Riddle, RiddleSolution
class SimpleSolveAgent(GatekeeperAgent):
def handle(self, solution: RiddleSolution, riddle: Riddle) -> RiddleSolution:
solution.accepted = True
solution.review = "Ok"
return solution
AGENT_CLASSES = [
SimpleSolveAgent
]