Befehlszeilen-Code-Executor#

Die Ausführung von Code über die Befehlszeile ist die einfachste Form der Code-Ausführung. Im Allgemeinen wird jeder Codeblock in einer Datei gespeichert und diese Datei dann ausgeführt. Das bedeutet, dass jeder Codeblock in einem neuen Prozess ausgeführt wird. Es gibt zwei Formen dieses Executors

Docker#

Hinweis

Um DockerCommandLineCodeExecutor zu verwenden, stellen Sie sicher, dass das Paket autogen-ext[docker] installiert ist. Weitere Details finden Sie in der Paketdokumentation.

Der DockerCommandLineCodeExecutor erstellt einen Docker-Container und führt alle Befehle innerhalb dieses Containers aus. Das standardmäßig verwendete Image ist python:3-slim. Dies kann durch Übergabe des Parameters image an den Konstruktor angepasst werden. Wenn das Image lokal nicht gefunden wird, versucht die Klasse, es herunterzuladen. Daher ist es ausreichend, wenn das Image lokal erstellt wurde. Das Einzige, was dieses Image mit dem Executor kompatibel macht, ist die Installation von sh und python. Daher ist die Erstellung eines benutzerdefinierten Images eine einfache und effektive Möglichkeit, die Verfügbarkeit erforderlicher Systemabhängigkeiten sicherzustellen.

Sie können den Executor als Kontextmanager verwenden, um sicherzustellen, dass der Container nach Gebrauch bereinigt wird. Andernfalls wird das Modul atexit verwendet, um den Container zu stoppen, wenn das Programm beendet wird.

Inspektion des Containers#

Wenn Sie den Container behalten möchten, nachdem AutoGen ihn aus irgendeinem Grund nicht mehr verwendet (z. B. zur Inspektion des Containers), können Sie den Parameter auto_remove beim Erstellen des Executors auf False setzen. stop_container kann ebenfalls auf False gesetzt werden, um zu verhindern, dass der Container am Ende der Ausführung gestoppt wird.

Beispiel#

from pathlib import Path

from autogen_core import CancellationToken
from autogen_core.code_executor import CodeBlock
from autogen_ext.code_executors.docker import DockerCommandLineCodeExecutor

work_dir = Path("coding")
work_dir.mkdir(exist_ok=True)

async with DockerCommandLineCodeExecutor(work_dir=work_dir) as executor:  # type: ignore
    print(
        await executor.execute_code_blocks(
            code_blocks=[
                CodeBlock(language="python", code="print('Hello, World!')"),
            ],
            cancellation_token=CancellationToken(),
        )
    )
CommandLineCodeResult(exit_code=0, output='Hello, World!\n', code_file='coding/tmp_code_07da107bb575cc4e02b0e1d6d99cc204.python')

Kombinieren einer Anwendung in Docker mit einem Docker-basierten Executor#

Es ist wünschenswert, Ihre Anwendung in ein Docker-Image zu bündeln. Aber wie erlauben Sie dann Ihrer containerisierten Anwendung, Code in einem anderen Container auszuführen?

Der empfohlene Ansatz dafür ist "Docker out of Docker", bei dem der Docker-Socket an den Haupt-AutoGen-Container angehängt wird, sodass dieser "Geschwister"-Container auf dem Host starten und steuern kann. Dies ist besser als "Docker in Docker", bei dem der Hauptcontainer einen Docker-Daemon ausführt und Container innerhalb von sich selbst startet. Sie können hier mehr darüber lesen hier.

Um dies zu tun, müssten Sie den Docker-Socket in den Container einhängen, der Ihre Anwendung ausführt. Dies kann durch Hinzufügen des Folgenden zum Befehl docker run erreicht werden

-v /var/run/docker.sock:/var/run/docker.sock

Dies ermöglicht es dem Container Ihrer Anwendung, Geschwister-Container auf dem Host zu starten und zu steuern.

Wenn Sie ein Arbeitsverzeichnis an den Container der Anwendung binden müssen, das Verzeichnis aber zu Ihrem Host-Computer gehört, verwenden Sie den Parameter bind_dir. Dies ermöglicht es dem Container der Anwendung, das Host-Verzeichnis an die neu gestarteten Container zu binden und den Zugriff auf die Dateien innerhalb des besagten Verzeichnisses zu ermöglichen. Wenn bind_dir nicht angegeben ist, wird auf work_dir zurückgegriffen.

Lokal#

Achtung

Die lokale Version führt Code auf Ihrem lokalen System aus. Verwenden Sie sie mit Vorsicht.

Um Code auf dem Host-Computer, d. h. auf dem Computer, auf dem Ihre Anwendung läuft, auszuführen, kann LocalCommandLineCodeExecutor verwendet werden.

Beispiel#

from pathlib import Path

from autogen_core import CancellationToken
from autogen_core.code_executor import CodeBlock
from autogen_ext.code_executors.local import LocalCommandLineCodeExecutor

work_dir = Path("coding")
work_dir.mkdir(exist_ok=True)

local_executor = LocalCommandLineCodeExecutor(work_dir=work_dir)
print(
    await local_executor.execute_code_blocks(
        code_blocks=[
            CodeBlock(language="python", code="print('Hello, World!')"),
        ],
        cancellation_token=CancellationToken(),
    )
)
CommandLineCodeResult(exit_code=0, output='Hello, World!\n', code_file='/home/ekzhu/agnext/python/packages/autogen-core/docs/src/guides/coding/tmp_code_07da107bb575cc4e02b0e1d6d99cc204.py')

Lokal in einer virtuellen Umgebung#

Wenn der Code innerhalb einer virtuellen Umgebung ausgeführt werden soll, die als Teil des Anwendungs-Setups erstellt wurde, können Sie ein Verzeichnis für die neu erstellte Umgebung angeben und dessen Kontext an LocalCommandLineCodeExecutor übergeben. Dieses Setup ermöglicht es dem Executor, die angegebene virtuelle Umgebung konsistent während der gesamten Lebensdauer der Anwendung zu nutzen und so isolierte Abhängigkeiten und eine kontrollierte Laufzeitumgebung zu gewährleisten.

import venv
from pathlib import Path

from autogen_core import CancellationToken
from autogen_core.code_executor import CodeBlock
from autogen_ext.code_executors.local import LocalCommandLineCodeExecutor

work_dir = Path("coding")
work_dir.mkdir(exist_ok=True)

venv_dir = work_dir / ".venv"
venv_builder = venv.EnvBuilder(with_pip=True)
venv_builder.create(venv_dir)
venv_context = venv_builder.ensure_directories(venv_dir)

local_executor = LocalCommandLineCodeExecutor(work_dir=work_dir, virtual_env_context=venv_context)
await local_executor.execute_code_blocks(
    code_blocks=[
        CodeBlock(language="bash", code="pip install matplotlib"),
    ],
    cancellation_token=CancellationToken(),
)
CommandLineCodeResult(exit_code=0, output='', code_file='/Users/gziz/Dev/autogen/python/packages/autogen-core/docs/src/user-guide/core-user-guide/framework/coding/tmp_code_d2a7db48799db3cc785156a11a38822a45c19f3956f02ec69b92e4169ecbf2ca.bash')

Wie wir sehen, wurde der Code erfolgreich ausgeführt und die Installation wurde auf die neu erstellte virtuelle Umgebung isoliert, ohne unsere globale Umgebung zu beeinträchtigen.