【Dify(v1.2) 核心源码深入解析】App 模块:Entities、Features 和 Task Pipeline

重磅推荐专栏: 《大模型AIGC》 《课程大纲》 《知识星球》
本专栏致力于探索和讨论当今最前沿的技术趋势和应用领域,包括但不限于ChatGPT和Stable Diffusion等。我们将深入研究大型模型的开发和应用,以及与之相关的人工智能生成内容(AIGC)技术。通过深入的技术解析和实践经验分享,旨在帮助读者更好地理解和应用这些领域的最新进展

前言

Dify 是一个功能强大的 AI 应用开发框架,它通过模块化设计和灵活的任务处理机制,帮助开发者快速构建智能应用。在这篇文章中,我们将深入解析 Dify 的三个核心模块:Entities(实体)、Features(功能)和 Task Pipeline(任务管道)。通过详细的代码解读和示例,帮助你全面理解 Dify 的架构设计和实现细节。

一、Entities(实体)

1.1 概述

Entities 是 Dify 中用于表示核心数据结构的模块。它定义了各种实体类,用于封装应用生成、工作流、消息等数据。这些实体类是 Dify 的基础,为其他模块提供了统一的数据接口。

1.2 关键实体类

1.2.1 AppGenerateEntity

AppGenerateEntity 是 Dify 中最基础的实体类,用于表示应用生成的上下文信息。以下是它的关键字段和用途:

python 复制代码
class AppGenerateEntity(BaseModel):
    task_id: str  # 任务 ID
    app_config: Any  # 应用配置
    file_upload_config: Optional[FileUploadConfig] = None  # 文件上传配置
    inputs: Mapping[str, Any]  # 输入参数
    files: Sequence[File]  # 文件列表
    user_id: str  # 用户 ID
    stream: bool  # 是否流式响应
    invoke_from: InvokeFrom  # 调用来源
    call_depth: int = 0  # 调用深度
    extras: dict[str, Any] = Field(default_factory=dict)  # 额外参数
    trace_manager: Optional[TraceQueueManager] = None  # 跟踪管理器

用途AppGenerateEntity 是所有应用生成实体的基类,它为其他实体类提供了通用的字段和方法。

1.2.2 EasyUIBasedAppGenerateEntity

EasyUIBasedAppGenerateEntityAppGenerateEntity 的子类,专门用于 EasyUI 基础的应用生成。它增加了模型配置和查询字段:

python 复制代码
class EasyUIBasedAppGenerateEntity(AppGenerateEntity):
    app_config: EasyUIBasedAppConfig  # 应用配置
    model_conf: ModelConfigWithCredentialsEntity  # 模型配置
    query: Optional[str] = None  # 查询字符串

用途:用于封装 EasyUI 应用的生成上下文,提供模型配置和查询支持。

1.2.3 WorkflowAppGenerateEntity

WorkflowAppGenerateEntity 是用于工作流应用生成的实体类,它增加了工作流运行 ID 和单次迭代/循环运行的配置:

python 复制代码
class WorkflowAppGenerateEntity(AppGenerateEntity):
    app_config: WorkflowUIBasedAppConfig  # 工作流应用配置
    workflow_run_id: str  # 工作流运行 ID

    class SingleIterationRunEntity(BaseModel):
        node_id: str  # 节点 ID
        inputs: dict  # 输入参数

    single_iteration_run: Optional[SingleIterationRunEntity] = None  # 单次迭代运行配置

    class SingleLoopRunEntity(BaseModel):
        node_id: str  # 节点 ID
        inputs: dict  # 输入参数

    single_loop_run: Optional[SingleLoopRunEntity] = None  # 单次循环运行配置

用途:用于封装工作流应用的生成上下文,支持单次迭代和循环运行的配置。

1.3 类图

以下是 Dify 中实体类的继承关系图:

classDiagram class AppGenerateEntity { +task_id: str +app_config: Any +file_upload_config: FileUploadConfig +inputs: Mapping[str, Any] +files: Sequence[File] +user_id: str +stream: bool +invoke_from: InvokeFrom +call_depth: int +extras: dict[str, Any] +trace_manager: TraceQueueManager } class EasyUIBasedAppGenerateEntity { +app_config: EasyUIBasedAppConfig +model_conf: ModelConfigWithCredentialsEntity +query: str } class WorkflowAppGenerateEntity { +app_config: WorkflowUIBasedAppConfig +workflow_run_id: str +single_iteration_run: SingleIterationRunEntity +single_loop_run: SingleLoopRunEntity } AppGenerateEntity <|-- EasyUIBasedAppGenerateEntity AppGenerateEntity <|-- WorkflowAppGenerateEntity

1.4 使用示例

