> ## Documentation Index
> Fetch the complete documentation index at: https://docs.befailproof.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# 部署

> AgentEye 部署文档。

本指南介绍如何在生产环境中部署 AgentEye 服务器和仪表板。

***

## 架构概览

```
  [ AI 代理机器 ]                        [ 您的基础设施 ]

    Python SDK
       |  写入 JSONL                        +----------------------+
       v                               +--->| PostgreSQL 15+       |
 agenteye-collector --HTTP--+          |    | (关系型存储)          |
                            |          |    +----------------------+
                            v          |
                       +--------+      |    +----------------------+
                       | Server |<-----+--->| ClickHouse 24+       |
                       +--------+      |    | (事件 / 分析)         |
                            ^          |    +----------------------+
                        API |          |
                            |          |    +----------------------+
                      +-----------+    +- - >| Redis 7+（可选）    |
                      | Dashboard |          +----------------------+
                      +-----------+
```

* **Server**：Rust HTTP 服务，接收事件批次，将其写入 ClickHouse，并在 PostgreSQL 中维护关系型状态。
* **Dashboard**：Next.js Web 应用，通过服务器 API 进行所有读写操作。
* **agenteye-collector**：部署在代理机器上，而非服务器主机上。
* **Postgres 15+**：**必需**。（在多租户版本中从 14 升级；org-membership 模式使用了列列表 `ON DELETE SET NULL` 外键，该特性为 Postgres 15+ 专属。部署此版本前请先升级 Postgres。）存储 OLTP 状态：`api_keys`、`users`、`sessions`、`evaluation_jobs`（队列）、`dashboards`、`saved_queries`、`otp_codes`，以及多租户表 `orgs`、`org_memberships`、`org_settings`。
* **ClickHouse 24+**：**必需**。所有摄取事件的分析存储引擎。引擎类型：`ReplacingMergeTree`，按月分区，按 `(session_id, ts, dedup_key)` 排序。服务器通过 `CLICKHOUSE_URL` 连接；内置的 `deploy/base/clickhouse/` 附带了针对单节点性能调优的配置。**多租户要求：** 内置配置启用了 SQL 访问管理 + `users_without_row_policies_can_read_rows=false`，以便服务器能够为每个组织创建一个只读 ClickHouse 用户及行策略（这是 SQL 编辑器和 AI 代理的引擎层租户隔离边界）。如果您使用自定义 ClickHouse 配置，请保留这些设置（参见 `deploy/base/clickhouse/configmap.yaml`）。
* **Redis 7+**：*可选*，用作共享缓存 + 限流后端。服务器和仪表板均通过 `REDIS_URL` 连接。如未配置，两者将优雅降级为仅使用 Postgres 的路径。详见下方 **Redis（可选缓存）** 章节。

***

## 服务器

### 拉取镜像

```bash theme={null}
echo $AGENTEYE_TOKEN | docker login ghcr.io -u x --password-stdin
docker pull ghcr.io/agenteye-enterprise/server:beta-latest
```

