在 AI 安全领域,一个高仿真的测试环境是验证防御策略的基石。最近,我找到了一个名为 ai-fail-lab 的 AI 安全靶场。该项目基于 FastAPIUvicorn 构建,采用 Docker Compose 进行容器化部署,旨在模拟各类 AI 模型的潜在安全风险。

然而,在将项目部署到本地却并不是件易事,我捣鼓了快一个小时。这篇文章详细记录了 AI 安全靶场项目 ai-fail-lab 的完整安装部署步骤,涵盖环境准备、依赖配置、容器构建、服务启动及常见问题排查,帮助大家快速搭建并运行该靶场环境。


项目地址

1
https://github.com/Landjun/ai-fail-lab

环境准备

安装 Docker

Ubuntu/Debian 系统安装示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 更新包索引
sudo apt-get update

# 安装依赖
sudo apt-get install -y ca-certificates curl gnupg

# 添加 Docker 官方 GPG 密钥
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

# 添加 Docker 仓库
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list

# 安装 Docker
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io

# 验证安装
docker --version

启动并设置开机自启:

1
2
sudo systemctl enable docker
sudo systemctl start docker

安装 Docker Compose

Docker Compose V2 已集成在 Docker Desktop 中。若为命令行环境,可手动安装:

1
2
3
4
5
# 安装 Docker Compose V2
sudo apt-get install -y docker-compose-plugin

# 验证安装
docker compose version

注意:旧版 docker-compose(V1)命令已逐渐被 docker compose(V2,无连字符)替代。这里统一使用 docker compose 命令。

确认 Python 环境(可选)

虽然项目运行在容器中,但本地安装 Python 3.11+ 有助于代码编辑和调试:

1
python3 --version

项目初始化

获取项目代码

将 ai-fail-lab 项目克隆或复制到本地工作目录:

1
2
3
4
mkdir -p ~/桌面/ai-fail-lab
cd ~/桌面/ai-fail-lab
# 如果是从 Git 仓库获取:
# git clone <仓库地址> .

项目结构概览

1
2
3
4
5
6
7
8
9
10
11
ai-fail-lab/
├── Dockerfile
├── docker-compose.yml
├── requirements.txt
├── app/
│ ├── __init__.py
│ ├── main.py # FastAPI 应用入口
│ ├── lab_engine.py # 靶场引擎
│ ├── llm_client.py # LLM 客户端(对接 OpenAI / Anthropic)
│ └── config.py # 配置模块
└── templates/ # Jinja2 模板文件

依赖配置

编写 requirements.txt

项目依赖文件 requirements.txt 必须精确锁定核心框架版本,防止 pip 自动拉取不兼容的新版本。最终稳定版本组合如下:

库名 锁定版本 说明
fastapi 0.111.0 Web 框架核心
starlette 0.37.2 FastAPI 底层 ASGI 框架
jinja2 3.1.4 模板引擎(与 Starlette 0.37.2 兼容)
uvicorn 最新版 ASGI 服务器
python-multipart 最新版 表单文件上传支持
openai 最新版 OpenAI API 客户端
anthropic 最新版 Anthropic Claude API 客户端
pydantic-settings 最新版 Pydantic 2.x 的配置管理

requirements.txt 内容:

1
2
3
4
5
6
7
8
fastapi==0.111.0
starlette==0.37.2
uvicorn
python-multipart
openai
anthropic
pydantic-settings
jinja2==3.1.4

版本锁定说明

重要:以下三个库的版本必须严格匹配,缺一不可:

  • fastapi==0.111.0
  • starlette==0.37.2
  • jinja2==3.1.4

其中 jinja2starlette 是解决 TypeError: unhashable type: 'dict' 错误的核心。Jinja2 3.1.5+ 重构了模板缓存机制,要求缓存键必须是可哈希(Hashable)的不可变对象,而 Starlette 在调用时传递了字典对象,导致类型错误。锁定上述版本组合可彻底解决此问题。


Docker Compose 配置

编写 docker-compose.yml

在项目根目录创建 docker-compose.yml 文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
services:
ai-fail-lab:
build: .
ports:
- "8000:8000"
volumes:
- ./reports:/app/reports
environment:
- DEBUG=false
- LLM_PROVIDER=${LLM_PROVIDER:-mock}
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:-}
- ANTHROPIC_MODEL=${ANTHROPIC_MODEL:-claude-haiku-4-5}
restart: unless-stopped
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"]
interval: 30s
timeout: 10s
retries: 3

配置说明:

配置项 说明
build: . 使用当前目录下的 Dockerfile 构建镜像
ports 将宿主机的 8000 端口映射到容器的 8000 端口
volumes 将宿主机的 ./reports 目录挂载到容器的 /app/reports,用于持久化报告数据
LLM_PROVIDER LLM 提供商,默认 mock(模拟模式),可改为 openaianthropic
ANTHROPIC_API_KEY Anthropic API 密钥,不设置则使用模拟响应
ANTHROPIC_MODEL 使用的 Claude 模型名称
restart: unless-stopped 容器退出后自动重启(除非手动停止)
healthcheck 健康检查,每 30 秒检测一次 /health 端点