python 复制代码
# 初始化 EasyUIBasedAppGenerateEntity
app_generate_entity = EasyUIBasedAppGenerateEntity(
    task_id="task-123",
    app_config=easy_ui_config,
    model_conf=model_config,
    query="Hello, Dify!",
    inputs={"name": "John"},
    files=[],
    user_id="user-123",
    stream=True,
    invoke_from=InvokeFrom.WEB_APP,
)

# 使用实体类生成应用
app_generator = AppGenerator(app_generate_entity)
response = app_generator.generate()

二、Features(功能)

2.1 概述

Features 模块提供了 Dify 的扩展功能,用于增强应用的特定能力。这些功能通常以独立的类实现,可以灵活地集成到任务管道中。

2.2 关键功能类

2.2.1 AnnotationReplyFeature

AnnotationReplyFeature 用于处理注释回复功能。它通过向量数据库查询相关的注释,并返回给用户:

python 复制代码
class AnnotationReplyFeature:
    def query(
        self,
        app_record: App,
        message: Message,
        query: str,
        user_id: str,
        invoke_from: InvokeFrom
    ) -> Optional[MessageAnnotation]:
        # 查询注释设置
        annotation_setting = db.session.query(AppAnnotationSetting).filter(
            AppAnnotationSetting.app_id == app_record.id
        ).first()

        if not annotation_setting:
            return None

        # 查询向量数据库
        vector = Vector(dataset, attributes=["doc_id", "annotation_id", "app_id"])
        documents = vector.search_by_vector(
            query=query, top_k=1, score_threshold=score_threshold
        )

        if documents and documents[0].metadata:
            annotation_id = documents[0].metadata["annotation_id"]
            annotation = AppAnnotationService.get_annotation_by_id(annotation_id)
            return annotation

        return None

用途:通过向量数据库查询注释,并返回匹配的注释内容。

2.2.2 HostingModerationFeature

HostingModerationFeature 用于内容审核功能。它检查生成的文本是否符合内容安全策略:

python 复制代码
class HostingModerationFeature:
    def check(
        self,
        application_generate_entity: EasyUIBasedAppGenerateEntity,
        prompt_messages: list[PromptMessage]
    ) -> bool:
        # 提取文本内容
        text = ""
        for prompt_message in prompt_messages:
            if isinstance(prompt_message.content, str):
                text += prompt_message.content + "\n"

        # 调用内容审核服务
        moderation_result = moderation.check_moderation(
            tenant_id=application_generate_entity.app_config.tenant_id,
            model_config=application_generate_entity.model_conf,
            text=text
        )

        return moderation_result

用途:检查生成的文本是否符合内容安全策略,确保输出内容的安全性。

2.3 流程图

以下是 AnnotationReplyFeature 的工作流程:

flowchart TD A[接收查询请求] --> B[查询注释设置] B --> C{是否存在注释设置} C -->|是| D[查询向量数据库] C -->|否| E[返回空结果] D --> F{是否存在匹配注释} F -->|是| G[返回注释内容] F -->|否| E[返回空结果]

2.4 使用示例

python 复制代码
# 初始化 AnnotationReplyFeature
annotation_feature = AnnotationReplyFeature()

# 查询注释回复
annotation = annotation_feature.query(
    app_record=app,
    message=message,
    query="How to use Dify?",
    user_id="user-123",
    invoke_from=InvokeFrom.WEB_APP
)

if annotation:
    print(f"Annotation reply: {annotation.content}")
else:
    print("No annotation found.")

三、Task Pipeline(任务管道)

3.1 概述

Task Pipeline 是 Dify 的核心模块,负责处理任务的生成、执行和响应。它通过事件驱动的方式,将任务分解为多个步骤,并逐步处理每个步骤。

3.2 关键类和方法

3.2.1 BasedGenerateTaskPipeline

BasedGenerateTaskPipeline 是任务管道的基础类,提供了任务处理的通用逻辑:

python 复制代码
class BasedGenerateTaskPipeline:
    def __init__(
        self,
        application_generate_entity: AppGenerateEntity,
        queue_manager: AppQueueManager,
        stream: bool,
    ) -> None:
        self._application_generate_entity = application_generate_entity
        self._queue_manager = queue_manager
        self._start_at = time.perf_counter()
        self._output_moderation_handler = self._init_output_moderation()
        self._stream = stream

    def _handle_error(self, *, event: QueueErrorEvent, session: Session | None = None, message_id: str = ""):
        # 处理错误事件
        logger.debug("error: %s", event.error)
        e = event.error
        err: Exception

        if isinstance(e, InvokeAuthorizationError):
            err = InvokeAuthorizationError("Incorrect API key provided")
        elif isinstance(e, InvokeError | ValueError):
            err = e
        else:
            err = Exception(e.description if getattr(e, "description", None) is not None else str(e))

        return err

    def _error_to_stream_response(self, e: Exception):
        # 将错误转换为流式响应
        return ErrorStreamResponse(task_id=self._application_generate_entity.task_id, err=e)

用途:提供任务处理的基础逻辑,包括错误处理和流式响应生成。