> 当前构建版本发布于 `beta-latest`；`latest` 仅在稳定版本发布时才会更新。生产环境中请固定使用特定的 `:v<version>` 标签，详见 [可用镜像标签](#available-image-tags)。

### 环境变量

| 变量                                            | 是否必需               | 默认值                 | 说明                                                                                                                                                                                                                                                                                                                     |
| --------------------------------------------- | ------------------ | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `DATABASE_URL`                                | 是                  | 无                   | Postgres DSN。标准 libpq 连接字符串格式，使用 `postgres://` 协议头。支持 `?sslmode=require` 及其他 libpq 参数。密码中不得包含 `/`、`+` 或 `=`；建议使用 `openssl rand -hex` 生成 URL 安全的密码。                                                                                                                                                                     |
| `ADMIN_KEY`                                   | 否                  | 无                   | 初始管理员 API 密钥。每次启动时以完整权限进行 upsert。更换时修改该值并重启服务即可。                                                                                                                                                                                                                                                                       |
| `LISTEN_ADDR`                                 | 否                  | `0.0.0.0:8080`      | TCP 监听地址                                                                                                                                                                                                                                                                                                               |
| `MAX_BODY_BYTES`                              | 否                  | `134217728`（128 MB） | 最大请求体大小                                                                                                                                                                                                                                                                                                                |
| `ADMIN_EMAIL`                                 | 否                  | 无                   | 初始管理员用户邮箱。每次启动时以完整权限进行 upsert，并标记为受保护状态：无法通过仪表板或 API 禁用或修改其权限。如需更换初始管理员，修改 `ADMIN_EMAIL` 并重启；新邮箱将被 upsert 为受保护状态，旧邮箱的受保护标记将保留，直至手动在数据库中清除。                                                                                                                                                                             |
| `ALLOWED_EMAILS`                              | 否                  | 无（全部阻止）             | 允许创建用户和登录的邮箱地址列表（逗号分隔）。支持精确地址（`user@example.com`）和域名通配符（`*@example.com`）。未设置时，无法创建或登录任何用户。**仅首次启动时生效**：首次启动时为默认组织的允许列表设置初始值；此后每个组织的 [`/<org>/settings`](#operational-settings) 页面为权威配置来源，修改此环境变量不再生效。                                                                                                                  |
| `SMTP_HOST`                                   | 否                  | 无                   | 用于发送 OTP 邮件的 SMTP 服务器主机名。未设置时，OTP 代码将记录到 stdout。                                                                                                                                                                                                                                                                       |
| `SMTP_PORT`                                   | 否                  | `587`               | SMTP 服务器端口                                                                                                                                                                                                                                                                                                             |
| `SMTP_USERNAME`                               | 否                  | 无                   | SMTP 认证用户名                                                                                                                                                                                                                                                                                                             |
| `SMTP_PASSWORD`                               | 否                  | 无                   | SMTP 认证密码                                                                                                                                                                                                                                                                                                              |
| `SMTP_FROM`                                   | 否                  | 无                   | OTP 邮件的发件人地址                                                                                                                                                                                                                                                                                                           |
| `SMTP_TLS`                                    | 否                  | STARTTLS            | 除非显式关闭，否则默认使用 STARTTLS：`false` 或 `0` 表示明文传输（无 TLS）；其他任意值（包括未设置）均启用 STARTTLS。                                                                                                                                                                                                                                           |
| `DASHBOARD_URL`                               | 否                  | 内置默认值               | 仪表板来源地址，用于构建 OTP 邮件魔法链接以及告警通知中的事件魔法链接。未设置时回退到内置默认值（仅对 OTP，还会优先使用仪表板派生的请求来源）。对于拆分域名部署，请设置此项以确保邮件和 Slack/事件链接均指向您的仪表板。详见下方 **邮件魔法链接 URL**；大多数运营者无需设置此项。                                                                                                                                                                  |
| `SESSION_TTL_SECS`                            | 否                  | `86400`（24 小时）      | 仪表板会话有效期（秒）。**仅首次启动时生效**：首次部署后可通过 [`/<org>/settings`](#operational-settings) 按组织编辑。                                                                                                                                                                                                                                    |
| `OTP_TTL_SECS`                                | 否                  | `600`（10 分钟）        | OTP 代码有效期（秒）。**仅首次启动时生效**：首次部署后可通过 [`/<org>/settings`](#operational-settings) 按组织编辑。                                                                                                                                                                                                                                   |
| `REDIS_URL`                                   | 否                  | 无                   | 可选的共享缓存 + 限流后端，例如 `redis://redis:6379/0`。设置后，服务器将缓存已认证的 API 密钥查询、仪表板的 `/models` 聚合、会话列表以及环境列表 facet；同时将 OTP 请求限流从 Postgres COUNT 切换为 Redis INCR。未设置或无法访问时，服务器在无缓存模式下运行（OTP 限流回退到 Postgres，其他所有缓存调用直接访问数据源）。详见下方 **Redis（可选缓存）**。                                                                                       |
| `CLICKHOUSE_URL`                              | **是**              | 无                   | ClickHouse 实例的基础 URL，例如 `http://clickhouse:8123`。服务器在每次启动时将事件模式应用到此数据库，若无法连接 ClickHouse 则拒绝启动。详见下方 **ClickHouse（必需的分析存储）**。                                                                                                                                                                                            |
| `CLICKHOUSE_DATABASE`                         | 否                  | `agenteye`          | ClickHouse 数据库（模式）名称。如不存在，服务器在启动时自动创建。                                                                                                                                                                                                                                                                                 |
| `ORG_CH_SECRET`                               | 否（单租户）/ **是（多组织）** | 开发默认值               | HMAC 密钥，用于派生每个组织的专属 ClickHouse 密码。SQL 编辑器和 AI 代理的 `run_query` 以该组织自己的只读 ClickHouse 用户身份执行，其行策略在引擎层强制实现租户隔离。单租户部署可使用内置开发默认值正常启动；**在创建第二个组织之前，必须设置一个强且稳定的值**，因为 `agenteye-orgctl org create` CLI 拒绝在内置开发默认值下运行。轮换此值会导致每个组织的 ClickHouse 用户失效，直到下次启动时重新配置（启动时的自动协调会修复此问题）。请妥善保管，并在各副本间保持一致。组织配置本身仅限运营者操作；详见下方 **组织（多租户）**。 |
| `DEFAULT_ORG_NAME`                            | 否                  | `Default`           | 内置默认组织的显示名称。**仅首次启动时生效**，且仅在该组织仍保持初始迁移后的通用标识时适用，启动后即忽略。一旦通过 `agenteye-orgctl org rename` 重命名该组织，重命名结果为权威值，此环境变量不再生效。                                                                                                                                                                                                   |
| `DEFAULT_ORG_SLUG`                            | 否                  | `default`           | 内置默认组织的 URL slug，即仪表板中该组织的路径（`/<slug>/…`）。与 `DEFAULT_ORG_NAME` 具有相同的仅首次启动/初始状态语义。必须为 1-40 个小写字母数字，允许内部单个连字符，且不得为[保留字](#organizations-multi-tenancy)；无效值将被忽略（组织保持 `default`）。允许单租户安装以如 `/acme` 替代 `/default` 展示，无需任何部署后 CLI 操作。                                                                                         |
| `RUST_LOG`                                    | 否                  | `info`              | 日志详细级别（`debug`、`warn`、`error`、`agenteye_server=trace`）                                                                                                                                                                                                                                                                 |
| `EVALUATOR_ENDPOINT`                          | 否                  | 无                   | 评估器服务的基础 URL（例如 `http://evaluator:9000`）。未设置时，整个评估流水线为空操作；不写入任何队列行，也不运行任何 worker。详见 [评估套件](/zh/agenteye/evaluation-suite)。                                                                                                                                                                                             |
| `EVALUATOR_TOKEN`                             | 否                  | 无                   | 作为 `Authorization: Bearer <token>` 发送给评估器。**必须与评估器服务配置的值相同。** 仅在评估器配置为无 token 时可以省略。                                                                                                                                                                                                                                   |
| `EVALUATOR_WORKERS`                           | 否                  | `2`                 | 并发数：每个服务器实例中负责分发评估任务的 worker 数量。在多个水平扩展的服务器上并发运行是安全的。                                                                                                                                                                                                                                                                  |
| `EVALUATOR_CLAIM_BATCH`                       | 否                  | `4`                 | 单个 worker 每次循环认领的最大评估数量。批次**并发**分发，因此评估器端点的总并发为 `EVALUATOR_WORKERS × EVALUATOR_CLAIM_BATCH`。                                                                                                                                                                                                                           |
| `EVALUATOR_POLL_IDLE_SECS`                    | 否                  | `2`                 | 无待处理任务时，worker 在两次分发尝试之间的休眠时长。                                                                                                                                                                                                                                                                                         |
| `EVALUATOR_POLLING_INTERVAL_SECS`             | 否                  | `10`                | 当评估器未在响应中返回 `next_poll_secs`，且未通过 `GET /config` 广播 `default_poll_interval_secs` 时，`GET /evaluate/{id}` 轮询的最终回退周期（秒）。                                                                                                                                                                                                   |
| `EVALUATOR_REQUEST_TIMEOUT_MS`                | 否                  | `30000`             | 对评估器的单次 HTTP 请求超时时间（毫秒）。                                                                                                                                                                                                                                                                                               |
| `EVALUATOR_MAX_ATTEMPTS`                      | 否                  | `5`                 | 失败次数达到此值后，评估将被记录为终态 `error`（如果失败原因为请求超时，则记录为 `timeout`）。                                                                                                                                                                                                                                                               |
| `EVALUATOR_CONFIG_REFRESH_SECS`               | 否                  | `300`（5 分钟）         | 服务器重新从评估器获取 `GET /config` 的频率。                                                                                                                                                                                                                                                                                         |
| `EVALUATOR_MAX_POLL_DURATION_SECS`            | 否                  | `3600`（1 小时）        | 会话在轮询队列中可停留的最长实际时间，超时后 AgentEye 将其终止为 `timeout`。防止评估器永久返回 `pending` 的情况。                                                                                                                                                                                                                                               |
| `ALERT_WORKERS`                               | 否                  | `1`                 | 并发数：每个服务器实例中负责评估告警规则的 worker 数量。详见 [告警](/zh/agenteye/alerts)。                                                                                                                                                                                                                                                          |
| `ALERT_CLAIM_BATCH`                           | 否                  | `16`                | 单个 worker 每次循环认领的最大告警数量。                                                                                                                                                                                                                                                                                               |
| `ALERT_POLL_IDLE_SECS`                        | 否                  | `5`                 | 队列为空时告警 worker 的休眠时长。                                                                                                                                                                                                                                                                                                  |
| `ALERT_REQUEST_TIMEOUT_MS`                    | 否                  | `15000`             | 单次触发评估超时时间（ClickHouse 查询 + 出站渠道 HTTP）。                                                                                                                                                                                                                                                                                 |
| `ALERT_MAX_ATTEMPTS`                          | 否                  | `5`                 | 连续瞬时失败次数达到此值后，告警按正常周期重新调度，而非指数退避。                                                                                                                                                                                                                                                                                      |
| `AUDIT_WORKERS`                               | 否                  | `1`                 | 并发数：每个服务器实例中负责执行审计任务的 worker 数量。详见 [审计](/zh/agenteye/audits)。                                                                                                                                                                                                                                                          |
| `AUDIT_CLAIM_BATCH`                           | 否                  | `1`                 | 单个 worker 每次循环认领的最大到期审计数量。由于代理式调查是一个长循环，默认值为 1。                                                                                                                                                                                                                                                                        |
| `AUDIT_POLL_IDLE_SECS`                        | 否                  | `30`                | 无到期审计时审计 worker 的休眠时长。                                                                                                                                                                                                                                                                                                 |
| `AUDIT_REQUEST_TIMEOUT_MS`                    | 否                  | `30000`             | 对 ClickHouse 的单次策略查询超时时间（毫秒）。                                                                                                                                                                                                                                                                                          |
| `AUDIT_LLM_TIMEOUT_MS`                        | 否                  | `1440000`           | 代理式调查调用 AI 助手服务的超时时间。完整的代理循环需要数分钟；请将此值设置为**高于**代理自身的 `AGENTEYE_AUDIT_TIMEOUT_MS`，以确保代理在服务器放弃之前能够返回部分发现结果。                                                                                                                                                                                                              |
| `AUDIT_MAX_ATTEMPTS`                          | 否                  | `5`                 | 连续瞬时失败次数达到此值后，审计按正常周期重新调度，而非指数退避。                                                                                                                                                                                                                                                                                      |
| `AGENTEYE_AGENT_URL` / `AGENTEYE_AGENT_TOKEN` | 否                  | —                   | 审计的代理式调查调用 AI 助手 `agent` 服务，**复用与助手相同的连接**——因此也需要在**服务器**上设置这两个值（内置的 manifests/compose 已完成此配置）。两者均已设置 ⇒ 审计运行 AI 调查；任一未设置 ⇒ 审计**仅运行策略**（确定性 SQL 策略检查仍然执行），忽略每个审计的 `llm_enabled` 标志。代理还必须配置 LLM——详见 [assistant.md](/zh/agenteye/assistant)。                                                                              |

**AI 助手服务——审计与沙盒设置。** 代理式调查及其 Pod 内 Python 沙盒的调优在 **agent 服务**（而非服务器）上配置，均以 `AGENTEYE_AUDIT_*` 为前缀，均为可选项：

| 变量                                                                                                        | 默认值                                        | 含义                                                      |
| --------------------------------------------------------------------------------------------------------- | ------------------------------------------ | ------------------------------------------------------- |
| `AGENTEYE_AUDIT_MAX_STEPS`                                                                                | `200`                                      | 每次调查的最大代理轮次。                                            |
| `AGENTEYE_AUDIT_TIMEOUT_MS`                                                                               | `1200000`                                  | 单次调查的实际耗时上限（20 分钟）。必须**低于**服务器的 `AUDIT_LLM_TIMEOUT_MS`。 |
| `AGENTEYE_AUDIT_MAX_CONCURRENCY`                                                                          | `1`                                        | 每个 agent Pod 的并发调查数（与聊天助手的配额相互独立）。                      |
| `AGENTEYE_AUDIT_SANDBOX_TIMEOUT_MS` / `_MEM_MB` / `_CPU_SECS` / `_OUTPUT_MAX_BYTES` / `_SCRIPT_MAX_BYTES` | `20000` / `768` / `10` / `64000` / `64000` | bubblewrap 沙盒的单脚本限制。                                    |

**沙盒平台要求。** 审计代码沙盒在 bubblewrap 隔离环境中运行模型的 Python 代码，需要**非特权用户命名空间**支持。Agent Pod 必须允许 `clone()` 标志——在 agent 上设置 `seccompProfile: Unconfined`（k8s）或 `security_opt: [seccomp:unconfined]`（compose）。在内核禁用非特权用户命名空间的节点上（例如某些 GKE COS 镜像），沙盒**预检失败，审计器自动降级为仅 SQL 模式**——不报错，只是在 agent 的 `/health` 接口中显示 `sandbox_available: false`。

### 运行

在您的环境中设置 `DATABASE_URL`，然后传递给容器：

```bash theme={null}
docker run -d --restart unless-stopped \
  --name agenteye-server \
  -e DATABASE_URL="$DATABASE_URL" \
  -e ADMIN_KEY="$ADMIN_KEY" \
  -p 8080:8080 \
  ghcr.io/agenteye-enterprise/server:beta-latest
```

服务器在启动时自动运行数据库迁移，无需单独执行迁移步骤。

### 健康检查

```
GET /health    # 存活探针  - 进程启动后始终返回 {"status":"ok"}
GET /ready     # 就绪探针  - Postgres + ClickHouse 可达时返回 200，否则返回 503
```

无需认证。使用 `/health` 作为**存活**探针，`/ready` 作为**就绪** / 负载均衡探针。`/ready` 检查服务器不可或缺的硬依赖项（Postgres + ClickHouse），因此正在运行但无法连接数据库的服务器将从轮询中移除并显示为 `NotReady`；Redis 状态会在响应中报告，但不会影响就绪判断。内置的 Kubernetes manifests 中就绪探针已指向 `/ready`，存活探针保持指向 `/health`。完整信息（包括可选的 Kubernetes 原生 Pod 故障告警到 Slack）详见 [enterprise-docs/health-monitoring.md](/zh/agenteye/health-monitoring)。

### 邮件魔法链接 URL

OTP 登录邮件包含一个一键**打开仪表板**的按钮。点击后用户跳转至 `/login?token=<code>&email=<address>`；仪表板将该组合换取会话并重定向到应用，无需手动输入验证码。服务器按以下三个优先级解析用于构建链接的仪表板来源地址：

1. **`X-AgentEye-Dashboard-Url` 请求头**：由仪表板的 `/api/auth/otp/request` 代理从其自身公开来源自动设置。在同源部署中（服务器与仪表板共享一个主机，通过一个转发代理请求头的 ingress 托管），**无需任何配置**。
2. **`DASHBOARD_URL` 环境变量**：如果您的仪表板与服务器 OTP 请求端点所在来源不同（拆分 `api.example.com` / `app.example.com`），或您的 ingress 未将公开主机传递到仪表板 Pod 中（导致 `request.nextUrl.origin` 解析为类似 `0.0.0.0:3000` 的通配绑定地址），请设置此项。示例：`DASHBOARD_URL=https://app.example.com`。
3. **默认值**：`https://app.befailproof.ai`，仅在以上两者均不存在时使用。

请求头的值会经过验证：仅接受 `https://*` 和回环地址（`http://localhost*`、`http://127.0.0.1*`）来源，即使使用 `https://` 协议头，通配绑定地址（`0.0.0.0`、`[::]`）也会被拒绝。其他任何值均回退到第 2 级。

在运行中的集群上通过一行命令设置，无需修改文件或重新构建 kustomize：

```bash theme={null}
kubectl set env deployment/server -n agenteye \
  DASHBOARD_URL=https://app.example.com
```

此操作会触发滚动更新；新 Pod 在首次请求时读取该值。请注意，此覆盖仅保存在 Deployment 上；如果后续再次对 overlay 执行 `kustomize build | kubectl apply`，该值将被清除，除非您将相同的环境变量添加到 overlay 的 `server-env.yaml` patch 中。

***

## 仪表板

### 拉取镜像

```bash theme={null}
docker pull ghcr.io/agenteye-enterprise/dashboard:beta-latest
```

### 环境变量

| 变量                      | 是否必需 | 默认值    | 说明                                                                                                                                                                                              |
| ----------------------- | ---- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `AGENTEYE_SERVER_URL`   | 是    | 无      | 服务器的基础 URL，例如 `http://localhost:8080`                                                                                                                                                           |
| `AGENTEYE_API_KEY`      | 是    | 无      | 仪表板用于向服务器进行身份验证的 API 密钥。需要全部权限（建议使用管理员密钥）。                                                                                                                                                      |
| `AE_LOG_LEVEL`          | 否    | `info` | 服务器端日志详细级别：`debug`、`info`、`warn`、`error`。设置为 `debug` 可在诊断问题时查看上游请求/响应行和会话验证追踪。                                                                                                                  |
| `AE_LOG_JSON`           | 否    | 自动     | `1` 强制使用每行 JSON 输出；`0` 强制使用人类可读输出。未设置时，如果 `NODE_ENV=production` 则自动启用 JSON。生产环境建议使用 JSON，以便通过 `jq` 或日志聚合器进行解析。                                                                                  |
| `AE_ANALYTICS_DISABLED` | 否    | 无      | 设置为 `1`/`true` 可禁用仪表板的匿名产品使用遥测数据。详见下方 [遥测与隐私](#telemetry--privacy)。                                                                                                                             |
| `REDIS_URL`             | 否    | 无      | 可选的共享缓存后端，例如 `redis://redis:6379/0`。设置后，仪表板将在各副本间缓存 `validateSession()` 结果，并为延迟聚合/环境列表代理路由共享 Next.js fetch 缓存。边缘侧 OTP 请求和验证限流也会在 Redis 可用时使用（Redis 不可访问时失效开放；服务器端限流为安全保障）。详见下方 **Redis（可选缓存）**。 |
| `AGENTEYE_AGENT_URL`    | 否    | 无      | 可选 AI 助手 `agent` 服务的基础 URL，例如 `http://agent:9100`。**不设置则完全隐藏助手**：仪表板中不会显示助手气泡。详见 [enterprise-docs/assistant.md](/zh/agenteye/assistant)。                                                        |
| `AGENTEYE_AGENT_TOKEN`  | 否    | 无      | 仪表板向 `agent` 服务出示的共享密钥。必须与 agent 上配置的 `AGENTEYE_AGENT_TOKEN` 一致。详见 [enterprise-docs/assistant.md](/zh/agenteye/assistant)。                                                                      |

### 运行

```bash theme={null}
docker run -d --restart unless-stopped \
  --name agenteye-dashboard \
  -e AGENTEYE_SERVER_URL="http://your-server-host:8080" \
  -e AGENTEYE_API_KEY="$ADMIN_KEY" \
  -p 3000:3000 \
  ghcr.io/agenteye-enterprise/dashboard:beta-latest
```

### 遥测与隐私

仪表板会向 Exosphere 的分析服务（PostHog）发送**匿名产品使用分析**数据：包括浏览了哪些仪表板页面，以及少量 UI 操作，例如创建 API 密钥或重新评估会话。这些使用信号用于指导功能优先级决策。

* **您基础设施中的代理、会话或事件数据绝对不会泄露。** 仅上报仪表板 UI 使用情况。页面 URL 在发送前会去除标识符，运营者仅以内部不透明 ID 标识，绝不使用邮箱。
* 遥测**默认启用**。如需完全关闭，请在仪表板容器上设置 `AE_ANALYTICS_DISABLED=1` 并重启。
* 分析数据发送至仪表板自身的 `/ingest` 路径，仪表板将其反向代理至 PostHog（`https://us.i.posthog.com`）。使用第一方请求可避免浏览器广告拦截器拦截。**仪表板容器**需要能够访问 PostHog；如被阻止，遥测静默失效，不影响仪表板正常使用。

***

## AI 助手（可选）

仪表板内置 AI 助手，让您的团队能够用自然语言查询代理数据（汇总会话、为 `/queries` 编辑器生成 SQL，以及将已保存的查询转换为仪表板图块），无需离开仪表板。它以独立的内部 `agent` 容器运行（基于 Claude Agents SDK），仅供仪表板访问，**在配置 LLM 端点之前保持禁用状态**。

要启用它，需要在 `agent` 服务上设置：LLM 连接（通过 `PORTKEY_API_KEY` + 模型目录 slug `AGENTEYE_AGENT_MODEL=@<slug>/<model>` 使用 **Portkey**，通过 `ANTHROPIC_API_KEY` 直连 Anthropic，通过 `ANTHROPIC_BASE_URL` 使用其他网关，或使用 Bedrock/Vertex）、一个**专用**数据密钥，以及与仪表板匹配的共享 `AGENTEYE_AGENT_TOKEN`。仪表板用户还需要 `agent:use` 权限。

助手的数据密钥无需手动创建：选取一个随机密钥，将其设置为 `agent` 上的 `AGENTEYE_API_KEY` **以及** `server` 上的 `AGENT_API_KEY`，服务器将在启动时以固定权限集完成初始化。其数据访问权限为只读（`events:read`、`evaluations:read`、`dashboards:read`、`queries:read`），同时持有需审批才能使用的创作权限（`dashboards:write`、`queries:write`、`queries:run`），允许其代表用户起草和验证已保存的查询并构建仪表板图块；所有 SQL 仍通过组织的只读 ClickHouse 角色运行，因此这拓宽了助手的创作范围，而非数据访问范围。这些权限在代码中固定，无法通过配置扩展。该密钥受到保护，无法通过 API 禁用或重新生成，只能通过修改值并重启来轮换。请勿将管理员/仪表板密钥复用于此用途。

完整的设置说明、环境变量参考、遥测选项和安全模型详见 **[enterprise-docs/assistant.md](/zh/agenteye/assistant)**。

***

## ClickHouse（必需的分析存储）

ClickHouse 在高事件量下保持仪表板响应速度，并允许 `/queries` SQL 编辑器在单一存储中跨事件、评估和会话进行联表查询。它是所有摄取事件、所有终态评估结果以及派生的每会话聚合的必需规范存储。PostgreSQL 存储关系型/可变状态表（api\_keys、users、otp\_codes、evaluation\_jobs、dashboards、saved\_queries）；分析层面的数据存储在 ClickHouse 中，以便仪表板的汇总和您自定义的 SQL 查询能够原生扫描和联表，无需跨数据库往返。服务器在未设置 `CLICKHOUSE_URL` 时拒绝启动。

### 模式

服务器启动时创建三个 ClickHouse 对象，均为幂等操作（`CREATE IF NOT EXISTS`）：

* **`agenteye.events`**：`ReplacingMergeTree(ingested_at)`，按 `toYYYYMM(ts)` 分区，按 `(session_id, ts, dedup_key)` 排序。重复插入（采集器重试）在合并时折叠为单行；服务器为每个事件计算确定性 SHA-256 `dedup_key`，确保重试安全。
* **`agenteye.evaluations`**：`ReplacingMergeTree(ingested_at)`，按 `toYYYYMM(finished_at)` 分区，按 `(session_id, finished_at, dedup_key)` 排序。由评估流水线在每个终态评估结果后写入一次。与 `events` 采用相同的去重密钥模型。
* **`agenteye.agent_sessions`**：基于 `agenteye.events` 的**视图**，非物理表。所有列均为派生列（`started_at = min(ts)`、`last_event_at = max(ts)`、`ended_at = max(if event_type='agent_end', ts, NULL)`、`event_count = count()` 等）。无需每事件 upsert，无需单独回填；视图自动反映 `events` 表中的最新数据。

为了向后兼容引用 `analytics.evaluations` / `analytics.sessions` 的已保存查询，服务器还创建了一个 `analytics` ClickHouse 数据库，其中包含指向 `agenteye.*` 表的视图；`analytics.events`、`analytics.evaluations`、`analytics.agent_sessions`、`analytics.sessions` 均可正常解析。

### 配置

内置的 docker-compose 和 `deploy/base/clickhouse/` 附带了针对 AgentEye 工作负载调优的 ClickHouse 服务：

* 内置 base overlay 中请求 2 GiB / 限制 4 GiB 内存（适合小型 POC/预发布节点）；生产用户应增大配置——推荐最低配置为 2c / 4Gi 请求，6c / 8Gi 限制。`max_server_memory_usage_to_ram_ratio=0.9`
* 标记缓存 5 GiB + 未压缩缓存 8 GiB
* `background_pool_size=16`，`background_merges_mutations_concurrency_ratio=2`
* MergeTree：`parts_to_throw_insert=3000`，`parts_to_delay_insert=1500`，`non_replicated_deduplication_window=1000`
* `local_io_method=auto`（支持的内核上使用 io\_uring）
* `fsync_metadata=0`：可接受，因为使用至少一次摄取 + ReplacingMergeTree 去重
* 启用 `query_log`，TTL 30 天；移除 `query_thread_log`（高 QPS 下开销较大）
* 用户侧查询 `max_execution_time=30`
* StatefulSet 模板中 PVC 100 GiB（生产环境中客户 overlay **应**覆盖为高速 SSD 存储类）

### 备份

您的完整数据集每晚备份为一个可恢复的归档文件，因此集群或存储丢失后可以恢复。ClickHouse 由每日 `agenteye-backup` CronJob 自动备份，该任务在一次运行中同时转储 PostgreSQL 和 ClickHouse。ClickHouse 通过其 HTTP API 读取：`agenteye.events` 和 `agenteye.evaluations` 以 ClickHouse 原生格式转储（视图和行策略在服务器启动时重新创建，因此表数据即为完整数据），并与 Postgres 转储一起打包为单个压缩归档文件上传到您的对象存储。

目标存储桶和云凭证按 overlay 配置。上传配置和恢复步骤详见 [enterprise-docs/kubernetes-deployment.md](/zh/agenteye/kubernetes-deployment) 中的 **备份** 章节。

***

## Redis（可选缓存）

Redis 是服务器和仪表板使用的**可选**共享缓存 + 限流后端。在两个服务上部署 Redis 并设置 `REDIS_URL` 后：

* **服务器**缓存已认证的 API 密钥查询、`/events/environments` + `/evaluations/environments` 列表、`/events/latency_aggregate` 汇总（仪表板轮询的最重查询）、`/sessions` 列表，并将 OTP 请求限流从 Postgres `COUNT(*)` 切换为 Redis `INCR + EXPIRE`。
* **仪表板**缓存 `validateSession()` 结果，使典型页面加载发出的 10-20 次已认证 API 调用共享一次上游会话检查。同时在仪表板边缘限制 OTP 请求和验证频率。

**两个服务在 Redis 不可访问时均能优雅降级。** 每次缓存调用在有限超时内返回 `Err`，调用方回退到数据源（服务器侧为 Postgres，仪表板侧为上游 Rust 服务器）。OTP 限流回退到服务器上的 Postgres `COUNT(*)` 路径（安全属性得以保持）；仪表板的边缘 OTP 限制失效开放，而服务器端限制依然有效。Redis 故障降低延迟，不影响正确性。

### 配置

docker-compose 套件已包含 Redis 服务，并将 `REDIS_URL=redis://redis:6379/0` 注入服务器和仪表板。如需使用外部 Redis，将 `REDIS_URL` 设置为您的端点地址，并从 compose 文件中移除 `redis` 服务即可。

### 内存与持久化

内置 Redis 镜像以 `--appendonly yes --appendfsync everysec --maxmemory 256mb --maxmemory-policy allkeys-lru` 运行。AOF 持久化确保缓存在容器重启后仍然存在；`everysec` 是合理的持久性/性能平衡点，因为丢失最后一秒的缓存写入是无害的。LRU 淘汰策略限制内存增长。

### 何时不应部署 Redis

* 单实例开发/QA 环境。服务器自身的进程内缓存已能提供大部分单副本收益；Redis 增加的是多副本共享能力，单实例场景并不需要。
* 运营成本超过延迟收益的气隙安装环境（运维一个额外服务的代价高于延迟优化）。

***

## Docker Compose（推荐）

`docker-compose.yml` 可从 `agenteye-enterprise/releases` 仓库获取，通过单条命令即可启动 Postgres、服务器和仪表板。

```bash theme={null}
GITHUB_TOKEN=$AGENTEYE_TOKEN gh release download \
  --repo agenteye-enterprise/releases \
  --pattern 'docker-compose.yml' \
  --dir ./agenteye
cd agenteye
```

**通过 `.env` 覆盖默认值：**

```
# 使用 URL 安全的密码（不含 /、+ 或 = 字符）。
# 生成方式：openssl rand -hex 24
POSTGRES_PASSWORD=your-db-password
ADMIN_KEY=your-admin-secret

# 仪表板认证
ADMIN_EMAIL=admin@yourcompany.com
ALLOWED_EMAILS=*@yourcompany.com

# 用于 OTP 邮件的 SMTP（省略则将 OTP 代码记录到 stdout）
# SMTP_HOST=smtp.yourprovider.com
# SMTP_PORT=587
# SMTP_USERNAME=your-smtp-user
# SMTP_PASSWORD=your-smtp-password
# SMTP_FROM=noreply@yourcompany.com

RUST_LOG=info
```

```bash theme={null}
docker compose up -d
```

**停止（保留数据卷）：**

```bash theme={null}
docker compose down
```

**停止并清除所有数据：**

```bash theme={null}
docker compose down -v
```

***

## 运营设置

以前通过环境变量固定的少量运营配置项，现在可以在仪表板的 **`/<org>/settings`** 页面按组织编辑；每个组织独立配置。更改在数秒内生效，无需重启或重新部署。

| 设置项       | 引导环境变量                     | 控制内容                                                                                                                                                                             |
| --------- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 允许登录的邮箱   | `ALLOWED_EMAILS`           | 允许接收 OTP 并被添加为用户的邮箱地址（或 `*@domain.com` 通配符）                                                                                                                                      |
| 默认用户权限    | `DEFAULT_USER_PERMISSIONS` | 管理员打开**新建用户**时预选的权限令牌（逗号分隔）。每个令牌必须是 [API 密钥权限](/zh/agenteye/api-keys) 中列出的字符串之一。默认为 `standard` 预设：只读访问权限加上日常值班操作（触发重新评估、运行查询、确认事件、使用助手）。                                         |
| 会话有效期     | `SESSION_TTL_SECS`         | 仪表板登录在需要重新认证之前的有效时长。仪表板每 5 秒重新检查上游会话，因此在 `/<org>/users` 上的权限更新将在受影响用户的下次请求时立即生效，无需重新登录。                                                                                          |
| 一次性验证码有效期 | `OTP_TTL_SECS`             | OTP / 魔法链接的可用时长                                                                                                                                                                  |
| 告警通知渠道    | `ALERTS_ENABLED_CHANNELS`  | 告警分发器被允许使用的渠道类型列表（逗号分隔）：`email`、`slack`、`webhook`。每个告警的配置仍在 `/<org>/alerts/<id>` 中编辑，但分发器会通过此集合过滤每次出站投递；在此处禁用的渠道会以 `skipped_disabled` 审计行短路。`dashboard` 渠道（本地审计插入）始终允许。默认全部三项启用。 |

### 引导机制说明

设置按组织存储在 `org_settings` 中。首次启动时，服务器从对应的环境变量（或在环境变量未设置时使用合理的默认值）为默认组织填充缺失的行。此后，**存储的值为权威配置来源，环境变量将被忽略**；后续重启时修改环境变量不会影响已有组织的值，新增组织从默认值开始，自行配置。

这意味着：

* 对于全新部署，按上述方式设置环境变量，默认组织将在首次启动时读取它们。
* 如需后续修改某个值，登录仪表板并在 `/<org>/settings` 下编辑。更改在数秒内对所有服务器副本生效，无需重启。
* 启动日志会记录已填充的内容与已有内容，以便确认引导是否生效：

  ```text theme={null}
  INFO settings bootstrap: seeded default-org row key=allowed_sign_ins env_var=ALLOWED_EMAILS seeded_from_env=true
  ```

#### 跨组织的登录语义

会话和 OTP 对用户是全局的，而非绑定到单个组织，因此登录时需要按以下两条规则协调各组织的设置：

* **会话/OTP 有效期**：用户所属所有组织中最严格（最短）的有效期生效。
* **允许登录的邮箱**：门控规则对所有组织的允许列表与组织成员资格进行 OR 运算：如果任一组织的允许列表接受用户的邮箱，**或**用户已经是任一组织的成员，则该用户可以请求 OTP。

### 权限

访问 `/<org>/settings` 页面需要两项权限：

* `settings:read`：查看页面和当前值。
* `settings:write`：保存更改。

引导管理员用户（从 `ADMIN_EMAIL` 初始化）会自动获得这两项权限以及所有其他权限。如需授予其他用户这些权限，请在 `/<org>/users` 中操作。

***

## 组织（多租户）

单个部署可以服务多个相互隔离的**组织**（租户）；每行数据恰好属于一个组织，隔离由数据库引擎在底层强制执行。单租户安装无需任何此处的配置；所有数据存储在内置的 `default` 组织中。（您可以通过在首次启动前设置 `DEFAULT_ORG_NAME` / `DEFAULT_ORG_SLUG`，或随时使用 `agenteye-orgctl org rename` 重命名，为该组织指定更友好的名称和 URL slug，使其路径如 `/acme` 而非 `/default`。）

**租户配置仅限运营者操作。** 组织及其成员资格通过 **`agenteye-orgctl`** CLI 创建和管理，该工具**内置于服务器镜像**中（与 `agenteye-server` 并列），在**现有服务器 Pod 内**运行；**没有独立的 Pod/Job、没有 HTTP API、也没有仪表板按钮**。它复用服务器的 `DATABASE_URL`、`CLICKHOUSE_URL` 和 `ORG_CH_SECRET`。

```bash theme={null}
# Docker Compose - 进入运行中的 server 服务：
docker compose exec server agenteye-orgctl org create --slug acme --name "Acme Corp"
docker compose exec server agenteye-orgctl member add --org acme --email alice@acme.example --set admin

# Kubernetes - 进入运行中的 server Deployment：
kubectl -n agenteye exec deploy/server -- agenteye-orgctl org list
```

可用命令：`org create | list | rename | delete | purge` 和 `member add | list | update | remove`，内置权限集 `admin`、`standard` 和 `read-only`。新添加的成员在首次登录仪表板时会收到 OTP。

**创建第二个组织之前：** 请设置一个强且稳定的 `ORG_CH_SECRET`（`org create` 命令拒绝在内置开发默认值下运行），并确保 Postgres 为 **15+** 版本。**不变的是：** 每组织的 API 密钥仍由组织成员在仪表板/API 中创建；只有组织和成员的生命周期管理移至 CLI。完整命令参考和示例详见 **[enterprise-docs/tenant-management.md](/zh/agenteye/tenant-management)**。

***

## 上下文窗口填充率

每个 `model_response` 事件显示一个**上下文填充率标签**——输入加输出 token 数占该模型上下文窗口的百分比。划分区间为：`healthy`（0–24%）、`watch`（25–49%）、`compacting`（50–74%）和 `reset context`（75–100%）。AgentEye 会自动解析常见的模型 ID，因此无需初始配置。

组织发送过的每个模型都会出现在 **设置 → 模型上下文窗口** 中。具有 `settings:write` 权限的用户可以覆盖其窗口大小，或添加私有/代理模型（0–1,000,000 token）；`0` 表示"未知"并隐藏该标签。更改对新摄取的事件生效。具有 `settings:read` 权限的用户可以查看列表。

升级后新事件会立即获得填充率。如需同时为现有部署的**历史**事件（以及每模型列表）填充数据，请运行一次性回填工具——它内置于服务器镜像中（与 `agenteye-orgctl` 类似），在现有服务器 Pod 中运行：

```bash theme={null}
# 预览（打印每组织的变更内容，不实际修改）：
kubectl -n agenteye exec deploy/server -- agenteye-backfill-context-window --dry-run
# 应用：
kubectl -n agenteye exec deploy/server -- agenteye-backfill-context-window
# docker compose：
docker compose exec server agenteye-backfill-context-window
```

该工具是幂等的（可安全重复运行），并从 Pod 中复用 `DATABASE_URL` / `CLICKHOUSE_URL` / `REDIS_URL`。如果您编辑了模型窗口并希望重新计算已有事件，可重新运行此工具。

***

## 生产注意事项

* **Postgres**：使用托管 Postgres 服务或具有定期备份的专用实例。`DATABASE_URL` 支持所有标准 libpq 参数，包括用于加密连接的 `sslmode=require`。
* **TLS**：在服务器和仪表板前面部署反向代理（nginx、Caddy、Traefik）来终止 TLS。
* **防火墙**：服务器端口（默认 8080）应仅对采集器机器和仪表板主机开放，不得暴露到公网。
* **管理员密钥**：将 `ADMIN_KEY` 设置为强随机密钥。完成初始化后，为采集器和仪表板创建专用的有限权限密钥，而不是到处使用管理员密钥。
* **镜像标签**：生产环境中请固定使用发布 manifests 中指定的版本（例如 `server:v0.0.1-beta.48`），而非浮动标签，以避免意外升级。当前 beta 构建版本发布于 `beta-latest`；`latest` 仅在稳定版本发布时才会更新。
* **健康监控**：在 Kubernetes 上，就绪探针使用 `/ready`（检查 Postgres + ClickHouse 可达性），存活探针保持使用 `/health`。如需对 AgentEye 整体状态的 Slack 告警，请启用可选的 Robusta 插件；详见 [enterprise-docs/health-monitoring.md](/zh/agenteye/health-monitoring)。

***

## 可用镜像标签

| 标签            | 说明                               |
| ------------- | -------------------------------- |
| `latest`      | 最新稳定版本                           |
| `beta-latest` | 最新预发布版本（beta）                    |
| `v<version>`  | 固定版本，例如 `v0.0.1-beta.48`（生产环境推荐） |
