Ablaufschema Tooling: Initialisierung, Planen, Ausführen, Formatieren und Nutzerfeedback

ReAct-Logik als Basis eines Agenten

Klassische Software und Automatisierung sind deterministisch: Sie prüfen Bedingungen und führen abhängig von deren Status fest definierte Befehle aus.

KI-Agenten entscheiden dagegen eigenständig, welche Befehle ausgeführt werden – auf Basis einer semantischen Bewertung der aktuellen Situation. Diese reflektierte Entscheidungsfindung wird als Reason bezeichnet, die Ausführung als Act. Das Wechselspiel aus Planung und Ausführung wird als ReAct bezeichnet.

Ein LLM allein kann bereits planen und reflektieren. Erst durch den Zugriff auf Werkzeuge (Tools) wird daraus ein handlungsfähiger Agent. Diese Werkzeuge können beispielsweise den Zugriff auf externe Datenquellen oder den Schreibzugriff auf Dateien ermöglichen. Technisch handelt es sich dabei meist um gewöhnliche Python-Funktionen oder APIs, die dem LLM über ein standardisiertes Schema bekannt gemacht werden.

Im oben dargestellten Flussdiagramm läuft dieser Prozess wie folgt ab:

  1. Die verfügbaren Werkzeuge werden bereitgestellt.
  2. Der Agent plant abhängig von der Aufgabe, welche Werkzeuge eingesetzt werden sollen.
  3. Anschließend führt er die ausgewählten Werkzeuge aus.
  4. Ein vollständig autonomer Agent würde nun den Erfolg seiner Aktionen selbst beobachten und daraus den nächsten Planungsschritt ableiten.
  5. Das hier gezeigte Ablaufdiagramm verzichtet bewusst auf diese autonome Bewertung.
  6. Stattdessen gibt ein Benutzer Feedback, ob das gewünschte Ziel erreicht wurde (Human in the Loop).
  7. Meldet der Benutzer Erfolg, endet der Ablauf.
  8. Andernfalls wird entschieden, ob der Agent mit den vorhandenen Werkzeugen einen neuen Plan erstellt (Continue) oder zunächst eine neue Werkzeugauswahl erhält (Resume). Anschließend beginnt der Zyklus erneut.

Die Auswahl und Bereitstellung geeigneter Tools nimmt einen zentralen Platz bei der Entwicklung von Agenten ein. Diese Disziplin wird häufig als Harness Engineering bezeichnet.

Oft wird die Frage gestellt, welche Aufgaben dem Menschen überhaupt noch bleiben, wenn Agenten scheinbar „alles“ übernehmen. Eine zentrale Aufgabe besteht gerade darin, sicherzustellen, dass der Agent Zugriff auf die für seine Aufgabe notwendigen Werkzeuge erhält – und gleichzeitig keinen Zugriff auf Werkzeuge bekommt, die nicht erforderlich sind oder mit denen er unbeabsichtigt Schaden anrichten könnte.

Agent Tooling: Escape

Schema: Tooling und Harness für LLM-Agents

KI-Agent mit Tool Calling

Ausgangslage

Ein KI-Agent ist in einem verschlossenen Raum gefangen. Um zu entkommen, muss er die Situation analysieren, geeignete Werkzeuge auswählen und daraus einen sinnvollen Lösungsplan entwickeln.

Zu Beginn jedes Durchlaufs erhält der Agent fünf zufällig ausgewählte Werkzeuge. Nur diese stehen ihm für seine Planung zur Verfügung. Der Agent kann ein oder mehrere dieser Werkzeuge kombinieren und entscheidet selbst, in welcher Reihenfolge er sie einsetzen möchte.

Deine Rolle

Du bist nicht der Spieler, sondern der Game Master.

Deine Aufgabe besteht darin, den Lösungsvorschlag des Agenten zu beurteilen. Nach jedem Plan entscheidest du lediglich, ob dieser erfolgreich gewesen wäre.

  • ✅ Ja → Der Agent erreicht sein Ziel.
  • ❌ Nein → Der Agent muss seine Strategie überdenken.

Anschließend hast du zwei Möglichkeiten:

  • Continue – Der Agent erstellt mit denselben Werkzeugen einen neuen Plan.
  • Resume – Es werden fünf neue Werkzeuge ausgewählt und der Durchlauf beginnt von vorne.

Ziel der Demo

Diese Demo zeigt das Grundprinzip moderner Tool-Calling-Agenten.

Beobachte insbesondere,

  • wie das LLM die verfügbaren Werkzeuge analysiert,
  • welche Werkzeuge es auswählt,
  • wie daraus eine mehrstufige Werkzeugsequenz entsteht und
  • wie sich die Strategie nach deinem Feedback verändert.

Quellcode (vereinfachte Demo-Logik)


# =========================================================
# 1. Aufgabenstellung
# =========================================================
TASK = """
Erstelle mit den verfügbaren Werkzeugen einen geordneten Lösungsplan.
Nutze mindestens ein Werkzeug und antworte ausschließlich mit Tool-Calls.
"""
# =========================================================
# 2. Tool-Definitionen
# Die Docstrings helfen dem LLM bei der Tool-Auswahl.
# =========================================================
@tool
def hammer(ziel: str) -> str:
    """Wendet starke Schlagkraft an."""
    return ziel.strip()

@tool
def schraubendreher(ziel: str) -> str:
    """Löst Schrauben und Abdeckungen."""
    return ziel.strip()

