大数跨境

Dify 1.17.1 来了:Agent 失忆、知识库炸数据、并发死锁…这次全修了

Dify 1.17.1 来了:Agent 失忆、知识库炸数据、并发死锁…这次全修了 AI4SE
2026-09-11
8
导读:上周刚写完 1.17.0 那 30 多个 Issue 的事,没想到 Dify 团队动作这么快

上周刚写完 1.17.0 那 30 多个 Issue 的事,没想到 Dify 团队动作这么快——9 月 10 号就推了 1.17.1,一口气把那些坑基本全填了。

这个版本的官方标题是"Bug Fixes and Improvements",但说实话,叫"Damage Control"可能更贴切。Agent 失忆的问题、知识库数据被悄悄改坏的问题、并发检索死锁的问题……每一个单拎出来都能让人半夜惊醒。

下面挑几个最值得关注的聊聊。


新功能:虽然不多,但有一个很实用

知识库 API Key 终于能绑定单个知识库了

这个改动看着不大,但对多知识库场景来说是个质变。

以前知识库的 API Key 是工作区级别的——一个 Key 能读写租户下所有知识库。你想给某个外部集成只开放一个知识库的权限?没门,给了 Key 就等于给了全部。

现在创建 Key 的时候多了个作用域选择器,可以绑定到具体知识库。绑定后的 Key 访问其他知识库直接返回 403。已有的 Key 保持原来的全局行为不受影响,升级不会破坏现有集成。

适用场景

  • 给第三方工具只开放特定知识库的读写权限
  • 多租户环境下做细粒度的权限隔离
  • 对外提供知识库 API 服务时控制访问范围

工作流节点支持键盘方向键移动

之前调整节点位置只能靠鼠标拖,现在节点、多选节点、注释都能用方向键移动了,按住 Shift 是大步移动。松手后才提交一次 undo 记录,不会按一次键就记一步。

小改进,但对经常在工作流画布上折腾的人来说,体验提升明显。

Marketplace 首页重设计 + 创作者主页

插件作者现在有了公开的 Profile 页(/marketplace/creator/<handle>),可以展示自己发布的所有插件。Marketplace 首页也重做了——Hero 区、Banner 轮播、置顶搜索栏、分类标签页、语言过滤,移动端还做了滑动卡片布局。

Markdown 表单字段名长度可配置

之前硬编码 128 字符上限,现在通过 MARKDOWN_FORM_FIELD_NAME_MAX_LENGTH 环境变量可以调整。


Bug 修复:这才是重头戏

知识库:一堆"数据被悄悄改坏"的坑

这版修了一组特别阴险的提取 Bug——文档内容被改了但不报错,你根本不知道数据有问题。

CSV 数据被 pandas 类型推断搞坏:前导零的编码变成了浮点数(00123 → 123.0),空单元格变成了字面量"nan",包含"NA"或"NULL"的单元格直接变缺失值。现在改为全部按文本读取,关闭了缺失值推断。

Notion 表格提取错列:单元格里只要有混合格式(加粗、链接、@提及),每个富文本段都会被当成独立的 Markdown 列,导致表格列数错乱。空单元格则被直接跳过,整行数据左移。

Notion 数据库属性被截断rich_text 和 title 类型只读了第一个文本段。比如标题"Hello world"里"world"是粗体,就只索引了"Hello "。

.xls 双引号问题:单元格里有双引号(比如 he said "hi"),.xlsx 路径做了转义但 .xls 路径没有,直接破坏了整行的 JSON 结构。现在两条路径行为统一了。

URL 加载的 PDF 全部崩溃:加了租户上下文之后,load_from_url 路径上会 assert 一个 URL 加载永远不会有的上传记录,直接抛 AssertionError。现在租户上下文改为可选,URL 来源的 PDF 文本提取恢复正常。

