Dify의 독립형 외래 환자 안내 워크플로(채팅 흐름)

AI 실습 튜토리얼9개월 전 업데이트 AI 공유 서클
11.7K 00

참고: 이 글에서는 Dify v0.7.2를 사용합니다.

이 채팅 플로우는 웹 또는 음성 대화를 통해 환자 데이터를 수집할 수 있는 외래 환자 안내용 챗봇을 구축하는 방법을 보여줍니다. 간단히 이해하면 환자 정보(연령, 성별, 증상)를 기반으로 환자에게 진료과를 추천하는 것입니다.

I. 워크플로 사고

1. 워크플로 스크린샷

외래 환자 오리엔테이션의 전체 워크플로 스크린샷은 아래와 같습니다:

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

2. 워크플로 의사 흐름도

외래 환자 안내 워크플로의 목적은 환자가 입력한 나이, 성별, 증상을 바탕으로 환자에게 진료과를 추천하는 것입니다. 첫 번째 대화에서는 환자가 정보의 전부 또는 일부를 한 번에 입력할 수 있으므로 '매개변수 추출기' 노드를 사용하여 환자의 첫 번째 입력에서 성별, 증상 및 나이를 추출합니다. 대화 변수 is_first_message는 "변수 할당" 노드에서 0으로 설정됩니다.

3. 문제 1

이후 대화를 진행하는 동안에는 한 번에 한 가지 유형의 필드 정보만 식별되지만, 환자가 여러 필드를 제공할 수 있으며 필드 식별 순서는 나이, 성별, 증상입니다.

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

4. 문제 2

환자 정보를 기반으로 이미 진료과가 추천된 경우 정보를 다시 입력하면 마지막 진료과가 추천됩니다. 부서 필드가 비어 있지 않으므로 직접 응답 프로세스를 따릅니다.

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

II. 세션 변수

세션 변수는 사용자 기본 설정, 대화 기록 등 LLM에 필요한 상황별 정보를 저장하는 데 사용됩니다. 읽기-쓰기 방식입니다. 세션 변수는 다자간 대화 시나리오를 지향하므로 세션 변수는 Chatflow 유형(Chat Assistant -> 워크플로우 오케스트레이션) 애플리케이션에서만 사용할 수 있습니다.

1.세션 변수데이터 유형

(1) 문자열

(2) 번호

(3) 개체

(4) Array[문자열] 문자열 배열

(5) Array[number] 숫자 배열

(6) Array[object] 객체의 배열

2.세션 변수특성화

(1) 세션 변수는 대부분의 노드 내에서 전역적으로 참조할 수 있습니다;

(2) 세션 변수를 작성하려면 다음을 사용해야 합니다.변수 할당노드;

(3) 세션 변수는 읽기-쓰기입니다.

3. 이 워크플로에 정의된 세션 변수

이 워크플로에 정의된 5가지 세션 변수는 첫 번째 대화인지 여부, 연령, 성별, 증상 및 부서입니다.

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

III. 워크플로 관련 인터페이스

1. 워크플로에 대한 인터페이스 가져오기

(1) 소스 코드 위치

  • 소스 코드 위치: dedify-0.7.2\api\controllers\console\app\workflow.py
  • 소스 코드 위치: dedify-0.7.2\api\서비시스\워크플로우_service.py

(2) 워크플로 작업 가져오기

http://localhost:5001/console/api/apps/3c309371-54f6-4bfb-894a-4193b189ffa5/workflows/draft. 여기서 초안과 같은 초안은 워크플로 페이지에서 디버깅을 나타냅니다.

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

(3) 워크플로 구현 획득

워크플로는 워크플로 데이터 테이블에 레코드를 저장합니다. 이제 버전은 초안이며 워크플로가 게시될 때마다 해당 테이블에 레코드가 삽입됩니다. 아래 그림과 같습니다:

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

(4) 워크플로 데이터 구조

