代码执行
💡我们已将
container模式设为代码执行的默认选项,特别是当智能体的使用面向不可信用户时。请参阅Docker安全指南以更好地理解Docker的安全特性。若需选择local模式,您需要显式地在taskweaver_config.json文件中将execution_service.kernel_mode参数设置为local。
TaskWeaver是一个代码优先的智能体框架,这意味着它总是将用户请求转换为代码并通过执行代码来生成响应。在当前实现中,我们使用Jupyter Kernel来执行代码。选择Jupyter Kernel是因为它是交互式计算的成熟工具,并且支持多种编程语言。
代码执行的两种模式
TaskWeaver支持两种代码执行模式:local和container。
container模式是默认模式。这两种模式的关键区别在于,container模式
在Docker容器内执行代码,为代码执行提供了更安全的环境,而
local模式将代码作为TaskWeaver进程的子进程执行。
因此,在local模式下,如果用户怀有恶意意图,用户可能
指示TaskWeaver在主机上执行有害代码。此外,LLM也可能生成
有害代码,导致潜在的安全风险。
在使用local模式时请务必谨慎,特别是当智能体的使用对不受信任的用户开放时。
如何配置代码执行模式
要配置代码执行模式,您需要在taskweaver_config.json文件中设置execution_service.kernel_mode参数。该参数的值可以是local或container,默认值为container。
TaskWeaver支持local模式,无需任何额外设置。但若要使用container模式,需满足以下先决条件:
- 主机上已安装Docker。
- 主机上已构建并准备好用于代码执行的Docker镜像。
- 在
taskweaver_config.json文件中,execution_service.kernel_mode参数被设置为container。
将代码仓库克隆到本地机器后,您可以通过在代码仓库的根目录下运行以下命令来构建Docker镜像:
cd scripts
# based on your OS
./build_executor.ps1 # for Windows
./build_executor.sh # for Linux or macOS
Docker镜像构建完成后,您可以运行docker images命令检查是否存在名为taskweavercontainers/taskweaver-executor的Docker镜像。
如果满足前提条件,您现在可以在container模式下运行TaskWeaver。
在container模式下运行TaskWeaver后,您可以通过运行docker ps来检查容器是否正在运行。
在执行一些代码后,您应该会看到一个使用taskweavercontainers/taskweaver-executor镜像的容器正在运行。
如何为代码执行定制Docker镜像
您可能需要自定义代码执行的Docker镜像以包含额外的包或库,特别是针对您开发的插件。当前用于代码执行的Docker镜像仅包含TaskWeaver/requirements.txt文件中指定的依赖项。要自定义Docker镜像,您需要修改位于TaskWeaver/docker/ces_container/Dockerfile的Dockerfile并重新构建Docker镜像。
当你打开Dockerfile文件时,会看到以下内容,你可以通过添加相应的RUN命令来安装额外的软件包或库。在这个示例中,我们将sentence-transformers包添加到了Docker镜像中。
FROM python:3.10-slim
...
# TODO: Install additional packages for plugins
RUN pip install --no-cache-dir --no-warn-script-location --user sentence-transformers
...
然后,您需要根据操作系统运行TaskWeaver/scripts/build_executor.sh目录下的build_executor.sh脚本
或TaskWeaver/scripts/build.ps1来重新构建Docker镜像。
cd TaskWeaver/scripts
./build_executor.sh
# or ./build_executor.ps1 if you are using Windows
如果您已成功重建Docker镜像,可以通过运行docker images命令查看新镜像。
构建完Docker镜像后,您需要重启TaskWeaver智能体才能使用新的Docker镜像。
container 模式的限制
container模式比local模式更安全,但也有一些限制:
container模式的启动时间比local模式长,因为它需要启动一个Docker容器。- 由于Jupyter内核运行在Docker容器内,它对宿主机的访问权限有限。我们将
project/workspace/sessions/目录映射到容器中,因此容器内执行的代码可以访问其中的文件。这意味着用户不能要求智能体从宿主机加载文件,因为该文件在容器中不可用。用户需要通过控制台的/upload命令或网页界面中的upload按钮上传文件。 - 我们已在Docker镜像中安装了运行Jupyter Kernel所需的软件包。如果用户需要使用Docker镜像中未提供的软件包,需要将该软件包添加到Dockerfile(位于
TaskWeaver/ces_container/Dockerfile)并重新构建Docker镜像。
限制Docker容器的外部网络访问
在某些情况下,智能体开发者可能希望限制Docker容器对外部网络(如互联网)的访问权限。换句话说,开发者仅希望在容器内运行代码,但不允许插件或生成的代码访问互联网。
以下方法是一种常见的限制Docker容器访问互联网的方式,同时仍允许特定端口的入站连接:
-
Creating a Docker network with
enable_ip_masqueradeset to false:By default, Docker uses IP masquerading (a form of network address translation or NAT) to allow containers to communicate with external networks with the source IP address being the host IP address. When you set
enable_ip_masqueradeto false for a custom Docker network, you prevent containers on that network from having their IP addresses masqueraded, effectively blocking them from accessing the internet. To create such a network in Docker, you would use the following command:docker network create --opt com.docker.network.bridge.enable_ip_masquerade=false my_non_internet_networkAny container connected to
my_non_internet_networkwill not have internet access due to the disabled IP masquerade.
Now, you can rundocker network inspect my_non_internet_networkand you will see an output similar to the following:
"Config": [
{
"Subnet": "172.19.0.0/16",
"Gateway": "172.19.0.1"
}
]This shows the subnet of the docker network, all containers connected to this network will have an IP address in this subnet.
-
在主机防火墙设置规则或使用iptables:
此步骤涉及设置规则以阻止来自Docker网络子网到任何外部地址的出站流量。这增加了额外的安全层,确保即使IP伪装被意外启用或容器找到其他路由,流量仍将被阻止。
-
在Linux主机上使用iptables时,您可以添加如下规则:
iptables -I FORWARD -s <docker_network_subnet> -j DROP请将
替换为您Docker网络实际使用的子网。 在前面的示例中,子网是172.19.0.0/16。该规则会丢弃来自该子网的所有转发流量。 -
在Windows主机上,您需要在Windows防火墙中创建类似的规则来阻止来自Docker网络子网的出站流量。
-
请记住,如果您了解其影响并有特定需求需要将容器与互联网隔离,这种方法可被视为良好实践。 然而,如果管理不当,它也可能使网络故障排除和容器通信复杂化。 在将这些配置应用到生产系统之前,请务必确保在安全环境中进行测试。