命令行代码执行器#
命令行代码执行是最简单的代码执行形式。 一般来说,它会将每个代码块保存到一个文件中,然后执行该文件。 这意味着每个代码块都在一个新进程中执行。这种执行器有两种形式:
Docker (
DockerCommandLineCodeExecutor) - 所有命令都在Docker容器中执行本地 (
LocalCommandLineCodeExecutor) - 这是所有命令在主机上执行的地方
Docker#
注意
要使用 DockerCommandLineCodeExecutor,请确保安装了 autogen-ext[docker] 包。更多详情,请参见 Packages Documentation。
DockerCommandLineCodeExecutor 将创建一个 Docker 容器并在该容器中运行所有命令。
默认使用的镜像是 python:3-slim,可以通过向构造函数传递 image 参数来自定义。
如果本地找不到该镜像,该类将尝试拉取它。
因此,本地构建该镜像就足够了。该镜像与执行器兼容的唯一要求是安装了 sh 和 python。
因此,创建自定义镜像是确保所需系统依赖项可用的简单有效方法。
你可以使用执行器作为上下文管理器,以确保在使用后容器被清理干净。否则,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')
正如我们所看到的,代码已成功执行,安装已隔离到新创建的虚拟环境中,没有影响我们的全局环境。