命令行代码执行器#
命令行代码执行是最简单的代码执行形式。 一般来说,它会将每个代码块保存到文件中然后执行该文件。 这意味着每个代码块都在新进程中执行。这种执行器有两种形式:
Docker (
DockerCommandLineCodeExecutor
) - 所有命令都在Docker容器中执行本地 (
LocalCommandLineCodeExecutor
) - 所有命令都在主机上执行
Docker#
备注
使用 DockerCommandLineCodeExecutor
前,请确保已安装 autogen-ext[docker]
包。详情请参阅包文档。
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外Docker"模式,即将Docker套接字挂载到主AutoGen容器,使其可以在主机上生成和控制"兄弟"容器。这比"Docker中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')
如我们所见,代码已成功执行,安装过程被隔离到新创建的虚拟环境中,未影响我们的全局环境。