인터페이스에서 반환하는 워크플로 데이터 구조는 아래와 같습니다:

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. 워크플로 인터페이스 업데이트하기

(1) 소스 코드 위치

  • 소스 위치: dedify-0.7.2\웹\앱\컴포넌트\워크플로우\후크\사용 노드 동기화 초안.ts
  • 소스 코드 위치: dedify-0.7.2\웹\서비스\워크플로우.ts

(2) 워크플로 작업 업데이트

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

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

(3) 워크플로우 프런트엔드 코드 업데이트

Dify 워크플로우의 프론트엔드에서 사용되는 React Flow 프레임워크로 인해 워크플로우가 변경될 때 추가, 삭제, 변경과 같은 POST 작업이 수행되는 것으로 추측됩니다. 백엔드 콘솔의 로그를 통해, 백엔드 콘솔에서workflows/draft?_token=::

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

통과(청구서 또는 검사 등)workflows/draft?_token=프런트엔드 코드를 검색한 결과 이 코드를 사용할 수 있는 곳은 단 한 곳뿐이었으며, 그 곳은 바로 여기였습니다.

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

POST 작업이 수행되므로 오른쪽에 페이로드 매개변수가 있어야 하며 워크플로 매개변수는 해당 파일에서 찾을 수 있습니다.

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

종속성getPostParams변경이 발생하면 비동기적으로 실행됩니다.syncWorkflowDraft(postParams).

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

(인과 관계 표시)syncWorkflowDraft(postParams)실제 호출은 아래와 같이 POST:

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

(4) 워크플로우 기능 요약

오른쪽dify-0.7.2\web\service\workflow.ts의 기능은 다음과 같이 요약됩니다:

일련 번호함수 이름기능 기능매개변수 및 설명
1fetchWorkflowDraft워크플로 초안을 받아보세요.url: 문자열, 요청의 URL입니다.
2syncWorkflowDraft워크플로 초안을 동기화합니다.url: 문자열, 요청의 URL입니다.params객체, 요청의 매개 변수, 요청에 포함된 graphfeaturesenvironment_variables 노래로 응답 conversation_variables.
3fetchNodesDefaultConfigs노드의 기본 구성을 가져옵니다.url: 문자열, 요청의 URL입니다.
4fetchWorkflowRunHistory워크플로 실행 기록을 확인하세요.url: 문자열, 요청의 URL입니다.
5fetcChatRunHistory채팅 실행 기록을 확인하세요.url: 문자열, 요청의 URL입니다.
6singleNodeRun단일 노드를 실행합니다.appId문자열, 애플리케이션의 ID입니다.nodeId: 문자열, 노드의 ID입니다.params객체, 요청의 매개변수입니다.
7getIterationSingleNodeRunUrl단일 노드에 대해 실행된 반복의 URL을 가져옵니다.isChatFlow채팅 스트림인지 여부를 나타내는 부울 값입니다.appId문자열, 애플리케이션의 ID입니다.nodeId: 문자열, 노드의 ID입니다.
8publishWorkflow워크플로를 게시합니다.url: 문자열, 요청의 URL입니다.
9fetchPublishedWorkflow게시된 워크플로를 확인하세요.url: 문자열, 요청의 URL입니다.
10stopWorkflowRun워크플로 실행을 중지합니다.url: 문자열, 요청의 URL입니다.
11fetchNodeDefault노드의 기본 구성을 가져옵니다.appId문자열, 애플리케이션의 ID입니다.blockType: 열거형 값, 노드 유형입니다.query객체, 선택 사항, 쿼리 매개변수.
12updateWorkflowDraftFromDSLDSL에서 워크플로 초안을 업데이트합니다.appId문자열, 애플리케이션의 ID입니다.data: 문자열, DSL 데이터.
13fetchCurrentValueOfConversationVariable세션 변수의 현재 값을 가져옵니다.url: 문자열, 요청의 URL입니다.params객체, 요청의 매개 변수, 요청에 포함된 conversation_id.

