Flujo de trabajo autónomo de orientación ambulatoria (chatflow) en Dify

Nota: Este artículo utiliza Dify v0.7.2.

Este flujo de chat muestra cómo construir un chatbot para la orientación de pacientes externos que pueda recopilar datos del paciente a través de la web o de un diálogo de voz. Entendido de forma sencilla, esto significa que se ofrece al paciente una recomendación para un departamento basada en la información del paciente (edad, sexo y síntomas).

I. Pensamiento de flujo de trabajo

1. Captura de pantalla del flujo de trabajo

Captura de pantalla del flujo de trabajo completo de la orientación ambulatoria, que se muestra a continuación:

Dify中自带的门诊导诊工作流(chatflow)

2. Pseudoflujograma del flujo de trabajo

El objetivo del flujo de trabajo de orientación ambulatoria es recomendar un departamento a un paciente en función de la edad, el sexo y los síntomas que éste introduzca. En la primera ronda de diálogo, dado que el paciente puede introducir toda o parte de la información a la vez, se utiliza el nodo "Extractor de parámetros" para extraer el sexo, el síntoma y la edad de la primera entrada del paciente. La variable de diálogo es_primer_mensaje se establece en 0 mediante el nodo "Asignación de variables".

3. Problemas 1

Durante las siguientes rondas de diálogo, sólo se reconoce 1 tipo de información de campo a la vez, aunque el paciente puede proporcionar múltiples campos, reconociéndose los campos en el orden de edad, sexo y síntomas.

Dify中自带的门诊导诊工作流(chatflow)

4. Problemas 2

Si ya se ha recomendado un departamento basándose en la información del paciente, al volver a introducir cualquier información se recomendará el último departamento. Como el campo de departamento no está vacío, se sigue el proceso de respuesta directa.

Dify中自带的门诊导诊工作流(chatflow)

II. Variables de la sesión

La variable de sesión se utiliza para almacenar información contextual necesaria para LLM, como las preferencias del usuario, el historial de diálogos, etc. Es de lectura-escritura. Las variables de sesión están orientadas a escenarios de diálogo multi-ronda, por lo que las variables de sesión sólo están disponibles para aplicaciones de tipo Chatflow (Chat Assistant -> Workflow Orchestration).

1.variable de sesióntipo de datos

(1) Cadena

(2) Número

(3) Objeto

(4) Array[cadena] matriz de cadenas

(5) Array[number] Conjunto de números

(6) Array[object] Conjunto de objetos

2.variable de sesióncaracterización

(1) Las variables de sesión pueden ser referenciadas globalmente dentro de la mayoría de los nodos;

(2) La escritura de variables de sesión requiere el uso de la funciónasignación variableNodos;

(3) Las variables de sesión son de lectura-escritura.

3. Variables de sesión definidas en este flujo de trabajo

Las cinco variables de sesión definidas para este flujo de trabajo son si se trata de la primera ronda de diálogo, la edad, el sexo, los síntomas y el departamento.

Dify中自带的门诊导诊工作流(chatflow)

III. Interfaces relacionadas con el flujo de trabajo

1. Obtener la interfaz del flujo de trabajo

(1) Localización del código fuente

  • Ubicación del código fuente: dedify-0.7.2\api\controllers\console\app\workflow.py
  • Ubicación del código fuente: dedify-0.7.2\api\services\workflow_service.py

(2) Obtención de operaciones de flujo de trabajo

http://localhost:5001/console/api/apps/3c309371-54f6-4bfb-894a-4193b189ffa5/workflows/draft. donde borrador, como borrador, indica depuración en la página de flujo de trabajo.

Dify中自带的门诊导诊工作流(chatflow)

(3) Adquisición de aplicaciones de flujo de trabajo

El flujo de trabajo almacena un registro en la tabla de datos de flujos de trabajo. La versión es ahora borrador y cada vez que se publica un flujo de trabajo, se inserta un registro en esa tabla. Como se muestra a continuación:

