"""导入产品推荐 Workflow 到 Dify/BaoDan。 使用方式: python scripts/import_workflow.py [--base-url URL] [--token TOKEN] 参数: --base-url Dify API 地址(默认 http://localhost:5001) --token Dify Console API Token(登录后从浏览器 Cookie 或 API 管理页面获取) 导入完成后,还需要在 Dify 后台: 1. 打开导入的"产品推荐方案生成" Workflow 2. 绑定知识库(节点3:知识库检索 → 选择已创建的知识库) 3. 确认 LLM 模型配置(节点4:方案生成 → 选择 DeepSeek) 4. 点击"发布" 5. 在"访问 API"页面创建 API Key,填入 .env 的 BAODAN_WORKFLOW_API_KEY """ import argparse import json import sys from pathlib import Path import requests def find_existing_app(base_url: str, token: str) -> str | None: """查找已存在的同名 Workflow 应用。""" headers = { "Authorization": f"Bearer {token}", "Content-Type": "application/json", } page = 1 while True: resp = requests.get( f"{base_url}/console/api/apps", params={"page": page, "limit": 100}, headers=headers, timeout=30 ) if resp.status_code != 200: break data = resp.json() apps = data.get("data", []) if not apps: break for app in apps: if app.get("name") == "产品推荐方案生成" and app.get("mode") == "workflow": return app.get("id") if len(apps) < 100: break page += 1 return None def import_workflow(base_url: str, token: str, yaml_path: str) -> dict: """通过 Dify Console API 导入 Workflow DSL(如果不存在则复用)。""" headers = { "Authorization": f"Bearer {token}", "Content-Type": "application/json", } # 先检查是否已存在同名应用 existing_app_id = find_existing_app(base_url, token) if existing_app_id: print(f"♻️ 复用已存在的应用,App ID: {existing_app_id}") return {"app_id": existing_app_id, "status": "reused"} url = f"{base_url}/console/api/apps/imports" with open(yaml_path, "r", encoding="utf-8") as f: yaml_content = f.read() payload = { "mode": "yaml-content", "yaml_content": yaml_content, "name": "产品推荐方案生成", "description": "根据客户信息和知识库检索结果,生成基础/均衡/全面三套保险推荐方案", "icon_type": "emoji", "icon": "\U0001F3E6", "icon_background": "#E4FBCC", } print(f"正在导入 Workflow 到 {base_url} ...") resp = requests.post(url, json=payload, headers=headers, timeout=30) result = resp.json() if resp.status_code == 200: print(f"✓ 导入成功!") print(f" App ID: {result.get('app_id', 'N/A')}") print(f" App Mode: {result.get('app_mode', 'N/A')}") print(f" Status: {result.get('status', 'N/A')}") return result elif resp.status_code == 202: # 版本不匹配,需要确认 import_id = result.get("id") print(f"⚠ 需要确认导入(版本不匹配)") print(f" Import ID: {import_id}") print(f" 当前版本: {result.get('current_dsl_version')}") print(f" 导入版本: {result.get('imported_dsl_version')}") confirm_url = f"{base_url}/console/api/apps/imports/{import_id}/confirm" confirm_resp = requests.post(confirm_url, headers=headers, timeout=30) confirm_result = confirm_resp.json() if confirm_resp.status_code == 200: print(f"✓ 确认导入成功!") print(f" App ID: {confirm_result.get('app_id', 'N/A')}") return confirm_result else: print(f"✗ 确认失败: {confirm_result}") return confirm_result else: print(f"✗ 导入失败 (HTTP {resp.status_code})") print(f" 错误: {result.get('message', result)}") return result def get_console_token_interactive(base_url: str) -> str: """交互式获取 Console Token。""" print() print("=" * 60) print(" 获取 Dify Console Token 的方法:") print("=" * 60) print() print(" 方法1:浏览器登录 Dify 后台 → F12 → Application → Cookies") print(" → 复制 dify_session 或 access_token 的值") print() print(" 方法2:使用 API 密钥管理页面生成的 Personal Access Token") print() token = input(" 请输入 Token: ").strip() return token def main(): parser = argparse.ArgumentParser(description="导入产品推荐 Workflow 到 Dify/BaoDan") parser.add_argument("--base-url", default="http://localhost:5001", help="Dify API 地址") parser.add_argument("--token", default="", help="Console API Token") parser.add_argument("--yaml", default="deploy/workflow_recommend.yml", help="DSL YAML 文件路径") args = parser.parse_args() # 确认 YAML 文件存在 yaml_path = Path(args.yaml) if not yaml_path.exists(): print(f"✗ 找不到 YAML 文件: {yaml_path}") sys.exit(1) # 获取 Token token = args.token if not token: token = get_console_token_interactive(args.base_url) if not token: print("✗ 未提供 Token,退出") sys.exit(1) # 导入 result = import_workflow(args.base_url, token, str(yaml_path)) if result.get("app_id"): print() print("=" * 60) print(" 后续步骤:") print("=" * 60) print() print(f" 1. 打开 Dify 后台 → 找到「产品推荐方案生成」应用") print(f" 2. 进入 Workflow 编辑器 → 点击「知识库检索」节点") print(f" → 替换 dataset_ids 为实际知识库 ID") print(f" 3. 点击「方案生成」节点 → 确认模型为 deepseek-chat") print(f" 4. 点击右上角「发布」按钮") print(f" 5. 进入「访问 API」页面 → 创建 API Key") print(f" 6. 将 API Key 填入 .env 的 BAODAN_WORKFLOW_API_KEY") print() if __name__ == "__main__": main()