内容
# 工厂规划器
基于ReAct的智能供应链协调代理,使用 **Google Agent Development Kit (ADK)** 并兼容 **Agent-to-Agent (A2A)** 协议。
## 这个代理的作用是什么?
`factory_planner` 是一个专家代理,旨在智能验证工业生产批次是否可以启动。其决策严格基于实时获取的三个信息坐标的组合:
1. **本地船队时间表(`production_schedule.json`)**:查询本地JSON文件(与BigQuery表 `dvt-sp-agentspace.dev_dataset.containers` 中的实时数据同步),以发现哪些集装箱正在运输,其始发港(pol)、目的地(pod)、预计到达时间(eta)和承运人(carriers)。
2. **通过MCP的实时气候风险(`get_port_weather`)**:调用由 **Model Context Protocol (MCP)** 协议开发的Node.js服务器,该服务器实时向 **wttr.in** 的全球气象API发送HTTP请求,动态评估是否存在可能危及海上运输的风暴、强风或气候警报。
3. **通过A2A的先进装载详情(`logistics_agent`)**:使用Google ADK的本地A2A互连与物流代理 **`LogisticsFix`** (部署在Cloud Run上)进行远程通信。该代理解决了原材料集装箱的海关手续是否已批准、重量是否正确以及内容是否合适的问题。
**黄金法则:** 基于这三点,规划器生成详细的最终建议。如果任何查询工具失败或断开连接,代理 **不会捏造数据**,而会 transparently 通知您。
## 🔌MCP服务器详情:封装Web以适应LLM
在这种情况下,**MCP服务器**被定义为API或Web的“包装器”。该项目在 **Node.js** 中实现了真正的MCP服务器,封装了 **wttr.in** 的全球气象API,并将其翻译成开放的JSON-RPC 2.0通信标准。
### 为什么Gemini需要我们创建这个包装器(MCP)?
语言模型(如Gemini 2.5 Flash)很智能,但在生产中存在物理限制:
1. **无自由导航:** 我们不希望它自主浏览互联网以查找天气,因为它可能会产生幻觉和/或产生不必要的token开支。
2. **上下文饱和:** 气象API返回包含数千行原始数据的巨大JSON。发送整个JSON到LLM会浪费token并减慢响应速度。MCP过滤信息并仅发送关键参数(温度、风、湿度)。
3. **本地逻辑和公式:** LLM不知道如何确定性地计算45公里/小时的风速是否对集装箱船构成高风险。 **我们的Node.js MCP服务器处理实际指标并数学计算运输风险级别**,为LLM提供处理好的结果(`LOW`、`MEDIUM`、`HIGH`)。
### MCP工程中的三个文件:
1. **声明(`mcp_config.json`)**:项目根目录中的清单,指示ADK启动Node子进程在Cloud Run上:
```json
"weather-server": { "command": "node", "args": [".../weather-server/index.js"] }
```
2. **Node.js包装器(`weather-server/index.js`)**:通过stdio使用JSON-RPC 2.0监听请求,实时向`wttr.in`发出HTTP请求,使用实时气象指标分类风险,并在断开连接时具有本地恢复能力。
3. **Python技能注入(`app/agent.py`)**:使用Google ADK的`McpToolset`类透明地连接Node子进程,并直接向Gemini的工具列表注入气候技能`get_port_weather`。
## 🗺️ 代理架构图
以下是 `factory_planner` 代理使用 **Google ADK 2.1.0** 验证生产批次的技术编排流程图:
```mermaid
graph TD
User([👤 用户 <br> Gemini Enterprise]) -->|1. 查询| RootAgent["🤖 计划代理<br> (Agent Runtime)"]
subgraph GCP_Cloud [GCP]
RootAgent -->|加载/读取/写入| GCS[(☁️ GCS Bucket<br>技能、时间表、报告)]
RootAgent -->|3. 调用A2A| A2A[🚚 物流代理<br>Cloud Run]
RootAgent -->|4. 查询天气| MCP[🌦️ MCP天气服务器<br>Cloud Run]
A2A --> BQ[(📊 BigQuery)]
end
%% 外部服务,位于GCP之外
MCP -->|API获取| Wttr[🌍 wttr.in实时API]
RootAgent -->|6. 响应| User
```
## 项目结构
```
factory-planner/
├── app/ # 代理的主要代码
│ ├── agent.py # 代理的推理逻辑、工具和回调
│ ├── agent_runtime_app.py # 代理的封装以适应GCP的Agent Runtime
│ ├── logistics_agent_card.json # A2A物流服务的Agent Card
│ └── app_utils/ # ADK的遥测和类型实用工具
├── skills/ # 动态技能目录,以Markdown格式存储
│ └── weather_report_skill.md # 气候报告生成的专家指南
├── weather-server/ # 实时气候MCP服务器(Node.js stdio)
│ └── index.js # JSON-RPC 2.0处理程序和wttr.in的HTTP请求
├── tests/ # 单元测试、集成测试和评估
├── DEPLOY_GCP.md # 在GCP上部署和注册的详细指南
├── GEMINI.md # Gemini开发代理指南(Gemini CLI/Antigravity)
├── mcp_config.json # MCP服务器配置
├── production_schedule.json # 活动集装箱的本地数据
└── pyproject.toml # Python项目的依赖项
```
## 💡 技能架构和云配置
为了展示 **Google ADK 2.1.0** 在大规模环境中的完整能力,该项目实施了100%无服务器、解耦和安全的架构:
* **来自Google Cloud Storage(GCS)的动态技能:**
* 技能手册(如 `skills/weather_report_skill.md`)安全地存储在 **`gs://dvt-sp-agentspace-factory-skills`** 存储桶中。
* **异步延迟加载:** 代理启动时,会延迟导入技能以安全地将GCS技能下载到内存中。
* **云中的动态船队时间表:**
* 活动集装箱数据库直接从 **`gs://dvt-sp-agentspace-factory-skills/production_schedule.json`** 读取。
* **超级动态!** 您可以通过直接编辑GCS存储桶中的JSON来更新船舶或港口,代理将在无需代码部署的情况下立即读取更改。
* **端到端安全和身份验证(OIDC Bearer Token):**
* Cloud Run上的气候MCP服务器配置为 **100%私有** (`--no-allow-unauthenticated`)。
* 在运行工具时,Python代理使用其服务帐户的默认凭证(或本地的gcloud)动态生成 **Google OIDC Identity Token**,并注入`Authorization: Bearer <TOKEN>`标头以安全地对Cloud Run进行身份验证。
* **具有直接下载链接的云端气候报告:**
* `save_markdown_report`工具将生成的Markdown报告公开上传到GCS存储桶的`/reports/`目录中。
* 返回一个可点击的链接 (`download_url`)。Gemini读取此URL并 **原生地在聊天中注入直接下载按钮** (例如 `[📥 下载GCS中的报告](生成的URL)`),允许用户只需单击一下即可将其保存到PC上。
## 📡 离线/本地优先模式(无需配置即可快速测试)
该项目设计为 **本地优先**,允许任何开发人员或测试人员在 **100%本地和离线**的情况下运行和验证代理行为,无需配置Google Cloud凭证或安装外部依赖项。
### 如何激活它?
只需在您的 `.env` 文件中设置以下变量:
```env
OFFLINE_MODE=true
```
### 离线模式下幕后发生了什么?
当此变量为 `true` 时,Python智能代理激活本地应急协议:
1. **本地技能和指令:** 代替尝试连接到互联网下载GCS技能,代理从 `skills/` 目录立即本地读取它们。
2. **本地时间表:** 绕过GCS,直接从本地 `production_schedule.json` 文件读取船队时间表。
3. **确定性气候模拟:** 代理不需要Cloud Run微服务或生成GCP令牌。查询内部高保真本地气象词典,立即以精确的气候和物理风险响应。
4. **本地保存:** 跳过上传到互联网,在本地 `reports/` 目录中保存Markdown报告。
## 先决条件
开始之前,请确保您已安装:
* **uv**: 高性能Python包管理器 - [安装uv](https://docs.astral.sh/uv/getting-started/installation/)
* **agents-cli**: Google官方代理CLI - 通过运行安装:`uv tool install google-agents-cli`
* **Google Cloud SDK**: 用于云服务和集成 - [安装gcloud](https://cloud.google.com/sdk/docs/install)
* **Node.js(v18+)**: 用于运行MCP天气服务器。
## 项目命令
从项目根目录(`factory-planner`)执行这些命令:
| 命令 | 描述 |
| :--- | :--- |
| `agents-cli install` | 使用`uv`在隔离的虚拟环境(`.venv`)中安装所有项目依赖项。 |
| `uv run adk run app` | **在交互式控制台模式下启动代理** (适用于快速本地测试)。 |
| `uv run python tests/unit/test_agent_local.py` | 运行代理的本地模拟,测试GCS、OIDC和A2A。 |
| `uv run adk web --port 8080 .` | 在`8080`端口启动ADK的交互式Web UI(可视化操场)。 |
| `uv run pytest tests/unit` | 运行本地工具的单元测试套件。 |
| `agents-cli deploy` | 打包并将代理部署到Google Cloud的**Agent Runtime**。 |
| `agents-cli publish gemini-enterprise` | 注册代理并在**Gemini Enterprise**控制台上公开其技能。 |
## 本地测试和开发
1. **安装依赖项:**
```bash
agents-cli install
```
2. **直接在终端中测试代理:**
```bash
uv run python tests/unit/test_agent_local.py
```
3. **交互式Web测试:**
```bash
uv run adk web --port 8080 .
```
## Google云部署
有关在 **Reasoning Engines**上部署代理并在 **Gemini Enterprise Agent Platform**上正式注册其技能的详细文档,请参阅 [DEPLOY_GCP.md](./DEPLOY_GCP.md)。