Dify中自带的门诊导诊工作流(chatflow)

(4) Estructura de datos del flujo de trabajo

A continuación se muestra la estructura de datos del flujo de trabajo devuelta por la interfaz:

class Workflow(db.Model):
__tablename__ = 'workflows'
__table_args__ = (
db.PrimaryKeyConstraint('id', name='workflow_pkey'),
db.Index('workflow_version_idx', 'tenant_id', 'app_id', 'version'),
)
id: Mapped[str] = db.Column(StringUUID, server_default=db.text('uuid_generate_v4()'))
tenant_id: Mapped[str] = db.Column(StringUUID, nullable=False)
app_id: Mapped[str] = db.Column(StringUUID, nullable=False)
type: Mapped[str] = db.Column(db.String(255), nullable=False)
version: Mapped[str] = db.Column(db.String(255), nullable=False)
graph: Mapped[str] = db.Column(db.Text)
features: Mapped[str] = db.Column(db.Text)
created_by: Mapped[str] = db.Column(StringUUID, nullable=False)
created_at: Mapped[datetime] = db.Column(db.DateTime, nullable=False, server_default=db.text('CURRENT_TIMESTAMP(0)'))
updated_by: Mapped[str] = db.Column(StringUUID)
updated_at: Mapped[datetime] = db.Column(db.DateTime)
_environment_variables: Mapped[str] = db.Column('environment_variables', db.Text, nullable=False, server_default='{}')
_conversation_variables: Mapped[str] = db.Column('conversation_variables', db.Text, nullable=False, server_default='{}')

2. Actualizar las interfaces de flujo de trabajo

(1) Localización del código fuente

  • Source Location: dedify-0.7.2\web\app\components\workflow\hooks\use-nodes-sync-draft.ts
  • Ubicación del código fuente: dedify-0.7.2\web\service\workflow.ts

(2) Actualizar las operaciones del flujo de trabajo

http://localhost:5001/console/api/apps/3c309371-54f6-4bfb-894a-4193b189ffa5/workflows/draft.

Dify中自带的门诊导诊工作流(chatflow)

(3) Actualizar el código front-end del flujo de trabajo

Debido al framework React Flow utilizado en el front-end del flujo de trabajo de Dify, se especula que se pueden realizar operaciones POST, como añadir, eliminar y cambiar, cuando el flujo de trabajo cambia. A través de los logs en la Consola del back-end, se encontró que la llamada a la funciónworkflows/draft?_token=::

Dify中自带的门诊导诊工作流(chatflow)

aprobar (una factura o inspección, etc.)workflows/draft?_token=Buscando en el código del front-end sólo encontré un lugar para usarlo, y debe ser aquí.

Dify中自带的门诊导诊工作流(chatflow)

Dado que se realiza la operación POST, debe haber un parámetro Payload, correcto, y el parámetro workflow se encuentra en ese archivo.

Dify中自带的门诊导诊工作流(chatflow)

Cuando la dependenciagetPostParamsCuando se produce un cambio, se ejecuta de forma asíncronasyncWorkflowDraft(postParams).

Dify中自带的门诊导诊工作流(chatflow)

(indica relación causal)syncWorkflowDraft(postParams)La llamada real es POST. como se muestra a continuación:

Dify中自带的门诊导诊工作流(chatflow)

(4) Resumen de las funciones del flujo de trabajo

derechadify-0.7.2\web\service\workflow.tsLas funciones en se resumen del siguiente modo:

