跳转至

08 - Agent与MCP集成

⚠️ 时效性说明:本章涉及前沿模型/价格/榜单等信息,可能随版本快速变化;请以论文原文、官方发布页和 API 文档为准。

Dify Agent与MCP集成示意图

学习时间:6小时 | 难度:⭐⭐⭐⭐ | 前置知识:完成01-07章学习


🎯 学习目标

完成本章学习后,你将能够: - 理解Dify Agent模式的原理与ReAct/Function Calling机制 - 掌握Dify内置工具和自定义工具的配置方法 - 了解MCP(Model Context Protocol)协议及其在Dify中的集成 - 构建具备工具调用能力的Agent应用 - 设计多Agent协作工作流 - 实现Agent应用的调试、评估与生产部署


📋 目录


1. Agent基础概念

1.1 什么是AI Agent

AI Agent是一种能够自主感知环境、做出决策并执行行动的智能系统。与传统Chatbot不同,Agent具备:

Text Only
┌──────────────────────────────────────────────────┐
│              Chatbot vs Agent 对比                 │
├──────────────────┬───────────────────────────────┤
│     Chatbot      │          Agent                │
├──────────────────┼───────────────────────────────┤
│ 单轮问答         │ 多步推理+行动                  │
│ 固定流程         │ 动态规划                       │
│ 纯文本输出       │ 调用工具执行真实操作            │
│ 无状态           │ 维护任务状态                    │
│ 预定义响应       │ 自主决策                        │
│ 简单场景         │ 复杂任务分解与执行              │
└──────────────────┴───────────────────────────────┘

1.2 Agent推理模式

Dify支持多种Agent推理策略:

推理模式 原理 适用场景 优缺点
ReAct Thought→Action→Observation循环 通用任务,需要推理过程 推理透明,但token消耗高
Function Calling 模型原生工具调用能力 OpenAI/Claude等支持FC的模型 效率高,依赖模型能力
Plan-and-Execute 先规划后执行 复杂多步任务 规划质量影响全局
Text Only
ReAct推理循环:

用户: "帮我查一下北京今天的天气,然后推荐合适的穿搭"

→ Thought: 我需要先查询北京今天的天气数据
→ Action: call_weather_api(city="北京")
→ Observation: 北京今天 15°C, 多云, 东北风3级

→ Thought: 15°C多云,需要推荐适合凉爽天气的穿搭
→ Action: generate_outfit_recommendation(temp=15, weather="cloudy")
→ Observation: 建议穿薄外套+长裤...

→ Thought: 已获取天气和穿搭信息,可以回复用户
→ Answer: 北京今天15°C,多云...建议穿薄外套+长裤...

1.3 Function Calling原理

Python
"""Function Calling工作原理——模型自主决定参数并调用外部工具"""

# 1. 定义工具(Tool/Function)——告诉模型有哪些能力可用
tools = [
    {
        "type": "function",
        "function": {
            "name": "search_database",
            # description是模型选择工具的唯一依据,必须足够详细
            "description": "搜索产品数据库,返回匹配的产品信息",
            "parameters": {
                "type": "object",
                "properties": {
                    "query": {
                        "type": "string",
                        "description": "搜索关键词"  # 每个参数都需要清晰的description
                    },
                    "category": {
                        "type": "string",
                        # 使用enum限制取值范围,避免模型传入无效值
                        "enum": ["电子产品", "服饰", "食品"],
                        "description": "产品类别"
                    },
                    "max_results": {
                        "type": "integer",
                        "default": 5,           # 提供默认值,减少必填参数
                        "description": "返回结果数量"
                    }
                },
                "required": ["query"]  # 只有query是必填的,降低调用门槛
            }
        }
    }
]

# 2. 模型决定是否调用工具
# 输入: 用户消息 + tools定义 → 模型理解工具能力
# 输出: tool_calls(模型自主决定调用哪个工具、传什么参数)

# 3. 执行工具并返回结果(由应用程序执行,非模型执行)
# 4. 模型基于工具结果生成最终自然语言回答

2. Dify Agent模式详解

2.1 创建Agent应用

在Dify中创建Agent应用的步骤:

Text Only
1. 新建应用 → 选择"Agent"类型
2. 配置基础模型(推荐GPT-4o/Claude 3.5 Sonnet)
3. 编写System Prompt(Agent角色和行为指令)
4. 添加工具(内置/自定义/API)
5. 配置Agent策略(ReAct/FC)
6. 测试与调试
7. 发布

2.2 Agent System Prompt设计

Markdown
## 高质量Agent System Prompt模板

你是一个专业的{角色名称},具备以下能力:
1. {核心能力1}
2. {核心能力2}
3. {核心能力3}

