Files
story/docs/dify-workflows.md
Codex Local bf1233d5df
ci / verify (push) Canceled after 0s
feat: expand companion platform, device controls, and memoir workflows
Add customer and operator login, BLE provisioning, device fleet controls, call memory, memoir generation, and refreshed family and maintenance portals. Include API contracts, migrations, firmware sources, tests, assets, and deployment documentation.
2026-10-08 10:06:44 +08:00

8.3 KiB

聊天整理与图文回忆录工作流

线上使用自托管 Dify 1.17.1。入口为 https://82.157.201.114/apps,使用独立管理员登录。账号密码保存在服务器 /opt/story-dify/admin-private.json,不要提交到代码仓库。

两个已发布的工作流

聊天流程:接收任务 → 读取聊天与已有故事 → 分类并逐事件拆分 → 独立审核今天实际事件 → 检查原话证据 → 同一事件比较新增信息 → 返回新增、更新、重复的统计。分类与日常审核分别选择模型,默认均为火山 deepseek-v4-1-flash-260910。

回忆录流程:读取该长者全部可用故事 → doubao-seed-evolving 一次编写整本 → 核验来源、章节与日期 → 平台先保存并显示正文 → doubao-seedream-5-0-pro-260628 逐章配图(并行 3 章)→ 汇总并保存。所有故事必须各出现一次,保持来源日期;插画失败仍保留正文。

选择模型节点,在右侧“设置”的“模型”菜单中选择,提示词在输入变量 prompt 中编辑。四个可配置节点如下:

工作流 节点 默认模型
聊天整理 分类与故事拆分 DeepSeek V4.1 Flash
聊天整理 审核今天实际事件 DeepSeek V4.1 Flash
图文回忆录 全部故事统一编写整本 Doubao Seed Evolving
图文回忆录 绘制该章情景插画 Seedream 5.0 Pro

文本菜单包含 DeepSeek V4.1 Flash、Doubao Seed Evolving、Seed 2.1 Pro、Seed 2.1 Lite。整本写作菜单仅列支持 JSON Schema 的三个 Doubao 模型。插画菜单包含 Seedream 5.0 Pro、5.0 Flash 和 4.0。选择“自定义模型 / 接入点”时,在下面填写火山模型 ID 或 ep- 接入点;写作模型须支持 JSON Schema,插画接入点须为图像生成。模型权限和费用沿用当前火山账户,菜单不会切换密钥或服务地址。选错模型或调用失败会明确报错,不会悄悄改回默认模型。

草稿自动保存,先“测试运行”,确认效果后点击右上角“发布”。发布影响后续线上生成任务,已在执行的任务继续使用开始时的工作流版本,同一任务的重复步骤不会因为菜单变化再次调用模型。开始节点的两个输入由平台自动传入。Dify 中手动测试且留空时,使用虚构示例,不写入长者账号。手动测试仍会调用实际火山模型。

画布的“日志”可查看真实任务执行进度、各节点耗时、实际模型 ID 与错误。回忆录正文内记录 workflow_run_id,便于对应 Dify 日志。四个模型步骤是原生自定义 API 工具节点,其余步骤保留 HTTP 请求、校验代码及原生迭代节点。

数据与授权

Go 后端继续负责登录、账号隔离、授权、来源版本检查、故事合并和数据库保存。真实聊天与整本内容只在私有模型桥接服务的短期内存中传递;Dify 输入和输出只有临时任务编号、执行凭证及统计。上下文任务结束即删除,最长 20 分钟。桥接服务没有数据库凭证,没有公开端口。

火山密钥、两个 Dify 工作流密钥和桥接服务密钥均通过服务器只读秘密文件加载。不要把长者原文或长期密钥粘贴到工作流变量、提示词或导出文件中。

配置与维护

API/Worker 配置:

DIFY_ENABLED=true
DIFY_BASE_URL=http://story-dify-nginx/v1
DIFY_BRIDGE_URL=http://model-bridge:8188
DIFY_BRIDGE_SECRET_FILE=/run/secrets/voice-runtime/dify-bridge-secret
DIFY_EXTRACTION_API_KEY_FILE=/run/secrets/voice-runtime/dify-extract-api-key
DIFY_MEMOIR_API_KEY_FILE=/run/secrets/voice-runtime/dify-memoir-api-key

默认 DIFY_ENABLED=false,使用原有生成器。启用时缺少凭证会在启动时明确失败。

