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

# 环境变量

> FIM One 的完整配置参考。

所有配置都通过 `.env` 完成。复制 `example.env` 并填入你的值：

```bash theme={null}
cp example.env .env
```

## 配置级别

每个集成都有一个配置级别，表示其重要性：

| 级别     | 含义      | 未配置时的行为                 |
| ------ | ------- | ----------------------- |
| **必需** | 核心系统依赖  | 系统将出错 — 聊天和主要功能将无法工作    |
| **推荐** | 重要功能启用器 | 优雅降级 — 该功能明显不可用，但系统继续运行 |
| **可选** | 增强功能    | 透明降级 — 系统运行正常，该功能不存在    |

> **注意**：管理员配置的模型（管理员 → 模型页面）可以替代 LLM 环境变量。健康检查会考虑两个来源。

***

## 前端（仅本地开发）

前端有一个仅用于本地开发的独立环境文件：`frontend/.env.local`。

> **此文件在 Docker 中不使用。** 在 Docker 容器内，Next.js 在内部将 `/api/*` 代理到 Python 后端（端口 8000 是容器内部的），因此不需要前端环境文件。

对于本地开发，默认设置开箱即用 — 除非你的后端运行在非默认端口，否则**不需要**创建 `frontend/.env.local`。

如果需要覆盖，请手动创建 `frontend/.env.local`：

```bash theme={null}
echo 'NEXT_PUBLIC_API_URL=http://localhost:9000' > frontend/.env.local
```

| 变量                    | 默认值                            | 描述                                                                                                |
| --------------------- | ------------------------------ | ------------------------------------------------------------------------------------------------- |
| `NEXT_PUBLIC_API_URL` | `http://localhost:8000` *（自动）* | **浏览器**用于直接 API 调用（OAuth 重定向、流式传输）的后端 URL。如果未设置，则从 `window.location` 自动检测 — 仅当后端在本地运行于非标准端口时才需覆盖。 |

> **构建时注意**：`NEXT_PUBLIC_*` 变量在 `pnpm build` 时被烘焙到 JS 包中。在运行时更改它们（例如通过根目录 `.env`）无效 — 这就是为什么它们仅存在于本地开发的 `frontend/.env.local` 中。

## LLM（必需）

| 变量                                | 必需    | 默认值                                   | 描述                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| --------------------------------- | ----- | ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `LLM_API_KEY`                     | **是** | —                                     | LLM 提供商的 API 密钥                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `LLM_BASE_URL`                    | 否     | `https://api.openai.com/v1`           | 任何 OpenAI 兼容 API 的基础 URL                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `LLM_MODEL`                       | 否     | `gpt-4o`                              | 主模型——用于规划、分析和 ReAct 智能体                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `FAST_LLM_MODEL`                  | 否     | *（回退到 `LLM_MODEL`）*                   | 快速模型——用于 DAG 步骤执行（更便宜、更快）                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `LLM_TEMPERATURE`                 | 否     | `0.7`                                 | 默认采样温度                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `LLM_CONTEXT_SIZE`                | 否     | `128000`                              | 主 LLM 的上下文窗口大小                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `LLM_MAX_OUTPUT_TOKENS`           | 否     | `64000`                               | 主 LLM 每次调用的最大输出令牌数                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `FAST_LLM_API_KEY`                | 否     | *（回退到 `LLM_API_KEY`）*                 | 快速模型提供商的 API 密钥。当快速模型由与主模型不同的提供商托管时使用                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `FAST_LLM_BASE_URL`               | 否     | *（回退到 `LLM_BASE_URL`）*                | 快速模型提供商的基础 URL                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `FAST_LLM_TEMPERATURE`            | 否     | *（回退到 `LLM_TEMPERATURE`）*             | 快速模型的采样温度                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `FAST_LLM_CONTEXT_SIZE`           | 否     | *（回退到 `LLM_CONTEXT_SIZE`）*            | 快速 LLM 的上下文窗口大小                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `FAST_LLM_MAX_OUTPUT_TOKENS`      | 否     | *（回退到 `LLM_MAX_OUTPUT_TOKENS`）*       | 快速 LLM 每次调用的最大输出令牌数                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `LLM_REASONING_EFFORT`            | 否     | *（禁用）*                                | 支持的模型的扩展思考级别（OpenAI o 系列、Gemini 2.5+、Claude）。值：`low`、`medium`、`high`。LiteLLM 自动将其转换为每个提供商的原生格式。模型的思维链在 UI"思考"步骤中显示。                                                                                                                                                                                                                                                                                                                                                  |
| `LLM_REASONING_BUDGET_TOKENS`     | 否     | *（从努力级别自动计算）*                         | Anthropic 思考的显式令牌预算（最小 1024）。对于 OpenAI/Gemini，直接使用努力级别。仅在设置 `LLM_REASONING_EFFORT` 时有效。                                                                                                                                                                                                                                                                                                                                                                              |
| `FIM_GPT5_RESPONSES_MODE`         | 否     | `native`                              | GPT-5.x 模型使用的协议。`native` 直接与 OpenAI Responses API 通信，并重放每轮的加密推理，使模型在工具调用间保持思维链。`bridge` 使用 LiteLLM 的聊天完成翻译，可行但每轮重新推导推理。`off` 强制使用普通聊天完成，当存在工具时推理被禁用。除非调试，否则不设置；没有 `/v1/responses` 路由的端点会自行回退。仅适用于 GPT-5.x。                                                                                                                                                                                                                                                           |
| `LLM_JSON_MODE_ENABLED`           | 否     | `true`                                | `response_format=json_object` 的全局开关。如果您的提供商拒绝 LiteLLM 的助手前缀注入（例如 AWS Bedrock 中继 → 第 2+ 个智能体迭代上的 `ValidationException`），设置为 `false`。禁用时，结构化调用跳过 JSON 模式并回退到纯文本正则表达式提取——无质量损失。适用于所有模型（ENV 配置和管理员配置）。                                                                                                                                                                                                                                                                   |
| `LLM_TOOL_CHOICE_ENABLED`         | 否     | `true`                                | 结构化输出提取中强制 `tool_choice` 的全局开关（级别 1——原生函数调用）。如果您的模型在强制工具选择时返回错误（例如拒绝 `tool_choice='specified'` 的思考模式模型），设置为 `false`。禁用时，结构化调用跳过原生 FC 并从 JSON 模式开始。每个模型的覆盖可在设置 → 模型 → 高级中使用。                                                                                                                                                                                                                                                                                          |
| `REASONING_LLM_MODEL`             | 否     | *（回退到 `LLM_MODEL`）*                   | 推理层的模型名称。用于需要深度分析的任务（例如 DAG 规划、计划分析）                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `REASONING_LLM_API_KEY`           | 否     | *（回退到 `LLM_API_KEY`）*                 | 推理模型提供商的 API 密钥                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `REASONING_LLM_BASE_URL`          | 否     | *（回退到 `LLM_BASE_URL`）*                | 推理模型提供商的基础 URL                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `REASONING_LLM_TEMPERATURE`       | 否     | *（回退到 `LLM_TEMPERATURE`）*             | 推理模型的采样温度                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `REASONING_LLM_CONTEXT_SIZE`      | 否     | *（回退到 `LLM_CONTEXT_SIZE`）*            | 推理模型的上下文窗口大小                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `REASONING_LLM_MAX_OUTPUT_TOKENS` | 否     | *（回退到 `LLM_MAX_OUTPUT_TOKENS`）*       | 推理模型每次调用的最大输出令牌数                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `REASONING_LLM_EFFORT`            | 否     | *（回退到 `LLM_REASONING_EFFORT`）*        | 推理模型层的推理努力级别。值：`low`、`medium`、`high`                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `REASONING_LLM_BUDGET`            | 否     | *（回退到 `LLM_REASONING_BUDGET_TOKENS`）* | 推理的令牌预算（主要用于 Anthropic）。覆盖推理层的自动计算预算                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `LLM_SUPPORTS_VISION`             | 否     | `true` *（乐观）*                         | 控制是否尝试 ENV 模式文档 OCR（通过 MarkItDown + `markitdown-ocr`）。仅在**管理员 → 模型中未配置活跃模型组**时适用（纯 ENV 模式）。当默认 `true` 生效时，`convert_to_markdown` 和 RAG 摄取假设 `LLM_MODEL` 支持视觉并为图像 OCR 调用它——这对所有常见选择（`gpt-4o`、`claude-3-5-sonnet`、`gemini-1.5-pro/flash`）是正确的行为。当您的 ENV 配置的 `LLM_MODEL` **不**支持视觉时（例如 `deepseek-v3`、`qwen-chat`、`llama-3.1`、`gpt-3.5-turbo`、`o1-mini`），设置为 `false` 以跳过失败的视觉调用并直接进行纯文本提取。当管理员 → 模型面板中存在活跃模型组时，此标志被忽略，该组的 `supports_vision` 标志接管——管理员策划的选择始终是数据库模式中的真实来源。 |