3. 워크플로 구현

참조Chatflow 생성, 업데이트, 실행 및 삭제 작업의 프로세스 구현6]의 "채팅 플로우 구현" 섹션을 참조하세요.

4. 워크플로 게시

(1) 소스 코드 위치

  • 소스 코드 위치: dedify-0.7.2\api\controllers\console\app\workflow.py
  • 소스 코드 위치: dedify-0.7.2\api\서비시스\워크플로우_service.py
  • 소스 위치: dedify-0.7.2\api\events\event_handlers\update_app_dataset_join_when_app_published_workflow_updated.py

(2) 워크플로 게시 인터페이스

워크플로 게시를 클릭하면 실행됩니다.http://localhost:5001/console/api/apps/3c309371-54f6-4bfb-894a-4193b189ffa5/workflows/publish인터페이스.

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

주로 새 워크플로를 만들고 앱 워크플로 이벤트를 트리거하는 것으로 구성됩니다. 아래 그림과 같습니다:

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

(3) 새 워크플로 레코드 만들기

이는 주로 새 워크플로 레코드를 만드는 것으로 구성되며, 버전 필드의 내용은 2024-09-07 09:11:25.894535로 초안이 아닌 워크플로가 게시되었음을 나타냅니다(워크플로가 게시되지 않았으며 워크플로 캔버스에서 아직 디버깅 중임). 아래와 같이 표시됩니다:

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

(4) 앱_게시된_워크플로우_업데이트 이벤트 구현

@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()  # 提交事务

이 코드의 기능은 app_published_workflow_was_updated 해당 애플리케이션에 대한 게시된 워크플로가 업데이트될 때 애플리케이션과 데이터 집합 간의 연결 관계를 업데이트하도록 신호를 보냅니다. 구체적인 단계는 다음과 같습니다:

  • 신호를 전송하는 애플리케이션 객체를 가져옵니다. app 및 업데이트된 워크플로우 개체 published_workflow.
  • 호출 get_dataset_ids_from_workflow 함수를 사용하여 업데이트된 워크플로우에서 데이터 세트 ID 컬렉션을 추출합니다. dataset_ids.
  • 데이터베이스를 쿼리하여 현재 애플리케이션의 모든 애플리케이션의 AppDatasetJoin 기록.
  • 추가 및 삭제할 데이터 집합 ID를 계산합니다:
    • 전류가 없는 경우 AppDatasetJoin 레코드가 있는 경우 추출된 모든 데이터 세트 ID를 추가해야 합니다.
    • 그렇지 않으면 추가 및 삭제할 데이터 집합 ID를 계산합니다.
  • 제거할 필요성 삭제 AppDatasetJoin 기록.
  • 새 항목 추가 AppDatasetJoin 기록.
  • 데이터베이스 트랜잭션을 제출합니다.

(5) 앱데이터셋조인 테이블의 역할

AppDatasetJoin 테이블은 애플리케이션(앱)과 데이터 집합(데이터세트) 간의 다대다 관계를 유지하는 역할을 합니다. 각 레코드는 애플리케이션과 데이터 세트의 연결을 나타냅니다. 구체적인 필드는 다음과 같습니다:

  • ID: 기본 키로, 레코드를 고유하게 식별합니다.
  • app_id: 애플리케이션의 고유 식별자입니다.
  • dataset_id: 데이터 집합의 고유 식별자입니다.
  • created_at: 레코드가 생성된 타임스탬프입니다.
  • 이 표를 사용하면 어떤 데이터 세트가 특정 애플리케이션과 연관되어 있는지 또는 특정 데이터 세트가 어떤 애플리케이션과 연관되어 있는지 쿼리할 수 있습니다.

(6) 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