### 工具使用规则
- 在需要查询实时信息时,使用搜索工具
- 在需要精确计算时,使用计算工具
- 在不确定的情况下,优先使用工具验证而非直接回答
- 每次工具调用前,先说明调用原因

### 回答规范
- 使用中文回答
- 引用工具返回的数据时标注来源
- 如果工具调用失败,说明原因并提供替代方案
- 复杂任务分步骤完成,每步给出进度说明

### 限制
- 不编造工具不支持的信息
- 不执行可能造成数据修改的危险操作
- 超出能力范围时明确告知用户

2.3 Agent配置参数

YAML
# Dify Agent配置示例——定义Agent的推理策略、模型、工具和记忆
agent:
  # 推理策略:function_calling效率更高,react更透明
  strategy: "function_calling"  # 或 "react"

  # 模型配置——Agent场景建议使用强推理能力的模型
  model:
    provider: "openai"
    name: "gpt-4o"
    temperature: 0.1  # Agent建议低温度,减少随机性,提高工具调用准确率
    max_tokens: 4096

  # 最大迭代次数——防止Agent进入死循环,建议5-10
  max_iterations: 10

  # 工具列表——Agent可调用的能力集
  tools:
    - name: "web_search"    # 内置搜索工具
      enabled: true
    - name: "calculator"    # 内置计算器
      enabled: true
    - name: "custom_api"    # 自定义API工具
      enabled: true
      config:
        api_endpoint: "https://api.example.com"
        auth_type: "bearer_token"

  # 对话记忆——控制上下文窗口大小,平衡质量和成本
  memory:
    type: "message_window"  # 滑动窗口策略,保留最近N条消息
    window_size: 20  # 保留最近20条消息,超出部分会被截断

  # 超时设置——Agent可能多步调用工具,需要较长超时
  timeout: 120  # 秒(建议Agent场景设置2-3分钟)

3. 工具系统

3.1 Dify内置工具

工具类别 工具名称 功能说明 使用场景
搜索 Google搜索 网页搜索 查询实时信息
搜索 Bing搜索 网页搜索 Google的替代方案
搜索 DuckDuckGo 隐私搜索 无需API Key
知识库 知识库检索 RAG检索 查询私有知识
数学 Calculator 数学计算 精确计算
代码 Code Interpreter 执行Python 数据处理/可视化
网页 Web Scraper 网页抓取 提取网页内容
图像 DALL-E 图像生成 生成示意图
天气 Weather 天气查询 实时天气
时间 CurrentTime 当前时间 时间相关任务

3.2 自定义API工具

YAML
# 自定义工具定义(OpenAPI Schema格式)
openapi: "3.0.0"
info:
  title: "企业内部工具集"
  version: "1.0.0"

servers:
  - url: "https://internal-api.company.com/v1"

paths:
  /employees/search:
    get:
      operationId: "searchEmployees"
      summary: "搜索公司员工信息"
      description: "根据姓名或工号搜索员工基本信息和联系方式"
      parameters:
        - name: query
          in: query
          required: true
          schema:
            type: string
          description: "搜索关键词(姓名或工号)"
        - name: department
          in: query
          required: false
          schema:
            type: string
          description: "部门筛选"
      responses:
        "200":
          description: "搜索结果"
          content:
            application/json:
              schema:
                type: object
                properties:
                  employees:
                    type: array
                    items:
                      type: object
                      properties:
                        name:
                          type: string
                        employee_id:
                          type: string
                        department:
                          type: string
                        email:
                          type: string

  /tickets/create:
    post:
      operationId: "createTicket"
      summary: "创建工单"
      description: "在内部工单系统中创建新工单"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - title
                - description
                - priority
              properties:
                title:
                  type: string
                  description: "工单标题"
                description:
                  type: string
                  description: "问题详细描述"
                priority:
                  type: string
                  enum: ["low", "medium", "high", "critical"]
                  description: "优先级"
      responses:
        "201":
          description: "工单创建成功"

3.3 工具编排最佳实践

Python
"""Dify工具编排设计原则"""

TOOL_DESIGN_PRINCIPLES = {
    "单一职责": {
        "原则": "每个工具只做一件事",
        "正确": "search_products, get_product_detail, create_order",
        "错误": "search_and_order_products(功能太多)"
    },
    "清晰描述": {
        "原则": "description要足够详细,帮助模型正确选择工具",
        "正确": "搜索产品数据库,支持按名称、类别、价格范围筛选",
        "错误": "搜索功能"
    },
    "参数设计": {
        "原则": "参数要有明确的类型、默认值和说明",
        "建议": [
            "必需参数尽量少(1-3个)",
            "使用enum限制有效值范围",
            "为可选参数提供合理默认值"
        ]
    },
    "错误处理": {
        "原则": "工具返回清晰的错误信息",
        "包含": "错误码 + 错误描述 + 建议操作",
        "示例": '{"error": "product_not_found", '
                '"message": "未找到匹配的产品", '
                '"suggestion": "请尝试更宽泛的搜索词"}'
    },
    "安全考虑": {
        "只读优先": "优先提供查询类工具,写入类工具需要确认",
        "权限控制": "敏感操作需要用户二次确认",
        "数据脱敏": "返回结果中脱敏个人信息"
    }
}

