Startseite / Artikel

Praktische Hinweise: Erstellung eines privaten Cloud-Coding-Agenten: OpenCode + ein lokales LLM

Schrittweise Anleitung zu den Praktischen Hinweisen: Erstellung eines privaten Cloud-Coding-Agenten: OpenCode + ein lokales LLM – Verträge, Überprüfungen sowie Code-Blöcke für Teams, die dieses Muster einsetzen.

Verlag: REACTAPP.TOP24 Min. Lesezeit5502 Wörter

Quellen: Building a Private Cloud Coding Agent: OpenCode + a Local LLM, Running on Serverless GPUs

Die folgenden Notizen skizzieren einen praktischen Weg bei der Entwicklung eines privaten Cloud-Coding-Agenten: OpenCode in Kombination mit einem lokalen LLM, der auf serverlosen GPUs läuft. Der Schwerpunkt liegt auf Verträgen, Überprüfungen sowie Ersatzcode-Platzhaltern statt auf motivierenden Formulierungen. Während der Übersichtsphase sollten Sie zunächst den Vertrag aufschreiben: erforderliche Eingaben, Erfolgsindikatoren sowie das Vorgehen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. Ziehen Sie kleine, testbare Einheiten vor statt umfangreicher Skripte. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortung verweisen und nicht auf ein verworrenes Ablaufschema.

Warum diese Architektur

Warum diese Architektur am besten funktioniert, wenn sie als messbare Struktur betrachtet wird. Erfassen Sie ein „goldenes“ Transkript, einen Fehlerfall sowie die Notizen zum Rollback, bevor Sie den Umfang erweitern. Betrachten Sie diese Phase als Vertrag zwischen Eingaben und validierten Ausgaben. Benennen Sie die Erzeugnisse, definieren Sie Erfolgskontrollen und lehnen Sie stille, unvollständige Abschlüsse ab. Legen Sie Budgetgrenzen pro Turnus und pro Sitzung fest. Agentenbasierte Tools erweitern den Kontext oft übermäßig; feste Obergrenzen verhindern, dass Demonstrationen zu unerwarteten Rechnungen werden.

Die Bausteine

Die Bausteine funktionieren am besten, wenn sie als messbare Oberfläche betrachtet werden. Erfassen Sie einen erfolgreichen Fall, einen Fehlerfall sowie die Notizen zur Rücksetzung, bevor Sie den Umfang erweitern. Erfassen Sie außerdem die Zeiten sowie die Kosten für Tokens oder Abfragen neben den funktionalen Ergebnissen. Eine frühzeitige Sichtbarkeit der Kosten verhindert überraschende Rechnungen, wenn sich der Einsatzbereich von einer Demo auf gemeinsame Umgebungen verschiebt. Legen Sie Budgets für Tokens pro Runde und pro Sitzung fest. Agentenbasierte Tools erweitern den Kontext stark; feste Obergrenzen verhindern, dass Demos zu unerwarteten Rechnungen werden.

Modal

Modal funktioniert am besten, wenn es als messbare Struktur betrachtet wird. Erfassen Sie ein „goldenes“ Transkript, einen Fehlerfall sowie eine Notiz zur Rücksetzung, bevor Sie den Umfang erweitern. Bewahren Sie die Konfiguration außerhalb des Anwendungscode auf. Umgebungsdateien, Geheimdatenspeicher und Feature-Flags sollten an einem Ort gesammelt sein, den Betreuer ohne Durchsicht des gesamten Systems prüfen können. Legen Sie Budgetgrenzen pro Turnus und Session fest. Agentenbasierte Tools erweitern den Kontext oft übermäßig; feste Obergrenzen verhindern, dass Demonstrationen zu unerwarteten Rechnungen werden. Modal funktioniert am besten, wenn es als messbare Struktur betrachtet wird. Erfassen Sie ein „goldenes“ Transkript, einen Fehlerfall sowie eine Notiz zur Rücksetzung, bevor Sie den Umfang erweitern. Ziehen Sie kleine, testbare Einheiten vor großen, komplexen Skripten. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortung verweisen und nicht auf einen verworrenen Ablauf.

Ollama

Für die Ollama-Phase sollten vor dem Ändern des Codes die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Betrachten Sie diese Phase als Vertrag zwischen den Eingaben und den validierten Ausgaben. Benennen Sie die Artefakte, definieren Sie Erfolgskontrollen und lehnen Sie stille, unvollständige Abschlüsse ab. Trennen Sie den Client-Aufbau vom Nachrichtenzyklus, damit Provider ausgetauscht werden können, ohne den Zustandsautomaten der Konversation umschreiben zu müssen.

OpenCode

Für die OpenCode-Phase sollten Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien vor dem Codeändern definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Zeiten sowie Kosten für Token oder Abfragen sollten neben den funktionalen Ergebnissen aufgezeichnet werden. Eine frühzeitige Sichtbarkeit der Kosten verhindert überraschende Rechnungen, wenn der Ablauf von einer Demo in gemeinsam genutzte Umgebungen wechselt. Bei dem nächsten Schritt, der ein Code oder einen Toolaufruf ist, sollten strukturierte Ausgaben mit Schema-Validierung Vorrang vor freiformiger Prosa haben.

Der Tunnel

Für die Tunnel-Phase sollten die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien vor dem Ändern des Codes definiert werden. Operator:innen sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Die Konfiguration sollte außerhalb des Anwendungscode liegen. Umgebungsdateien, Geheimdatenspeicher sowie Feature-Flags sollten an einem Ort zusammengefasst sein, den Operator:innen überprüfen können, ohne den gesamten Ablauf durchzulesen. Wählen Sie bei dem nächsten Schritt, der ein Code-Aufruf oder eine Tool-Anfrage ist, strukturierte Ausgaben mit Schema-Validierung statt freier Prosa. Für die Tunnel-Phase sollten die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien vor dem Ändern des Codes definiert werden. Operator:innen sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Wählen Sie kleine, testbare Einheiten statt umfangreicher Skripte. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortung verweisen und nicht auf einen verworrenen Ablauf.

