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 :

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

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.

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

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.

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

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.

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

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.

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

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

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

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

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

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

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

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.

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

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.

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

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

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

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

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

(4) Résumé des fonctions du flux de travail

droitdify-0.7.2\web\service\workflow.tsLes fonctions sont résumées ci-dessous :

numéro de sérienom de la fonctionfonction fonctionParamètres et explications
1fetchWorkflowDraftObtenir le projet de flux de travail.url: Chaîne, l'URL de la demande.
2syncWorkflowDraftSynchroniser les projets de flux de travail.url: Chaîne, l'URL de la demande.paramsl'objet, les paramètres de la demande, contenant l'objet graph,features,environment_variables répondre en chantant conversation_variables.
3fetchNodesDefaultConfigsObtenir la configuration par défaut du nœud.url: Chaîne, l'URL de la demande.
4fetchWorkflowRunHistoryObtenir l'historique de l'exécution du flux de travail.url: Chaîne, l'URL de la demande.
5fetcChatRunHistoryObtenir l'historique de l'exécution du chat.url: Chaîne, l'URL de la demande.
6singleNodeRunExé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.
7getIterationSingleNodeRunUrlObtient l'URL de l'itération pour un seul nœud.isChatFlowValeur 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.
8publishWorkflowPublier un flux de travail.url: Chaîne, l'URL de la demande.
9fetchPublishedWorkflowObtenir des flux de travail publiés.url: Chaîne, l'URL de la demande.
10stopWorkflowRunArrêter l'exécution du flux de travail.url: Chaîne, l'URL de la demande.
11fetchNodeDefaultObtenir 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.
12updateWorkflowDraftFromDSLMise à jour des projets de flux de travail de la DSL.appId: Chaîne, ID de l'application.data: Chaîne, données DSL.
13fetchCurrentValueOfConversationVariableObtient la valeur actuelle de la variable de session.url: Chaîne, l'URL de la demande.paramsl'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/publishInterface.

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

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 :

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

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

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

(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 travail published_workflow.
  • invocations get_dataset_ids_from_workflow qui extrait la collection d'ID de l'ensemble de données du flux de travail mis à jour dataset_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.
  • 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érienom de l'interfacelien d'interfaceExplication des fonctions de l'interface
1Envoyer un message de dialoguePOST /chat-messagesCréer des messages de session qui envoient des données à l'utilisateur ou lui posent des questions.
2Téléchargement de fichiersPOST /files/uploadTélécharger des fichiers (actuellement, seules les images sont prises en charge) à utiliser lors de l'envoi de messages.
3ne plus répondrePOST /chat-messages/:task_id/stopArrêter la diffusion des réponses (seul le mode diffusion est pris en charge).
4Message Feedback (Likes)POST /messages/:message_id/feedbacksRetour d'information des utilisateurs et commentaires sur les messages pour faciliter l'optimisation de la production.
5Obtenir une liste de questions suggérées pour le prochain tour.GET /messages/{message_id}/suggestedObtenez une liste de questions suggérées pour le prochain tour.
6Obtenir les messages de l'historique de la sessionGET /messagesPermet d'obtenir l'historique des journaux de messages de la session.
7Obtenir la liste des sessionsGET /conversationsObtenir une liste des sessions de l'utilisateur actuel.
8Suppression d'une sessionDELETE /conversations/:conversation_idSupprime la session spécifiée.
9renommage de sessionPOST /conversations/:conversation_id/nameRenommer la session.
10de la parole au textePOST /audio-to-textConvertir les fichiers vocaux en texte.
11synthèse vocalePOST /text-to-audioConvertir le texte en parole.
12Obtenir des informations sur la configuration de l'applicationGET /paramètresObtenir des informations sur la configuration de l'application, telles que les commutateurs de fonction, les paramètres d'entrée, etc.
13Obtenir des méta-informations sur les applicationsGET /metaObtenir 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

Articles connexes

Pas de commentaires

Vous devez être connecté pour participer aux commentaires !
S'inscrire maintenant
aucun
Pas de commentaires...