概述
什么是流水线知识库?
流水线知识库(RAG Pipeline Knowledge Base) 是 Dify 中一种高级的知识库模式,它将文档处理流程转化为可视化的工作流(Workflow),允许用户自定义文档的解析、清洗、切片、索引等全流程。
核心特点
- 可视化工作流:通过拖拽方式构建文档处理流程
- 高度可定制:每个处理环节都可自定义配置
- 模板化管理:支持内置模板、自定义模板和导入导出
- 异步执行:使用 Celery 任务队列处理文档
- 状态追踪:完整记录每个节点的执行状态
适用场景
- 复杂文档处理需求:需要特殊的文档解析逻辑
- 多步骤数据清洗:需要多个清洗步骤的场景
- 自定义索引策略:需要特殊的向量化或索引方式
- 可复用处理流程:需要在多个知识库中复用同一套处理逻辑
核心概念
1. 运行模式(Runtime Mode)
Dify 中的知识库支持两种运行模式:
# api/models/dataset.py
runtime_mode = mapped_column(
db.String(255),
nullable=True,
server_default=db.text("'general'::character varying")
)
general:传统知识库模式,使用固定的处理流程rag_pipeline:流水线知识库模式,使用自定义工作流
2. Pipeline 实体
# api/models/dataset.py (Line 1274-1291)
class Pipeline(Base):
"""流水线实体"""
id = mapped_column(StringUUID, server_default=db.text("uuidv7()"))
tenant_id: Mapped[str] = mapped_column(StringUUID, nullable=False)
name = mapped_column(db.String(255), nullable=False)
description = mapped_column(sa.Text, nullable=False)
workflow_id = mapped_column(StringUUID, nullable=True) # 关联的工作流
is_public = mapped_column(sa.Boolean, nullable=False, server_default=db.text("false"))
is_published = mapped_column(sa.Boolean, nullable=False, server_default=db.text("false"))
created_by = mapped_column(StringUUID, nullable=True)
created_at = mapped_column(sa.DateTime, nullable=False)
updated_by = mapped_column(StringUUID, nullable=True)
updated_at = mapped_column(sa.DateTime, nullable=False)
核心字段说明:
workflow_id:指向具体的 Workflow,定义了文档处理流程is_published:标识流水线是否已发布(只有发布后才能处理文档)
3. Dataset 与 Pipeline 的关联
# api/models/dataset.py (Line 73)
pipeline_id = mapped_column(StringUUID, nullable=True)
# Dataset.is_published 属性 (Line 233-240)
@property
def is_published(self):
if self.pipeline_id:
pipeline = db.session.query(Pipeline).where(Pipeline.id == self.pipeline_id).first()
if pipeline:
return pipeline.is_published
return False
关联关系:
- 每个 Dataset 可以关联一个 Pipeline
- Dataset 的发布状态由其关联的 Pipeline 决定
- 只有
runtime_mode="rag_pipeline"的 Dataset 才会使用 Pipeline
4. 流水线模板
# api/services/rag_pipeline/pipeline_template/pipeline_template_type.py
class PipelineTemplateType(StrEnum):
REMOTE = "remote" # 远程模板(从市场获取)
DATABASE = "database" # 数据库模板
CUSTOMIZED = "customized" # 自定义模板
BUILTIN = "builtin" # 内置模板
模板类型:
- 内置模板:系统预设的通用文档处理流程
- 自定义模板:用户自行创建并保存的模板
- 数据库模板:存储在数据库中的模板
- 远程模板:从插件市场获取的模板
架构设计
整体架构图
数据模型关系
工作原理
1. 创建流水线知识库
流程图
源码实现
📍 源码位置: api/services/dataset_service.py -
DatasetService.create_empty_rag_pipeline_dataset
@staticmethod
def create_empty_rag_pipeline_dataset(
tenant_id: str,
rag_pipeline_dataset_create_entity: RagPipelineDatasetCreateEntity,
):
# 🔑 关键点1:生成唯一的知识库名称
if not rag_pipeline_dataset_create_entity.name:
datasets = db.session.query(Dataset).filter_by(tenant_id=tenant_id).all()
names = [dataset.name for dataset in datasets]
rag_pipeline_dataset_create_entity.name = generate_incremental_name(
names, "Untitled"
)
# 🔑 关键点2:创建 Pipeline 实体
pipeline = Pipeline(
tenant_id=tenant_id,
name=rag_pipeline_dataset_create_entity.name,
description=rag_pipeline_dataset_create_entity.description,
created_by=current_user.id,
)
db.session.add(pipeline)
db.session.flush()
# 🔑 关键点3:创建 Dataset 并关联 Pipeline
dataset = Dataset(
tenant_id=tenant_id,
name=rag_pipeline_dataset_create_entity.name,
description=rag_pipeline_dataset_create_entity.description,
permission=rag_pipeline_dataset_create_entity.permission,
provider="vendor",
runtime_mode="rag_pipeline", # 设置为流水线模式
icon_info=rag_pipeline_dataset_create_entity.icon_info.model_dump(),
created_by=current_user.id,
pipeline_id=pipeline.id, # 关联 Pipeline
)
db.session.add(dataset)
db.session.commit()
return dataset
2. 配置工作流
工作流结构
流水线的核心是 Workflow,它定义了文档处理的完整流程:
# 工作流示例(YAML 格式)
version: "0.1"
kind: "rag-pipeline"
environment_variables: []
conversation_variables: []
graph:
nodes:
- id: "datasource"
type: "datasource"
data:
title: "数据源"
type: "datasource"
- id: "document_extractor"
type: "document-extractor"
data:
title: "文档解析"
variable_selector:
- "datasource"
- "output"
- id: "text_processing"
type: "text-processing"
data:
title: "文本清洗"
variable_selector:
- "document_extractor"
- "text"
- id: "knowledge_retrieval"
type: "knowledge-retrieval"
data:
title: "向量化索引"
variable_selector:
- "text_processing"
- "output"
edges:
- source: "datasource"
target: "document_extractor"
- source: "document_extractor"
target: "text_processing"
- source: "text_processing"
target: "knowledge_retrieval"
同步和发布流程
📍 源码位置: api/services/rag_pipeline/rag_pipeline.py -
RagPipelineService.publish_workflow
def publish_workflow(
self,
pipeline_id: str,
):
"""
发布工作流
:param pipeline_id: pipeline id
"""
# 🔑 关键点1:验证工作流存在
pipeline = db.session.query(Pipeline).where(Pipeline.id == pipeline_id).first()
if not pipeline:
raise ValueError("Pipeline not found")
# 🔑 关键点2:从草稿复制到正式版本
draft_workflow = (
db.session.query(Workflow)
.where(
Workflow.tenant_id == pipeline.tenant_id,
Workflow.type == WorkflowType.RAG_PIPELINE,
Workflow.app_id == pipeline.id,
Workflow.version == "draft",
)
.first()
)
if not draft_workflow:
raise ValueError("Draft workflow not found")
# 🔑 关键点3:更新 Pipeline 状态
pipeline.workflow_id = draft_workflow.id
pipeline.is_published = True
pipeline.updated_by = current_user.id
pipeline.updated_at = datetime.now(UTC).replace(tzinfo=None)
db.session.commit()
3. 文档处理执行
完整执行流程
任务队列处理
📍 源码位置: api/tasks/rag_pipeline/rag_pipeline_run_task.py -
rag_pipeline_run_task
@shared_task(queue="pipeline")
def rag_pipeline_run_task(
rag_pipeline_invoke_entities_file_id: str,
tenant_id: str,
):
"""
异步执行 RAG Pipeline 任务
:param rag_pipeline_invoke_entities_file_id: 包含序列化实体的文件 ID
:param tenant_id: 租户 ID
"""
try:
# 🔑 关键点1:从文件中读取任务实体
rag_pipeline_invoke_entities_content = FileService(db.engine).get_file_content(
rag_pipeline_invoke_entities_file_id
)
rag_pipeline_invoke_entities = json.loads(rag_pipeline_invoke_entities_content)
# 🔑 关键点2:使用线程池并发执行(最大 10 个工作线程)
with ThreadPoolExecutor(max_workers=10) as executor:
futures = []
for rag_pipeline_invoke_entity in rag_pipeline_invoke_entities:
# 提交单个文档处理任务到线程池
future = executor.submit(
run_single_rag_pipeline_task,
rag_pipeline_invoke_entity,
flask_app
)
futures.append(future)
# 等待所有任务完成
for future in futures:
try:
future.result()
except Exception:
logging.exception("Error in pipeline task")
finally:
# 🔑 关键点3:处理队列中的下一个任务
tenant_self_pipeline_task_queue = f"tenant_self_pipeline_task_queue:{tenant_id}"
next_file_id = redis_client.rpop(tenant_self_pipeline_task_queue)
if next_file_id:
# 继续处理下一个任务
rag_pipeline_run_task.delay(
rag_pipeline_invoke_entities_file_id=next_file_id,
tenant_id=tenant_id,
)
else:
# 队列为空,清除标志
redis_client.delete(f"tenant_pipeline_task:{tenant_id}")
单个文档处理
📍 源码位置: api/tasks/rag_pipeline/rag_pipeline_run_task.py -
run_single_rag_pipeline_task
def run_single_rag_pipeline_task(rag_pipeline_invoke_entity: Mapping[str, Any], flask_app):
"""在 Flask 应用上下文中运行单个 RAG Pipeline 任务"""
with flask_app.app_context():
# 🔑 关键点1:加载实体和用户信息
rag_pipeline_invoke_entity_model = RagPipelineInvokeEntity.model_validate(
rag_pipeline_invoke_entity
)
with Session(db.engine) as session:
account = session.query(Account).where(
Account.id == user_id
).first()
pipeline = session.query(Pipeline).where(
Pipeline.id == pipeline_id
).first()
workflow = session.query(Workflow).where(
Workflow.id == pipeline.workflow_id
).first()
# 🔑 关键点2:创建工作流执行仓储
workflow_execution_repository = (
DifyCoreRepositoryFactory.create_workflow_execution_repository(
session_factory=session_factory,
user=account,
triggered_from=WorkflowRunTriggeredFrom.RAG_PIPELINE_RUN,
)
)
# 🔑 关键点3:执行流水线
from core.app.apps.pipeline.pipeline_generator import PipelineGenerator
pipeline_generator = PipelineGenerator()
pipeline_generator._generate(
pipeline=pipeline,
workflow_id=workflow_id,
user=account,
application_generate_entity=entity,
invoke_from=InvokeFrom.PUBLISHED,
workflow_execution_repository=workflow_execution_repository,
streaming=streaming,
)
4. 节点执行机制
每个工作流节点的执行遵循统一的接口:
# 节点基类接口
class Node:
def _run(self) -> Generator[NodeRunResult, None, None]:
"""
执行节点逻辑
:return: 节点执行结果生成器
"""
pass
常见节点类型:
| 节点类型 | 功能 | 输入 | 输出 |
|---|---|---|---|
datasource | 数据源 | 文件/URL | 原始数据 |
document-extractor | 文档解析 | 原始数据 | 结构化文本 |
text-processing | 文本清洗 | 文本 | 清洗后文本 |
text-splitter | 文本切片 | 文本 | 文本片段列表 |
knowledge-indexing | 向量化索引 | 文本片段 | 索引结果 |
使用场景
场景 1:PDF 文档的高级处理
需求:处理包含表格和图片的复杂 PDF,需要提取表格数据并识别图片中的文字。
解决方案:
graph:
nodes:
- id: "datasource"
type: "datasource"
- id: "pdf_extractor"
type: "document-extractor"
data:
extraction_method: "ocr" # 使用 OCR
extract_tables: true # 提取表格
extract_images: true # 提取图片
- id: "table_processor"
type: "code"
data:
code: |
# 自定义表格处理逻辑
tables = inputs['tables']
processed_tables = []
for table in tables:
# 转换为 Markdown 格式
md_table = convert_to_markdown(table)
processed_tables.append(md_table)
return {'output': processed_tables}
- id: "text_merger"
type: "template-transform"
data:
template: |
正文内容:
{{ text }}
表格数据:
{{ tables }}
- id: "semantic_splitter"
type: "text-splitter"
data:
split_method: "semantic"
chunk_size: 1000
场景 2:多语言文档处理
需求:处理多语言文档,需要识别语言并分别处理。
解决方案:
graph:
nodes:
- id: "language_detector"
type: "llm"
data:
prompt: "检测以下文本的语言,只返回语言代码:\n{{ text }}"
model: "gpt-4"
- id: "language_router"
type: "if-else"
data:
conditions:
- variable: "{{ language_detector.output }}"
comparison: "equals"
value: "zh"
target: "chinese_processor"
- variable: "{{ language_detector.output }}"
comparison: "equals"
value: "en"
target: "english_processor"
- id: "chinese_processor"
type: "text-processing"
data:
segmentation: "jieba" # 中文分词
- id: "english_processor"
type: "text-processing"
data:
segmentation: "nltk" # 英文分词
场景 3:增量更新知识库
需求:定期从外部 API 获取数据并更新知识库。
解决方案:
graph:
nodes:
- id: "api_datasource"
type: "http-request"
data:
url: "https://api.example.com/articles"
method: "GET"
headers:
Authorization: "Bearer {{ env.API_KEY }}"
- id: "json_parser"
type: "code"
data:
code: |
import json
data = json.loads(inputs['response'])
articles = data['articles']
return {'articles': articles}
- id: "deduplication"
type: "code"
data:
code: |
# 去重逻辑:检查文档是否已存在
existing_docs = query_existing_documents()
new_articles = [
a for a in inputs['articles']
if a['id'] not in existing_docs
]
return {'new_articles': new_articles}
- id: "batch_indexing"
type: "iteration"
data:
input: "{{ deduplication.new_articles }}"
nodes:
- type: "knowledge-indexing"
使用方式
1. 通过控制台创建
步骤 1:创建空白流水线知识库
POST /console/api/datasets/rag/pipeline/empty-dataset
Content-Type: application/json
Authorization: Bearer <token>
{
"name": "我的流水线知识库",
"description": "自定义处理流程",
"permission": "only_me"
}
响应示例:
{
"id": "dataset-uuid",
"name": "我的流水线知识库",
"runtime_mode": "rag_pipeline",
"pipeline_id": "pipeline-uuid",
"is_published": false
}
步骤 2:配置工作流
POST /console/api/datasets/{dataset_id}/rag/pipeline/workflow/sync-draft
Content-Type: application/json
{
"graph": {
"nodes": [...],
"edges": [...]
}
}
步骤 3:发布流水线
POST /console/api/datasets/{dataset_id}/rag/pipeline/workflow/publish
2. 通过 YAML 导入
YAML 模板示例
version: "0.1"
kind: "rag-pipeline"
name: "PDF 处理流水线"
description: "专门处理 PDF 文档的流水线"
environment_variables:
- name: "OCR_API_KEY"
value: ""
description: "OCR 服务的 API Key"
graph:
nodes:
- id: "start"
type: "datasource"
data:
title: "数据源"
type: "datasource"
desc: "上传 PDF 文件"
- id: "pdf_parser"
type: "document-extractor"
data:
title: "PDF 解析"
variable_selector:
- "start"
- "output"
extraction_settings:
parser: "pdfplumber"
extract_images: true
ocr_enabled: true
- id: "text_cleaner"
type: "text-processing"
data:
title: "文本清洗"
variable_selector:
- "pdf_parser"
- "text"
rules:
- type: "remove_extra_spaces"
- type: "remove_urls"
- id: "chunker"
type: "text-splitter"
data:
title: "文本切片"
variable_selector:
- "text_cleaner"
- "output"
chunk_size: 800
chunk_overlap: 100
- id: "embedder"
type: "knowledge-indexing"
data:
title: "向量化"
variable_selector:
- "chunker"
- "chunks"
embedding_model:
provider: "openai"
model: "text-embedding-3-small"
edges:
- source: "start"
target: "pdf_parser"
- source: "pdf_parser"
target: "text_cleaner"
- source: "text_cleaner"
target: "chunker"
- source: "chunker"
target: "embedder"
导入 API
POST /console/api/datasets/rag/pipeline/dataset
Content-Type: application/json
{
"yaml_content": "<上面的 YAML 内容>"
}
3. 使用模板创建
获取可用模板列表
GET /console/api/datasets/rag/pipeline/templates?type=built-in&language=zh-CN
响应示例:
{
"templates": [
{
"id": "template-1",
"name": "通用文档处理",
"description": "适用于大多数文档类型",
"chunk_structure": "text",
"icon": {...}
},
{
"id": "template-2",
"name": "高精度 PDF 处理",
"description": "使用 OCR 和高级解析",
"chunk_structure": "text",
"icon": {...}
}
]
}
使用模板创建
POST /console/api/datasets/rag/pipeline/dataset
Content-Type: application/json
{
"template_id": "template-1",
"name": "基于模板的知识库",
"description": "使用内置模板创建"
}
源码解析
核心服务类
1. RagPipelineService
职责:流水线知识库的核心业务逻辑
关键方法:
class RagPipelineService:
def __init__(self, session_maker: sessionmaker | None = None):
"""初始化服务,注入仓储依赖"""
self._node_execution_service_repo = ...
self._workflow_run_repo = ...
def get_pipeline_templates(cls, type: str = "built-in") -> dict:
"""获取流水线模板列表"""
pass
def sync_draft_workflow(self, pipeline_id: str, graph: dict):
"""同步草稿工作流"""
pass
def publish_workflow(self, pipeline_id: str):
"""发布工作流,使其可以处理文档"""
pass
def run_draft_workflow_node(self, pipeline_id: str, node_id: str, inputs: dict):
"""运行单个节点(用于调试)"""
pass
def get_rag_pipeline_paginate_workflow_runs(self, pipeline_id: str, page: int):
"""获取流水线执行历史(分页)"""
pass
设计模式:
- 仓储模式:通过
_node_execution_service_repo和_workflow_run_repo分离数据访问逻辑 - 工厂模式:使用
PipelineTemplateRetrievalFactory创建不同类型的模板检索器
2. PipelineGenerator
职责:执行流水线,生成处理结果
核心流程:
class PipelineGenerator:
def generate(
self,
pipeline: Pipeline,
workflow: Workflow,
user: Union[Account, EndUser],
args: Mapping[str, Any],
invoke_from: InvokeFrom,
streaming: bool = True,
) -> Generator:
"""
生成流水线执行结果
执行流程:
1. 初始化工作流上下文
2. 创建变量池
3. 遍历工作流图的节点
4. 执行每个节点
5. 传递节点输出到下一个节点
6. 生成执行事件流
"""
# 初始化工作流入口
workflow_entry = WorkflowEntry(
workflow=workflow,
user=user,
invoke_from=invoke_from,
)
# 执行工作流
for event in workflow_entry.run(args):
yield event
执行策略:
- 流式执行:使用 Generator 实现流式输出
- 事件驱动:通过事件(Event)通知节点执行状态
- 错误处理:支持
continue-on-error和fail-branch策略
3. RagPipelineDslService
📍 源码位置: api/services/rag_pipeline/rag_pipeline_dsl_service.py
职责:处理流水线 DSL 的导入导出
关键功能:
class RagPipelineDslService:
def import_rag_pipeline(
self,
tenant_id: str,
yaml_content: str,
mode: ImportMode,
) -> RagPipelineImportInfo:
"""
导入 RAG Pipeline DSL
流程:
1. 解析 YAML 内容
2. 验证版本兼容性
3. 检查依赖项(模型、工具等)
4. 创建临时数据(待用户确认)
5. 返回导入信息
"""
pass
def export_rag_pipeline_dsl(
self,
dataset_id: str,
) -> str:
"""
导出 RAG Pipeline DSL
流程:
1. 获取 Pipeline 和 Workflow
2. 提取工作流图
3. 移除敏感信息
4. 生成 YAML 格式
"""
pass
def create_rag_pipeline_dataset(
self,
tenant_id: str,
rag_pipeline_dataset_create_entity: RagPipelineDatasetCreateEntity,
):
"""
从 YAML 直接创建流水线知识库
流程:
1. 导入 DSL
2. 自动确认导入
3. 创建 Dataset 和 Pipeline
4. 发布工作流
"""
pass
安全特性:
- 依赖检查:验证引用的模型、工具、插件是否可用
- 数据加密:对敏感配置进行 AES 加密
- 版本控制:检查 DSL 版本兼容性
执行流程关键代码
文档状态更新
# api/services/rag_pipeline/pipeline_generate_service.py
@classmethod
def update_document_status(cls, document_id: str):
"""更新文档状态为 waiting(等待处理)"""
document = db.session.query(Document).where(Document.id == document_id).first()
if document:
document.indexing_status = "waiting"
db.session.commit()
节点执行结果处理
# api/services/rag_pipeline/rag_pipeline.py
def _handle_node_run_result(
self,
node_id: str,
node_run_result: NodeRunResult,
workflow_run_id: str,
) -> dict:
"""
处理节点执行结果
:param node_id: 节点 ID
:param node_run_result: 节点执行结果
:param workflow_run_id: 工作流运行 ID
:return: 处理后的结果
"""
# 记录节点执行
node_execution = WorkflowNodeExecution(
id=str(uuid4()),
workflow_run_id=workflow_run_id,
node_id=node_id,
node_type=node_run_result.node_type,
title=node_run_result.title,
inputs=node_run_result.inputs,
outputs=node_run_result.outputs,
status=node_run_result.status,
error=node_run_result.error,
elapsed_time=node_run_result.elapsed_time,
)
# 保存到数据库
self._node_execution_service_repo.create(node_execution)
return {
"node_id": node_id,
"status": node_run_result.status,
"outputs": node_run_result.outputs,
}
配置说明
环境变量
# Celery 任务队列配置
CELERY_BROKER_URL=redis://localhost:6379/1
# 流水线任务队列
CELERY_PIPELINE_QUEUE=pipeline
# 最大并发工作线程数
RAG_PIPELINE_MAX_WORKERS=10
# 任务超时时间(秒)
RAG_PIPELINE_TASK_TIMEOUT=3600
数据库配置
确保以下表存在:
-- 流水线表
CREATE TABLE pipelines (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
tenant_id UUID NOT NULL,
name VARCHAR(255) NOT NULL,
description TEXT,
workflow_id UUID,
is_public BOOLEAN DEFAULT FALSE,
is_published BOOLEAN DEFAULT FALSE,
created_by UUID,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_by UUID,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 文档流水线执行日志
CREATE TABLE document_pipeline_execution_logs (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
pipeline_id UUID NOT NULL,
document_id UUID NOT NULL,
datasource_type VARCHAR(255) NOT NULL,
datasource_info TEXT NOT NULL,
datasource_node_id VARCHAR(255) NOT NULL,
input_data JSONB NOT NULL,
created_by UUID,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_doc_pipeline_exec_logs_doc_id
ON document_pipeline_execution_logs(document_id);
Workflow 类型配置
# api/models/workflow.py
class WorkflowType(StrEnum):
WORKFLOW = "workflow"
CHAT = "chat"
COMPLETION = "completion"
RAG_PIPELINE = "rag-pipeline" # 流水线类型
最佳实践
1. 模板化管理
建议:为不同类型的文档创建专用模板
# 创建自定义模板
rag_pipeline_service.publish_customized_pipeline_template(
pipeline_id=pipeline_id,
template_entity={
"name": "法律文档处理模板",
"description": "专门处理法律合同文档",
"chunk_structure": "qa", # Q&A 结构
"icon": {"icon": "⚖️", "icon_type": "emoji"},
"language": "zh-CN",
}
)
优势:
- 减少重复配置
- 统一处理标准
- 便于团队协作
2. 错误处理策略
配置节点错误处理:
nodes:
- id: "risky_operation"
type: "code"
data:
error_strategy: "continue" # 继续执行
on_error:
- type: "log"
message: "节点执行失败,已跳过"
- type: "email"
recipients: ["admin@example.com"]
最佳策略:
- 关键节点:使用
fail-branch,执行失败分支 - 非关键节点:使用
continue-on-error,记录日志但继续执行 - 数据质量检查:在切片前进行,失败则终止
3. 性能优化
3.1 批量处理
# 批量上传文档,减少任务调度开销
documents = [doc1, doc2, doc3, ...]
# 打包成一个任务
rag_pipeline_invoke_entities = [
{
"document_id": doc.id,
"pipeline_id": pipeline_id,
# ...
}
for doc in documents
]
# 序列化并提交
file_id = FileService.save_file(json.dumps(rag_pipeline_invoke_entities))
rag_pipeline_run_task.delay(file_id, tenant_id)
3.2 调整并发数
根据硬件资源调整线程池大小:
# api/tasks/rag_pipeline/rag_pipeline_run_task.py
# 修改 max_workers 参数
with ThreadPoolExecutor(max_workers=20) as executor: # 默认 10
# ...
建议配置:
- CPU 密集型任务(如文本处理):
max_workers = CPU 核心数 * 2 - IO 密集型任务(如 API 调用):
max_workers = 20-50
3.3 缓存策略
nodes:
- id: "expensive_operation"
type: "llm"
data:
cache_enabled: true
cache_ttl: 3600 # 缓存 1 小时
cache_key_template: "{{ document.hash }}"
4. 监控与告警
4.1 执行历史查询
# 获取流水线执行历史
workflow_runs = RagPipelineService().get_rag_pipeline_paginate_workflow_runs(
pipeline_id=pipeline_id,
page=1,
page_size=20,
)
for run in workflow_runs:
print(f"执行 ID: {run.id}")
print(f"状态: {run.status}")
print(f"开始时间: {run.created_at}")
print(f"耗时: {run.elapsed_time}s")
4.2 失败重试
# 重试失败的文档
RagPipelineService().retry_error_document(
dataset_id=dataset_id,
document_id=document_id,
)
4.3 监控指标
建议监控的关键指标:
| 指标 | 说明 | 告警阈值 |
|---|---|---|
| 任务队列长度 | tenant_self_pipeline_task_queue 的长度 | > 100 |
| 任务执行时间 | 单个文档处理耗时 | > 5 分钟 |
| 失败率 | 失败文档数 / 总文档数 | > 5% |
| 并发任务数 | 同时执行的任务数 | > max_workers |
5. 安全建议
5.1 敏感信息处理
environment_variables:
- name: "API_KEY"
value: "" # 不要在 DSL 中硬编码
description: "从环境变量或密钥管理服务获取"
5.2 访问控制
# 设置知识库权限
dataset.permission = DatasetPermissionEnum.PARTIAL_TEAM
# 指定可访问成员
DatasetPermissionService.update_partial_member_list(
tenant_id=tenant_id,
dataset_id=dataset_id,
partial_member_list=["user-1", "user-2"],
)
5.3 数据隔离
确保租户数据隔离:
# 所有查询都应包含 tenant_id
pipelines = db.session.query(Pipeline).where(
Pipeline.tenant_id == current_tenant_id
).all()
常见问题
Q1: 流水线一直处于"未发布"状态?
原因:工作流未正确同步或发布。
解决方案:
# 1. 检查工作流是否存在
draft_workflow = db.session.query(Workflow).where(
Workflow.app_id == pipeline_id,
Workflow.version == "draft"
).first()
if not draft_workflow:
# 2. 同步草稿工作流
RagPipelineService().sync_draft_workflow(
pipeline_id=pipeline_id,
graph={...}
)
# 3. 发布
RagPipelineService().publish_workflow(pipeline_id=pipeline_id)
Q2: 文档处理失败,如何查看详细错误?
查看节点执行日志:
node_executions = RagPipelineService().get_rag_pipeline_workflow_run_node_executions(
workflow_run_id=workflow_run_id
)
for execution in node_executions:
if execution.status == "failed":
print(f"节点: {execution.title}")
print(f"错误: {execution.error}")
Q3: 如何批量处理文档?
使用批量上传接口:
POST /console/api/datasets/{dataset_id}/documents/batch
Content-Type: multipart/form-data
files: [file1, file2, file3, ...]
系统会自动将它们打包成一个任务。
Q4: 流水线执行太慢?
优化方向:
- 增加并发数:修改
ThreadPoolExecutor(max_workers=20) - 优化节点逻辑:减少不必要的 API 调用
- 使用缓存:为重复操作启用缓存
- 拆分大文档:在切片前进行预处理
总结
流水线知识库是 Dify 提供的一种高级文档处理方式,通过可视化工作流实现了文档处理流程的完全自定义。
核心优势:
- ✅ 灵活性:可自由组合节点,适应各种复杂场景
- ✅ 可观测性:完整的执行日志和状态追踪
- ✅ 可复用性:通过模板实现流程复用
- ✅ 高性能:异步任务队列 + 并发执行
适用场景:
- 需要特殊文档解析逻辑
- 多步骤数据清洗
- 自定义索引策略
- 可复用处理流程
学习路径:
- 从内置模板开始,理解基本流程
- 修改模板,尝试添加自定义节点
- 创建完全自定义的流水线
- 发布为模板供团队使用
最后更新: 2026-01-16
基于代码版本: Dify 主分支(截至 2026-01-16)