使用说明
使用MCP工具的AI代理-详细的项目流程
📋 项目概述
该项目实现了 AI 代理 它可以与用户进行对话式交互,并使用三个主要工具执行任务:
- 电子邮件工具 -通过SMTP发送电子邮件
- 图表工具 -生成数据可视化仪表板
- PDF工具 -从PDF文档中查询和提取信息
该项目支持两种操作模式:
- 独立代理模式 (
agent.py)-与LLM互动聊天 - MCP服务器模式 (
tools/mcp_server.py)-通过模型上下文协议公开的工具
🏗️ 架构概述
┌─────────────────────────────────────────────────────────────┐
│ AI Agent Project │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌────────────────┐ ┌──────────────────┐ │
│ │ agent.py │ │ tools/mcp_server │ │
│ │ (Standalone) │ │ (MCP Server) │ │
│ └───────┬────────┘ └────────┬─────────┘ │
│ │ │ │
│ └────────────┬────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────┐ │
│ │ Tool Implementations │ │
│ ├────────────────────────┤ │
│ │ • email_tool.py │ │
│ │ • chart_tool.py │ │
│ │ • pdf_tool.py │ │
│ └────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
🔄 流程图1:独立代理模式(python agent.py)
┌─────────────────────────────────────────────────────────────────┐
│ START │
└────────────────────────────┬────────────────────────────────────┘
▼
┌──────────────────────┐
│ Load Environment │
│ Variables (.env) │
└──────────┬───────────┘
▼
┌──────────────────────┐
│ Load LLM Model │
│ (Llama or Fallback) │
└──────────┬───────────┘
▼
┌──────────────────────┐
│ Initialize Chat │
│ History = [] │
└──────────┬───────────┘
▼
┌────────────────────────────────────────┐
│ │
│ CHAT LOOP (Infinite) │
│ │
└────────────┬───────────────────────────┘
▼
┌────────────────────────┐
│ Wait for User Input │
└────────────┬───────────┘
▼
┌────────────────────────┐
│ User types message │
└────────────┬───────────┘
▼
┌────────────────────────┐ YES
│ Input = 'exit'? ├──────────────► END
└────────────┬───────────┘
│ NO
▼
┌────────────────────────┐
│ Add to Chat History │
│ history.append(user) │
└────────────┬───────────┘
▼
┌────────────────────────┐
│ Build Prompt with │
│ SYSTEM_PROMPT + │
│ Chat History │
└────────────┬───────────┘
▼
┌────────────────────────┐
│ Send to LLM Model │
│ (Text Generation) │
└────────────┬───────────┘
▼
┌────────────────────────┐
│ Get Model Response │
└────────────┬───────────┘
▼
┌────────────────────────┐
│ Try Parse as JSON │
│ Tool Call? │
└────────────┬───────────┘
│
┌───────────┴──────────┐
│ │
YES NO
│ │
▼ ▼
┌────────────────────┐ ┌────────────────────┐
│ Extract Tool Name │ │ Display as Normal │
│ and Arguments │ │ Chat Response │
└─────────┬──────────┘ └─────────┬──────────┘
▼ │
┌────────────────────┐ │
│ Call Tool Function │ │
│ - send_email │ │
│ - gen_chart │ │
│ - query_pdf │ │
└─────────┬──────────┘ │
▼ │
┌────────────────────┐ │
│ Get Tool Result │ │
└─────────┬──────────┘ │
▼ │
┌────────────────────┐ │
│ Display Result │ │
└─────────┬──────────┘ │
▼ │
┌────────────────────┐ │
│ Add to History │ │
└─────────┬──────────┘ │
│ │
└───────────┬───────────┘
▼
┌───────────────────────┐
│ Loop back to Wait │
│ for User Input │
└───────────────────────┘
🔄 流程图2:工具执行流程
┌─────────────────────────────────────────────────────────────┐
│ TOOL EXECUTION │
└──────────────────────┬──────────────────────────────────────┘
▼
┌─────────────────────────┐
│ Parse Tool Name & Args │
└─────────┬───────────────┘
▼
┌─────────────────────────┐
│ Which Tool? │
└─────────┬───────────────┘
│
┌────────────┼────────────┐
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│send_email│ │gen_chart │ │query_pdf │
└────┬─────┘ └────┬─────┘ └────┬─────┘
│ │ │
▼ ▼ ▼
┌──────────────────────────────────────────────────────┐
│ EMAIL TOOL FLOW │
├──────────────────────────────────────────────────────┤
│ │
│ 1. Load SMTP config from .env │
│ - SMTP_HOST, SMTP_PORT │
│ - SMTP_USER, SMTP_PASSWORD │
│ │
│ 2. Validate credentials │
│ │
│ 3. Create MIME message │
│ - Set From, To, Subject │
│ - Set Body text │
│ │
│ 4. Connect to SMTP server │
│ - Use TLS if configured │
│ │
│ 5. Authenticate │
│ │
│ 6. Send message │
│ │
│ 7. Return success message │
│ │
└──────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────┐
│ CHART GENERATION FLOW │
├──────────────────────────────────────────────────────┤
│ │
│ 1. Receive data records (JSON array) │
│ - x_key: column for X-axis │
│ - y_key: column for Y-axis │
│ - title: chart title │
│ │
│ 2. Validate data │
│ - Check records not empty │
│ - Verify keys exist in data │
│ │
│ 3. Create Pandas DataFrame │
│ │
│ 4. Generate plot with Matplotlib │
│ - Create figure │
│ - Plot x vs y with markers │
│ - Set labels and title │
│ │
│ 5. Create output directory │
│ - Default: ./data │
│ │
│ 6. Generate timestamped filename │
│ - Format: dashboard_YYYYMMDD_HHMMSS.png │
│ │
│ 7. Save PNG file │
│ │
│ 8. Return file path │
│ │
└──────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────┐
│ PDF QUERY FLOW │
├──────────────────────────────────────────────────────┤
│ │
│ 1. Load PDF_PATH from .env │
│ - Default: ./data/docs.pdf │
│ │
│ 2. Check if PDF exists │
│ │
│ 3. Extract all text from PDF │
│ - Use pypdf library │
│ - Iterate through all pages │
│ - Concatenate text │
│ │
│ 4. Search for question keywords │
│ - Convert to lowercase │
│ - Find first keyword match │
│ │
│ 5. Extract snippet │
│ - Get context around match │
│ - Max 800 characters │
│ │
│ 6. Return text snippet │
│ │
└──────────────────────────────────────────────────────┘
🔄 流程图3:MCP服务器模式
┌─────────────────────────────────────────────────────────┐
│ MCP SERVER MODE │
│ python -m tools.mcp_server │
└───────────────────────┬─────────────────────────────────┘
▼
┌────────────────────────┐
│ Load FastMCP Server │
│ Name: ai-agent-tools │
└────────────┬───────────┘
▼
┌────────────────────────┐
│ Register 3 Tools: │
│ • send_email │
│ • gen_dashboard_chart │
│ • query_pdf │
└────────────┬───────────┘
▼
┌────────────────────────┐
│ Start stdio Server │
│ (JSON-RPC over stdio) │
└────────────┬───────────┘
▼
┌───────────────────────────────┐
│ Listen for JSON-RPC Requests │
│ on stdin │
└───────────┬───────────────────┘
▼
┌───────────────────────────────┐
│ Receive Request from Client │
│ (e.g., Claude Desktop) │
└───────────┬───────────────────┘
▼
┌───────────────────────────────┐
│ Parse JSON-RPC Message │
└───────────┬───────────────────┘
▼
┌───────────────────────────────┐
│ Route to Tool Handler │
└───────────┬───────────────────┘
▼
┌───────────────────────────────┐
│ Execute Tool Function │
└───────────┬───────────────────┘
▼
┌───────────────────────────────┐
│ Serialize Result as JSON │
└───────────┬───────────────────┘
▼
┌───────────────────────────────┐
│ Send JSON-RPC Response │
│ to stdout │
└───────────┬───────────────────┘
▼
┌───────────────────────────────┐
│ Loop: Wait for Next Request │
└───────────────────────────────┘
📊 组件交互图
┌──────────────┐
│ User │
└──────┬───────┘
│
│ "Send email to john@example.com"
│
▼
┌──────────────────────────────────────────┐
│ agent.py (Main Application) │
├──────────────────────────────────────────┤
│ │
│ 1. Receives user input │
│ 2. Formats prompt with history │
│ 3. Sends to LLM │
│ ┌─────────────────────┐ │
│ │ LLM Model (Llama) │ │
│ │ - Understands │ │
│ │ natural language │ │
│ │ - Decides tool use │ │
│ └─────────────────────┘ │
│ 4. Parses response │
│ │
└───────────────┬──────────────────────────┘
│
│ Tool Call: send_email(to="john@...", ...)
▼
┌───────────────────────────────────────────┐
│ tools/email_tool.py │
├───────────────────────────────────────────┤
│ │
│ Connects to: │
│ ┌─────────────────────────────┐ │
│ │ SMTP Server (Gmail, etc) │ │
│ │ - Authenticates │ │
│ │ - Sends email │ │
│ └─────────────────────────────┘ │
│ │
└───────────────┬───────────────────────────┘
│
│ Result: "Email sent successfully"
▼
┌───────────────────────────────────────────┐
│ agent.py │
│ - Displays result to user │
│ - Adds to conversation history │
└───────────────┬───────────────────────────┘
│
▼
┌──────────────┐
│ User │
│ (sees result)│
└──────────────┘
🗂️ 数据流图
INPUT DATA SOURCES PROCESSING OUTPUT
───────────────── ────────── ──────
┌──────────────┐ ┌──────────────┐
│ User Input │──────┐ │ Email Sent │
│ (Console) │ │ └──────────────┘
└──────────────┘ │ ▲
│ │
┌──────────────┐ │ ┌──────────────┐ │
│ .env File │──────┼────────▶│ Agent Core │─────────┤
│ - Secrets │ │ │ - LLM │ │
│ - Config │ │ │ - Parser │ │
└──────────────┘ │ │ - Tools │ │
│ └──────────────┘ │
┌──────────────┐ │ │
│ JSON Data │──────┘ │
│ (Charts) │ │
└──────────────┘ ┌─────────┴────────┐
│ Chart PNG File │
┌──────────────┐ │ (./data/*.png) │
│ PDF Files │────────────────────────────────┤ │
│ (./data/*.pdf)│ └──────────────────┘
└──────────────┘
┌──────────────┐
│ Text Output │
│ (Console) │
└──────────────┘
🔧 配置流程
┌─────────────────────────────────────────────────────────┐
│ CONFIGURATION HIERARCHY │
└─────────────────────────────────────────────────────────┘
.env.example
│
│ (Copy to)
▼
.env ─────────────┐
│ │
│ │
┌───────────┴───────────┐ │
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────────┐
│ agent.py │ │ tools/*.py │
│ │ │ │
│ • LLM_MODEL │ │ • SMTP_* │
│ • HF_TOKEN │ │ • CHART_* │
│ │ │ • PDF_PATH │
└──────────────┘ └──────────────────┘
Environment Variables Used:
───────────────────────────
LLM Model:
• HF_TOKEN - Hugging Face authentication
• LLM_MODEL - Model name (default: Llama-3.2-3B)
Email Tool:
• SMTP_HOST - SMTP server address
• SMTP_PORT - SMTP port (default: 587)
• SMTP_USER - Login username
• SMTP_PASSWORD - Login password
• SMTP_USE_TLS - Enable TLS (default: true)
• EMAIL_FROM - Sender email address
Chart Tool:
• CHART_OUTPUT_DIR - Output directory (default: ./data)
PDF Tool:
• PDF_PATH - PDF file location (default: ./data/docs.pdf)
🎯 用例场景
场景1:发送电子邮件报告
User Input: "Send email to manager@company.com about Q4 results"
Flow:
1. User types message → agent.py
2. agent.py → LLM processes request
3. LLM → Returns JSON tool call
{
"tool": "send_email",
"args": {
"to": "manager@company.com",
"subject": "Q4 Results Report",
"body": "The Q4 results are ready for review..."
}
}
4. agent.py → Calls email_tool.send_email()
5. email_tool → Connects to SMTP server
6. SMTP server → Sends email
7. Result → Returns to agent
8. agent → Displays "Email sent successfully"
场景2:生成仪表板
User Input: "Create a sales chart for January data"
Flow:
1. User provides data or agent extracts from context
2. LLM → Returns JSON tool call
{
"tool": "generate_dashboard_chart",
"args": {
"records": [
{"date": "2025-01-01", "sales": 1000},
{"date": "2025-01-02", "sales": 1500}
],
"x_key": "date",
"y_key": "sales",
"title": "January Sales"
}
}
3. agent.py → Calls chart_tool.generate_dashboard_chart()
4. chart_tool → Creates matplotlib plot
5. chart_tool → Saves to ./data/dashboard_TIMESTAMP.png
6. Result → Returns file path
7. agent → Displays "Chart saved to ./data/dashboard_20251208.png"
场景3:查询PDF
User Input: "What does the PDF say about requirements?"
Flow:
1. User asks question → agent.py
2. LLM → Returns JSON tool call
{
"tool": "query_pdf",
"args": {
"question": "requirements"
}
}
3. agent.py → Calls pdf_tool.query_pdf()
4. pdf_tool → Reads PDF from ./data/docs.pdf
5. pdf_tool → Extracts relevant text snippet
6. Result → Returns text containing "requirements"
7. agent → Displays extracted text to user
🔄 错误处理流程
┌─────────────────────────────────────────────────────────┐
│ ERROR HANDLING │
└─────────────────────────────────────────────────────────┘
Agent Level:
┌─────────────────┐
│ LLM Load Fails │
└────────┬────────┘
│
▼
┌─────────────────┐ YES ┌──────────────────┐
│ Gated Model? ├───────────▶│ Show HF License │
└────────┬────────┘ │ Instructions │
│ NO └──────────────────┘
▼
┌─────────────────┐
│ Try Fallback │
│ (SmolLM) │
└────────┬────────┘
│
▼
┌─────────────────┐ FAIL ┌──────────────────┐
│ Fallback Works? ├───────────▶│ Exit with Error │
└────────┬────────┘ └──────────────────┘
│ SUCCESS
▼
┌─────────────────┐
│ Continue with │
│ Fallback Model │
└─────────────────┘
Tool Level:
Email Tool:
• Missing SMTP config → RuntimeError
• Auth fails → SMTP exception
• Network error → Connection error
Chart Tool:
• No data → ValueError
• Invalid keys → ValueError
• Cannot save → IOError
PDF Tool:
• PDF not found → FileNotFoundError
• Cannot parse → PDF error
• No match → Returns beginning of document
📦 项目结构
ai-agent-mcp/
│
├── agent.py # Main standalone agent
├── pyproject.toml # Poetry dependencies
├── .env # Configuration (user creates)
├── .env.example # Configuration template
│
├── tools/ # Tool implementations
│ ├── __init__.py
│ ├── mcp_server.py # MCP server wrapper
│ ├── email_tool.py # Email functionality
│ ├── chart_tool.py # Chart generation
│ └── pdf_tool.py # PDF querying
│
├── data/ # Data directory
│ ├── *.png # Generated charts
│ └── docs.pdf # PDF for querying
│
├── test_tools.py # Tool testing script
├── example_usage.py # Usage examples
└── USAGE.md # User guide
🚀 执行模式摘要
| 模式 | 命令 | 用例 |
|---|---|---|
| 交互式代理 | python agent.py |
与AI代理聊天,对话式执行工具 |
| MCP服务器 | python -m tools.mcp_server |
向MCP客户端公开工具(Claude Desktop) |
| 直接测试 | python test_tools.py |
无LLM的测试工具 |
| 示例脚本 | python example_usage.py |
请参阅编程工具用法 |
🔑 关键技术
- LLM:拥抱脸部变形金刚(Llama 3.2或SmolLM2)
- 主控程序:模型上下文协议(FastMCP)
- 电子邮件:通过Python发送SMTP
smtplib - 图表:Matplotlib+熊猫
- PDF:pypdf库
- 配置:python dotenv
- 依赖项:诗歌
这个全面的流程文档显示了所有组件如何交互以创建具有工具调用功能的功能性AI代理!