命令行代码执行器#

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

Docker#

注意

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

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

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

检查容器#

如果您希望在 AutoGen 使用完容器后出于任何原因(例如检查容器)保留容器,那么您可以在创建执行器时将 auto_remove 参数设置为 Falsestop_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')

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