环境变量配置

项目支持通过环境变量控制行为。可在宿主机设置以下变量:

环境变量 默认值 说明
LLM_PROVIDER mock 设置 openai 启用 OpenAI,设置 anthropic 启用 Claude
ANTHROPIC_API_KEY Anthropic API 密钥,用于调用 Claude 模型
ANTHROPIC_MODEL claude-haiku-4-5 指定使用的 Claude 模型
DEBUG false 是否开启调试模式

提示:在开发环境中,可将 LLM_PROVIDER 设为 mock,此时项目使用模拟响应,无需配置真实的 API Key 即可运行。


构建与启动

构建镜像

进入项目目录,执行以下命令构建 Docker 镜像:

1
2
cd ~/桌面/ai-fail-lab
docker compose up -d --build --no-cache

参数说明:

  • -d:后台运行
  • --build:构建前自动执行 Dockerfile
  • --no-cache:不使用构建缓存,确保依赖被重新安装

提示:首次构建可能需要几分钟,取决于网络速度。如果网络较慢,可考虑配置 Docker 镜像加速器。

查看启动日志

构建完成后,查看容器日志确认启动状态:

1
docker compose logs -f

成功启动的标志:

1
2
3
4
INFO:     Started server process [1]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)

看到 Uvicorn running on http://0.0.0.0:8000 即表示服务已成功启动。

验证部署

方式一:通过浏览器访问

在浏览器中打开以下地址:

方式二:通过命令行检查

1
2
3
4
5
# 检查健康端点
curl http://localhost:8000/health

# 检查主页
curl http://localhost:8000

方式三:通过 Docker 命令检查(我喜欢用这个)

1
2
3
4
5
# 查看容器运行状态
docker compose ps

# 查看实时日志
docker compose logs -f

常见问题排查

ModuleNotFoundError:缺少模块

现象: 容器启动时报 ModuleNotFoundError: No module named 'xxx'

可能原因与解决方案:

缺失模块 原因 解决方案
pydantic_settings Pydantic 2.0 将 BaseSettings 拆分到独立包 在 requirements.txt 中添加 pydantic-settings
anthropic 代码引入了 Anthropic SDK 但未声明依赖 在 requirements.txt 中添加 anthropic
其他模块 依赖文件遗漏 检查代码中的 import 语句,确保全部写入 requirements.txt

通用修复步骤:

1
2
3
4
# 1. 更新 requirements.txt
# 2. 强制重新构建(清除缓存)
docker compose down
docker compose up -d --build --no-cache

TypeError: unhashable type: ‘dict’

现象: 服务启动成功,但访问主页时报 500 错误,日志中出现:

1
TypeError: unhashable type: 'dict'

根因: Jinja2 3.1.5+ 重构了模板缓存机制,与 Starlette 的模板调用方式不兼容。

解决方案: 将以下三个库锁定为兼容版本:

1
2
3
fastapi==0.111.0
starlette==0.37.2
jinja2==3.1.4

修改 requirements.txt 后,必须强制重新构建:

1
2
docker compose down
docker compose up -d --build --no-cache

版本警告

现象: 启动时出现如下警告:

1
WARN[0000] the attribute 'version' is obsolete, it will be ignored

解决方案:docker-compose.yml 文件顶部删除 version: "3.9"version: "3" 行。现代 Docker Compose 会自动推断版本。

端口被占用

现象: 启动时报 port 8000 is already in use

解决方案: 修改 docker-compose.yml 中的端口映射:

1
2
ports:
- "8080:8000" # 将宿主机端口改为 8080

然后重新构建启动。

容器反复重启

排查步骤:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 1. 查看容器状态
docker compose ps

# 2. 查看详细日志
docker compose logs --tail=50

# 3. 进入容器排查
docker compose exec ai-fail-lab bash

# 4. 在容器内检查依赖
pip list | grep -E "jinja2|starlette|fastapi"

# 5. 确认版本
python -c "import jinja2; print(jinja2.__version__)"

停止与清理

停止服务

1
docker compose down

停止并删除容器和镜像

1
docker compose down --rmi all

清理 Docker 系统资源

1
docker system prune -af

安装流程速查

以下为安装步骤的快速参考:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 1. 进入项目目录
cd ~/桌面/ai-fail-lab

# 2. 确认依赖文件内容正确(参考第三章)
cat requirements.txt

# 3. 确认 docker-compose.yml 配置正确(参考第四章)
cat docker-compose.yml

# 4. 构建并启动
docker compose up -d --build --no-cache

# 5. 查看日志
docker compose logs -f

# 6. 验证访问
curl http://localhost:8000/health

# 7. 如需停止
docker compose down

注意事项:

  1. 始终使用 --no-cache 参数重新构建,确保依赖被正确安装(有些版本用不了,别问为什么知道)
  2. 核心依赖(fastapi、starlette、jinja2)必须精确锁定版本
  3. 任何代码中的 import 语句都必须在 requirements.txt 中有对应声明
  4. 生产环境建议设置 DEBUG=false 并配置真实的 API Key

开启你的AI之旅吧😊