# Dify 对话流 API 官方文档 > 文档来源:https://dify.ireborn.com.cn/app/4bea851a-7f24-47bd-9d0b-1d74f69ba603/develop > 导出时间:2025-10-14 ## 工作流编排对话型应用 API 对话应用支持会话持久化,可将之前的聊天记录作为上下文进行回答,可适用于聊天/客服 AI 等。 ### 基础 URL ``` http://dify.ireborn.com.cn/v1 ``` ### 鉴权 Service API 使用 `API-Key` 进行鉴权。 **强烈建议开发者把 `API-Key` 放在后端存储,而非分享或者放在客户端存储,以免 `API-Key` 泄露,导致财产损失。** 所有 API 请求都应在 `Authorization` HTTP Header 中包含您的 `API-Key`,如下所示: ``` Authorization: Bearer {API_KEY} ``` --- ## POST /chat-messages - 发送对话消息 创建会话消息。 ### Request Body | Name | Type | Description | |------|------|-------------| | `query` | string | 用户输入/提问内容。 | | `inputs` | object | 允许传入 App 定义的各变量值。inputs 参数包含了多组键值对(Key/Value pairs),每组的键对应一个特定变量,每组的值则是该变量的具体值。如果变量是文件类型,请指定一个包含以下 `files` 中所述键的对象。默认 `{}` | | `response_mode` | string | `streaming` 流式模式(推荐)。基于 SSE([Server-Sent Events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events))实现类似打字机输出方式的流式返回。
`blocking` 阻塞模式,等待执行完毕后返回结果。(请求若流程较长可能会被中断)。由于 Cloudflare 限制,请求会在 100 秒超时无返回后中断。 | | `user` | string | 用户标识,用于定义终端用户的身份,方便检索、统计。由开发者定义规则,需保证用户标识在应用内唯一。服务 API 不会共享 WebApp 创建的对话。 | | `conversation_id` | string | (选填)会话 ID,需要基于之前的聊天记录继续对话,必须传之前消息的 conversation_id。 | | `files` | array[object] | 文件列表,适用于传入文件结合文本理解并回答问题,仅当模型支持 Vision/Video 能力时可用。

**文件类型:**
- `document`: TXT, MD, MARKDOWN, MDX, PDF, HTML, XLSX, XLS, VTT, PROPERTIES, DOC, DOCX, CSV, EML, MSG, PPTX, PPT, XML, EPUB
- `image`: JPG, JPEG, PNG, GIF, WEBP, SVG
- `audio`: MP3, M4A, WAV, WEBM, MPGA
- `video`: MP4, MOV, MPEG, WEBM
- `custom`: 其他文件类型

**transfer_method (string)** 传递方式:
- `remote_url`: 文件地址
- `local_file`: 上传文件