Voraussetzungen und Einrichtung

Während der Voraussetzungen- und Einrichtungsphase sollten Sie zunächst einen Vertrag aufschreiben: erforderliche Eingaben, Erfolgsindikatoren sowie das Vorgehen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. Betrachten Sie diese Phase als Vertrag zwischen Eingaben und validierten Ausgaben. Benennen Sie die Artefakte, definieren Sie Erfolgskontrollen und lehnen Sie stille, teilweise abgeschlossene Abläufe ab. Cachen Sie stabile Systemanweisungen sowie Tool-Schemata. Das erneute Senden identischer Präambeln ist eine häufige Ursache für Ressourcenverschwendung.

pip install modal
modal setup

Entwurf der Container-Image

Beim Bearbeiten der Phase „Entwurf der Container-Image“ sollten Sie zunächst den Vertrag aufschreiben: erforderliche Eingaben, Erfolgsignal sowie das Vorgehen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. Notieren Sie neben den funktionalen Ergebnissen auch die Laufzeiten sowie die Kosten für Tokens oder Abfragen. Eine frühzeitige Sichtbarkeit der Kosten verhindert überraschende Rechnungen, wenn der Weg von einer Demo in gemeinsame Umgebungen wechselt. Speichern Sie stabile Systemanweisungen sowie Tool-Schemata im Cache. Das erneute Senden identischer Vorlagen ist eine häufige Ursache für unnötige Ressourcenverbrauch.

import modal

image = (
    modal.Image.from_registry(
        "nvidia/cuda:13.0.0-devel-ubuntu24.04",
        add_python="3.12",
    )
    .apt_install(
        "curl",
        "git",
        "ca-certificates",
        "zstd",
    )
    .run_commands(
        "curl -fsSL https://ollama.com/install.sh | sh",
    )
    .run_commands(
        "curl -fsSL https://opencode.ai/install | bash",
    )
    .env(
        {
            "OLLAMA_MODELS": "/models/.ollama/models",
            "OLLAMA_HOST": "127.0.0.1:11434",
            "PATH": "/root/.opencode/bin:/usr/local/bin:/usr/bin:/bin",
        }
    )
)

Das Startskript: Orchestrierung von Ollama und OpenCode

Beim Arbeiten an der Phase „The startup script orchestrating“ sollte man zunächst den Vertrag aufschreiben: erforderliche Eingaben, Erfolgsignal sowie das Vorgehen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. Bewahren Sie die Konfiguration außerhalb des Anwendungscode auf. Umgebungsdateien, Geheimdatenspeicher und Feature-Flags sollten an einem Ort gesammelt sein, den Betreiber ohne das Durchlesen des gesamten Systems überprüfen können. Protokollieren Sie bei jedem Aufruf die Anfrage-ID, die Modell-ID sowie die Latenzzeit. Ohne diese Aufzeichnungen wirken intermittierende Fehler des Anbieters wie Bugs in der Anwendung. Beim Arbeiten an der Phase „The startup script orchestrating“ sollte man zunächst den Vertrag aufschreiben: erforderliche Eingaben, Erfolgssignal sowie das Vorgehen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. Ziehen Sie kleine, testbare Einheiten vor großen, komplexen Skripten. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortung verweisen und nicht auf ein verworrenes Ablaufschema.

Schritt 1 – Starten Sie Ollama im Hintergrund und überprüfen Sie, ob der Prozess nicht sofort abstürzt

Die Phase „Ollama starten“ funktioniert am besten, wenn sie als messbarer Ansatz betrachtet wird. Erfassen Sie vor Erweiterung des Umfangs ein erfolgreiches Beispiel, einen Fehlerfall sowie eine Notiz zur Rücksetzung. Betrachten Sie diese Phase als Vertrag zwischen Eingaben und validierten Ausgaben. Benennen Sie die Ergebnisdokumente, definieren Sie Erfolgskontrollen und lehnen Sie stille, unvollständige Abschlüsse ab. Fixieren Sie den Interpreter sowie die Abhängigkeitsdatei, bevor Sie den Schleifenprozess einrichten. Abweichungen zwischen Laptop und CI sind die häufigste Ursache für stille Ausfälle bei API-Demos.

ollama serve > /tmp/ollama.log 2>&1 &
OLLAMA_PID=$!

sleep 3
if ! kill -0 "$OLLAMA_PID" 2>/dev/null; then
    echo "OLLAMA FAILED TO START"
    cat /tmp/ollama.log
    exit 1
fi

Schritt 2 – Abfragen, bis die API tatsächlich Daten liefert und nicht nur läuft

Die Umfrage in Schritt 2 bis zur jeweiligen Phase funktioniert am besten, wenn sie als messbarer Indikator betrachtet wird. Erfassen Sie vor Erweiterung des Umfangs ein erfolgreiches Beispiel, einen Fehlerfall sowie eine Notiz zur Rücksetzung. Erfassen Sie außerdem die Dauer sowie die Kosten für Token oder Abfragen neben den funktionalen Ergebnissen. Eine frühzeitige Sichtbarkeit der Kosten verhindert überraschende Rechnungen, wenn der Prozess von einer Demo in gemeinsame Umgebungen übergeht. Legen Sie Budgets für Token pro Runde und pro Sitzung fest. Agentenbasierte Tools erweitern den Kontext stark; feste Obergrenzen verhindern, dass Demos zu unerwarteten Rechnungen werden.

READY=0

for i in $(seq 1 120); do
    if curl -sf http://127.0.0.1:11434/api/tags > /dev/null 2>&1; then
        READY=1
        echo "Ollama is ready."
        break
    fi
    sleep 1
done

if [ "$READY" != "1" ]; then
    echo "Ollama failed to start."
    cat /tmp/ollama.log
    exit 1
fi

Schritt 3 – Laden Sie das Modell herunter, aber nur, wenn es noch nicht vorhanden ist