número de serienombre de la funciónfunción funciónParámetros y explicaciones
1fetchWorkflowDraftObtén el borrador del flujo de trabajo.url: Cadena, la URL de la solicitud.
2syncWorkflowDraftSincronice los borradores del flujo de trabajo.url: Cadena, la URL de la solicitud.params: objeto, los parámetros de la solicitud, que contiene el graphyfeaturesyenvironment_variables responder cantando conversation_variables.
3fetchNodesDefaultConfigsObtener la configuración por defecto del nodo.url: Cadena, la URL de la solicitud.
4fetchWorkflowRunHistoryObtener el historial de ejecución del flujo de trabajo.url: Cadena, la URL de la solicitud.
5fetcChatRunHistoryObtener el historial de chats.url: Cadena, la URL de la solicitud.
6singleNodeRunEjecuta un único nodo.appId: String, ID de la aplicación.nodeId: String, el ID del nodo.params: Objeto, parámetros de la solicitud.
7getIterationSingleNodeRunUrlObtiene la URL de la iteración ejecutada para un único nodo.isChatFlow: Valor booleano que indica si se trata o no de un flujo de chat.appId: String, ID de la aplicación.nodeId: String, el ID del nodo.
8publishWorkflowPublica un flujo de trabajo.url: Cadena, la URL de la solicitud.
9fetchPublishedWorkflowObtener flujos de trabajo publicados.url: Cadena, la URL de la solicitud.
10stopWorkflowRunDetener la ejecución del flujo de trabajo.url: Cadena, la URL de la solicitud.
11fetchNodeDefaultObtener la configuración por defecto del nodo.appId: String, ID de la aplicación.blockTypeValor de enumeración, tipo de nodo.queryObjeto, opcional, parámetro de consulta.
12updateWorkflowDraftFromDSLActualizar los borradores de flujo de trabajo de DSL.appId: String, ID de la aplicación.data: Cadena, Datos DSL.
13fetchCurrentValueOfConversationVariableObtiene el valor actual de la variable de sesión.url: Cadena, la URL de la solicitud.params: objeto, los parámetros de la solicitud, que contiene el conversation_id.

3. Aplicación del flujo de trabajo

Referencia a laImplementación de procesos de operaciones de creación, actualización, ejecución y eliminación de ChatflowLa sección "Implementación de Chatflow" en [6].

4. Publicación de flujos de trabajo

(1) Localización del código fuente

  • Ubicación del código fuente: dedify-0.7.2\api\controllers\console\app\workflow.py
  • Ubicación del código fuente: dedify-0.7.2\api\services\workflow_service.py
  • Ubicación de la fuente: dedify-0.7.2\api\events\event_handlers\update_app_dataset_join_when_app_published_workflow_updated.py

(2) Interfaz de publicación de flujos de trabajo

Se ejecuta al hacer clic en Publicar flujo de trabajohttp://localhost:5001/console/api/apps/3c309371-54f6-4bfb-894a-4193b189ffa5/workflows/publishInterfaz.

Dify中自带的门诊导诊工作流(chatflow)

Consiste principalmente en crear un nuevo flujo de trabajo y activar el evento de flujo de trabajo de la aplicación. Como se muestra a continuación:

Dify中自带的门诊导诊工作流(chatflow)

(3) Creación de un nuevo registro de flujo de trabajo

Esto consiste principalmente en crear un nuevo registro de flujo de trabajo donde el contenido del campo versión es 2024-09-07 09:11:25.894535. indicando que el flujo de trabajo ha sido publicado, no borrador (el flujo de trabajo no ha sido publicado y todavía está siendo depurado en el lienzo de flujo de trabajo). Como se muestra a continuación:

Dify中自带的门诊导诊工作流(chatflow)

(4) implementación del evento app_published_workflow_was_updated

