news 2026/9/29 10:18:40

Dify_SQLAgent 实战:用 MCP 打通金融数据库的 Agent 配置骨架

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Dify_SQLAgent 实战:用 MCP 打通金融数据库的 Agent 配置骨架

1. 金融数据问答为什么总卡在“最后一公里”

做金融数据类 Agent 的朋友大概率都遇到过这个场景:用户问“帮我查一下最近三个交易日沪深300成分股里涨幅超过5%的标的”,模型能理解意图,但真正落到数据库查询时就开始掉链子——要么 SQL 写错字段名,要么把trade_date和report_date搞混,要么干脆编造一个不存在的表。问题的根子不在模型能力,而在于 Agent 缺少一个稳定的“手”去触碰真实的结构化数据。

Dify 的 SQLAgent 思路正好补上这一环:用工作流把自然语言转成 SQL,再通过一个受控的服务接口去执行查询,最后把结果回传给模型做分析。而 MCP(Model Control Protocol)在这里扮演的是“工具总线”的角色,让 Dify 的 Agent 能以标准化方式调用外部数据库服务,而不是把数据库连接串硬编码在提示词里。这套组合适合谁?适合手里有行情、财报、持仓等结构化数据、想让业务人员用自然语言直接问数的开发者,也适合正在用 Cursor 写代码、希望顺手就能查库验证逻辑的工程师。

我试过把这套链路拆成三段来搭:FastAPI 做 SQL 执行层、Dify 工作流做 NL2SQL 编排、MCP Server 做工具暴露。下面按可复制的顺序把配置骨架给出来,重点放在 MCP 服务声明、Dify 工具节点参数和 config.toml 这三块,最后跑一次从提问到结果返回的验证。

2. TaoToken 前置:先把模型调用通道理清楚

在搭 SQLAgent 之前,得先确认模型调用这条路是通的。Dify 工作流里的 LLM 节点需要调用大模型来完成关键词提取和 SQL 生成,如果你用的是本地模型或者自建网关,这一步可以跳过;但如果想快速跑通、不想在模型部署上耗时间,可以用 TaoToken 这类聚合通道来统一管理模型调用。

TaoToken 的定位是给开发者提供一个兼容 OpenAI 接口规范的模型调用入口,你可以在控制台里创建 API Key,然后在 Dify 的模型供应商配置里填入对应的 Base URL 和 Key。这样 Dify 的 LLM 节点就能直接选用你配置的模型,不用改代码。

具体操作路径:先到控制台创建一个 API Key,然后进入接入文档确认接口格式,把 Base URL 填成https://taotoken.net/api,Key 填你刚创建的那串。Dify 里配置模型供应商时选“OpenAI-API-compatible”类型,把这两项填进去即可。如果你后面要长期跑编码类 Agent,可以看看 Coding Plan 的额度方案;如果只是验证模型对话效果,模型对话页面可以直接试。

注意:TaoToken 的 API 地址不带 UTM 参数,直接写https://taotoken.net/api就行,别把营销参数混进代码里。

这一步做完,Dify 里就有了可用的 LLM,接下来才能让工作流里的“关键词提取”和“SQL 生成”两个节点跑起来。

3. 可复制配置:MCP 服务声明 + Dify 工具节点 + config.toml

3.1 MCP 服务声明怎么写

MCP Server 的核心作用是把 Dify 的 Agent API 包装成一个标准工具,让 Cursor 或其他 MCP 客户端能直接调用。项目里的dify_agent_server.py就是干这个的,你需要关注两个环境变量:DIFY_API_KEY和DIFY_API_URL。

# dify_agent_server.py 关键配置段 import os from mcp.server import Server from mcp.server.stdio import stdio_server DIFY_API_KEY = os.getenv("DIFY_API_KEY", "app-xxxxxxxxxxxxxxxx") DIFY_API_URL = os.getenv("DIFY_API_URL", "https://你的dify域名/v1/chat-messages") server = Server("dify-sql-agent") @server.tool() async def query_financial_data(question: str) -> str: """接收自然语言问题,调用 Dify 工作流返回 SQL 查询结果""" import httpx async with httpx.AsyncClient(timeout=60) as client: resp = await client.post( DIFY_API_URL, headers={ "Authorization": f"Bearer {DIFY_API_KEY}", "Content-Type": "application/json" }, json={ "inputs": {}, "query": question, "response_mode": "blocking", "user": "mcp-client" } ) data = resp.json() return data.get("answer", "查询无返回")

这段代码里@server.tool()装饰器把query_financial_data注册成一个 MCP 工具,入参是自然语言问题,出参是 Dify 工作流返回的答案。response_mode用blocking是为了让调用方同步拿到结果,适合查询类场景。