4. MCP协议与集成

4.1 MCP(Model Context Protocol)概述

MCP是由Anthropic提出的开放协议,用于标准化LLM应用与外部数据源、工具的连接方式。

Text Only
┌─────────────────────────────────────────────────────┐
│              MCP架构概览                              │
│                                                     │
│  ┌─────────────┐     ┌─────────────────────┐       │
│  │  MCP Client  │←──→│    MCP Server        │       │
│  │ (Dify/IDE/   │     │  (数据源/工具提供者)  │       │
│  │  App)        │     │                     │       │
│  └─────────────┘     │  提供:              │       │
│                       │  ├── Resources      │       │
│  通信方式:             │  │   (数据/文件)     │       │
│  ├── stdio           │  ├── Tools          │       │
│  ├── HTTP+SSE        │  │   (可执行操作)     │       │
│  └── WebSocket       │  └── Prompts        │       │
│                       │      (提示模板)      │       │
│                       └─────────────────────┘       │
│                                                     │
│  MCP vs 传统API集成:                                 │
│  ├── 传统:每个工具一套集成逻辑,N个工具N套适配         │
│  └── MCP:统一协议,一次集成支持所有MCP Server          │
└─────────────────────────────────────────────────────┘

4.2 MCP核心概念

Python
"""MCP协议核心概念"""

MCP_CONCEPTS = {
    "Resources(资源)": {
        "定义": "MCP Server暴露的数据或内容",
        "URI格式": "file:///path/to/file, db://table/records",
        "特点": "只读,由应用程序控制何时获取",
        "示例": ["文件内容", "数据库记录", "API响应", "截屏"]
    },
    "Tools(工具)": {
        "定义": "MCP Server暴露的可执行操作",
        "特点": "由模型决定何时调用(类似Function Calling)",
        "示例": ["执行SQL查询", "发送邮件", "创建文件", "调用API"],
        "安全": "需要用户确认执行(human-in-the-loop)"
    },
    "Prompts(提示)": {
        "定义": "预定义的提示模板,可复用上下文",
        "特点": "由用户显式选择使用",
        "示例": ["代码审查模板", "数据分析模板", "报告生成模板"]
    },
    "Sampling(采样)": {
        "定义": "Server可以请求Client执行LLM推理",
        "特点": "实现Agent嵌套(Server端也能调用LLM)",
        "场景": "复杂工具需要LLM辅助决策时使用"
    }
}

4.3 在Dify中配置MCP

YAML
# Dify MCP集成配置步骤

# 步骤1:在Dify后台安装MCP插件
# 路径:工作空间设置 → 插件 → MCP

# 步骤2:配置MCP Server连接——支持本地(stdio)和远程(SSE)两种方式
mcp_servers:
  # 本地文件系统 MCP Server(通过npx直接启动,无需单独部署)
  - name: "filesystem"
    transport: "stdio"       # 本地标准输入输出通信
    command: "npx"
    args: ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/docs"]

  # 数据库 MCP Server(支持SQL查询,需配置连接字符串)
  - name: "postgres"
    transport: "stdio"
    command: "npx"
    args: ["-y", "@modelcontextprotocol/server-postgres"]
    env:
      POSTGRES_CONNECTION_STRING: "postgresql://user:pass@localhost/db"

  # 远程 MCP Server(通过SSE協议连接,适用于云端部署)
  - name: "remote_tools"
    transport: "sse"         # Server-Sent Events长连接
    url: "https://mcp.example.com/sse"
    headers:
      Authorization: "Bearer ${MCP_API_KEY}"  # 使用环境变量避免硬编码密钥

# 步骤3:在Agent中启用MCP工具
# 创建Agent应用 → 工具管理 → 勾选MCP Server提供的工具

4.4 自定义MCP Server开发

Python
"""使用Python开发自定义MCP Server——将企业内部工具暴露给LLM Agent"""

# pip install mcp

from mcp.server import Server
from mcp.types import Tool, TextContent
from mcp.server.stdio import stdio_server
import json

# 创建MCP Server实例,名称用于Client识别和日志
server = Server("company-tools")