桥接服务源码为 cmd/workflow-model-bridge、internal/workflowbridge,连接器为 internal/dify。模型名称从节点传入,缺省时兼容旧工作流的原模型。Dify 自托管目录为 /opt/story-dify,已解析的私密 Compose 配置为 compose.private.json。服务配置、数据库密码及所有私密文件均禁止提交。

原生工具提供者名称为“故事平台 · 分步骤模型”,由 scripts/dify-model-tools.py 管理。Dify 1.17.1 的 OpenAPI 解析器会忽略 enum 和参数 form,因此安装脚本在原生 ApiToolBundle 元数据中配置 SELECT 菜单;API 和运行时使用同一份元数据。不要直接在工具页重新保存 schema,否则菜单参数会被解析回普通文本;变更菜单应更新安装脚本并重新生成元数据。字符串凭证参数使用 mixed 变量模板,避免 Dify 编辑器在更换模型时清空字符串的 variable 绑定。

API 与 Worker 的 API_TOOL_DEFAULT_READ_TIMEOUT=660 必须同时保留,否则原生工具默认 60 秒会中断整本写作。2026-10-07 模型菜单版本的桥接镜像为 story-workflow-model-bridge:1.1.0-model-menu,配置、桥接二进制和原工作流备份在 /opt/story-dify/model-menu-backup-20261007,回滚时应同时恢复原发布工作流指针和原草稿。

docker compose -p story-dify -f /opt/story-dify/compose.private.json ps
docker compose -p story-dify -f /opt/story-dify/compose.private.json logs --tail 100 api worker model-bridge

平台 API、Worker、gateway 与 Dify nginx、模型桥接服务共用外部网络 story-workflows。Dify nginx 的自身 API/Web 上游使用独立别名 story-dify-api 和 story-dify-web,避免与故事平台服务名冲突。gateway 的 Dify 路由配置有 /opt/story-dify/gateway-before-dify.conf 备份。后续重建 gateway 必须保留这个外部网络和 Dify 路由;本次平台发布的冻结 Compose 配置已包含该网络。

Dify 1.17.1 的登录跳转和会话刷新经过 /auth/refresh,gateway 必须将该路径精确代理到 story-dify-nginx。漏配时,访问 /apps 会误进入故事平台家庭登录页。不要代理整个 /auth/ 前缀,故事平台自身使用 /auth/callback 处理 OIDC 回调。2026-10-07 已补齐精确路由,并同步正在挂载的配置、当前发布配置与 /opt/story-dify/gateway-dify-routes.conf;修复前备份位于 /opt/story-dify/gateway-auth-refresh-backup-20261007T003108Z。修改挂载文件应保留 inode,再执行 nginx -t 和 nginx -s reload。

Dify 与 sandbox 的执行密钥必须一致;Celery broker URL 必须使用实际 Redis 密码。仅健康探针通过不足以确认工作流可执行。整本模型单次请求允许 480 秒,整体重试最多 600 秒。整本编写节点读超时为 660 秒,Squid 的请求/读超时为 12 分钟、连接存活为 20 分钟,避免默认两分钟代理限制中断长正文。

可复现的画布与验证

python scripts/build-dify-workflows.py --provider-id PROVIDER_UUID 从应用提示词生成带菜单的 deploy/dify/workflows/*.yml 和工具 OpenAPI 定义。先在目标工作空间安装原生提供者,再传入其 UUID;当前工作空间为 5210ee18-44c1-47f3-a36e-4996e2403d50。不传 UUID 则生成兼容旧版桥接服务的 HTTP 画布。这些文件是合法 YAML 的 JSON 写法,Dify 0.7.0 DSL 可直接导入,不含长期密钥。可以从 Dify 导出当前已修改的 DSL 作为新版本。部署迁移应使用 dify-model-tools.py stage APP_ID... --backup-dir PRIVATE_PATH,保留实际草稿里的提示词;验证后再 publish,发生并发修改时哈希校验会拒绝发布。

验证覆盖:Dify 流式执行和中断停止、私有上下文授权和删除、并发步骤避免重复调用、完整故事目录成书、插画欠费保留正文、空故事数组传输,以及数据库中正文先显示、来源变更失效、撤回授权后拒绝读取。实际 Dify 画布另用隔离模型夹具执行两个完整流程,其中回忆录测试包含三个章节的原生并行迭代;测试应用和容器结束后删除。真实火山模型调用另行验证。

回忆录模型的 JSON 格式兼容:根据 schema 补齐缺失的段落数组左括号,并处理引号和换行的转义。修复保持原始段落、故事编号和日期,之后仍执行完整来源校验;被长度截断的模型回复不会被修复后接收。