本文档由 AI 自动翻译。如有任何不准确之处,请参考 英文原版。有些操作只能在 Dify 中完成,例如创建知识库及其元数据字段、上传文件,以及启用或禁用文档。
获取知识库端点
API 密钥及其访问范围详见 知识库 API。 在 Dify 中打开该知识库,点击左下角的 API 访问,复制其中的端点。端点以/knowledge-fs/spaces/<knowledge base ID> 结尾,其中的 ID 就是各操作所需的 knowledge_base_id。
查询知识库
先确定检索深度(mode):
下面的脚本需要 Bash、curl、jq 和 Python 3。按顺序把两个代码块复制到
query.sh 中,运行 bash query.sh,再根据提示输入刚才复制的端点和 API 密钥。
1
创建查询令牌
调用 创建查询令牌,在
query 中传入问题,在 mode 中传入检索深度。2
3
读取事件
只有
answer.done 才算成功。answer.error 可能在若干 answer.delta 帧之后到达,此时 HTTP 状态仍是 200:丢弃已收到的部分文本。连接断开后无法续传。无论失败发生在流打开之前还是之后,都从第 1 步重新开始。按你所用的最慢深度设置客户端的读取超时。运行查询接口不发送保活事件,默认超时可能会切断 deep 或 research 的流。无论哪种深度,返回的文本最多 2,000 个字符,被截断时也没有任何提示。answer.done 的 metadata.evidenceBundle 中的分段文本从不截断,需要完整的检索文本时,从这里读取。x-session-id 作为 sessionId 传入也一样,所以追问需要的信息都要写进这次的 query。
排查回答
回答看起来不对时,把它的查询记录 ID 传给 获取查询记录,查看这次运行记录下的各个步骤。用同一个 ID 还可以检查证据:- 调用 获取查询分段列表,查看检索到的分段、得分和引用。
- 如果检索到的文本自相矛盾,调用 获取查询冲突列表,找出相互冲突的分段。
- 调用 获取缺失分段列表,查看这次运行需要但没能用上的分段,以及没用上的原因。
防止重复写入和过期写入
凡是支持Idempotency-Key 请求头的写操作,都带上它。如果响应丢失,用同一个键再发一次相同的请求:返回的是原来的任务、运行或作业,不会再新建一个。每个新操作都要用新的键,因为重复的键会返回之前的结果,即使那次操作已经结束。
在更新或删除对象的前一刻读取它当前的版本,放进该操作的版本字段一起发送。这样,收到 409 就说明对象在你读取之后发生了变化:重新读取,确认你的变更仍然适用,再重新发送。409 也可能表示该 Idempotency-Key 已用于其他请求:此时改用新的键。
运行研究任务
research 深度的查询在流中直接给出回答,研究任务则在后台运行,并保留结果。用户正在等回答时,用查询;工作可以稍后完成,或之后还要用到结果时,用研究任务。
1
规划
把问题作为
query 发送给 规划研究任务,同时传入想用的 mode 和 topK。它会返回预估的成本、延迟和步骤,但不会启动任何任务。2
创建
调用 创建研究任务,传入相同的问题和设置。想在预估超出可接受范围时直接拒绝任务,就加上
limits:预估超出这些限制的任务会失败,返回 422。如需限制任务运行期间的花费,加上 budgetUsd。需要回答时,把预算设得远高于规划结果中的 estimates.costUsd.max,因为每次调用模型时,预算都要容得下这次调用最多可能的花费。因预算停止的任务,状态为 canceled。3
轮询
用返回的任务 ID 调用 获取研究任务,直到任务结束。
4
读取结果
调用 获取研究任务结果列表,在最后一条结果中查看
answer。浏览文档和分段
文档就是 文档 页面中显示的条目。文档有自己的文档 ID,背后存储的文件另有一个文档文件 ID。每次内容更新(包括数据源同步带来的更新)都会存入一个新文件,生成新的 ID,但文档 ID 保持不变。保存文档 ID,并通过它的修订版本追溯内容历史。
要显示某条引用来自哪个文档,把它的
documentAssetId 传给 按文件获取文档,并将 document_asset_version 设为 1。
要读取文档的分段,把文档 ID 和修订版本号传给 获取分段列表。要读取当前用于检索的内容,从 获取文档 中取 active.revision。要读取更早的内容,在 获取文档修订版本列表 中找到对应的修订版本。
要从其他系统(例如 CMS 或工单工具)设置文档的元数据,调用 更新文档元数据。
添加数据源
数据源通过连接读取内容。连接指在 集成 > 数据来源 中配置、并关联到该知识库的提供商账号或 API 密钥。每个提供商的第一个数据源需在 Dify 中添加,入口是知识库的 数据源 页面。如需通过 API 添加更多数据源:-
调用 获取数据源连接列表,选择一个状态为
active、且configuration指明了目标提供商的连接。 -
调用 创建数据源,将连接的
id作为connectionId,将其configuration.providerKind作为metadata.providerKind。按数据源读取的内容设置type和uri:- 网站:
type: web,uri为网站的根 URL。 - 在线文档平台或在线云盘:
type: connector,uri为connector://<connectionId>。
Idempotency-Key,同一请求发送两次会创建两个数据源。附上一个唯一的metadata.client_request_id:如果响应丢失,重新创建数据源之前,先在 获取数据源列表 中查找这个值。 - 网站:
导入网站页面
网站数据源有 3 种填充方式:- 从抓取预览中挑选页面。
- 导入已知的 URL。
- 同步 一个还没有页面列表的数据源:Dify 会抓取整个网站,并导入找到的每个页面。
1
2
挑选页面
用运行 ID 分页调用 获取抓取预览页面列表,收集每个要导入页面的
page_id。sourceUrls 传入。未传入页面对应的文档会在下次同步时删除。要改为在同一次运行中删除,同时设置 replaceExistingSelection: true。
导入在线文档和云盘文件
通过 API,可为新的connector 数据源填充一次内容。数据源一旦导入过条目,无论是在 Dify 中还是通过 API,之后的导入就只能移除条目:包含新条目的导入会失败,尽管其 failure 提示可以重试。新条目需在 Dify 中添加。
你发送的条目就是该数据源的全部内容:未发送条目对应的文档会在同一次运行中删除。
- 根据数据源的
metadata.providerKind,在线文档数据源用 获取数据源页面列表 浏览,在线云盘用 获取数据源文件列表 浏览。 - 调用 导入数据源条目,传入与提供商匹配的
kind,以及根据浏览结果构建的items,并严格遵循该操作规定的providerItemId格式。 - 用返回的
id跟踪这次运行。
跟踪数据源运行
用发起运行时返回的id 调用 获取数据源运行,一直跟踪到运行结束。运行进入 completed 时,它导入或刷新的每个条目都已完成索引并激活,无需另外跟踪索引。
一个数据源同一时间只处理一次运行:已有运行在进行时,再发起同步或导入会失败,返回 502。等进行中的运行结束,或调用 取消数据源运行 将其取消。抓取预览在你从中导入或将其取消之前,都算作进行中的运行,因此不打算从中导入的预览要取消掉。
要查找不是你发起的运行(例如定时同步,或在 Dify 中发起的运行),调用 获取数据源运行列表。
运行失败时,查看其 failure 了解原因。要排除凭据错误,调用 测试数据源凭据:如果 valid 为 false,在 Dify 中修正该连接的凭据。
要让 failed 或 canceled 状态的运行沿用同一个 ID 从头再跑一次,调用 重试数据源运行。如果要重做已取消的抓取预览,或失败的 导入网站页面 运行,改用新的 Idempotency-Key 发起新的预览或导入。
同步数据源与定时同步
要立即获取数据源的最新内容,调用 同步数据源,然后 跟踪它返回的运行。 要定时同步,需为每个数据源分别保存定时同步设置:2
保存定时同步
调用 更新同步策略,将
revision 作为 expectedRevision、version 作为 expectedSourceVersion 传入。version,仍绑定在旧值上的定时同步会在下一次到期时自行关闭。
要停止定时同步,保存 mode: manual 并设置 enabled: false。用 更新数据源 把数据源的 status 设为 disabled 只会暂停定时同步,暂停期间到期的同步会在数据源重新启用后立即运行。
重新索引并跟踪索引进度
索引失败或已取消时,用 重试索引任务 重新启动该任务。文档已完成索引但结果有误时,重新索引该文档。更换模型无需重新索引:受影响的内容会自动重建。 调用 重新索引文档,传入documentIds 或 all: true。只有状态为 queued 的条目启动了任务:逐一保存它们的 compilation_job.id。
要知道新内容何时生效,轮询索引任务,直到其结束:
- 对于重新索引,用
compilation_job.id轮询 获取索引任务。 - 对于不是通过 API 发起的索引(例如在 Dify 中上传文件),从 获取文档 或 获取文档列表 中读取
latest_task.id,再用文档 ID 和该任务 ID 轮询 获取文档的索引任务。
更换模型或检索设置
从 获取可用模型 返回的结果中选择模型。该操作需要可访问所有知识库的密钥:仅限特定知识库的密钥会收到 403forbidden。
如果在第一个文档完成索引之前设置模型,模型要等到该文档索引完成后才会校验。届时查看 获取知识库设置 中的 issues:其中列出了所有让知识库无法就绪的问题。
有文档正在索引时,更换模型会被拒绝,返回 409:先等索引完成,或取消相应的索引任务。
知识库有了已索引的内容后,大多数设置变更都会作为迁移在后台运行:
每次更新只能更换嵌入模型或检索设置中的一项,不能两者都改:同时包含两者的调用会被拒绝,返回 422。要两者都更换,先发送嵌入模型的变更,等它的迁移成功后,再发送检索设置的变更。
删除文档和数据源
要删除整个文档,需在 Dify 中操作。通过 API 可删除文档文件(删除文档文件、批量删除文档文件)和数据源(删除数据源)。 删除文档文件只会删除基于该文件的修订版本,不会删除文档本身。不要删除生效修订版本的文件:旧的修订版本不会顶替上来,文档也会从获取文档列表的结果和 Dify 的文档列表中消失。但文档并没有被删除,仍会占用文档配额。 删除数据源会同时删除它导入的文档。要保留这些文档,先从 获取文档文件列表 中保存带有该source_id 的文件 ID,因为删除完成后,这些文件的 source_id 会变为 null。然后用 documents=keep 删除数据源。保留的文档在删除完成前处于隐藏状态,之后也不再随任何数据源更新。
要确认删除已完成,用 job.id 轮询 获取删除作业,直到作业结束。
对于批量删除,用 batch_id 轮询 获取删除批次,直到 results 中的每一项要么为 rejected,要么对应的作业已经结束。rejected 的文件没有删除,error 说明了原因。出现 pending 的项,说明批次中途停止,继续轮询也不会让它变化:用同一个 Idempotency-Key 再次发送相同的请求,即可只重试 pending 的文件。
以 failed 结束的删除,无论通过 API 还是在 Dify 中,都无法重试或清除。要删除的内容会一直隐藏,包括以 documents=keep 删除数据源时保留的文档。
处理错误
与 错误与速率限制 中介绍的一样,错误带有code、message 和 status,很多错误还会附带 failure 对象:其中的 retryPolicy 说明重试是否有用。运行查询 的错误有自己的结构,列在该操作的页面上。
遇到 502 时,读操作可稍等片刻后重试。写操作则可能在响应丢失之前就已生效:用同一个 Idempotency-Key 重新发送;不支持幂等键的写操作,先确认结果再重新发送。发起同步或导入时遇到 502,也可能是因为该数据源已有进行中的运行:详见 跟踪数据源运行。
除 获取可用模型 外,403 forbidden 表示工作空间已达到知识库的 请求频率限制。整个工作空间共享这一限制,每次调用都会计入,读操作也不例外。被限制拒绝的调用同样计入,因此重试前要先退避,轮询时也要拉开间隔。要在一次调用中轮询多个索引任务或批量任务,将它们的 ID 作为 task_ids 传给 获取后台任务列表。