# 使用@server.tool()装饰器注册工具——函数签名自动转换为工具参数Schema
@server.tool()
async def query_sales_data(  # async def定义异步函数;用await调用
    start_date: str,
    end_date: str,
    product_category: str = "all"
) -> list[TextContent]:
    """
    查询销售数据。

    Args:
        start_date: 开始日期(YYYY-MM-DD)
        end_date: 结束日期(YYYY-MM-DD)
        product_category: 产品类别,默认all

    Returns:
        销售数据摘要
    """
    # 实际查询数据库(使用参数化查询防止SQL注入)
    results = await db.query(  # await等待异步操作完成
        "SELECT * FROM sales WHERE date BETWEEN %s AND %s",
        (start_date, end_date)
    )

    # 按类别过滤(在应用层而非SQL层,保持灵活性)
    if product_category != "all":
        results = [r for r in results if r["category"] == product_category]

    # 汇总统计信息,返回结构化摘要而非原始数据
    summary = {
        "total_revenue": sum(r["amount"] for r in results),
        "total_orders": len(results),
        "top_products": get_top_products(results, n=5)
    }

    # MCP工具必须返回TextContent列表
    return [TextContent(
        type="text",
        text=json.dumps(summary, ensure_ascii=False, indent=2)  # json.dumps将Python对象转为JSON字符串
    )]

@server.tool()
async def create_report(
    title: str,
    content: str,
    format: str = "markdown"
) -> list[TextContent]:
    """
    生成并保存报告文件。

    Args:
        title: 报告标题
        content: 报告内容
        format: 格式(markdown/html/pdf)
    """
    filepath = f"/reports/{title}.{format}"
    await save_report(filepath, content, format)

    return [TextContent(
        type="text",
        text=f"报告已保存: {filepath}"
    )]

# 定义资源——使用URI模板暴露可查询的数据资源
@server.resource("sales://monthly/{year}/{month}")
async def get_monthly_sales(year: str, month: str) -> str:
    """获取月度销售报告——只读Resource,由应用程序控制访问时机"""
    data = await db.get_monthly_report(int(year), int(month))
    return json.dumps(data, ensure_ascii=False)

# 启动MCP Server——通过stdio与Client通信(适用于本地部署)
async def main():
    async with stdio_server() as (read_stream, write_stream):
        await server.run(read_stream, write_stream)

if __name__ == "__main__":
    import asyncio
    asyncio.run(main())  # asyncio.run()启动异步事件循环

4.5 MCP vs OpenAPI工具对比

维度 OpenAPI/REST MCP
协议标准 OpenAPI 3.0 MCP规范
通信方式 HTTP请求/响应 stdio/SSE/WebSocket
状态管理 无状态 有状态(会话级)
双向通信 不支持 支持(Sampling)
资源发现 需要文档 自动发现(list_tools)
适用场景 已有REST API 新建工具/复杂交互
Dify集成 自定义API工具 MCP插件
生态 成熟,工具多 新兴,快速增长

5. Agent工作流设计

5.1 Agent节点在工作流中的使用

Dify工作流支持将Agent作为节点嵌入更复杂的流程:

Text Only
┌─────────────────────────────────────────────────────┐
│           Agent增强型工作流设计                        │
│                                                     │
│  开始 → [输入预处理] → [意图分类]                      │
│                            │                        │
│                 ┌──────────┼──────────┐              │
│                 ▼          ▼          ▼              │
│           [FAQ RAG]  [Agent节点]  [表单收集]           │
│           知识库检索  工具调用+推理   结构化提问          │
│                 │          │          │              │
│                 └──────────┼──────────┘              │
│                            ▼                        │
│                    [结果整合与格式化]                   │
│                            ▼                        │
│                    [质量检查节点]                      │
│                     ├── 通过 → [输出]                  │
│                     └── 不通过 → [人工审核]             │
│                                                     │
└─────────────────────────────────────────────────────┘

5.2 条件化Agent调用

YAML
# 智能路由 + Agent工作流示例——根据意图分类路由到不同处理节点

