1. 为什么要在 SAE 上用 saectl 拉起 Dify + MCP Server
如果你正在找一个能快速把 AI 智能体应用跑起来、又不想被 K8s 运维拖住的方式,SAE(Serverless 应用引擎)配合 saectl 命令行工具,是目前比较省心的一条路径。Dify 负责可视化编排工作流和 Agent,MCP Server 负责把外部工具以统一协议暴露出来,两者组合之后,你只需要在 Dify 里拖拽节点、填一个 MCP 地址,就能让智能体调用真实工具。这套方案适合三类人:想快速验证 AI 智能体产品形态的独立开发者、需要把内部系统接入大模型能力的企业后端、以及不想维护集群但又要生产级可用性的小团队。
我这次实测的路径是:先用 saectl 把 Dify 社区版部署到 SAE,再把一个基于 MCP Python SDK 的 SSE 协议 Server 打包成镜像部署上去,最后在 Dify 里通过 MCP 插件把两者串起来。整个过程里,模型调用通道我用 TaoToken 统一管理 Key,这样 Dify 里的模型供应商配置只需要填一个地址和一把 Key,切换模型时不用改代码。下面把可复制的配置骨架、验证动作和踩过的坑都写清楚。
2. 前置准备:saectl 安装与 TaoToken 通道配置
2.1 saectl 工具安装与登录
saectl 是 SAE 提供的命令行工具,安装方式参考官方文档即可。安装完成后执行登录,绑定你的阿里云账号和地域:
saectl version saectl login --region cn-hangzhou登录成功后,后续所有 YAML 资源都会提交到你指定的地域。建议先用saectl config view确认当前上下文,避免把测试资源提交到生产地域。
2.2 TaoToken 统一 Key 与 API 通道
Dify 里要配置模型供应商,如果每个模型都单独填 Key,后期维护会很乱。我的做法是在 TaoToken 控制台创建一把 Key,然后在 Dify 的模型供应商里选择 OpenAI 兼容接口,把 API Base 填成 TaoToken 的地址,Key 填刚创建的那把。这样 Dify 内部所有模型调用都走同一条通道,换模型只改模型名。
具体操作路径:进入控制台创建 API Key,然后打开接入文档确认 Base URL 格式。模型对话调试可以直接在模型对话页面验证 Key 是否可用,长期跑编码类 Agent 的话可以看 Coding Plan 的额度说明。API 地址统一用https://taotoken.net/api,不要带多余路径。
# 本地先验证 Key 是否可用 curl https://taotoken.net/api/v1/models \ -H "Authorization: Bearer $TAOTOKEN_API_KEY"返回模型列表就说明通道正常。这一步建议在部署 Dify 之前做完,否则 Dify 起来之后模型调不通,排查起来会多一层干扰。
2.3 Dify 依赖资源清单
Dify 不是单容器应用,它依赖数据库、缓存、向量库和存储。在 SAE 上部署前,先把这些资源准备好:
| 资源类型 | 用途 | 建议 |
|---|---|---|
| PostgreSQL | 存 Dify 元数据 | 独立实例,不要和业务库混用 |
| Redis | 缓存与队列 | 选持久化版本 |
| PGVector | 向量检索 | 与 PostgreSQL 可同实例不同库 |
| NAS | 文件存储 | 挂载到 Dify 容器 |
| NAT 网关 | 出网访问 | 模型 API 调用需要 |
这些资源不在 SAE 内部创建,而是提前在对应云产品里开好,把连接信息填进后面的 YAML 模板。
3. 可复制配置:saectl 部署 Dify 与 MCP Server
3.1 Dify 凭证 Secret 模板
下载 SAE Dify 模板仓库后,第一件事是替换凭证。以dify-credential为例,把占位符换成你自己的资源信息:
apiVersion: v1 data: DB_USERNAME: ${pg_database_username} DB_PASSWORD: ${pg_database_password} PGVECTOR_USER: ${vector_database_username} PGVECTOR_PASSWORD: ${vector_database_password} REDIS_USERNAME: ${redis_database_username} REDIS_PASSWORD: ${redis_database_password} kind: Secret metadata: name: dify-credentials namespace: dify type: Opaque注意data字段下的值需要 base64 编码,如果你直接写明文,saectl 提交时会报格式错误。可以用echo -n "your_password" | base64生成。
3.2 一键部署脚本执行
变量替换完成后,执行仓库里的安装脚本:
chmod +x ./install.sh ./install.sh脚本会自动创建 namespace、提交所有 K8s 资源、等待 Pod 就绪,最后打印 Dify 的公网访问地址。执行过程中如果卡在某个资源上,可以用saectl get pods -n dify看具体哪个组件没起来。实测下来,首次拉镜像会比较慢,耐心等几分钟。
3.3 MCP Server 镜像与部署
MCP Server 我用的是官方 Python SDK 里的 simple-tool 示例,它实现了 SSE 协议和一个网页抓取工具。核心逻辑是SseServerTransport处理/sse连接和/messages/消息推送:
from mcp.server.sse import SseServerTransport from starlette.applications import Starlette from starlette.routing import Mount, Route sse = SseServerTransport("/messages/") async def handle_sse(request): async with sse.connect_sse( request.scope, request.receive, request._send ) as streams: await app.run( streams[0], streams[1], app.create_initialization_options() ) starlette_app = Starlette( debug=True, routes=[ Route("/sse", endpoint=handle_sse), Mount("/messages/", app=sse.handle_post_message), ], )工具定义用装饰器注册,list_tools返回工具列表,call_tool处理调用:
@app.list_tools() async def list_tools() -> list[types.Tool]: return [ types.Tool( name="fetch", description="Fetches a website and returns its content", inputSchema={ "type": "object", "required": ["url"], "properties": { "url": {"type": "string", "description": "URL to fetch"} }, }, ) ] @app.call_tool() async def fetch_tool(name: str, arguments: dict): if name != "fetch": raise ValueError(f"Unknown tool: {name}") if "url" not in arguments: raise ValueError("Missing required argument 'url'") return await fetch_website(arguments["url"])把这段代码打包成镜像推到镜像仓库,然后用 saectl 部署,暴露 CLB 类型的 Service。部署完成后在 SAE 控制台能看到应用处于 Running 状态,日志里有服务器启动输出。
4. 验证请求:从 Dify 到 MCP 的完整调用链
4.1 Dify 模型供应商连通性验证
Dify 起来之后,第一件事是配模型。进入设置里的模型供应商,选 OpenAI 兼容类型,API Base 填 TaoToken 的地址,Key 填你创建的那把。保存后点测试,能返回模型列表就说明通道通了。如果报 401,检查 Key 有没有多余空格;如果报超时,检查 SAE 应用的 NAT 网关是否配置正确。
4.2 MCP 工具在 Dify 中的配置
在 Dify 插件市场安装 MCP 工具插件,然后创建工作流应用,添加 Agent 节点。Agent 策略选 ReAct 模式,在 MCP 服务配置里填 SAE 上 MCP Server 绑定的 CLB 地址:
{ "mcp_server": { "url": "http://your-clb-ip:80/sse", "headers": {}, "timeout": 5, "sse_read_timeout": 300 } }这里url必须指向/sse路径,sse_read_timeout建议设大一点,因为工具调用可能耗时较长。
4.3 运行 Agent 并查看日志
点击运行后,Dify 会可视化展示 Agent 的思考过程:先 List Tool 拿到可用工具,再根据用户输入决定是否 Call Tool。同时去 SAE 控制台看 MCP Server 的日志,能看到客户端和服务端的交互记录。如果 Agent 没有调用工具,检查 ReAct 模式的提示词是否明确要求使用工具,以及 MCP 地址是否可达。
5. 本篇常见错排查
5.1 saectl 提交报 Secret 格式错误
最常见的原因是data字段没做 base64 编码。K8s 的 Secret 要求data下所有值都是 base64 字符串,而stringData才接受明文。如果你从模板复制过来直接填明文,就会报illegal base64 data。解决办法是改用stringData,或者手动编码。
5.2 Dify 启动后模型调用超时
先确认 SAE 应用的出网配置。Dify 容器要访问外部模型 API,必须走 NAT 网关。如果 NAT 没配或者路由不对,容器内curl外部地址会超时。可以在 SAE 控制台进入容器执行curl -v https://taotoken.net/api/v1/models验证。另外检查安全组是否放行了出方向流量。
5.3 MCP Server 连接被拒绝
Dify 里填的 MCP 地址如果是内网地址,而 Dify 和 MCP Server 不在同一个 VPC,就连不通。SAE 上部署的 MCP Server 要暴露 CLB 公网地址,或者确保 Dify 和 MCP 在同一 VPC 内通过内网互通。另外/sse路径不能漏,漏了会返回 404。
5.4 Agent 不调用工具
ReAct 模式下,如果提示词没有明确引导,模型可能直接回答而不调用工具。可以在 Agent 节点的指令里加一句「当需要获取外部信息时,优先使用 fetch 工具」。另外确认 MCP 插件版本和 Dify 版本兼容,部分旧版本插件对 SSE 超时处理有问题。
6. 后续接入与长期使用建议
Dify 和 MCP Server 跑起来之后,日常维护主要关注两件事:模型通道的稳定性和 MCP 工具的扩展。模型通道方面,TaoToken 的 API Key 建议按环境分多把,开发和生产分开,方便排查和限额。接入文档里有详细的参数说明,遇到 4xx 错误先对照文档检查请求格式。如果你打算长期跑编码类 Agent,Coding Plan 的额度模式比按次调用更划算。需要管理多把 Key 或者查看用量,直接进 API Keys 页面操作。
MCP 工具扩展方面,官方 Python SDK 的示例可以直接改,新增工具只需要在list_tools里加定义、在call_tool里加分支。部署更新时用 saectl 重新提交镜像即可,SAE 会滚动更新,不会中断服务。实测下来,从改代码到新工具在 Dify 里可用,大概五分钟。