Schritt 3 – Die Phase „Pull the stage“ funktioniert am besten, wenn sie als messbare Ebene betrachtet wird. Erfassen Sie ein „goldenes Transkript“, einen Fehlerfall sowie eine Notiz zur Rücksetzung, bevor Sie den Umfang erweitern. Bewahren Sie Konfigurationen außerhalb des Anwendungscode auf. Umgebungsdateien, Geheimdatenspeicher und Feature-Flags sollten an einem Ort gesammelt sein, den Betreiber ohne das Durchlesen des gesamten Systems prüfen können. Legen Sie Budgetlimits pro Runde und pro Sitzung fest. Agentenbasierte Tools erweitern den Kontext stark; feste Obergrenzen verhindern, dass Demonstrationen zu unerwarteten Rechnungen werden.

if ollama list | grep -F "qwen3-coder" > /dev/null 2>&1; then
    echo "Model already exists:"
    ollama list
else
    echo "Downloading: qwen3-coder:30b"
    ollama pull "qwen3-coder:30b"
fi

Schritt 3 – Die Phase „Pull the stage“ funktioniert am besten, wenn sie als messbare Ebene betrachtet wird. Erfassen Sie ein „goldenes Transkript“, einen Fehlerfall sowie eine Notiz zur Rücksetzung, bevor Sie den Umfang erweitern. Ziehen Sie kleine, testbare Einheiten vor umfangreichen Skripten vor. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortung verweisen und nicht auf einen verworrenen Ablauf.

Schritt 4 – Klonen Sie das Repository mit einem echten Fehlerweg

Zur Schritt-4-Klonierung der Phase sollten vor dem Ändern des Codes die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Betrachten Sie diese Phase als Vertrag zwischen den Eingaben und den validierten Ausgaben. Benennen Sie die Artefakte, definieren Sie Erfolgskontrollen und lehnen Sie stille, unvollständige Abschlüsse ab. Wählen Sie bei dem nächsten Schritt, der aus Code oder einem Toolaufruf besteht, strukturierte Ausgaben mit Schema-Validierung vor freiformiger Prosa.

if [ ! -d /workspace/.git ]; then
    if GIT_TERMINAL_PROMPT=0 git clone \
        --branch "main" \
        --depth 1 \
        "https://github.com/yourname/yourrepo.git" \
        /workspace
    then
        echo "Clone succeeded."
    else
        echo "WARNING: git clone failed. Continuing without the repo."
        mkdir -p /workspace
    fi
else
    echo "Repository already exists."
fi

Schritt 5 – Konfiguration von OpenCode schreiben

In der Phase „Schritt 5: OpenCode schreiben“ sollten die Eingabedaten, der Verantwortliche für den Schritt sowie die Abbruchkriterien definiert werden, bevor der Code geändert wird. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Zeiten sowie Kosten für Token oder Abfragen sollten neben den funktionalen Ergebnissen aufgezeichnet werden. Eine frühzeitige Sichtbarkeit der Kosten verhindert überraschende Rechnungen, wenn der Ablauf von einer Demo-Umgebung in eine gemeinsam genutzte Umgebung wechselt. Bei dem nächsten Schritt, der entweder die Erstellung von Code oder einen Aufruf einer Tool beinhaltet, sollten strukturierte Ausgaben mit Schema-Validierung Vorrang vor freiformigen Texten haben.

mkdir -p /root/.config/opencode
cat > /root/.config/opencode/opencode.json <<'EOF'
{
    "$schema": "https://opencode.ai/config.json",
    "model": "ollama/qwen3-coder:30b",
    "provider": {
        "ollama": {
            "npm": "@ai-sdk/openai-compatible",
            "name": "Ollama - Qwen3 Coder 30B",
            "options": {
                "baseURL": "http://127.0.0.1:11434/v1"
            },
            "models": {
                "qwen3-coder:30b": {
                    "name": "Qwen3-Coder 30B",
                    "limit": {
                        "context": 32768,
                        "output": 16384
                    }
                }
            }
        }
    }
}
EOF

Schritt 6 – OpenCode im Vordergrund starten

Für die Startphase OpenCode im Schritt 6 sollten Eingabedaten, der Verantwortliche für den Schritt sowie die Abbruchkriterien vor dem Ändern des Codes definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Die Konfiguration sollte außerhalb des Anwendungscode gespeichert werden. Umgebungsdateien, Geheimdatenspeicher sowie Feature-Flags sollten an einem Ort zusammengefasst sein, den die Operator überprüfen können, ohne den gesamten Codeverlauf durchlesen zu müssen. Wählen Sie bei dem nächsten Schritt, der ein Codeabschnitt oder einen Toolaufruf ist, strukturierte Ausgaben mit Schema-Validierung vor.

exec opencode serve \
    --hostname 0.0.0.0 \
    --port 4096 \
    --print-logs

Für die Startphase OpenCode im Schritt 6 sollten Eingabedaten, der Verantwortliche für den Schritt sowie die Abbruchkriterien vor dem Codeändern definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Es ist besser, kleine, testbare Einheiten statt umfangreicher Skripte zu verwenden. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortung verweisen und nicht auf ein verworrenes Ablaufverfahren.

Aufbewahrung der Modellgewichte

Beim Arbeiten in der Phase der Beibehaltung der Modellgewichte sollten Sie zunächst einen Vertrag aufschreiben: erforderliche Eingaben, Erfolgsignal sowie das Vorgehen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. Betrachten Sie diese Phase als Vertrag zwischen Eingaben und validierten Ausgaben. Benennen Sie die Erzeugnisse, definieren Sie Erfolgskontrollen und lehnen Sie stille, teilweise abgeschlossene Vorgänge ab. Cachen Sie stabile Systemanweisungen sowie Tool-Schemata. Das erneute Senden identischer Präambeln ist eine häufige Ursache für Ressourcenverschwendung.

volume = modal.Volume.from_name(
    "opencode-ollama-models",
    create_if_missing=True,
)
volumes={
    "/models": volume,
},

Erstellen des Sandboxes