get_dataset_ids_from_workflow 함수의 주요 기능은 주어진 워크플로우 개체에서 모든 지식 검색 노드의 관련 데이터 세트 ID를 추출하는 것입니다. 구체적인 단계는 다음과 같습니다:

  • 데이터 세트 ID를 저장하기 위해 빈 dataset_ids 컬렉션을 초기화합니다.
  • 워크플로 그래프의 그래프 구조를 가져옵니다.
  • 그래프 구조가 비어 있는 경우 빈 데이터셋_아이디 컬렉션을 반환합니다.
  • 그래프에 있는 모든 노드를 가져옵니다.
  • KNOWLEDGE_RETRIEVAL 지식_검색_노드 유형의 모든 노드를 필터링합니다.
  • 이러한 지식 검색 노드를 반복하여 데이터 세트 ID를 추출한 다음 데이터 세트_ids 컬렉션에서 업데이트합니다.
  • 추출된 모든 데이터 세트 ID의 컬렉션을 반환합니다.

5. 워크플로 기타 인터페이스

인터페이스의 이 부분은 자세히 설명하지 않겠으며, 워크플로 오케스트레이션 대화형 애플리케이션 API는 매우 명확하게 설명되어 있습니다.

일련 번호인터페이스 이름인터페이스 링크인터페이스 기능 설명
1대화 메시지 보내기POST /chat-messages사용자 입력을 보내거나 질문을 하는 세션 메시지를 만듭니다.
2파일 업로드POST /파일/업로드메시지를 보낼 때 사용할 파일(현재는 이미지만 지원됨)을 업로드합니다.
3응답 중지POST /chat-messages/:task_id/stop스트리밍 응답 중지(스트리밍 모드만 지원됨).
4메시지 피드백(좋아요)POST /메시지/:메시지_id/feedbacks사용자 피드백과 메시지에 대한 좋아요를 통해 결과물을 최적화할 수 있습니다.
5다음 라운드를 위한 추천 질문 목록 보기GET /메시지/{메시지_id}/suggested다음 라운드를 위한 추천 질문 목록을 확인하세요.
6세션 기록 메시지 가져오기GET /메시지세션의 메시지 로그 기록을 가져옵니다.
7세션 목록 가져오기GET /대화현재 사용자의 세션 목록을 가져옵니다.
8세션 삭제하기대화 삭제 /대화/:대화_id지정된 세션을 삭제합니다.
9세션 이름 바꾸기POST /대화/:대화_id/이름세션 이름을 바꿉니다.
10음성-텍스트 변환POST /오디오-텍스트 변환음성 파일을 텍스트로 변환하세요.
11텍스트 음성 변환POST /text-to-audio텍스트를 음성으로 변환합니다.
12애플리케이션 구성 정보 가져오기GET /parameters기능 스위치, 입력 매개변수 등과 같은 애플리케이션의 구성 정보를 가져옵니다.
13애플리케이션 메타 정보 가져오기GET /meta도구 아이콘을 가져오기 위한 애플리케이션의 메타 정보를 가져옵니다.

참고 문헌

[1] 세션 변수: https://docs.dify.ai/v/zh-hans/guides/workflow/variables

[2] 변수 할당: https://docs.dify.ai/v/zh-hans/guides/workflow/node/variable-assignment

[3] 변수 집계: https://docs.dify.ai/v/zh-hans/guides/workflow/node/variable-assigner

[4] React Flow 중국어 웹사이트: https://reactflow-cn.js.org/

[5] 리액트 플로우 영문 웹사이트: https://reactflow.dev/

[6] Chatflow 생성, 업데이트, 실행 및 삭제 작업의 프로세스 구현: https://z0yrmerhgi8.feishu.cn/wiki/FFzxwdF4PijlhjkLUoecOv6Vn8a

© 저작권 정책

관련 문서

댓글 없음

댓글에 참여하려면 로그인해야 합니다!
지금 로그인
없음
댓글 없음...