当前位置: 首页 > news >正文

【实战】Dify从0到100进阶--中药科普助手(2)

Agent策略

在这里插入图片描述

1.Function Calling

1. 定义

Function Calling 是一种“黑盒”式的工具调用方式:

  • 模型在生成回复时,会在内容中“调用”预先注册的函数(Function)。
  • 平台拦截到函数调用意图后,按需执行对应 Function,并将结果返回给模型,模型再基于结果生成最终回复。

2. 流程

  1. 函数注册:在 Agent 启动时,开发者将若干工具 API(如 get_yaocaiInfoget_weather 等)以 JSON Schema 的形式注册到 Agent。

  2. 意图识别:当用户输入到达模型,模型会判断是否需要调用函数,若需要则输出一段类似于:

    {"name": "get_yaocaiInfo","arguments": { "name": "当归" }
    }
    
  3. 执行调用:Agent 将该调用片段拦截,依据 namearguments 调用对应后端 API,获取函数执行结果(如药材信息)。

  4. 结果回填:将函数返回值(JSON、文本等)传回到模型的上下文中,模型基于此内容继续生成对用户的自然语言回复。

3. 特点与优劣

  • 优势
    • 减少模型 hallucination:信息由外部 API 提供,准确且可控。
    • 清晰的调用链路:模型意图→函数执行→结果回填。
    • 易扩展:只需新增或更新函数定义,无需更改模型本身。
  • 劣势
    • 对话链路较长:调用→回填→二次生成,会增加响应延迟。
    • 受限于注册时定义的 Schema,灵活度略低。

4. 典型场景

  • 结构化数据查询:药材百科、天气、股票报价、数据库检索等。
  • 确定性操作:下单、日程管理、文件读写等需要精确执行的任务。

2.ReAct(Reason + Action)

1. 定义

ReAct 是一种“透明”式的思考与行动融合策略,由模型在同一次生成中同时输出:

  • Thought(思考链路):模型的中间推理过程,用于决策下一步做什么。
  • Action(动作指令):模型直接发出对外部工具或 API 的调用请求。
  • Observation(观察结果):Agent 工具执行后的即时反馈。

通过多轮 Thought–Action–Observation 循环,最终由模型给出回答。

2. 流程

  1. 初始思考:模型针对用户提问,先输出一个思考(Thought),如“要查询当归功效,先调用药材信息接口”。

  2. 动作输出:接着输出对应的 Action,例如:

    Action: get_yaocaiInfo(name="当归")
    
  3. 工具执行:Agent 执行该动作,并将 Observation(API 返回的 JSON 或文本)附加到对话上下文。

  4. 循环迭代:模型读取 Observation,可能继续新的 Thought/Action,直到得出最终回答(Answer)。

  5. 结束回答:模型在最后一步输出清晰、连贯的 Answer,呈现给用户。

3. 特点与优劣

  • 优势
    • 强可解释性:中间所有的思路(Thought)都对外可见,便于审计和调试。
    • 灵活性高:模型可根据 Observation 自由决定下一步动作,支持复杂多步骤任务。
  • 劣势
    • 对话冗长:中间多次 Thought/Action 循环,响应体积较大,不利于极简场景。
    • 需要较强的模型推理能力,否则容易出现多余或无效循环。

4. 典型场景

  • 复杂决策流程:多步检索、多源信息融合、动态规划类任务。
  • 调试与监控:需要全链路可视的场景,如安全审计、训练评估。

3.选型建议

维度Function CallingReAct
交互速度较快(单次调用+回填)较慢(多轮思考—行动—观察循环)
实现难度低,只需注册函数与 Schema中,需要设计思考—行动模板与管理循环终止条件
可解释性较低,隐藏了模型中间推理较高,完整暴露模型思考过程
任务复杂度适合单步查询或简单操作适合多步骤、需动态决策的复杂任务
Hallucination 风险低,调用真实数据源中等,若循环不当可能出现误调用或无效调用
  • 简单信息查询确定性任务:优先选用 Function Calling
  • 复杂多步推理审计可视化:推荐使用 ReAct,可全面暴露中间链路。

MCP工具