> **解析顺序**：用户偏好 → 管理员模型（数据库）→ ENV 回退。如果在管理员 → 模型中配置了角色为"通用"的管理员模型，这些 ENV 变量仅作为回退。健康检查考虑两个来源。

### MarkItDown OCR 分辨率

`convert_to_markdown` 内置工具和 RAG 摄取管道都使用 Microsoft 的 [MarkItDown](https://github.com/microsoft/markitdown) + 官方 [`markitdown-ocr`](https://github.com/microsoft/markitdown/tree/main/packages/markitdown-ocr) 插件从文档中提取文本 — 包括在有支持视觉的 LLM 可用时对嵌入图像和扫描 PDF 页面进行 OCR。

**视觉 LLM 分辨率顺序**（首次匹配获胜）：

| # | 来源                                           | 优先级原因                                                                              |
| - | -------------------------------------------- | ---------------------------------------------------------------------------------- |
| 1 | 智能体的**主要 LLM**（如果 `supports_vision=True`）    | 一致性：相同的 API 密钥、相同的计费桶、与对话相同的速率限制池。                                                 |
| 2 | 活跃的**模型组 → 快速模型**（如果 `supports_vision=True`） | 快速模型（`gpt-4o-mini`、`claude-haiku`、`gemini-1.5-flash`）是理想的 OCR 工具 — 便宜、低延迟、通常支持多模态。 |
| 3 | 活跃的**模型组 → 通用模型**（如果 `supports_vision=True`） | 当主要模型不在组中时的质量备选方案。                                                                 |
| 4 | **ENV 主要 LLM**（`LLM_MODEL`）                  | 纯 ENV 模式的乐观备选方案。仅在不存在活跃模型组时采用。由 `LLM_SUPPORTS_VISION` 控制。                          |

**推理模型永远不会被优先选择用于 OCR。** 推理层级（`o1`、`o3-mini`、`DeepSeek-R1`）历来缺乏视觉支持，本身也不是 OCR 的合适工具 — OCR 是一项感知任务，而非推理任务。如果工作区仅有一个支持视觉的推理模型（`supports_vision=True`），它仍会通过主要 LLM 路径被选中，但解析器不会主动将其排名高于快速/通用模型。

**零回归备选方案**：当在任何级别都找不到支持视觉的模型时，OCR 会被静默禁用，MarkItDown 以纯文本模式运行。Word/PowerPoint/Excel 嵌入图像 OCR 变为不可用（与此功能发布前相同），但所有其他文本提取（标题、表格、段落文本）继续正常工作。**不存在添加此功能使提取效果比之前行为更差的情况。**

**非 OpenAI 提供商（Anthropic、Google Gemini 等）** 得到透明支持：解析的 LLM 被包装在 `LiteLLMOpenAIShim` 中，该 shim 将 `chat.completions.create(...)` 调用路由通过 `litellm.completion()`，后者处理提供商特定的消息格式转换（例如 Anthropic 的 `source.type="base64"` 图像块）。一个 shim 覆盖 LiteLLM 支持的每个提供商 — 添加新提供商在 FIM One 中零代码更改成本。

### 扩展思维（推理）

当设置 `LLM_REASONING_EFFORT` 时，FIM One 启用模型的扩展思维能力，使内部思维链在 UI 的"思维"步骤中显示。FIM One 使用 [LiteLLM](https://github.com/BerriAI/litellm) 自动将推理努力参数转换为每个提供商的原生格式。

#### 支持的提供商

哪些提供商接受思考、如何启用每个提供商、它采用哪些`effort`值，以及推理文本最终出现在哪里，这些信息都记录在[提供商能力矩阵的表C](/architecture/llm-provider-guide#provider-capability-matrix)中，并带有代码锚点。该表是权威列表；本页面仅记录变量。

FIM One从`LLM_BASE_URL`解析提供商（加上配置时的显式提供商字段），并将请求映射到正确的API格式。未知的URL被视为OpenAI兼容。

#### 重要注意事项

<Warning>
  **第三方代理 / 自定义端点不保证兼容。**
  如果您的 `LLM_BASE_URL` 指向第三方 API 代理（例如 OpenRouter、one-api、自定义网关），LiteLLM 将尝试根据 URL 正确路由。但是，如果您的代理需要非标准格式，推理可能无法按预期工作。请查阅代理的文档以了解其预期的参数格式。
</Warning>

#### 推理时的温度约束

某些提供商在启用推理时会限制`temperature`。**这些限制都会自动强制执行；请根据您的工作负载需求设置`LLM_TEMPERATURE`。**

* **Anthropic**：启用扩展思考时需要`temperature=1`。请求构建器会在Anthropic路由上固定该值，因此您配置的温度会被这些调用覆盖，而不是被拒绝。
* **Anthropic、严格模型**（Opus 4.7和4.8、Fable 5、Mythos 5）：无论是否启用思考，都会直接拒绝`temperature`、`top_p`和`top_k`。FIM One会从这些模型的请求中移除`temperature`。
* **OpenAI GPT-5.x**：仅支持`temperature=1`。LiteLLM的`drop_params`过滤会移除不支持的值。

手动设置`LLM_TEMPERATURE=1`来满足Anthropic的要求是不必要的，这样做会让您无法在每个非思考调用上运行更低的温度。

#### `LLM_REASONING_BUDGET_TOKENS` 的工作原理

此变量**仅在旧版 Anthropic 思考路径上有意义**（Claude 4.5 及更早版本，路由为 `anthropic/`）。在该路径上，它会覆盖自动计算的预算，并作为 `budget_tokens` 在 `thinking` 参数内发送。自适应思考模型（Opus 4.6 及更新版本、Sonnet 4.6、Fable 5、Mythos 5）采用努力级别而非预算，完全忽略此变量。未设置时，预算从 `LLM_MAX_OUTPUT_TOKENS` × 努力比率推导：

| `LLM_REASONING_EFFORT` | 预算比率 | 示例（max\_tokens = 64000） |
| ---------------------- | ---- | ----------------------- |
| `low`                  | 20%  | 12,800 tokens           |
| `medium`               | 50%  | 32,000 tokens           |
| `high`                 | 80%  | 51,200 tokens           |

最小预算为 1,024 tokens（Anthropic 的硬性最低值）。

对于 OpenAI 和 Gemini，提供商根据 `reasoning_effort` 级别在内部处理令牌分配——`LLM_REASONING_BUDGET_TOKENS` 无效。

## 智能体执行

### ReAct 智能体

| 变量                                  | 必需 | 默认值     | 描述                                                                                                                                                                                      |
| ----------------------------------- | -- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `REACT_MAX_ITERATIONS`              | 否  | `20`    | 每个 ReAct 请求的最大工具调用迭代次数。值越高越彻底，但速度越慢且成本越高                                                                                                                                                |
| `REACT_MAX_TURN_TOKENS`             | 否  | `0`     | 紧急断路器：单个 ReAct 轮次的最大累积令牌数（所有迭代的提示词 + 完成）。默认 `0` = 无限制。**这不是用于日常令牌控制的**——请使用按用户的 `token_quota`。这是针对极端场景（如智能体陷入无限工具调用循环）的最后防线。触发此限制会中止任务执行，浪费已消耗的所有令牌并返回不完整结果。除非有特定的失控智能体问题需要处理，否则保持为 `0` |
| `REACT_TOOL_SELECTION_THRESHOLD`    | 否  | `12`    | 当注册工具总数超过此阈值时，轻量级 LLM 调用会在每个请求前选择最相关的子集                                                                                                                                                 |
| `REACT_TOOL_SELECTION_MAX`          | 否  | `6`     | 智能选择后保留的最大工具数（仅当工具数超过 `REACT_TOOL_SELECTION_THRESHOLD` 时有效）                                                                                                                             |
| `REACT_SELF_REFLECTION_INTERVAL`    | 否  | `6`     | 每 N 次工具调用后注入一次自反思提示词，帮助智能体纠正方向并避免循环                                                                                                                                                     |
| `REACT_TOOL_OBS_TRUNCATION`         | 否  | `8000`  | 合成最终答案时每个工具观察的最大字符数。较高的值保留更多结构化数据（JSON、表格），但消耗更多令牌                                                                                                                                      |
| `REACT_TOOL_RESULT_BUDGET`          | 否  | `40000` | 单个会话中所有工具结果的聚合令牌预算。当工具结果令牌总数超过此上限时，新结果会被截断并附加通知。防止大型 API 响应（例如 5 个连接器调用各返回 8K）导致的上下文膨胀。设为 `0` 禁用此上限                                                                                     |
| `REACT_COMPLETION_CHECK_SKIP_CHARS` | 否  | `800`   | 当智能体的最终答案超过此字符数时，跳过答案后完成度检查 LLM 调用。长详细答案不需要"我是否遗漏了什么？"验证往返。设置较低值可更激进地跳过；设置为非常大的值可始终运行检查                                                                                                 |
| `REACT_CYCLE_DETECTION_THRESHOLD`   | 否  | `2`     | 当同一工具连续以相同参数调用此次数时，会注入确定性警告，告诉智能体尝试不同方法。与依赖 LLM 发现循环的自反思不同，这是基于哈希的检查，无法被绕过。也适用于 DAG 步骤                                                                                                  |
| `REACT_COMPLETION_CHECK_MIN_TOOLS`  | 否  | `3`     | 完成度检查清单启动前的最小工具调用次数。简单任务（1-2 次工具调用）跳过验证以避免不必要的延迟。设为 `1` 可始终启用验证。也适用于 DAG 步骤                                                                                                             |
| `REACT_TURN_PROFILE_ENABLED`        | 否  | `true`  | 发出按轮次阶段级别的计时日志（`memory_load`、`compact`、`tool_schema_build`、`llm_first_token`、`llm_total`、`tool_exec`）。每轮一行结构化日志。设为 `false` 禁用分析（零开销）                                                    |
| `REACT_PLAN_TOOL_ENABLED`           | 否  | `true`  | 注册 `update_plan` 待办工具，使智能体在多步任务期间记录和维护计划检查清单。对于 DAG 步骤智能体和无工具的智能体自动跳过                                                                                                                   |
| `REACT_PLAN_REMINDER_INTERVAL`      | 否  | `3`     | 在注入陈旧计划提醒前，未调用 `update_plan` 的工具轮次数（嵌入完整检查清单），使计划在上下文压缩中保留                                                                                                                              |
| `REACT_PLAN_REPEAT_THRESHOLD`       | 否  | `4`     | 连续轮次调用同一工具（使用不同参数）的次数，之后提醒告诉智能体改变方法而不是重复无效调用。完全重复的调用由循环检测单独处理                                                                                                                           |
| `REACT_PLAN_NUDGE_AFTER`            | 否  | `5`     | 未记录计划的工具轮次数，之后一次性推动建议记录计划。仅在计划工具启用时适用                                                                                                                                                   |
| `REACT_FINISH_SIGNAL`               | 否  | `true`  | 聊天路径上的 FINAL 优先应答：智能体在 `finish` 信号上结束工具循环，然后将答案作为真正令牌流式传输的轮次写入。设为 `false` 恢复内联循环答案与缓冲重放                                                                                                 |
| `REACT_MAX_CONTINUATIONS`           | 否  | `3`     | 当模型答案被提供商的输出令牌限制截断时的最大续接轮次（`finish_reason=length`）。截断的段落被拼接成一个无缝答案，既在智能体循环中也在流式合成中                                                                                                      |
| `REACT_BACKGROUND_TOOLS_ENABLED`    | 否  | `true`  | 在慢速工具（沙箱 python/shell/node 执行）上提供 `run_in_background` 选项。智能体立即获得任务 id 并继续工作；工具完成时结果作为 `<task_notification>` 消息到达                                                                        |
| `REACT_BG_WAIT_TIMEOUT`             | 否  | `300`   | 智能体想要最终确定答案时等待仍在运行的后台工具的最大秒数。窗口内未完成的任务被取消并显示明确的超时通知                                                                                                                                     |
| `DAG_CHECKPOINT_EVIDENCE_CHARS`     | 否  | `4000`  | DAG 崩溃恢复检查点文件（`data/dag_checkpoints/`）中每步的证据上限。步骤摘要完整存储                                                                                                                                 |
| `DAG_CHECKPOINT_MAX_AGE_HOURS`      | 否  | `24`    | 超过此时间的 DAG 检查点在加载时被忽略，因此陈旧的崩溃遗留物永远不会恢复到新运行中                                                                                                                                             |
| `LLM_RATE_LIMIT_PER_USER`           | 否  | `true`  | 使用按用户键控的速率限制桶而不是单个进程全局桶。防止一个嘈杂用户在同一工作进程上饿死所有其他用户。底层速率硬编码为每个桶每分钟 60 个请求和 100K 个令牌——此设置仅控制桶是共享（全局）还是分区（按用户）。设为 `false` 恢复到旧版全局桶（不推荐）                                                      |

### DAG 规划器

| 变量                               | 必需 | 默认值     | 描述                                                                                                                                                                                              |
| -------------------------------- | -- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `MAX_CONCURRENCY`                | 否  | `5`     | DAG 执行器中的最大并行步骤数                                                                                                                                                                                |
| `DAG_STEP_MAX_ITERATIONS`        | 否  | `15`    | 每个 DAG 步骤内的最大工具调用迭代次数                                                                                                                                                                           |
| `DAG_STEP_TIMEOUT`               | 否  | `600`   | 步骤执行超时时间（秒）。超过此时间的步骤标记为失败，其依赖步骤级联跳过                                                                                                                                                             |
| `DAG_MAX_REPLAN_ROUNDS`          | 否  | `3`     | 目标未达成时的最大自主重新规划尝试次数。用户中断（注入）次数不限，不计入此预算                                                                                                                                                         |
| `DAG_REPLAN_STOP_CONFIDENCE`     | 否  | `0.8`   | 仅在智能体判断目标**不可达**（不可能的请求、功能缺失、资源失效）时适用：在达到或超过此确定性时停止重试。缺失或未完成的交付物始终会重新规划，无论置信度如何——仅 `DAG_MAX_REPLAN_ROUNDS` 限制这些重试                                                                               |
| `DAG_VERIFY_TRUNCATION`          | 否  | `2000`  | 发送给步骤验证器 LLM 进行质量判断的步骤输出最大字符数                                                                                                                                                                   |
| `DAG_ANALYZER_TRUNCATION`        | 否  | `10000` | 格式化用于执行后分析器的每个步骤结果的最大字符数                                                                                                                                                                        |
| `DAG_STEP_EVIDENCE_CHARS`        | 否  | `16000` | 每个步骤保留的原始工具输出（网页获取、搜索结果、文件读取）最大字符数，作为权威"源证据"。这些数据与步骤的摘要一起提供给分析器和最终合成，以便答案的事实声明（总数、枚举、严重程度）可以针对源进行验证，而不是依赖可能已无声地丢弃或错误标记项目的摘要。设置为 `0` 禁用证据捕获                                                      |
| `DAG_REPLAN_RECENT_TRUNCATION`   | 否  | `500`   | 构建重新规划上下文时来自最近一轮的每个步骤结果的最大字符数                                                                                                                                                                   |
| `DAG_REPLAN_OLDER_TRUNCATION`    | 否  | `200`   | 构建重新规划上下文时来自较早轮次的每个步骤结果的最大字符数。较早轮次的结果更激进地截断以节省上下文                                                                                                                                               |
| `DAG_TOOL_CACHE`                 | 否  | `true`  | 在单个 DAG 执行中缓存相同的工具调用。仅缓存显式标记为 `cacheable` 的工具（搜索、知识检索等只读工具）。设置为 `false` 完全禁用缓存                                                                                                                  |
| `DAG_STEP_VERIFICATION`          | 否  | `false` | 每个 DAG 步骤后的通用 LLM 质量检查。失败时，步骤使用反馈重试一次。**默认关闭**——在每个步骤上增加延迟，很少需要；大多数步骤输出无需重新检查即可接受。仅在观察到频繁的低质量步骤结果时使用                                                                                            |
| `DAG_CITATION_VERIFICATION`      | 否  | `true`  | 专业领域步骤的引用准确性检查。**前置条件**：查询必须首先由 LLM 领域分类器分类为专业领域（参见 `ESCALATION_DOMAINS`）。当检测到该领域且此标志为 `true` 时，每个完成的步骤都会扫描法律/医学/财务引用并验证准确性——捕获幻觉的文章编号、虚构的案例参考和不正确的监管引用。如果领域分类返回 `null`（通用查询），则无论此设置如何，引用验证都不运行 |
| `DAG_CITATION_VERIFY_TRUNCATION` | 否  | `6000`  | 发送给引用验证提示的步骤结果最大字符数                                                                                                                                                                             |

### 领域分类

控制独立的基于LLM的领域检测层，在ReAct和DAG执行**之前**运行。当查询被分类为专家领域时，系统激活领域感知功能：升级到推理模型、领域特定的SOP指令和引用验证（仅DAG）。

| 变量                   | 必需 | 默认值                                             | 描述                                                                                                                                                           |
| -------------------- | -- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `ESCALATION_DOMAINS` | 否  | `legal,medical,financial,tax,compliance,patent` | 专家领域的逗号分隔列表。快速LLM根据此列表对每个查询进行分类。匹配时，系统：(1) 升级到推理模型以获得更高的准确性，(2) 注入领域特定的SOP指令（例如在写入前通过搜索验证引用），(3) 为DAG步骤启用引用验证。根据需要添加自定义领域（例如 `legal,education,construction`） |

### 上下文守卫

控制自动上下文窗口管理，防止对话超过模型的限制。

| 变量                             | 必需 | 默认值     | 描述                                |
| ------------------------------ | -- | ------- | --------------------------------- |
| `CONTEXT_GUARD_DEFAULT_BUDGET` | 否  | `32000` | 上下文窗口管理的默认令牌预算。当对话超过此值时，较早的消息会被压缩 |
| `CONTEXT_GUARD_MAX_MSG_CHARS`  | 否  | `50000` | 任何单条消息的硬字符限制。超过此限制的消息会被截断作为安全网    |
| `CONTEXT_GUARD_KEEP_RECENT`    | 否  | `4`     | 压缩对话历史时保留的最近消息数                   |

### 内容护栏

逗号分隔的护栏名称，用于检查*内容*的输入或输出。独立于工具权限闸门（`core/hooks/*`）和安全层（`core/security/*`）。详见[内容护栏](/configuration/guardrails)。

| 变量                               | 必需 | 默认值         | 描述                                                                                  |
| -------------------------------- | -- | ----------- | ----------------------------------------------------------------------------------- |
| `FIM_GUARDRAILS_INPUT`           | 否  | `jailbreak` | 活跃的输入护栏。默认的`jailbreak`正则表达式检测器在检测到已知的提示词覆盖短语时会在花费任何LLM令牌之前中止该轮次。设置为空以禁用。未知名称会被记录并跳过 |
| `FIM_GUARDRAILS_OUTPUT`          | 否  | （空）         | 活跃的输出护栏。当前包含：`max_length`（限制答案字符数）。在智能体生成最终答案后运行                                    |
| `FIM_GUARDRAIL_MAX_OUTPUT_CHARS` | 否  | `50000`     | `max_length`输出护栏使用的字符上限。仅当`max_length`列在`FIM_GUARDRAILS_OUTPUT`中时有效                 |

### 智能体工作区

| 变量                            | 必需 | 默认值    | 描述                                          |
| ----------------------------- | -- | ------ | ------------------------------------------- |
| `WORKSPACE_OFFLOAD_THRESHOLD` | 否  | `8000` | 当工具输出超过这么多字符时，它会被保存到工作区文件中，并将截断的预览注入到对话上下文中 |
| `WORKSPACE_PREVIEW_CHARS`     | 否  | `2000` | 截断的工作区引用中包含的预览字符数                           |
| `WORKSPACE_CLEANUP_MAX_HOURS` | 否  | `72`   | 超过这么多小时的工作区文件符合自动清理的条件                      |

### System

| Variable                    | Required | Default | Description                                                                                                                                                   |
| --------------------------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ~~`SYSTEM_PROMPT_RESERVE`~~ | —        | —       | **已移除。** 之前从上下文预算中减去固定的4K预留用于系统提示词。这导致了重复计算，因为ContextGuard在估计消息列表令牌时已经包含了系统提示词。预算公式现在为`(context_size - max_output_tokens) × 0.92`（该边际吸收令牌估计误差），系统提示词的实际大小动态计算 |

***

## Web 工具（可选）

| 变量                    | 必需 | 默认值                         | 描述                                                                                                                          |
| --------------------- | -- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `JINA_API_KEY`        | 否  | —                           | Jina API 密钥。为**默认**搜索后端提供支持，并在未设置服务特定密钥时充当**获取、嵌入和重排序**的共享备用方案。在 [jina.ai](https://jina.ai/) 获取                             |
| `TAVILY_API_KEY`      | 否  | —                           | Tavily 搜索 API 密钥。当 `WEB_SEARCH_PROVIDER=tavily` 时必需；如果提供商未设置，自动检测也会使用它                                                      |
| `BRAVE_API_KEY`       | 否  | —                           | Brave 搜索 API 密钥。当 `WEB_SEARCH_PROVIDER=brave` 时必需；如果提供商未设置，自动检测也会使用它                                                        |
| `EXA_API_KEY`         | 否  | —                           | Exa 搜索 API 密钥。当 `WEB_SEARCH_PROVIDER=exa` 时必需；如果提供商未设置，自动检测也会使用它。参见 [Exa](/integrations/exa)。在 [exa.ai](https://exa.ai/) 获取 |
| `WEB_SEARCH_PROVIDER` | 否  | `jina`                      | 搜索提供商选择器：`jina`（默认）/ `tavily` / `brave` / `exa`。使用非默认提供商时建议明确设置此项                                                           |
| `WEB_FETCH_PROVIDER`  | 否  | `jina`（如果设置了密钥，否则为 `httpx`） | 获取提供商：`jina`（使用 Jina Reader API）/ `httpx`（直接 HTTP 请求，无需 API 密钥）                                                             |

> **快速开始提示**：仅设置 `JINA_API_KEY` 即可启用默认 Web 搜索堆栈、Web 获取、嵌入和重排序——一个密钥，四项服务。通过 `WEB_SEARCH_PROVIDER` 和匹配的 API 密钥将搜索切换到 Tavily、Brave 或 Exa。

## RAG 与知识库（推荐）

### 嵌入

嵌入将文本转换为向量以进行知识库搜索。FIM One 使用标准的 **OpenAI 兼容 `/v1/embeddings` 端点**，因此它适用于任何公开此接口的提供商 — 不仅仅是 Jina。

| 变量                    | 必需 | 默认值                      | 描述            |
| --------------------- | -- | ------------------------ | ------------- |
| `EMBEDDING_API_KEY`   | 否  | *(回退到 `JINA_API_KEY`)*   | 嵌入提供商的 API 密钥 |
| `EMBEDDING_BASE_URL`  | 否  | `https://api.jina.ai/v1` | 嵌入提供商的基础 URL  |
| `EMBEDDING_MODEL`     | 否  | `jina-embeddings-v3`     | 模型标识符         |
| `EMBEDDING_DIMENSION` | 否  | `1024`                   | 向量维度          |

**提供商示例** — 只需设置这三个变量即可切换：

| 提供商               | `EMBEDDING_BASE_URL`          | `EMBEDDING_MODEL`        | `EMBEDDING_DIMENSION` |
| ----------------- | ----------------------------- | ------------------------ | --------------------- |
| **Jina** *(默认)*   | `https://api.jina.ai/v1`      | `jina-embeddings-v3`     | `1024`                |
| **OpenAI**        | `https://api.openai.com/v1`   | `text-embedding-3-small` | `1536`                |
| **Voyage**        | `https://api.voyageai.com/v1` | `voyage-3`               | `1024`                |
| **Ollama** *(本地)* | `http://localhost:11434/v1`   | `nomic-embed-text`       | `768`                 |

<Warning>
  **更改嵌入模型或维度会使所有现有知识库向量失效。** 旧向量是在不同的嵌入空间中计算的 — 检索准确性将无声地降低。切换后，您必须**重建所有知识库索引**。
</Warning>

### 检索

| 变量               | 必需 | 默认值         | 描述                                            |
| ---------------- | -- | ----------- | --------------------------------------------- |
| `RETRIEVAL_MODE` | 否  | `grounding` | `grounding`（带引用和置信度评分的完整管道）或 `simple`（基础 RAG） |

### 重排器

重排器对检索到的文档重新评分以提高相关性。支持三个提供商 — 通过 `RERANKER_PROVIDER` 选择或让系统从可用的 API 密钥自动检测。

| 变量                      | 必需 | 默认值                                  | 描述                                                                             |
| ----------------------- | -- | ------------------------------------ | ------------------------------------------------------------------------------ |
| `RERANKER_PROVIDER`     | 否  | *(自动检测)*                             | `jina` / `cohere` / `openai`。如果未设置：如果设置了 `COHERE_API_KEY` 则使用 Cohere，否则使用 Jina |
| `RERANKER_MODEL`        | 否  | `jina-reranker-v2-base-multilingual` | 模型标识符（适用于 Jina 和 OpenAI 提供商）                                                   |
| `COHERE_API_KEY`        | 否  | —                                    | Cohere API 密钥（当设置且 `RERANKER_PROVIDER` 未设置时自动选择 Cohere 重排器）                    |
| `COHERE_RERANKER_MODEL` | 否  | `rerank-multilingual-v3.0`           | Cohere 特定的重排器模型                                                                |

> **Jina** 使用 `JINA_API_KEY`（来自上面的 Web 工具）。**OpenAI** 复用 `LLM_API_KEY` / `LLM_BASE_URL` — 无需额外密钥。**Cohere** 需要其自己的 `COHERE_API_KEY`。

> 重排器是**可选的** — 知识库搜索可以在不使用它的情况下使用融合评分。对于知识库功能，**推荐**使用嵌入。

### 向量存储

| 变量                 | 必需 | 默认值                   | 描述                             |
| ------------------ | -- | --------------------- | ------------------------------ |
| `VECTOR_STORE_DIR` | 否  | `./data/vector_store` | LanceDB 向量存储数据的目录（基于文件，无需外部服务） |

***

## 代码执行

| 变量                     | 必需 | 默认值                | 描述                                                                                                    |
| ---------------------- | -- | ------------------ | ----------------------------------------------------------------------------------------------------- |
| `CODE_EXEC_BACKEND`    | 否  | `local`            | `local`（直接主机执行）或 `docker`（隔离容器）                                                                       |
| `DOCKER_PYTHON_IMAGE`  | 否  | `python:3.11-slim` | Python 执行的 Docker 镜像                                                                                  |
| `DOCKER_NODE_IMAGE`    | 否  | `node:20-slim`     | Node.js 执行的 Docker 镜像                                                                                 |
| `DOCKER_SHELL_IMAGE`   | 否  | `python:3.11-slim` | shell 执行的 Docker 镜像                                                                                   |
| `DOCKER_MEMORY`        | 否  | *（Docker 默认值）*     | 每个容器的 RAM 上限（例如 `256m`、`512m`、`1g`）                                                                   |
| `DOCKER_CPUS`          | 否  | *（Docker 默认值）*     | 每个容器的 CPU 配额（例如 `0.5`、`1.0`）                                                                          |
| `SANDBOX_TIMEOUT`      | 否  | `120`              | 默认执行超时时间（秒）                                                                                           |
| `DOCKER_HOST_DATA_DIR` | 否  | *（未设置）*            | `./data` 卷挂载的主机端绝对路径。DooD（Docker-outside-of-Docker）部署需要此项；`docker-compose.yml` 通过 `${PWD}/data` 自动设置。 |

> **安全性**：`local` 模式直接在主机上运行 AI 生成的代码。对于面向互联网或多用户部署，始终设置 `CODE_EXEC_BACKEND=docker`。

***

## 工具制品

工具执行（代码执行、模板渲染、图像生成）产生的文件的大小限制。

| 变量                    | 必需 | 默认值                | 描述               |
| --------------------- | -- | ------------------ | ---------------- |
| `MAX_ARTIFACT_SIZE`   | 否  | `10485760` (10 MB) | 单个制品文件的最大大小（字节）  |
| `MAX_ARTIFACTS_TOTAL` | 否  | `52428800` (50 MB) | 每个会话的制品总大小上限（字节） |

***

## 文档处理（可选）

控制上传的 PDF/DOCX 文件如何被处理以供 LLM 使用。具有视觉能力的模型（GPT-4o、Claude 3/4、Gemini）可以接收渲染后的 PDF 页面作为图像，以获得更高的保真度。

| 变量                          | 必需 | 默认值    | 描述                                                   |
| --------------------------- | -- | ------ | ---------------------------------------------------- |
| `DOCUMENT_PROCESSING_MODE`  | 否  | `auto` | `auto`（如果模型支持则使用视觉），`vision`（始终渲染页面），`text`（始终仅提取文本） |
| `DOCUMENT_VISION_DPI`       | 否  | `150`  | PDF 页面渲染的 DPI。更高 = 更好的质量，更多 token                    |
| `DOCUMENT_VISION_MAX_PAGES` | 否  | `20`   | 每个 PDF 渲染为图像的最大页数                                    |

> **注意**：每个模型的视觉支持通过管理员 → 模型中的 `supports_vision` 开关进行配置。未明确设置时，系统会从模型名称自动检测视觉能力。

## 图像生成（可选）

| 变量                   | 必需 | 默认值                              | 描述                                                                                           |
| -------------------- | -- | -------------------------------- | -------------------------------------------------------------------------------------------- |
| `IMAGE_GEN_PROVIDER` | 否  | `google`                         | `google`（Gemini 原生 API）或 `openai`（OpenAI 兼容 `/v1/images/generations`）                        |
| `IMAGE_GEN_API_KEY`  | 否  | —                                | Google AI Studio 密钥（`google`）或代理/OpenAI API 密钥（`openai`）                                     |
| `IMAGE_GEN_MODEL`    | 否  | `gemini-3.1-flash-image-preview` | 图像生成模型（例如 `dall-e-3`、`gemini-nano-banana-2`）                                                 |
| `IMAGE_GEN_BASE_URL` | 否  | *（按提供商）*                         | Google：`https://generativelanguage.googleapis.com/v1beta`；OpenAI：`https://api.openai.com/v1` |

***

## 电子邮件（SMTP）（推荐）

当设置了 `SMTP_HOST`、`SMTP_USER` 和 `SMTP_PASS` 时，自动注册 `email_send` 内置工具。

| 变量                       | 必需 | 默认值                | 描述                                                                                             |
| ------------------------ | -- | ------------------ | ---------------------------------------------------------------------------------------------- |
| `SMTP_HOST`              | 条件 | —                  | SMTP 服务器主机名                                                                                    |
| `SMTP_PORT`              | 否  | `465`              | SMTP 端口                                                                                        |
| `SMTP_SSL`               | 否  | `ssl`              | TLS 模式：`ssl`（端口 465）/ `tls`（STARTTLS，端口 587）/ `none` 或 `""`（明文，凭证以明文发送）。任何其他值都会被拒绝，而不是静默回退到明文。 |
| `SMTP_USER`              | 条件 | —                  | SMTP 登录用户名                                                                                     |
| `SMTP_PASS`              | 条件 | —                  | SMTP 登录密码                                                                                      |
| `SMTP_FROM`              | 否  | *（使用 `SMTP_USER`）* | From 标头中显示的发件人地址                                                                               |
| `SMTP_FROM_NAME`         | 否  | —                  | From 标头中显示的显示名称                                                                                |
| `SMTP_REPLY_TO`          | 否  | —                  | Reply-To 地址；回复将发送到此处而不是 `SMTP_FROM`                                                            |
| `SMTP_ALLOWED_DOMAINS`   | 否  | —                  | 逗号分隔的域名允许列表（例如 `example.com,corp.io`）；阻止列表外域名的收件人                                              |
| `SMTP_ALLOWED_ADDRESSES` | 否  | —                  | 逗号分隔的精确地址允许列表；与 `SMTP_ALLOWED_DOMAINS` 结合使用；两者都不设置时允许任何收件人（不建议用于共享邮箱）                          |

***

## 连接器

| 变量                             | 必需 | 默认值           | 描述                                                                                                                                      |
| ------------------------------ | -- | ------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `CONNECTOR_RESPONSE_MAX_CHARS` | 否  | `50000`       | 非数组 JSON / 纯文本连接器响应的最大字符数                                                                                                               |
| `CONNECTOR_RESPONSE_MAX_ITEMS` | 否  | `10`          | 当连接器响应为 JSON 数组时保留的最大数组项数                                                                                                               |
| `CREDENTIAL_ENCRYPTION_KEY`    | 否  | *(未设置)*       | 用于连接器凭证 blob 的 Fernet 加密密钥。设置后，存储在 `connector_credentials` 中的身份验证令牌将被加密存储。如果未设置，凭证将以纯文本 JSON 形式存储（向后兼容）。更改此密钥将使所有现有加密凭证失效。              |
| `CONNECTOR_TOOL_MODE`          | 否  | `progressive` | 连接器工具如何暴露给智能体。`progressive`：单个 `ConnectorMetaTool`，带有 `discover`/`execute` 子命令（\~30 tokens/连接器）。`classic`：每个操作一个工具（旧版，\~250 tokens/操作）。 |
| `DATABASE_TOOL_MODE`           | 否  | `progressive` | 数据库连接器工具如何暴露给智能体。`progressive`：单个 `DatabaseMetaTool`，带有 `list_tables`/`discover`/`query` 子命令。`legacy`：每个数据库连接器每个操作一个工具（3 个工具）。          |
| `MCP_TOOL_MODE`                | 否  | `progressive` | MCP 服务器工具如何暴露给智能体。`progressive`：单个 `MCPServerMetaTool`，带有 `discover`/`call` 子命令。`legacy`：每个 MCP 服务器操作一个工具（原始单个工具）。                      |

***

## 平台

| 变量                               | 必需 | 默认值                                     | 描述                                                                                                                                                                          |
| -------------------------------- | -- | --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `DATABASE_URL`                   | 否  | `sqlite+aiosqlite:///./data/fim_one.db` | 数据库连接字符串。**SQLite**（零配置）：`sqlite+aiosqlite:///./data/fim_one.db`。**PostgreSQL**（生产环境）：`postgresql+asyncpg://user:pass@localhost:5432/fim_one`。Docker Compose自动配置PostgreSQL。 |
| `JWT_SECRET_KEY`                 | 否  | `CHANGE_ME`                             | JWT令牌签名的密钥。占位符值`CHANGE_ME`（或任何旧版默认值）会在首次启动时触发自动生成安全的256位随机密钥，并写回`.env`。在生产环境中显式设置以保持令牌在重启和副本间的有效性。                                                                          |
| `FIM_BCRYPT_COST`                | 否  | `12`                                    | bcrypt工作因子用于密码哈希，范围限制在4-31。默认值12在现代CPU上每次哈希耗时约200ms；在弱硬件上降低该值，在安全加固的部署中提高该值。                                                                                                |
| `CORS_ORIGINS`                   | 否  | —                                       | 逗号分隔的额外允许CORS源列表，超出默认localhost条目。当前端运行在非localhost域名上时需要（例如`https://app.example.com`）。                                                                                       |
| `UPLOADS_DIR`                    | 否  | `./uploads`                             | 上传文件的目录                                                                                                                                                                     |
| `EXPORT_FONT_DIR`                | 否  | *（自动检测）*                                | 存放`NotoSansSC-Regular.ttf` / `NotoSansSC-Bold.ttf`的目录，用于PDF导出。使用`python scripts/fetch_export_fonts.py`获取；Docker镜像已内置。没有可嵌入的TrueType CJK字体时，PDF导出会回退到非嵌入式CID字体，导致间距降级且无粗体。   |
| `MAX_UPLOAD_SIZE_MB`             | 否  | `50`                                    | 最大文件上传大小（单位：MB，后端强制）                                                                                                                                                        |
| `NEXT_PUBLIC_MAX_UPLOAD_SIZE_MB` | 否  | `50`                                    | 前端UI显示的最大文件上传大小。**构建时变量**——必须与`MAX_UPLOAD_SIZE_MB`匹配。                                                                                                                       |
| `MCP_SERVERS`                    | 否  | —                                       | MCP服务器配置的JSON数组（需要`uv sync --extra mcp`）                                                                                                                                    |
| `ALLOW_STDIO_MCP`                | 否  | `false`                                 | 允许stdio MCP服务器。仅在受信任的本地部署中设置为`true`                                                                                                                                         |
| `ALLOWED_STDIO_COMMANDS`         | 否  | `npx,uvx,node,python,python3,deno,bun`  | stdio MCP服务器允许的基础命令的逗号分隔列表。仅在`ALLOW_STDIO_MCP=true`时生效                                                                                                                      |
| `LOG_LEVEL`                      | 否  | `INFO`                                  | 日志级别：`DEBUG` / `INFO` / `WARNING` / `ERROR` / `CRITICAL`                                                                                                                    |
| `REDIS_URL`                      | 否  | —                                       | Redis连接URL用于跨工作进程中断中继。**当`WORKERS>1`时必需**——没有它，中流中断/注入请求可能会命中不同的工作进程而无声失败。由Docker Compose自动配置。                                                                              |
| `WORKERS`                        | 否  | `1`                                     | Uvicorn工作进程数。`1`是安全的，不需要外部服务。对于生产多工作进程，使用PostgreSQL（SQLite是单写入器）。SQLite在轻负载下适合本地开发。身份验证、OAuth和文件操作完全支持多工作进程（基于JWT）。Docker Compose自动配置PostgreSQL和Redis。                      |

<Warning>
  **多工作进程检查清单**（`WORKERS>1`）：

  * **停止（中止流式传输）**——始终有效，无需额外配置（信号在同一TCP连接上传输）。
  * **注入（中流后续）**——**需要`REDIS_URL`**。没有Redis，注入请求可能落在不同的工作进程上，该进程不知道正在运行的执行，导致无声失败。
  * **生产环境**：使用PostgreSQL（`DATABASE_URL`）。SQLite的单写入器锁在并发写入下可能导致争用。
  * **本地开发**：SQLite+多工作进程在轻使用下可以接受；如果使用注入功能，只需添加`REDIS_URL`。
</Warning>

## 工作流运行保留

自动清理旧工作流运行的后台任务。按工作流的覆盖设置（在工作流设置UI中配置）优先于这些全局默认值。

| 变量                                    | 必需 | 默认值   | 描述                       |
| ------------------------------------- | -- | ----- | ------------------------ |
| `WORKFLOW_RUN_MAX_AGE_DAYS`           | 否  | `30`  | 删除早于此天数的工作流运行            |
| `WORKFLOW_RUN_MAX_PER_WORKFLOW`       | 否  | `100` | 每个工作流最多保留此数量的运行（最旧的优先删除） |
| `WORKFLOW_RUN_CLEANUP_INTERVAL_HOURS` | 否  | `24`  | 后台清理任务运行的频率，单位为小时        |

### 通道确认请求过期

后台清理程序，将陈旧的待审批请求（由通道钩子如 `FeishuGateHook` 或审批演练场产生）标记为已过期。确保稍后点击被遗忘的卡片不会翻转已被拆除的智能体状态。

| 变量                                            | 必需 | 默认值    | 描述                         |
| --------------------------------------------- | -- | ------ | -------------------------- |
| `CHANNEL_CONFIRMATION_TTL_MINUTES`            | 否  | `1440` | 超过此时间的待确认请求将自动过期（默认值：24小时） |
| `CHANNEL_CONFIRMATION_SWEEP_INTERVAL_SECONDS` | 否  | `600`  | 过期清理程序运行的频率（默认值：每10分钟）     |

## OAuth（可选）

当为提供商同时设置 `CLIENT_ID` 和 `CLIENT_SECRET` 时，登录页面会自动显示相应的 OAuth 按钮。

| 变量                      | 必需       | 默认值                         | 描述                                                                                                                                    |
| ----------------------- | -------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `GITHUB_CLIENT_ID`      | 否        | —                           | GitHub OAuth 应用客户端 ID。在 [github.com/settings/developers](https://github.com/settings/developers) → OAuth Apps 创建                      |
| `GITHUB_CLIENT_SECRET`  | 否        | —                           | GitHub OAuth 应用客户端密钥                                                                                                                  |
| `GOOGLE_CLIENT_ID`      | 否        | —                           | Google OAuth 客户端 ID。在 [console.cloud.google.com/apis/credentials](https://console.cloud.google.com/apis/credentials) 创建               |
| `GOOGLE_CLIENT_SECRET`  | 否        | —                           | Google OAuth 客户端密钥                                                                                                                    |
| `DISCORD_CLIENT_ID`     | 否        | —                           | Discord OAuth2 客户端 ID。在 [discord.com/developers](https://discord.com/developers/applications) 创建                                      |
| `DISCORD_CLIENT_SECRET` | 否        | —                           | Discord OAuth2 客户端密钥                                                                                                                  |
| `FEISHU_APP_ID`         | 否        | —                           | 飞书（Lark）应用 ID。在 [open.feishu.cn](https://open.feishu.cn/app) 创建。需要 `contact:user.email:readonly` 权限                                   |
| `FEISHU_APP_SECRET`     | 否        | —                           | 飞书（Lark）应用密钥                                                                                                                          |
| `FRONTEND_URL`          | **生产环境** | `http://localhost:3000`     | OAuth 完成后浏览器跳转的位置。在生产环境中必须设置（例如 `https://yourdomain.com`）                                                                             |
| `API_BASE_URL`          | **生产环境** | `http://localhost:8000`     | 外部可访问的后端 URL，用于构建 OAuth 回调 URL。在生产环境中必须设置                                                                                             |
| `NEXT_PUBLIC_API_URL`   | **生产环境** | *（自动检测为 `<hostname>:8000`）* | 浏览器端 API 基础 URL，用于 OAuth 重定向。**这是前端构建时变量** — 在本地开发时在 `frontend/.env.local` 中设置，或在自定义生产部署时作为 Docker 构建参数传递。自动检测适用于标准反向代理设置（端口 80/443）。 |

> **生产环境** = 本地可选（使用默认值），但对于任何面向互联网的部署都**必需**。

### 需要向每个提供商注册的 OAuth 回调 URL

后端构造回调 URL 为：`{API_BASE_URL}/api/auth/oauth/{provider}/callback`

| 提供商     | 要注册的回调 URL                                               |
| ------- | -------------------------------------------------------- |
| GitHub  | `https://yourdomain.com/api/auth/oauth/github/callback`  |
| Google  | `https://yourdomain.com/api/auth/oauth/google/callback`  |
| Discord | `https://yourdomain.com/api/auth/oauth/discord/callback` |

***

## Cloudflare Tunnel（可选）

通过 Cloudflare 的网络路由所有流量，而不是直接暴露端口。无需 Nginx、SSL 证书和开放防火墙规则。有关设置说明，请参阅[生产部署](/quickstart#cloudflare-tunnel)部分。

<Warning>
  **中国大陆用户**：Cloudflare Free/Pro/Business 计划在中国大陆没有 PoP。流量被路由到海外边缘节点，导致频繁出现 502 错误。除非您拥有带有中国网络的 Cloudflare Enterprise，否则如果您的主要用户在中国大陆，请勿使用此功能。
</Warning>

| 变量                        | 必需                 | 默认值 | 描述                                                                                                                                                 |
| ------------------------- | ------------------ | --- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CLOUDFLARE_TUNNEL_TOKEN` | **是**（如果使用 Tunnel） | —   | 来自 Cloudflare Zero Trust → Networks → Tunnels → 您的 tunnel → Configure 的令牌。以 `eyJ...` 开头。由 `docker-compose.tunnel.yml` 中的 `cloudflared` sidecar 所需。 |

***

## 分析（可选）

所有分析提供商都是可选的。设置任意组合——所有活跃的提供商同时加载。全部留空可禁用分析（建议用于本地开发）。

| 变量                                 | 必需 | 默认值                                 | 描述                                                                                                   |
| ---------------------------------- | -- | ----------------------------------- | ---------------------------------------------------------------------------------------------------- |
| `NEXT_PUBLIC_GA_MEASUREMENT_ID`    | 否  | —                                   | Google Analytics 4 测量ID（例如 `G-XXXXXXXXXX`）。在 [analytics.google.com](https://analytics.google.com) 获取 |
| `NEXT_PUBLIC_UMAMI_SCRIPT_URL`     | 否  | —                                   | Umami 分析脚本URL（例如 `https://your-umami.com/script.js`）。自托管、隐私友好的替代方案——[umami.is](https://umami.is)     |
| `NEXT_PUBLIC_UMAMI_WEBSITE_ID`     | 否  | —                                   | Umami 网站ID。设置 `NEXT_PUBLIC_UMAMI_SCRIPT_URL` 时必需                                                     |
| `NEXT_PUBLIC_PLAUSIBLE_DOMAIN`     | 否  | —                                   | Plausible 分析域名（例如 `yourdomain.com`）。轻量级、隐私友好——[plausible.io](https://plausible.io)                   |
| `NEXT_PUBLIC_PLAUSIBLE_SCRIPT_URL` | 否  | `https://plausible.io/js/script.js` | 自托管实例的自定义Plausible脚本URL                                                                              |

> 所有 `NEXT_PUBLIC_*` 分析变量都是**构建时**的——更改需要前端重新构建才能生效。

## Stripe 计费（可选）

Stripe 为 Pro 订阅提供支持。将所有三个变量留空可禁用计费——FIM One 的其余部分保持不变。**必须**同时设置 `STRIPE_SECRET_KEY` **和** `STRIPE_WEBHOOK_SECRET`；部分配置会在首次使用时引发错误。

| 变量                          | 必需 | 默认值                                          | 描述                                                                                                                                                         |
| --------------------------- | -- | -------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `STRIPE_SECRET_KEY`         | 否  | —                                            | Stripe API 密钥。必须以 `sk_test_` / `sk_live_`（完全访问权限）或 `rk_test_` / `rk_live_`（受限密钥）开头。从 Stripe Dashboard → Developers → API keys 获取。切勿将 `sk_live_*` 密钥提交到源代码。 |
| `STRIPE_WEBHOOK_SECRET`     | 否  | —                                            | Stripe webhook 签名密钥（`whsec_*`）。在 Stripe Dashboard → Developers → Webhooks → Add endpoint 中注册 webhook 端点时创建。验证入站 webhook 负载所需。                              |
| `STRIPE_BILLING_RETURN_URL` | 否  | `http://localhost:3000/settings?tab=billing` | Stripe 在 Checkout / Customer Portal 会话后重定向用户的 URL。将其设置为生产环境计费设置页面（例如 `https://your-domain.com/settings?tab=billing`）。                                      |
