Flux de travail autonome pour l'orientation des patients externes (chatflow) dans Dify
Note : Cet article utilise Dify v0.7.2.
Ce flux de discussion montre comment construire un chatbot pour l'orientation des patients ambulatoires qui peut collecter des données sur les patients par le biais d'un dialogue Web ou vocal. En clair, cela signifie que le patient se voit recommander un service en fonction des informations dont il dispose (âge, sexe et symptômes).
I. Réflexion sur le flux de travail
1. capture d'écran du flux de travail
Capture d'écran du flux de travail complet de l'orientation des patients ambulatoires, illustré ci-dessous :

2. le pseudo-organigramme du flux de travail
L'objectif du flux de travail d'orientation des patients externes est de recommander un service à un patient sur la base des informations fournies par ce dernier concernant son âge, son sexe et ses symptômes. Au cours du premier cycle de dialogue, le patient pouvant saisir tout ou partie des informations en une seule fois, le nœud "Extracteur de paramètres" est utilisé pour extraire le sexe, les symptômes et l'âge à partir de la première entrée du patient. La variable de dialogue is_first_message est fixée à 0 par le nœud "Variable Assignment".
3. problèmes 1
Au cours des dialogues suivants, un seul type d'information est reconnu à la fois, bien que le patient puisse fournir plusieurs champs, les champs étant reconnus dans l'ordre de l'âge, du sexe et des symptômes.

4. problèmes 2
Si un service a déjà été recommandé sur la base des informations relatives au patient, la saisie d'une nouvelle information entraînera la recommandation du dernier service. Comme le champ département n'est pas vide, le processus de réponse directe est suivi.

II. Variables de la session
La variable de session est utilisée pour stocker les informations contextuelles nécessaires à LLM, telles que les préférences de l'utilisateur, l'historique du dialogue, etc. Elle est en lecture-écriture. Les variables de session sont orientées vers des scénarios de dialogue à plusieurs tours, de sorte que les variables de session ne sont disponibles que pour les applications de type Chatflow (Chat Assistant -> Workflow Orchestration).
1.variable de sessiontype de données
(1) Chaîne
(2) Nombre
(3) Objet
(4) Array[string] tableau de chaînes de caractères
(5) Tableau [nombre] Tableau de nombres
(6) Tableau [objet] Tableau d'objets
2.variable de sessioncaractérisation
(1) Les variables de session peuvent être référencées globalement dans la plupart des nœuds ;
(2) L'écriture de variables de session nécessite l'utilisation de la fonctionl'affectation des variablesNœuds ;
(3) Les variables de session sont en lecture-écriture.
3. les variables de session définies dans ce flux de travail
Les cinq variables de session définies pour ce flux de travail sont le fait qu'il s'agisse du premier cycle de dialogue, l'âge, le sexe, les symptômes et le département.

III. Interfaces liées aux flux de travail
1. obtenir l'interface du flux de travail
(1) Emplacement du code source
- Emplacement du code source : dedify-0.7.2\capi\controllers\console\appworkflow.py
- Emplacement du code source : dedify-0.7.2\capi\services\workflow_service.py
(2) Obtenir des opérations de flux de travail
http://localhost:5001/console/api/apps/3c309371-54f6-4bfb-894a-4193b189ffa5/workflows/draft. où draft, comme brouillon, indique le débogage dans la page du flux de travail.

(3) Acquisition d'implémentations de flux de travail
Le flux de travail stocke un enregistrement dans la table de données des flux de travail. La version est maintenant provisoire et chaque fois qu'un flux de travail est publié, un enregistrement est inséré dans cette table. Comme indiqué ci-dessous :

(4) Structure de données du flux de travail
La structure de données du flux de travail renvoyée par l'interface est présentée ci-dessous :
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. mettre à jour les interfaces de flux de travail
(1) Emplacement du code source
- Source Location : dedify-0.7.2\webappapp\components\workflow\hooks\use-nodes-sync-draft.ts
- Emplacement du code source : dedify-0.7.2\web\service\workflow.ts
(2) Mise à jour des opérations de flux de travail
http://localhost:5001/console/api/apps/3c309371-54f6-4bfb-894a-4193b189ffa5/workflows/draft.

(3) Mise à jour du code frontal du flux de travail
En raison du cadre React Flow utilisé dans le front-end du flux de travail de Dify, on suppose que des opérations POST, telles que l'ajout, la suppression et la modification, peuvent être effectuées lorsque le flux de travail change. Grâce aux journaux de la console du back-end, il a été constaté que l'appel à la fonctionworkflows/draft?_token=
: :

faire passer (un projet de loi, une inspection, etc.)workflows/draft?_token=
En cherchant dans le code frontal, je n'ai trouvé qu'un seul endroit où l'utiliser, et ce doit être ici.

Puisque l'opération POST est effectuée, il doit y avoir un paramètre Payload, c'est vrai, et le paramètre workflow se trouve dans ce fichier.