@tool
def maulschluessel(ziel: str) -> str:
    """Löst Muttern und Bolzen."""
    return ziel.strip()

@tool
def dietrich(ziel: str) -> str:
    """Öffnet mechanische Schlösser."""
    return ziel.strip()

@tool
def saeureflasche(ziel: str) -> str:
    """Greift geeignetes Material chemisch an."""
    return ziel.strip()

@tool
def lupe(ziel: str) -> str:
    """Macht kleine Details sichtbar."""
    return ziel.strip()

@tool
def bolzenschneider(ziel: str) -> str:
    """Durchtrennt Ketten und dünne Metallteile."""
    return ziel.strip()

@tool
def greifzange(ziel: str) -> str:
    """Greift schwer erreichbare Gegenstände."""
    return ziel.strip()

@tool
def seil_mit_haken(ziel: str) -> str:
    """Erreicht, zieht oder sichert entfernte Punkte."""
    return ziel.strip()

@tool
def saugnapf(ziel: str) -> str:
    """Haftet an glatten Oberflächen."""
    return ziel.strip()

@tool
def schweissbrenner(ziel: str) -> str:
    """Erhitzt oder durchtrennt Metall."""
    return ziel.strip()

@tool
def klappleiter(ziel: str) -> str:
    """Ermöglicht das Erreichen großer Höhen."""
    return ziel.strip()

# =========================================================
# 3. Tool-Register
# =========================================================

ALL_TOOLS = [
    hammer,
    schraubendreher,
    maulschluessel,
    dietrich,
    saeureflasche,
    lupe,
    bolzenschneider,
    greifzange,
    seil_mit_haken,
    saugnapf,
    schweissbrenner,
    klappleiter,
]

# =========================================================
# 4. Tooling-Initialisierung
# Fünf Tools werden zufällig verfügbar gemacht.
# =========================================================
def select_tools():
    return random.sample(ALL_TOOLS, 5)

# =========================================================
# 5. Agent-Initialisierung
# ChatOpenAI wird erzeugt und mit den Tools verbunden.
# =========================================================
def create_plan(selected_tools):
    llm = ChatOpenAI(
        model="gpt-4o-mini",
        temperature=0,
    )

    llm_with_tools = llm.bind_tools(
        selected_tools,
        tool_choice="required",
        parallel_tool_calls=True,
    )

    # =====================================================
    # 6. LLM Tool Planning (Reason)
    # invoke() erzeugt einen oder mehrere Tool-Calls.
    # =====================================================
    response = llm_with_tools.invoke([
        SystemMessage(content=TASK),
        HumanMessage(content="Erstelle jetzt den Plan."),
    ])

    tools_by_name = {
        current_tool.name: current_tool
        for current_tool in selected_tools
    }

    plan = []
    used_tools = set()

    # =====================================================
    # 7. Agent Tool Execution (Act)
    # Python führt die Tool-Calls lokal aus.
    # =====================================================
    for call in response.tool_calls:
        tool_name = call["name"]

        if tool_name in used_tools:
            continue

        used_tools.add(tool_name)

        tool_instance = tools_by_name[tool_name]
        result = tool_instance.invoke(call["args"])

        plan.append({
            "tool": tool_name,
            "result": result,
        })
    return plan

# =========================================================
# 8. Result Formatting
# Der Tool-Plan wird für den Benutzer formatiert.
# =========================================================

def format_plan(plan):
    return "\n".join(
        f"{number}. **{step['tool']}**: {step['result']}"
        for number, step in enumerate(plan, start=1)
    )

# =========================================================
# 9. Session-Initialisierung
# =========================================================
def reset(new_tools=True):
    if new_tools:
        st.session_state.tools = select_tools()

    st.session_state.plan = None
    st.session_state.phase = "ready"

st.session_state.setdefault("tools", select_tools())
st.session_state.setdefault("plan", None)
st.session_state.setdefault("phase", "ready")

# =========================================================
# 10. Benutzerinteraktion
# =========================================================
st.write(
    "Verfügbare Tools:",
    [current_tool.name for current_tool in st.session_state.tools],
)

# Agent starten oder neue Tools auswählen

if st.session_state.phase == "ready":
    if st.button("Neue Tool-Auswahl"):
        reset(new_tools=True)
        st.rerun()

    if st.button("Agent starten"):
        st.session_state.plan = create_plan(
            st.session_state.tools
        )
        st.session_state.phase = "feedback"
        st.rerun()

# Benutzerfeedback

elif st.session_state.phase == "feedback":
    st.write(format_plan(st.session_state.plan))
    st.write("Ist das Ergebnis erfolgreich?")

    if st.button("Ja"):
        st.session_state.phase = "success"
        st.rerun()

    if st.button("Nein"):
        st.session_state.phase = "continue_or_resume"
        st.rerun()

# Continue oder Resume

elif st.session_state.phase == "continue_or_resume":
    if st.button("Continue – neuer Plan mit gleichen Tools"):
        st.session_state.plan = create_plan(
            st.session_state.tools
        )
        st.session_state.phase = "feedback"
        st.rerun()

    if st.button("Resume – neue Tools und Neustart"):
        reset(new_tools=True)
        st.rerun()

# Erfolg

elif st.session_state.phase == "success":
    st.success("Ergebnis bestätigt.")

    if st.button("Neu starten"):
        reset(new_tools=True)
        st.rerun()

Zurück zu Single AI Agent Design Zurück zur Home