@app_published_workflow_was_updated.connect
def handle(sender, **kwargs):
app = sender
published_workflow = kwargs.get("published_workflow")
published_workflow = cast(Workflow, published_workflow)
dataset_ids = get_dataset_ids_from_workflow(published_workflow)  # 从工作流中获取数据集ID
app_dataset_joins = db.session.query(AppDatasetJoin).filter(AppDatasetJoin.app_id == app.id).all()  # 获取应用数据集关联
removed_dataset_ids = []  # 用于存储移除的数据集ID
if not app_dataset_joins:  # 如果没有应用数据集关联
added_dataset_ids = dataset_ids  # 添加数据集ID
else:  # 如果有应用数据集关联
old_dataset_ids = set()  # 用于存储旧的数据集ID
for app_dataset_join in app_dataset_joins:  # 遍历应用数据集关联
old_dataset_ids.add(app_dataset_join.dataset_id)  # 添加数据集ID
added_dataset_ids = dataset_ids - old_dataset_ids  # 添加数据集ID
removed_dataset_ids = old_dataset_ids - dataset_ids  # 移除数据集ID
if removed_dataset_ids:  # 如果有移除的数据集ID
for dataset_id in removed_dataset_ids:  # 遍历移除的数据集ID
db.session.query(AppDatasetJoin).filter(
AppDatasetJoin.app_id == app.id, AppDatasetJoin.dataset_id == dataset_id
).delete()  # 删除应用数据集关联
if added_dataset_ids:  # 如果有添加的数据集ID
for dataset_id in added_dataset_ids:  # 遍历添加的数据集ID
app_dataset_join = AppDatasetJoin(app_id=app.id, dataset_id=dataset_id)  # 创建应用数据集关联
db.session.add(app_dataset_join)  # 添加应用数据集关联
db.session.commit()  # 提交事务

La función de este código es manejar el app_published_workflow_was_updated Señal para actualizar la relación de asociación entre una aplicación y un conjunto de datos cuando se actualiza el flujo de trabajo publicado para esa aplicación. Los pasos específicos son los siguientes:

  • Obtener el objeto de aplicación que envía la señal app y objetos de flujo de trabajo actualizados published_workflow.
  • invocaciones get_dataset_ids_from_workflow que extrae la colección de ID de conjuntos de datos del flujo de trabajo actualizado dataset_ids.
  • Consultar la base de datos para obtener todos los datos de la aplicación actual AppDatasetJoin Registros.
  • Calcular los ID de los conjuntos de datos que deben añadirse y suprimirse:
    • Si no hay AppDatasetJoin es necesario añadir todos los ID de los conjuntos de datos extraídos.
    • En caso contrario, calcule los ID de los conjuntos de datos que deben añadirse y suprimirse.
  • Eliminar la necesidad de eliminar AppDatasetJoin Registros.
  • Añadir nuevo AppDatasetJoin Registros.
  • Enviar una transacción de base de datos.

(5) Función de la tabla AppDatasetJoin

La tabla AppDatasetJoin sirve para mantener una relación de muchos a muchos entre una aplicación (App) y un conjunto de datos (Dataset). Cada registro representa la asociación de una aplicación con un conjunto de datos. Los campos específicos son los siguientes

  • id: clave primaria, identifica un registro de forma única.
  • app_id: El identificador único de la aplicación.
  • dataset_id: Identificador único del conjunto de datos.
  • created_at: Fecha de creación del registro.
  • Con esta tabla, es posible consultar qué conjuntos de datos están asociados a una aplicación concreta, o a qué aplicaciones está asociado un conjunto de datos concreto.

(6) implementación de get_dataset_ids_from_workflow()

def get_dataset_ids_from_workflow(published_workflow: Workflow) -> set:  # 从工作流中获取数据集ID
dataset_ids = set()  # 用于存储数据集ID
graph = published_workflow.graph_dict  # 获取工作流图
if not graph:  # 如果没有图
return dataset_ids  # 返回空集合
nodes = graph.get("nodes", [])  # 获取图中的节点
# fetch all knowledge retrieval nodes  # 获取所有知识检索节点
knowledge_retrieval_nodes = [
node for node in nodes if node.get("data", {}).get("type") == NodeType.KNOWLEDGE_RETRIEVAL.value
]  # 获取所有知识检索节点
if not knowledge_retrieval_nodes:  # 如果没有知识检索节点
return dataset_ids  # 返回空集合
for node in knowledge_retrieval_nodes:  # 遍历知识检索节点
try:
node_data = KnowledgeRetrievalNodeData(**node.get("data", {}))  # 获取节点数据
dataset_ids.update(node_data.dataset_ids)  # 更新数据集ID
except Exception as e:  # 如果出现异常
continue
return dataset_ids

