|
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+# Dify API 集成指南
|
|
|
2
|
+
|
|
|
3
|
+> 西安云美电子科技有限公司 - 企业知识库
|
|
|
4
|
+> 版本:v1.0 | 创建时间:2026-06-06
|
|
|
5
|
+
|
|
|
6
|
+---
|
|
|
7
|
+
|
|
|
8
|
+## 1. 概述
|
|
|
9
|
+
|
|
|
10
|
+Dify 提供完整的 RESTful API,支持将知识库对话能力集成到企业微信、钉钉、自建系统等渠道。本文档涵盖最常用的 API 接口及集成示例。
|
|
|
11
|
+
|
|
|
12
|
+**Base URL**: `http://<dify-host>/v1`
|
|
|
13
|
+
|
|
|
14
|
+---
|
|
|
15
|
+
|
|
|
16
|
+## 2. 认证方式
|
|
|
17
|
+
|
|
|
18
|
+所有 API 请求需在 Header 中携带 API Key:
|
|
|
19
|
+
|
|
|
20
|
+```
|
|
|
21
|
+Authorization: Bearer app-<your-api-key>
|
|
|
22
|
+```
|
|
|
23
|
+
|
|
|
24
|
+**获取 API Key**:Dify 控制台 → 应用 → API 访问 → 创建 API Key
|
|
|
25
|
+
|
|
|
26
|
+---
|
|
|
27
|
+
|
|
|
28
|
+## 3. 对话接口
|
|
|
29
|
+
|
|
|
30
|
+### 3.1 发送对话消息
|
|
|
31
|
+
|
|
|
32
|
+```
|
|
|
33
|
+POST /v1/chat-messages
|
|
|
34
|
+```
|
|
|
35
|
+
|
|
|
36
|
+**请求参数**
|
|
|
37
|
+
|
|
|
38
|
+| 参数 | 类型 | 必填 | 说明 |
|
|
|
39
|
+|------|------|:----:|------|
|
|
|
40
|
+| query | string | ✅ | 用户输入的问题 |
|
|
|
41
|
+| inputs | object | ❌ | 额外输入参数 |
|
|
|
42
|
+| response_mode | string | ✅ | `blocking`(阻塞)或 `streaming`(流式) |
|
|
|
43
|
+| conversation_id | string | ❌ | 对话 ID,首次对话不传,后续传入上一次返回的 ID |
|
|
|
44
|
+| user | string | ✅ | 用户标识 |
|
|
|
45
|
+| files | array | ❌ | 上传文件列表 |
|
|
|
46
|
+
|
|
|
47
|
+**阻塞模式请求示例**
|
|
|
48
|
+
|
|
|
49
|
+```bash
|
|
|
50
|
+curl -X POST 'http://<dify-host>/v1/chat-messages' \
|
|
|
51
|
+ -H 'Authorization: Bearer app-<api-key>' \
|
|
|
52
|
+ -H 'Content-Type: application/json' \
|
|
|
53
|
+ -d '{
|
|
|
54
|
+ "query": "差旅报销标准是什么?",
|
|
|
55
|
+ "inputs": {},
|
|
|
56
|
+ "response_mode": "blocking",
|
|
|
57
|
+ "user": "zhangsan"
|
|
|
58
|
+ }'
|
|
|
59
|
+```
|
|
|
60
|
+
|
|
|
61
|
+**阻塞模式响应**
|
|
|
62
|
+
|
|
|
63
|
+```json
|
|
|
64
|
+{
|
|
|
65
|
+ "task_id": "xxx",
|
|
|
66
|
+ "message_id": "xxx",
|
|
|
67
|
+ "conversation_id": "xxx",
|
|
|
68
|
+ "answer": "根据《差旅管理制度》第三章:\n\n1. 住宿标准:一线城市 500 元/晚...\n2. 交通标准:高铁二等座...",
|
|
|
69
|
+ "created_at": 1717632000
|
|
|
70
|
+}
|
|
|
71
|
+```
|
|
|
72
|
+
|
|
|
73
|
+**流式模式响应(SSE)**
|
|
|
74
|
+
|
|
|
75
|
+```
|
|
|
76
|
+data: {"event": "message", "message_id": "xxx", "conversation_id": "xxx", "answer": "根据", ...}
|
|
|
77
|
+data: {"event": "message", "message_id": "xxx", "conversation_id": "xxx", "answer": "根据《", ...}
|
|
|
78
|
+data: {"event": "message_end", ...}
|
|
|
79
|
+```
|
|
|
80
|
+
|
|
|
81
|
+### 3.2 获取对话历史
|
|
|
82
|
+
|
|
|
83
|
+```
|
|
|
84
|
+GET /v1/messages?conversation_id=<id>&user=<user>
|
|
|
85
|
+```
|
|
|
86
|
+
|
|
|
87
|
+**响应**
|
|
|
88
|
+
|
|
|
89
|
+```json
|
|
|
90
|
+{
|
|
|
91
|
+ "limit": 20,
|
|
|
92
|
+ "has_more": false,
|
|
|
93
|
+ "data": [
|
|
|
94
|
+ {
|
|
|
95
|
+ "id": "xxx",
|
|
|
96
|
+ "query": "差旅报销标准",
|
|
|
97
|
+ "answer": "根据《差旅管理制度》...",
|
|
|
98
|
+ "created_at": 1717632000
|
|
|
99
|
+ }
|
|
|
100
|
+ ]
|
|
|
101
|
+}
|
|
|
102
|
+```
|
|
|
103
|
+
|
|
|
104
|
+### 3.3 获取对话列表
|
|
|
105
|
+
|
|
|
106
|
+```
|
|
|
107
|
+GET /v1/conversations?user=<user>&last_id=<id>&limit=20&sort_by=-updated_at
|
|
|
108
|
+```
|
|
|
109
|
+
|
|
|
110
|
+### 3.4 重命名对话
|
|
|
111
|
+
|
|
|
112
|
+```
|
|
|
113
|
+PATCH /v1/conversations/<conversation_id>/name
|
|
|
114
|
+```
|
|
|
115
|
+
|
|
|
116
|
+```json
|
|
|
117
|
+{
|
|
|
118
|
+ "name": "报销相关问题"
|
|
|
119
|
+}
|
|
|
120
|
+```
|
|
|
121
|
+
|
|
|
122
|
+### 3.5 删除对话
|
|
|
123
|
+
|
|
|
124
|
+```
|
|
|
125
|
+DELETE /v1/conversations/<conversation_id>
|
|
|
126
|
+```
|
|
|
127
|
+
|
|
|
128
|
+---
|
|
|
129
|
+
|
|
|
130
|
+## 4. 知识库管理接口
|
|
|
131
|
+
|
|
|
132
|
+### 4.1 创建知识库
|
|
|
133
|
+
|
|
|
134
|
+```
|
|
|
135
|
+POST /v1/datasets
|
|
|
136
|
+```
|
|
|
137
|
+
|
|
|
138
|
+```json
|
|
|
139
|
+{
|
|
|
140
|
+ "name": "KB-RULE-制度流程",
|
|
|
141
|
+ "description": "公司各类管理制度和审批流程文档"
|
|
|
142
|
+}
|
|
|
143
|
+```
|
|
|
144
|
+
|
|
|
145
|
+### 4.2 获取知识库列表
|
|
|
146
|
+
|
|
|
147
|
+```
|
|
|
148
|
+GET /v1/datasets?page=1&page_size=20
|
|
|
149
|
+```
|
|
|
150
|
+
|
|
|
151
|
+### 4.3 上传文档到知识库
|
|
|
152
|
+
|
|
|
153
|
+**步骤一:创建上传任务**
|
|
|
154
|
+
|
|
|
155
|
+```
|
|
|
156
|
+POST /v1/datasets/<dataset_id>/document/create-by-file
|
|
|
157
|
+Content-Type: multipart/form-data
|
|
|
158
|
+```
|
|
|
159
|
+
|
|
|
160
|
+| 参数 | 类型 | 必填 | 说明 |
|
|
|
161
|
+|------|------|:----:|------|
|
|
|
162
|
+| file | file | ✅ | 文档文件(PDF/Word/TXT/Markdown/Excel) |
|
|
|
163
|
+| indexing_technique | string | ✅ | `high_quality`(高质量)或 `economy`(经济) |
|
|
|
164
|
+| process_rule | object | ❌ | 分段规则 |
|
|
|
165
|
+
|
|
|
166
|
+**分段规则示例**
|
|
|
167
|
+
|
|
|
168
|
+```json
|
|
|
169
|
+{
|
|
|
170
|
+ "mode": "automatic",
|
|
|
171
|
+ "rules": {
|
|
|
172
|
+ "pre_processing_rules": [
|
|
|
173
|
+ {"id": "remove_extra_spaces", "enabled": true},
|
|
|
174
|
+ {"id": "remove_urls_emails", "enabled": false}
|
|
|
175
|
+ ],
|
|
|
176
|
+ "segmentation": {
|
|
|
177
|
+ "max_segmentation_tokens_length": 500,
|
|
|
178
|
+ "overlap_tokens_length": 50,
|
|
|
179
|
+ "separator": ["\n", "\n\n", "。", "!", "?", ";"]
|
|
|
180
|
+ }
|
|
|
181
|
+ }
|
|
|
182
|
+}
|
|
|
183
|
+```
|
|
|
184
|
+
|
|
|
185
|
+**步骤二:查询上传进度**
|
|
|
186
|
+
|
|
|
187
|
+```
|
|
|
188
|
+GET /v1/datasets/<dataset_id>/documents/<document_id>/indexing-status
|
|
|
189
|
+```
|
|
|
190
|
+
|
|
|
191
|
+### 4.4 通过文本创建文档
|
|
|
192
|
+
|
|
|
193
|
+```
|
|
|
194
|
+POST /v1/datasets/<dataset_id>/document/create-by-text
|
|
|
195
|
+```
|
|
|
196
|
+
|
|
|
197
|
+```json
|
|
|
198
|
+{
|
|
|
199
|
+ "name": "报销流程说明",
|
|
|
200
|
+ "text": "## 报销流程\n\n1. 填写报销单...\n2. 部门审批...\n3. 财务审核...",
|
|
|
201
|
+ "indexing_technique": "high_quality",
|
|
|
202
|
+ "process_rule": {
|
|
|
203
|
+ "mode": "automatic"
|
|
|
204
|
+ }
|
|
|
205
|
+}
|
|
|
206
|
+```
|
|
|
207
|
+
|
|
|
208
|
+### 4.5 获取知识库文档列表
|
|
|
209
|
+
|
|
|
210
|
+```
|
|
|
211
|
+GET /v1/datasets/<dataset_id>/documents?page=1&page_size=20
|
|
|
212
|
+```
|
|
|
213
|
+
|
|
|
214
|
+### 4.6 删除文档
|
|
|
215
|
+
|
|
|
216
|
+```
|
|
|
217
|
+DELETE /v1/datasets/<dataset_id>/documents/<document_id>
|
|
|
218
|
+```
|
|
|
219
|
+
|
|
|
220
|
+---
|
|
|
221
|
+
|
|
|
222
|
+## 5. 集成示例
|
|
|
223
|
+
|
|
|
224
|
+### 5.1 Python 集成示例
|
|
|
225
|
+
|
|
|
226
|
+```python
|
|
|
227
|
+import requests
|
|
|
228
|
+
|
|
|
229
|
+DIFY_BASE_URL = "http://<dify-host>/v1"
|
|
|
230
|
+API_KEY = "app-<your-api-key>"
|
|
|
231
|
+
|
|
|
232
|
+def chat(query: str, user: str = "default", conversation_id: str = None):
|
|
|
233
|
+ """发送对话消息"""
|
|
|
234
|
+ headers = {
|
|
|
235
|
+ "Authorization": f"Bearer {API_KEY}",
|
|
|
236
|
+ "Content-Type": "application/json"
|
|
|
237
|
+ }
|
|
|
238
|
+ data = {
|
|
|
239
|
+ "query": query,
|
|
|
240
|
+ "inputs": {},
|
|
|
241
|
+ "response_mode": "blocking",
|
|
|
242
|
+ "user": user,
|
|
|
243
|
+ }
|
|
|
244
|
+ if conversation_id:
|
|
|
245
|
+ data["conversation_id"] = conversation_id
|
|
|
246
|
+
|
|
|
247
|
+ resp = requests.post(
|
|
|
248
|
+ f"{DIFY_BASE_URL}/chat-messages",
|
|
|
249
|
+ headers=headers,
|
|
|
250
|
+ json=data,
|
|
|
251
|
+ timeout=30
|
|
|
252
|
+ )
|
|
|
253
|
+ result = resp.json()
|
|
|
254
|
+ return {
|
|
|
255
|
+ "answer": result.get("answer", ""),
|
|
|
256
|
+ "conversation_id": result.get("conversation_id", ""),
|
|
|
257
|
+ "message_id": result.get("message_id", ""),
|
|
|
258
|
+ }
|
|
|
259
|
+
|
|
|
260
|
+# 使用示例
|
|
|
261
|
+result = chat("差旅报销标准是什么?", user="zhangsan")
|
|
|
262
|
+print(result["answer"])
|
|
|
263
|
+```
|
|
|
264
|
+
|
|
|
265
|
+### 5.2 企业微信 Webhook 集成
|
|
|
266
|
+
|
|
|
267
|
+```python
|
|
|
268
|
+from flask import Flask, request, jsonify
|
|
|
269
|
+import requests
|
|
|
270
|
+
|
|
|
271
|
+app = Flask(__name__)
|
|
|
272
|
+
|
|
|
273
|
+DIFY_API_KEY = "app-<your-api-key>"
|
|
|
274
|
+DIFY_BASE_URL = "http://<dify-host>/v1"
|
|
|
275
|
+
|
|
|
276
|
+@app.route("/wecom/webhook", methods=["POST"])
|
|
|
277
|
+def wecom_webhook():
|
|
|
278
|
+ """企业微信消息回调"""
|
|
|
279
|
+ data = request.json
|
|
|
280
|
+ user_query = data.get("Content", "")
|
|
|
281
|
+ user_id = data.get("FromUserName", "unknown")
|
|
|
282
|
+
|
|
|
283
|
+ # 调用 Dify API
|
|
|
284
|
+ resp = requests.post(
|
|
|
285
|
+ f"{DIFY_BASE_URL}/chat-messages",
|
|
|
286
|
+ headers={"Authorization": f"Bearer {DIFY_API_KEY}"},
|
|
|
287
|
+ json={
|
|
|
288
|
+ "query": user_query,
|
|
|
289
|
+ "response_mode": "blocking",
|
|
|
290
|
+ "user": user_id,
|
|
|
291
|
+ },
|
|
|
292
|
+ timeout=30
|
|
|
293
|
+ )
|
|
|
294
|
+ answer = resp.json().get("answer", "暂无回复")
|
|
|
295
|
+
|
|
|
296
|
+ # 返回企业微信消息格式
|
|
|
297
|
+ return jsonify({
|
|
|
298
|
+ "msgtype": "text",
|
|
|
299
|
+ "text": {"content": answer}
|
|
|
300
|
+ })
|
|
|
301
|
+
|
|
|
302
|
+if __name__ == "__main__":
|
|
|
303
|
+ app.run(host="0.0.0.0", port=5000)
|
|
|
304
|
+```
|
|
|
305
|
+
|
|
|
306
|
+### 5.3 Node.js 集成示例
|
|
|
307
|
+
|
|
|
308
|
+```javascript
|
|
|
309
|
+const axios = require('axios');
|
|
|
310
|
+
|
|
|
311
|
+const DIFY_BASE_URL = 'http://<dify-host>/v1';
|
|
|
312
|
+const API_KEY = 'app-<your-api-key>';
|
|
|
313
|
+
|
|
|
314
|
+async function chat(query, user = 'default') {
|
|
|
315
|
+ const { data } = await axios.post(
|
|
|
316
|
+ `${DIFY_BASE_URL}/chat-messages`,
|
|
|
317
|
+ {
|
|
|
318
|
+ query,
|
|
|
319
|
+ inputs: {},
|
|
|
320
|
+ response_mode: 'blocking',
|
|
|
321
|
+ user,
|
|
|
322
|
+ },
|
|
|
323
|
+ {
|
|
|
324
|
+ headers: {
|
|
|
325
|
+ 'Authorization': `Bearer ${API_KEY}`,
|
|
|
326
|
+ 'Content-Type': 'application/json',
|
|
|
327
|
+ },
|
|
|
328
|
+ timeout: 30000,
|
|
|
329
|
+ }
|
|
|
330
|
+ );
|
|
|
331
|
+ return {
|
|
|
332
|
+ answer: data.answer,
|
|
|
333
|
+ conversationId: data.conversation_id,
|
|
|
334
|
+ };
|
|
|
335
|
+}
|
|
|
336
|
+
|
|
|
337
|
+// 使用示例
|
|
|
338
|
+chat('差旅报销标准是什么?', 'zhangsan')
|
|
|
339
|
+ .then(result => console.log(result.answer));
|
|
|
340
|
+```
|
|
|
341
|
+
|
|
|
342
|
+---
|
|
|
343
|
+
|
|
|
344
|
+## 6. 错误处理
|
|
|
345
|
+
|
|
|
346
|
+| HTTP 状态码 | 说明 | 处理建议 |
|
|
|
347
|
+|:-----------:|------|---------|
|
|
|
348
|
+| 400 | 请求参数错误 | 检查请求体格式 |
|
|
|
349
|
+| 401 | API Key 无效 | 检查 Authorization Header |
|
|
|
350
|
+| 403 | 无权限访问 | 检查 API Key 权限配置 |
|
|
|
351
|
+| 429 | 请求频率超限 | 添加请求间隔/重试机制 |
|
|
|
352
|
+| 500 | 服务端内部错误 | 查看 Dify 服务日志 |
|
|
|
353
|
+
|
|
|
354
|
+**建议的重试策略**:
|
|
|
355
|
+
|
|
|
356
|
+```python
|
|
|
357
|
+import time
|
|
|
358
|
+
|
|
|
359
|
+def chat_with_retry(query, max_retries=3, retry_delay=2):
|
|
|
360
|
+ for attempt in range(max_retries):
|
|
|
361
|
+ try:
|
|
|
362
|
+ return chat(query)
|
|
|
363
|
+ except requests.exceptions.Timeout:
|
|
|
364
|
+ if attempt == max_retries - 1:
|
|
|
365
|
+ raise
|
|
|
366
|
+ time.sleep(retry_delay * (attempt + 1))
|
|
|
367
|
+ except requests.exceptions.HTTPError as e:
|
|
|
368
|
+ if e.response.status_code == 429:
|
|
|
369
|
+ time.sleep(retry_delay * (attempt + 1))
|
|
|
370
|
+ else:
|
|
|
371
|
+ raise
|
|
|
372
|
+```
|
|
|
373
|
+
|
|
|
374
|
+---
|
|
|
375
|
+
|
|
|
376
|
+## 7. API 速率限制
|
|
|
377
|
+
|
|
|
378
|
+| 计划类型 | 限制 |
|
|
|
379
|
+|----------|------|
|
|
|
380
|
+| 自部署版 | 无官方限制,受服务器资源约束 |
|
|
|
381
|
+| 建议配置 | 单用户 ≥ 60 次/分钟 |
|
|
|
382
|
+
|
|
|
383
|
+---
|
|
|
384
|
+
|
|
|
385
|
+_最后更新: 2026-06-06_
|