命令行代码执行器#

命令行代码执行是最简单的代码执行形式。一般来说,它会将每个代码块保存到一个文件,然后执行该文件。这意味着每个代码块都在一个新进程中执行。这种执行器有两种形式:

Docker#

注意

要使用 DockerCommandLineCodeExecutor,请确保安装了 autogen-ext[docker] 包。有关更多详细信息,请参阅软件包文档

DockerCommandLineCodeExecutor 将创建一个 Docker 容器并在该容器内运行所有命令。使用的默认镜像为 python:3-slim,可以通过将 image 参数传递给构造函数进行自定义。 如果在本地找不到该镜像,则该类将尝试拉取它。 因此,在本地构建镜像就足够了。 该镜像要与执行器兼容,唯一的要求是安装了 shpython。 因此,创建自定义镜像是确保所需系统依赖项可用的简单有效方法。

您可以将执行器用作上下文管理器,以确保在使用后清理容器。 否则,将在程序退出时使用 atexit 模块停止容器。

检查容器#

如果您希望在 AutoGen 完成使用后保留容器(例如,检查容器),则可以在创建执行器时将 auto_remove 参数设置为 False。 也可以将 stop_container 设置为 False,以防止在执行结束时停止容器。

示例#

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')

将 Docker 中的应用程序与基于 Docker 的执行器结合使用#

最好将您的应用程序捆绑到 Docker 镜像中。 但是,如何允许容器化的应用程序在另一个容器中执行代码?

推荐的方法称为“Docker out of Docker”,其中 Docker 套接字已挂载到主 AutoGen 容器,以便它可以生成和控制主机上的“同级”容器。 这比所谓的“Docker in Docker”更好,后者是主容器运行 Docker 守护程序并在自身内部生成容器。 您可以在此处阅读有关此内容的更多信息。

为此,您需要将 Docker 套接字挂载到运行您的应用程序的容器中。 可以通过将以下内容添加到 docker run 命令中来完成此操作

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

这将允许您的应用程序的容器生成和控制主机上的同级容器。

如果您需要将工作目录绑定到应用程序的容器,但该目录属于您的主机,请使用 bind_dir 参数。 这将允许应用程序的容器将主机目录绑定到新生成的容器,并允许它访问所述目录中的文件。 如果未指定 bind_dir,它将回退到 work_dir

本地#

注意

本地版本将在您的本地系统上运行代码。谨慎使用。

要在主机(即运行您的应用程序的机器)上执行代码,可以使用 LocalCommandLineCodeExecutor

示例#

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')

虚拟环境中的本地#

如果您希望代码在作为应用程序设置一部分创建的虚拟环境中运行,您可以为新创建的环境指定一个目录,并将其上下文传递给 LocalCommandLineCodeExecutor。此设置允许执行器在整个应用程序的生命周期中始终如一地使用指定的虚拟环境,从而确保隔离的依赖项和受控的运行时环境。

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')

正如我们所看到的,代码已成功执行,并且安装已隔离到新创建的虚拟环境,而没有影响我们的全局环境。