Flujo de trabajo autónomo de orientación ambulatoria (chatflow) en Dify
Tutoriales prácticos sobre IAActualizado hace 8 meses Círculo de intercambio de inteligencia artificial 3.5K 00
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:

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.

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.

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.

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.

(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:

(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.

(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=
::

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í.

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.

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

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

(4) Resumen de las funciones del flujo de trabajo
derechadify-0.7.2\web\service\workflow.ts
Las funciones en se resumen del siguiente modo:
número de serie | nombre de la función | función función | Parámetros y explicaciones |
---|---|---|---|
1 | fetchWorkflowDraft | Obtén el borrador del flujo de trabajo. | url : Cadena, la URL de la solicitud. |
2 | syncWorkflowDraft | Sincronice los borradores del flujo de trabajo. | url : Cadena, la URL de la solicitud.params : objeto, los parámetros de la solicitud, que contiene el graph yfeatures yenvironment_variables responder cantando conversation_variables . |
3 | fetchNodesDefaultConfigs | Obtener la configuración por defecto del nodo. | url : Cadena, la URL de la solicitud. |
4 | fetchWorkflowRunHistory | Obtener el historial de ejecución del flujo de trabajo. | url : Cadena, la URL de la solicitud. |
5 | fetcChatRunHistory | Obtener el historial de chats. | url : Cadena, la URL de la solicitud. |
6 | singleNodeRun | Ejecuta un único nodo. | appId : String, ID de la aplicación.nodeId : String, el ID del nodo.params : Objeto, parámetros de la solicitud. |
7 | getIterationSingleNodeRunUrl | Obtiene 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. |
8 | publishWorkflow | Publica un flujo de trabajo. | url : Cadena, la URL de la solicitud. |
9 | fetchPublishedWorkflow | Obtener flujos de trabajo publicados. | url : Cadena, la URL de la solicitud. |
10 | stopWorkflowRun | Detener la ejecución del flujo de trabajo. | url : Cadena, la URL de la solicitud. |
11 | fetchNodeDefault | Obtener la configuración por defecto del nodo. | appId : String, ID de la aplicación.blockType Valor de enumeración, tipo de nodo.query Objeto, opcional, parámetro de consulta. |
12 | updateWorkflowDraftFromDSL | Actualizar los borradores de flujo de trabajo de DSL. | appId : String, ID de la aplicación.data : Cadena, Datos DSL. |
13 | fetchCurrentValueOfConversationVariable | Obtiene 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/publish
Interfaz.

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:

(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:

(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 actualizadospublished_workflow
. - invocaciones
get_dataset_ids_from_workflow
que extrae la colección de ID de conjuntos de datos del flujo de trabajo actualizadodataset_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.
- Si no hay
- 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 serie | nombre de la interfaz | enlace de interfaz | Explicación de las funciones de interfaz |
---|---|---|---|
1 | Enviar un mensaje de diálogo | POST /mensajes-chat | Crear mensajes de sesión que envíen información al usuario o le hagan preguntas. |
2 | Cargar archivos | POST /archivos/cargar | Cargar archivos (actualmente sólo se admiten imágenes) para utilizarlos al enviar mensajes. |
3 | deje de responder | POST /chat-messages/:task_id/stop | Detener la transmisión de respuestas (sólo se admite el modo de transmisión). |
4 | Comentarios sobre los mensajes (Me gusta) | POST /messages/:message_id/feedbacks | Comentarios y "me gusta" de los usuarios sobre los mensajes para facilitar la optimización del resultado. |
5 | Obtenga una lista de preguntas sugeridas para la siguiente ronda | GET /mensajes/{id_mensaje}/sugeridos | Obtenga una lista de preguntas sugeridas para la siguiente ronda. |
6 | Obtener mensajes del historial de sesiones | GET /mensajes | Obtener el historial de los registros de mensajes de la sesión. |
7 | Obtener lista de sesiones | GET /conversaciones | Obtiene una lista de las sesiones del usuario actual. |
8 | Borrar una sesión | DELETE /conversaciones/:conversation_id | Elimina la sesión especificada. |
9 | cambio de nombre de sesión | POST /conversaciones/:conversation_id/nombre | Cambia el nombre de la sesión. |
10 | voz a texto | POST /audio-a-texto | Convierte archivos de voz a texto. |
11 | texto a voz | POST /texto-a-audio | Convierte texto en voz. |
12 | Obtener información sobre la configuración de la aplicación | GET /parámetros | Obtener información de configuración de la aplicación, como interruptores de función, parámetros de entrada, etc. |
13 | Obtener metainformación de la aplicación | GET /meta | Obtener 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
Derechos de autor del artículo Círculo de intercambio de inteligencia artificial Todos, por favor no reproducir sin permiso.
Artículos relacionados
Sin comentarios...