workflow:
  name: "智能客服升级版"

  nodes:
    # 意图分类节点:使用LLM判断用户意图,作为后续路由的依据
    - id: "classifier"
      type: "llm"
      prompt: |
        判断用户意图,返回以下类别之一:
        - FAQ: 常见问题
        - ORDER: 订单查询/操作
        - COMPLAINT: 投诉
        - COMPLEX: 复杂问题

        用户消息: {{input}}
        类别:

    # FAQ类意图:走知识库RAG检索,成本低、速度快
    - id: "faq_rag"
      type: "knowledge_retrieval"
      condition: "classifier.output == 'FAQ'"
      dataset_id: "faq_dataset_001"
      top_k: 3

    # 订单类意图:走Agent节点,具备工具调用能力
    - id: "order_agent"
      type: "agent"
      condition: "classifier.output == 'ORDER'"
      model: "gpt-4o-mini"        # 订单查询较简单,用小模型即可
      tools:
        - "query_order_status"     # 查订单状态
        - "track_shipment"         # 查物流
        - "request_refund"         # 申请退款(写操作,需确认)
      max_iterations: 5
      system_prompt: |
        你是订单助手。帮用户查询订单状态、物流信息。
        执行退款操作前必须确认订单号和退款原因。

    # 投诉类意图:直接创建高优先级工单,转人工处理
    - id: "escalate"
      type: "http_request"
      condition: "classifier.output == 'COMPLAINT'"
      url: "https://api.company.com/tickets"
      method: "POST"
      body:
        type: "complaint"
        message: "{{input}}"
        priority: "high"

5.3 迭代式Agent工作流

Python
"""设计一个迭代式研究Agent工作流"""

RESEARCH_AGENT_WORKFLOW = {
    "节点1 - 研究规划": {
        "类型": "LLM",
        "功能": "分析研究主题,生成3-5个子问题",
        "输出": "研究计划(子问题列表)"
    },
    "节点2 - 迭代研究(循环)": {
        "类型": "Agent(循环节点)",
        "功能": "对每个子问题:搜索→阅读→总结",
        "工具": ["web_search", "web_scraper", "knowledge_base"],
        "循环条件": "遍历所有子问题",
        "每轮输出": "该子问题的研究结果"
    },
    "节点3 - 信息整合": {
        "类型": "LLM",
        "功能": "整合所有子问题的研究结果",
        "输出": "完整的研究报告草稿"
    },
    "节点4 - 质量评估": {
        "类型": "LLM",
        "功能": "评估报告质量,识别缺失信息",
        "输出": "质量分数 + 改进建议"
    },
    "节点5 - 条件分支": {
        "类型": "条件",
        "条件": "质量分数 >= 8 → 输出",
        "否则": "回到节点2补充研究(最多2次)"
    },
    "节点6 - 格式化输出": {
        "类型": "模板",
        "功能": "将报告格式化为最终格式"
    }
}

6. 多Agent协作

6.1 多Agent架构模式

Text Only
模式1: 主控Agent + 专家Agent

┌──────────────────────┐
│    主控Agent          │
│  (路由 + 协调)        │
│                      │
│  "用户的问题需要哪个   │
│   专家来处理?"        │
└──────┬───────────────┘
  ┌────┼────┬────────┐
  ▼    ▼    ▼        ▼
[数据] [代码] [文案]  [设计]
Agent  Agent  Agent   Agent

模式2: 流水线Agent

[需求分析Agent] → [方案设计Agent] → [代码生成Agent] → [测试Agent]

模式3: 辩论/协商Agent

  [Agent A: 正方] ←→ [Agent B: 反方]
    [裁判Agent: 综合判断]

6.2 在Dify中实现多Agent

YAML
# 通过嵌套工作流实现多Agent协作——主控Agent调度多个专家Agent

# 主工作流:编排Agent主控调度器
main_workflow:
  name: "多Agent协作系统"

  nodes:
    # 主控Agent:分析任务类型,调度合适的专家Agent
    - id: "orchestrator"
      type: "agent"
      system_prompt: |
        你是团队协调者。根据用户需求,调用合适的专家工具:
        - analyze_data: 数据分析任务
        - write_code: 编程任务
        - create_content: 内容创作任务
        分析每个专家的返回结果,必要时多次调用不同专家。
      tools:
        - "analyze_data"     # 数据分析子工作流(作为工具暴露)
        - "write_code"       # 代码生成子工作流
        - "create_content"   # 内容创作子工作流

# 子工作流作为工具暴露——每个子工作流是一个独立的专家Agent
sub_workflows:
  - name: "analyze_data"
    type: "workflow_as_tool"    # 关键:将工作流包装为可调用工具
    workflow_id: "data_analysis_workflow"
    description: "执行数据分析,包括数据清洗、统计和可视化"

  - name: "write_code"
    type: "workflow_as_tool"
    workflow_id: "code_generation_workflow"
    description: "根据需求生成代码,支持Python/JavaScript"

7. Agent调试与评估

7.1 Agent调试方法

Python
"""Agent调试检查清单"""