3.2.2 EasyUIBasedGenerateTaskPipeline

EasyUIBasedGenerateTaskPipelineBasedGenerateTaskPipeline 的子类,专门用于处理 EasyUI 基础的任务:

python 复制代码
class EasyUIBasedGenerateTaskPipeline(BasedGenerateTaskPipeline, MessageCycleManage):
    def __init__(
        self,
        application_generate_entity: Union[
            ChatAppGenerateEntity, CompletionAppGenerateEntity, AgentChatAppGenerateEntity
        ],
        queue_manager: AppQueueManager,
        conversation: Conversation,
        message: Message,
        stream: bool,
    ) -> None:
        super().__init__(
            application_generate_entity=application_generate_entity,
            queue_manager=queue_manager,
            stream=stream,
        )
        self._model_config = application_generate_entity.model_conf
        self._app_config = application_generate_entity.app_config

        self._conversation_id = conversation.id
        self._conversation_mode = conversation.mode

        self._message_id = message.id
        self._message_created_at = int(message.created_at.timestamp())

        self._task_state = EasyUITaskState(
            llm_result=LLMResult(
                model=self._model_config.model,
                prompt_messages=[],
                message=AssistantPromptMessage(content=""),
                usage=LLMUsage.empty_usage(),
            )
        )

    def process(self) -> Union[
        ChatbotAppBlockingResponse,
        CompletionAppBlockingResponse,
        Generator[Union[ChatbotAppStreamResponse, CompletionAppStreamResponse], None, None],
    ]:
        # 处理任务
        generator = self._wrapper_process_stream_response(trace_manager=self._application_generate_entity.trace_manager)
        if self._stream:
            return self._to_stream_response(generator)
        else:
            return self._to_blocking_response(generator)

用途:处理 EasyUI 应用的任务生成和响应,支持流式和阻塞式响应。

3.3 时序图

以下是任务管道的执行流程时序图:

sequenceDiagram participant 用户 participant 任务管道 participant 队列管理器 participant 数据库 用户->>任务管道: 发起任务请求 任务管道->>队列管理器: 注册任务 队列管理器->>任务管道: 返回任务 ID 任务管道->>数据库: 保存任务状态 数据库-->>任务管道: 返回保存结果 任务管道->>队列管理器: 监听事件 队列管理器->>任务管道: 发送事件 任务管道->>任务管道: 处理事件 任务管道->>用户: 返回响应

3.4 使用示例

python 复制代码
# 初始化任务管道
task_pipeline = EasyUIBasedGenerateTaskPipeline(
    application_generate_entity=app_generate_entity,
    queue_manager=queue_manager,
    conversation=conversation,
    message=message,
    stream=True
)

# 处理任务
response = task_pipeline.process()

# 处理流式响应
if isinstance(response, Generator):
    for stream_response in response:
        print(f"Stream response: {stream_response}")
else:
    print(f"Blocking response: {response}")

四、总结

通过本文的详细解读,我们深入了解了 Dify 的三个核心模块:Entities、Features 和 Task Pipeline。这些模块共同构成了 Dify 的核心架构,为开发者提供了强大的功能和灵活的扩展能力。

  • Entities:提供了核心数据结构,用于封装应用生成、工作流和消息等数据。
  • Features:提供了扩展功能,如注释回复和内容审核,增强了应用的能力。
  • Task Pipeline:作为核心任务处理模块,通过事件驱动的方式处理任务生成和响应。

希望本文能帮助你更好地理解和使用 Dify,构建出更强大的 AI 应用!

相关推荐
程序猿chen几秒前
JVM考古现场(二十四):逆熵者·时间晶体的永恒之战
java·jvm·git·后端·程序人生·java-ee·改行学it
AronTing2 分钟前
单例模式:确保唯一实例的设计模式
java·javascript·后端
AronTing10 分钟前
模板方法模式:定义算法骨架的设计模式
java·后端·面试
AronTing14 分钟前
迭代器模式:统一数据遍历方式的设计模式
java·后端·面试
AronTing14 分钟前
策略模式:动态切换算法的设计智慧
java·后端·面试
爱的叹息15 分钟前
查看Spring Boot项目所有配置信息的几种方法,包括 Actuator端点、日志输出、代码级获取 等方式,附带详细步骤和示例
java·spring boot·后端
量子位31 分钟前
挤爆字节服务器的 Agent 到底啥水平?一手实测来了
人工智能·aigc
量子位32 分钟前
狸谱 App 负责人一休:从 “叫爸爸” 小游戏到百万月活 AI 爆款,社交传播有这些底层逻辑丨中国 AIGC 产业峰会
人工智能·aigc
眠修33 分钟前
Python 简介与入门
开发语言·python
机器之心33 分钟前
ICLR 2025 Oral | 训练LLM,不只是多喂数据,PDS框架给出最优控制理论选择
人工智能