3.2 Dify 工具节点参数怎么填

在 Dify 工作流里,你需要加一个“工具”节点来调用上面这个 MCP 服务。工具节点的配置分三块:

第一块是工具类型,选“自定义工具”或“MCP 工具”,取决于你的 Dify 版本。第二块是入参映射,把工作流上游 LLM 节点输出的 SQL 语句或者自然语言问题映射到工具的question参数上。第三块是出参处理,把工具返回的answer字段接到下游的“结束”节点或者再送进 LLM 做分析。

# Dify 工具节点参数示意(在 UI 里对应填写) tool_name: query_financial_data input_mapping: question: "{{#llm_node.text#}}" output_mapping: result: "{{#tool_node.answer#}}" timeout: 60 retry: 1

这里的关键是input_mapping的变量引用要写对,Dify 里用{{#节点ID.字段#}}的语法。如果你上游是 LLM 节点生成的 SQL,那question传的其实是 SQL 语句,这时候 MCP 服务那边要能识别并直接执行;如果传的是自然语言,那 Dify 工作流里得先有一个 NL2SQL 的 LLM 节点。

3.3 config.toml 骨架

MCP 客户端(比如 Cursor)需要一个配置文件来知道去哪里启动这个 Server。在 Cursor 的mcp.json或者通用 MCP 客户端的config.toml里,写法如下:

# config.toml — MCP 客户端配置骨架 [mcp_servers.dify_sql_agent] command = "python" args = ["/path/to/dify-mcp/dify_agent_server.py"] env = { DIFY_API_KEY = "app-xxxxxxxxxxxxxxxx", DIFY_API_URL = "https://你的dify域名/v1/chat-messages" }

如果你用的是 Cursor,路径通常在C:\Users\{你的用户名}\.cursor\mcp.json,格式是 JSON 而不是 TOML,但字段含义一样:command指定解释器,args指定脚本路径,env注入环境变量。配好之后重启 Cursor,在 MCP 面板里应该能看到dify_sql_agent这个服务处于运行状态。

注意:DIFY_API_KEY不要硬编码在脚本里提交到 Git,用环境变量或者.env文件管理,.env记得加进.gitignore。

4. 验证请求:从自然语言到 SQL 结果返回

配置写完,得跑一次完整链路确认能通。验证分两步:先确认 FastAPI 的 SQL 执行层没问题,再确认 Dify 工作流 + MCP 的端到端链路能返回结果。

4.1 先验 FastAPI 的 SQL 查询服务

进入fastapi-sqlapi目录,装依赖、起服务:

pip install -r requirements.txt uvicorn app.main:app --reload --host 0.0.0.0 --port 8000

然后跑客户端测试脚本:

python client.py

如果client.py里配的是一条简单的SELECT语句,比如查某张行情表的前几行,你应该能在终端看到返回的 JSON 数据。这一步通了,说明数据库连接串、表结构、查询接口都没问题。

4.2 再验 Dify + MCP 端到端

在 Cursor 里打开 MCP 面板,确认dify_sql_agent服务已连接。然后在对话里输入一个自然语言问题,比如“查一下最近5个交易日成交额最大的3只股票”。MCP 客户端会把这个问题通过query_financial_data工具发给 Dify,Dify 工作流里的 LLM 节点提取关键词、生成 SQL,Code 节点调用 FastAPI 执行查询,最后把结果回传。

# 也可以用测试脚本直接验 Dify API python test_agent_dify.py

这个脚本会直接调 Dify 的 chat-messages 接口,绕过 MCP 层,适合排查是 Dify 工作流的问题还是 MCP 封装的问题。如果脚本能返回结果但 Cursor 里不行,那问题多半在 MCP 配置或环境变量上。

实测下来,一次成功的返回应该包含三部分:生成的 SQL 语句、查询结果数据、以及 LLM 对结果的简要分析。如果只返回了 SQL 没有数据,检查 FastAPI 服务是否在跑;如果返回了数据但格式乱,检查 Dify 结束节点的输出变量映射。

5. 本篇常见错排查

5.1 MCP 服务启动失败:command 路径不对

最常见的报错是 Cursor 里 MCP 面板显示服务离线,日志里提示spawn python ENOENT或者No such file or directory。这通常是command字段写的是python但系统 PATH 里找不到,或者args里的脚本路径是相对路径。解决办法:command写 Python 解释器的绝对路径,args写脚本的绝对路径。Windows 上路径用双反斜杠或者正斜杠。

5.2 Dify API 返回 401:Key 无效或没带 Bearer

如果test_agent_dify.py报 401,先检查DIFY_API_KEY是不是复制完整了,有没有多余空格。Dify 的 API Key 格式通常是app-开头的一长串。另外确认请求头里Authorization的值是Bearer {key},少了Bearer前缀也会 401。

5.3 SQL 执行报错:字段名或表名对不上

金融数据库的表结构往往比较复杂,LLM 生成的 SQL 里字段名可能和实际不一致。排查方法:先在 FastAPI 的client.py里手动跑一条已知正确的 SQL,确认表名和字段名;然后在 Dify 的 RAG 知识库里把表结构说明补全,包括库名、表名、字段名、字段类型、字段注释。知识库越详细,LLM 生成的 SQL 越准。

5.4 查询超时:数据量太大或没加 LIMIT

金融行情数据动辄几百万行,如果 LLM 生成的 SQL 没有加LIMIT,查询可能跑很久然后超时。解决办法有两个:一是在系统提示词里明确要求“生成的 SQL 必须带 LIMIT 100”,二是在 FastAPI 层加一个查询超时和行数上限的保护。

5.5 MCP 工具调用返回空:response_mode 不对

如果 MCP 工具返回的answer是空的,检查 Dify 工作流的response_mode是不是blocking。如果是streaming,MCP 这边的同步 HTTP 请求拿不到完整结果。另外确认 Dify 工作流的“结束”节点有输出变量,且变量名和 MCP 脚本里取的一致。

6. 把链路跑通之后,下一步做什么

配置跑通只是起点。接下来你可以做三件事:第一,把 Dify 工作流里的 LLM 节点换成更适合 SQL 生成的模型,通过 TaoToken 的模型对话页面先对比几个模型在 NL2SQL 任务上的表现,再决定用哪个;第二,把 MCP 服务扩展到多个工具,比如除了查询还加一个“导出 CSV”的工具,让 Agent 的能力更完整;第三,如果这套 Agent 要长期跑在编码或数据分析场景里,可以看看 Coding Plan 的额度方案,避免频繁手动换 Key。

接入文档里有完整的接口说明和示例,API Keys 页面可以管理你的调用凭证。整套链路的核心思路就一句话:让模型负责理解意图,让 MCP 负责标准化调用,让 FastAPI 负责安全执行 SQL。三者各司其职,金融数据的自然语言查询就能稳定跑起来。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/29 10:18:12

深度学习图像处理从入门到实战:选型、训练与部署全攻略

上周跟一个做工业质检的朋友吃饭,聊到他在产线上调参的事。背景纹理一复杂,传统的阈值分割就开始乱报,换了几轮参数都没彻底救回来。我说你干脆把缺陷区域分割的活儿交给深度学习,模型自己会去学“什么是缺陷”。他试跑了一版&…

作者头像 李华
网站建设 2026/9/29 10:15:11

轨道紧固件缺陷检测数据集 | 轨道紧固件 缺陷检测 铁路巡检 断裂识别9117期

轨道紧固件缺陷检测数据集 | 轨道紧固件 缺陷检测 铁路巡检 断裂识别9117期 数据集概述 本数据集专注于铁路轨道紧固件的缺陷视觉检测,服务于轨道巡检、设备状态评估及运维决策。数据涵盖六类紧固件状态与相关杂物,适配铁路巡检车、无人机及固定监控的自…

作者头像 李华
网站建设 2026/9/29 10:14:25

RL-08-赵-Value函数拟合算法02-ActionValue估算03:Deep Q-learning04【DQN优化技巧②:经验回放】【Β={(s,a,r,s′)},replay服从均匀分布】

2、技巧02:Experience replay(经验回放) 问题: 什么是Experience replay? 回答: 我们收集一些experience samples之后,we do NOT use these samples in the order they were collected。 Instead, 我们将它们存储在一个set中,称为 replay buffer B≐{ (s,a,r,s′)}\mat…

作者头像 李华
网站建设 2026/9/29 10:13:33

Linux 常用快捷键及修改设置:从桌面环境到终端 Shell 的键位定制

刚装好 Linux 那阵子,很多人会觉得自己像换了一台新电脑:界面挺清爽,鼠标也能点,但一看到旁边老手用几个组合键就调出终端、文件管理器和截图工具,心里还是会痒。Linux 系统常用快捷键及如何修改设置,表面上…

作者头像 李华
网站建设 2026/9/29 10:13:26

计算机网络考试题PDF复习方法论:从文件体检到考点拆解与模拟

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/29 10:13:20

设备偶发掉线排查指南:从硬件到网络的系统方法论

1. 先别急着换硬件:偶发掉线的第一现场调查1.1 “掉线”到底长什么样做运维和自动化设备管理的人,应该都经历过这种场景:一台设备跑得好好的,突然就掉线了,ping不通、管理界面打不开、业务侧直接报“设备离线”。技术人…

作者头像 李华