使用说明
多代理客户支持系统(谷歌ADK+MCP+SQLite)
该项目实现了端到端 多代理客户支持系统 使用:
- 谷歌代理开发工具包(ADK) 用于多代理编排
- 一种模型上下文协议(MCP)HTTP服务器 公开数据库工具
- SQLite数据库 用于客户+票务数据(
support.db) - 哔哔 使MCP服务器可从ADK公开访问
- 三个概念代理:
- 路由器代理 –理解意图并路由请求
- 客户数据代理 –调用MCP工具读取/更新数据库
- 支援谍员 –处理账单问题、升级和升级
该系统会遍历现实的客户支持场景,例如:
- 获取客户资料
- 升级帐户
- 寻找持有未结门票的活跃客户
- 处理重复账单和退款
- 更新联系信息并总结票务历史
1.项目文件
此存储库具有 扁平结构 (由Colab创建):
.
├── README.md # This file
├── requirements.txt # Python dependencies
├── database_setup.py # Script to create and seed support.db
├── mcp_server.ipynb # Colab/Jupyter notebook: MCP server + ngrok tunnel
└── a2a.ipynb # Colab/Jupyter notebook: ADK multi-agent demo
每个文件的作用
-
database_setup.py-
创建
support.db(SQLite数据库)。 -
构建
customers和tickets桌子。 -
可选择插入演示中使用的样本客户+门票。
-
-
mcp_server.ipynb-
定义低级SQLite帮助程序(
get_db_connection,row_to_dict等等)。 -
实现Python函数:
-
get_customer -
list_customers -
update_customer -
create_ticket -
get_customer_history
-
-
将这些功能包装为 MCP工具.
-
开始a Flask HTTP服务器 带着一个
/mcp通过服务器发送事件(SSE)传输MCP的端点。 -
用途 吸烟 将本地服务器公开为
https://<random-subdomain>.ngrok-free.dev/mcp. -
包括一个发送
initializeMCP请求通过requests并打印服务器的响应。
-
-
a2a.ipynb-
配置 MCP工具集 在Google ADK中指向MCP URL。
-
定义 客户数据代理 (
LlmAgent)它使用MCP工具。 -
定义 路由器代理 和 支援谍员 加上辅助函数,如
ask_agent_team(...). -
运行任务的演示场景(客户查找、升级帮助、打开工单、计费问题、电子邮件更新+ 历史)。
-
打印详细信息 代理事件跟踪 对于每种情况。
-
2.要求
所有Python依赖项都列在 requirements.txt.
典型的库包括:
-
google-adk(代理开发工具包) -
a2a(代理对代理协议) -
flask,flask-cors -
requests,python-dotenv,termcolor,pyngrok -
标准Python库(已包含在Python运行时中)
创建虚拟环境后安装它们(见下文)。
3.设置和安装
您可以运行此项目 本地 (推荐用于README)或完全在 Colab (最初开发的)。
3.1克隆存储库
git clone https://github.com/<your-username>/<your-repo>.git
cd <your-repo>
3.2创建和激活虚拟环境
python3 -m venv .venv
source .venv/bin/activate # macOS / Linux
# .venv\Scripts\activate # Windows
3.3安装要求
pip install -r requirements.txt
3.4设置您的OpenAI API密钥
您可以导出它:
export OPENAI_API_KEY="your-openai-key-here"
或创建 .env repo根目录中的文件:
OPENAI_API_KEY=your-openai-key-here
4.步骤1-初始化SQLite数据库
从存储库根运行安装脚本:
python database_setup.py
出现提示时:
Would you like to insert sample data? (y/n): y
这将创建一个 support.db 文件与以下文件位于同一目录中:
-
A.
customers表(id、姓名、电子邮件、电话、状态、时间戳) -
A.
tickets表(id、customer_id、问题、状态、优先级、created_at) -
演示场景中使用的示例客户和门票历史记录
您可以通过以下方式验证它是否存在:
ls
# You should see: database_setup.py, a2a.ipynb, mcp_server.ipynb, support.db, etc.
5.步骤2–运行MCP服务器笔记本
MCP服务器在内部运行 mcp_server.ipynb.
5.1打开笔记本
您可以在以下位置打开它:
-
Colab (从GitHub上传repo/sync),或
-
Jupyter/VS代码 当地。
5.2按顺序运行单元格
在 mcp_server.ipynb:
1.进口和配置
- `sqlite3`, `flask`, `flask_cors`, `requests`, `termcolor`, `pyngrok`, etc.
- `DB_PATH = "./support.db"` (must match the database created in Step 1).
2.数据库辅助函数
- `get_db_connection()`
- `row_to_dict(row)`
3.业务逻辑功能 (直接访问SQLite):
- `get_customer(customer_id: int)`
- `list_customers(status: Optional[str] = None)`
- `update_customer(customer_id, name, email, phone)`
- `create_ticket(customer_id, issue, priority)`
- `get_customer_history(customer_id)`
4.MCP服务器实现
- Defines MCP tools (`MCP_TOOLS`) with JSON schemas.
- Implements handlers for:
- `"initialize"`
- `"tools/list"`
- `"tools/call"`
- Exposes `/mcp` (POST) for MCP messages using SSE.
5.Flask+ngrok启动
- Starts Flask on `127.0.0.1:5000`.
- Runs a health check (`/health`).
- Authenticates ngrok using `NGROK_AUTHTOKEN`.
- Prints lines like:
``` text
✅ MCP Server is running!
📍 Local URL: http://127.0.0.1:5000
🌐 Setting up public tunnel with ngrok...
✅ Public URL: https://una-verminous-chace.ngrok-free.dev
🔗 MCP ENDPOINT : https://una-verminous-chace.ngrok-free.dev/mcp
```
- **Copy the MCP endpoint URL** — you will need it in `a2a.ipynb`.
6.MCP自检单元(可选,但推荐)
-
发送
"initialize"JSON-RPC请求requests.post. -
流式传输SSE响应并打印:
✅ Got MCP response from ADK notebook: { "jsonrpc": "2.0", "id": 999, "result": { "protocolVersion": "2024-11-05", "capabilities": { "tools": {} }, "serverInfo": { "name": "customer-management-server", "version": "1.0.0" } } }
如果你看到这个,你的 MCP服务器+ngrok隧道正在工作.
6.步骤3–运行多代理A2A笔记本
打开 a2a.ipynb.
6.1配置MCP工具集
确保定义的单元格 MCP_SERVER_URL 使用上一步中的隧道。例子:
MCP_SERVER_URL = "https://una-verminous-chace.ngrok-free.dev/mcp"
然后,客户数据代理的连接方式如下:
from google.adk.agents import LlmAgent
from google.adk.tools.mcp_tool import MCPToolset, StreamableHTTPConnectionParams
customer_data_mcp_tools = MCPToolset(
connection_params=StreamableHTTPConnectionParams(
url=MCP_SERVER_URL
)
)
customer_data_agent = LlmAgent(
model="gemini-2.5-flash",
name="customer_data_agent",
description="Agent focused on reading and updating customer records via MCP tools.",
tools=[customer_data_mcp_tools],
instruction="""
You are a customer data specialist.
You can reach a customer database through MCP tools. Use them to:
- fetch details for specific customers by ID
- list customers (optionally by status)
- update contact information (name, email, phone)
- review support ticket history
- open new support tickets
When you act:
- Call the appropriate MCP tool.
- Explain briefly what you did.
- Present customer information in a clean, readable format.
"""
)
6.2路由器和支持代理
a2a.ipynb 还定义了:
-
A. 路由器代理 即:
-
读取用户查询
-
决定这主要是数据、支持还是混合
-
呼叫
transfer_to_agent将工作委托给customer_data_agent或support_agent.
-
-
A. 支援谍员 即:
-
处理账单问题、退款和帐户更改
-
可以向数据代理询问客户或工单上下文
-
以自然语言返回用户友好的解释。
-
6.3运行演示场景
接近尾声 a2a.ipynb,有:
async def run_demo_scenarios():
await ask_agent_team("Please pull the customer record for ID 5.")
await ask_agent_team("I'm customer 12345 and I'd like to upgrade my account. What should I do?")
await ask_agent_team("Show me which active customers currently have open support tickets.")
await ask_agent_team("I was billed twice on my last invoice. I need this investigated and refunded as soon as possible.")
await ask_agent_team("For customer 1, update the email address to new@email.com and then summarize their recent ticket history.")
await run_demo_scenarios()
对于每个查询,运行此单元格打印:
-
A. 头球 与用户消息一起
-
一 代理事件跟踪 显示:
-
路由器委派
-
MCP工具调用(例如。,
get_customer,get_customer_history) -
工具结果(成功或错误,如缺少数据库时出现“没有这样的表”)
-
最终答案返回给“用户”。
-
当 support.db 如果存在并且MCP接线正确,系统将:
-
拉客户5
-
尝试客户12345的升级流程
-
向活跃客户展示未结门票
-
确认重复计费并承诺调查+退款
-
更新客户1的电子邮件并总结他们的票务历史。
7.典型问题及调试注意事项
在开发过程中,以下是常见的陷阱:
1. no such table: customers
-
原因:
support.db未创建或database_setup.py不与在同一目录中运行mcp_server.ipynb. -
修复:重新运行
python database_setup.py并确认support.db存在于笔记本旁边。
2.服务器超时或 No response received
-
原因:MCP服务器未运行、ngrok隧道已过期或MCP URL不匹配。
-
修复:重新启动
mcp_server.ipynb,复制新的ngrok/mcpURL和更新MCP_SERVER_URL在a2a.ipynb.
3.端口5000已在使用中
-
原因:以前的Flask服务器仍在Colab/local中运行。
-
修复:重新启动运行时或更改中使用的端口
server.py/mcp_server.ipynb.
了解这些故障模式是学习经验的一部分,并有助于强化当任何链接(DB、隧道或URL)配置错误时,多组件系统是多么脆弱。