AGENT_DEBUG_CHECKLIST = {
    "工具调用问题": {
        "不调用工具": [
            "检查System Prompt是否明确说明何时使用工具",
            "检查工具description是否足够清晰",
            "检查模型是否支持Function Calling",
            "尝试在Prompt中添加Few-shot示例"
        ],
        "调用错误工具": [
            "检查工具命名和描述是否有歧义",
            "减少工具数量(<10个为佳)",
            "在description中添加使用/不使用的场景说明"
        ],
        "参数错误": [
            "检查参数的type和description是否准确",
            "添加参数示例值",
            "使用enum限制有效值"
        ]
    },
    "推理问题": {
        "无限循环": [
            "设置max_iterations(建议5-10)",
            "检查工具返回是否给出了足够信息让Agent停止",
            "添加明确的终止条件在System Prompt中"
        ],
        "推理链质量差": [
            "切换到更强的模型(GPT-4o)",
            "降低temperature(0.0-0.1)",
            "在System Prompt中添加推理步骤指引"
        ]
    },
    "性能问题": {
        "响应太慢": [
            "减少不必要的工具调用",
            "并行执行独立的工具调用",
            "缓存频繁查询的结果",
            "使用更快的模型(GPT-4o-mini)处理简单步骤"
        ]
    }
}

7.2 Agent评估指标

评估维度 指标 说明 目标值
任务完成率 Success Rate 正确完成任务的比例 >85%
工具使用准确率 Tool Accuracy 调用正确工具的比例 >90%
平均步骤数 Avg Steps 完成任务的平均步骤 越少越好
延迟 E2E Latency 端到端响应时间 <30s
Token消耗 Token Usage 单次任务token用量 控制成本
回退率 Fallback Rate 需要人工介入的比例 <15%
用户满意度 CSAT 用户评分 >4.0/5
Python
"""Agent评估脚本示例——系统化衡量Agent的任务完成率、工具准确率和性能"""

import json
from typing import List, Dict

class AgentEvaluator:
    """系统化评估Agent应用——基于预定义测试用例自动评分"""

    def __init__(self, test_cases: List[Dict]):
        self.test_cases = test_cases  # 预定义的测试用例集
        self.results = []              # 评估结果存储

    def evaluate(self, agent_fn):
        """
        运行评估:对每个测试用例调用Agent,收集多维度指标

        Args:
            agent_fn: Agent调用函数,输入问题返回结果字典
        """
        for case in self.test_cases:
            # 调用Agent处理测试输入
            result = agent_fn(case["input"])

            # 收集评估维度:输出内容、工具使用、步骤数、延迟、Token消耗
            evaluation = {
                "input": case["input"],
                "expected": case["expected_output"],
                "actual": result["output"],
                "tools_used": result["tools_called"],        # 实际调用的工具列表
                "expected_tools": case.get("expected_tools", []),  # 期望调用的工具
                "steps": result["num_steps"],               # 推理步骤数
                "latency": result["latency_ms"],             # 端到端延迟(ms)
                "tokens": result["total_tokens"],            # Token消耗量
            }

            # 判断任务是否成功(基于输出匹配)
            evaluation["success"] = self._check_success(
                evaluation["actual"],
                evaluation["expected"]
            )

            # 检查工具调用是否符合预期(集合比较,不关心顺序)
            evaluation["correct_tools"] = set(
                evaluation["tools_used"]
            ) == set(evaluation["expected_tools"])

            self.results.append(evaluation)

        return self._summary()

    def _summary(self):
        """汇总评估结果——计算各指标的均值"""
        n = len(self.results)
        return {
            "success_rate": sum(r["success"] for r in self.results) / n,      # 任务成功率
            "tool_accuracy": sum(r["correct_tools"] for r in self.results) / n, # 工具调用准确率
            "avg_steps": sum(r["steps"] for r in self.results) / n,            # 平均推理步骤
            "avg_latency_ms": sum(r["latency"] for r in self.results) / n,      # 平均延迟
            "avg_tokens": sum(r["tokens"] for r in self.results) / n,           # 平均Token消耗
        }

# 测试用例示例——每个用例包含输入、期望输出和期望调用的工具
test_cases = [
    {
        "input": "帮我查一下订单 ORD-12345 的物流状态",
        "expected_output": "包含物流状态信息",
        # Agent应先查订单,再查物流,需要两个工具协作
        "expected_tools": ["query_order", "track_shipment"]
    },
    {
        "input": "我要退货,订单号ORD-67890",
        "expected_output": "退货申请已提交",
        # Agent应先查询订单确认存在,再创建退货单
        "expected_tools": ["query_order", "create_return"]
    }
]

8. 生产部署最佳实践

8.1 Agent应用上线清单

Text Only
□ 功能测试
  ├── 所有工具单独测试通过
  ├── 正常路径测试(Happy Path)
  ├── 异常路径测试(工具超时/错误/无结果)
  └── 边界情况测试(空输入/超长输入/注入攻击)

