Unified Endpoint
发送统一 OpenAI 兼容消息
当前系统只暴露一个统一入口 POST /v1/chat/completions。
网关会基于 Authorization 与
model 解析 Dify
配置,并自动路由到不同上游应用。
文本生成型应用
/completion-messages
对话型应用
/chat-messages
工作流编排对话型应用
/chat-messages
Workflow 应用
/workflows/run
唯一鉴权规范
Authorization
Bearer <DIFY_API_URL>
必须传 Dify API 基础地址,例如:https://api.dify.ai/v1
model
dify|BOT_TYPE|API_KEY
BOT_TYPE 只允许 Completion、Chat、Workflow。
API_KEY 例如:app-xxxx
四类应用映射
| 应用类型 | model | 上游路径 | 说明 |
|---|---|---|---|
| 文本生成型应用 | dify|Completion|API_KEY |
/completion-messages |
优先消费 prompt,否则提取最后一条消息文本。 |
| 对话型应用 | dify|Chat|API_KEY |
/chat-messages |
优先使用 query,其次 prompt。 |
| 工作流编排对话型应用 | dify|Chat|API_KEY |
/chat-messages |
仍走 Chat 路径,但会产生更丰富的 workflow 事件并透传到 x_dify。 |
| Workflow 应用 | dify|Workflow|API_KEY |
/workflows/run 或 /workflows/{workflow_id}/run |
支持 streaming 与 blocking,两者都映射回统一 OpenAI 外层结构。 |
请求 Schema
文本生成型应用,请求最终会路由到
/completion-messages。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
model |
string | 是 | 固定格式 dify|Completion|API_KEY。 |
变量透传说明
顶层
variable 会被直接映射到 Dify inputs。
可使用 input_*、output_*、custom_*、system_*、user_*
等自定义变量名,不做特殊解析、不改名、不分组,最终都会随 variable 一起原样透传。注意需要先在 Dify 开始节点中新增对应的段落类型输入字段。
{
"model": "dify|Completion|app-xxxx",
"stream": true,
"response_mode": "streaming",
"user": "demo-user",
"prompt": "请把下面内容翻译成英文:今天天气很好。"
}
curl 'http://127.0.0.1:3099/v1/chat/completions' \
--request POST \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer https://api.dify.ai/v1' \
--data '{
"model": "dify|Completion|app-xxxx",
"stream": true,
"response_mode": "streaming",
"user": "demo-user",
"prompt": "请把下面内容翻译成英文:今天天气很好。"
}'
事件类型
下面不是事件列表表格,而是每一种 Dify SSE 事件的严格对象示例。所有原始事件最终都会进入
x_dify.raw_event,部分事件还会同时参与 OpenAI 文本 delta 映射。
messageCompletion / Chat 文本事件
{
"event": "message",
"task_id": "task-xxx",
"message_id": "msg-xxx",
"conversation_id": "conv-xxx",
"answer": "Hello world",
"created_at": 1710000000,
"metadata": {
"usage": {
"prompt_tokens": 12,
"completion_tokens": 8,
"total_tokens": 20
}
}
}
agent_messageChat / 工作流编排对话型应用文本事件
{
"event": "agent_message",
"task_id": "task-xxx",
"message_id": "msg-xxx",
"conversation_id": "conv-xxx",
"answer": "这是 Agent 生成的回复片段。",
"created_at": 1710000001
}
message_replace替换型文本事件
{
"event": "message_replace",
"task_id": "task-xxx",
"message_id": "msg-xxx",
"conversation_id": "conv-xxx",
"answer": "这是用于替换先前内容的文本。",
"created_at": 1710000002
}
text_chunkCompletion / Chat / Workflow 通用文本分片
{
"event": "text_chunk",
"task_id": "task-xxx",
"message_id": "msg-xxx",
"conversation_id": "conv-xxx",
"text": "这是一个增量文本分片",
"created_at": 1710000003
}
message_file文件事件,仅透传到 x_dify
{
"event": "message_file",
"task_id": "task-xxx",
"message_id": "msg-xxx",
"conversation_id": "conv-xxx",
"file": {
"id": "file-xxx",
"type": "image",
"url": "https://example.com/result.png",
"belongs_to": "assistant"
},
"created_at": 1710000004
}
agent_thoughtAgent 思考过程事件
{
"event": "agent_thought",
"task_id": "task-xxx",
"message_id": "msg-xxx",
"conversation_id": "conv-xxx",
"thought": "我需要先检索知识库,再总结答案。",
"position": 1,
"created_at": 1710000005
}
tts_message音频分片事件
{
"event": "tts_message",
"task_id": "task-xxx",
"message_id": "msg-xxx",
"conversation_id": "conv-xxx",
"audio": "base64-audio-chunk",
"created_at": 1710000006
}
tts_message_end音频结束事件
{
"event": "tts_message_end",
"task_id": "task-xxx",
"message_id": "msg-xxx",
"conversation_id": "conv-xxx",
"created_at": 1710000007
}
workflow_started
工作流开始事件
{
"event": "workflow_started",
"task_id": "task-xxx",
"workflow_run_id": "wf-xxx",
"data": {
"id": "wf-xxx",
"workflow_id": "workflow-123",
"status": "running",
"created_at": 1710000008
}
}
node_started工作流节点开始
{
"event": "node_started",
"task_id": "task-xxx",
"workflow_run_id": "wf-xxx",
"data": {
"node_id": "node-1",
"node_type": "llm",
"title": "总结节点",
"index": 1,
"predecessor_node_id": null,
"created_at": 1710000009
}
}
node_finished工作流节点完成
{
"event": "node_finished",
"task_id": "task-xxx",
"workflow_run_id": "wf-xxx",
"data": {
"node_id": "node-1",
"node_type": "llm",
"title": "总结节点",
"status": "succeeded",
"elapsed_time": 1.28,
"outputs": {
"text": "节点产出的文本结果"
},
"finished_at": 1710000010
}
}
node_retry工作流节点重试
{
"event": "node_retry",
"task_id": "task-xxx",
"workflow_run_id": "wf-xxx",
"data": {
"node_id": "node-1",
"node_type": "llm",
"title": "总结节点",
"retry_index": 1,
"error": "upstream timeout",
"created_at": 1710000011
}
}
workflow_finished
工作流结束,可携带最终 outputs
{
"event": "workflow_finished",
"task_id": "task-xxx",
"workflow_run_id": "wf-xxx",
"data": {
"id": "wf-xxx",
"workflow_id": "workflow-123",
"status": "succeeded",
"outputs": {
"text": "这是最终工作流输出",
"result": "structured-output"
},
"elapsed_time": 3.42,
"finished_at": 1710000012
}
}
message_end消息结束事件
{
"event": "message_end",
"task_id": "task-xxx",
"message_id": "msg-xxx",
"conversation_id": "conv-xxx",
"metadata": {
"usage": {
"prompt_tokens": 12,
"completion_tokens": 8,
"total_tokens": 20
}
},
"created_at": 1710000013
}
ping保活事件
{
"event": "ping"
}
error错误事件,最终会映射为 OpenAI 错误输出
{
"event": "error",
"task_id": "task-xxx",
"message": "upstream service unavailable",
"status": 503,
"code": "service_unavailable"
}
SSE 映射规则
- Completion:
message/agent_message/text_chunk/message_replace输出文本 delta;message_end输出 stop chunk。 - Chat / Advanced Chat:文本事件输出
choices[0].delta.content;非文本事件只透传x_dify。 - Workflow:
text_chunk输出文本 delta;workflow_finished若可解析最终 outputs,则额外输出最终文本 chunk。 - 错误处理:
error会先保留到x_dify,再输出 OpenAI 错误行,最后结束流。
响应结构
OpenAI 兼容响应
{
"id": "chatcmpl-6a3d4283-5c77-4300-b7d9-4d6686e8df0c",
"object": "chat.completion",
"created": 1776284129,
"model": "dify|Chat|app-xxxx",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "你好,我是一个可以继续上下文的对话助手。"
},
"logprobs": null,
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 18,
"completion_tokens": 16,
"total_tokens": 34
},
"system_fingerprint": "fp_2f57f81c11",
"x_dify": {
"event": "message",
"conversation_id": "fa2f6006-934c-40f8-bccb-339ae1f045aa",
"metadata": {
"usage": {
"prompt_tokens": 18,
"completion_tokens": 16,
"total_tokens": 34
}
},
"raw_event": {
"event": "message"
}
}
}
字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
id |
string | OpenAI 风格响应 ID。 |
object |
string | 非流式时通常为 chat.completion,流式时为 chat.completion.chunk。 |
model |
string | 透传展示当前请求的 model 配置。 |
choices |
array | 兼容 OpenAI 的响应 choices。 |
usage |
object | 根据 Dify metadata.usage 映射出的 token 统计。 |
x_dify |
object | 扩展字段,保留 Dify 原始事件、元数据与上下文信息。 |