Während der Phase „Erstellung des Sandboxes“ sollten Sie zunächst den Vertrag aufschreiben: erforderliche Eingaben, Erfolgsignal sowie das Vorgehen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. Notieren Sie außerdem die Laufzeiten sowie die Kosten für Tokens oder Abfragen neben den funktionalen Ergebnissen. Eine frühzeitige Sichtbarkeit der Kosten verhindert überraschende Rechnungen, wenn der Weg von einer Demo-Umgebung in gemeinsam genutzte Umgebungen wechselt. Speichern Sie stabile Systemanweisungen sowie Tool-Schemata im Cache. Das erneute Senden identischer Vorlagen ist eine häufige Ursache für unnötige Ressourcenverbrauch.

def create_sandbox():
    script = startup_script()
    secrets = []
    if GITHUB_REPO_IS_PRIVATE:
        secrets.append(modal.Secret.from_name(GITHUB_SECRET_NAME))
    sandbox = modal.Sandbox.create(
        "bash", "-lc", script,
        app=app,
        image=image,
        gpu="H100",
        cpu=8,
        memory=32768,
        secrets=secrets,
        timeout=12 * 60 * 60,
        idle_timeout=300,
        volumes={"/models": volume},
        encrypted_ports=[OPENCODE_PORT],
        workdir="/workspace",
    )
    return sandbox

Bearbeitung privater Repositorien

Beim Bearbeiten der Phase „Umgang mit privaten Repositorien“ sollte man zunächst den Vertrag aufschreiben: erforderliche Eingaben, Erfolgssignal sowie das Vorgehen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. Bewahren Sie Konfigurationen außerhalb des Anwendungscode auf. Umgebungsdateien, Geheimdatenspeicher und Feature-Flags sollten an einem Ort zusammengefasst sein, den Betreiber ohne das Durchlesen des gesamten Systems überprüfen können. Cachen Sie stabile Systemanweisungen sowie Tool-Schemata. Das erneute Senden identischer Vorlagen ist eine häufige Ursache für Ressourcenverschwendung. Beim Bearbeiten der Phase „Umgang mit privaten Repositorien“ sollte man zunächst den Vertrag aufschreiben: erforderliche Eingaben, Erfolgssignal sowie das Vorgehen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. Ziehen Sie kleine, testbare Einheiten vor großen Skripten vor. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortung verweisen und nicht auf ein verworrenes Ablaufschema.

modal secret create github-token GITHUB_TOKEN=ghp_your_token_here
if GITHUB_REPO_IS_PRIVATE:
    secrets.append(modal.Secret.from_name("github-token"))
clone_url = f"https://${{GITHUB_TOKEN}}@github.com/{GITHUB_REPO}.git"

Der lokale Eingangspunkt: Beibehaltung der Sandbox

Die Phase des lokalen Eingangspunkts funktioniert am besten, wenn sie als messbare Größe betrachtet wird. Erfassen Sie ein optimales Beispiel, einen Fehlerfall sowie eine Notiz zur Rücksetzung, bevor Sie den Umfang erweitern. Behandeln Sie diese Phase als Vertrag zwischen Eingaben und validierten Ausgaben. Benennen Sie die Ergebnisse, definieren Sie Erfolgskontrollen und lehnen Sie stille, unvollständige Abschlüsse ab. Legen Sie Budgetgrenzen pro Runde und pro Sitzung fest. Agentenbasierte Tools erweitern den Kontext oft übermäßig; feste Obergrenzen verhindern, dass Demonstrationen zu unerwarteten Rechnungen werden.

try:
    while True:
        time.sleep(5)
        returncode = sandbox.poll()
        if returncode is not None:
            print(f"Sandbox process exited with code {returncode}.")
            break
except KeyboardInterrupt:
    print("Ctrl+C received. Terminating sandbox...")
    sandbox.terminate()
modal run --detach opencode.py
modal shell sb-abc123xyz

Die vollständige Implementierung

Die vollständige Implementierung funktioniert am besten, wenn sie als messbare Oberfläche betrachtet wird. Erfassen Sie ein gelungenes Beispiel, einen Fehlerfall sowie die Notizen zum Rollback, bevor Sie den Umfang erweitern. Erfassen Sie außerdem die Laufzeiten sowie die Kosten für Tokens oder Abfragen zusammen mit den funktionalen Ergebnissen. Eine frühzeitige Sichtbarkeit der Kosten verhindert überraschende Rechnungen, wenn der Einsatzbereich von einer Demo in gemeinsame Umgebungen wechselt. Legen Sie Budgets für Tokens pro Turnus und pro Sitzung fest. Agentenbasierte Tools erweitern den Kontext stark; feste Obergrenzen verhindern, dass Demos zu unerwarteten Rechnungen werden.

import time

import modal


# ============================================================
# Configuration
# ============================================================

APP_NAME = "opencode-ollama"

MODEL = "qwen3-coder:30b"

OPENCODE_PORT = 4096
OLLAMA_PORT = 11434

VOLUME_NAME = "opencode-ollama-models"

# Set this to the repo you want cloned into the sandbox.
# Leave as None or "" to skip cloning entirely.
GITHUB_REPO = "yourusername/your-repository"
GITHUB_BRANCH = "main"

# If GITHUB_REPO is private, create a Modal Secret containing
# a GitHub Personal Access Token (fine-grained, read-only, scoped
# to this one repo) with:
#   modal secret create github-token GITHUB_TOKEN=ghp_xxx
# and set this to True.
GITHUB_REPO_IS_PRIVATE = False
GITHUB_SECRET_NAME = "github-token"


# ============================================================
# Modal app + persistent volume
# ============================================================

app = modal.App(APP_NAME)

volume = modal.Volume.from_name(
    VOLUME_NAME,
    create_if_missing=True,
)


# ============================================================
# Container image
# ============================================================

image = (
    modal.Image.from_registry(
        "nvidia/cuda:13.0.0-devel-ubuntu24.04",
        add_python="3.12",
    )
    .apt_install(
        "curl",
        "git",
        "ca-certificates",
        "zstd",
    )
    .run_commands(
        "curl -fsSL https://ollama.com/install.sh | sh",
    )
    .run_commands(
        "curl -fsSL https://opencode.ai/install | bash",
    )
    .env(
        {
            "OLLAMA_MODELS": "/models/.ollama/models",
            "OLLAMA_HOST": "127.0.0.1:11434",
            "PATH": "/root/.opencode/bin:/usr/local/bin:/usr/bin:/bin",
        }
    )
)


