dify/knowledge-fs/docs/knowledge-retrieval-v2-node-iteration-plan.md

203 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Knowledge Retrieval v2 节点迭代计划
新增独立的 `knowledge-retrieval-v2` 工作流节点,对接 KnowledgeFS 知识库。与现有
`knowledge-retrieval` 节点(旧 dataset 体系)并存,互不混用。
## 需求范围
**覆盖**workflow / chatflow 画布中的 KnowledgeFS 检索节点(配置、执行、试运行、发布、
运行详情展示)。
**不覆盖(明确非目标)**
- Agent 应用的 dataset 工具、其他旧知识库引用面的 KFS 化。
- v1 节点的退役与自动迁移工具(仅通过输出变量结构兼容为其预留可能性)。
- 检索质量回流workflow 空结果进 failed-query 体系)——独立立项,见"后续项"。
## 核心设计决策(已定)
| # | 决策 | 结论 |
|---|---|---|
| D1 | 节点标识 | 全新 NodeType 字符串 `knowledge-retrieval-v2`backend `version()="1"`;前端新增 `BlockEnum.KnowledgeRetrievalV2`。**不采用** agent_v2 的同 type + version 判别模式(那是原地升级语义,本需求要求两节点并存) |
| D2 | 检索 API | 网关 `POST /knowledge-spaces/{id}/retrieval-tests`evidence-only**不用** `createQuery`(会走 LLM 生成答案,成本/延迟/语义都不符) |
| D3 | 配置归属 | 节点配置面保持薄:空间选择 + query 变量 + mode+ manual metadata filters。topK/阈值/rerank 归空间的 published retrieval profile节点不复刻 v1 的节点级检索参数 |
| D4 | 多空间 | MVP 支持多空间:最多 10 个空间、最多 4 路并发检索、保留 KFS 返回的 profile-final `score` 做稳定降序合并并全局 topN 截断;**不做每空间二次 min-max 归一化**(它会把弱相关单结果错误抬到 1。跨空间统一 rerank 留 P2文档明示分数仅弱可比 |
| D5 | 绑定生命周期 | 发布含 v2 节点的 workflow 时对 `caller_kind=workflow` 做**精确同步**:新增/恢复目标绑定,并撤销已从已发布 graph 移除的绑定。`orphan_reconciler` 当前只处理 Space 生命周期,不能替代 workflow 引用清理admission 失败运行时报确定性错误码 |
| D6 | mode 默认值 | 节点默认不传 mode每个空间分别跟随其 published `defaultMode`)。显式值仅允许 `fast/deep/research`KFS 当前没有 `auto` retrieval mode不能向该端点发送 `auto`。research 模式允许选择但 UI 标注高延迟高成本 |
| D7 | metadata 过滤 | 迭代 1 在 retrieval-tests 暴露有界的 KFS 固定字段 filters节点 MVP 仅 manual 模式。不能复用旧 dataset 的任意 `name/operator/value` 条件因为两者合同不兼容automaticLLM 抽条件)为 P2 |
## 开发前评审修订2026-08-09
原方案整体可实施,但开发以以下约束为准:
- `retrieval-tests` 是 evidence-only 产品操作,即使 method 为 POST也登记为只读 action
`includeText=true` 只返回有界正文,不透传候选内部 metadata。
- 单候选正文最多 8,192 Unicode 字符,最多 100 个候选;产品操作响应上限 4 MiB。
- 多空间查询任一空间失败时 fail-closed不返回容易被误认为完整结果的 partial evidence空结果是成功。
- 多空间未显式指定 mode 时,各空间可能采用不同默认模式,因此聚合 metrics 的 `mode` 允许
`mixed`,同时返回 requested/effective mode 与 per-space 摘要,不能假设只有一个 mode。
- 草稿 debugger/explore 运行可在授权校验前幂等创建所选空间绑定;已发布/终端用户运行绝不
自动补绑定。发布路径先校验所有目标空间,再在一个事务里精确同步绑定,避免半发布状态。
- `control_space_ids` 最多 10 个并去重;`top_n` 范围 1100query 限 16,000 字符;
filters 采用 dates/documentTypes/entities/freshnessStatuses/languages/nodeKinds/sourceIds/tags。
- DSL 跨环境不会静默接受缺失 Space导入进入 checklist warning发布前 validation 阻断。
## 现状事实(调研结论,开发前置依赖)
- 执行链路已备好:`api/services/knowledge_fs/app_execution_capability.py` 是 App 运行时
唯一入口admission → capability broker 签发 → `product_remote_http`
`KnowledgeFSAppSpaceJoinType.WORKFLOW` 已存在,`create_research_task()` 是完整参考实现。
- 绑定设施齐全:`app_binding_management.py`、`orphan_reconciler.py`、Console API
`/console/api/knowledge-fs/spaces/{id}/app-bindings`upsert/revoke/list
- 缺口 1`retrieval-tests` 未注册进 `api/knowledge-fs-product-operations.json`
(目前查询类只有 `createQuery`)。
- 缺口 2`retrieval-tests` 响应 items **无证据正文**(仅 nodeId/citation/score/sources
需网关侧新增 `includeText`
- 缺口 3`retrieval-tests` 请求体无 filtersKFS 管线内部支持,端点未暴露)。
- 节点注册机制:后端 `NODE_TYPE_CLASSES_MAPPING`type → version → classNode 子类自动注册);
前端 `BlockEnum` + `nodes/components.ts` 两个 Map + `workflow/constants.ts` 面板列表。
---
## 迭代 1网关侧——检索操作产品化knowledge-fs 仓库3-4 人日)
1. `RetrievalTestRequestSchema` 增加 `includeText: boolean`(默认 false与有界
`filters`(结构对齐管线内部 `normalizeRetrievalMetadataFilters` 支持的形态,显式上限)。
响应 items 增加 `text`(按 `maxTextCharsPerCandidate` 思路截断)。
`packages/api/src/retrieval-test-routes.ts` + `retrieval-test-handlers.ts` + 测试。
2. Capability v2 合同登记:`contracts/dify-capability-v2-operations.json` 新增操作
action `queries.retrieval_test`resource `knowledge_space`),跑
`scripts/export-capability-v2-operations.mjs`,补 `dify-capability-v2.test.ts` 断言。
参考样例2026-07-31 difyctl fs 命令的合同变更(同一套流程)。
3. OpenAPI 快照更新(`pnpm openapi:export:test`)。
4. 响应体量核算topK(≤100) × 截断后 text 的最大字节数必须低于产品操作限额
(同类操作多为 14MB超限则下调默认 text 上限。
**验收**:带 capability token 的 retrieval-tests 返回含 text/filters 生效的 items
合同测试与 OpenAPI 快照绿。
## 迭代 2Dify API 侧——产品操作 + 执行服务3 人日)
1. `api/knowledge-fs-product-operations.json` 注册 `retrieveEvidence`
POST `/knowledge-spaces/{id}/retrieval-tests`transport json限额对齐核算结果
同步 `api/knowledge-fs-contract.lock.json`
2. `services/knowledge_fs/product_dto.py``KnowledgeFSRetrievalTestPayload` /
`KnowledgeFSRetrievalTestResponse`mode/query/includeText/filtersitems 含
text/citation/score/sourcesmetrics 摘要含 mode/totalMs/degradationFlags
3. `app_execution_capability.py` 新增 `run_retrieval(run_context, caller_kind, resource,
payload)`,完整照 `create_research_task()` 模式operation ready 检查 → `issue()`
`execute_json` → DTO 校验)。
4. 单测照 `tests/.../test_knowledge_fs_capability.py`、`test_knowledge_fs_product_dto.py`
既有模式补齐。
**验收**:服务层以 `caller_kind=workflow` 对本地 KFS 完成一次真实检索冒烟。
## 迭代 3后端节点实现4-5 人日)
新目录 `api/core/workflow/nodes/knowledge_retrieval_v2/`
1. `entities.py``KnowledgeRetrievalV2NodeData`
- `type = "knowledge-retrieval-v2"`
- `control_space_ids: list[str]`Dify 侧 control_space_id非上游 space uuid
- `query_variable_selector`
- `mode: Literal["fast","deep","research"] | None`None=各空间跟随自己的默认);
- `top_n: int`(多空间合并后截断数);
- `metadata_filters`manual使用 KFS 固定字段合同,不复用旧 dataset 的通用条件)。
- 直接继承 BaseNode**不继承 LLMNode**v1 的历史包袱v2 无 single-retrieval 模式)。
2. `knowledge_retrieval_v2_node.py``version()="1"`。执行:解析 query 变量 → 逐空间有界并发
`run_retrieval` → 保留 KFS final score 做稳定合并 + topN → 组装输出。
3. `exc.py` 错误分类admission 拒绝(未绑定/权限撤销、KFS 不可用fail-closed 503
合同校验失败;检索为空不是错误。
4. **输出变量**(与前端 outputVars 声明严格一致):
- `result[]``{content, title, metadata: {citation: {document_id, document_version,
section_path, page_number, start_offset, end_offset, artifact_hash}, score, sources,
space_id}}`。content/title 命名对齐 v1保证下游 prompt 模板迁移成本最低citation 为
v2 增值结构。
- `metrics``{mode, total_ms, degradation_flags}`(供条件分支)。
5. 注册确认Node 子类进 lazy registry`node_factory.py` 无需特殊 init kwargs
(依赖经 service 获取,不像 agent 节点注入 backend client工作流校验 / DSL 导入导出
对该 type 的处理路径确认。
6. 单测mock `KnowledgeFSAppExecutionCapabilityService`,覆盖单/多空间、变量解析、
filters、空结果、错误路径、输出 schema。
**验收**curl 构造 DSL 可跑通含 v2 节点的 workflowsingle-step run 可用。
## 迭代 4绑定与生命周期2-3 人日)
1. 发布钩子:扫描 graph 中 v2 节点的 `control_space_ids`,逐个
`app_bindings.upsert(caller_kind=WORKFLOW)`;权限失败发布报错并指明空间。
2. **草稿运行 admission 语义**(本迭代最高风险项,建议与迭代 2 同步定义draft/single-step
运行时绑定可能尚未 upsert——方案二选一draft run 按需 upsert或提供 preview 专用
admission 放行。定义后补集成场景验证。
3. DSL 导入/跨环境迁移:`control_space_id` 环境相关,导入时校验存在性,缺失进 checklist
警告(对齐 v1 对 `dataset_ids` 的处理),不静默保留脏引用。
4. 生命周期验证:空间删除/成员变更 → admission 拒绝 → 节点确定性错误码;确认
发布精确同步会撤销已从 graph 移除的 workflow 绑定。`orphan_reconciler`
只负责 Space 生命周期孤儿,不承担 app graph 引用清理。
**验收**:发布→运行→撤权→运行失败→恢复→运行成功全链路行为确定;草稿运行语义有测试锁定。
## 迭代 5前端节点5-6 人日D1D7 定稿后即可与迭代 2-4 并行,先 mock 服务层)
1. 注册:`web/app/components/workflow/types.ts` 增 `KnowledgeRetrievalV2 =
'knowledge-retrieval-v2'``nodes/components.ts` 的 NodeComponentMap/PanelComponentMap
各一行;`workflow/constants.ts` 面板列表(置于 v1 旁);独立 icon与 v1 区分配色/角标)。
2. 新目录 `web/app/components/workflow/nodes/knowledge-retrieval-v2/`(对照 v1 结构:
`default.ts` / `node.tsx` / `panel.tsx` / `types.ts` / `use-config.ts` /
`use-single-run-form-params.ts`
- `default.ts`metaData、默认值mode 空)、`checkValid`query 变量 + ≥1 空间)。
- panel空间多选`GET /console/api/knowledge-fs/spaces`、query 变量选择器(复用
VarReferencePicker、mode 下拉research 标注高延迟高成本、manual metadata filters、
只读展示所选空间 retrieval profile 摘要topK/rerank/defaultMode——传达"检索配置在
空间侧")。
- `node.tsx`:空间名 chips + mode 徽标。
3. 门控workspace 未启用 KnowledgeFS`system-features-state.ts`)时节点不出现在面板。
4. 输出变量声明与运行详情outputVars 对齐后端;运行结果面板展示 citation
(文档名 + 章节路径 + 页码)——相对 v1 的体验升级重点。
5. i18nen-US / zh-Hans 全量 key其余语言英文兜底。
6. Vitestpanel 交互、checkValid、use-config按 frontend-testing 规范)。
**验收**:画布添加/配置/试运行/发布全通checklist 生效;未启用 KFS 的 workspace 不可见。
## 迭代 6可观测性2 人日)
1. `WorkflowNodeExecutionMetadataKey` 是上游闭合枚举,不强行塞入自定义 key。mode、
totalMs、candidateCounts、degradationFlags 落节点 `process_data.knowledge_fs`
同时将稳定子集作为 `metrics` 输出,运行详情可见且不污染全局元数据合同。
2. trace 贯通workflow trace id 经 `issue(trace_id=...)` 传入KFS 侧 metrics 可反查。
## 迭代 7测试收尾与发布3 人日)
1. 后端 integration 测试CI-only与前端 Vitest 全绿。当 `e2e/` 具备可重置的
KnowledgeFS 服务和预置文档 fixture 后,再启用“建空间→传文档→建 workflow→
v2 节点检索→断言输出” Cucumber 场景;本期不提交无可用 fixture 的永久 skip/
假绿场景,以 KFS route、Dify service、node 和 DSL fixture 的分层合同测试替代。
2. 含 v2 节点的 DSL 导出样例进测试 fixture防 schema 回归。
3. 文档:节点使用文档 + v1/v2 对比表数据源、配置归属、citation、模式差异
4. 发布策略:随 workspace 级 KnowledgeFS 开关走,不设独立 flag回滚 = 关空间侧开关,
节点运行 fail-closed 报 503错误文案给出指引。
---
## 依赖与并行
- 关键路径:迭代 1 → 2 → 3 → 4合同链串行
- 迭代 5 在设计决策定稿后即可并行mock 服务层)。
- 总量约 2226 人日;一前一后两人约三周到可发布。
## 风险清单(按优先级)
1. 草稿运行 admission 语义(迭代 4.2)——最易返工,提前到迭代 2 一起定义。
2. includeText 后响应体量触产品操作限额——迭代 1 内完成核算并定截断上限。
3. research 模式同步延迟——允许但默认不选,待 PageIndex research v2 落地后再放开宣传。
4. 跨空间分数合并可解释性——文档先行,避免用户拿跨空间分数做阈值分支。
5. 双节点并存的面板认知成本——命名与门控按 D1/迭代 5.3 执行;纯 greenfield 空间是否隐藏
v1 为待定产品决策,不阻塞开发。
## 后续项(明确不在本期)
- automatic metadata 过滤LLM 抽取条件)。
- 跨空间统一 rerank。
- workflow 检索空结果回流 KFS failed-query 质量体系(需网关侧记录开关,独立立项)。
- v1 → v2 迁移工具与 v1 退役计划。