La función principal de la función get_dataset_ids_from_workflow es extraer los ID de los conjuntos de datos relevantes de todos los nodos de recuperación de conocimientos de un objeto de flujo de trabajo determinado. los pasos son los siguientes:

  • Inicializar una colección dataset_ids vacía para almacenar los ID de los conjuntos de datos.
  • Obtiene la estructura del grafo del flujo de trabajo.
  • Devuelve la colección dataset_ids vacía si la estructura del grafo está vacía.
  • Obtiene todos los nodos del grafo.
  • Filtra todos los nodos de tipo KNOWLEDGE_RETRIEVAL knowledge_retrieval_nodes.
  • Iterar sobre estos nodos de recuperación de conocimientos, extraer sus ID de conjuntos de datos y actualizarlos en la colección dataset_ids.
  • Devuelve una colección de todos los ID de conjuntos de datos extraídos.

5. Workflow otras interfaces

Esta parte de la interfaz no será elaborada, la API de la aplicación conversacional de orquestación del flujo de trabajo ha sido descrita muy claramente.

número de serienombre de la interfazenlace de interfazExplicación de las funciones de interfaz
1Enviar un mensaje de diálogoPOST /mensajes-chatCrear mensajes de sesión que envíen información al usuario o le hagan preguntas.
2Cargar archivosPOST /archivos/cargarCargar archivos (actualmente sólo se admiten imágenes) para utilizarlos al enviar mensajes.
3deje de responderPOST /chat-messages/:task_id/stopDetener la transmisión de respuestas (sólo se admite el modo de transmisión).
4Comentarios sobre los mensajes (Me gusta)POST /messages/:message_id/feedbacksComentarios y "me gusta" de los usuarios sobre los mensajes para facilitar la optimización del resultado.
5Obtenga una lista de preguntas sugeridas para la siguiente rondaGET /mensajes/{id_mensaje}/sugeridosObtenga una lista de preguntas sugeridas para la siguiente ronda.
6Obtener mensajes del historial de sesionesGET /mensajesObtener el historial de los registros de mensajes de la sesión.
7Obtener lista de sesionesGET /conversacionesObtiene una lista de las sesiones del usuario actual.
8Borrar una sesiónDELETE /conversaciones/:conversation_idElimina la sesión especificada.
9cambio de nombre de sesiónPOST /conversaciones/:conversation_id/nombreCambia el nombre de la sesión.
10voz a textoPOST /audio-a-textoConvierte archivos de voz a texto.
11texto a vozPOST /texto-a-audioConvierte texto en voz.
12Obtener información sobre la configuración de la aplicaciónGET /parámetrosObtener información de configuración de la aplicación, como interruptores de función, parámetros de entrada, etc.
13Obtener metainformación de la aplicaciónGET /metaObtener la Meta información de la aplicación para obtener el icono de la herramienta.

bibliografía

[1] Variables de sesión: https://docs.dify.ai/v/zh-hans/guides/workflow/variables

[2] Asignación de variables: https://docs.dify.ai/v/zh-hans/guides/workflow/node/variable-assignment

[3] Agregación de variables: https://docs.dify.ai/v/zh-hans/guides/workflow/node/variable-assigner

[4] Reaccione Sitio web chino de Flow: https://reactflow-cn.js.org/

[5] Página web de React Flow en español: https://reactflow.dev/

[6] Implementación de procesos de operaciones de creación, actualización, ejecución y eliminación de Chatflow: https://z0yrmerhgi8.feishu.cn/wiki/FFzxwdF4PijlhjkLUoecOv6Vn8a

© declaración de copyright

Artículos relacionados

Sin comentarios

Debe iniciar sesión para participar en los comentarios.
Acceder ahora
ninguno
Sin comentarios...