□ 性能测试
  ├── 平均响应时间 < 目标值
  ├── P99延迟可接受
  └── 并发测试(模拟实际负载)

□ 安全审查
  ├── Prompt注入防护
  ├── 工具权限最小化
  ├── 敏感信息脱敏
  └── 日志中不记录密码/Token

□ 监控配置
  ├── 任务成功率监控
  ├── 工具调用错误率
  ├── Token消耗趋势
  ├── 延迟监控(告警阈值)
  └── 用户反馈收集

□ 降级方案
  ├── LLM API不可用 → 规则引擎兜底
  ├── 工具调用超时 → 跳过或重试
  ├── 复杂问题 → 转人工
  └── 成本超限 → 切换小模型

8.2 成本控制

Python
"""Agent应用成本控制策略——在保证质量的前提下最小化Token消耗"""

COST_CONTROL = {
    "模型选择": {
        "策略": "简单任务用小模型,复杂任务用大模型",
        # 分级策略:约80%的请求可用小模型处理,节省大量费用
        "实现": {
            "意图分类": "GPT-4o-mini(几乎不用大模型)",
            "Agent推理": "GPT-4o(需要强推理能力)",
            "简单生成": "GPT-4o-mini",
        },
        "节省": "~60% Token费用"
    },
    "工具调用优化": {
        "缓存": "常用工具结果缓存(TTL=5min)",       # 相同参数避免重复调用
        "批量": "支持批量查询的工具一次查多个",     # 减少工具调用次数
        "预检": "先检查参数合法性再调用API"       # 避免无效调用浪费Token
    },
    "对话管理": {
        "上下文窗口": "只保留最近10-20轮对话",       # 控制输入Token数
        "摘要压缩": "超过窗口的历史用摘要代替",     # 保留关键信息,减少冗余
        "Session超时": "30分钟无活动自动关闭"       # 及时释放资源
    },
    "限制策略": {
        "每用户每日": "最多100次Agent调用",           # 防止滥用
        "单次最大Token": "4096 output tokens",          # 控制单次成本
        "最大迭代": "10步(防无限循环)"                  # 安全上限
    }
}

9. 实战:构建智能研究助手

9.1 需求分析

构建一个能够自动搜索、分析、整理信息的研究助手Agent:

Text Only
功能需求:
├── 接收研究主题
├── 自动搜索相关资料(网页+知识库)
├── 提取关键信息并做摘要
├── 对比不同来源的信息
├── 生成结构化研究报告
└── 支持追问深入某个方面

技术选型:
├── 模型:GPT-4o(复杂推理)
├── 推理模式:ReAct(透明的推理过程)
├── 工具:Web搜索 + 网页抓取 + 知识库 + Code Interpreter
└── 部署:Dify Cloud / Self-hosted

9.2 实现步骤

YAML
# 研究助手Agent配置

application:
  name: "AI研究助手"
  type: "agent"

  model:
    provider: "openai"
    name: "gpt-4o"
    temperature: 0.2

  system_prompt: |
    你是一位专业的研究助手,擅长搜索、分析和整理信息。

    ## 工作流程
    1. 理解用户的研究主题和具体需求
    2. 制定研究计划(列出需要调查的子问题)
    3. 逐个搜索和分析子问题
    4. 整合信息,生成报告

    ## 工具使用规则
    - 对于每个子问题,先搜索再分析
    - 使用web_search搜索最新信息
    - 使用web_scraper获取详细内容
    - 使用knowledge_base搜索内部知识
    - 使用code_interpreter进行数据分析或可视化

    ## 输出格式
    研究报告应包含:
    - 🎯 主题概述
    - 📊 关键发现(带来源引用)
    - 🔍 详细分析
    - 💡 结论与建议
    - 📚 参考来源

    ## 质量标准
    - 每个论点至少2个来源佐证
    - 标注信息的时效性
    - 对不确定的信息标注"待验证"

  tools:
    - name: "web_search"
      provider: "google"
    - name: "web_scraper"
      provider: "builtin"
    - name: "knowledge_base"
      dataset_ids: ["research_papers", "company_docs"]
    - name: "code_interpreter"
      provider: "builtin"

  max_iterations: 15

  memory:
    type: "message_window"
    window_size: 30

9.3 测试与迭代

Python
"""研究助手评估用例"""