Web Scraper 返回 Python 数据结构而不是文本readabilipy 返回的 plain_text 是 dict 列表,之前直接拼进输出模板,每个抓取的页面都带着一堆 [{'text': '<p>…</p>'}, …] 这种原始数据结构。

部分段落更新会清空附件:更新段落时如果没传 attachment_ids,系统会当成"替换为空",把附件绑定和多模态向量全删了。现在改为不传就保持原样,传 [] 才清空。

无效 Markdown 图片链接卡死索引队列:相对路径、data:ftp:、畸形链接全都被送进远程图片抓取器的 SSRF 重试循环,一个文档里有很多坏链接就能把索引 worker 卡住,后面的任务全排队。现在会校验并跳过不可抓取的链接。

删除内容留下孤文件:段落删除、多模态重索引、批量文档删除都只删了数据库记录,物理文件留在对象存储里。现在三条路径都会在数据库提交后删除底层对象。

⚠️ 官方建议:升级后重新导入受影响的文档,已索引的文本不会自动修复。

Agent 与对话:Chatflow Agent V2 不失忆了

Agent V2 跨轮次失忆:之前 session 没有按 conversation_id 做 key,导致 Agent 每一轮都忘光了。现在修了。同时还修了中途发布新版本导致的配置不匹配问题——已有对话锁定在开始时的版本,新对话才用新版配置。

推理模型输出全显示为"thinking":GLM-5.3 这类模型用 <think> 标签包裹思维链,如果工具调用打断了生成(\</think\> 还没输出),答案就被嵌套在一个未闭合的标签里,整段内容都显示成"思考中"。现在会在工具日志中断流、新 <think> 标签出现、流结束时自动闭合悬空标签。

图片上传变成下载指令:Agent App 里上传的图片被转成了 shell 下载指令而不是传给模型。现在视觉能力模型会收到原生多模态内容,非图片文件和无视觉能力的模型走下载兜底。图片 URL 和 Base64 在日志里也做了脱敏。

建议问题接口能卡好几分钟:没有单独配置建议问题模型时,走的是工作区默认模型,继承了 reasoning_effort=high、2560 token 输出上限、600 秒超时这些昂贵设置,浏览器 100 秒就放弃了,后端还在跑。现在输出限制在 256 token,关闭或最低化思考强度,30 秒超时。有反馈从 113-344 秒降到了 3 秒以内。

E2B Agent 运行报 502:E2B SDK 里一个过时的 HTTP/2 连接问题,现在升级了 SDK 并加了重试逻辑,容量耗尽返回 429 而不是报创建失败。

工作流:Human Input 的一堆坑

Human Input 提交后工作流看起来卡住了:1.17.0 的 HITL 回调迁移之后,提交表单后审批按钮还留在界面上,Web App 输入也被阻塞。原因是引擎发了一个通用的 node-success 事件,但响应管道期望的是 form-filled 或 timeout 事件。现在这些事件会被重建。

Human Input 不能放在 Loop/Iteration 里:1.17.0 明明加了运行时支持,但编辑器里两个过时的守卫还在拦着。现在能正常放进去了。

超时边触发了错误的分支:编辑器写的超时边是 __timeout,但后端比较的是 __timeout__,导致超时可能走了用户操作分支而不是超时分支。

同一运行里第二次暂停无法恢复:对象存储拒绝删除上一个暂停快照时,异常中断了事务——运行已经持久化为 PAUSED 状态,但唯一的暂停记录是上一个已经恢复的,下一次提交就报"Cannot resume an already resumed pause"。现在快照清理改为尽力而为。

Loop 的 Boolean 中断条件永远不生效:新条件把 "true"/"false" 存成了字符串而不是布尔值。现在改为存储和使用真正的布尔值,旧字符串值在渲染时自动规范化。

Workflow-as-Tool 只暴露第一个 End 节点的输出:现在会从所有 End 节点收集输出声明,并标注来源节点。

