From f723cd3581967879bfffa5d97a1c23bbc682bdb5 Mon Sep 17 00:00:00 2001 From: Riskey <36894937+RiskeyL@users.noreply.github.com> Date: Sat, 9 May 2026 20:50:40 +0800 Subject: [PATCH 1/4] docs: add Hidden & Pre-Filled section to User Input page (#773) * docs: add Hidden & Pre-Filled section to User Input page * translate: add Hidden & Pre-Filled section in user-input (zh, ja) * docs: add macro translation principles to zh formatting guide * fix: correct Variables anchor in zh/ja translations --- en/use-dify/nodes/user-input.mdx | 100 +++++++++++++++-- images/use-dify/workflow/embedding-icon.png | Bin 0 -> 37967 bytes .../workflow/hidden-field-config-icon.png | Bin 0 -> 36388 bytes ja/use-dify/nodes/user-input.mdx | 98 +++++++++++++++-- tools/translate/formatting-zh.md | 10 +- zh/use-dify/nodes/user-input.mdx | 104 ++++++++++++++++-- 6 files changed, 283 insertions(+), 29 deletions(-) create mode 100644 images/use-dify/workflow/embedding-icon.png create mode 100644 images/use-dify/workflow/hidden-field-config-icon.png diff --git a/en/use-dify/nodes/user-input.mdx b/en/use-dify/nodes/user-input.mdx index 4c3a57e70..c167edfc4 100644 --- a/en/use-dify/nodes/user-input.mdx +++ b/en/use-dify/nodes/user-input.mdx @@ -32,16 +32,14 @@ Preset input variables are system-defined and available by default. ### Custom -You can configure custom input fields in a User Input node to collect different kinds of user input. Each field becomes a variable that can be referenced by downstream nodes. +You can configure custom input fields in a User Input node to collect different kinds of user input. Each field becomes a variable that can be referenced by downstream nodes. **Label Name** is displayed to your end users. - In a chatflow application, you can **Hide** any user input field to make it invisible to end users while keeping it available for reference within the chatflow. - - Note that a **Required** field cannot be hidden. + If a field's value is something you already know (like a product identifier or tenant ID) and doesn't have to come from end users, mark it as **Hidden & Pre-Filled** and supply it yourself. See [Hide and Pre-Fill Input Fields](#hide-and-pre-fill-input-fields) for details. #### Text Input @@ -110,12 +108,96 @@ Since the User Input node only collects files—it does not read or parse their When users upload multiple files with mixed types (e.g., images and documents), you can use a List Operator node to separate them by file type before routing them to different processing branches. -## What's Next +## Hide and Pre-Fill Input Fields + +Sometimes the workflow needs an input you already know, and asking end users to type it would be friction. Mark such a field as **Hidden & Pre-Filled**: you supply the value, end users never see the field, and the workflow still receives it. + +Imagine your company runs landing pages for many different products, each featuring an AI chatbot. The workflow behind every chatbot is essentially the same; only the product identifier differs. -After setting up a User Input node, you can connect it to other nodes to process the collected data. Common patterns include: +Rather than maintain a separate workflow per product, you keep just one (with a hidden `productName` field) and pre-fill a different value on each landing page. End users perceive each page as having its own product-specific chatbot, but behind the scenes, every page passes a different `productName` into the same workflow. -- Send the input to an LLM node for processing. + + Hidden fields are **not secret**. Values travel in the URL query string and are visible in the browser address bar, browser history, and network traffic. For credentials and API keys, use [Environment Variables](/en/use-dify/getting-started/key-concepts#variables) instead. + -- Use a Knowledge Retrieval node to find information relevant to the input. + + Single File and File List fields do not support this feature. + -- Create conditional branches based on the input with an If/Else node. \ No newline at end of file + + + 1. In the **Edit Input Field** window, uncheck **Required** if it's checked. These two options are mutually exclusive. + 2. Check **Hidden & Pre-Filled**. Optionally set a default value as a fallback when no value is pre-filled at runtime. + + Hidden fields still appear in the **Preview** panel so you can test the flow without publishing. + + + + 1. Publish your app. + 2. Choose the method that fits how your end users reach the app. + + + + + Use this when end users open the WebApp directly from its link. + + 1. In the app's publishing panel, within the **Web App** section, click the gear icon next to **Launch**. + + ![Hidden Fields Pre-Fill Icon](/images/use-dify/workflow/hidden-field-config-icon.png) + + 2. Fill in the hidden fields and click **Launch**. The WebApp opens with your values applied as URL query parameters; copy the URL from the address bar to share. + + **To generate many links with different values**, use the same pattern to write more yourself, or have a system fill in the values automatically: + + ```text wrap + {WEBAPP_URL}?{VARIABLE_NAME}={VALUE}&{VARIABLE_NAME}={VALUE} + + # Example: https://udify.app/chat/abc123?productName=Acme®ion=us-east + ``` + + URL-encode any values that contain spaces or special characters (for example, `Acme Corp` becomes `Acme%20Corp`). + + + + A support team using a CRM can add `?customerId={{customer.id}}` to the end of the WebApp URL in their ticket-response templates. + + The CRM substitutes the real customer ID when the rep sends the link, so the chatbot knows which customer it's talking to without having to ask. + + + + + + Use this when the app is embedded as an iframe or script on your site. + + + + Use this when every visitor should receive the same values (a site-wide region, the embedded page's product ID, etc.). + + 1. In the app's publishing panel, within the **Web App** section, click **Embedded** > **Pre-Fill Hidden Fields**. + + ![Embedded Icon](/images/use-dify/workflow/embedding-icon.png) + + 2. Fill in the hidden fields. Entered values are baked into the iframe URL and the `inputs` object of the script snippet. + + + Use this when each visitor should receive their own values (the logged-in user's ID, the page they're on, etc.). + + In the embed snippet on your site, set each hidden field as a key in the `inputs` object of `window.difyChatbotConfig`. Each value is computed at render time from your site's context, so every visitor gets their own. + + ```html + + ``` + + + + + + \ No newline at end of file diff --git a/images/use-dify/workflow/embedding-icon.png b/images/use-dify/workflow/embedding-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..53ed9466a00f6bbf59de38a52852e19209f0211f GIT binary patch literal 37967 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 literal 0 HcmV?d00001 diff --git a/ja/use-dify/nodes/user-input.mdx b/ja/use-dify/nodes/user-input.mdx index a391bdeb9..405c741c9 100644 --- a/ja/use-dify/nodes/user-input.mdx +++ b/ja/use-dify/nodes/user-input.mdx @@ -42,9 +42,7 @@ description: "ワークフローとチャットフローアプリケーション - チャットフローアプリケーションでは、任意のユーザー入力フィールドを**非表示**にして、エンドユーザーには見えないようにしつつ、チャットフロー内で参照可能な状態を維持できます。 - - **必須**フィールドは非表示にできないことに注意してください。 + フィールドの値が既知のもの(製品識別子やテナント ID など)で、エンドユーザーから取得する必要がない場合、そのフィールドを **非表示・事前入力** に設定し、自分で値を提供できます。詳細は [入力フィールドの非表示・事前入力](#入力フィールドの非表示事前入力) を参照してください。 #### テキスト入力 @@ -113,12 +111,96 @@ description: "ワークフローとチャットフローアプリケーション ユーザーが混在タイプの複数のファイル(画像とドキュメントなど)をアップロードする場合、リスト演算子ノードを使用してファイルタイプ別に分離してから、異なる処理ブランチにルーティングできます。 -## 次のステップ +## 入力フィールドの非表示・事前入力 + +ワークフローには、すでに分かっている入力が必要な場合があります。エンドユーザーに入力させるのは煩わしいでしょう。そのフィールドを **非表示・事前入力** に設定すると、値は自分で提供し、エンドユーザーには見えませんが、ワークフローには値が渡ります。 + +たとえば、複数の異なる製品ごとにランディングページを運営し、それぞれに AI チャットボットを掲載する企業を想像してください。すべてのチャットボットの背後にあるワークフローはほぼ同じで、製品識別子だけが異なります。 -ユーザー入力ノードを設定したら、収集したデータを処理する他のノードに接続できます。一般的なパターンには次のものがあります: +製品ごとに別々のワークフローを保守する代わりに、`productName` という非表示フィールドを持つ 1 つのワークフローを用意し、各ランディングページに対応する値を事前入力します。エンドユーザーから見ると、各ページにその製品専用のチャットボットがあるように感じられますが、実際にはすべてのページが同じワークフローに異なる `productName` を渡しているだけです。 -- 入力を LLM ノードに送信して処理する。 + + 非表示フィールドは **秘匿情報ではありません**。値は URL クエリ文字列に含まれて送られ、ブラウザのアドレスバー、履歴、ネットワーク通信から見えます。認証情報や API キーには [環境変数](/ja/use-dify/getting-started/key-concepts#変数) を使用してください。 + -- ナレッジ検索ノードを使用して、入力に関連する情報を検索する。 + + 単一ファイルおよびファイルリストのフィールドは、この機能をサポートしていません。 + -- If/Else ノードを使用して、入力に基づいて条件分岐を作成する。 \ No newline at end of file + + + 1. **入力フィールドを編集** ウィンドウで、**必須** がチェックされている場合は外します。この 2 つのオプションは併用できません。 + 2. **非表示・事前入力** をチェックします。実行時に値が指定されない場合のフォールバックとして、デフォルト値を任意で設定できます。 + + 非表示フィールドは **プレビュー** パネルには引き続き表示されるため、公開前にフローをテストできます。 + + + + 1. アプリを公開します。 + 2. エンドユーザーがアプリにアクセスする方法に合わせて、いずれかの方法を選択します。 + + + + + エンドユーザーがリンクから直接 WebApp を開く場合に使用します。 + + 1. アプリの公開パネルの **Web App** セクションで、**公開** の横の歯車アイコンをクリックします。 + + ![非表示フィールドの事前入力アイコン](/images/use-dify/workflow/hidden-field-config-icon.png) + + 2. 非表示フィールドに値を入力し、**公開** をクリックします。WebApp は値が URL クエリパラメーターとして適用された状態で開きます。アドレスバーから URL をコピーして共有してください。 + + **異なる値で多数のリンクを生成するには**、同じパターンで自分でさらに作成するか、システムに値を自動的に入力させます。 + + ```text wrap + {WEBAPP_URL}?{VARIABLE_NAME}={VALUE}&{VARIABLE_NAME}={VALUE} + + # 例:https://udify.app/chat/abc123?productName=Acme®ion=us-east + ``` + + スペースや特殊文字を含む値は URL エンコードしてください(例:`Acme Corp` は `Acme%20Corp` になります)。 + + + + CRM を使用しているサポートチームは、チケット返信テンプレートで WebApp URL の末尾に `?customerId={{customer.id}}` を追加できます。 + + 担当者がリンクを送信する際、CRM が実際の顧客 ID に置き換えるため、チャットボットはどの顧客との会話か尋ねずに把握できます。 + + + + + + アプリを iframe またはスクリプトとしてサイトに埋め込む場合に使用します。 + + + + すべての訪問者が同じ値を受け取る場合に使用します(サイト全体のリージョン、埋め込みページの製品 ID など)。 + + 1. アプリの公開パネルの **Web App** セクションで、**埋め込み** > **非表示フィールドを事前入力** をクリックします。 + + ![埋め込みアイコン](/images/use-dify/workflow/embedding-icon.png) + + 2. 非表示フィールドに値を入力します。入力した値は iframe URL とスクリプトスニペットの `inputs` オブジェクトに組み込まれます。 + + + 各訪問者が固有の値を受け取る場合に使用します(ログインユーザーの ID、現在のページなど)。 + + サイトの埋め込みスニペットで、各非表示フィールドを `window.difyChatbotConfig` の `inputs` オブジェクトのキーとして設定します。各値はサイトのコンテキストからレンダリング時に計算されるため、各訪問者は固有の値を受け取ります。 + + ```html + + ``` + + + + + + \ No newline at end of file diff --git a/tools/translate/formatting-zh.md b/tools/translate/formatting-zh.md index 14ac5c19d..7bb87324e 100644 --- a/tools/translate/formatting-zh.md +++ b/tools/translate/formatting-zh.md @@ -173,7 +173,15 @@ Avoid using `——` in Chinese text. Restructure instead: The single most important rule: after understanding what an English sentence says, write the Chinese from scratch as if you were writing it natively. Do not preserve English clause order, modifier chains, or connector words just because they appear in the source. Fidelity to natural Chinese always outranks fidelity to English structure. -Before finalizing any sentence, ask: "Would a Chinese technical writer actually write this?" If the answer is no, rewrite. +Three macro principles guide this: + +1. **Voice it, don't transcribe it.** Internalize the meaning of the source sentence, then write the Chinese as if explaining the concept to a colleague, not as if translating each clause. Looking back at the source pulls you toward its structure; looking away frees you to write natural Chinese. + +2. **Trust short verbal clauses over long noun phrases.** Chinese reads more naturally as sequences of short actions than as stacked noun phrases. When you find yourself building chains of `的` or piling up nominal connectors (`X 的 Y 的形式`, `Z 的回退`), restructure into shorter sentences with concrete verbs. + +3. **Match register to the document's audience.** Documentation Chinese is professional-conversational, not formal-literary. When a colloquial-natural word and a formal-translated word convey the same meaning, choose the colloquial one. You're writing instructions for engineers, not legal text. + +Before finalizing any sentence, read it aloud (silently, in your head). If it wouldn't pass as a native Chinese explanation spoken to a colleague, restructure. ### Patterns to Eliminate diff --git a/zh/use-dify/nodes/user-input.mdx b/zh/use-dify/nodes/user-input.mdx index 985664af5..9b55123cd 100644 --- a/zh/use-dify/nodes/user-input.mdx +++ b/zh/use-dify/nodes/user-input.mdx @@ -7,7 +7,7 @@ description: "收集用户输入以启动工作流和对话流应用程序" ## 简介 -用户输入节点允许你定义从最终用户收集哪些内容作为应用程序的输入。 +用户输入节点允许你定义从终端用户收集哪些内容作为应用程序的输入。 使用此节点启动的应用程序*按需*运行,可以通过直接用户交互或 API 调用启动。 @@ -23,7 +23,7 @@ description: "收集用户输入以启动工作流和对话流应用程序" 预设输入变量由系统定义,默认可用。 -- `userinput.files`:最终用户运行应用程序时上传的文件。 +- `userinput.files`:终端用户运行应用程序时上传的文件。 对于工作流应用程序,此预设变量已被视为*遗留*变量,仅为向后兼容而保留。 @@ -38,13 +38,11 @@ description: "收集用户输入以启动工作流和对话流应用程序" 你可以在用户输入节点中配置自定义输入字段,以收集不同类型的用户输入。每个字段都会成为下游节点可以引用的变量。 - **标签名称**会显示给你的最终用户。 + **标签名称**会显示给你的终端用户。 - 在对话流应用程序中,你可以**隐藏**任何用户输入字段,使其对最终用户不可见,同时保持在对话流中可引用。 - - 请注意,**必填**字段无法隐藏。 + 若字段的值是你已知的(如产品标识符或租户 ID),且无需由终端用户输入,可将其标记为 **隐藏并预填**,自行提供值。详见 [隐藏并预填输入字段](#隐藏并预填输入字段)。 #### 文本输入 @@ -113,12 +111,96 @@ description: "收集用户输入以启动工作流和对话流应用程序" 当用户上传混合类型的多个文件(例如,图像和文档)时,你可以使用列表操作符节点按文件类型分离它们,然后将它们路由到不同的处理分支。 -## 下一步 +## 隐藏并预填输入字段 + +工作流有时需要一些你已知的输入,让终端用户手动填写只会增加摩擦。可将此类字段标记为 **隐藏并预填**:值由你预先填好,终端用户看不到该字段,而工作流仍能拿到值。 + +假设你的公司有多个产品的落地页,每个页面都嵌入了 AI 聊天机器人。这些聊天机器人背后的工作流基本相同,只是处理的产品不同。 -设置用户输入节点后,你可以将其连接到其他节点以处理收集的数据。常见模式包括: +与其为每个产品维护一个独立的工作流,不如只用一个,并为其添加隐藏的 `productName` 字段,然后为各个落地页预填不同的值。在终端用户看来,每个页面都有专属的产品聊天机器人,但实际上各个页面只是向同一个工作流传入了不同的 `productName`。 -- 将输入发送到 LLM 节点进行处理。 + + 隐藏字段 **并不保密**。字段值会出现在 URL 查询字符串中,浏览器地址栏、历史记录和网络流量中都能看到。凭据和 API 密钥需改用 [环境变量](/zh/use-dify/getting-started/key-concepts#变量)。 + -- 使用知识检索节点查找与输入相关的信息。 + + 单个文件和文件列表字段不支持此功能。 + -- 使用 If/Else 节点根据输入创建条件分支。 \ No newline at end of file + + + 1. 在 **编辑变量** 窗口中,取消勾选 **必填**(若已勾选)。这两个选项互斥。 + 2. 勾选 **隐藏并预填**。可同时设置默认值用作兜底。 + + 隐藏字段在 **预览** 面板中仍会显示,便于你在发布前测试流程。 + + + + 1. 发布应用。 + 2. 根据终端用户访问应用的方式,选择对应的方法。 + + + + + 适用于终端用户通过链接直接打开 WebApp 的场景。 + + 1. 在应用发布面板的 **Web App** 板块中,点击 **启动** 旁的齿轮图标。 + + ![隐藏字段预填图标](/images/use-dify/workflow/hidden-field-config-icon.png) + + 2. 填入隐藏字段的值并点击 **启动**。WebApp 打开后,预填值已作为 URL 查询参数填入地址栏,复制 URL 即可分享。 + + **若需生成大量带有不同值的链接**,可参照该 URL 模式自行编写更多链接,或让第三方系统自动生成: + + ```text wrap + {WEBAPP_URL}?{VARIABLE_NAME}={VALUE}&{VARIABLE_NAME}={VALUE} + + # 示例:https://udify.app/chat/abc123?productName=Acme®ion=us-east + ``` + + 含空格或特殊字符的值需要 URL 编码(例如 `Acme Corp` 写作 `Acme%20Corp`)。 + + + + 客服团队可在 CRM 的工单回复模板中,将 `?customerId={{customer.id}}` 追加到 WebApp URL 末尾。 + + 客服发送链接时,CRM 会自动替换成实际的客户 ID,聊天机器人无需再询问即可识别客户。 + + + + + + 适用于将应用以 iframe 或脚本形式嵌入网站的场景。 + + + + 适用于所有访客接收相同值的场景(如全站区域、嵌入页面的产品 ID 等)。 + + 1. 在应用发布面板的 **Web App** 板块中,点击 **嵌入** > **预填隐藏字段**。 + + ![嵌入图标](/images/use-dify/workflow/embedding-icon.png) + + 2. 填入隐藏字段的值。这些值会嵌入到 iframe URL 和脚本片段的 `inputs` 对象中。 + + + 适用于每位访客接收各自值的场景(如登录用户的 ID、当前所在页面等)。 + + 在网站的嵌入脚本中,把每个隐藏字段加到 `window.difyChatbotConfig` 的 `inputs` 对象里。值在渲染时根据当前页面上下文动态计算,每位访客都能拿到各自的值。 + + ```html + + ``` + + + + + + \ No newline at end of file From d52677cc1df57cc7d3b2fb9e1d9ab133c3cae87e Mon Sep 17 00:00:00 2001 From: -LAN- Date: Mon, 11 May 2026 18:09:25 +0800 Subject: [PATCH 2/4] docs: update docker compose environment docs (#774) * docs: update docker compose environment docs * chore: retrigger documentation analysis * docs: refine env-split deployment docs and translate zh/ja * docs: update aws premium env guidance * docs: refine aws premium env guidance and translate zh/ja --------- Co-authored-by: RiskeyL <7a8y@163.com> --- .../local-source-code.mdx | 7 +- en/self-host/configuration/environments.mdx | 21 +++- en/self-host/platform-guides/dify-premium.mdx | 57 +++++++--- en/self-host/quick-start/docker-compose.mdx | 81 ++++++++------ .../local-source-code.mdx | 7 +- ja/self-host/configuration/environments.mdx | 15 ++- ja/self-host/platform-guides/dify-premium.mdx | 79 +++++++++----- ja/self-host/quick-start/docker-compose.mdx | 92 +++++++++------- .../local-source-code.mdx | 7 +- zh/self-host/configuration/environments.mdx | 15 ++- zh/self-host/platform-guides/dify-premium.mdx | 59 +++++++--- zh/self-host/quick-start/docker-compose.mdx | 101 ++++++++++-------- 12 files changed, 355 insertions(+), 186 deletions(-) diff --git a/en/self-host/advanced-deployments/local-source-code.mdx b/en/self-host/advanced-deployments/local-source-code.mdx index 421359ea4..53d27a690 100644 --- a/en/self-host/advanced-deployments/local-source-code.mdx +++ b/en/self-host/advanced-deployments/local-source-code.mdx @@ -31,11 +31,10 @@ A series of middlewares for storage (e.g. PostgreSQL / Redis / Weaviate (if not ```bash cd docker -cp middleware.env.example middleware.env +cp envs/middleware.env.example middleware.env -# change the profile to mysql if you are not using postgresql -# change the profile to other vector database if you are not using weaviate -docker compose -f docker-compose.middleware.yaml --profile postgresql --profile weaviate -p dify up -d +# Change DB_TYPE or COMPOSE_PROFILES in middleware.env if you are not using PostgreSQL and Weaviate. +docker compose --env-file middleware.env -f docker-compose.middleware.yaml -p dify up -d ``` --- diff --git a/en/self-host/configuration/environments.mdx b/en/self-host/configuration/environments.mdx index 046091438..abb8e4971 100644 --- a/en/self-host/configuration/environments.mdx +++ b/en/self-host/configuration/environments.mdx @@ -3,10 +3,23 @@ title: Environment Variables description: Reference for all environment variables used by Dify self-hosted deployments --- -Dify works out of the box with default settings. You can customize your deployment by modifying the environment variables in the `.env` file. +Dify works out of the box with default settings. To customize your deployment, edit environment variables in the relevant file: + +- **Essential startup values** live in `docker/.env`, which you created from `docker/.env.example` during deployment. Edit them directly. + +- **Optional or provider-specific settings** have templates under `docker/envs/`. To override a default value, copy the matching template (drop the `.example` suffix), then edit your copy. + + For example: + + ```bash + cd dify/docker + cp envs/vectorstores/milvus.env.example envs/vectorstores/milvus.env + ``` + +Values in `docker/.env` take precedence over values in any `docker/envs/*.env` files. -After upgrading Dify, run `diff .env .env.example` in the `docker` directory to check for newly added or changed variables, then update your `.env` file accordingly. +After upgrading Dify, compare each `.env.example` with its matching `.env` for new or changed variables. ## Common Variables @@ -1294,6 +1307,8 @@ These configure the Squid-based SSRF proxy container that blocks requests to int ## Docker Compose +These variables stay in `docker/.env` because Docker Compose uses them to select profiles and expose ports before containers start. + | Variable | Default | Description | |---|---|---| | `COMPOSE_PROFILES` | `${VECTOR_STORE:-weaviate},${DB_TYPE:-postgresql}` | Automatically selects which service containers to start based on your database and vector store choices. For example, setting `DB_TYPE=mysql` starts MySQL instead of PostgreSQL. | @@ -1614,4 +1629,4 @@ The plugin daemon can store plugin packages in different storage backends. Confi | `PLUGIN_VOLCENGINE_TOS_REGION` | (empty) | Volcengine TOS region. | - \ No newline at end of file + diff --git a/en/self-host/platform-guides/dify-premium.mdx b/en/self-host/platform-guides/dify-premium.mdx index 6df524990..2df2e158d 100644 --- a/en/self-host/platform-guides/dify-premium.mdx +++ b/en/self-host/platform-guides/dify-premium.mdx @@ -1,5 +1,6 @@ --- title: Dify Premium on AWS +description: Deploy, customize, and upgrade Dify Premium on AWS --- Dify Premium is our AWS AMI offering that allows custom branding and is one-click deployable to your AWS VPC as an EC2 instance. Head to [AWS Marketplace](https://aws.amazon.com/marketplace/pp/prodview-t22mebxzwjhu6) to subscribe. It's useful in a couple of scenarios: @@ -18,12 +19,32 @@ If this is your first time accessing Dify, enter the Admin initialization passwo ### Configuration -Just like a self-hosted deployment, you may modify the environment variables in the `.env` file in your EC2 instance as you see fit. Then, restart Dify with: + + + Edit environment variables in the relevant file on your EC2 instance: + + - **Essential startup values** live in `/dify/.env`. Edit them directly. + + - **Optional or provider-specific settings** have templates under `/dify/envs/`. To override a default value, copy the matching template (drop the `.example` suffix), then edit your copy. -```bash -docker-compose down -docker-compose -f docker-compose.yaml -f docker-compose.override.yaml up -d -``` + For example: + + ```bash + cd /dify + cp envs/vectorstores/opensearch.env.example envs/vectorstores/opensearch.env + ``` + + Values in `/dify/.env` take precedence over values in any `/dify/envs/*.env` files. + + If your AWS deployment injects variables through `docker-compose.override.yaml`, keep those settings there. Service-level `environment:` values in Compose take precedence over env-file values. + + + ```bash + docker compose down + docker compose -f docker-compose.yaml -f docker-compose.override.yaml up -d + ``` + + ### Web App Logo & Branding @@ -32,7 +53,9 @@ In **Settings** > **Customization**, you can remove the `Powered by Dify` brandi ## Upgrade - Before upgrading, check the [Release Notes](https://github.com/langgenius/dify/releases) on GitHub for version-specific upgrade instructions. Some versions may require additional steps such as database migrations or configuration changes. + - Before upgrading, check the [Release Notes](https://github.com/langgenius/dify/releases) on GitHub for version-specific upgrade instructions. Some versions may require additional steps such as database migrations or configuration changes. + + - Dify's Docker Compose files now require Docker Compose 2.24.0 or later. Run `docker compose version` to confirm before upgrading. In the EC2 instance, run the following commands: @@ -41,22 +64,23 @@ In the EC2 instance, run the following commands: ```bash cd /dify - docker-compose down + docker compose down ``` - Back up your `.env` file and the `volumes` directory, which contains your database, storage, and other persistent data: + Back up your `.env` file, any optional env files you created under `envs/`, and the `volumes` directory, which contains your database, storage, and other persistent data: ```bash cp /dify/.env /dify/.env.bak + tar -cvf envs-$(date +%s).tgz envs tar -cvf volumes-$(date +%s).tgz volumes ``` - The upgrade process will overwrite configuration files but will not affect your `.env` file or runtime data (such as databases and uploaded files) in the `volumes/` directory. + The upgrade process will overwrite configuration templates but will not affect your `.env` file, local `/dify/envs/*.env` files, or runtime data (such as databases and uploaded files) in the `volumes/` directory. - If you have manually modified any configuration files beyond `.env`, back them up before upgrading. + If you have manually modified configuration files beyond `.env` and `/dify/envs/*.env`, back them up before upgrading. Pull the latest code and sync the configuration files: @@ -68,16 +92,21 @@ In the EC2 instance, run the following commands: ``` - New versions may introduce new environment variables in `.env.example`. Compare it with your current `.env` and add any missing variables: + New versions may introduce variables in `.env.example` or in optional templates under `envs/`. Compare each template with its matching local env file and add any missing variables you need: ```bash diff /dify/.env /dify/.env.example + find /dify/envs -name "*.env" -print | while read -r env_file; do + diff "$env_file" "$env_file.example" + done ``` + + If you need to customize a newly added optional template, copy it beside itself without the `.example` suffix before editing it. See [Configuration](#configuration) for details. ```bash - docker-compose pull - docker-compose -f docker-compose.yaml -f docker-compose.override.yaml up -d + docker compose pull + docker compose -f docker-compose.yaml -f docker-compose.override.yaml up -d ``` - \ No newline at end of file + diff --git a/en/self-host/quick-start/docker-compose.mdx b/en/self-host/quick-start/docker-compose.mdx index 61a723d43..b418eda69 100644 --- a/en/self-host/quick-start/docker-compose.mdx +++ b/en/self-host/quick-start/docker-compose.mdx @@ -18,12 +18,11 @@ Make sure your machine meets the following minimum system requirements. ### Software -| Operating System | Required Software | Notes | -| :----------------------------- | :---------------------------------------- | :----- | -| macOS 10.14 or later | Docker Desktop | Configure the Docker virtual machine with at least 2 virtual CPUs and 8 GiB of memory.



For installation instructions, see [Install Docker Desktop on Mac](https://docs.docker.com/desktop/mac/install/). | -| Linux distributions | Docker 19.03+



Docker Compose 1.28+ | For installation instructions, see [Install Docker Engine](https://docs.docker.com/engine/install/) and [Install Docker Compose](https://docs.docker.com/compose/install/). | -| Windows with WSL 2 enabled | Docker Desktop | Store source code and data bound to Linux containers in the Linux file system rather than Windows.



For installation instructions, see [Install Docker Desktop on Windows](https://docs.docker.com/desktop/windows/install/#wsl-2-backend). | - +| Operating System | Required Software | Notes | +| :----------------------------- | :---------------------------------------- | :----- | +| macOS 10.14 or later | Docker Desktop with Docker Compose 2.24.0+ | Configure the Docker virtual machine with at least 2 virtual CPUs and 8 GiB of memory.



For installation instructions, see [Install Docker Desktop on Mac](https://docs.docker.com/desktop/mac/install/). | +| Linux distributions | Docker 19.03+



Docker Compose 2.24.0+ | For installation instructions, see [Install Docker Engine](https://docs.docker.com/engine/install/) and [Install Docker Compose](https://docs.docker.com/compose/install/). | +| Windows with WSL 2 enabled | Docker Desktop with Docker Compose 2.24.0+ | Store source code and data bound to Linux containers in the Linux file system rather than Windows.



For installation instructions, see [Install Docker Desktop on Windows](https://docs.docker.com/desktop/windows/install/#wsl-2-backend). | ## Deploy and Start @@ -33,6 +32,7 @@ Make sure your machine meets the following minimum system requirements. ```bash git clone --branch "$(curl -s https://api.github.com/repos/langgenius/dify/releases/latest | jq -r .tag_name)" https://github.com/langgenius/dify.git + ``` @@ -43,26 +43,22 @@ Make sure your machine meets the following minimum system requirements. cd dify/docker ``` - 2. Copy the example environment configuration file: + 2. Copy the essential environment configuration file: ```bash - cp .env.example .env + cp .env.example .env ``` - 3. Start the containers using the command that matches your Docker Compose version: + To customize your deployment later, see [Customize](#customize). - - ```bash Docker Compose V2 - docker compose up -d - ``` - ```bash Docker Compose V1 - docker-compose up -d - ``` - + 3. Start the containers: + + Dify requires Docker Compose 2.24.0 or later. Run `docker compose version` to confirm. + - - Run `docker compose version` to check your Docker Compose version. - + ```bash + docker compose up -d + ``` The following containers will be started: @@ -110,6 +106,7 @@ Make sure your machine meets the following minimum system requirements. docker-worker-1 langgenius/dify-api:1.10.1 "/bin/bash /entrypoi…" worker 26 seconds ago Up 22 seconds 5001/tcp docker-worker_beat-1 langgenius/dify-api:1.10.1 "/bin/bash /entrypoi…" worker_beat 26 seconds ago Up 22 seconds 5001/tcp ``` + @@ -137,23 +134,43 @@ Make sure your machine meets the following minimum system requirements. ## Customize -Modify the environment variable values in your local `.env` file, then restart Dify to apply the changes: +To customize your deployment, edit environment variables in the relevant file, then restart Dify. -```bash -docker compose down -docker compose up -d -``` + + - - For more information, see [environment variables](/en/self-host/configuration/environments). - + - **Essential startup values** live in `docker/.env`, which you created from `docker/.env.example` during deployment. Edit them directly. + + - **Optional or provider-specific settings** have templates under `docker/envs/`. To override a default value, copy the matching template (drop the `.example` suffix), then edit your copy. + + For example: + + ```bash + cd dify/docker + cp envs/vectorstores/milvus.env.example envs/vectorstores/milvus.env + ``` + + Values in `docker/.env` take precedence over values in any `docker/envs/*.env` files. + + + For descriptions of every variable, see [Environment Variables](/en/self-host/configuration/environments). + + + + + + ```bash + docker compose down + docker compose up -d + ``` + + + ## Upgrade Upgrade steps may vary between releases. Refer to the upgrade guide for your target version provided in the [Releases](https://github.com/langgenius/dify/releases) page. - - After upgrading, check whether the `.env.example` file has changed and update your local `.env` file accordingly. - - \ No newline at end of file + After upgrading, compare each `.env.example` with its matching `.env` for new or changed variables. +
diff --git a/ja/self-host/advanced-deployments/local-source-code.mdx b/ja/self-host/advanced-deployments/local-source-code.mdx index 8532ffa92..6ed9e923a 100644 --- a/ja/self-host/advanced-deployments/local-source-code.mdx +++ b/ja/self-host/advanced-deployments/local-source-code.mdx @@ -36,11 +36,10 @@ git clone https://github.com/langgenius/dify.git ```bash cd docker -cp middleware.env.example middleware.env +cp envs/middleware.env.example middleware.env -# postgresql を使用していない場合は profile を mysql に変更してください -# weaviate を使用していない場合は profile を他のベクターデータベースに変更してください -docker compose -f docker-compose.middleware.yaml --profile postgresql --profile weaviate -p dify up -d +# PostgreSQL と Weaviate を使用しない場合は、middleware.env の DB_TYPE または COMPOSE_PROFILES を変更してください。 +docker compose --env-file middleware.env -f docker-compose.middleware.yaml -p dify up -d ``` ## バックエンドサービスのセットアップ diff --git a/ja/self-host/configuration/environments.mdx b/ja/self-host/configuration/environments.mdx index d633f55e0..3d0f1a61c 100644 --- a/ja/self-host/configuration/environments.mdx +++ b/ja/self-host/configuration/environments.mdx @@ -5,10 +5,21 @@ description: Dify セルフホストデプロイで使用されるすべての ⚠️ このドキュメントは AI によって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/self-host/configuration/environments) を参照してください。 -Dify はデフォルト設定でそのまま動作します。`.env` ファイルの環境変数を変更することで、デプロイをカスタマイズできます。 +Dify はデフォルト設定でそのまま動作します。デプロイをカスタマイズするには、関連するファイルの環境変数を編集します: + +- **必須の起動値** は `docker/.env` にあります(デプロイ時に `docker/.env.example` からコピーして作成したファイル)。直接編集します。 + +- **オプションまたはプロバイダー固有の設定** は `docker/envs/` にテンプレートとして用意されています。デフォルト値を上書きするには、対応するテンプレートをコピーし(`.example` 拡張子を外す)、コピーを編集します。例: + + ```bash + cd dify/docker + cp envs/vectorstores/milvus.env.example envs/vectorstores/milvus.env + ``` + +`docker/.env` の値は、`docker/envs/*.env` ファイルの値より優先されます。 -Dify をアップグレードした後、`docker`ディレクトリで `diff .env .env.example`を実行して、新しく追加または変更された変数を確認し、`.env` ファイルを適宜更新してください。 +Dify をアップグレードした後、各 `.env.example` を対応する `.env` と比較し、新規または変更された変数を確認してください。 ## 共通変数 diff --git a/ja/self-host/platform-guides/dify-premium.mdx b/ja/self-host/platform-guides/dify-premium.mdx index d1491ede4..5478ac50c 100644 --- a/ja/self-host/platform-guides/dify-premium.mdx +++ b/ja/self-host/platform-guides/dify-premium.mdx @@ -1,64 +1,88 @@ --- -title: AWS上のDify Premium +title: AWS 上の Dify Premium +description: AWS 上で Dify Premium をデプロイ、カスタマイズ、アップグレードする --- ⚠️ このドキュメントは AI によって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/self-host/platform-guides/dify-premium) を参照してください。 -Dify Premiumは、カスタムブランディングを可能にし、EC2インスタンスとしてAWS VPCにワンクリックでデプロイできるAWS AMIサービスです。[AWS Marketplace](https://aws.amazon.com/marketplace/pp/prodview-t22mebxzwjhu6)にアクセスして購読してください。以下のようなシナリオで有用です: +Dify Premium は、カスタムブランディングを可能にする AWS AMI サービスです。EC2 インスタンスとして AWS VPC にワンクリックでデプロイできます。[AWS Marketplace](https://aws.amazon.com/marketplace/pp/prodview-t22mebxzwjhu6) にアクセスして購読してください。以下のようなシナリオで有用です: -- 中小企業として1つまたは少数のアプリケーションを作成したく、データレジデンシーを重視している。 -- [Dify Cloud](https://cloud.dify.ai)に興味があるが、あなたのユースケースが[プラン](https://dify.ai/pricing)でサポートされているよりも多くのリソースを必要とする。 -- 組織内でDify Enterpriseを採用する前にPOCを実行したい。 +- 中小企業として 1 つまたは少数のアプリケーションを作成したく、データレジデンシーを重視している。 +- [Dify Cloud](https://cloud.dify.ai) に興味があるが、ユースケースが [プラン](https://dify.ai/pricing) でサポートされているよりも多くのリソースを必要とする。 +- 組織内で Dify Enterprise を採用する前に POC を実行したい。 -## アクセス & セットアップ +## アクセスとセットアップ -AMIがデプロイされた後、EC2コンソールで確認できるインスタンスのパブリックIPを通じてDifyにアクセスします(デフォルトではHTTPポート80を使用)。 +AMI がデプロイされた後、EC2 コンソールで確認できるインスタンスのパブリック IP を通じて Dify にアクセスします。デフォルトでは HTTP ポート 80 を使用します。 -初めてDifyにアクセスする場合は、Admin初期化パスワード(EC2のインスタンスID)を入力してセットアップ処理を開始します。 +初めて Dify にアクセスする場合は、管理者初期化パスワード(EC2 のインスタンス ID)を入力してセットアップを開始します。 ## カスタマイズ ### 設定 -セルフホストデプロイと同様に、EC2インスタンス内の`.env`ファイルの環境変数を必要に応じて変更できます。その後、以下でDifyを再起動します: + + + EC2 インスタンスで、関連するファイルの環境変数を編集します: + + - **必須の起動値** は `/dify/.env` にあります。直接編集します。 -```bash -docker-compose down -docker-compose -f docker-compose.yaml -f docker-compose.override.yaml up -d -``` + - **オプションまたはプロバイダー固有の設定** は `/dify/envs/` にテンプレートとして用意されています。デフォルト値を上書きするには、対応するテンプレートをコピーし(`.example` 拡張子を外す)、コピーを編集します。 -### WebAppロゴ & ブランディング + 例: -**設定** > **カスタマイズ**で、`Powered by Dify`ブランディングを削除するか、独自のロゴに置き換えることができます。 + ```bash + cd /dify + cp envs/vectorstores/opensearch.env.example envs/vectorstores/opensearch.env + ``` + + `/dify/.env` の値は、`/dify/envs/*.env` ファイルの値より優先されます。 + + AWS デプロイで `docker-compose.override.yaml` を通じて変数が注入されている場合は、それらの設定をそのまま残してください。Compose のサービスレベル `environment:` の値は、env ファイルから読み込まれる値より優先されます。 + + + ```bash + docker compose down + docker compose -f docker-compose.yaml -f docker-compose.override.yaml up -d + ``` + + + +### Web アプリのロゴとブランディング + +**設定** > **カスタマイズ** で、`Powered by Dify` ブランディングを削除するか、独自のロゴに置き換えられます。 ## アップグレード - アップグレードする前に、GitHubの[リリースノート](https://github.com/langgenius/dify/releases)でバージョン固有のアップグレード手順を確認してください。一部のバージョンでは、データベースの移行や設定変更などの追加手順が必要な場合があります。 + - アップグレード前に、GitHub の [リリースノート](https://github.com/langgenius/dify/releases) でバージョン固有のアップグレード手順を確認してください。一部のバージョンでは、データベースの移行や設定変更などの追加手順が必要な場合があります。 + + - Dify の Docker Compose ファイルは現在 Docker Compose 2.24.0 以降を必要とします。アップグレード前に `docker compose version` を実行して確認してください。 -EC2インスタンスで、以下のコマンドを実行します: +EC2 インスタンスで、以下のコマンドを実行します: ```bash cd /dify - docker-compose down + docker compose down ``` - `.env`ファイルと`volumes`ディレクトリをバックアップします。これにはデータベース、ストレージ、その他の永続データが含まれています: + `.env` ファイル、`envs/` 下に作成したオプションの env ファイル、およびデータベースやストレージなどの永続データを含む `volumes` ディレクトリをバックアップします: ```bash cp /dify/.env /dify/.env.bak + tar -cvf envs-$(date +%s).tgz envs tar -cvf volumes-$(date +%s).tgz volumes ``` - + - アップグレードプロセスは設定ファイルを上書きしますが、`.env`ファイルや`volumes/`ディレクトリ内のランタイムデータ(データベースやアップロードされたファイルなど)には影響しません。 + アップグレードプロセスは設定テンプレートを上書きします。ただし、`.env` ファイル、ローカルの `/dify/envs/*.env` ファイル、`volumes/` ディレクトリ内のランタイムデータ(データベースやアップロードされたファイルなど)には影響しません。 - `.env`以外の設定ファイルを手動で変更している場合は、アップグレード前にバックアップしてください。 + `.env` と `/dify/envs/*.env` 以外の設定ファイルを手動で変更している場合は、アップグレード前にバックアップしてください。 最新のコードをプルし、設定ファイルを同期します: @@ -70,16 +94,21 @@ EC2インスタンスで、以下のコマンドを実行します: ``` - 新しいバージョンでは`.env.example`に新しい環境変数が導入される場合があります。現在の`.env`と比較し、不足している変数を追加してください: + 新しいバージョンでは `.env.example` または `envs/` 下のオプションテンプレートに新しい変数が導入される場合があります。各テンプレートと対応するローカル env ファイルを比較し、必要な不足変数を追加してください: ```bash diff /dify/.env /dify/.env.example + find /dify/envs -name "*.env" -print | while read -r env_file; do + diff "$env_file" "$env_file.example" + done ``` + + 新しく追加されたオプションテンプレートをカスタマイズする必要がある場合は、`.example` 拡張子を外したファイルとしてコピーしてから編集してください。詳細は [設定](#設定) を参照してください。 ```bash - docker-compose pull - docker-compose -f docker-compose.yaml -f docker-compose.override.yaml up -d + docker compose pull + docker compose -f docker-compose.yaml -f docker-compose.override.yaml up -d ``` diff --git a/ja/self-host/quick-start/docker-compose.mdx b/ja/self-host/quick-start/docker-compose.mdx index 07bc4c0ea..09b9630eb 100644 --- a/ja/self-host/quick-start/docker-compose.mdx +++ b/ja/self-host/quick-start/docker-compose.mdx @@ -6,12 +6,12 @@ sidebarTitle: Docker Compose ⚠️ このドキュメントは AI によって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/self-host/quick-start/docker-compose) を参照してください。 - 一般的なデプロイに関する質問については、[FAQ](/ja/self-host/quick-start/faqs) を参照してください。 + 一般的なデプロイの問題は [FAQ](/ja/self-host/quick-start/faqs) を参照してください。 ## デプロイ前の準備 -お使いのマシンが以下の最小システム要件を満たしていることを確認してください。 +マシンが以下の最小システム要件を満たしているか確認してください。 ### ハードウェア @@ -20,11 +20,11 @@ sidebarTitle: Docker Compose ### ソフトウェア -| オペレーティングシステム | 必要なソフトウェア | 備考 | -| :----------------------------- | :---------------------------------------- | :----- | -| macOS 10.14 以降 | Docker Desktop | Docker 仮想マシンを最低 2 つの仮想 CPU と 8 GiB のメモリで設定してください。



インストール手順については、[Mac 用 Docker Desktop のインストール](https://docs.docker.com/desktop/mac/install/) を参照してください。 | -| Linux ディストリビューション | Docker 19.03+



Docker Compose 1.28+ | インストール手順については、[Docker Engine のインストール](https://docs.docker.com/engine/install/) および [Docker Compose のインストール](https://docs.docker.com/compose/install/) を参照してください。 | -| WSL 2 が有効な Windows | Docker Desktop | Linux コンテナにバインドされるソースコードやデータは、Windows ファイルシステムではなく、Linux ファイルシステムに保存してください。



インストール手順については、[Windows 用 Docker Desktop のインストール](https://docs.docker.com/desktop/windows/install/#wsl-2-backend) を参照してください。 | +| オペレーティングシステム | 必要なソフトウェア | 備考 | +| :--- | :--- | :--- | +| macOS 10.14 以降 | Docker Desktop / Docker Compose 2.24.0+ | 2 vCPU 以上、8 GiB 以上のメモリを割り当てます。



[Mac 用 Docker Desktop のインストール](https://docs.docker.com/desktop/mac/install/) を参照してください。 | +| Linux | Docker 19.03+ / Docker Compose 2.24.0+ | 手順は以下を参照してください。



[Docker Engine のインストール](https://docs.docker.com/engine/install/) / [Docker Compose のインストール](https://docs.docker.com/compose/install/) | +| Windows (WSL 2) | Docker Desktop / Docker Compose 2.24.0+ | ソースコードとデータは Linux ファイルシステムに保存。



[Windows 用 Docker Desktop のインストール](https://docs.docker.com/desktop/windows/install/#wsl-2-backend) を参照してください。 | ## デプロイと起動 @@ -43,34 +43,30 @@ sidebarTitle: Docker Compose ```bash cd dify/docker ``` - - 2. 環境設定ファイルの例をコピーします: + + 2. 必須の環境設定ファイルをコピーします: ```bash - cp .env.example .env + cp .env.example .env ``` - 3. お使いの Docker Compose バージョンに合わせたコマンドでコンテナを起動します: + 後でデプロイをカスタマイズする場合は [カスタマイズ](#カスタマイズ) を参照してください。 - - ```bash Docker Compose V2 - docker compose up -d - ``` - ```bash Docker Compose V1 - docker-compose up -d - ``` - + 3. コンテナを起動します: + + Dify は Docker Compose 2.24.0 以降を必要とします。`docker compose version` を実行してバージョンを確認してください。 + - - `docker compose version` を実行して Docker Compose のバージョンを確認してください。 - + ```bash + docker compose up -d + ``` - 以下のコンテナが起動されます: + 以下のコンテナが起動します: - 5 つのコアサービス:`api`、`worker`、`worker_beat`、`web`、`plugin_daemon` - 6 つの依存コンポーネント:`weaviate`、`db_postgres`、`redis`、`nginx`、`ssrf_proxy`、`sandbox` - 各コンテナのステータスと起動時間を示す以下のような出力が表示されるはずです: + 各コンテナのステータスと起動時間を示す以下のような出力が表示されます: ```bash [+] Running 13/13 @@ -88,14 +84,14 @@ sidebarTitle: Docker Compose ✔ Container docker-plugin_daemon-1 Started 3.2s ✔ Container docker-nginx-1 Started 3.4s ``` - + 4. すべてのコンテナが正常に動作しているか確認します: ```bash docker compose ps ``` - 各コンテナが`Up`または`healthy`ステータスで表示される以下のような出力が表示されるはずです: + 各コンテナのステータスが `Up` または `healthy` となっている、以下のような出力が表示されます: ```bash NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS @@ -138,23 +134,43 @@ sidebarTitle: Docker Compose ## カスタマイズ -ローカルの `.env` ファイルの環境変数値を変更し、Dify を再起動して変更を適用します: +デプロイをカスタマイズするには、関連するファイルの環境変数を編集してから Dify を再起動します。 -```bash -docker compose down -docker compose up -d -``` + + - - 詳細については、[環境変数](/ja/self-host/configuration/environments) を参照してください。 - + - **必須の起動値** は `docker/.env` にあります(デプロイ時に `docker/.env.example` からコピーして作成したファイル)。直接編集します。 + + - **オプションまたはプロバイダー固有の設定** は `docker/envs/` にテンプレートとして用意されています。デフォルト値を上書きするには、対応するテンプレートをコピーし(`.example` 拡張子を外す)、コピーを編集します。 + + 例: + + ```bash + cd dify/docker + cp envs/vectorstores/milvus.env.example envs/vectorstores/milvus.env + ``` + + `docker/.env` の値は、`docker/envs/*.env` ファイルの値より優先されます。 + + + すべての変数の説明は [環境変数](/ja/self-host/configuration/environments) を参照してください。 + + + + + + ```bash + docker compose down + docker compose up -d + ``` + + + ## アップグレード アップグレード手順はリリースによって異なる場合があります。[Releases](https://github.com/langgenius/dify/releases) ページで提供されている対象バージョンのアップグレードガイドを参照してください。 - - アップグレード後、`.env.example` ファイルが変更されているかどうかを確認し、それに応じてローカルの `.env` ファイルを更新してください。 - - \ No newline at end of file + アップグレード後、各 `.env.example` を対応する `.env` と比較し、新規または変更された変数を確認してください。 + diff --git a/zh/self-host/advanced-deployments/local-source-code.mdx b/zh/self-host/advanced-deployments/local-source-code.mdx index bf06c5a89..cdf6cfaef 100644 --- a/zh/self-host/advanced-deployments/local-source-code.mdx +++ b/zh/self-host/advanced-deployments/local-source-code.mdx @@ -35,11 +35,10 @@ Dify 后端服务需要一系列用于存储(如 PostgreSQL / Redis / Weaviate ```bash cd docker -cp middleware.env.example middleware.env +cp envs/middleware.env.example middleware.env -# 如果不使用 postgresql,请将 profile 更改为 mysql -# 如果不使用 weaviate,请将 profile 更改为其他向量数据库 -docker compose -f docker-compose.middleware.yaml --profile postgresql --profile weaviate -p dify up -d +# 如果不使用 PostgreSQL 和 Weaviate,请修改 middleware.env 中的 DB_TYPE 或 COMPOSE_PROFILES。 +docker compose --env-file middleware.env -f docker-compose.middleware.yaml -p dify up -d ``` --- diff --git a/zh/self-host/configuration/environments.mdx b/zh/self-host/configuration/environments.mdx index 9214e2920..8dc4fec8d 100644 --- a/zh/self-host/configuration/environments.mdx +++ b/zh/self-host/configuration/environments.mdx @@ -5,10 +5,21 @@ description: Dify 自托管部署使用的所有环境变量参考 ⚠️ 本文档由 AI 自动翻译。如有任何不准确之处,请参考 [英文原版](/en/self-host/configuration/environments)。 -Dify 使用默认配置即可开箱即用。你可以通过修改 `.env` 文件中的环境变量来自定义部署。 +Dify 使用默认配置即可开箱即用。如需自定义部署,编辑相关文件中的环境变量: + +- **必要的启动值** 位于 `docker/.env` 文件中(部署时从 `docker/.env.example` 复制创建)。直接编辑即可。 + +- **可选或特定提供商的设置** 在 `docker/envs/` 下有对应模板。要覆盖默认值,复制相应模板(去掉 `.example` 后缀),然后编辑副本。例如: + + ```bash + cd dify/docker + cp envs/vectorstores/milvus.env.example envs/vectorstores/milvus.env + ``` + +`docker/.env` 中的值优先于任何 `docker/envs/*.env` 文件中的值。 -升级 Dify 后,在 `docker` 目录下运行 `diff .env .env.example` 检查新增或变更的变量,然后相应更新你的 `.env` 文件。 +升级 Dify 后,对照各 `.env.example` 文件检查对应的 `.env`,确认是否有新增或变更的变量。 ## 通用变量 diff --git a/zh/self-host/platform-guides/dify-premium.mdx b/zh/self-host/platform-guides/dify-premium.mdx index ead0d1a35..4fd542c49 100644 --- a/zh/self-host/platform-guides/dify-premium.mdx +++ b/zh/self-host/platform-guides/dify-premium.mdx @@ -1,5 +1,6 @@ --- title: AWS 上的 Dify Premium +description: 在 AWS 上部署、自定义和升级 Dify Premium --- ⚠️ 本文档由 AI 自动翻译。如有任何不准确之处,请参考 [英文原版](/en/self-host/platform-guides/dify-premium)。 @@ -14,27 +15,49 @@ Dify Premium 是我们的 AWS AMI 产品,支持自定义品牌,可一键部 AMI 部署后,通过 EC2 控制台中找到的实例公共 IP 访问 Dify(默认使用 HTTP 端口 80)。 -如果这是你首次访问 Dify,请输入管理员初始化密码(你的 EC2 实例 ID)来开始设置过程。 +如果这是你首次访问 Dify,输入管理员初始化密码(你的 EC2 实例 ID)来开始设置过程。 ## 自定义 ### 配置 -就像自托管部署一样,你可以根据需要修改 EC2 实例中 `.env` 文件下的环境变量。然后,使用以下命令重启 Dify: + + + 在 EC2 实例中,编辑相关文件中的环境变量: + + - **必要的启动值** 位于 `/dify/.env` 文件中。直接编辑即可。 + + - **可选或特定提供商的设置** 在 `/dify/envs/` 下有对应模板。要覆盖默认值,复制相应模板(去掉 `.example` 后缀),然后编辑副本。 + + 例如: -```bash -docker-compose down -docker-compose -f docker-compose.yaml -f docker-compose.override.yaml up -d -``` + ```bash + cd /dify + cp envs/vectorstores/opensearch.env.example envs/vectorstores/opensearch.env + ``` + + `/dify/.env` 中的值优先于任何 `/dify/envs/*.env` 文件中的值。 + + 如果你的 AWS 部署通过 `docker-compose.override.yaml` 注入变量,将这些设置保留在该文件中。Compose 中服务级别的 `environment:` 值优先于 env 文件中的值。 + + + ```bash + docker compose down + docker compose -f docker-compose.yaml -f docker-compose.override.yaml up -d + ``` + + ### Web 应用标志和品牌 -在**设置** > **自定义**中,你可以移除 `Powered by Dify` 品牌标识或替换为你自己的标志。 +在 **设置** > **自定义** 中,可移除 `Powered by Dify` 品牌标识或替换为你自己的标志。 ## 升级 - 在升级之前,请查看 GitHub 上的 [Release Notes](https://github.com/langgenius/dify/releases) 了解特定版本的升级说明。某些版本可能需要额外的步骤,例如数据库迁移或配置更改。 + - 升级前,查看 GitHub 上的 [Release Notes](https://github.com/langgenius/dify/releases) 了解特定版本的升级说明。某些版本可能需要额外步骤,例如数据库迁移或配置更改。 + + - Dify 的 Docker Compose 文件现在需要 Docker Compose 2.24.0 或更高版本。升级前运行 `docker compose version` 确认。 在 EC2 实例中,运行以下命令: @@ -43,22 +66,23 @@ docker-compose -f docker-compose.yaml -f docker-compose.override.yaml up -d ```bash cd /dify - docker-compose down + docker compose down ``` - 备份你的 `.env` 文件和 `volumes` 目录,其中包含你的数据库、存储和其他持久化数据: + 备份 `.env` 文件、`envs/` 下你创建的任何可选 env 文件,以及包含数据库、存储和其他持久化数据的 `volumes` 目录: ```bash cp /dify/.env /dify/.env.bak + tar -cvf envs-$(date +%s).tgz envs tar -cvf volumes-$(date +%s).tgz volumes ``` - 升级过程会覆盖配置文件,但不会影响你的 `.env` 文件或 `volumes/` 目录中的运行时数据(如数据库和上传的文件)。 + 升级过程将覆盖配置模板,但不会影响 `.env` 文件、本地的 `/dify/envs/*.env` 文件或 `volumes/` 目录中的运行时数据(如数据库和上传的文件)。 - 如果你手动修改过 `.env` 以外的任何配置文件,请在升级前备份它们。 + 如果你手动修改过 `.env` 和 `/dify/envs/*.env` 以外的任何配置文件,请在升级前备份它们。 拉取最新代码并同步配置文件: @@ -70,16 +94,21 @@ docker-compose -f docker-compose.yaml -f docker-compose.override.yaml up -d ``` - 新版本可能会在 `.env.example` 中引入新的环境变量。将其与你当前的 `.env` 进行比较,并添加任何缺失的变量: + 新版本可能在 `.env.example` 或 `envs/` 下的可选模板中引入新变量。将每个模板与对应的本地 env 文件进行比较,并添加任何你需要的缺失变量: ```bash diff /dify/.env /dify/.env.example + find /dify/envs -name "*.env" -print | while read -r env_file; do + diff "$env_file" "$env_file.example" + done ``` + + 如需自定义新增的可选模板,复制该文件(去掉 `.example` 后缀)后再编辑。详见 [配置](#配置)。 ```bash - docker-compose pull - docker-compose -f docker-compose.yaml -f docker-compose.override.yaml up -d + docker compose pull + docker compose -f docker-compose.yaml -f docker-compose.override.yaml up -d ``` diff --git a/zh/self-host/quick-start/docker-compose.mdx b/zh/self-host/quick-start/docker-compose.mdx index a02556ba5..d93573668 100644 --- a/zh/self-host/quick-start/docker-compose.mdx +++ b/zh/self-host/quick-start/docker-compose.mdx @@ -6,12 +6,12 @@ sidebarTitle: Docker Compose ⚠️ 本文档由 AI 自动翻译。如有任何不准确之处,请参考 [英文原版](/en/self-host/quick-start/docker-compose)。 - 如需了解常见部署问题,请参阅 [常见问题解答](/zh/self-host/quick-start/faqs)。 + 常见部署问题,详见 [常见问题解答](/zh/self-host/quick-start/faqs)。 ## 部署前准备 -请确保你的机器满足以下最低系统要求。 +确保机器满足以下最低系统要求。 ### 硬件 @@ -20,18 +20,17 @@ sidebarTitle: Docker Compose ### 软件 -| 操作系统 | 所需软件 | 说明 | -| :----------------------------- | :---------------------------------------- | :----- | -| macOS 10.14 或更高版本 | Docker Desktop | 将 Docker 虚拟机配置为至少 2 个虚拟 CPU 和 8 GiB 内存。



安装说明请参阅 [Mac 版 Docker Desktop 安装指南](https://docs.docker.com/desktop/mac/install/)。 | -| Linux 平台 | Docker 19.03+



Docker Compose 1.28+ | 安装说明请参阅 [Docker 引擎安装指南](https://docs.docker.com/engine/install/) 和 [Docker Compose 安装指南](https://docs.docker.com/compose/install/)。 | -| 启用了 WSL 2 的 Windows | Docker Desktop | 建议将源代码和绑定到 Linux 容器的数据存储在 Linux 文件系统中,而不是 Windows 文件系统中。



安装说明请参阅 [Windows 版 Docker Desktop 安装指南](https://docs.docker.com/desktop/windows/install/#wsl-2-backend)。 | - +| 操作系统 | 所需软件 | 说明 | +| :--- | :--- | :--- | +| macOS 10.14 或更高版本 | Docker Desktop(含 Docker Compose 2.24.0+) | Docker 虚拟机至少配置 2 个虚拟 CPU 和 8 GiB 内存。



安装说明详见 [Mac 版 Docker Desktop 安装指南](https://docs.docker.com/desktop/mac/install/)。 | +| Linux 发行版 | Docker 19.03+



Docker Compose 2.24.0+ | 安装说明详见 [Docker 引擎安装指南](https://docs.docker.com/engine/install/) 和 [Docker Compose 安装指南](https://docs.docker.com/compose/install/)。 | +| Windows(启用 WSL 2) | Docker Desktop(含 Docker Compose 2.24.0+) | 源代码和绑定到 Linux 容器的数据建议存储在 Linux 文件系统中,而非 Windows。



安装说明详见 [Windows 版 Docker Desktop 安装指南](https://docs.docker.com/desktop/windows/install/#wsl-2-backend)。 | ## 部署并启动 - 将 Dify 源代码克隆到本地机器。 + 克隆 Dify 源代码到本地机器。 ```bash git clone --branch "$(curl -s https://api.github.com/repos/langgenius/dify/releases/latest | jq -r .tag_name)" https://github.com/langgenius/dify.git @@ -39,39 +38,35 @@ sidebarTitle: Docker Compose - 1. 导航到 Dify 源代码中的 `docker` 目录: + 1. 进入 Dify 源代码中的 `docker` 目录: ```bash cd dify/docker ``` - - 2. 复制示例环境配置文件: + + 2. 复制必要的环境配置文件: ```bash - cp .env.example .env + cp .env.example .env ``` - 3. 根据你的 Docker Compose 版本选择相应命令启动容器: + 如需自定义部署,参见 [自定义](#自定义)。 - - ```bash Docker Compose V2 - docker compose up -d - ``` - ```bash Docker Compose V1 - docker-compose up -d - ``` - + 3. 启动容器: + + Dify 需要 Docker Compose 2.24.0 或更高版本。运行 `docker compose version` 确认版本。 + - - 运行 `docker compose version` 检查你的 Docker Compose 版本。 - + ```bash + docker compose up -d + ``` - 将启动以下容器: + 启动以下容器: - 5 个核心服务:`api`、`worker`、`worker_beat`、`web`、`plugin_daemon` - 6 个依赖组件:`weaviate`、`db_postgres`、`redis`、`nginx`、`ssrf_proxy`、`sandbox` - 你应该会看到类似以下的输出,显示每个容器的状态和启动时间: + 应看到类似以下的输出,显示每个容器的状态和启动时间: ```bash [+] Running 13/13 @@ -89,14 +84,14 @@ sidebarTitle: Docker Compose ✔ Container docker-plugin_daemon-1 Started 3.2s ✔ Container docker-nginx-1 Started 3.4s ``` - + 4. 验证所有容器是否成功运行: ```bash docker compose ps ``` - 你应该会看到类似以下的输出,每个容器的状态应为 `Up` 或 `healthy`: + 应看到类似以下的输出,每个容器的状态应为 `Up` 或 `healthy`: ```bash NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS @@ -117,7 +112,7 @@ sidebarTitle: Docker Compose ## 访问 -1. 打开管理员初始化页面以设置管理员账户: +1. 打开管理员初始化页面,设置管理员账户: ```bash # 本地环境 @@ -139,23 +134,43 @@ sidebarTitle: Docker Compose ## 自定义 -修改本地 `.env` 文件中的环境变量值,然后重启 Dify 以应用更改: +如需自定义部署,编辑相关文件中的环境变量,然后重启 Dify。 -```bash -docker compose down -docker compose up -d -``` + + - - 更多信息请参阅 [环境变量](/zh/self-host/configuration/environments)。 - + - **必要的启动值** 位于 `docker/.env` 文件中(部署时从 `docker/.env.example` 复制创建)。直接编辑即可。 -## 升级 + - **可选或特定提供商的设置** 在 `docker/envs/` 下有对应模板。要覆盖默认值,复制相应模板(去掉 `.example` 后缀),然后编辑副本。 -不同版本的升级步骤可能有所不同。请参阅 [Releases](https://github.com/langgenius/dify/releases) 页面中提供的目标版本升级指南。 + 例如: - + ```bash + cd dify/docker + cp envs/vectorstores/milvus.env.example envs/vectorstores/milvus.env + ``` - 升级后,请检查 `.env.example` 文件是否有变更,并相应更新你的本地 `.env` 文件。 + `docker/.env` 中的值优先于任何 `docker/envs/*.env` 文件中的值。 - \ No newline at end of file + + 所有变量的说明,详见 [环境变量](/zh/self-host/configuration/environments)。 + + + + + + ```bash + docker compose down + docker compose up -d + ``` + + + + +## 升级 + +不同版本的升级步骤可能有所不同。详见 [Releases](https://github.com/langgenius/dify/releases) 页面中提供的目标版本升级指南。 + + + 升级后,对照各 `.env.example` 文件检查对应的 `.env`,确认是否有新增或变更的变量。 + From 332f7265a629ad7e629ece9f09ebe93763e498bc Mon Sep 17 00:00:00 2001 From: Riskey <36894937+RiskeyL@users.noreply.github.com> Date: Tue, 12 May 2026 11:10:59 +0800 Subject: [PATCH 3/4] Docs/1.14.1 check (#775) * docs: sync knowledge api spec for 1.14.1 * chore: tighten release-sync and api-reference skills * docs: update education discount steps * docs: relax over-applied zh translation rules * docs: sync env vars for 1.14.1 * chore: env-vars verifier supports multi-file layout * docs: cover editable class labels in question classifier; sync question classifier zh/ja docs * chore: sync termbase_i18n with current glossary * docs: update collaboration docs for websocket service split; sync zh/ja translation * docs: human input updates for 1.14.1; sync zh/ja * docs: add end user term to glossary * chore: align ja api spec human input terminology with glossary * fix: enforce at-least-one tag in unbinding request schema * Revert "fix: enforce at-least-one tag in unbinding request schema" This reverts commit b392b148. Mintlify renders schema-level `anyOf` as unlabeled "Option 1" / "Option 2" tabs in the request body section, which is more confusing than the loose-schema-with-prose-rule it replaced. The SDK-generator benefit isn't worth the rendered-docs regression for a deprecated compat path. Keep the contract in the parameter descriptions only. Co-Authored-By: Claude Opus 4.7 (1M context) --------- Co-authored-by: Claude Opus 4.7 (1M context) --- .../skills/dify-docs-api-reference/SKILL.md | 15 +++ .claude/skills/dify-docs-env-vars/SKILL.md | 16 ++- .../dify-docs-env-vars/verify-env-docs.py | 85 +++++++++++++--- .../skills/dify-docs-release-sync/SKILL.md | 24 ++++- en/api-reference/openapi_knowledge.json | 91 +++++++++++++++++- en/self-host/configuration/environments.mdx | 23 ++--- en/use-dify/build/workflow-collaboration.mdx | 7 +- en/use-dify/nodes/human-input.mdx | 32 +++--- en/use-dify/nodes/question-classifier.mdx | 28 ++++-- .../workspace/subscription-management.mdx | 18 ++-- .../human-input-action-button-config.png | Bin 0 -> 22040 bytes ja/api-reference/openapi_chat.json | 2 +- ja/api-reference/openapi_chatflow.json | 32 +++--- ja/api-reference/openapi_knowledge.json | 91 +++++++++++++++++- ja/api-reference/openapi_workflow.json | 6 +- ja/self-host/configuration/environments.mdx | 23 ++--- ja/use-dify/build/workflow-collaboration.mdx | 9 +- ja/use-dify/nodes/human-input.mdx | 40 +++++--- ja/use-dify/nodes/question-classifier.mdx | 85 +++++++--------- .../workspace/subscription-management.mdx | 14 ++- tools/translate/formatting-zh.md | 3 - tools/translate/termbase_i18n.md | 83 +++++++++++++++- writing-guides/glossary.md | 9 ++ zh/api-reference/openapi_knowledge.json | 91 +++++++++++++++++- zh/self-host/configuration/environments.mdx | 23 ++--- zh/use-dify/build/workflow-collaboration.mdx | 9 +- zh/use-dify/nodes/human-input.mdx | 40 +++++--- zh/use-dify/nodes/question-classifier.mdx | 77 ++++++--------- .../workspace/subscription-management.mdx | 14 ++- 29 files changed, 715 insertions(+), 275 deletions(-) create mode 100644 images/use-dify/workflow/human-input-action-button-config.png diff --git a/.claude/skills/dify-docs-api-reference/SKILL.md b/.claude/skills/dify-docs-api-reference/SKILL.md index 6d833334d..9b3564da3 100644 --- a/.claude/skills/dify-docs-api-reference/SKILL.md +++ b/.claude/skills/dify-docs-api-reference/SKILL.md @@ -143,6 +143,21 @@ Pattern: `{verb}{AppType}{Resource}` - **Descriptions must add value**: `"Session identifier."` is a label, not a description. Instead: `"The \`user\` identifier provided in API requests."`. - **Nullable/conditional fields**: Explain when present or `null`. +#### Endpoint vs parameter descriptions + +| Field | Scope | +|---|---| +| Endpoint `description` | What the endpoint does, plus any whole-API surprise (cascading delete, long-poll duration). One sentence when possible. | +| Parameter `description` | Field meaning, valid values, deprecation, normalization, and rules about when to use it vs an alternative. | + +If the endpoint description explains a parameter, move it down. + +❌ "Remove one or more tag bindings from a knowledge base. Provide tag IDs in `tag_ids`. The legacy `tag_id` field is still accepted for single-tag requests and is normalized into `tag_ids` server-side; supply at least one of the two." + +✅ Endpoint: "Remove one or more tags from a knowledge base." + `tag_ids`: "Tag IDs to unbind. Required unless the legacy `tag_id` is provided." + `tag_id`: "Legacy single-tag form. Normalized into `tag_ids` server-side. Use `tag_ids` for new integrations." + ### Cross-API Links When a description mentions another endpoint, add a markdown link. Pattern: `/api-reference/{category}/{endpoint-name}` (kebab-case from endpoint summary). diff --git a/.claude/skills/dify-docs-env-vars/SKILL.md b/.claude/skills/dify-docs-env-vars/SKILL.md index 59c75aa39..dd4e9b70e 100644 --- a/.claude/skills/dify-docs-env-vars/SKILL.md +++ b/.claude/skills/dify-docs-env-vars/SKILL.md @@ -17,15 +17,21 @@ Read these shared guides: 2. `writing-guides/formatting-guide.md` 3. `writing-guides/glossary.md` -## Source of Truth: `docker/.env.example` +## Source of Truth: `docker/.env.example` + `docker/envs/**/*.env.example` -The doc mirrors `docker/.env.example`, the supported self-host knob surface. +After Dify PR #31586, the supported self-host knob surface is split across: + +- `docker/.env.example` — essential startup values +- `docker/envs/**/*.env.example` — categorized optional vars (core-services, databases, infrastructure, security, vectorstores, middleware) + +The verifier reads both. Pass `--env-example docker/.env.example --env-example docker/envs` (the second arg is a directory; the verifier globs `**/*.env.example` recursively). | Var location | Action | |---|---| -| In `.env.example`, uncommented | Document. | -| In `.env.example`, commented (`#FOO=bar`) | Document; add to **Verifier false positives** in `ignored-vars.md` (the verifier can't parse defaults from comments). | -| Only in `api/configs/` Pydantic, not in `.env.example` | **Don't document.** Upstream-deferred; file a PR adding it to `.env.example` first. | +| In any `.env.example` file, uncommented | Document. | +| In any `.env.example` file, commented (`#FOO=bar`) | Document; add to **Verifier false positives** in `ignored-vars.md` (the verifier can't parse defaults from comments). | +| Only in `api/configs/` Pydantic, not in any `.env.example` | **Don't document.** Upstream-deferred; file a PR adding it to the appropriate `.env.example` file first. | +| Removed from `.env.example` because the code no longer reads it | **Remove from docs.** Documenting unreferenced vars implies they still take effect. Discoverability for upgraders belongs in upstream Dify release notes, not this docs site. | The verifier's "extra in docs" signal is not an escape hatch. Never suppress it for Pydantic-only vars via `ignored-vars.md`. diff --git a/.claude/skills/dify-docs-env-vars/verify-env-docs.py b/.claude/skills/dify-docs-env-vars/verify-env-docs.py index a8e0f0eec..5c4de6af1 100644 --- a/.claude/skills/dify-docs-env-vars/verify-env-docs.py +++ b/.claude/skills/dify-docs-env-vars/verify-env-docs.py @@ -1,14 +1,18 @@ #!/usr/bin/env python3 """ -Verify Dify environment variable documentation against .env.example. +Verify Dify environment variable documentation against .env.example sources. -Parses both files, extracts variable names and defaults, and reports -discrepancies between what the documentation says and what .env.example defines. +Parses one or more env-example files plus the docs MDX, extracts variable names +and defaults, and reports discrepancies. + +After Dify PR #31586, env vars were split across `docker/.env.example` and +`docker/envs/**/*.env.example`. The verifier accepts either a single file or +a directory; passing a directory globs `**/*.env.example` recursively. Usage: - python3 verify-env-docs.py [--env-example PATH] [--docs PATH] + python3 verify-env-docs.py --env-example PATH [--env-example PATH ...] --docs PATH -Both arguments are required (no defaults). +`--env-example` may be repeated and may point to either a file or a directory. """ import argparse @@ -17,8 +21,8 @@ from pathlib import Path -def parse_env_example(path: str) -> dict[str, str]: - """Parse .env.example and return {VARIABLE_NAME: default_value}.""" +def parse_env_file(path: Path) -> dict[str, str]: + """Parse a single env-example file and return {VARIABLE_NAME: default_value}.""" variables = {} with open(path, encoding="utf-8") as f: for line in f: @@ -35,6 +39,52 @@ def parse_env_example(path: str) -> dict[str, str]: return variables +def collect_env_files(sources: list[str]) -> list[Path]: + """Resolve each source (file or directory) into a list of env-example files. + + Files are returned as-is. Directories are scanned recursively for any + file whose name ends with `.env.example` (matches both `.env.example` + and `.env.example`). + """ + files: list[Path] = [] + seen: set[Path] = set() + for source in sources: + p = Path(source) + if not p.exists(): + print(f"ERROR: env source not found: {source}", file=sys.stderr) + sys.exit(1) + if p.is_dir(): + for f in sorted(p.rglob("*.env.example")): + if f not in seen: + files.append(f) + seen.add(f) + # Also catch the bare `.env.example` filename, which rglob's + # `*.env.example` pattern does include via the leading wildcard, + # but be explicit for clarity. + for f in sorted(p.rglob(".env.example")): + if f not in seen: + files.append(f) + seen.add(f) + else: + if p not in seen: + files.append(p) + seen.add(p) + return files + + +def parse_env_example(sources: list[str]) -> tuple[dict[str, str], list[Path]]: + """Parse all env-example files reachable from the given sources. + + Later files override earlier ones for duplicate keys. Returns the merged + variable map plus the list of files actually parsed (for diagnostics). + """ + files = collect_env_files(sources) + merged: dict[str, str] = {} + for f in files: + merged.update(parse_env_file(f)) + return merged, files + + def parse_ignored_vars(path: str) -> set[str]: """Parse the ignored-vars markdown file and return the set of ignored names. @@ -183,7 +233,13 @@ def main(): parser.add_argument( "--env-example", required=True, - help="Path to .env.example file (e.g., /path/to/dify/docker/.env.example)", + action="append", + help=( + "Path to a .env.example file or to a directory containing them. " + "May be repeated. When given a directory, the verifier globs " + "**/*.env.example recursively. Pass both `docker/.env.example` and " + "`docker/envs/` to capture the post-PR-#31586 layout." + ), ) parser.add_argument( "--docs", @@ -197,18 +253,17 @@ def main(): ) args = parser.parse_args() - if not Path(args.env_example).exists(): - print(f"ERROR: .env.example not found at {args.env_example}") - sys.exit(1) if not Path(args.docs).exists(): print(f"ERROR: Documentation not found at {args.docs}") sys.exit(1) - env_vars = parse_env_example(args.env_example) + env_vars, env_files = parse_env_example(args.env_example) doc_vars = parse_mdx_docs(args.docs) ignored = parse_ignored_vars(args.ignored) - print(f"Parsed {len(env_vars)} variables from .env.example") + print(f"Parsed {len(env_vars)} variables from {len(env_files)} env-example file(s):") + for f in env_files: + print(f" - {f}") print(f"Parsed {len(doc_vars)} variables from documentation") print(f"Loaded {len(ignored)} ignored variables from {args.ignored}") print() @@ -223,12 +278,12 @@ def main(): print(f" {name}={env_vars[name]}") print() - # --- Check 2: Variables in docs but not in .env.example --- + # --- Check 2: Variables in docs but not in any env-example source --- extra_in_docs = sorted( (set(doc_vars.keys()) - set(env_vars.keys())) - ignored ) if extra_in_docs: - print(f"=== IN DOCS BUT NOT IN .env.example ({len(extra_in_docs)}) ===") + print(f"=== IN DOCS BUT NOT IN ANY .env.example ({len(extra_in_docs)}) ===") for name in extra_in_docs: print(f" {name} (doc default: {doc_vars[name]!r})") print() diff --git a/.claude/skills/dify-docs-release-sync/SKILL.md b/.claude/skills/dify-docs-release-sync/SKILL.md index 6894eba50..21c231706 100644 --- a/.claude/skills/dify-docs-release-sync/SKILL.md +++ b/.claude/skills/dify-docs-release-sync/SKILL.md @@ -53,6 +53,23 @@ git log .. --oneline --grep="(#" This captures every change between the two versions, regardless of whether PRs were tagged to a milestone. +**Do not pre-filter the diff to a hand-picked path list.** Run `git diff --stat` over the full change set, then categorize in 1.2. Pre-filtering hides files like new `docker/dify-compose*` scripts, `docker/.env.default`, `docker/README.md`, or root `README.md` that drive deployment-doc updates. + +### 1.1a Cross-check existing docs PRs + +Before generating the report, check whether dify-docs already has open or recently-merged PRs covering the same source PRs. This prevents duplicate work and reveals doc paths you might miss: + +```bash +# Search by source-PR number(s) you plan to flag +gh pr list --repo langgenius/dify-docs --state all --search "#" \ + --json number,title,state,files +# Or scan recent docs PRs for the release window +gh pr list --repo langgenius/dify-docs --state all --limit 30 \ + --json number,title,state,mergedAt,files +``` + +If a docs PR already covers an item, mark it **Already addressed (PR #N)** in the report and exclude it from execution. + For context on specific changes, fetch the relevant PR details: ```bash # Extract PR numbers from commit messages @@ -110,8 +127,8 @@ Read the PR description for context. Map changed source paths to likely doc area | dify | `api/core/agent/` | `en/use-dify/build-apps/agent.mdx` | | dify | `api/core/app/` | `en/use-dify/build-apps/` | | dify | `web/app/components/` | UI-related docs (check PR description for specifics) | -| dify | `docker/`, deployment configs | `en/getting-started/install/` | -| dify | `api/configs/` | Configuration/environment variable docs | +| dify | `docker/.env.example`, `docker/docker-compose.yaml`, `docker/docker-compose-template.yaml`, `api/configs/` | `en/self-host/configuration/environments.mdx` (env var docs) | +| dify | `docker/README.md`, `docker/dify-compose*`, `docker/.env.default`, root `README.md`, any new file under `docker/` | `en/self-host/quick-start/docker-compose.mdx` and `en/self-host/quick-start/faqs.mdx` (deployment workflow docs) | | graphon | `src/graphon/nodes/` (built-in nodes: llm, code, http_request, if_else, loop, iteration, parameter_extractor, document_extractor, list_operator, variable_aggregator/assigner, question_classifier, template_transform, tool, start/end/answer, human_input) | `en/use-dify/workflow/nodes/` | | graphon | `src/graphon/model_runtime/` | `en/use-dify/model-providers/` | | graphon | `src/graphon/graph_engine/`, `src/graphon/runtime/` | workflow engine behavior, execution semantics | @@ -296,3 +313,6 @@ For each affected variable group, use `dify-docs-env-vars` skill: | Skipping Pydantic model changes | A model change may affect multiple endpoints — trace which controllers use it | | Forgetting to checkout target version | Audit against the target release code, not whatever is currently checked out | | Manually translating after EN fixes | Translation is automatic on PR push — never run manual translation scripts. **Exception**: `environments.mdx` is in the ignore list and must be translated manually. | +| Pre-filtering the diff to a hand-picked path list | Run the full `git diff --stat` first; categorize after. Pre-filtering hides deployment scripts, new docker files, and root README changes. | +| Trusting the `chore:` / `fix:` prefix as a no-doc-impact signal | Read the PR title and body. "chore: easier and simpler deploy" is a deployment workflow change. Prefix is not a category. | +| Skipping the dify-docs PR cross-check | Always run `gh pr list --repo langgenius/dify-docs` against the source PR numbers before reporting. Avoids duplicate work and surfaces doc paths the heuristic mapping missed. | diff --git a/en/api-reference/openapi_knowledge.json b/en/api-reference/openapi_knowledge.json index 9cc881180..14e1d8258 100644 --- a/en/api-reference/openapi_knowledge.json +++ b/en/api-reference/openapi_knowledge.json @@ -4544,7 +4544,7 @@ "Tags" ], "summary": "Delete Tag Binding", - "description": "Remove a tag binding from a knowledge base.", + "description": "Remove one or more tags from a knowledge base.", "operationId": "unbindTagFromDataset", "requestBody": { "required": true, @@ -4553,13 +4553,21 @@ "schema": { "type": "object", "required": [ - "tag_id", "target_id" ], "properties": { + "tag_ids": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1, + "description": "Tag IDs to unbind. Required unless the legacy `tag_id` is provided." + }, "tag_id": { "type": "string", - "description": "Tag ID to unbind." + "deprecated": true, + "description": "Legacy single-tag form. Normalized into `tag_ids` server-side. Use `tag_ids` for new integrations." }, "target_id": { "type": "string", @@ -6871,6 +6879,83 @@ } } } + }, + "metadata_filtering_conditions": { + "type": "object", + "nullable": true, + "description": "Restrict retrieval to chunks whose document metadata matches the given conditions. Conditions are evaluated server-side against document metadata fields.", + "properties": { + "logical_operator": { + "type": "string", + "enum": [ + "and", + "or" + ], + "default": "and", + "nullable": true, + "description": "How to combine multiple conditions." + }, + "conditions": { + "type": "array", + "nullable": true, + "description": "List of metadata conditions to evaluate.", + "items": { + "type": "object", + "required": [ + "name", + "comparison_operator" + ], + "properties": { + "name": { + "type": "string", + "description": "Metadata field name to compare against." + }, + "comparison_operator": { + "type": "string", + "description": "Comparison to apply. String operators (`contains`, `not contains`, `start with`, `end with`, `is`, `is not`, `empty`, `not empty`, `in`, `not in`) act on string or array metadata. Numeric operators (`=`, `≠`, `>`, `<`, `≥`, `≤`) act on numeric metadata. Time operators (`before`, `after`) act on time metadata.", + "enum": [ + "contains", + "not contains", + "start with", + "end with", + "is", + "is not", + "empty", + "not empty", + "in", + "not in", + "=", + "≠", + ">", + "<", + "≥", + "≤", + "before", + "after" + ] + }, + "value": { + "nullable": true, + "description": "Value to compare against. Type depends on `comparison_operator`: string for most string operators, array of strings for `in` and `not in`, number for numeric operators, and omitted for `empty` and `not empty`.", + "oneOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "number" + } + ] + } + } + } + } + } } } } diff --git a/en/self-host/configuration/environments.mdx b/en/self-host/configuration/environments.mdx index abb8e4971..8493c1599 100644 --- a/en/self-host/configuration/environments.mdx +++ b/en/self-host/configuration/environments.mdx @@ -106,14 +106,13 @@ How long signed file URLs remain valid, in seconds. After this time, the URL is ### ENABLE_COLLABORATION_MODE -Default: `false` +Default: `true` -Master switch for real-time collaboration on the Workflow canvas, covering simultaneous editing, in-canvas comments, and @mentions. +Enables real-time collaboration on the Workflow canvas: simultaneous editing, in-canvas comments, and @mentions. -Setting this alone is not sufficient. Collaboration runs over WebSocket, which also requires: +If you access Dify on a host other than `localhost`, set `NEXT_PUBLIC_SOCKET_URL` to a WebSocket URL your browser can reach (see [CORS Configuration](#cors-configuration)). The default `ws://localhost` only works for local-only setups. -- `SERVER_WORKER_CLASS` set to `geventwebsocket.gunicorn.workers.GeventWebSocketWorker` (see [Container Startup Configuration](#container-startup-configuration)). -- `NEXT_PUBLIC_SOCKET_URL` set to a WebSocket URL your browser can reach (see [CORS Configuration](#cors-configuration)). +To disable collaboration, set this to `false`. On Docker Compose, also remove `collaboration` from `COMPOSE_PROFILES`. Otherwise the dedicated `api_websocket` container keeps running but receives no traffic. If you use your own reverse proxy, forward `Upgrade` and `Connection` headers on `/socket.io/` (the bundled nginx template already does this). Running multiple API replicas requires sticky sessions. @@ -191,9 +190,12 @@ Only effective when starting with Docker image or Docker Compose. | `DIFY_BIND_ADDRESS` | `0.0.0.0` | Network interface the API server binds to. `0.0.0.0` listens on all interfaces; set to `127.0.0.1` to restrict to localhost only. | | `DIFY_PORT` | `5001` | Port the API server listens on. | | `SERVER_WORKER_AMOUNT` | `1` | Number of Gunicorn worker processes. With gevent (default), each worker handles multiple concurrent connections via greenlets, so 1 is usually sufficient. For sync workers, use `(2 x CPU cores) + 1`. [Reference](https://gunicorn.org/design/#how-many-workers). | -| `SERVER_WORKER_CLASS` | `gevent` | Gunicorn worker type. `gevent` provides lightweight async concurrency. Set to `geventwebsocket.gunicorn.workers.GeventWebSocketWorker` when `ENABLE_COLLABORATION_MODE` is `true`; left at `gevent`, WebSocket handshakes fail silently. Other values break psycopg2 and gRPC patching. | +| `SERVER_WORKER_CLASS` | `gevent` | Gunicorn worker type. Keep the default; other values break psycopg2 and gRPC patching. | | `SERVER_WORKER_CONNECTIONS` | `10` | Maximum concurrent connections per worker. Only applies to async workers (gevent). If you experience connection rejections or slow responses under load, try increasing this value. | | `GUNICORN_TIMEOUT` | `360` | If a worker doesn't respond within this many seconds, Gunicorn kills and restarts it. Set to 360 (6 minutes) to support long-lived SSE connections used for streaming LLM responses. | +| `API_WEBSOCKET_WORKER_CLASS` | `geventwebsocket.gunicorn.workers.GeventWebSocketWorker` | Docker Compose only. Worker class for the dedicated `api_websocket` container. Keep the default; other values break WebSocket support. | +| `API_WEBSOCKET_WORKER_CONNECTIONS` | `1000` | Docker Compose only. Maximum simultaneous WebSocket connections the `api_websocket` container accepts. Each open Workflow editor in a browser tab uses one, so the default supports up to 1000 simultaneous editor sessions; raise it if you expect more. | +| `API_WEBSOCKET_GUNICORN_TIMEOUT` | `360` | Docker Compose only. If an `api_websocket` worker doesn't respond within this many seconds, Gunicorn restarts it. The default 360 seconds (6 minutes) supports long-lived WebSocket connections. | | `CELERY_WORKER_CLASS` | (empty; defaults to gevent) | Celery worker type with the same gevent patching requirements as `SERVER_WORKER_CLASS`. Strongly discouraged to change. | | `CELERY_WORKER_AMOUNT` | `4` | Number of Celery worker processes. Only used when autoscaling is disabled. Lower it on constrained VMs; for elastic throughput, enable `CELERY_AUTO_SCALE` instead of raising this. | | `CELERY_AUTO_SCALE` | `false` | Enable dynamic autoscaling. When enabled, Celery monitors queue depth and spawns/kills workers between `CELERY_MIN_WORKERS` and `CELERY_MAX_WORKERS`. | @@ -233,6 +235,7 @@ These control how Dify manages its pool of database connections. The defaults wo | `SQLALCHEMY_MAX_OVERFLOW` | `10` | Additional temporary connections allowed when the pool is full. With default settings, up to 40 connections (30 + 10) can exist simultaneously. | | `SQLALCHEMY_POOL_RECYCLE` | `3600` | Recycle connections after this many seconds to prevent stale connections. | | `SQLALCHEMY_POOL_TIMEOUT` | `30` | How long to wait for a connection when the pool is exhausted. Requests fail with a timeout error if no connection frees up in time. | +| `SQLALCHEMY_POOL_RESET_ON_RETURN` | `rollback` | Action SQLAlchemy takes when a connection returns to the pool. `rollback` clears any uncommitted transaction state before reuse; `commit` commits it instead. | | `SQLALCHEMY_POOL_PRE_PING` | `false` | Test each connection with a lightweight query before using it. Prevents "connection lost" errors but adds slight latency. Recommended for production with unreliable networks. | | `SQLALCHEMY_POOL_USE_LIFO` | `false` | Reuse the most recently returned connection (LIFO) instead of rotating evenly (FIFO). LIFO keeps fewer connections "warm" and can reduce overhead. | | `SQLALCHEMY_ECHO` | `false` | Print all SQL statements to logs. Useful for debugging query issues. | @@ -876,7 +879,7 @@ seekdb is the lite version of OceanBase and shares the same connection configura | `VIKINGDB_SECRET_KEY` | (empty) | Secret key. | | `VIKINGDB_REGION` | `cn-shanghai` | Region. | | `VIKINGDB_HOST` | `api-vikingdb.xxx.volces.com` | API host. Replace with your region-specific endpoint. | -| `VIKINGDB_SCHEMA` | `http` | Protocol scheme (`http` or `https`). | +| `VIKINGDB_SCHEME` | `http` | Protocol scheme (`http` or `https`). | | `VIKINGDB_CONNECTION_TIMEOUT` | `30` | Connection timeout in seconds. | | `VIKINGDB_SOCKET_TIMEOUT` | `30` | Socket timeout in seconds. | @@ -1011,8 +1014,6 @@ seekdb is the lite version of OceanBase and shares the same connection configura | Variable | Default | Description | |---|---|---| -| `PROMPT_GENERATION_MAX_TOKENS` | `512` | Maximum tokens when the system auto-generates a prompt using an LLM. Prevents runaway generations that waste API quota. | -| `CODE_GENERATION_MAX_TOKENS` | `1024` | Maximum tokens when the system auto-generates code using an LLM. | | `PLUGIN_BASED_TOKEN_COUNTING_ENABLED` | `false` | Use plugin-based token counting for accurate usage tracking. When disabled, token counting returns 0 (faster but cost tracking is less accurate). | ### Multi-modal Configuration @@ -1277,6 +1278,7 @@ The sandbox is an isolated service for executing code nodes (Python, JavaScript, | `NGINX_PROXY_READ_TIMEOUT` | `3600s` | Proxy read timeout. Set high (1 hour) to support long-running SSE streams. | | `NGINX_PROXY_SEND_TIMEOUT` | `3600s` | Proxy send timeout. | | `NGINX_ENABLE_CERTBOT_CHALLENGE` | `false` | Accept Let's Encrypt ACME challenge requests at `/.well-known/acme-challenge/`. Enable for automated certificate renewal. | +| `NGINX_SOCKET_IO_UPSTREAM` | `api_websocket:5001` | Upstream that Nginx forwards `/socket.io/` traffic to. Defaults to the dedicated `api_websocket` container started by the `collaboration` profile. Change only if you run the WebSocket service outside Docker Compose. | After enabling HTTPS, also update the URL variables in [Common Variables](#common-variables) (e.g., `CONSOLE_API_URL`, `CONSOLE_WEB_URL`) to use `https://`. @@ -1311,7 +1313,7 @@ These variables stay in `docker/.env` because Docker Compose uses them to select | Variable | Default | Description | |---|---|---| -| `COMPOSE_PROFILES` | `${VECTOR_STORE:-weaviate},${DB_TYPE:-postgresql}` | Automatically selects which service containers to start based on your database and vector store choices. For example, setting `DB_TYPE=mysql` starts MySQL instead of PostgreSQL. | +| `COMPOSE_PROFILES` | `${VECTOR_STORE:-weaviate},${DB_TYPE:-postgresql},collaboration` | Selects which service containers to start. The default includes the matching vector store and database (so `DB_TYPE=mysql` starts MySQL instead of PostgreSQL), plus the `collaboration` profile that starts the dedicated `api_websocket` container. Remove `collaboration` to skip the separate WebSocket service. | | `EXPOSE_NGINX_PORT` | `80` | Host port mapped to Nginx HTTP. | | `EXPOSE_NGINX_SSL_PORT` | `443` | Host port mapped to Nginx HTTPS. | @@ -1566,7 +1568,6 @@ The plugin daemon can store plugin packages in different storage backends. Confi | `PLUGIN_PYTHON_ENV_INIT_TIMEOUT` | `120` | Timeout in seconds for initializing Python environments for plugins. | | `PLUGIN_STDIO_BUFFER_SIZE` | `1024` | Buffer size in bytes for plugin stdio communication. | | `PLUGIN_STDIO_MAX_BUFFER_SIZE` | `5242880` | Maximum buffer size in bytes (5 MB) for plugin stdio communication. | -| `ENFORCE_LANGGENIUS_PLUGIN_SIGNATURES` | `true` | Enforce signature verification for LangGenius official plugins. | | `ENDPOINT_URL_TEMPLATE` | `http://localhost/e/{hook_id}` | URL template for plugin endpoints. `{hook_id}` is replaced with the actual hook ID. | | `EXPOSE_PLUGIN_DAEMON_PORT` | `5002` | Host port mapped to the plugin daemon. | | `EXPOSE_PLUGIN_DEBUGGING_HOST` | `localhost` | Host for plugin remote debugging. | diff --git a/en/use-dify/build/workflow-collaboration.mdx b/en/use-dify/build/workflow-collaboration.mdx index 10783d19f..8b6e4da9b 100644 --- a/en/use-dify/build/workflow-collaboration.mdx +++ b/en/use-dify/build/workflow-collaboration.mdx @@ -29,11 +29,10 @@ If you @mention a teammate in a comment, they'll receive an email notification. Anyone with access to the app can read comments; adding, editing, or resolving requires editor permissions or above. -On self-hosted deployments, collaboration is turned off by default. Enable it by setting: +For self-hosted deployments: -- `ENABLE_COLLABORATION_MODE` = `true` -- `SERVER_WORKER_CLASS` = `geventwebsocket.gunicorn.workers.GeventWebSocketWorker` -- `NEXT_PUBLIC_SOCKET_URL` = your deployment's WebSocket URL (e.g., `wss://dify.example.com`) +- If you access Dify on a host other than `localhost`, set `NEXT_PUBLIC_SOCKET_URL` to a WebSocket URL your browser can reach (e.g., `wss://dify.example.com`). +- To disable collaboration, set `ENABLE_COLLABORATION_MODE` to `false`. If using Docker Compose, also remove `collaboration` from `COMPOSE_PROFILES`. See [Environment Variables](/en/self-host/configuration/environments#enable_collaboration_mode) for details. diff --git a/en/use-dify/nodes/human-input.mdx b/en/use-dify/nodes/human-input.mdx index 4079f7bb9..4b4476f42 100644 --- a/en/use-dify/nodes/human-input.mdx +++ b/en/use-dify/nodes/human-input.mdx @@ -3,9 +3,7 @@ title: Human Input description: Pause workflows to request human input, review, or decisions --- -The Human Input node pauses workflows at key points to request human input before execution continues. - -When execution reaches this node, a customizable request form is delivered through specific channels. Recipients can provide input, review data, and choose from predefined decisions that determine how the workflow proceeds. +The Human Input node pauses workflows at key points to deliver a customizable request form. Recipients can use the form to review information, provide input, and choose from predefined decisions that determine how the workflow proceeds. By embedding human judgement directly where it matters, you can **balance automated efficiency with human oversight**. @@ -19,7 +17,7 @@ Configure the following to define how the node requests and processes human inpu - **Delivery method**: How the request form reaches recipients. -- **Form content**: What information recipients will see and what they can input. +- **Form content**: What information recipients will see and what they can interact with. - **User action**: What decisions recipients can make and how the workflow proceeds accordingly. @@ -29,13 +27,13 @@ Configure the following to define how the node requests and processes human inpu Choose the channel through which the request is delivered. Currently available methods: -- **Web app**: Displays the request form in the WebApp for the current user to respond. +- **Web app**: Displays the request form to the WebApp end user. Not available in workflows started by a Trigger. External clients can also retrieve and submit WebApp forms through the Service API. See [Get Human Input Form](/api-reference/human-input/get-human-input-form). -- **Email**: Sends an email containing the request link to one or more recipients. +- **Email**: Sends a request link via email to specific workspace members, external email addresses, or every member of the workspace. Anyone with the link can respond, no Dify account required. The request closes after the first response regardless of delivery method. @@ -43,7 +41,7 @@ Choose the channel through which the request is delivered. Currently available m ### Form Content -Customize what appears in the request form: +Customize the form recipients see and interact with: - **Format and structure with Markdown** @@ -54,7 +52,7 @@ Customize what appears in the request form: Reference workflow variables to show dynamic content, such as AI-generated text for review or any needed contextual information from upstream nodes. - If you reference the `text` output variable from a reasoning model, the form will display the model's thinking process along with the final answer by default. + Reasoning models emit their thinking process alongside the final answer. Referencing the `text` output variable shows both by default. To show only the answer, toggle on **Enable Reasoning Tag Separation** for the corresponding LLM node. @@ -63,14 +61,22 @@ Customize what appears in the request form: Input fields can start empty or pre-filled with variables (e.g., LLM output to refine) or static text (e.g., example or default values) that recipients can edit. - Each input field becomes a variable for downstream use. For instance, pass edited content for further processing or send feedback to an LLM for regeneration. + Each input field becomes a variable for downstream use. For instance, pass edited content for further processing or send feedback to an LLM for content revision. + +After the recipient responds, the form content with all values filled in is available downstream as the `__rendered_content` variable. ### User Action -Define the decision buttons that recipients can click. Each button routes the workflow to a different execution path. +Define the decision buttons that recipients can click, each routing the workflow to a different execution path. For example, a `Post` branch might lead to nodes that trigger content publishing, while a `Regenerate` branch might loop back to an LLM node to revise the content. +Each button has a display title and an action ID. When a button is clicked, its ID is exposed downstream as `__action_id` and its title (button text) as `__action_value`. + + + ![Action Button Configuration](/images/use-dify/workflow/human-input-action-button-config.png) + + Use preset button styles to visually distinguish actions. @@ -79,6 +85,8 @@ For example, a `Post` branch might lead to nodes that trigger content publishing ### Timeout Strategy -Configure how long to wait for a response before the request expires. +Configure how long the request stays open before it expires. The default is 3 days. + +If no recipient responds before the timeout, the workflow follows the timeout branch from the node. Wire this branch to a fallback path, such as a notification or a retry loop. -If no recipient responds within the set time, the workflow automatically ends unless you define a fallback branch to handle the timeout—for example, send a notification or retry the request. +If no timeout branch is connected, the workflow ends. diff --git a/en/use-dify/nodes/question-classifier.mdx b/en/use-dify/nodes/question-classifier.mdx index 7a9ab6d80..974e1493e 100644 --- a/en/use-dify/nodes/question-classifier.mdx +++ b/en/use-dify/nodes/question-classifier.mdx @@ -3,7 +3,7 @@ title: Question Classifier description: Intelligently categorize user input to route workflow paths --- -The Question Classifier node intelligently categorizes user input to route conversations down different workflow paths. Instead of building complex conditional logic, you define categories and let the LLM determine which one fits best based on semantic understanding. +The Question Classifier node intelligently categorizes user input to route conversations down different workflow paths. Instead of building complex conditional logic, you define classes and let the LLM determine which one fits best based on semantic understanding. ## Configuration @@ -11,17 +11,27 @@ The Question Classifier node intelligently categorizes user input to route conve **Input Variable** - Select what to classify, typically `sys.query` for user questions, but can be any text variable from previous workflow nodes. -**Model Selection** - Choose an LLM for classification. Faster models work well for simple categories, while more powerful models handle nuanced distinctions better. +**Model Selection** - Choose an LLM for classification. Faster models work well for simple classes, while more powerful models handle nuanced distinctions better. - + ![Question Classifier Configuration Interface](https://assets-docs.dify.ai/dify-enterprise-mintlify/en/guides/workflow/node/2f039c5ff3f095b0eed291101d9bff15.png) -### Category Definition +### Class Definition -Create clear, descriptive labels for each category with specific descriptions of what belongs in each. Be precise about boundaries between categories to help the LLM make accurate decisions. +Each class has two independent pieces of text: -Each category becomes a potential output path that you can connect to different downstream nodes like specialized knowledge bases, response templates, or processing workflows. +- **Class description** (the editor body) is what the LLM reads when choosing a branch. + + Write a precise, distinguishing description of what belongs in the class; boundary phrases like "anything related to..." or "excluding..." help when classes overlap. Exposed downstream as `class_name`. + +- **Class title** (the small heading above the editor) is the label shown on the canvas. + + Double-click the default **CLASS N** title to rename it. Exposed downstream as `class_label`. + +The title and the description edit independently, so you can keep a short, scannable label on the canvas while giving the LLM a longer, more specific description. + +Each class becomes a potential output path that you can connect to different downstream nodes like specialized knowledge bases, response templates, or processing workflows. ## Classification Example @@ -31,10 +41,10 @@ Here's how the Question Classifier works in a customer service scenario: ![Customer Service Classification Workflow](https://assets-docs.dify.ai/dify-enterprise-mintlify/en/guides/workflow/node/2f06ecce149c844c23be70a8fcff09bc.png) -**Categories Defined**: +**Classes Defined**: - **After-sales service** - Warranty claims, returns, repairs, and post-purchase support - **Product usage** - Setup instructions, troubleshooting, feature explanations -- **Other questions** - General inquiries not covered by specific categories +- **Other questions** - General inquiries not covered by specific classes **Classification Results**: - "How to set up contacts on iPhone 14?" → **Product usage** @@ -47,4 +57,4 @@ Each classification result routes to different knowledge bases and response stra ### Instructions and Guidelines -Add detailed classification guidelines in the **Instructions** field to handle edge cases, ambiguous scenarios, or specific business rules. This helps the LLM understand nuanced distinctions between categories. +Add detailed classification guidelines in the **Instructions** field to handle edge cases, ambiguous scenarios, or specific business rules. This helps the LLM understand nuanced distinctions between classes. diff --git a/en/use-dify/workspace/subscription-management.mdx b/en/use-dify/workspace/subscription-management.mdx index 9a0085e4d..0bef22a5f 100644 --- a/en/use-dify/workspace/subscription-management.mdx +++ b/en/use-dify/workspace/subscription-management.mdx @@ -64,12 +64,16 @@ Students, teachers, and educational staff can verify their educational affiliati Go to **Settings** > **Billing** > **Get Education Verified**, then enter your school's full name and select your role. The result appears immediately. - - After approval, upgrade to the **Yearly** Professional Plan. The education discount applies automatically at checkout. + + 1. After approval, select the workspace you want to use the education discount with, then click **Use education discount**. + + You'll be redirected to checkout with the Yearly Professional Plan and discount pre-applied. - - The education discount applies only to **yearly** billing. Before paying, make sure the checkout total shows **\$0**. - + + The education discount only applies to the Yearly Professional plan. + + + 2. Complete payment to activate the subscription. @@ -79,12 +83,12 @@ Students, teachers, and educational staff can verify their educational affiliati You likely selected the Monthly Professional plan. The education discount applies only to the Yearly plan, so the Monthly plan charges the full \$59. - To resolve this, cancel the current subscription, wait for the billing cycle to end, then subscribe to the **Yearly** Professional plan with the education discount. + To resolve this, cancel the current subscription, wait for the billing cycle to end, then subscribe to the *Yearly* Professional plan with the education discount. The education discount cannot be applied to an existing paid plan. - To resolve this, cancel your current subscription, wait for the billing cycle to end, then subscribe to the **Yearly** Professional plan with the education discount. + To resolve this, cancel your current subscription, wait for the billing cycle to end, then subscribe to the *Yearly* Professional plan with the education discount. Common reasons: non-educational email, inaccurate information, or misuse of privileges. Appeal via [support@dify.ai](mailto:support@dify.ai). diff --git a/images/use-dify/workflow/human-input-action-button-config.png b/images/use-dify/workflow/human-input-action-button-config.png new file mode 100644 index 0000000000000000000000000000000000000000..89f53cdc75752c5a64a67322710894da3c930e3d GIT binary patch literal 22040 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、`<`、`≥`、`≤`)は数値メタデータに作用します。時刻演算子(`before`、`after`)は時刻メタデータに作用します。", + "enum": [ + "contains", + "not contains", + "start with", + "end with", + "is", + "is not", + "empty", + "not empty", + "in", + "not in", + "=", + "≠", + ">", + "<", + "≥", + "≤", + "before", + "after" + ] + }, + "value": { + "nullable": true, + "description": "比較対象の値です。型は `comparison_operator` によって異なります。ほとんどの文字列演算子では文字列、`in` および `not in` では文字列配列、数値演算子では数値、`empty` および `not empty` では省略します。", + "oneOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "number" + } + ] + } + } + } + } + } } } } diff --git a/ja/api-reference/openapi_workflow.json b/ja/api-reference/openapi_workflow.json index a0663f983..65ce4712e 100644 --- a/ja/api-reference/openapi_workflow.json +++ b/ja/api-reference/openapi_workflow.json @@ -3162,7 +3162,7 @@ }, "status": { "type": "string", - "description": "ワークフローの実行ステータスです。`running` は実行中、`succeeded` は正常完了、`failed` は実行エラー、`stopped` は手動停止、`partial-succeeded` は一部のノードが成功し他が失敗、`paused` は人的介入待ちを示します。" + "description": "ワークフローの実行ステータスです。`running` は実行中、`succeeded` は正常完了、`failed` は実行エラー、`stopped` は手動停止、`partial-succeeded` は一部のノードが成功し他が失敗、`paused` は人間の入力待ちを示します。" }, "outputs": { "type": "object", @@ -3235,7 +3235,7 @@ }, "status": { "type": "string", - "description": "ワークフローの実行ステータスです。`running` は実行中、`succeeded` は正常完了、`failed` は実行エラー、`stopped` は手動停止、`partial-succeeded` は一部のノードが成功し他が失敗、`paused` は人的介入待ちを示します。" + "description": "ワークフローの実行ステータスです。`running` は実行中、`succeeded` は正常完了、`failed` は実行エラー、`stopped` は手動停止、`partial-succeeded` は一部のノードが成功し他が失敗、`paused` は人間の入力待ちを示します。" }, "inputs": { "type": "object", @@ -3507,7 +3507,7 @@ }, "status": { "type": "string", - "description": "ワークフローの実行ステータスです。`running` は実行中、`succeeded` は正常完了、`failed` は実行エラー、`stopped` は手動停止、`partial-succeeded` は一部のノードが成功し他が失敗、`paused` は人的介入待ちを示します。" + "description": "ワークフローの実行ステータスです。`running` は実行中、`succeeded` は正常完了、`failed` は実行エラー、`stopped` は手動停止、`partial-succeeded` は一部のノードが成功し他が失敗、`paused` は人間の入力待ちを示します。" }, "error": { "type": "string", diff --git a/ja/self-host/configuration/environments.mdx b/ja/self-host/configuration/environments.mdx index 3d0f1a61c..30935c51e 100644 --- a/ja/self-host/configuration/environments.mdx +++ b/ja/self-host/configuration/environments.mdx @@ -106,14 +106,13 @@ Docker ネットワーク内のサービス間通信で使用されるファイ ### ENABLE_COLLABORATION_MODE -デフォルト値:`false` +デフォルト値:`true` -ワークフローキャンバスのリアルタイム共同編集(同時編集、キャンバス上のコメント、@メンション)を制御するマスタースイッチです。 +ワークフローキャンバスのリアルタイム共同編集(同時編集、キャンバス上のコメント、@メンション)を有効化します。 -この変数を設定するだけでは不十分です。共同編集は WebSocket 経由で動作するため、以下も必要です: +`localhost` 以外のホストから Dify にアクセスする場合、`NEXT_PUBLIC_SOCKET_URL` をブラウザから到達できる WebSocket URL に設定してください([CORS 設定](#cors-設定) を参照)。デフォルトの `ws://localhost` はローカル専用環境でのみ動作します。 -- `SERVER_WORKER_CLASS` を `geventwebsocket.gunicorn.workers.GeventWebSocketWorker` に設定します([コンテナ起動設定](#コンテナ起動設定) を参照)。 -- `NEXT_PUBLIC_SOCKET_URL` をブラウザからアクセス可能な WebSocket URL に設定します([CORS 設定](#cors-設定) を参照)。 +共同編集機能を無効化するには、この値を `false` に設定します。Docker Compose を使用している場合は、`COMPOSE_PROFILES` から `collaboration` も削除してください。削除しないと、専用の `api_websocket` コンテナはトラフィックを受け取らないまま起動し続けます。 独自のリバースプロキシを使用する場合は `/socket.io/` パスで `Upgrade` および `Connection` ヘッダーを転送してください(同梱の nginx テンプレートにはこの設定が含まれています)。API を複数レプリカで運用する場合はスティッキーセッションが必要です。 @@ -191,9 +190,12 @@ Docker イメージまたは Docker Compose で起動する場合にのみ有効 | `DIFY_BIND_ADDRESS` | `0.0.0.0` | API サーバーがバインドするネットワークインターフェース。`0.0.0.0`はすべてのインターフェースでリッスンします。`127.0.0.1` に設定するとローカルホストのみに制限されます。 | | `DIFY_PORT` | `5001` | API サーバーのリッスンポート。 | | `SERVER_WORKER_AMOUNT` | `1` | Gunicorn ワーカープロセス数。gevent(デフォルト)使用時は各ワーカーが greenlet で複数の同時接続を処理するため、通常 1 で十分です。同期ワーカーの場合は `(2 x CPUコア数) + 1`を使用してください。[参考ドキュメント](https://gunicorn.org/design/#how-many-workers)。 | -| `SERVER_WORKER_CLASS` | `gevent` | Gunicorn ワーカータイプ。`gevent` は軽量な非同期並行処理を提供します。`ENABLE_COLLABORATION_MODE` が `true` の場合、`geventwebsocket.gunicorn.workers.GeventWebSocketWorker` に設定します。`gevent` のままだと WebSocket ハンドシェイクがサイレントに失敗します。他の値は psycopg2 と gRPC のパッチを壊します。 | +| `SERVER_WORKER_CLASS` | `gevent` | Gunicorn ワーカータイプ。デフォルト値のままにしてください。他の値は psycopg2 と gRPC のパッチを壊します。 | | `SERVER_WORKER_CONNECTIONS` | `10` | ワーカーごとの最大同時接続数。非同期ワーカー(gevent)にのみ適用されます。高負荷時に接続拒否やレスポンス遅延が発生する場合は、この値を増加してください。 | | `GUNICORN_TIMEOUT` | `360` | ワーカーがこの秒数以内に応答しない場合、Gunicorn はそのワーカーを終了して再起動します。ストリーミング LLM レスポンスに使用される長時間 SSE 接続をサポートするため、360(6 分)に設定されています。 | +| `API_WEBSOCKET_WORKER_CLASS` | `geventwebsocket.gunicorn.workers.GeventWebSocketWorker` | Docker Compose のみ。専用の `api_websocket` コンテナのワーカークラスです。デフォルト値のままにしてください。他の値は WebSocket サポートを壊します。 | +| `API_WEBSOCKET_WORKER_CONNECTIONS` | `1000` | Docker Compose のみ。`api_websocket` コンテナが同時に受け付ける WebSocket 接続の最大数です。開いているワークフローエディタタブごとに 1 接続を使用するため、デフォルトでは最大 1000 の同時編集セッションを処理できます。それ以上が見込まれる場合は値を増やしてください。 | +| `API_WEBSOCKET_GUNICORN_TIMEOUT` | `360` | Docker Compose のみ。`api_websocket` ワーカーがこの秒数内に応答しない場合、Gunicorn が再起動します。デフォルトの 360 秒(6 分)は長時間保持される WebSocket 接続に適しています。 | | `CELERY_WORKER_CLASS` | (空;デフォルトは gevent) | Celery ワーカータイプ。`SERVER_WORKER_CLASS` と同じ gevent パッチ要件があります。変更は強く非推奨です。 | | `CELERY_WORKER_AMOUNT` | `4` | Celery ワーカープロセス数。オートスケーリング無効時のみ使用されます。リソースの限られた VM では下げてください。スループットを柔軟に調整したい場合は、この値を上げるより `CELERY_AUTO_SCALE` を有効化するほうが適切です。 | | `CELERY_AUTO_SCALE` | `false` | 動的オートスケーリングを有効化。有効時、Celery はキュー深度を監視し、`CELERY_MIN_WORKERS`から `CELERY_MAX_WORKERS` の間でワーカーを動的に生成/終了します。 | @@ -233,6 +235,7 @@ Dify がデータベースコネクションプールを管理する方法を制 | `SQLALCHEMY_MAX_OVERFLOW` | `10` | プールが満杯の場合に許可される追加の一時接続数。デフォルト設定では、最大 40 接続(30 + 10)が同時に存在できます。 | | `SQLALCHEMY_POOL_RECYCLE` | `3600` | この秒数の後に接続をリサイクルし、古い接続を防止します。 | | `SQLALCHEMY_POOL_TIMEOUT` | `30` | プールが枯渇した場合の接続待機時間。この時間内に接続が解放されない場合、リクエストはタイムアウトエラーで失敗します。 | +| `SQLALCHEMY_POOL_RESET_ON_RETURN` | `rollback` | 接続がプールに返却された際の SQLAlchemy の動作です。`rollback` は再利用前に未コミットのトランザクション状態をクリアし、`commit` はコミットします。 | | `SQLALCHEMY_POOL_PRE_PING` | `false` | 使用前に軽量クエリで接続をテストします。「接続切断」エラーを防止しますが、わずかなレイテンシーが追加されます。不安定なネットワークの本番環境で推奨されます。 | | `SQLALCHEMY_POOL_USE_LIFO` | `false` | 均等ローテーション(FIFO)の代わりに、最後に返却された接続を再利用します(LIFO)。LIFO はより少ない接続を「ウォーム」状態に保ち、オーバーヘッドを削減できます。 | | `SQLALCHEMY_ECHO` | `false` | すべての SQL 文をログに出力します。クエリ問題のデバッグに有用です。 | @@ -876,7 +879,7 @@ seekdb は OceanBase のライト版であり、同じ接続設定を共有し | `VIKINGDB_SECRET_KEY` | (空) | Secret key。 | | `VIKINGDB_REGION` | `cn-shanghai` | リージョン。 | | `VIKINGDB_HOST` | `api-vikingdb.xxx.volces.com` | API ホスト。リージョン固有のエンドポイントに置き換えてください。 | -| `VIKINGDB_SCHEMA` | `http` | プロトコルスキーム(`http`または `https`)。 | +| `VIKINGDB_SCHEME` | `http` | プロトコルスキーム(`http`または `https`)。 | | `VIKINGDB_CONNECTION_TIMEOUT` | `30` | 接続タイムアウト(秒)。 | | `VIKINGDB_SOCKET_TIMEOUT` | `30` | Socket タイムアウト(秒)。 | @@ -1011,8 +1014,6 @@ seekdb は OceanBase のライト版であり、同じ接続設定を共有し | 変数 | デフォルト値 | 説明 | |---|---|---| -| `PROMPT_GENERATION_MAX_TOKENS` | `512` | システムが LLM を使用してプロンプトを自動生成する際の最大トークン数。API クォータを無駄にする暴走生成を防止します。 | -| `CODE_GENERATION_MAX_TOKENS` | `1024` | システムが LLM を使用してコードを自動生成する際の最大トークン数。 | | `PLUGIN_BASED_TOKEN_COUNTING_ENABLED` | `false` | 正確な使用量追跡のためにプラグインベースのトークンカウントを使用。無効の場合、トークンカウントは 0 を返します(高速ですがコスト追跡の精度が低下します)。 | ### マルチモーダル設定 @@ -1277,6 +1278,7 @@ Docker Compose でデータベースコンテナを直接設定します。 | `NGINX_PROXY_READ_TIMEOUT` | `3600s` | プロキシ読み取りタイムアウト。長時間の SSE ストリームをサポートするため高く設定(1 時間)されています。 | | `NGINX_PROXY_SEND_TIMEOUT` | `3600s` | プロキシ送信タイムアウト。 | | `NGINX_ENABLE_CERTBOT_CHALLENGE` | `false` | `/.well-known/acme-challenge/` で Let's Encrypt ACME チャレンジリクエストを受け入れます。自動証明書更新のために有効化してください。 | +| `NGINX_SOCKET_IO_UPSTREAM` | `api_websocket:5001` | Nginx が `/socket.io/` トラフィックを転送する上流(upstream)です。デフォルトでは `collaboration` プロファイルで起動する専用の `api_websocket` コンテナを指します。Docker Compose の外で WebSocket サービスを実行する場合のみ変更してください。 | HTTPS を有効化した後、 [共通変数](#共通変数) の URL 変数(例:`CONSOLE_API_URL`、`CONSOLE_WEB_URL`)も `https://` を使用するように更新してください。 @@ -1309,7 +1311,7 @@ HTTPS を有効化した後、 [共通変数](#共通変数) の URL 変数( | 変数 | デフォルト値 | 説明 | |---|---|---| -| `COMPOSE_PROFILES` | `${VECTOR_STORE:-weaviate},${DB_TYPE:-postgresql}` | データベースとベクトルストアの選択に基づいて、起動するサービスコンテナを自動選択します。例えば、`DB_TYPE=mysql` を設定すると PostgreSQL の代わりに MySQL が起動します。 | +| `COMPOSE_PROFILES` | `${VECTOR_STORE:-weaviate},${DB_TYPE:-postgresql},collaboration` | 起動するサービスコンテナを選択します。デフォルトでは、対応するベクトルストアとデータベース(`DB_TYPE=mysql` を設定すれば PostgreSQL の代わりに MySQL が起動)、および専用の `api_websocket` コンテナを起動する `collaboration` プロファイルが含まれます。`collaboration` を削除すると、独立した WebSocket サービスを起動しません。 | | `EXPOSE_NGINX_PORT` | `80` | Nginx HTTP にマッピングされるホストポート。 | | `EXPOSE_NGINX_SSL_PORT` | `443` | Nginx HTTPS にマッピングされるホストポート。 | @@ -1564,7 +1566,6 @@ API と Celery ワーカー間の Redis ベースのイベント転送です。 | `PLUGIN_PYTHON_ENV_INIT_TIMEOUT` | `120` | プラグインの Python 環境初期化のタイムアウト(秒)。 | | `PLUGIN_STDIO_BUFFER_SIZE` | `1024` | プラグイン stdio 通信のバッファサイズ(バイト)。 | | `PLUGIN_STDIO_MAX_BUFFER_SIZE` | `5242880` | プラグイン stdio 通信の最大バッファサイズ(バイト、5 MB)。 | -| `ENFORCE_LANGGENIUS_PLUGIN_SIGNATURES` | `true` | LangGenius 公式プラグインの署名検証を強制。 | | `ENDPOINT_URL_TEMPLATE` | `http://localhost/e/{hook_id}` | プラグインエンドポイントの URL テンプレート。`{hook_id}` は実際のフック ID に置き換えられます。 | | `EXPOSE_PLUGIN_DAEMON_PORT` | `5002` | プラグインデーモンにマッピングされるホストポート。 | | `EXPOSE_PLUGIN_DEBUGGING_HOST` | `localhost` | プラグインリモートデバッグのホスト。 | diff --git a/ja/use-dify/build/workflow-collaboration.mdx b/ja/use-dify/build/workflow-collaboration.mdx index 430892cbf..f2edcc32b 100644 --- a/ja/use-dify/build/workflow-collaboration.mdx +++ b/ja/use-dify/build/workflow-collaboration.mdx @@ -31,11 +31,10 @@ sidebarTitle: コラボレーション アプリにアクセスできるメンバーは誰でもコメントを閲覧できます。コメントの追加、編集、解決には編集権限以上が必要です。 -セルフホスト環境では、共同編集機能はデフォルトで無効です。以下の環境変数を設定して有効化します: +セルフホスト環境では: -- `ENABLE_COLLABORATION_MODE` = `true` -- `SERVER_WORKER_CLASS` = `geventwebsocket.gunicorn.workers.GeventWebSocketWorker` -- `NEXT_PUBLIC_SOCKET_URL` = あなたのデプロイの WebSocket URL(例:`wss://dify.example.com`) +- `localhost` 以外のホストから Dify にアクセスする場合、`NEXT_PUBLIC_SOCKET_URL` をブラウザから到達できる WebSocket URL(例:`wss://dify.example.com`)に設定します。 +- 共同編集機能を無効化するには、`ENABLE_COLLABORATION_MODE` を `false` に設定します。Docker Compose を使用している場合は、`COMPOSE_PROFILES` から `collaboration` も削除します。 -詳細とデフォルト値は [環境変数](/ja/self-host/configuration/environments#enable_collaboration_mode) を参照してください。 +詳細は [環境変数](/ja/self-host/configuration/environments#enable_collaboration_mode) を参照してください。 diff --git a/ja/use-dify/nodes/human-input.mdx b/ja/use-dify/nodes/human-input.mdx index 8ffa79781..ccc125704 100644 --- a/ja/use-dify/nodes/human-input.mdx +++ b/ja/use-dify/nodes/human-input.mdx @@ -1,13 +1,11 @@ --- -title: 人的介入 +title: 人間の入力 description: ワークフローを一時停止して、人間の入力、レビュー、または意思決定を要求します --- ⚠️ このドキュメントは AI によって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/use-dify/nodes/human-input) を参照してください。 -**人的介入ノード** は、ワークフローを主要なポイントで一時停止し、実行を継続する前に人間による入力を要求します。 - -実行がこのノードに到達すると、カスタマイズ可能なリクエストフォームが特定のチャネルを通じて配信されます。受信者は、入力の提供、データの確認、およびワークフローの進行方法を決定する事前に定義された選択肢からの選択を行うことができます。 +人間の入力ノードは、ワークフローを重要なポイントで一時停止し、カスタマイズ可能なリクエストフォームを配信します。受信者はフォームを使って情報を確認し、入力を提供し、ワークフローの進行方法を決定する事前定義された選択肢から選ぶことができます。 重要な場面に人間の判断を直接組み込むことで、 **自動化による効率性と人間による監視のバランス** をとることができます。 @@ -21,7 +19,7 @@ description: ワークフローを一時停止して、人間の入力、レビ - **配信方法**: リクエストフォームがどのように受信者に届くか。 -- **フォーム内容**: 受信者に表示される情報と、受信者が入力できる内容。 +- **フォーム内容**: 受信者に表示される情報と、操作できる内容。 - **ユーザーアクション**: 受信者が行える決定と、それに応じたワークフローの進行方法。 @@ -31,13 +29,13 @@ description: ワークフローを一時停止して、人間の入力、レビ リクエストを配信するチャネルを選択します。現在利用可能な方法は以下の通りです: -- **WebApp** :現在のユーザーが応答できるように、WebApp にリクエストフォームを表示します。 +- **WebApp** :WebApp のエンドユーザーにリクエストフォームを表示します。トリガーで開始されたワークフローでは利用できません。 外部クライアントは Service API 経由で WebApp のフォームを取得・送信することもできます。詳細は [人間の入力フォームを取得](/api-reference/人間の入力/人間の入力フォームを取得) を参照してください。 -- **メール** :リクエストリンクを含むメールを 1 人または複数の受信者に送信します。 +- **メール** :特定のワークスペースメンバー、外部のメールアドレス、またはワークスペース全員にリクエストリンクをメールで送信します。リンクを持っている人は誰でも応答でき、Dify アカウントは不要です。 配信方法に関わらず、最初の応答があった時点でリクエストはクローズされます。 @@ -45,7 +43,7 @@ description: ワークフローを一時停止して、人間の入力、レビ ### フォーム内容 -リクエストフォームに表示される内容をカスタマイズします: +受信者が見て操作するフォームをカスタマイズします: - **Markdown によるフォーマットと構造化** @@ -53,26 +51,34 @@ description: ワークフローを一時停止して、人間の入力、レビ - **変数による動的データの表示** - ワークフロー変数を参照して、レビュー用の AI 生成テキストや上流ノードからの必要なコンテキスト情報などの動的コンテンツを表示します。 + ワークフロー変数を参照して、レビュー用の AI 生成テキストや上流ノードの必要なコンテキスト情報などの動的コンテンツを表示します。 - 推論モデルからの `text` 出力変数を参照する場合、フォームには最終的な回答とともにモデルの思考プロセスが表示されます。 + 推論モデルは最終回答とともに思考プロセスも出力します。`text` 出力変数を参照するとデフォルトで両方が表示されます。 - 回答のみを表示したい場合は、対応する LLM ノードの設定を調整します。 **推論タグの分離を有効にする** (Enable Reasoning Tag Separation)をオンにしてください。 + 回答のみを表示するには、対応する LLM ノードで **推論タグの分離を有効にする** (Enable Reasoning Tag Separation)をオンにします。 - **入力フィールドによる入力の収集** - 入力フィールドは、空の状態から始められます。あるいは受信者が編集できるように、変数(例:修正する LLM の出力)や静的テキスト(例:サンプルやデフォルト値)を事前に入れておくことも可能です。 + 入力フィールドは、空の状態から始めることも、変数(例:修正する LLM の出力)や静的テキスト(例:サンプルやデフォルト値)を事前に入れておくこともでき、受信者が編集できます。 + + 各入力フィールドは下流で使用するための変数となります。例えば、編集されたコンテンツをさらなる処理に渡したり、コンテンツ修正のためのフィードバックを LLM に送信したりできます。 - 各入力フィールドは、下流で使用するための変数となります。例えば、編集されたコンテンツをさらなる処理のために渡したり、再生成のために LLM にフィードバックを送信したりできます。 +受信者が応答すると、すべての値が入力されたフォーム内容は下流変数 `__rendered_content` として利用できます。 ### ユーザーアクション -受信者がクリックできる決定ボタンを定義します。各ボタンは、ワークフローを異なる実行パスにルーティングします。 +受信者がクリックできる決定ボタンを定義します。各ボタンはワークフローを異なる実行パスにルーティングします。 例えば、`投稿` ブランチはコンテンツの公開をトリガーするノードにつながります。`再生成` ブランチはコンテンツを修正するために LLM ノードにループバックするような構成が可能です。 +各ボタンには表示タイトルとアクション ID があります。ボタンがクリックされると、その ID は下流変数 `__action_id`、タイトル(ボタンテキスト)は `__action_value` として利用できます。 + + + ![アクションボタン設定](/images/use-dify/workflow/human-input-action-button-config.png) + + プリセットのボタンスタイルを使用して、アクションを視覚的に区別します。 @@ -81,6 +87,8 @@ description: ワークフローを一時停止して、人間の入力、レビ ### タイムアウト戦略 -リクエストが期限切れになるまで応答を待機する時間を設定します。 +リクエストが期限切れになるまでの時間を設定します。デフォルトは 3 日です。 + +タイムアウトまでに受信者が応答しなかった場合、ワークフローはノードのタイムアウトブランチに進みます。このブランチをフォールバックパス(通知の送信やリトライループなど)に接続してください。 -設定時間内に受信者が応答しなかった場合、ワークフローは自動的に終了します。タイムアウトを処理するためのフォールバックブランチ(例:通知の送信やリクエストの再試行)を定義すれば、この終了を回避できます。 +タイムアウトブランチが接続されていない場合、ワークフローは終了します。 diff --git a/ja/use-dify/nodes/question-classifier.mdx b/ja/use-dify/nodes/question-classifier.mdx index c593990ba..57bdb5df0 100644 --- a/ja/use-dify/nodes/question-classifier.mdx +++ b/ja/use-dify/nodes/question-classifier.mdx @@ -1,83 +1,64 @@ --- -title: "質問分類器" -description: "ワークフローパスをルーティングするためにユーザー入力をインテリジェントに分類" +title: 質問分類器 +description: ワークフローパスをルーティングするためにユーザー入力をインテリジェントに分類 --- ⚠️ このドキュメントは AI によって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/use-dify/nodes/question-classifier) を参照してください。 - -質問分類器ノードは、ユーザー入力をインテリジェントに分類して、会話を異なるワークフローパスにルーティングします。複雑な条件ロジックを構築する代わりに、カテゴリを定義し、大規模言語モデルにセマンティック理解に基づいて最適なものを決定させます。 +質問分類器ノードは、ユーザー入力をインテリジェントに分類して、会話を異なるワークフローパスにルーティングします。複雑な条件ロジックを構築する代わりに、クラスを定義すると、大規模言語モデルがセマンティック理解に基づいて最適なものを判断します。 ## 設定 -### 入力とモデルセットアップ +### 入力とモデルの設定 -**入力変数** - 分類する内容を選択します。通常はユーザーの質問に対して`sys.query`を使用しますが、前のワークフローノードからの任意のテキスト変数も使用できます。 +**入力変数** - 分類する内容を選択します。通常はユーザーの質問に対して `sys.query` を使用しますが、上流のワークフローノードからの任意のテキスト変数も使用できます。 -**モデル選択** - 分類用の大規模言語モデルを選択します。高速なモデルは単純なカテゴリには適していますが、より強力なモデルは微妙な区別をより適切に処理できます。 +**モデル選択** - 分類用の大規模言語モデルを選択します。単純なクラスには高速なモデルで十分ですが、微妙な区別にはより高性能なモデルが適しています。 - - ![Question Classifier configuration interface](https://assets-docs.dify.ai/dify-enterprise-mintlify/en/guides/workflow/node/2f039c5ff3f095b0eed291101d9bff15.png) + + ![質問分類器の設定画面](https://assets-docs.dify.ai/dify-enterprise-mintlify/en/guides/workflow/node/2f039c5ff3f095b0eed291101d9bff15.png) -### カテゴリ定義 - -各カテゴリに属するものについての具体的な説明を含む、明確で説明的なラベルを作成します。大規模言語モデルが正確な決定を下せるよう、カテゴリ間の境界について正確に記述してください。 +### クラスの定義 -各カテゴリは潜在的な出力パスとなり、専門的な知識ベース、レスポンステンプレート、または処理ワークフローなど、異なる下流ノードに接続できます。 +各クラスには独立した 2 つのテキストがあります: -## 分類例 +- **クラス説明**(エディタ本文)は、モデルが分岐を選ぶ際に参照する内容です。 -以下は、カスタマーサービスシナリオでの質問分類器の動作例です: + クラスに属する内容を正確に区別できる説明を記述します。クラスが重なる場合は、「〜に関するもの」「〜を除く」などの境界フレーズが判断の助けになります。下流では `class_name` として出力されます。 - - ![Customer service classification workflow](https://assets-docs.dify.ai/dify-enterprise-mintlify/en/guides/workflow/node/2f06ecce149c844c23be70a8fcff09bc.png) - +- **クラスタイトル**(エディタ上部の小見出し)は、キャンバスに表示されるラベルです。 -**定義されたカテゴリ**: -- **アフターサービス** - 保証請求、返品、修理、購入後サポート -- **製品使用** - セットアップ手順、トラブルシューティング、機能説明 -- **その他の質問** - 特定のカテゴリでカバーされない一般的な問い合わせ + デフォルトの **クラス N** タイトルをダブルクリックして名前を変更できます。下流では `class_label` として出力されます。 -**分類結果**: -- "iPhone 14で連絡先を設定する方法は?" → **製品使用** -- "私の購入品の保証期間は何ですか?" → **アフターサービス** -- "今日の天気はどうですか?" → **その他の質問** - -各分類結果は異なる知識ベースと対応戦略にルーティングされ、ユーザーが関連性のある専門的な支援を受けられるようにします。 - -## 高度な設定 - -### 指示とガイドライン +タイトルと説明は独立して編集できるため、キャンバス上では短く読みやすいラベルを保ちつつ、モデルにはより詳細で具体的な説明を渡せます。 -**指示**フィールドに詳細な分類ガイドラインを追加して、エッジケース、曖昧なシナリオ、または特定のビジネスルールを処理します。これにより、大規模言語モデルがカテゴリ間の微妙な区別を理解できるようになります。 +各クラスは潜在的な出力パスとなり、専門的なナレッジベース、レスポンステンプレート、処理ワークフローなど、異なる下流ノードに接続できます。 -### メモリ統合 - -入力を分類する際に会話履歴を含めるために**メモリ**を有効にします。これにより、現在の入力が以前のコンテキストに依存する複数ターンの会話での精度が向上します。 - -**メモリウィンドウ**は、含める会話履歴の量を制御しト認識とトークン効率および処理速度のバランスを取ります。 - -## 出力使用 - -分類器は、一致したカテゴリラベルを含む`class_name`変数を出力します。この変数を下流ノードで以下の用途に使用します: +## 分類例 -**条件分岐ルーティング** - 分類結果に基づいて異なるワークフローパスに接続 +以下は、カスタマーサービスシナリオでの質問分類器の使用例です: -**知識ベース選択** - 各カテゴリ専用の知識ベースにルーティング + + ![カスタマーサービス分類ワークフロー](https://assets-docs.dify.ai/dify-enterprise-mintlify/en/guides/workflow/node/2f06ecce149c844c23be70a8fcff09bc.png) + -**レスポンスカスタマイゼーション** - 異なるレスポンステンプレートや処理ロジックを適用 +**定義されたクラス**: -**分析とログ記録** - カテゴリ全体でのユーザー問い合わせの分布を追跡 +- **アフターサービス** - 保証請求、返品、修理、購入後サポート +- **製品使用** - セットアップ手順、トラブルシューティング、機能説明 +- **その他の質問** - 上記のクラスに該当しない一般的な問い合わせ -## ベストプラクティス +**分類結果**: -**明確なカテゴリ境界** - 分類精度を向上させるために、特定の説明を持つ明確で重複しないカテゴリを定義します。 +- 「iPhone 14 で連絡先を設定する方法は?」 → **製品使用** +- 「購入品の保証期間はどのくらいですか?」 → **アフターサービス** +- 「今日の天気はどうですか?」 → **その他の質問** -**適切なモデル選択** - 分類の複雑さに基づいてモデルを選択します。単純な二項分類では高速なモデルで十分ですが、微妙な多カテゴリ分類にはより能力の高いモデルが必要な場合があります。 +各分類結果は異なるナレッジベースとレスポンス戦略にルーティングされ、ユーザーが関連性のある専門的なサポートを受けられるようにします。 -**エッジケースのテスト** - 複数のカテゴリに適合する可能性のある曖昧な入力での分類動作を検証します。 +## 高度な設定 -**会話コンテキストの使用** - 分類が以前のやり取りに依存する会話型アプリケーションではメモリを有効にします。 +### 指示とガイドライン -**監視と反復** - 分類結果をレビューし、実際の使用パターンに基づいてカテゴリ説明を改善します。 +**指示** フィールドに詳細な分類ガイドラインを追加して、エッジケース、曖昧なシナリオ、または特定のビジネスルールに対応します。これにより、大規模言語モデルがクラス間の微妙な区別を理解できるようになります。 diff --git a/ja/use-dify/workspace/subscription-management.mdx b/ja/use-dify/workspace/subscription-management.mdx index b4eea29e9..641a362a4 100644 --- a/ja/use-dify/workspace/subscription-management.mdx +++ b/ja/use-dify/workspace/subscription-management.mdx @@ -66,12 +66,16 @@ Dify の請求はワークスペース単位で管理されます。サブスク **設定** > **請求** > **教育認証を取得** に移動し、学校の正式名称を入力して役割を選択します。結果はすぐに表示されます。 - - 承認後、**年額** Professional プランにアップグレードします。チェックアウト時に教育割引が自動的に適用されます。 + + 1. 承認後、教育割引を適用するワークスペースを選択し、**教育割引を使用** をクリックします。 + + チェックアウト画面に遷移し、年額 Professional プランと教育割引が事前に適用されます。 - - 教育割引は **年額** 請求のみに適用されます。支払う前に、チェックアウトの合計が **\$0** と表示されていることを確認してください。 - + + 教育割引は年額 Professional プランのみに適用されます。 + + + 2. 支払いを完了するとサブスクリプションが有効になります。 diff --git a/tools/translate/formatting-zh.md b/tools/translate/formatting-zh.md index 7bb87324e..ab195259e 100644 --- a/tools/translate/formatting-zh.md +++ b/tools/translate/formatting-zh.md @@ -191,15 +191,12 @@ These constructions immediately mark output as machine-translated. Eliminate the |:---------------|:-----------------------|:----------------| | If your team maintains its own RAG system, you can connect... | 如果你的团队维护着自己的 RAG 系统,你可以将... | 团队自建 RAG 系统时,可将... | | This lets your AI applications retrieve information directly | 这让你的 AI 应用能够直接检索信息 | AI 应用即可直接检索信息 | -| When your application runs, Dify sends... | 当你的应用运行时,Dify 会发送... | 应用运行时,Dify 发送... | | You can connect these external sources to Dify | 你可以将这些外部知识源连接到 Dify | 可将这些外部知识源连接到 Dify | | The API service you registered | 你已注册的 API 服务 | 已注册的 API 服务 | Specific words to drop or shorten when context allows: - **Drop redundant 「你的」 only when ownership is unambiguously clear and the sentence subject doesn't shift.** Keep 「你/你的」 when: the subject of the current clause differs from the previous one; without it the referent could be misread; or the sentence describes an action the reader performs. Over-dropping creates ambiguity—when in doubt, keep it. -- **Drop 「会」** in present-tense system behavior descriptions. `Dify 发送请求` is cleaner than `Dify 会发送请求`. -- **Drop 「当...时」** wrappers around simple time clauses. `应用运行时` is cleaner than `当应用运行时`. - **Replace 「能够」 with 「能」 or just the verb.** 「让...可以」 chains should be restructured with 「即可」 or rewritten. - **Default to 「可」 over 「可以」.** Use `可以` only when `可` causes ambiguity or sounds unnatural. diff --git a/tools/translate/termbase_i18n.md b/tools/translate/termbase_i18n.md index b23d33463..8e311320e 100644 --- a/tools/translate/termbase_i18n.md +++ b/tools/translate/termbase_i18n.md @@ -8,9 +8,9 @@ |:--------|:--------|:---------| | Workflow | 工作流 | ワークフロー | | Chatflow | 对话流 | チャットフロー | +| workflow | 工作流 | ワークフロー | | Agent | Agent | Agent | | Text Generator | 文本生成应用 | テキストジェネレーター | -| Agent app | Agent 应用 | エージェントアプリ | | knowledge base | 知识库 | ナレッジベース | | plugin | 插件 | プラグイン | | Dify tool | Dify 工具 | ツール | @@ -66,8 +66,9 @@ | Loop | 循环 | ループ | | Doc Extractor | 文档提取器 | テキスト抽出 | | List Operator | 列表操作 | リスト処理 | -| Agent | Agent | エージェント | +| Agent | Agent | Agent | | Human Input | 人工介入 | 人間の入力 | +| Trigger | 触发器 | トリガー | | Schedule Trigger | 定时触发器 | スケジュールトリガー | | Webhook Trigger | Webhook 触发器 | Webhook トリガー | | Plugin Trigger | 插件触发器 | プラグイントリガー | @@ -100,6 +101,7 @@ | Summary Auto-Gen | 摘要自动生成 | 要約自動生成 | | Top K | Top K | Top K | | score threshold | 分数阈值 | スコアしきい値 | +| similarity score | 相似度分数 | 類似度スコア | ### Configuration & Parameters @@ -115,6 +117,8 @@ | input field | 输入字段 | 入力フィールド | | request form | 请求表单 | リクエストフォーム | | Assemble Variable | 变量组装 | 変数アセンブル | +| blocking mode | 阻塞式返回 | ブロッキングモード | +| streaming mode | 流式返回 | ストリーミングモード | ### Agent @@ -184,8 +188,9 @@ | Data Source | 数据来源 | データソース | | API Extension | API 扩展 | API 拡張 | | Billing | 账单 | 請求 | +| Get Education Verified | 获取教育版认证 | 教育認証を取得 | | Integrations | 集成 | 統合 | -| Default Model Settings | 默认模型设置 | デフォルトモデル設定 | +| Default Model Settings | 默认模型设置 | システムモデル設定 | | System Reasoning Model | 系统推理模型 | システム推論モデル | | Embedding Model | Embedding 模型 | 埋め込みモデル | | Rerank Model | Rerank 模型 | Rerank モデル | @@ -193,8 +198,17 @@ | Text-to-Speech Model | 文本转语音模型 | テキスト-to-音声モデル | | Load Balancing | 负载均衡 | 負荷分散 | | AI Credits | AI Credits | AI クレジット | -| Usage Priority | 使用优先级 | 利用優先度 | -| API Key | API 密钥 | API キー | +| Usage Priority | 使用优先级 | 使用優先度 | +| API Key | API Key | API キー | + +### Billing + +| English | Chinese | Japanese | +|:--------|:--------|:---------| +| Sandbox | Sandbox | Sandbox | +| Professional | Professional | Professional | +| Team | Team | Team | +| Upgrade | 升级 | アップグレード | ### Workspace Roles @@ -273,6 +287,56 @@ | Environment Variables | 环境变量 | 環境変数 | | System Variables | 系统变量 | システム変数 | +### Collaboration + +| English | Chinese | Japanese | +|:--------|:--------|:---------| +| Add Comment | 添加评论 | コメントを追加 | +| Edit comment | 编辑评论 | コメントを編集 | +| Comment Mode | 评论模式 | コメントモード | + +### Variable Config + +| English | Chinese | Japanese | +|:--------|:--------|:---------| +| Short Text | 文本 | 短文 | +| Paragraph | 段落 | 段落 | +| Select | 下拉选项 | 選択 | +| Number | 数字 | 数値 | +| Checkbox | 复选框 | チェックボックス | +| API-based Variable | 基于 API 的变量 | API ベースの変数 | +| Label Name | 显示名称 | ラベル名 | + +### Prompt Generation + +| English | Chinese | Japanese | +|:--------|:--------|:---------| +| Generate | 生成 | 生成 | +| Ideal Output | 理想输出 | 理想的な出力 | + +### Vision & File Upload + +| English | Chinese | Japanese | +|:--------|:--------|:---------| +| Vision | 视觉 | ビジョン | +| Audio | 音频 | 音声 | +| Document | 文档 | ドキュメント | +| Settings | 设置 | 設定 | +| Resolution | 分辨率 | 解像度 | +| High | 高 | 高 | +| Low | 低 | 低 | +| Upload Method | 上传方式 | アップロード方法 | +| Upload Limit | 上传数量限制 | アップロード制限 | + +### Debug Controls + +| English | Chinese | Japanese | +|:--------|:--------|:---------| +| Debug as Multiple Models | 多个模型进行调试 | 複数モデルでデバッグ | +| Function Calling | Function Calling | 関数呼び出し | +| ReAct | ReAct | ReAct | +| Agent Settings | Agent 设置 | エージェント設定 | + ### Agent Node Config | English | Chinese | Japanese | @@ -281,6 +345,14 @@ | Query Variable | 查询变量 | 検索変数 | | Metadata Filtering | 元数据过滤 | メタデータフィルタ | +### Question Classifier Node Config + +| English | Chinese | Japanese | +|:--------|:--------|:---------| +| Class Name | 分类名称 | クラス名 | +| Class Label | 分类标签 | クラスラベル | +| CLASS {{index}} | 分类 {{index}} | クラス {{index}} | + ### Knowledge Retrieval Methods | English | Chinese | Japanese | @@ -296,6 +368,7 @@ | English | Chinese | Japanese | |:--------|:--------|:---------| | External Knowledge Base | 外部知识库 | 外部知識ベース | +| External Knowledge ID | 外部知识库 ID | 外部ナレッジベース ID | | External API | 外部 API | 外部 API | | Service API | 服务 API | サービスAPI | | Multimodal | 多模态 | マルチモーダル | diff --git a/writing-guides/glossary.md b/writing-guides/glossary.md index cfed17897..29be3213f 100644 --- a/writing-guides/glossary.md +++ b/writing-guides/glossary.md @@ -23,6 +23,7 @@ Terms appear in body text exactly as written in this table. Capitalize them furt | workspace | 工作区 | ワークスペース | | | template | 模板 | テンプレート | Published app that others can download from Dify Marketplace and use | | WebApp | WebApp | WebApp | | +| end user | 终端用户 | エンドユーザー | Person interacting with a published WebApp; not a workspace member | ### Models @@ -353,6 +354,14 @@ Terms in this section must match the Dify product interface exactly. When these | Query Variable | 查询变量 | 検索変数 | workflow.nodes.knowledgeRetrieval.queryVariable | Knowledge retrieval node config | | Metadata Filtering | 元数据过滤 | メタデータフィルタ | workflow.nodes.knowledgeRetrieval.metadata.title | Knowledge retrieval node config | +### Question Classifier Node Config + +| English (UI) | Chinese (UI) | Japanese (UI) | i18n Key | Notes | +|:-------------|:-------------|:--------------|:---------|:------| +| Class Name | 分类名称 | クラス名 | workflow.nodes.questionClassifiers.outputVars.className | Output variable; classifier-facing description used in the LLM prompt | +| Class Label | 分类标签 | クラスラベル | workflow.nodes.questionClassifiers.outputVars.classLabel | Output variable; user-facing branch title | +| CLASS {{index}} | 分类 {{index}} | クラス {{index}} | workflow.nodes.questionClassifiers.defaultLabel | Default class title; index is 1-based | + ### Knowledge Retrieval Methods | English (UI) | Chinese (UI) | Japanese (UI) | i18n Key | Notes | diff --git a/zh/api-reference/openapi_knowledge.json b/zh/api-reference/openapi_knowledge.json index 2537e1076..0894734ed 100644 --- a/zh/api-reference/openapi_knowledge.json +++ b/zh/api-reference/openapi_knowledge.json @@ -4544,7 +4544,7 @@ "标签" ], "summary": "解除标签与知识库的绑定", - "description": "移除知识库的标签绑定。", + "description": "从知识库中移除一个或多个标签。", "operationId": "unbindTagFromDataset", "requestBody": { "required": true, @@ -4553,13 +4553,21 @@ "schema": { "type": "object", "required": [ - "tag_id", "target_id" ], "properties": { + "tag_ids": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1, + "description": "要解绑的标签 ID 列表。未提供旧版 `tag_id` 时必填。" + }, "tag_id": { "type": "string", - "description": "要解绑的标签 ID。" + "deprecated": true, + "description": "旧版单标签字段。服务端将其归一化为 `tag_ids`。新接入应使用 `tag_ids`。" }, "target_id": { "type": "string", @@ -6871,6 +6879,83 @@ } } } + }, + "metadata_filtering_conditions": { + "type": "object", + "nullable": true, + "description": "仅检索文档元数据匹配指定条件的分段。条件由服务端基于文档元数据字段评估。", + "properties": { + "logical_operator": { + "type": "string", + "enum": [ + "and", + "or" + ], + "default": "and", + "nullable": true, + "description": "多个条件之间的组合方式。" + }, + "conditions": { + "type": "array", + "nullable": true, + "description": "要评估的元数据条件列表。", + "items": { + "type": "object", + "required": [ + "name", + "comparison_operator" + ], + "properties": { + "name": { + "type": "string", + "description": "用于比较的元数据字段名称。" + }, + "comparison_operator": { + "type": "string", + "description": "应用的比较方式。字符串运算符(`contains`、`not contains`、`start with`、`end with`、`is`、`is not`、`empty`、`not empty`、`in`、`not in`)作用于字符串或数组类型的元数据。数值运算符(`=`、`≠`、`>`、`<`、`≥`、`≤`)作用于数值类型的元数据。时间运算符(`before`、`after`)作用于时间类型的元数据。", + "enum": [ + "contains", + "not contains", + "start with", + "end with", + "is", + "is not", + "empty", + "not empty", + "in", + "not in", + "=", + "≠", + ">", + "<", + "≥", + "≤", + "before", + "after" + ] + }, + "value": { + "nullable": true, + "description": "用于比较的值。类型取决于 `comparison_operator`:大多数字符串运算符使用字符串;`in` 和 `not in` 使用字符串数组;数值运算符使用数字;`empty` 和 `not empty` 时省略。", + "oneOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "number" + } + ] + } + } + } + } + } } } } diff --git a/zh/self-host/configuration/environments.mdx b/zh/self-host/configuration/environments.mdx index 8dc4fec8d..f023a7770 100644 --- a/zh/self-host/configuration/environments.mdx +++ b/zh/self-host/configuration/environments.mdx @@ -106,14 +106,13 @@ Docker 网络内部服务间通信使用的文件访问 URL(例如插件守护 ### ENABLE_COLLABORATION_MODE -默认值:`false` +默认值:`true` -工作流画布实时协作的总开关,涵盖多人同时编辑、画布评论和 @ 提及。 +启用工作流画布的实时协作功能:多人同时编辑、画布评论以及 @ 提及。 -仅设置此变量还不够。协作通过 WebSocket 运行,还需要: +如果用户通过 `localhost` 以外的主机访问 Dify,将 `NEXT_PUBLIC_SOCKET_URL` 设置为浏览器可访问的 WebSocket URL(参见 [CORS 配置](#cors-配置))。默认值 `ws://localhost` 仅适用于本地访问场景。 -- 将 `SERVER_WORKER_CLASS` 设为 `geventwebsocket.gunicorn.workers.GeventWebSocketWorker`(参见 [容器启动配置](#容器启动配置))。 -- 将 `NEXT_PUBLIC_SOCKET_URL` 设为浏览器可访问的 WebSocket URL(参见 [CORS 配置](#cors-配置))。 +如需禁用协作功能,将此值设为 `false`。使用 Docker Compose 时,还需从 `COMPOSE_PROFILES` 中移除 `collaboration`,否则专用的 `api_websocket` 容器会持续运行但无任何流量。 如果使用自己的反向代理,需在 `/socket.io/` 路径上转发 `Upgrade` 与 `Connection` 请求头(Dify 自带的 nginx 模板已包含此配置)。多 API 副本部署需启用会话保持(sticky sessions)。 @@ -191,9 +190,12 @@ openssl rand -base64 42 | `DIFY_BIND_ADDRESS` | `0.0.0.0` | API 服务器绑定的网络接口。`0.0.0.0` 监听所有接口;设为 `127.0.0.1` 限制为仅本地访问。 | | `DIFY_PORT` | `5001` | API 服务器监听端口。 | | `SERVER_WORKER_AMOUNT` | `1` | Gunicorn 工作进程数。使用 gevent(默认)时,每个工作进程通过 greenlet 处理多个并发连接,因此 1 通常足够。对于同步工作进程,使用 `(2 x CPU 核心数) + 1`。[参考文档](https://gunicorn.org/design/#how-many-workers)。 | -| `SERVER_WORKER_CLASS` | `gevent` | Gunicorn 工作进程类型。`gevent` 提供轻量级异步并发。当 `ENABLE_COLLABORATION_MODE` 为 `true` 时,需设为 `geventwebsocket.gunicorn.workers.GeventWebSocketWorker`;若仍保留 `gevent`,WebSocket 握手将静默失败。其他值会破坏 psycopg2 和 gRPC 补丁。 | +| `SERVER_WORKER_CLASS` | `gevent` | Gunicorn 工作进程类型。保持默认值;其他值会破坏 psycopg2 和 gRPC 补丁。 | | `SERVER_WORKER_CONNECTIONS` | `10` | 每个工作进程的最大并发连接数。仅适用于异步工作进程(gevent)。如果在高负载下遇到连接拒绝或响应缓慢,尝试增大此值。 | | `GUNICORN_TIMEOUT` | `360` | 如果工作进程在此秒数内没有响应,Gunicorn 将终止并重启它。设为 360(6 分钟)以支持用于流式 LLM 响应的长连接 SSE。 | +| `API_WEBSOCKET_WORKER_CLASS` | `geventwebsocket.gunicorn.workers.GeventWebSocketWorker` | 仅适用于 Docker Compose。专用 `api_websocket` 容器的工作进程类型。保持默认值;其他值会破坏 WebSocket 支持。 | +| `API_WEBSOCKET_WORKER_CONNECTIONS` | `1000` | 仅适用于 Docker Compose。`api_websocket` 容器可同时接受的 WebSocket 连接数上限。每个打开的工作流编辑器标签页占用一个连接,因此默认值最多支持 1000 个并发编辑会话;如有更多需求可调高此值。 | +| `API_WEBSOCKET_GUNICORN_TIMEOUT` | `360` | 仅适用于 Docker Compose。`api_websocket` 工作进程在此秒数内无响应时,Gunicorn 会将其重启。默认值 360 秒(6 分钟)适用于长时间保持的 WebSocket 连接。 | | `CELERY_WORKER_CLASS` | (空;默认为 gevent) | Celery 工作进程类型,与 `SERVER_WORKER_CLASS` 有相同的 gevent 补丁要求。强烈不建议修改。 | | `CELERY_WORKER_AMOUNT` | `4` | Celery 工作进程数。仅在禁用自动扩缩时使用。资源受限的 VM 可适当降低;若需弹性吞吐,建议启用 `CELERY_AUTO_SCALE` 而非仅调高此值。 | | `CELERY_AUTO_SCALE` | `false` | 启用动态自动扩缩。启用后,Celery 监控队列深度,在 `CELERY_MIN_WORKERS` 和 `CELERY_MAX_WORKERS` 之间动态创建/销毁工作进程。 | @@ -233,6 +235,7 @@ openssl rand -base64 42 | `SQLALCHEMY_MAX_OVERFLOW` | `10` | 连接池满时允许的额外临时连接数。使用默认设置时,最多可同时存在 40 个连接(30 + 10)。 | | `SQLALCHEMY_POOL_RECYCLE` | `3600` | 在此秒数后回收连接,防止连接过期。 | | `SQLALCHEMY_POOL_TIMEOUT` | `30` | 连接池耗尽时等待连接的时长。如果在此时间内没有连接释放,请求将超时失败。 | +| `SQLALCHEMY_POOL_RESET_ON_RETURN` | `rollback` | SQLAlchemy 在连接归还连接池时执行的动作。`rollback` 在重用前清除未提交的事务状态;`commit` 则提交该状态。 | | `SQLALCHEMY_POOL_PRE_PING` | `false` | 使用连接前通过轻量查询测试连接。防止「连接丢失」错误,但会增加少量延迟。建议在网络不稳定的生产环境中启用。 | | `SQLALCHEMY_POOL_USE_LIFO` | `false` | 复用最近归还的连接(LIFO)而非均匀轮转(FIFO)。LIFO 使较少的连接保持「活跃」状态,可以减少开销。 | | `SQLALCHEMY_ECHO` | `false` | 将所有 SQL 语句输出到日志。适用于调试查询问题。 | @@ -876,7 +879,7 @@ seekdb 是 OceanBase 的轻量版本,共享相同的连接配置。 | `VIKINGDB_SECRET_KEY` | (空) | Secret key。 | | `VIKINGDB_REGION` | `cn-shanghai` | 区域。 | | `VIKINGDB_HOST` | `api-vikingdb.xxx.volces.com` | API 主机。替换为你所在区域的端点。 | -| `VIKINGDB_SCHEMA` | `http` | 协议方案(`http` 或 `https`)。 | +| `VIKINGDB_SCHEME` | `http` | 协议方案(`http` 或 `https`)。 | | `VIKINGDB_CONNECTION_TIMEOUT` | `30` | 连接超时(秒)。 | | `VIKINGDB_SOCKET_TIMEOUT` | `30` | Socket 超时(秒)。 | @@ -1011,8 +1014,6 @@ seekdb 是 OceanBase 的轻量版本,共享相同的连接配置。 | 变量 | 默认值 | 说明 | |---|---|---| -| `PROMPT_GENERATION_MAX_TOKENS` | `512` | 系统使用 LLM 自动生成提示时的最大 token 数。防止失控生成浪费 API 配额。 | -| `CODE_GENERATION_MAX_TOKENS` | `1024` | 系统使用 LLM 自动生成代码时的最大 token 数。 | | `PLUGIN_BASED_TOKEN_COUNTING_ENABLED` | `false` | 使用基于插件的 token 计数以实现精确用量跟踪。禁用时 token 计数返回 0(更快但成本跟踪不够精确)。 | ### 多模态配置 @@ -1277,6 +1278,7 @@ Dify 的所有出站 HTTP 请求(HTTP 节点、图片下载等)都通过代 | `NGINX_PROXY_READ_TIMEOUT` | `3600s` | 代理读取超时。设置较高(1 小时)以支持长时间运行的 SSE 流。 | | `NGINX_PROXY_SEND_TIMEOUT` | `3600s` | 代理发送超时。 | | `NGINX_ENABLE_CERTBOT_CHALLENGE` | `false` | 在 `/.well-known/acme-challenge/` 接受 Let's Encrypt ACME 验证请求。启用以支持自动证书续期。 | +| `NGINX_SOCKET_IO_UPSTREAM` | `api_websocket:5001` | Nginx 将 `/socket.io/` 流量转发到的上游地址。默认指向由 `collaboration` profile 启动的专用 `api_websocket` 容器。仅当 WebSocket 服务运行在 Docker Compose 之外时才需要修改。 | 启用 HTTPS 后,还需要将 [通用变量](#通用变量) 中的 URL 变量(例如 `CONSOLE_API_URL`、`CONSOLE_WEB_URL`)更新为使用 `https://`。 @@ -1309,7 +1311,7 @@ Dify 的所有出站 HTTP 请求(HTTP 节点、图片下载等)都通过代 | 变量 | 默认值 | 说明 | |---|---|---| -| `COMPOSE_PROFILES` | `${VECTOR_STORE:-weaviate},${DB_TYPE:-postgresql}` | 根据你的数据库和向量存储选择自动决定启动哪些服务容器。例如设置 `DB_TYPE=mysql` 将启动 MySQL 而非 PostgreSQL。 | +| `COMPOSE_PROFILES` | `${VECTOR_STORE:-weaviate},${DB_TYPE:-postgresql},collaboration` | 选择启动哪些服务容器。默认包含匹配的向量存储和数据库(如设置 `DB_TYPE=mysql` 将启动 MySQL 而非 PostgreSQL),以及启动专用 `api_websocket` 容器的 `collaboration` profile。移除 `collaboration` 即可跳过独立的 WebSocket 服务。 | | `EXPOSE_NGINX_PORT` | `80` | 映射到 Nginx HTTP 的宿主机端口。 | | `EXPOSE_NGINX_SSL_PORT` | `443` | 映射到 Nginx HTTPS 的宿主机端口。 | @@ -1564,7 +1566,6 @@ API 和 Celery 工作进程之间基于 Redis 的事件传输。 | `PLUGIN_PYTHON_ENV_INIT_TIMEOUT` | `120` | 初始化插件 Python 环境的超时时间(秒)。 | | `PLUGIN_STDIO_BUFFER_SIZE` | `1024` | 插件标准 I/O 通信的缓冲区大小(字节)。 | | `PLUGIN_STDIO_MAX_BUFFER_SIZE` | `5242880` | 插件标准 I/O 通信的最大缓冲区大小(字节,5 MB)。 | -| `ENFORCE_LANGGENIUS_PLUGIN_SIGNATURES` | `true` | 强制验证 LangGenius 官方插件的签名。 | | `ENDPOINT_URL_TEMPLATE` | `http://localhost/e/{hook_id}` | 插件端点的 URL 模板。`{hook_id}` 将被替换为实际的 hook ID。 | | `EXPOSE_PLUGIN_DAEMON_PORT` | `5002` | 映射到插件守护进程的宿主机端口。 | | `EXPOSE_PLUGIN_DEBUGGING_HOST` | `localhost` | 插件远程调试的主机。 | diff --git a/zh/use-dify/build/workflow-collaboration.mdx b/zh/use-dify/build/workflow-collaboration.mdx index 3780c7c3e..8b3480f29 100644 --- a/zh/use-dify/build/workflow-collaboration.mdx +++ b/zh/use-dify/build/workflow-collaboration.mdx @@ -31,11 +31,10 @@ sidebarTitle: 协作 任何能访问该应用的成员都可以查看评论;添加、编辑或解决评论需要编辑权限及以上。 -在自托管部署中,协作功能默认关闭。通过设置以下环境变量启用: +对于自托管部署: -- `ENABLE_COLLABORATION_MODE` = `true` -- `SERVER_WORKER_CLASS` = `geventwebsocket.gunicorn.workers.GeventWebSocketWorker` -- `NEXT_PUBLIC_SOCKET_URL` = 你的部署的 WebSocket URL(例如 `wss://dify.example.com`) +- 如果通过 `localhost` 以外的主机访问 Dify,将 `NEXT_PUBLIC_SOCKET_URL` 设置为浏览器可访问的 WebSocket URL(例如 `wss://dify.example.com`)。 +- 如需禁用协作功能,将 `ENABLE_COLLABORATION_MODE` 设置为 `false`。使用 Docker Compose 时,还需从 `COMPOSE_PROFILES` 中移除 `collaboration`。 -详细说明与默认值参见 [环境变量](/zh/self-host/configuration/environments#enable_collaboration_mode)。 +详见 [环境变量](/zh/self-host/configuration/environments#enable_collaboration_mode)。 diff --git a/zh/use-dify/nodes/human-input.mdx b/zh/use-dify/nodes/human-input.mdx index 3cdad8674..e3217039d 100644 --- a/zh/use-dify/nodes/human-input.mdx +++ b/zh/use-dify/nodes/human-input.mdx @@ -5,11 +5,9 @@ description: 暂停工作流以请求人工输入、审核或决策 ⚠️ 本文档由 AI 自动翻译。如有任何不准确之处,请参考 [英文原版](/en/use-dify/nodes/human-input)。 -人工介入节点会在关键点暂停工作流,在继续执行前请求人工输入。 +人工介入节点在关键点暂停工作流,发送可自定义的请求表单。接收人可使用表单审核信息、提供输入,并从预定义的决策中进行选择,这些决策决定工作流如何继续。 -当执行到达此节点时,系统会通过特定渠道发送可自定义的请求表单。接收人可以提供输入、审核数据,并从预定义的决策中进行选择,这些决策将决定工作流后续如何进行。 - -通过在关键环节直接嵌入人工判断,你可以在 **自动化效率与人工监督之间取得平衡**。 +通过在关键环节直接嵌入人工判断,你可在 **自动化效率与人工监督之间取得平衡**。 ![请求表单示例](/images/use-dify/workflow/human-input-request-form-example.png) @@ -21,7 +19,7 @@ description: 暂停工作流以请求人工输入、审核或决策 - **发送方式**:请求表单如何送达接收人。 -- **表单内容**:接收人将看到什么信息以及他们可以输入什么。 +- **表单内容**:接收人将看到什么信息以及他们可以与之交互的内容。 - **用户动作**:接收人可以做出哪些决策,以及工作流相应如何进行。 @@ -31,13 +29,13 @@ description: 暂停工作流以请求人工输入、审核或决策 选择发送请求的渠道。当前可用的方式: -- **WebApp**:在 WebApp 中显示请求表单,供当前用户响应。 +- **WebApp**:向 WebApp 终端用户显示请求表单。在由触发器启动的工作流中不可用。 外部客户端也可通过 Service API 获取并提交 WebApp 表单。详见 [获取人工介入表单](/api-reference/人工介入/获取人工介入表单)。 -- **邮件**:向一位或多位接收人发送包含请求链接的电子邮件。 +- **邮件**:将请求链接发送至特定工作区成员、外部邮箱地址或工作区全体成员。任何持有链接的人都可响应,无需 Dify 账户。 无论采用何种发送方式,请求将在收到第一个响应后关闭。 @@ -45,7 +43,7 @@ description: 暂停工作流以请求人工输入、审核或决策 ### 表单内容 -自定义请求表单中显示的内容: +自定义接收人看到并与之交互的表单: - **使用 Markdown 格式化结构** @@ -53,26 +51,34 @@ description: 暂停工作流以请求人工输入、审核或决策 - **使用变量显示动态数据** - 引用工作流变量以显示动态内容,例如供审核的 AI 生成文本或上游节点所需的任何上下文信息。 + 引用工作流变量以显示动态内容,例如供审核的 AI 生成文本或上游节点的任何上下文信息。 - 如果你引用推理模型的 `text` 输出变量,表单将默认显示模型的思维过程以及最终答案。 + 推理模型在最终答案旁输出其思维过程。引用 `text` 输出变量时默认显示两者。 - 要仅显示答案,请为相应的 LLM 节点开启 **思维链分离渲染**(Enable Reasoning Tag Separation)。 + 要仅显示答案,为相应的 LLM 节点开启 **思维链分离渲染**(Enable Reasoning Tag Separation)。 - **使用输入字段收集输入** - 输入字段可以是空的,也可以预填变量(例如,需优化的 LLM 输出)或静态文本(例如,示例或默认值),接收人可以对其进行编辑。 + 输入字段可以是空的,也可以预填变量(例如,需优化的 LLM 输出)或静态文本(例如,示例或默认值),接收人可对其进行编辑。 + + 每个输入字段都成为供下游使用的变量。例如,将编辑后的内容传递给后续处理,或将反馈发送给 LLM 进行内容修订。 - 每个输入字段都会成为供下游使用的变量。例如,将编辑后的内容传递给后续处理,或将反馈发送给 LLM 进行重新生成。 +接收人响应后,填入所有值的表单内容可作为下游变量 `__rendered_content` 使用。 ### 用户动作 -定义接收人可以点击的决策按钮。每个按钮将工作流路由到不同的执行路径。 +定义接收人可点击的决策按钮,每个按钮将工作流路由到不同的执行路径。 例如,`发布` 分支可能会通向触发内容发布的节点,而 `重新生成` 分支可能会循环回 LLM 节点以修改内容。 +每个按钮包含显示标题和动作 ID。按钮被点击时,其 ID 可作为 `__action_id`、标题(按钮文本)可作为 `__action_value` 在下游使用。 + + + ![动作按钮配置](/images/use-dify/workflow/human-input-action-button-config.png) + + 使用预设按钮样式在视觉上区分动作。 @@ -81,6 +87,8 @@ description: 暂停工作流以请求人工输入、审核或决策 ### 超时策略 -配置在请求过期前等待响应的时间。 +配置请求保持开启的时长。默认 3 天。 + +如果在超时前没有接收人响应,工作流将沿节点的超时分支继续。将该分支连接到后备路径,例如发送通知或重试循环。 -如果在设定时间内没有接收人响应,工作流将自动结束,除非你定义了一个后备分支来处理超时,例如发送通知或重试请求。 +如果未连接超时分支,工作流将结束。 diff --git a/zh/use-dify/nodes/question-classifier.mdx b/zh/use-dify/nodes/question-classifier.mdx index f46049663..7f8385725 100644 --- a/zh/use-dify/nodes/question-classifier.mdx +++ b/zh/use-dify/nodes/question-classifier.mdx @@ -1,80 +1,63 @@ --- -title: "问题分类器" +title: 问题分类器 --- ⚠️ 本文档由 AI 自动翻译。如有任何不准确之处,请参考 [英文原版](/en/use-dify/nodes/question-classifier)。 - -问题分类器节点智能地对用户输入进行分类,以将对话路由到不同的工作流路径。无需构建复杂的条件逻辑,你只需定义类别,让大型语言模型基于语义理解来确定最合适的分类。 +问题分类器节点对用户输入进行智能分类,将对话路由到不同的工作流路径。无需构建复杂的条件逻辑,只需定义分类,让大语言模型基于语义理解判断最契合的一项。 ## 配置 ### 输入和模型设置 -**输入变量** - 选择要分类的内容,通常是用户问题的 `sys.query`,但也可以是来自之前工作流节点的任何文本变量。 +**输入变量** - 选择要分类的内容,通常使用用户问题的 `sys.query`,也可以是来自上游工作流节点的任意文本变量。 -**模型选择** - 选择用于分类的大型语言模型。对于简单分类,速度较快的模型表现良好,而对于细致入微的区分,更强大的模型处理得更好。 +**模型选择** - 选择用于分类的大语言模型。简单分类用速度较快的模型即可处理;分类边界细微时,更强的模型表现更好。 - + ![问题分类器配置界面](https://assets-docs.dify.ai/dify-enterprise-mintlify/en/guides/workflow/node/2f039c5ff3f095b0eed291101d9bff15.png) -### 类别定义 - -为每个类别创建清晰、描述性的标签,并具体描述每个类别应包含的内容。明确类别之间的边界,以帮助大型语言模型做出准确决策。 - -每个类别都成为一个潜在的输出路径,你可以将其连接到不同的下游节点,如专门的知识库、响应模板或处理工作流。 - -## 分类示例 - -以下是问题分类器在客户服务场景中的工作方式: - - - ![客户服务分类工作流](https://assets-docs.dify.ai/dify-enterprise-mintlify/en/guides/workflow/node/2f06ecce149c844c23be70a8fcff09bc.png) - - -**定义的类别**: -- **售后服务** - 保修申请、退货、维修和购后支持 -- **产品使用** - 设置说明、故障排除、功能解释 -- **其他问题** - 特定类别未涵盖的一般查询 +### 分类定义 -**分类结果**: -- "如何在iPhone 14上设置联系人?" → **产品使用** -- "我购买的产品保修期是多长?" → **售后服务** -- "今天天气如何?" → **其他问题** - -每个分类结果都路由到不同的知识库和响应策略,确保用户获得相关的专业帮助。 +每个分类包含两段相互独立的文本: -## 高级配置 +- **分类描述**(编辑器正文)是模型选择分支时读取的内容。 -### 指令和指南 + 写出能准确区分该分类内容的描述。分类边界相近时,使用「与……相关」「不包括……」等边界表述有助于模型做出判断。下游通过 `class_name` 输出。 -在**指令**字段中添加详细的分类指南,以处理边缘情况、模糊场景或特定业务规则。这有助于大型语言模型理解类别之间的细微差别。 +- **分类标题**(编辑器上方的小标题)是画布上展示的标签。 -### 记忆集成 + 双击默认的 **分类 N** 标题可重命名。下游通过 `class_label` 输出。 -启用**记忆**以在分类输入时包含对话历史。这提高了多轮对话中的准确性,其中当前输入依赖于之前的上下文。 +标题和描述可独立编辑,以便你在画布上保留简洁易读的标签,同时为模型提供更完整、更具体的描述。 -**记忆窗口**控制包含多少对话历史,在上下文感知与标记数效率和处理速度之间取得平衡。 +每个分类对应一条潜在的输出路径,可连接到不同的下游节点,例如专门的知识库、响应模板或处理流程。 -## 输出使用 +## 分类示例 -分类器输出一个包含匹配类别标签的 `class_name` 变量。在下游节点中使用此变量用于: +以下是问题分类器在客户服务场景中的使用方式: -**条件路由** - 基于分类结果连接不同的工作流路径 + + ![客户服务分类工作流](https://assets-docs.dify.ai/dify-enterprise-mintlify/en/guides/workflow/node/2f06ecce149c844c23be70a8fcff09bc.png) + -**知识库选择** - 路由到每个类别的专门知识库 +**已定义的分类**: -**响应自定义** - 应用不同的响应模板或处理逻辑 +- **售后服务** - 保修申请、退货、维修以及购后支持 +- **产品使用** - 安装说明、故障排查、功能解释 +- **其他问题** - 不属于以上分类的一般问询 -**分析和日志记录** - 跟踪用户查询在各类别中的分布情况 +**分类结果**: -## 最佳实践 +- 「如何在 iPhone 14 上设置联系人?」 → **产品使用** +- 「我购买的产品保修期是多长?」 → **售后服务** +- 「今天天气如何?」 → **其他问题** -**清晰的类别边界** - 定义明确、不重叠的类别,并提供具体描述以提高分类准确性。 +每个分类结果路由到不同的知识库和响应策略,确保用户获得相关、专业的帮助。 -**适当的模型选择** - 根据分类复杂性选择模型。简单的二元分类适用于速度较快的模型,而细致入微的多类别分类可能需要更强大的模型。 +## 高级配置 -**测试边缘情况** - 验证可能适合多个类别的用对话上下文** - 为依赖之前交互进行分类的对话应用程序启用记忆。 +### 指令和指南 -**监控和迭代** - 审查分类结果,并根据实际使用模式优化类别描述。 +在 **指令** 字段中添加详细的分类指南,用于处理边界场景、模棱两可的情况或特定业务规则。这有助于大语言模型理解分类之间的细微差别。 diff --git a/zh/use-dify/workspace/subscription-management.mdx b/zh/use-dify/workspace/subscription-management.mdx index 407cbe08f..0820577e1 100644 --- a/zh/use-dify/workspace/subscription-management.mdx +++ b/zh/use-dify/workspace/subscription-management.mdx @@ -66,12 +66,16 @@ Dify 中的计费基于工作区范围。你的订阅决定了整个工作区的 前往 **设置** > **账单** > **获取教育版认证**,填写学校全称并选择角色。结果会立即显示。 - - 审核通过后,升级到 **年付** Professional 计划。结算时会自动应用教育折扣。 + + 1. 审核通过后,选择要使用教育优惠的工作区,然后点击 **使用教育优惠**。 + + 随后将跳转至结算页面,自动选择年付 Professional 计划和应用教育优惠。 - - 教育折扣仅适用于 **年付** 计费。付款前,请确认结算金额为 **\$0**。 - + + 教育优惠仅适用于年付 Professional 计划。 + + + 2. 完成付款即可激活订阅。 From 4b5db51759c9b260c1c3a580b4c7ecdd20b5ba7e Mon Sep 17 00:00:00 2001 From: RiskeyL <7a8y@163.com> Date: Tue, 12 May 2026 14:10:12 +0800 Subject: [PATCH 4/4] docs: add "Agent app" glossary entry to disambiguate from Agent node --- writing-guides/glossary.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/writing-guides/glossary.md b/writing-guides/glossary.md index 29be3213f..f647fced3 100644 --- a/writing-guides/glossary.md +++ b/writing-guides/glossary.md @@ -15,7 +15,8 @@ Terms appear in body text exactly as written in this table. Capitalize them furt | Workflow | 工作流 | ワークフロー | | | Chatflow | 对话流 | チャットフロー | | | workflow | 工作流 | ワークフロー | Always lowercase in English. Collective term covering both Workflow and Chatflow apps. Chinese and Japanese reuse the Workflow app-type translation. | -| Agent | Agent | Agent | Dify App type (alongside Workflow, Chatflow, etc.) that autonomously uses tools| +| Agent | Agent | Agent | Dify App type (alongside Workflow, Chatflow, etc.) that autonomously uses tools | +| Agent app | Agent 应用 | Agent アプリ | Explicit form of the Agent app type; use when context could confuse it with the Agent workflow node | | Text Generator | 文本生成应用 | テキストジェネレーター | | | knowledge base | 知识库 | ナレッジベース | Always lowercase unless at sentence start | | plugin | 插件 | プラグイン | |