RESEARCH_ASSISTANT_TESTS = [
    {
        "input": "调研2024年大模型推理优化的最新技术",
        "expected_coverage": [
            "Speculative Decoding", "KV Cache优化",
            "量化技术", "vLLM/TGI"
        ],
        "quality_criteria": {
            "had_sources": True,
            "min_sources": 3,
            "structured_output": True,
            "recency": "2024"
        }
    },
    {
        "input": "对比分析LangChain和LlamaIndex的优缺点",
        "expected_coverage": [
            "架构对比", "RAG能力", "Agent能力",
            "社区生态", "使用场景推荐"
        ],
        "quality_criteria": {
            "balanced_comparison": True,
            "has_recommendation": True
        }
    }
]

📝 本章面试题

基础题

Q1:ReAct和Function Calling两种Agent模式有什么区别?各适用于什么场景?

参考答案:ReAct是Thought→Action→Observation循环,推理过程透明可追踪,token消耗较高,适合需要展示推理过程的复杂任务。Function Calling是模型原生能力,直接输出工具调用JSON,效率高、延迟低,适合工具调用明确的场景(如查询API)。Dify中推荐:支持FC的模型(GPT-4o/Claude)优先用FC,开源模型或需要调试推理过程时用ReAct。

Q2:MCP协议相比传统的REST API集成有什么优势?

参考答案:(1) 统一协议——一次集成支持所有MCP Server,减少集成工作量;(2) 动态发现——Client可自动获取Server提供的工具/资源列表;(3) 有状态——支持会话级状态管理;(4) 双向通信——Server可通过Sampling请求Client执行LLM推理;(5) 资源模型——除了工具还支持Resources和Prompts;(6) 安全——内置human-in-the-loop确认机制。但REST API生态更成熟,已有API的场景不必强制迁移MCP。

进阶题

Q3:如何设计Agent的降级和容错方案?

参考答案:多层降级策略:(1) 模型层——主模型超时切备用模型,大模型降级到小模型;(2) 工具层——工具超时设置重试(max 2次)、超时返回默认值而非阻塞、关键工具准备离线缓存;(3) 推理层——设置max_iterations防无限循环、检测重复工具调用(同参数连续调用2次则停止);(4) 系统层——Agent故障回退到规则引擎/预设回复、复杂问题自动转人工;(5) 监控——实时监控成功率/延迟/Token消耗,自动告警。

Q4:Agent应用的成本如何优化?在保证质量的前提下如何控制Token消耗?

参考答案:(1) 模型分级——意图分类用小模型(成本-90%),仅复杂推理用大模型;(2) 工具结果缓存——相同参数的工具调用缓存5-10分钟;(3) 上下文管理——只保留最近10-20轮对话,历史用摘要压缩;(4) Prompt优化——精简System Prompt,移除冗余指令,使用Few-shot而非长描述;(5) 提前终止——检测到用户意图简单时直接回答不走Agent链路;(6) 语义缓存——相似问题复用历史回答(节省20-40%)。

Q5:设计一个多Agent协作的代码审查系统,说明架构和Agent的分工。

参考答案:三Agent流水线架构:(1) 分析Agent——接收代码diff,识别变更范围和类型(新功能/修复/重构),使用AST解析工具分析代码结构,工具:代码解析器、Git工具;(2) 审查Agent——对每个变更模块检查:安全漏洞(SQL注入/XSS)、性能问题(N+1查询/内存泄漏)、代码规范(命名/复杂度)、业务逻辑正确性,工具:规则检查器、知识库(编码规范);(3) 总结Agent——整合审查结果,按严重度排序,生成结构化审查报告(Blocking/Non-blocking/Nit),给出总体评价和改进建议。主控Agent协调三者顺序执行并处理异常。

Q6:在Dify中如何实现一个RAG增强的Agent,使其既能查知识库又能搜索互联网?

参考答案:创建Agent应用,添加两类工具:(1) 知识库检索工具——配置Dify知识库数据集(上传文档并建立向量索引),设置检索参数(top_k=5, score_threshold=0.7);(2) 网页搜索工具——配置Google/Bing搜索API。在System Prompt中明确路由规则:"内部知识问题优先查知识库;时效性问题或知识库无结果时搜索互联网;最终回答标注信息来源"。关键设计:先检索知识库→评估结果质量→不足时再搜索互联网→合并去重→生成最终回答。这样兼顾私有知识的准确性和互联网信息的时效性。


✅ 学习检查清单

  • 理解ReAct和Function Calling的工作原理与区别
  • 能在Dify中创建Agent应用并配置工具
  • 了解MCP协议的核心概念(Resources/Tools/Prompts)
  • 能编写自定义API工具的OpenAPI Schema
  • 理解多Agent协作的设计模式
  • 掌握Agent调试的方法和评估指标
  • 了解Agent应用的成本控制和降级策略

🔗 延伸阅读


返回Dify实战目录


最后更新日期:2026-02-12 适用版本:Dify实战教程 v2026