单个坏 LLM 节点搞崩整个编辑器:LLM 节点的 model_selector 被存为 null 时,整个 Workflow Studio 的节点检查清单崩溃,触发页面级错误边界,整个画布不可用。现在改为只标记有问题的节点。

触发器入口的工作流还能被手动调用:通过 Web App、Service API、OpenAPI、MCP 手动调用触发器工作流,创建了永远不会正常运行的 workflow run。现在会在创建 run 或日志之前直接拒绝。

并发与死锁:两个生产级别的严重问题

并发知识检索死锁:命中数更新用 UPDATE … WHERE id IN (...) 批量递增匹配段,但 PostgreSQL 不保证行锁按 ID 顺序获取——重叠的并发检索可能以不同顺序获取锁,导致 deadlock_detected。现在改为先按 ORDER BY id 稳定排序再获取锁,加最多 3 次死锁重试。

自动摘要生成卡死工作线程:腾讯 VectorDB 拒绝 JSON 元数据中的布尔值,is_summary: true 在 upsert 时失败——但此时摘要生成和 embedding 已经完成了。失败路径又开了第二个数据库会话去记录错误,和调用者的会话互相等待,直接死锁,工作线程永远不释放。现在腾讯 VectorDB 改用整数存储该标记,错误记录改在调用者的会话里完成。

触发器与插件

Windows 上构建的 Skill 包直接报错:SKILL.md 用 CRLF 换行时,frontmatter 解析器匹配不上,name 字段为空,导入报"config asset name must not be blank"。现在支持并自动规范化 CRLF。

触发器测试能跑但生产不触发:插件触发器关系同步的是草稿工作流而不是发布版本,发布后的事件找不到订阅者。

基于租约的触发器大约一周后失效:订阅创建时存的是占位符 expires_at: -1 而不是 provider 返回的真实租约,刷新扫描器跳过 -1,所以 Gmail watch 之类的就静默过期了。


升级注意事项

  1. Weaviate 用户注意:内置 Weaviate 从 1.27.0 升到了 1.39.2,跨了 12 个 minor 版本,必须按升级指南分阶段手动升级,直接拉新镜像重启会导致向量搜索静默损坏。全新部署、外部 Weaviate 和其他向量库不受影响。

  2. 从 1.15 之前版本升级:不再需要手动跑 flask data-migrate legacy-model-types,这个迁移已经合入 flask db upgrade,旧模型类型值自动规范化。

  3. MySQL 用户:修了一个 REPEATABLE READ 隔离级别下,文档创建/更新报"One or more files not found"的问题。PostgreSQL 不受影响。

  4. WebSocket 大工作流:大工作流图会导致协作 socket 超过 Engine.IO 默认的 1MB 限制,现在可通过 WEBSOCKET_MAX_HTTP_BUFFER_SIZE 配置,默认 10MB。


写在最后

1.17.1 的定位很明确——不追求新功能,集中解决 1.17.0 遗留的质量问题。从修复列表来看,团队对知识库数据完整性、Agent 会话状态、并发安全这几个核心链路的投入很大。

如果你在跑 1.17.0,建议尽快升级。特别是知识库提取那几个"不报错但数据坏了"的 Bug,以及并发死锁问题,在生产环境下影响不小。

如果你还在 1.16.x 求稳,这个版本也值得关注——它把很多 1.17.0 的坑填了,可能是进入 1.17 系列的比较稳妥的入口。

积累大量Dify应用场景欢迎交流!


Dify嗨聊

图片

友情提示:欢迎关注,请添加微信:winteroak,邀请加入海聊吧!

【声明】内容源于网络
0
0
AI4SE
聚焦Dify、Coze等工作流和 AI 智能体研发,融合LLM、AI Agent、RAG、MCP 等技术,驱动高效赋能。
内容 216
粉丝 0
AI4SE 聚焦Dify、Coze等工作流和 AI 智能体研发,融合LLM、AI Agent、RAG、MCP 等技术,驱动高效赋能。
总阅读9.4k
粉丝0
内容216