# ============================================================
# Sandbox startup script
# ============================================================

def startup_script():

    repo_setup = ""

    if GITHUB_REPO:

        if GITHUB_REPO_IS_PRIVATE:
            clone_url = (
                f"https://${{GITHUB_TOKEN}}@github.com/{GITHUB_REPO}.git"
            )
        else:
            clone_url = f"https://github.com/{GITHUB_REPO}.git"

        repo_setup = f"""
echo "=============================================="
echo "Cloning repository"
echo "=============================================="
nvidia-smi || true

if [ ! -d /workspace/.git ]; then

    if GIT_TERMINAL_PROMPT=0 git clone \\
        --branch "{GITHUB_BRANCH}" \\
        --depth 1 \\
        "{clone_url}" \\
        /workspace
    then
        echo "Clone succeeded."
    else
        echo ""
        echo "=============================================="
        echo "WARNING: git clone failed."
        echo "=============================================="
        echo "This is usually because the repository is"
        echo "private (set GITHUB_REPO_IS_PRIVATE = True and"
        echo "attach a token) or the repo/branch name is"
        echo "wrong. Continuing without the repo so OpenCode"
        echo "still starts."
        echo ""
        mkdir -p /workspace
    fi

else

    echo "Repository already exists."

fi
"""

    else:

        repo_setup = """
echo "=============================================="
echo "No GitHub repository configured"
echo "=============================================="

mkdir -p /workspace
"""

    return f"""
#!/bin/bash

set -e

echo "=============================================="
echo "Modal OpenCode + Ollama"
echo "=============================================="

echo "Model: {MODEL}"
echo "OpenCode port: {OPENCODE_PORT}"
echo "Ollama port: {OLLAMA_PORT}"

# ------------------------------------------------------------
# Ollama model directory
# ------------------------------------------------------------

mkdir -p /models/.ollama/models

export OLLAMA_MODELS=/models/.ollama/models
export OLLAMA_HOST=127.0.0.1:11434

# ------------------------------------------------------------
# Start Ollama
# ------------------------------------------------------------

echo ""
echo "Starting Ollama..."

ollama serve \\
    > /tmp/ollama.log \\
    2>&1 &

OLLAMA_PID=$!

sleep 3

if ! kill -0 "$OLLAMA_PID" 2>/dev/null; then
    echo ""
    echo "=============================================="
    echo "OLLAMA FAILED TO START"
    echo "=============================================="
    echo ""
    cat /tmp/ollama.log
    echo ""
    exit 1
fi

echo "Ollama PID: $OLLAMA_PID"

# ------------------------------------------------------------
# Wait for Ollama to be ready
# ------------------------------------------------------------

echo ""
echo "Waiting for Ollama..."

READY=0

for i in $(seq 1 120); do

    if curl -sf \\
        http://127.0.0.1:11434/api/tags \\
        > /dev/null 2>&1
    then

        READY=1
        echo "Ollama is ready."
        break

    fi

    sleep 1

done

if [ "$READY" != "1" ]; then

    echo ""
    echo "Ollama failed to start."
    echo ""
    cat /tmp/ollama.log

    exit 1

fi

# ------------------------------------------------------------
# Pull the model (skipped if already present in the volume)
# ------------------------------------------------------------

echo ""
echo "=============================================="
echo "Checking Ollama model"
echo "=============================================="

if ollama list | grep -F \\
    "qwen3-coder" \\
    > /dev/null 2>&1
then

    echo "Model already exists:"
    ollama list

else

    echo ""
    echo "Model not found."
    echo ""
    echo "Downloading:"
    echo "  {MODEL}"
    echo ""
    echo "This can take some time on first startup."
    echo ""

    ollama pull "{MODEL}"

fi

echo ""
echo "=============================================="
echo "Available Ollama models"
echo "=============================================="

ollama list

# ------------------------------------------------------------
# Repository
# ------------------------------------------------------------

{repo_setup}

cd /workspace

# ------------------------------------------------------------
# OpenCode configuration
# ------------------------------------------------------------

mkdir -p /root/.config/opencode

cat > /root/.config/opencode/opencode.json <<'EOF'
{{
    "$schema": "https://opencode.ai/config.json",

    "model": "ollama/{MODEL}",

    "provider": {{
        "ollama": {{
            "npm": "@ai-sdk/openai-compatible",

            "name": "Ollama - Qwen3 Coder 30B",

            "options": {{
                "baseURL": "http://127.0.0.1:11434/v1"
            }},

            "models": {{
                "{MODEL}": {{
                    "name": "Qwen3-Coder 30B",

                    "limit": {{
                        "context": 32768,
                        "output": 16384
                    }}
                }}
            }}
        }}
    }}
}}
EOF

echo ""
echo "=============================================="
echo "OpenCode configuration"
echo "=============================================="

cat /root/.config/opencode/opencode.json

# ------------------------------------------------------------
# Start OpenCode
# ------------------------------------------------------------

echo ""
echo "=============================================="
echo "Starting OpenCode server"
echo "=============================================="

exec opencode serve \\
    --hostname 0.0.0.0 \\
    --port {OPENCODE_PORT} \\
    --print-logs
"""


# ============================================================
# Create Sandbox
# ============================================================

def create_sandbox():

    script = startup_script()

    secrets = []

    if GITHUB_REPO_IS_PRIVATE:
        secrets.append(modal.Secret.from_name(GITHUB_SECRET_NAME))

    sandbox = modal.Sandbox.create(
        "bash",
        "-lc",
        script,

        app=app,

        image=image,

        gpu="H100",

        cpu=8,

        memory=32768,

        secrets=secrets,

        timeout=12 * 60 * 60,

        idle_timeout=300,

        volumes={
            "/models": volume,
        },

        encrypted_ports=[
            OPENCODE_PORT,
        ],

        workdir="/workspace",
    )

    return sandbox