1. 插件概述

  • 名称:MCP SSE / StreamableHTTP
  • 版本:0.2.1
  • 仓库github.com/junjiem/mcp_sse
  • 作用:通过 HTTP 的 SSE(Server‑Sent Events) 或 Streamable HTTP 方式,实现 Dify Agent 与后端工具服务(MCP Server)之间的发现与调用。
  • 定位:将后端各类微服务、AI 模型推理接口、业务 API 等封装为“工具”,由 Agent 在对话中动态调用。

2. 核心能力

该插件主要提供两类 Action

Action 名称描述
get_tool_list向 MCP 服务端查询并获取可用的工具列表。
call_tool按指定工具名和参数,向 MCP 服务端发起调用,并接收返回结果(可流式返回)。

两者结合即可让 Agent 在对话流程中,自动发现动态调用、并实时处理后端工具。

3. 传输协议

  1. SSE(Server‑Sent Events)

    • 单向、持久的服务器消息推送通道。
    • 客户端发起一次 HTTP 请求后,与服务端建立长连接,服务端通过这条连接不断推送 JSON 格式的事件。
    • 适合 流式响应(如实时日志、流水线输出)或需要即时多步反馈的场景。
  2. Streamable HTTP

    • 基于标准 HTTP/1.1 的分块传输编码(Chunked Transfer Encoding)。
    • 服务器将响应分为多个 chunk 逐个发送,客户端逐 chunk 处理并呈现。
    • 兼容性更高,适合稍微简单的流式数据场景。

两者在插件中可二选一,也可同时支持,视后端实现及 Agent 需求而定。

4. 配置示例

在 Dify Agent 的配置文件中,只需声明一段 mcpServers 即可接入:

