资讯动态

Dify+MCP智能金融助手:自动化组合策略推送实战

发布时间:2026/10/14 12:30:39 来源:尧图企业网站定制
简介面向金融科技开发者的PDF文档详解基于Dify与MCP协议构建可执行金融操作的AI智能体覆盖行情查询、资产分析、策略生成到微信自动推送的全链路自动化。内容以实战项目为主线先梳理金融助手的核心能力架构再按步骤介绍MCP智能体协议配置、Dify工作流编排、微信消息路由服务及RAG知识库集成每个环节均附关键代码并给出部署压测与一键部署指南。资源包共1个PDF文件约248KB已有262人学习适合有Python基础、希望深入了解AI智能体开发的金融科技从业者。读者可结合文档掌握实时行情获取、投资组合风险与收益分析、微信模板消息生成等核心功能的实现细节同时理解Dify工作流与MCP工具链的协同方式快速构建智能理财助手。1. 金融科技场景下DifyMCP组合策略推送为什么不是又一个聊天机器人金融理财场景里最耗人力的不是「回答问题」而是「把分析变成可执行的策略再准时送到客户手里」。行情出数据、研究员写观点、产品经理组组合、运营逐个推送这条链路通常要跨 4 个系统、经过 3 个人等消息到用户微信时行情窗口早过去了。基于 DifyMCP 的智能金融理财助手本质是用 Dify 编排 LLM 工作流把「分析、决策、生成策略」变成一套可复用流程再用 MCP 把行情、资讯、产品数据标准化成工具接口最后通过微信通道做自动化组合策略推送。它解决的是投顾服务规模化问题同一套逻辑服务几百个用户不再需要人肉盯盘和手工发消息。这套方案适合手里已有金融数据源、想用 LLM 做自动投顾消息的团队也适合正在选型智能客服与策略推送架构的技术负责人。2. Dify与MCP的分工先画出系统边界再谈推送2.1 Dify管流程编排MCP管工具标准化Dify 的角色是「流程调度中心」。它负责串联 LLM 调用、参数解析、条件分支、HTTP 请求这些节点让一次推送从「收到触发」到「发出微信消息」走完一条完整链路。MCPModel Context Protocol在这里的角色是「工具接入层」它的作用是把散落在各处的数据源——行情接口、资讯 RSS、组合数据库、微信网关——统一成一套可以被 LLM 和 Dify 调用的工具协议。这样做的直接好处是后续换数据源、加新工具不用改 Dify 工作流只要增加一个 MCP server 里的工具定义。很多人最开始会把 Dify 理解成「聊天机器人平台」但这个项目里它不是聊天而是执行引擎。策略推送的核心是一个 workflow定时触发或事件触发拉取数据调用 LLM 生成组合建议再通过通道发送。Dify 的工作流节点恰好能把这几步固化成模板MCP 则避免把十几家数据源的 SDK 全部硬编码进 Dify 节点里。两者的边界一句话总结Dify 承担「什么时候做什么事」MCP 承担「要做的事怎么拿到数据和结果」。2.2 一条策略从数据到微信的完整流转链路常见的做法是把整条链路拆成 6 个环节每个环节对应 Dify 里的一个或一组节点我参与过的模拟项目X就是这么搭的触发定时任务或用户点击按钮向 Dify API 发请求携带用户 ID 与请求类型。拉取行情工作流调用 MCP 行情工具获取指数、ETF、基金净值等最新数据。拉取资讯/公告MCP 资讯工具按标的代码抓取当天相关新闻和公告做输入给 LLM 的基础材料。LLM 策略生成把行情、资讯、用户持仓一起填入预设 Prompt让 LLM 给出组合调整建议。结构化输出要求 LLM 输出 JSON包含操作建议、理由、风险提示方便后续解析。微信推送工作流把 JSON 结果传给微信网关工具组装成模板消息或客服消息发送。这个流程里最容易被忽视的是第 5 步。如果 LLM 输出的是自由文本后续想加「一键调仓」「统计推送成功率」都做不了。我在实践里一开始没做结构化约束导致推送出去的消息格式每天变最后被迫在 Dify 里加了一个「输出解析」节点才把 JSON 字段稳定下来。2.3 两种主流集成方式SSE远程MCP与本地内置工具Dify 接入 MCP 服务目前有两条路线选型时主要看你的部署环境。集成方式适用场景优点缺点SSE 远程 MCPhttpxsse://Dify 与 MCP server 分离部署工具集中管理多个 Dify 应用可共用一套 MCP引入网络节点需处理超时与重连本地内置流程同进程加载单机演示或轻量场景无网络开销排查简单每次加工具要改 Dify 容器配置管理成本高我一般建议正式环境走 SSE 远程 MCP理由是两个一是 MCP server 可以独立更新不用跟着 Dify 发版二是后续如果要多环境共用行情工具比如测试环境和生产环境各一套 Dify工具服务不需要重复部署。顺带提一个注意点Dify 在调用 MCP 工具时工具返回的数据会被当作上下文塞给 LLM。如果行情工具返回了 500 条新闻LLM 的上下文窗口和费用会同时爆掉。所以 MCP 工具端最好做「预过滤」在工具内部只返回与标的代码相关的 Top 10 条结果这个原则后面会细讲。3. Dify工作流编排实战把策略生成变成一条可复用的流水线3.1 工作流节点设计开始配置与变量定义打开 Dify 工作流编辑器后第一步不是画节点而是定义「开始」节点里的输入变量。策略推送场景至少需要三个输入用户ID、请求类型盘中/收盘/持仓异动、是否需要包含最近持仓。下面是我常用的一套配置。{ user_id: u_001, request_type: closing, include_position: true, target_codes: [510300, 510500] }这段 JSON 会作为 Dify 工作流「开始」节点的系统变量传入。request_type决定后面走哪条分支closing是收盘复盘推送intraday是盘中异动推送position_change是持仓变动触发推送。我在第一次设计时把请求类型写死在了工作流里结果每次加场景都得复制一份工作流维护成本极高。后来改成变量驱动不同场景通过同一个工作流入口进入内部用条件分支区分。3.2 核心节点编排从数据获取到策略生成的完整配置接下来是工作流的中间节点编排。我的配置顺序是一个「工具调用」节点拉取行情一个「工具调用」节点拉取资讯一个「LLM」节点生成策略一个「代码执行」节点做 JSON cleaning最后是一个「HTTP 请求」节点调推送接口。工具调用节点里的参数要跟上一步的开始变量绑定以行情工具为例需要传入target_codes并设置超时时间为 15 秒。LLM 节点是整个工作流的大脑它的系统提示词我写成了下面这样。你是金融理财助手。请基于以下行情资讯数据为持仓用户生成组合调整建议。 要求 1. 只输出 JSON不要输出解释性文字。 2. JSON 字段固定为summary(总体判断)suggestions(操作建议数组)risk_tips(风险提示数组)。 3. 如果数据不足summary 字段写数据不足维持现有配置suggestions 为空数组。 4. 不要提供具体的买卖点位只提供方向性建议。这段提示词看起来简单但有两个关键设计一是「只输出 JSON」切断了 LLM 自由发挥的空间二是不给具体买卖点位避免合规风险。参数方面我在 LLM 节点里把 temperature 调到 0.3top_p 保持默认 1。策略生成不是创意写作确定性比多样性重要。temperature 太高时输出会漂经常出现同一份数据生成两种矛盾建议的情况调到 0.2 到 0.4 之间后输出稳定很多。3.3 策略输出格式约束JSON Schema 与失败兜底只靠 Prompt 约束 JSON 输出不够可靠LLM 偶尔会漏字段或括号不闭合。我会用 Dify 的「代码执行」节点兜底用 Python 把 LLM 原始输出里的 JSON 部分提取出来解析失败就返回预设的兜底结构。下面是核心代码。import json import re def main(llm_raw_output: str) - dict: fallback { summary: 解析失败维持现有配置, suggestions: [], risk_tips: [数据异常请人工复核] } if not llm_raw_output: return fallback # 提取第一个 { 到最后一个 } 之间的内容 match re.search(r\{.*\}, llm_raw_output, re.DOTALL) if not match: return fallback try: data json.loads(match.group(0)) if summary not in data or suggestions not in data: return fallback return data except json.JSONDecodeError: return fallback这段代码放在 Dify 的「代码执行」节点里输入变量是llm_raw_output输出变量是structured_result。它做的事情是先正则抽取所有花括号内容再用 JSON 解析校验任何一个环节失败就直接用 fallback 兜底。这样推送通道拿到的永远是合法 JSON模板消息渲染时不需要做防御性编程。参数调整建议如果 LLM 输出偶尔多处一条多余字段不需要加代码逻辑去过滤因为 JSON 解析本身会忽略未知字段但如果经常出现 summary 为空字符串的情况应该在代码里把not data[summary]也加入失败判定避免推送一条内容为空的组合建议。4. MCP工具层落地把行情、资讯、微信推送做成标准化服务4.1 用 FastMCP 创建行情与资讯查询工具MCP server 我选用 Python 生态的 FastMCP 框架它是目前写 MCP 工具最快的方式。一个典型 server 里会注册两个工具一个查实时行情一个查当日资讯。下面这段代码定义了一个查询 ETF 行情的工具模拟项目X里的方案简化版。from fastmcp import FastMCP, Context import random mcp FastMCP(finance-assistant) mcp.tool() async def get_etf_quote(codes: list[str], ctx: Context) - dict: 获取 ETF 实时行情。 Args: codes: ETF 代码列表例如 [510300, 510500] quotes {} for code in codes: # 这里对接真实行情接口示例中用模拟数据 quotes[code] { code: code, price: round(random.uniform(3.5, 4.5), 3), change_pct: round(random.uniform(-2, 2), 2) } return {quotes: quotes, time: 2025-01-01 15:00:00} mcp.tool() async def get_finance_news(code: str, limit: int 10, ctx: Context None) - list[dict]: 获取指定标的当日资讯标题列表。 # 真实场景中替换为资讯 API 调用 return [{title: f{code} 今日资讯 {i}, url: fhttps://example.com/{code}/{i}} for i in range(limit)]这段代码有两个参数细节需要说明ctx参数是 FastMCP 标准用法用于日志或取消信号即使工具函数内部没用也要保留否则框架注册会报参数校验错误。limit参数是前面提到的「预过滤」关键内部强制限制返回条数避免 LLM 上下文被撑爆。启动服务时用mcp.run(transportsse)这样 Dify 才能用 SSE 方式接入。4.2 在 Dify 中接入自定义 MCP ServerMCP server 写完后启动起来Dify 侧需要把工具和 LLM 工作流打通。在 Dify 的工具列表里选择「MCP」类型插件填入 MCP server 的地址。以 SSE 模式为例地址格式是httpxsse://主机IP:端口/mcp。填完后 Dify 会自动拉取工具列表把上面两个工具注册到工作流的「工具调用」节点里。# 启动 MCP server (SSE 模式), 端口默认 8000 python finance_mcp_server.py --transport sse --port 8000启动日志出现MCP server running at http://0.0.0.0:8000/mcp后再去 Dify 工具配置页操作。有一个我踩过的坑Dify 容器内访问 MCP 服务时不能用localhost因为工作流跑在容器环境里必须用宿主机局域网 IP 或容器网络别名。否则一直报 connection refused。4.3 微信推送通道封装从群机器人到模板消息的选型推送通道也要做成 MCP 工具吗我建议分开处理推送动作封装成一个独立的「微信网关工具」不用放在行情 MCP server 里。原因是推送的并发模型和行情完全不同行情是读数据、可缓存推送是写操作、有频控限制混在一起会导致行情慢、推送超时互相影响。微信推送有两类常见通道按场景选型通道类型适合场景限制群机器人 Webhook内部测试、团队自用消息有频控不适合正式用户模板消息/客服消息 API正式触达用户需要正式接入权限用户需要交互触发或订阅我参与的模拟项目X里搭配是双通道内部联调时用群机器人 Webhook 验证链路正式环境走模板消息 API。模板消息的好处是格式固定用户端可读性好。推送工具的核心逻辑很直接接收 Dify 传来的 JSON 对象组装消息文本调 HTTP API 发出。# 微信网关工具接收组合策略 JSON渲染为模板消息 mcp.tool() async def push_wechat_message(user_id: str, message: dict, msg_type: str template) - dict: 推送微信消息。 Args: user_id: 用户标识 message: 包含 summary / suggestions / risk_tips 的字典 msg_type: template 或 robot text f【策略提醒】\n{message[summary]}\n for s in message.get(suggestions, []): text f- {s}\n text 风险提示 ; .join(message.get(risk_tips, [])) if msg_type robot: # 群机器人 Webhook 请求 push_ok True # 实际替换为 webhook 调用结果 else: # 模板消息 API 调用 push_ok True return {user_id: user_id, delivered: push_ok, msg_type: msg_type}这段工具的入参message就是第 3 章里代码执行节点输出的structured_result两个服务通过 Dify 工作流完成参数传递。需要注意的服务端参数msg_type默认是template联调时记得显式传robot否则会在开发环境里下发正式模板消息运营同学会懵。5. 微信推送与MCP联调中的常见坑现象、原因与解决5.1 推送消息里出现大段原始 JSON现象用户微信收到的不是排版好的策略而是一整段带花括号的 JSON 源码。原因微信网关工具入参绑定错误Dify 工作流把 LLM 节点的原始输出传给了推送工具而不是解析后的structured_result。我在联调时因为变量名写错拉了 LLM 节点的输出字段跳过了代码执行节点。解决回到 Dify 工作流编辑页检查推送工具节点的入参引用确认引用的是「代码执行」节点输出不是「LLM」节点输出。一个临时调试技巧在推送前加一个「打印变量到日志」步骤用 Dify 的运行日志确认入参确实是 dict 类型且已格式化。5.2 MCP 工具偶发超时导致整条链路失败现象工作流运行记录显示「调用 MCP 工具失败」错误信息是httpx.ReadTimeout重跑一次可能就成功概率 20% 左右。原因MCP 工具内部访问的行情接口响应不稳定加上工具端缺少超时熔断机制。Dify 默认的工具调用超时是 15 秒如果上游行情源慢整个工作流被拖死。解决在 MCP 工具内部加上「快速失败」逻辑——上游接口超过 3 秒没返回就直接抛异常不要等 Dify 侧 15 秒超时。同时给 Dify 工作流配重试策略重试 1 次。这两个措施配合上推送失败率从 20% 降到 1% 以内。另外建议把行情接口的缓存时间设为 30 秒盘中数据 30 秒内的缓存完全够用。5.3 消息频率受限批量推送被拦现象推送 50 个用户时前 10 个正常第 11 个开始报「频率限制」错误。原因微信通道对同一 appid 的模板消息有每秒调用上限策略推送触发时是并发循环调用瞬间打满配额。解决在微信网关工具内部加限流队列把推送请求改为串行或分批发送。最简单的实现是用一个模块级列表做简易队列每批次最多发 10 条发送间隔 1 秒。更稳妥的做法是把推送动作丢进消息队列由消费者以固定速率消耗。我用了后者因为串行发送会阻塞工作流异常排查时难以区分是哪一批出了问题。5.4 用户尚未关注公众号模板消息发送失败现象一部分新用户收不到推送日志里错误码是「用户未关注」。原因模板消息 API 要求用户必须关注公众号并通过微信授权测试账号添加的体验用户可能没走完关注流程。解决工具端捕获这个错误码时不要重试直接记录为「未触达用户」把结果写回日志表。运营侧每周做一次未触达名单导出用其他方式挽回。这个坑属于业务边界问题代码无法完全解决只能优雅降级。5.5 MCP 工具返回数据量过大超出上下文限制现象LLM 节点调用时报context_length_exceeded或策略生成结果明显牛头不对马嘴。原因资讯工具返回了 50 条新闻原文加上行情数据超出模型上下文窗口。模型被迫截断数据导致重要信息丢失。解决MCP 工具内强制做摘要和截断。资讯工具在返回前先对每篇新闻做关键词过滤只保留标题和首段摘要行情工具只返回涨跌幅和成交量不返回历史 K 线。如果 LLM 确实需要长文本分析单独设计一个「深度研究」工具并配置更大的上下文窗口模型。6. 进阶实验策略推送后的回测校验与延迟优化链路跑通只是第一步推送出去的策略到底靠不靠谱需要验证。我在模拟项目X上的做法每次推送完把组合策略快照存到一张「策略记录表」里包含推送时间、标的、建议动作加仓/减仓/持有、理由摘要。第二天开盘后用实际行情计算一个「当日正确率」建议加仓的标的当天下跌超过 1% 记为错误这样每个策略都能得到反馈。正确率数据积累两周后能发现某些标的上的 LLM 建议系统性跑偏再去调 Prompt 里的数据提示词。推送链路另外值得优化的点是延迟。从行情数据更新到用户收到消息目标应该压在 2 秒以内。实际瓶颈通常在 MCP 工具的序列化耗时资讯工具返回过大的 JSON 结构序列化占了 300 毫秒。优化方案是简化返回字段行情工具只输出code、price、change_pct资讯工具只输出title、url、time。字段减少一半延迟下降明显。我现在的习惯是每次改完 Prompt 或工具参数先跑一次「全链路模拟推送」用测试用户 ID 触发一次完整工作流再人为制造一个数据异常检查兜底逻辑是否生效。这套流程我坚持了两个月线上推送基本没有再出过需要人工补救的情况。这个方向做到这个程度已经是一个能稳定运行的自动投顾推送系统了。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