# ============================================================
# Local entrypoint
# ============================================================

@app.local_entrypoint()
def main():

    print()
    print("==============================================")
    print("Creating Modal Sandbox")
    print("==============================================")
    print()

    sandbox = create_sandbox()

    print()
    print("Sandbox created:")
    print(sandbox.object_id)

    print()
    print("Waiting for OpenCode server...")
    print()

    time.sleep(5)

    tunnel_url = None

    try:

        tunnels = sandbox.tunnels()
        tunnel = tunnels[OPENCODE_PORT]
        tunnel_url = tunnel.url

        print()
        print("==============================================")
        print("OPEN CODE IS READY")
        print("==============================================")
        print()
        print("Sandbox ID (save this to reconnect):")
        print(sandbox.object_id)
        print()
        print("Browser:")
        print()
        print(tunnel_url)
        print()
        print("Your OpenCode server is backed by:")
        print()
        print("  Ollama")
        print("  Qwen3-Coder 30B")
        print()
        print("Ollama endpoint (inside the sandbox only):")
        print("http://127.0.0.1:11434")
        print()
        print("==============================================")
        print()

    except Exception as e:

        print()
        print("Sandbox started, but tunnel information")
        print("could not be retrieved automatically.")
        print()
        print(f"Error: {e}")
        print()
        print("The Sandbox ID is:")
        print(sandbox.object_id)

    print("Sandbox is running. Press Ctrl+C to stop it.")
    print("(Run with `modal run --detach opencode.py` to keep")
    print(" it alive after you disconnect.)")
    print()

    try:
        while True:
            time.sleep(5)

            returncode = sandbox.poll()

            if returncode is not None:
                print(f"Sandbox process exited with code {returncode}.")
                break

    except KeyboardInterrupt:
        print()
        print("Ctrl+C received. Terminating sandbox...")
        sandbox.terminate()
        print("Sandbox terminated.")

Ausführen

Es funktioniert am besten, wenn es als messbare Struktur betrachtet wird. Erfassen Sie ein „goldenes“ Transkript, einen Fehlerfall sowie eine Notiz zur Rücksetzung, bevor Sie den Umfang erweitern. Bewahren Sie die Konfiguration außerhalb des Anwendungscode auf. Umgebungsdateien, Geheimdatenspeicher und Feature-Flags sollten an einem Ort gesammelt sein, den Betreiber ohne das Durchlesen des gesamten Systems überprüfen können. Legen Sie Budgetlimits pro Turnus und pro Sitzung fest. Agentenbasierte Tools erweitern den Kontext oft übermäßig; feste Obergrenzen verhindern, dass Demonstrationen zu unerwarteten Rechnungen werden. Es funktioniert am besten, wenn es als messbare Struktur betrachtet wird. Erfassen Sie ein „goldenes“ Transkript, einen Fehlerfall sowie eine Notiz zur Rücksetzung, bevor Sie den Umfang erweitern. Ziehen Sie kleine, testbare Einheiten vor großen, komplexen Skripten vor. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortung verweisen und nicht auf einen verworrenen Ablauf.

modal run opencode.py
==============================================
OPEN CODE IS READY
==============================================

Sandbox ID (save this to reconnect):
sb-abc123xyz

Browser:

https://your-generated-subdomain-4096.modal.host
modal run --detach opencode.py
modal shell sb-abc123xyz
sandbox = modal.Sandbox.from_id("sb-abc123xyz")
sandbox.terminate()

Systemerweiterung

In der Phase des Systemerweiterns sollten vor dem Ändern des Codes die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Betrachten Sie diese Phase als Vertrag zwischen den Eingaben und den validierten Ausgaben. Benennen Sie die Artefakte, definieren Sie Erfolgskontrollen und lehnen Sie stille, unvollständige Abschlüsse ab. Wählen Sie bei dem nächsten Schritt, der Code oder einen Toolaufruf ist, strukturierte Ausgaben mit Schema-Validierung vor freiformiger Prosa.

Sicherheitsaspekte

In der Phase der Sicherheitsüberlegungen sollten die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien vor dem Ändern des Codes definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Zeiten sowie Kosten für Token oder Abfragen sollten neben den funktionalen Ergebnissen aufgezeichnet werden. Eine frühzeitige Sichtbarkeit der Kosten verhindert überraschende Rechnungen, wenn der Ablauf von einer Demo-Umgebung in gemeinsam genutzte Umgebungen wechselt. Bei dem nächsten Schritt, der ein Code oder einen Toolaufruf beinhaltet, sollten strukturierte Ausgaben mit Schema-Validierung Vorrang vor freiformiger Prosa haben.

Fazit

Zur Abschlussphase sollten die Eingaben, der Verantwortliche für den Schritt sowie die Beendigungskriterien vor dem Ändern des Codes definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf verborgene Zustände schließen zu müssen. Die Konfiguration sollte außerhalb des Anwendungscode gespeichert werden. Umgebungsdateien, Geheimdatenspeicher und Feature-Flags sollten an einem Ort zusammengefasst sein, den die Operator überprüfen können, ohne den gesamten Ablauf durchzulesen. Wählen Sie bei dem nächsten Schritt, der ein Codeabschnitt oder einen Toolaufruf ist, strukturierte Ausgaben mit Schema-Validierung statt freier Prosa. Zur Abschlussphase sollten die Eingaben, der Verantwortliche für den Schritt sowie die Beendigungskriterien vor dem Ändern des Codes definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf verborgene Zustände schließen zu müssen. Wählen Sie kleine, testbare Einheiten statt umfangreicher Skripte. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortung verweisen und nicht auf einen verworrenen Ablauf.

Operative Kontrollliste

Zur Phase der Betriebskontrollliste sollten die Eingaben, der Verantwortliche für den Schritt sowie die Beendigungskriterien vor dem Codeändern definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen.

Dokumentieren Sie den erfolgreichen Ablauf sowie den Notfallweg gemeinsam. Wiederholte Versuche, menschliche Überprüfungen und die Handhabung von Fehlern gehören zum Produkt selbst, nicht zu späteren Optimierungen.