Lorsque la dépendancegetPostParams
Lorsqu'une modification se produit, elle est exécutée de manière asynchronesyncWorkflowDraft(postParams)
.

(indique la relation de cause à effet)syncWorkflowDraft(postParams)
L'appel réel est POST. comme indiqué ci-dessous :

(4) Résumé des fonctions du flux de travail
droitdify-0.7.2\web\service\workflow.ts
Les fonctions sont résumées ci-dessous :
numéro de série | nom de la fonction | fonction fonction | Paramètres et explications |
---|---|---|---|
1 | fetchWorkflowDraft | Obtenir le projet de flux de travail. | url : Chaîne, l'URL de la demande. |
2 | syncWorkflowDraft | Synchroniser les projets de flux de travail. | url : Chaîne, l'URL de la demande.params l'objet, les paramètres de la demande, contenant l'objet graph ,features ,environment_variables répondre en chantant conversation_variables . |
3 | fetchNodesDefaultConfigs | Obtenir la configuration par défaut du nœud. | url : Chaîne, l'URL de la demande. |
4 | fetchWorkflowRunHistory | Obtenir l'historique de l'exécution du flux de travail. | url : Chaîne, l'URL de la demande. |
5 | fetcChatRunHistory | Obtenir l'historique de l'exécution du chat. | url : Chaîne, l'URL de la demande. |
6 | singleNodeRun | Exécuter un seul nœud. | appId : Chaîne, ID de l'application.nodeId : Chaîne, l'ID du nœud.params : Objet, paramètres de la demande. |
7 | getIterationSingleNodeRunUrl | Obtient l'URL de l'itération pour un seul nœud. | isChatFlow Valeur booléenne indiquant s'il s'agit ou non d'un flux de discussion.appId : Chaîne, ID de l'application.nodeId : Chaîne, l'ID du nœud. |
8 | publishWorkflow | Publier un flux de travail. | url : Chaîne, l'URL de la demande. |
9 | fetchPublishedWorkflow | Obtenir des flux de travail publiés. | url : Chaîne, l'URL de la demande. |
10 | stopWorkflowRun | Arrêter l'exécution du flux de travail. | url : Chaîne, l'URL de la demande. |
11 | fetchNodeDefault | Obtenir la configuration par défaut du nœud. | appId : Chaîne, ID de l'application.blockType : Valeur d'une énumération, type de nœud.query : Objet, optionnel, paramètre de requête. |
12 | updateWorkflowDraftFromDSL | Mise à jour des projets de flux de travail de la DSL. | appId : Chaîne, ID de l'application.data : Chaîne, données DSL. |
13 | fetchCurrentValueOfConversationVariable | Obtient la valeur actuelle de la variable de session. | url : Chaîne, l'URL de la demande.params l'objet, les paramètres de la demande, contenant l'objet conversation_id . |
3. la mise en œuvre du flux de travail
Référence à laMise en œuvre des opérations de création, de mise à jour, d'exécution et de suppression du ChatflowLa section "Mise en œuvre de Chatflow" dans [6].
4. la publication de flux de travail
(1) Emplacement du code source
- Emplacement du code source : dedify-0.7.2\capi\controllers\console\appworkflow.py
- Emplacement du code source : dedify-0.7.2\capi\services\workflow_service.py
- Source : dedify-0.7.2\capi\events\event_handlers\update_app_dataset_join_when_app_published_workflow_updated.py
(2) Interface de publication du flux de travail
Il est exécuté lorsque vous cliquez sur Publier le flux de travailhttp://localhost:5001/console/api/apps/3c309371-54f6-4bfb-894a-4193b189ffa5/workflows/publish
Interface.

Il s'agit principalement de créer un nouveau flux de travail et de déclencher l'événement de flux de travail de l'application. Comme le montre le schéma ci-dessous :

