首页/新闻资讯/正文详情

智能体开发实战 | 基于Dify+MCP打造MySQL理财助手智能体

发布时间:2026/9/26 9:25:27 来源:云帆数科 栏目:资讯中心
智能体开发实战 | 基于Dify+MCP打造MySQL理财助手智能体
1. 从一张记账表说起为什么理财助手总在“接口对接”上翻车很多人做理财助手智能体第一反应是写一堆 if-else 去拼 SQL或者给每个数据源单独写适配层。结果就是用户说“昨天吃饭花了50”模型能听懂但工具调用链一断数据就写不进去用户问“这个月餐饮花了多少”模型又得重新理解一遍表结构。真正卡住进度的不是模型能力而是工具与数据源之间的“最后一公里”。MCPModel Context Protocol解决的正是这件事。它把外部工具抽象成标准化接口让大模型像插 U 盘一样调用 MySQL、文件系统或 HTTP 服务。你不需要为每个模型重写适配代码只需要一个 MCP Server 暴露工具Dify 里的 Agent 就能通过 Function Calling 自动发现并调用。这篇内容面向已经会用 Dify 搭 Chatflow、但被“工具链编排”卡住的开发者。我会用一张finance收支表从 Docker 起 MySQL、写 MCP Server、配 Dify Agent 节点一直跑到“记一笔账 按类别汇总”的完整闭环。全程可复制踩过的坑我也会标出来。2. 前置准备TaoToken 与 Dify 环境怎么摆在开始写 MCP Server 之前先把模型调用链路理顺。Dify 本身不绑定模型但 Agent 节点需要稳定的模型服务来驱动 Function Calling。我实测下来豆包系列在工具调用上的指令遵循比较稳通义千问系列在复杂 SQL 生成时偶尔会漏掉表结构约束。如果你还没有可用的模型 API Key可以通过 TaoToken 获取。它的接入方式兼容 OpenAI 风格Dify 里配置模型供应商时直接填 Base URL 和 Key 即可。具体入口模型对话调试https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentmodel_chatAPI Key 管理https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentapi_keys接入文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentdoc注意Dify 的 Agent 节点对模型有 Function Calling 能力要求选模型时确认支持工具调用否则 MCP 工具列表拿不到。环境侧你需要Docker DesktopWindows/macOS 均可用来跑 MySQL 和 DifyPython 3.10推荐用 uv 管理虚拟环境Dify 已通过 Docker 部署能访问插件市场3. 可复制配置MySQL 表结构 MCP Server 骨架3.1 起一个带 finance 表的 MySQL先写docker_compose.yaml把 MySQL 5.7 拉起来。字符集用 utf8mb4避免中文备注乱码。services: mysql: image: mysql:5.7 container_name: mysql5.7 ports: - 3306:3306 environment: - MYSQL_ROOT_PASSWORDroot - MYSQL_ALLOW_EMPTY_PASSWORDyes - TZAsia/Shanghai volumes: - ./volumes:/var/lib/mysql command: --character-set-serverutf8mb4执行docker compose up -d然后用 DBeaver 或 MySQL 客户端连接localhost:3306建库建表create database testdb; use testdb; CREATE TABLE finance ( id bigint(20) NOT NULL AUTO_INCREMENT, user_id varchar(36) NOT NULL DEFAULT COMMENT 用户ID, date datetime NOT NULL COMMENT 金额发生日期, amount decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT 收入支出金额(收入正数支出负数), category varchar(32) NOT NULL DEFAULT COMMENT 收支类别, remark varchar(100) NOT NULL DEFAULT COMMENT 收支具体类目, PRIMARY KEY (id), KEY idx_user_date (user_id,date) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT日常收支;这张表的关键设计amount用正负号区分收支category做粗分类remark存具体类目。Agent 生成 SQL 时只要提示词里把类别枚举写清楚插入和汇总都不容易跑偏。3.2 MCP Server两个工具就够用用 uv 初始化项目装依赖uv init finance cd finance uv venv .venv\Scripts\activate uv add mcp[cli] mysql-connector-python python-dotenv如果激活时报“禁止运行脚本”用管理员权限执行Set-ExecutionPolicy RemoteSigned后重试。创建.envDB_HOSTlocalhost DB_USERroot DB_PASSWDroot DB_NAMEtestdbMCP Server 只暴露两个工具get_table_definition拿表结构execute_sql执行 SQL。这样 Agent 先查表结构再生成 SQL避免瞎猜字段。import mysql.connector import json import os from contextlib import contextmanager from dotenv import load_dotenv from mcp.server.fastmcp import FastMCP load_dotenv() class DbManager: def __init__(self): self.connection_pool mysql.connector.pooling.MySQLConnectionPool( pool_namedb_pool, pool_size5, pool_reset_sessionTrue, hostos.getenv(DB_HOST), useros.getenv(DB_USER), passwordos.getenv(DB_PASSWD), databaseos.getenv(DB_NAME), ) contextmanager def get_cursor(self): with self.connection_pool.get_connection() as connection: cursor None try: cursor connection.cursor() yield cursor connection.commit() except Exception as e: connection.rollback() raise e finally: if cursor: cursor.close() def execute_sql(self, sql: str) - str: with self.get_cursor() as cursor: cursor.execute(sql) if cursor.description is not None: rows cursor.fetchall() result { columns: [desc[0] for desc in cursor.description], rows: rows, } return json.dumps(result, defaultstr) else: return frow affected:{cursor.rowcount} dbManager DbManager() mcp FastMCP() mcp.tool() def get_table_definition(table: str) - str: get table definition return dbManager.execute_sql(fshow create table {table}) mcp.tool() def execute_sql(sql: str) - str: execute sql return dbManager.execute_sql(sql) if __name__ __main__: mcp.run(transportsse)启动uv run main.py。看到 SSE 服务监听在 8000 端口就说明 MCP Server 活了。4. Dify 侧配置Agent 节点 MCP 工具策略4.1 装插件与配 MCP 服务在 Dify 右上角“插件”里从 Marketplace 安装两个插件Dify Agent 策略和MCP SSE / StreamableHTTP。装完后切到“插件”tab找到 MCP 插件点“去授权”填入{ finance_server: { url: http://host.docker.internal:8000/sse, headers: {}, timeout: 50, sse_read_timeout: 50 } }注意Dify 跑在 Docker 里访问宿主机服务要用host.docker.internal不要写 localhost。4.2 Chatflow 里替换成 Agent 节点新建空白 Chatflow把默认 LLM 节点换成 Agent 节点。Agent 策略选Function Calling模型选豆包 1.5 Pro 32k。系统提示词直接抄下面这段# 角色 你是记账助手可以通过调用MCP工具完成记录日常收入和支出并作分析。 为了获得MCP工具列表必须先通过mcp_sse_list_tools获取。 为了完成记账操作需要先获取表finance的定义。 记账的用户ID取值为{{#sys.user_id#}} # 收支类别 收入工资薪金劳务报酬投资收益分红收入租金收入其它收入 支出住房交通通讯保险餐饮电子产品日用品服饰旅行娱乐医疗学习其它支出 # 技能 ## 技能1记录日常开支 将开支信息记录到数据库表finance ## 技能2统计日常开支 根据用户输入信息分析统计日常开支 # 限制 仅处理记账相关问题不回复其它问题最大迭代次数建议设 8 以上。Agent 完成一次记账通常要两步先get_table_definition再execute_sql。迭代次数太小会在第二步直接截断。5. 验证请求从对话到数据落库在 Dify 预览窗口输入昨天吃饭用了50元还花了22元买了拖鞋。今天买手机花了1999元吃饭花了60元预期 Agent 会依次调用mcp_sse_list_tools、get_table_definition、execute_sql最终返回“已成功记录 4 笔支出”。然后去数据库查select * from finance order by date desc;你应该看到 4 行记录amount为负数category分别是餐饮、日用品、电子产品、餐饮。再输入“汇总各个类别的金额”Agent 会生成类似select category, sum(amount) as total from finance group by category;返回结果里餐饮合计 -110日用品 -22电子产品 -1999。到这一步读写闭环就跑通了。6. 本篇常见错排查报错一MCP 工具列表为空。检查 Dify 里 MCP 插件配置的 URL 是否用了host.docker.internal以及 MCP Server 是否真的在 8000 端口监听。可以在宿主机浏览器访问http://localhost:8000/sse看是否有事件流返回。报错二Agent 反复调用get_table_definition不执行 SQL。通常是模型 Function Calling 能力不足。换豆包 1.5 Pro 或确认所选模型支持工具调用。提示词里“必须先获取表定义”这句也会强化这个行为如果模型太弱可以暂时去掉。报错三插入中文备注乱码。检查 MySQL 容器启动参数是否带了--character-set-serverutf8mb4以及建表时DEFAULT CHARSETutf8mb4。Dify 侧不需要额外编码设置。报错四execute_sql返回 row affected 但数据没进去。看 DbManager 里是否在异常时 rollback 了。如果 SQL 语法错误MySQL 会抛异常连接池回滚Agent 会收到错误信息。让 Agent 根据错误重试即可但要在提示词里允许它修正 SQL。报错五Dify 容器访问不到宿主机 MySQL。MCP Server 跑在宿主机连的是localhost:3306这个没问题。但如果你把 MCP Server 也放进 Docker就要把DB_HOST改成host.docker.internal。7. 跑通之后把 MCP 工具链用起来这套结构的价值在于可扩展。你不需要改 Dify 工作流只要在 MCP Server 里加新工具比如get_monthly_summary或export_csvAgent 就能自动发现并调用。长期做编码类 Agent 或需要多工具编排的场景可以考虑用 Coding Plan 来降低模型调用成本入口在 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentcoding_plan 。如果你在接入过程中遇到 MCP 工具注册失败或 Agent 不调用工具的问题优先检查 API Key 和接入文档里的模型配置项https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentapi_keys 和 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentdoc 。模型对话调试可以直接在 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentmodel_chat 里先验证 Function Calling 是否正常再回 Dify 编排。

相关推荐

Flutter图像处理实战:用TaoToken统一Key接入AI图像能力并显示结果
Flutter图像处理实战:用TaoToken统一Key接入AI图像能力并显示结果

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

2026年AI编程新趋势:从提示词到循环工程,小白也能掌握大模型核心——TaoToken统一Key接入Cline与CC Switch的settings.json配置骨架
2026年AI编程新趋势:从提示词到循环工程,小白也能掌握大模型核心——TaoToken统一Key接入Cline与CC Switch的settings.json配置骨架

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

STM32理论实战:时钟树、定时器与外设调试全解析
STM32理论实战:时钟树、定时器与外设调试全解析

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

PyTorch CIFAR-10图像识别实战:从环境搭建到模型训练全解析
PyTorch CIFAR-10图像识别实战:从环境搭建到模型训练全解析

简介:基于PyTorch框架的CIFAR-10图像识别方案,面向机器学习初学者与计算机视觉入门者,解决如何用卷积神经网络完成图像分类任务的问题。压缩包共5个文件,包含2个Python脚本、1个已训练模型权重、1个数据元信息文件和1份说明文档&a… · 2026/9/26 10:00:18

坐标转换模型实战:仿射变换与布尔莎七参数配置验证
坐标转换模型实战:仿射变换与布尔莎七参数配置验证

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

Windows-universal-samples 触控键盘(Touch Keyboard)UWP 示例详解:默认显示行为与编程控制
Windows-universal-samples 触控键盘(Touch Keyboard)UWP 示例详解:默认显示行为与编程控制

示例工程 【免费下载链接】Windows-universal-samples API samples for the Universal Windows Platform. 项目地址: https://gitcode.com/gh_mirrors/wi/Windows-universal-samples 点击查看 免费下载 本指南以仓库中归档的 Touch Keyboard 示例 为线索&#xff0… · 2026/9/26 10:00:11

MySQLTuner 本地开发同步工作流:版本一致性、Changelog 自动整理与发布前自检实战
MySQLTuner 本地开发同步工作流:版本一致性、Changelog 自动整理与发布前自检实战

数据库运维 【免费下载链接】MySQLTuner-perl MySQLTuner is a script written in Perl that will assist you with your MySQL configuration and make recommendations for increased performance and stability. 项目地址: https://gitcode.com/gh_mirrors/my/My… · 2026/9/26 10:00:05

嵌入式驱动从“能跑”到“不崩”的工程化实践
嵌入式驱动从“能跑”到“不崩”的工程化实践

1. 从“灯亮了”到“客户退货”:驱动开发里最隐蔽的断层你写完一个GPIO点灯驱动,烧进板子,LED稳稳亮起——那一刻的成就感,我太熟悉了。十年前我在深圳一家工控设备厂做第一版电机控制固件,也是这样:UART收… · 2026/9/26 10:00:05

Ubuntu 16.04 下 CUDA/cuDNN 卸载升级与 TensorFlow 重装:TaoToken 统一 Key 配置骨架
Ubuntu 16.04 下 CUDA/cuDNN 卸载升级与 TensorFlow 重装:TaoToken 统一 Key 配置骨架

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

数据库课后习题答案别硬背:当测试用例集刷,效率翻倍
数据库课后习题答案别硬背:当测试用例集刷,效率翻倍

简介:万常选版《数据库原理与设计》课后习题答案资源,覆盖第2至6章及第9章,适合正在学习关系模型、数据库建模、关系数据理论与模式求精的本科生、自学者作为复习与自测材料。压缩包共7个文件,含3个doc参考答案、2个sql示例脚本、… · 2026/9/26 0:00:21

OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置
OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置

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

向下兼容与向上兼容:接口设计中的兼容性策略与工程实践
向下兼容与向上兼容:接口设计中的兼容性策略与工程实践

一次版本升级事故,是很多团队绕不过去的坎。线上环境里,服务端明明已经上线了新版接口,老的移动端还在照着旧文档传参数。请求一到网关,校验直接拒绝,用户操作失败,客服群炸了锅,开发群里开始互… · 2026/9/26 0:00:46

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码