- `url`: 文件地址(仅当传递方式为 remote_url 时)
- `upload_file_id`: 上传文件 ID(仅当传递方式为 local_file 时) | | `auto_generate_name` | bool | (选填)自动生成标题,默认 true。若设置为 false,则可通过调用会话重命名接口并设置 auto_generate 为 true 实现异步生成标题。 | | `workflow_id` | string | (选填)工作流ID,用于指定特定版本,如果不提供则使用默认的已发布版本。 | | `trace_id` | string | (选填)链路追踪ID。适用于与业务系统已有的trace组件打通,实现端到端分布式追踪等场景。如果未指定,系统会自动生成trace_id。支持以下三种方式传递,具体优先级依次为:
1. Header:通过 HTTP Header X-Trace-Id 传递,优先级最高。
2. Query 参数:通过 URL 查询参数 trace_id 传递。
3. Request Body:通过请求体字段 trace_id 传递(即本字段)。 | ### Response 当 `response_mode` 为 `blocking` 时,返回 **ChatCompletionResponse** object。 当 `response_mode` 为 `streaming` 时,返回 **ChunkChatCompletionResponse** object 流式序列。 #### ChatCompletionResponse(阻塞模式) 返回完整的 App 结果,Content-Type 为 `application/json`。 | 字段 | 类型 | 描述 | |------|------|------| | `event` | string | 事件类型,固定为 `message` | | `task_id` | string | 任务 ID,用于请求跟踪和下方的停止响应接口 | | `id` | string | 唯一ID | | `message_id` | string | 消息唯一 ID | | `conversation_id` | string | 会话 ID | | `mode` | string | App 模式,固定为 `chat` | | `answer` | string | 完整回复内容 | | `metadata` | object | 元数据 | | `usage` | Usage | 模型用量信息 | | `retriever_resources` | array[RetrieverResource] | 引用和归属分段列表 | | `created_at` | int | 消息创建时间戳,如:1705395332 | #### ChunkChatCompletionResponse(流式模式) 返回 App 输出的流式块,Content-Type 为 `text/event-stream`。 每个流式块均为 `data:` 开头,块之间以 `\n\n` 即两个换行符分隔,如下所示: ``` data: {"event": "message", "task_id": "900bbd43-dc0b-4383-a372-aa6e6c414227", "id": "663c5084-a254-4040-8ad3-51f2a3c1a77c", "answer": "Hi", "created_at": 1705398420}\n\n ``` **流式块中根据 `event` 不同,结构也不同:** ##### event: workflow_started workflow 开始执行 | 字段 | 类型 | 描述 | |------|------|------| | `task_id` | string | 任务 ID,用于请求跟踪和下方的停止响应接口 | | `workflow_run_id` | string | workflow 执行 ID | | `event` | string | 固定为 `workflow_started` | | `data` | object | 详细内容 | | `data.id` | string | workflow 执行 ID | | `data.workflow_id` | string | 关联 Workflow ID | | `data.created_at` | timestamp | 开始时间 | ##### event: node_started node 开始执行 | 字段 | 类型 | 描述 | |------|------|------| | `task_id` | string | 任务 ID,用于请求跟踪和下方的停止响应接口 | | `workflow_run_id` | string | workflow 执行 ID | | `event` | string | 固定为 `node_started` | | `data` | object | 详细内容 | | `data.id` | string | workflow 执行 ID | | `data.node_id` | string | 节点 ID | | `data.node_type` | string | 节点类型 | | `data.title` | string | 节点名称 | | `data.index` | int | 执行序号,用于展示 Tracing Node 顺序 | | `data.predecessor_node_id` | string | 前置节点 ID,用于画布展示执行路径 | | `data.inputs` | object | 节点中所有使用到的前置节点变量内容 | | `data.created_at` | timestamp | 开始时间 | ##### event: node_finished node 执行结束,成功失败同一事件中不同状态 | 字段 | 类型 | 描述 | |------|------|------| | `task_id` | string | 任务 ID,用于请求跟踪和下方的停止响应接口 | | `workflow_run_id` | string | workflow 执行 ID | | `event` | string | 固定为 `node_finished` | | `data` | object | 详细内容 | | `data.id` | string | node 执行 ID | | `data.node_id` | string | 节点 ID | | `data.index` | int | 执行序号,用于展示 Tracing Node 顺序 | | `data.predecessor_node_id` | string | optional 前置节点 ID,用于画布展示执行路径 | | `data.inputs` | object | 节点中所有使用到的前置节点变量内容 | | `data.process_data` | json | Optional 节点过程数据 | | `data.outputs` | json | Optional 输出内容 | | `data.status` | string | 执行状态 running / succeeded / failed / stopped | | `data.error` | string | Optional 错误原因 | | `data.elapsed_time` | float | Optional 耗时(s) | | `data.execution_metadata` | json | 元数据 | | `data.execution_metadata.total_tokens` | int | optional 总使用 tokens | | `data.execution_metadata.total_price` | decimal | optional 总费用 | | `data.execution_metadata.currency` | string | optional 货币,如 USD / RMB | | `data.created_at` | timestamp | 开始时间 | ##### event: workflow_finished workflow 执行结束,成功失败同一事件中不同状态 | 字段 | 类型 | 描述 | |------|------|------| | `task_id` | string | 任务 ID,用于请求跟踪和下方的停止响应接口 | | `workflow_run_id` | string | workflow 执行 ID | | `event` | string | 固定为 `workflow_finished` | | `data` | object | 详细内容 | | `data.id` | string | workflow 执行 ID | | `data.workflow_id` | string | 关联 Workflow ID | | `data.status` | string | 执行状态 running / succeeded / failed / stopped | | `data.outputs` | json | Optional 输出内容 | | `data.error` | string | Optional 错误原因 | | `data.elapsed_time` | float | Optional 耗时(s) | | `data.total_tokens` | int | Optional 总使用 tokens | | `data.total_steps` | int | 总步数(冗余),默认 0 | | `data.created_at` | timestamp | 开始时间 | | `data.finished_at` | timestamp | 结束时间 | ##### event: message LLM 返回文本块事件,即:完整的文本以分块的方式输出。 | 字段 | 类型 | 描述 | |------|------|------| | `task_id` | string | 任务 ID,用于请求跟踪和下方的停止响应接口 | | `message_id` | string | 消息唯一 ID | | `conversation_id` | string | 会话 ID | | `answer` | string | LLM 返回文本块内容 | | `created_at` | int | 创建时间戳,如:1705395332 | ##### event: message_file 文件事件,表示有新文件需要展示 | 字段 | 类型 | 描述 | |------|------|------| | `id` | string | 文件唯一ID | | `type` | string | 文件类型,目前仅为image | | `belongs_to` | string | 文件归属,user或assistant,该接口返回仅为 assistant | | `url` | string | 文件访问地址 | | `conversation_id` | string | 会话ID | ##### event: message_end 消息结束事件,收到此事件则代表流式返回结束。 | 字段 | 类型 | 描述 | |------|------|------| | `task_id` | string | 任务 ID,用于请求跟踪和下方的停止响应接口 | | `message_id` | string | 消息唯一 ID | | `conversation_id` | string | 会话 ID | | `metadata` | object | 元数据 | | `usage` | Usage | 模型用量信息 | | `retriever_resources` | array[RetrieverResource] | 引用和归属分段列表 | ##### event: tts_message TTS 音频流事件,即:语音合成输出。内容是Mp3格式的音频块,使用 base64 编码后的字符串,播放的时候直接解码即可。(开启自动播放才有此消息) | 字段 | 类型 | 描述 | |------|------|------| | `task_id` | string | 任务 ID,用于请求跟踪和下方的停止响应接口 | | `message_id` | string | 消息唯一 ID | | `audio` | string | 语音合成之后的音频块使用 Base64 编码之后的文本内容,播放的时候直接 base64 解码送入播放器即可 | | `created_at` | int | 创建时间戳,如:1705395332 | ##### event: tts_message_end TTS 音频流结束事件,收到这个事件表示音频流返回结束。 | 字段 | 类型 | 描述 | |------|------|------| | `task_id` | string | 任务 ID,用于请求跟踪和下方的停止响应接口 | | `message_id` | string | 消息唯一 ID | | `audio` | string | 结束事件是没有音频的,所以这里是空字符串 | | `created_at` | int | 创建时间戳,如:1705395332 | ##### event: message_replace 消息内容替换事件。开启内容审查和审查输出内容时,若命中了审查条件,则会通过此事件替换消息内容为预设回复。 | 字段 | 类型 | 描述 | |------|------|------| | `task_id` | string | 任务 ID,用于请求跟踪和下方的停止响应接口 | | `message_id` | string | 消息唯一 ID | | `conversation_id` | string | 会话 ID | | `answer` | string | 替换内容(直接替换 LLM 所有回复文本) | | `created_at` | int | 创建时间戳,如:1705395332 | ##### event: error 流式输出过程中出现的异常会以 stream event 形式输出,收到异常事件后即结束。 | 字段 | 类型 | 描述 | |------|------|------| | `task_id` | string | 任务 ID,用于请求跟踪和下方的停止响应接口 | | `message_id` | string | 消息唯一 ID | | `status` | int | HTTP 状态码 | | `code` | string | 错误码 | | `message` | string | 错误消息 | ##### event: ping 每 10s 一次的 ping 事件,保持连接存活。 ### Errors - `404` - 对话不存在 - `400, invalid_param` - 传入参数异常 - `400, app_unavailable` - App 配置不可用 - `400, provider_not_initialize` - 无可用模型凭据配置 - `400, provider_quota_exceeded` - 模型调用额度不足 - `400, model_currently_not_support` - 当前模型不可用 - `400, workflow_not_found` - 指定的工作流版本未找到 - `400, draft_workflow_error` - 无法使用草稿工作流版本 - `400, workflow_id_format_error` - 工作流ID格式错误,需要UUID格式 - `400, completion_request_error` - 文本生成失败 - `500` - 服务内部异常 ### Request 示例 ```bash curl -X POST 'http://dify.ireborn.com.cn/v1/chat-messages' \ --header 'Authorization: Bearer {api_key}' \ --header 'Content-Type: application/json' \ --data-raw '{ "inputs": {}, "query": "What are the specs of the iPhone 13 Pro Max?", "response_mode": "streaming", "conversation_id": "", "user": "abc-123", "files": [ { "type": "image", "transfer_method": "remote_url", "url": "https://cloud.dify.ai/logo/logo-site.png" } ] }' ``` ### Response 示例 #### 阻塞模式 ```json { "event": "message", "task_id": "c3800678-a077-43df-a102-53f23ed20b88", "id": "9da23599-e713-473b-982c-4328d4f5c78a", "message_id": "9da23599-e713-473b-982c-4328d4f5c78a", "conversation_id": "45701982-8118-4bc5-8e9b-64562b4555f2", "mode": "chat", "answer": "iPhone 13 Pro Max specs are listed here:...", "metadata": { "usage": { "prompt_tokens": 1033, "prompt_unit_price": "0.001", "prompt_price_unit": "0.001", "prompt_price": "0.0010330", "completion_tokens": 128, "completion_unit_price": "0.002", "completion_price_unit": "0.001", "completion_price": "0.0002560", "total_tokens": 1161, "total_price": "0.0012890", "currency": "USD", "latency": 0.7682376249867957 }, "retriever_resources": [ { "position": 1, "dataset_id": "101b4c97-fc2e-463c-90b1-5261a4cdcafb", "dataset_name": "iPhone", "document_id": "8dd1ad74-0b5f-4175-b735-7d98bbbb4e00", "document_name": "iPhone List", "segment_id": "ed599c7f-2766-4294-9d1d-e5235a61270a", "score": 0.98457545, "content": "\"Model\",\"Release Date\",\"Display Size\",\"Resolution\",\"Processor\",\"RAM\",\"Storage\",\"Camera\",\"Battery\",\"Operating System\"\n\"iPhone 13 Pro Max\",\"September 24, 2021\",\"6.7 inch\",\"1284 x 2778\",\"Hexa-core (2x3.23 GHz Avalanche + 4x1.82 GHz Blizzard)\",\"6 GB\",\"128, 256, 512 GB, 1TB\",\"12 MP\",\"4352 mAh\",\"iOS 15\"" } ] }, "created_at": 1705407629 } ``` #### 流式模式 ``` data: {"event": "workflow_started", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "workflow_id": "dfjasklfjdslag", "created_at": 1679586595}} data: {"event": "node_started", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "node_id": "dfjasklfjdslag", "node_type": "start", "title": "Start", "index": 0, "predecessor_node_id": "fdljewklfklgejlglsd", "inputs": {}, "created_at": 1679586595}} data: {"event": "node_finished", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "node_id": "dfjasklfjdslag", "node_type": "start", "title": "Start", "index": 0, "predecessor_node_id": "fdljewklfklgejlglsd", "inputs": {}, "outputs": {}, "status": "succeeded", "elapsed_time": 0.324, "execution_metadata": {"total_tokens": 63127864, "total_price": 2.378, "currency": "USD"}, "created_at": 1679586595}} data: {"event": "workflow_finished", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "workflow_id": "dfjasklfjdslag", "outputs": {}, "status": "succeeded", "elapsed_time": 0.324, "total_tokens": 63127864, "total_steps": "1", "created_at": 1679586595, "finished_at": 1679976595}} data: {"event": "message", "message_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "conversation_id": "45701982-8118-4bc5-8e9b-64562b4555f2", "answer": " I", "created_at": 1679586595} data: {"event": "message", "message_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "conversation_id": "45701982-8118-4bc5-8e9b-64562b4555f2", "answer": "'m", "created_at": 1679586595} data: {"event": "message", "message_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "conversation_id": "45701982-8118-4bc5-8e9b-64562b4555f2", "answer": " glad", "created_at": 1679586595} data: {"event": "message", "message_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "conversation_id": "45701982-8118-4bc5-8e9b-64562b4555f2", "answer": " to", "created_at": 1679586595} data: {"event": "message", "message_id" : "5ad4cb98-f0c7-4085-b384-88c403be6290", "conversation_id": "45701982-8118-4bc5-8e9b-64562b4555f2", "answer": " meet", "created_at": 1679586595} data: {"event": "message", "message_id" : "5ad4cb98-f0c7-4085-b384-88c403be6290", "conversation_id": "45701982-8118-4bc5-8e9b-64562b4555f2", "answer": " you", "created_at": 1679586595} data: {"event": "message_end", "id": "5e52ce04-874b-4d27-9045-b3bc80def685", "conversation_id": "45701982-8118-4bc5-8e9b-64562b4555f2", "metadata": {"usage": {"prompt_tokens": 1033, "prompt_unit_price": "0.001", "prompt_price_unit": "0.001", "prompt_price": "0.0010330", "completion_tokens": 135, "completion_unit_price": "0.002", "completion_price_unit": "0.001", "completion_price": "0.0002700", "total_tokens": 1168, "total_price": "0.0013030", "currency": "USD", "latency": 1.381760165997548}, "retriever_resources": [{"position": 1, "dataset_id": "101b4c97-fc2e-463c-90b1-5261a4cdcafb", "dataset_name": "iPhone", "document_id": "8dd1ad74-0b5f-4175-b735-7d98bbbb4e00", "document_name": "iPhone List", "segment_id": "ed599c7f-2766-4294-9d1d-e5235a61270a", "score": 0.98457545, "content": "\"Model\",\"Release Date\",\"Display Size\",\"Resolution\",\"Processor\",\"RAM\",\"Storage\",\"Camera\",\"Battery\",\"Operating System\"\n\"iPhone 13 Pro Max\",\"September 24, 2021\",\"6.7 inch\",\"1284 x 2778\",\"Hexa-core (2x3.23 GHz Avalanche + 4x1.82 GHz Blizzard)\",\"6 GB\",\"128, 256, 512 GB, 1TB\",\"12 MP\",\"4352 mAh\",\"iOS 15\""}]}} data: {"event": "tts_message", "conversation_id": "23dd85f3-1a41-4ea0-b7a9-062734ccfaf9", "message_id": "a8bdc41c-13b2-4c18-bfd9-054b9803038c", "created_at": 1721205487, "task_id": "3bf8a0bb-e73b-4690-9e66-4e429bad8ee7", "audio": "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq"} data: {"event": "tts_message_end", "conversation_id": "23dd85f3-1a41-4ea0-b7a9-062734ccfaf9", "message_id": "a8bdc41c-13b2-4c18-bfd9-054b9803038c", "created_at": 1721205487, "task_id": "3bf8a0bb-e73b-4690-9e66-4e429bad8ee7", "audio": ""} ``` --- ## POST /files/upload - 上传文件 上传文件并在发送消息时使用,可实现图文多模态理解。支持您的应用程序所支持的所有格式。上传的文件仅供当前终端用户使用。 该接口需使用 `multipart/form-data` 进行请求。 ### Request Body | Name | Type | Description | |------|------|-------------| | `file` | file | 要上传的文件。 | | `user` | string | 用户标识,用于定义终端用户的身份,必须和发送消息接口传入 user 保持一致。 | ### Response 成功上传后,服务器会返回文件的 ID 和相关信息。 | 字段 | 类型 | 描述 | |------|------|------| | `id` | uuid | ID | | `name` | string | 文件名 | | `size` | int | 文件大小(byte) | | `extension` | string | 文件后缀 | | `mime_type` | string | 文件 mime-type | | `created_by` | uuid | 上传人 ID | | `created_at` | timestamp | 上传时间 | ### Errors - `400, no_file_uploaded` - 必须提供文件 - `400, too_many_files` - 目前只接受一个文件 - `400, unsupported_preview` - 该文件不支持预览 - `400, unsupported_estimate` - 该文件不支持估算 - `413, file_too_large` - 文件太大 - `415, unsupported_file_type` - 不支持的扩展名,当前只接受文档类文件 - `503, s3_connection_failed` - 无法连接到 S3 服务 - `503, s3_permission_denied` - 无权限上传文件到 S3 - `503, s3_file_too_large` - 文件超出 S3 大小限制 ### Request 示例 ```bash curl -X POST 'http://dify.ireborn.com.cn/v1/files/upload' \ --header 'Authorization: Bearer {api_key}' \ --form 'file=@localfile;type=image/[png|jpeg|jpg|webp|gif]' \ --form 'user=abc-123' ``` ### Response 示例 ```json { "id": "72fa9618-8f89-4a37-9b33-7e1178a24a67", "name": "example.png", "size": 1024, "extension": "png", "mime_type": "image/png", "created_by": 123, "created_at": 1577836800 } ``` --- ## POST /chat-messages/:task_id/stop - 停止响应 仅支持流式模式。 ### Path | 参数 | 类型 | 描述 | |------|------|------| | `task_id` | string | 任务 ID,可在流式返回 Chunk 中获取 | ### Request Body | Name | Type | Description | |------|------|-------------| | `user` | string | Required 用户标识,用于定义终端用户的身份,必须和发送消息接口传入 user 保持一致。API 无法访问 WebApp 创建的会话。 | ### Response | 字段 | 类型 | 描述 | |------|------|------| | `result` | string | 固定返回 success | ### Request 示例 ```bash curl -X POST 'http://dify.ireborn.com.cn/v1/chat-messages/:task_id/stop' \ -H 'Authorization: Bearer {api_key}' \ -H 'Content-Type: application/json' \ --data-raw '{ "user": "abc-123" }' ``` ### Response 示例 ```json { "result": "success" } ``` --- ## 其他接口 文档还包含以下接口(此处仅列出标题,详细内容请查看原始文档): - POST /messages/:message_id/feedbacks - 消息反馈(点赞) - GET /app/feedbacks - 获取APP的消息点赞和反馈 - GET /messages/{message_id}/suggested - 获取下一轮建议问题列表 - GET /messages - 获取会话历史消息 - GET /conversations - 获取会话列表 - DELETE /conversations/:conversation_id - 删除会话 - POST /conversations/:conversation_id/name - 会话重命名 - GET /conversations/:conversation_id/variables - 获取对话变量 - PUT /conversations/:conversation_id/variables/:variable_id - 更新对话变量 - POST /audio-to-text - 语音转文字 - POST /text-to-audio - 文字转语音 - GET /info - 获取应用基本信息 - GET /parameters - 获取应用参数 - GET /meta - 获取应用Meta信息 - GET /site - 获取应用 WebApp 设置 - GET /apps/annotations - 获取标注列表 - POST /apps/annotations - 创建标注 - PUT /apps/annotations/{annotation_id} - 更新标注 - DELETE /apps/annotations/{annotation_id} - 删除标注 - POST /apps/annotation-reply/{action} - 标注回复初始设置 - GET /apps/annotation-reply/{action}/status/{job_id} - 查询标注回复初始设置任务状态 --- ## 关键说明 ### 流式模式事件流程 对于工作流编排的对话应用,典型的事件流程如下: 1. `workflow_started` - 工作流开始(包含 conversation_id) 2. `node_started` - 节点开始执行 3. `node_finished` - 节点执行完成(可能包含输出数据) 4. `workflow_finished` - 工作流完成(包含最终输出) 5. `message` - LLM 文本块(逐字返回,可能有多个) 6. `message_end` - 消息结束 ### conversation_id 管理 - **首次对话**:不传 `conversation_id`,系统会在 `workflow_started` 事件中返回新的 `conversation_id` - **续接对话**:传入之前获取的 `conversation_id`,保持上下文连续性 ### 重要注意事项 1. API Key 必须放在后端,不要暴露在客户端 2. 流式模式使用 SSE(Server-Sent Events)协议 3. 每个事件块以 `data:` 开头,块之间用 `\n\n` 分隔 4. Cloudflare 有 100 秒超时限制(阻塞模式) 5. 流式模式每 10 秒发送一次 ping 事件保持连接