(3) Création d'un nouvel enregistrement de flux de travail
Cela consiste principalement à créer un nouvel enregistrement de flux de travail dont le contenu du champ version est 2024-09-07 09:11:25.894535. indiquant que le flux de travail a été publié, et non pas brouillon (le flux de travail n'a pas été publié et est toujours en cours de débogage dans le canevas de flux de travail). Comme le montre le tableau ci-dessous :

(4) Mise en œuvre de l'événement 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 fonction de ce code est de gérer le app_published_workflow_was_updated
Signal pour mettre à jour la relation d'association entre une application et un ensemble de données lorsque le flux de travail publié pour cette application est mis à jour. Les étapes spécifiques sont les suivantes :
- Obtenir l'objet de l'application qui envoie le signal
app
et mise à jour des objets du flux de travailpublished_workflow
. - invocations
get_dataset_ids_from_workflow
qui extrait la collection d'ID de l'ensemble de données du flux de travail mis à jourdataset_ids
. - Interroger la base de données pour obtenir toutes les données de l'application en cours.
AppDatasetJoin
Les dossiers. - Calculer les ID des ensembles de données à ajouter et à supprimer :
- S'il n'y a pas de
AppDatasetJoin
il faut ajouter tous les identifiants d'ensembles de données extraits. - Sinon, calculez les ID des ensembles de données à ajouter et à supprimer.
- S'il n'y a pas de
- Suppression de la nécessité de supprimer
AppDatasetJoin
Les dossiers. - Ajouter un nouveau
AppDatasetJoin
Les dossiers. - Soumettre une transaction de base de données.
(5) Rôle de la table AppDatasetJoin
La table AppDatasetJoin sert à maintenir une relation de plusieurs à plusieurs entre une application (App) et un jeu de données (Dataset). Chaque enregistrement représente l'association d'une application avec un jeu de données. Les champs spécifiques sont les suivants :
- id : clé primaire, identifiant unique d'un enregistrement.
- app_id : L'identifiant unique de l'application.
- dataset_id : Identifiant unique de l'ensemble de données.
- created_at : date de création de l'enregistrement.
- Ce tableau permet d'interroger les ensembles de données associés à une application particulière, ou les applications auxquelles un ensemble de données particulier est associé.
(6) Mise en œuvre 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 fonction get_dataset_ids_from_workflow a pour fonction principale d'extraire les ID des ensembles de données pertinents de tous les nœuds de recherche de connaissances d'un objet de flux de travail donné. les étapes sont les suivantes :
- Initialiser une collection dataset_ids vide pour stocker les identifiants des jeux de données.
- Obtenir la structure du graphe du flux de travail.
- Renvoie la collection dataset_ids vide si la structure du graphe est vide.
- Récupère tous les nœuds du graphe.
- Filtre tous les noeuds de type KNOWLEDGE_RETRIEVAL knowledge_retrieval_nodes.
- Itérer sur ces nœuds de recherche de connaissances, extraire leurs identifiants d'ensembles de données et les mettre à jour dans la collection dataset_ids.
- Renvoie une collection de tous les identifiants d'ensembles de données extraits.
5. les autres interfaces du flux de travail
Cette partie de l'interface ne sera pas développée, l'API de l'application conversationnelle d'orchestration du flux de travail ayant été décrite très clairement.
numéro de série | nom de l'interface | lien d'interface | Explication des fonctions de l'interface |
---|---|---|---|
1 | Envoyer un message de dialogue | POST /chat-messages | Créer des messages de session qui envoient des données à l'utilisateur ou lui posent des questions. |
2 | Téléchargement de fichiers | POST /files/upload | Télécharger des fichiers (actuellement, seules les images sont prises en charge) à utiliser lors de l'envoi de messages. |
3 | ne plus répondre | POST /chat-messages/:task_id/stop | Arrêter la diffusion des réponses (seul le mode diffusion est pris en charge). |
4 | Message Feedback (Likes) | POST /messages/:message_id/feedbacks | Retour d'information des utilisateurs et commentaires sur les messages pour faciliter l'optimisation de la production. |
5 | Obtenir une liste de questions suggérées pour le prochain tour. | GET /messages/{message_id}/suggested | Obtenez une liste de questions suggérées pour le prochain tour. |
6 | Obtenir les messages de l'historique de la session | GET /messages | Permet d'obtenir l'historique des journaux de messages de la session. |
7 | Obtenir la liste des sessions | GET /conversations | Obtenir une liste des sessions de l'utilisateur actuel. |
8 | Suppression d'une session | DELETE /conversations/:conversation_id | Supprime la session spécifiée. |
9 | renommage de session | POST /conversations/:conversation_id/name | Renommer la session. |
10 | de la parole au texte | POST /audio-to-text | Convertir les fichiers vocaux en texte. |
11 | synthèse vocale | POST /text-to-audio | Convertir le texte en parole. |
12 | Obtenir des informations sur la configuration de l'application | GET /paramètres | Obtenir des informations sur la configuration de l'application, telles que les commutateurs de fonction, les paramètres d'entrée, etc. |
13 | Obtenir des méta-informations sur les applications | GET /meta | Obtenir les méta-informations de l'application pour obtenir l'icône de l'outil. |
bibliographie
[1] Variables de session : https://docs.dify.ai/v/zh-hans/guides/workflow/variables[2] Assignation de variable : https://docs.dify.ai/v/zh-hans/guides/workflow/node/variable-assignment[3] Agrégation de variables : https://docs.dify.ai/v/zh-hans/guides/workflow/node/variable-assigner[4] Réagir Site web du flux en chinois : https://reactflow-cn.js.org/[5] React Flow Site web en anglais : https://reactflow.dev/[6] Mise en œuvre des opérations de création, de mise à jour, d'exécution et de suppression de Chatflow : https://z0yrmerhgi8.feishu.cn/wiki/FFzxwdF4PijlhjkLUoecOv6Vn8a© déclaration de droits d'auteur
Article copyright Cercle de partage de l'IA Tous, prière de ne pas reproduire sans autorisation.
Articles connexes
Pas de commentaires...