Wählen Sie bei dem nächsten Schritt, der ein Code-Ausführung oder eine Toolaufruf ist, strukturierte Ausgaben mit Schema-Validierung vor freien Textbeschreibungen.

Führen Sie Checkpoints nach aufwändigen Schritten durch. Das Wiederaufnehmen sollte keine erneute Gebührenerhebung für denselben LLM-Aufruf veranlassen, wenn ein Operator einen späteren Knoten erneut ausführt.

Pinnen Sie Abhängigkeitsversionen und dokumentieren Sie den Image-Digest, mit dem die Demo ausgeführt wurde. Reproduzierbarkeit ist besser als „stammesbezogenes Wissen“.

Erhalten Sie Aufzeichnungen der Laufzeiten sowie der Kosten für Token oder Abfragen neben den funktionalen Ergebnissen. Eine frühzeitige Sichtbarkeit der Kosten verhindert überraschende Rechnungen, wenn sich der Einsatzbereich von einer Demo in gemeinsame Umgebungen verschiebt.

Vor der Einführung des Stack sollten Sie Versionen einfrieren, ein „goldenes“ Transkript für den kritischen Weg erstellen und die Schritte zum Rollback bestätigen. Gemeinsame Umgebungen erfordern Rate Limits, Überprüfungen der Nutzungsrechte sowie einen klaren Verantwortlichen für die Rotation von Geheimnissen. Wählen Sie langweilige Zuverlässigkeit statt cleverer, einmaliger Demos.

Batch-Hinweis für 0b5d2687b03c: Halten Sie die Schlüssel des Anbieters außerhalb des Repositories, legen Sie eine Obergrenze für Token pro Sitzung fest und speichern Sie die Transkripte neben den Evaluierungs-Dateien, damit spätere Modellwechsel vergleichbar bleiben.

Für die Stufe 0 der Verstärkungsmaßnahmen sollten vor dem Ändern des Codes die Eingabedaten, der Verantwortliche für den Schritt sowie die Abbruchkriterien definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Die Konfiguration sollte außerhalb des Anwendungscode gespeichert werden. Umgebungsdateien, Geheimdatenspeicher sowie Feature-Flags sollten an einem Ort zusammengefasst sein, den die Operator überprüfen können, ohne den gesamten Codeverlauf durchlesen zu müssen.

Detail der Verstärkungsmaßnahme 0/810: Messen Sie für diese Maßnahme die Ausführungsdauer, die Fehlerklasse sowie den Tokenverbrauch und entscheiden Sie anschließend auf der Grundlage eines festgelegten Fragekatalogs – und nicht aufgrund von Einzelfällen –, ob die Änderung beibehalten werden soll.

Beim Bearbeiten der ersten Stufe der Sicherheitsstärkung sollten Sie zunächst den Ablaufplan aufschreiben: erforderliche Eingaben, Erfolgsindikatoren sowie das Vorgehen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. Ziehen Sie kleine, testbare Einheiten vor großen Skripten vor. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortungsbereich verweisen und nicht auf ein verworrenes Ablaufschema.

Sicherheitsstärkungsdetail 1/810: Messen Sie die Ausführungszeit, die Fehlerklasse sowie den Tokenverbrauch für diese Anweisung und entscheiden Sie anschließend auf der Grundlage eines festgelegten Fragekatalogs – und nicht nur aufgrund von Einzelfällen –, ob die Änderung beibehalten werden soll.

Sicherheitsstärkungshinweis 2 funktioniert am besten, wenn er als messbarer Bereich betrachtet wird. Erfassen Sie vor der Erweiterung des Umfangs ein „goldenes“ Transkript, einen Fehlfall sowie eine Notiz zur Rücksetzung. Notieren Sie neben den funktionalen Ergebnissen auch die Ausführungszeiten sowie die Kosten für Tokens oder Abfragen. Eine frühzeitige Sichtbarkeit der Kosten verhindert überraschende Rechnungen, wenn der Ablauf von einer Demo in gemeinsame Umgebungen übergeht.

Verstärkungsmaßnahme Detail 2/810: Messen Sie die Ausführungsdauer, die Fehlerklasse sowie den Tokenverbrauch für diese Notiz und entscheiden Sie anschließend auf der Grundlage eines festgelegten Fragebogens statt aufgrund von Einzelfällen, ob die Änderung beibehalten werden soll.

Für die dritte Phase der Verstärkungsmaßnahme sollten vor dem Ändern des Codes die Eingabedaten, der Verantwortliche für den Schritt sowie die Abschlusskriterien definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Dokumentieren Sie sowohl den erfolgreichen Ablauf als auch den Notfallfall gemeinsam. Wiederholungsversuche, menschliche Überprüfungen sowie die Handhabung von Fehlern gehören zum Produkt selbst und nicht zu späteren Optimierungen.

Verstärkungsmaßnahme Detail 3/810: Messen Sie die Ausführungsdauer, die Fehlerklasse sowie den Tokenverbrauch für diese Notiz und entscheiden Sie anschließend auf der Grundlage eines festgelegten Fragebogens statt aufgrund von Einzelfällen, ob die Änderung beibehalten werden soll.

Beim Bearbeiten der Stufe 4 zur Sicherheitsstärkung sollten Sie zunächst einen Vertrag aufschreiben: erforderliche Eingaben, Erfolgsindikatoren sowie das Vorgehen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. Betrachten Sie diese Stufe als Vertrag zwischen Eingaben und validierten Ausgaben. Benennen Sie die relevanten Artefakte, definieren Sie Erfolgskontrollen und lehnen Sie stille, teilweise abgeschlossene Änderungen ab.

Sicherheitsdetail 4/810: Messen Sie die Ausführungsdauer, die Fehlerklasse sowie den Tokenverbrauch für diese Anweisung und entscheiden Sie anschließend auf der Grundlage eines festgelegten Fragekatalogs – und nicht nur aufgrund von Einzelfällen –, ob die Änderung beibehalten werden soll.