{"mcpServers": {"zhongyao_mcp": {"type": "sse",                    // 或 "streamable_http""url":  "http://10.16.7.24:8003/sse",// 以下为可选字段:// "headers": { "Authorization": "Bearer <token>" },// "timeout": 120000               // 毫秒}}
}
  • type:支持 "sse""streamable_http"
  • url:后端 MCP 服务地址
  • headers / timeout:可选,用于接入需要认证或自定义超时的场景

5. 两大 Action 详解

5.1 get_tool_list

  • 请求方式:长连接(SSE)或分块 HTTP

  • 请求内容

    { "action": "get_tool_list" }
    
  • 返回示例

    {"tools": [{"name": "get_yaocaiInfo","description": "根据中药名获取药材信息","parameters": { /* JSON Schema 定义 */ }},{"name": "get_yaocai_image","description": "生成中药材图片","parameters": { /* JSON Schema 定义 */ }}// …更多工具…]
    }
    
  • 应用:Agent 启动时或定期调用,自动加载最新工具列表,动态构建 FunctionCalling/ReAct 的可调用函数集。

5.2 call_tool

  • 请求方式:同上

  • 请求内容

    {"action":   "call_tool","tool_name":"get_yaocaiInfo","arguments": { "name": "当归" }
    }
    
  • 流式响应
    如果工具后端按 SSE/Chunked 分片返回,则客户端可边取边用,每收到一段就进行 Observation 注入。

工具Tool

import os
import json
import requests
from fastmcp import FastMCP
from volcenginesdkarkruntime import Ark# MCP 服务初始化
mcp = FastMCP("ZhongyiServer", port=8003)# 获取 SiliconFlow API Key(建议通过环境变量 SILICONFLOW_API_KEY 管理)
SILICONFLOW_API_KEY = os.getenv("SILICONFLOW_API_KEY", "XXXXXXX")# 初始化豆包(doubao)Ark 客户端
# 请确保您已将 API Key 存储在环境变量 ARK_API_KEY 中
doubao_client = Ark(base_url="https://ark.cn-beijing.volces.com/api/v3",api_key="XXXXXXX",
)# 通用 Header
HEADERS = {"Authorization": f"Bearer {SILICONFLOW_API_KEY}","Content-Type": "application/json"
}@mcp.tool()
async def get_yaocaiInfo(yaocai: str):"""输入药材名称,调用硅基流动大模型返回中药材信息(JSON 格式)。"""try:url = "https://api.siliconflow.cn/v1/chat/completions"payload = {"model": "Qwen/Qwen2.5-VL-72B-Instruct","messages": [{"role": "system", "content": "你是一个专业的中医药专家,请提供准确的中药材信息。"},{"role": "user", "content": (f"请以 JSON 格式返回关于 \"{yaocai}\" 的中药材信息,包含字段:""name(药材名称)、property(药性)、taste(药味)、meridian(归经)、function(功效主治)、usage(用法用量)。")}]}resp = requests.post(url, headers=HEADERS, json=payload, timeout=60)resp.raise_for_status()content = resp.json()["choices"][0]["message"]["content"]try:return json.loads(content)except json.JSONDecodeError:return {"error": "无法解析为 JSON", "raw": content}except Exception as e:return {"error": str(e)}@mcp.tool()
async def get_yaocai_image(yaocai: str):"""输入药材名称,调用豆包的 doubao-seedream 模型生成并返回图片 URL。"""try:# 调用豆包图生模型images_response = doubao_client.images.generate(model="doubao-seedream-3-0-t2i-250415",prompt=(f"高清晰度的{yaocai}中药材实物图片,白色背景,清晰展示其颜色、形状和质地。"))# 从返回结果中提取 URLdata = images_response.data or []if data and data[0].url:return {"success": True,"yaocai": yaocai,"image_url": data[0].url}else:return {"success": False,"yaocai": yaocai,"error": "无效的图像响应"}except Exception as e:return {"success": False,"yaocai": yaocai,"error": str(e)}if __name__ == "__main__":# 监听所有网卡并启动 SSE 服务mcp.settings.host = "0.0.0.0"mcp.settings.port = 8003mcp.run(transport="sse")

1. 导入与依赖初始化

import os
import json
import requests
from fastmcp import FastMCP
from volcenginesdkarkruntime import Ark
  • osjsonrequests:基础的环境变量读取、JSON 处理和 HTTP 请求库。
  • fastmcp.FastMCP:来自 FastMCP 的核心类,用于快速创建并注册 MCP 工具(micro‑chain plugin)并启动服务。
  • volcenginesdkarkruntime.Ark:字节跳动(火山引擎)的 Ark 客户端,用于调用豆包(Doubao)相关模型,比如图像生成。

2. MCP 服务初始化

# MCP 服务初始化
mcp = FastMCP("ZhongyiServer", port=8003)
  • FastMCP("ZhongyiServer", port=8003)
    • 第一个参数 "ZhongyiServer" 是本服务的名字。
    • port=8003 指定了 MCP 服务监听的默认端口。

3. API Key 管理

SILICONFLOW_API_KEY = os.getenv("SILICONFLOW_API_KEY", "XXXXXXX")
  • 从环境变量 SILICONFLOW_API_KEY 中读取 SiliconFlow(硅基流动大模型)所需的 API Key,若未设置则使用 "XXXXXXX" 作为占位。
  • 建议在生产环境中通过环境变量(或密钥管理服务)来管理,而不要把真实 Key 硬编码在代码里。

4. 豆包(Doubao)Ark 客户端初始化

doubao_client = Ark(base_url="https://ark.cn-beijing.volces.com/api/v3",api_key="XXXXXXX",
)
  • base_url:豆包 Ark 服务的接口地址。
  • api_key:此处也要替换为环境变量中读取的真实 Key(如 os.getenv("ARK_API_KEY"))。

5. 通用请求头

HEADERS = {"Authorization": f"Bearer {SILICONFLOW_API_KEY}","Content-Type": "application/json"
}
  • 用于向 SiliconFlow 的聊天接口发送 HTTP 请求时,提供身份认证和声明请求体格式。

6. 定义 MCP 工具:get_yaocaiInfo

@mcp.tool()
async def get_yaocaiInfo(yaocai: str):"""输入药材名称,调用硅基流动大模型返回中药材信息(JSON 格式)。"""try:url = "https://api.siliconflow.cn/v1/chat/completions"payload = {"model": "Qwen/Qwen2.5-VL-72B-Instruct","messages": [{"role": "system", "content": "你是一个专业的中医药专家,请提供准确的中药材信息。"},{"role": "user", "content": (f"请以 JSON 格式返回关于 \"{yaocai}\" 的中药材信息,包含字段:""name(药材名称)、property(药性)、taste(药味)、meridian(归经)、function(功效主治)、usage(用法用量)。")}]}resp = requests.post(url, headers=HEADERS, json=payload, timeout=60)resp.raise_for_status()content = resp.json()["choices"][0]["message"]["content"]try:return json.loads(content)except json.JSONDecodeError:return {"error": "无法解析为 JSON", "raw": content}except Exception as e:return {"error": str(e)}
  • 装饰器 @mcp.tool():把此异步函数注册为 MCP 工具,外部可以通过 MCP 协议调用 get_yaocaiInfo
  • 功能:向 SiliconFlow 的聊天接口发起请求,请求模型以 JSON 格式返回指定药材的详细信息。
  • 错误处理
    • HTTP 异常与超时捕获后返回 {"error": ...}
    • 如果 API 返回的文本无法解析为合法 JSON,也会反馈原始内容。

7. 定义 MCP 工具:get_yaocai_image

@mcp.tool()
async def get_yaocai_image(yaocai: str):"""输入药材名称,调用豆包的 doubao-seedream 模型生成并返回图片 URL。"""try:images_response = doubao_client.images.generate(model="doubao-seedream-3-0-t2i-250415",prompt=(f"高清晰度的{yaocai}中药材实物图片,白色背景,清晰展示其颜色、形状和质地。"))data = images_response.data or []if data and data[0].url:return {"success": True, "yaocai": yaocai, "image_url": data[0].url}else:return {"success": False, "yaocai": yaocai, "error": "无效的图像响应"}except Exception as e:return {"success": False, "yaocai": yaocai, "error": str(e)}
  • 装饰器 @mcp.tool():同样注册为 MCP 工具。
  • 功能:调用豆包图像生成模型(doubao-seedream)生成指定药材的实物图,并提取返回的 URL。
  • 返回格式
    • 成功时 { "success": True, "yaocai": ..., "image_url": ... }
    • 失败时带错误信息。

8. 启动 MCP SSE 服务

if __name__ == "__main__":# 监听所有网卡并启动 SSE 服务mcp.settings.host = "0.0.0.0"mcp.settings.port = 8003mcp.run(transport="sse")
  • host = "0.0.0.0":监听所有网络接口,外部机器可访问。
  • transport="sse":使用 Server-Sent Events(SSE)协议,支持单向实时推送,适合分布式微服务之间的轻量级消息调用。
  • 最终在 8003 端口 启动一个 SSE 服务,其他服务或前端就可以通过 MCP 协议(HTTP+SSE)调用你定义的两个工具。
http://www.dtcms.com/a/321258.html

相关文章:

  • 用browse实现菜单功能的方法
  • 快速上手 Ollama:强大的开源语言模型框架
  • Docker的安装使用以及常见的网络问题
  • 数据库恢复技术:保障数据安全的关键
  • DeepSeek辅助编写的带缓存检查的数据库查询缓存系统
  • Odoo 18 → Odoo 19 功能改动对比表
  • 基于Web的交互式坐标系变换矩阵计算工具
  • 时间复杂度计算(以for循环为例)
  • BBH详解:面向大模型的高阶推理评估基准与数据集分析
  • 轻松实现浏览器自动化——AI浏览器自动化框架Stagehand
  • 力扣 hot100 Day69
  • 使用 PicGo 与 GitHub 搭建高效图床,并结合 Local Images Plus 备份原图
  • 杂谈 001 · VScode / Copilot 25.08 更新
  • 供电架构之供电构型分类
  • 浪漫沙迦2|浪漫沙加2 七英雄的复仇 送修改器(Romancing SaGa 2)免安装中文版
  • 机器视觉任务(目标检测、实例分割、姿态估计、多目标跟踪、单目标跟踪、图像分类、单目深度估计)常用算法及公开数据集分享
  • excel 导出
  • 【vue】Vue 重要基础知识清单
  • Numpy科学计算与数据分析:Numpy广播机制入门与实践
  • 使用FinTSB框架进行金融时间序列预测的完整指南
  • 算法提升之-启发式并查集
  • 剪映里面导入多张照片,p图后如何再导出多张照片?
  • VScode 文件标签栏多行显示
  • QML中显示二级界面的三种方式
  • 【Git】企业级使用
  • electron自定义国内镜像
  • 静电释放场景误报率↓78%!陌讯多模态融合算法在工业检测的落地优化
  • 【unity实战】用unity实现一个简易的战斗飞机控制器
  • BUG调试案例十七:ENC424J600以太网掉线问题案例
  • uniapp瀑布流最简单的实现方法