Die Sicherheitsanweisung 5 funktioniert am besten, wenn sie als messbarer Bereich betrachtet wird. Erfassen Sie vor der Erweiterung des Umfangs ein „goldenes Transkript“, einen Fehlerfall sowie eine Notiz zur Rücksetzung. Bewahren Sie Konfigurationen außerhalb des Anwendungscode auf. Umgebungsdateien, Geheimdatenspeicher und Feature-Flags sollten an einem Ort gesammelt werden, den Betreiber ohne das Durchlesen des gesamten Systems prüfen können.

Verstärkungsmaßnahme Detail 5/810: Messen Sie die Ausführungsdauer, die Fehlerklasse sowie den Tokenverbrauch für diese Notiz und entscheiden Sie anschließend auf der Grundlage eines festgelegten Fragebogens statt aufgrund von Einzelfällen, ob die Änderung beibehalten werden soll.

Für die 6. Stufe der Verstärkungsmaßnahme sollten vor dem Ändern des Codes die Eingabedaten, der Verantwortliche für den Schritt sowie die Abschlusskriterien definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Bevorzugen Sie kleine, testbare Einheiten vor umfangreichen Skripten. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzelne Verantwortung verweisen und nicht auf ein verworrenes Ablaufverfahren.

Verstärkungsmaßnahme Detail 6/810: Messen Sie die Ausführungsdauer, die Fehlerklasse sowie den Tokenverbrauch für diese Notiz und entscheiden Sie anschließend auf der Grundlage eines festgelegten Fragebogens statt aufgrund von Einzelfällen, ob die Änderung beibehalten werden soll.

Beim Bearbeiten der Stufe 7 der Sicherheitsstärkung sollten Sie zunächst den Ablaufplan aufschreiben: erforderliche Eingaben, Erfolgsindikatoren sowie das Vorgehen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. Notieren Sie außerdem die Laufzeiten sowie die Kosten für Tokens oder Abfragen neben den funktionalen Ergebnissen. Eine frühzeitige Sichtbarkeit der Kosten verhindert überraschende Rechnungen, wenn der Prozess von einer Demo-Umgebung in gemeinsam genutzte Umgebungen übergeht.

Sicherheitsstärkungsdetail 7/810: Messen Sie für diese Stufe die Gesamtlaufzeit, die Fehlerklasse sowie den Tokenverbrauch und entscheiden Sie anschließend anhand eines festgelegten Fragekatalogs statt aufgrund von Einzelfallbeobachtungen, ob die Änderung beibehalten werden soll.

Sicherheitsstärkungshinweis 8 funktioniert am besten, wenn er als messbarer Bereich betrachtet wird. Erfassen Sie vor der Erweiterung des Umfangs ein „goldenes“ Transkript, einen Fehlfall sowie eine Notiz zur Rücksetzung. Dokumentieren Sie gemeinsam den erfolgreichen Ablauf sowie den Wiederherstellungsprozess. Versuche, menschliche Kontrollpunkte und die Handhabung von Fehlern gehören zum Produkt selbst und nicht zu späteren Optimierungen.

Verstärkungsmerkmal 8/810: Messen Sie die Wall-Time, die Fehlerklasse sowie den Tokenverbrauch für diese Notiz und entscheiden Sie anschließend auf der Grundlage eines festgelegten Fragebogens statt aufgrund von Einzelbeobachtungen, ob die Änderung beibehalten werden soll.

Überarbeitungsmarke 1 für 0b5d2687b03c: Formulieren Sie die umliegenden Aussagen in Operator-Sprache um, lassen Sie die [[CODE_n]]-Felder unverändert und vermeiden Sie das Wiederholen von Ausgangssätzen.

Überarbeitungsmarke 2 für 0b5d2687b03c: Formulieren Sie die umliegenden Aussagen in Operator-Sprache um, lassen Sie die [[CODE_n]]-Felder unverändert und vermeiden Sie das Wiederholen von Ausgangssätzen.

Überarbeitungsmarke 3 für 0b5d2687b03c: Formulieren Sie die umliegenden Aussagen in Operator-Sprache um, lassen Sie die [[CODE_n]]-Felder unverändert und vermeiden Sie das Wiederholen von Ausgangssätzen.

Überarbeitungsmarke 4 für 0b5d2687b03c: Formulieren Sie die umliegenden Aussagen in Operator-Sprache um, lassen Sie die [[CODE_n]]-Felder unverändert und vermeiden Sie das Wiederholen von Ausgangssätzen.

Überschreiben Sie Marker 5 für 0b5d2687b03c: Formulieren Sie die umliegenden Aussagen in Operator-Sprache um, lassen Sie die [[CODE_n]]-Felder unverändert und vermeiden Sie das Wiederholen der Quellsätze.

Überschreiben Sie Marker 6 für 0b5d2687b03c: Formulieren Sie die umliegenden Aussagen in Operator-Sprache um, lassen Sie die [[CODE_n]]-Felder unverändert und vermeiden Sie das Wiederholen der Quellsätze.

Überschreiben Sie Marker 7 für 0b5d2687b03c: Formulieren Sie die umliegenden Aussagen in Operator-Sprache um, lassen Sie die [[CODE_n]]-Felder unverändert und vermeiden Sie das Wiederholen der Quellsätze.

Überschreiben Sie Marker 8 für 0b5d2687b03c: Formulieren Sie die umliegenden Aussagen in Operator-Sprache um, lassen Sie die [[CODE_n]]-Felder unverändert und vermeiden Sie das Wiederholen der Quellsätze.

Überschreiben Sie Marker 9 für 0b5d2687b03c: Formulieren Sie die umliegenden Aussagen in Operator-Sprache um, lassen Sie die [[CODE_n]]-Felder unverändert und vermeiden Sie das Wiederholen der Quellsätze.

Überschreiben Sie den Markierer 10 für 0b5d2687b03c: Formulieren Sie die umliegenden Angaben in Operator-Sprache um, lassen Sie die [[CODE_n]]-Felder unverändert und vermeiden Sie das Wiederholen der Quellsätze.