ADR-015: 標記為「已實作」✅ (Phase 16 R1 完成) ADR-009: 標記為「已實作」✅ (Phase 9.1-9.5 全部完成) ADR-006: 新增智能路由整合章節 (Phase 13.3) 首席架構師 ADR 審計 P0/P1 完成 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
157 lines
4.1 KiB
Markdown
157 lines
4.1 KiB
Markdown
# ADR-015: MCP 模組化架構重構
|
||
|
||
| 欄位 | 值 |
|
||
|------|-----|
|
||
| **狀態** | **已實作** ✅ |
|
||
| **決策日期** | 2026-03-26 |
|
||
| **實作完成** | 2026-03-26 (Phase 16 R1) |
|
||
| **決策者** | 統帥 + 首席架構師 |
|
||
| **觸發原因** | Code Review 發現嚴重模組化違規 |
|
||
|
||
---
|
||
|
||
## 背景
|
||
|
||
Phase 13.2 實作 MCP Tool 整合時,為了快速交付,在 `mcp_bridge.py` 直接 import services 層,違反了 leWOOOgo 積木化原則。
|
||
|
||
### 違規清單
|
||
|
||
| 位置 | 違規 |
|
||
|------|------|
|
||
| mcp_bridge.py:570 | `from src.services.executor import get_executor` |
|
||
| mcp_bridge.py:655 | `from src.services.signoz_client import get_signoz_client` |
|
||
| mcp_bridge.py:734 | `from src.services.approval_db import ...` |
|
||
| mcp_bridge.py:738 | `from src.services.incident_service import get_incident_service` |
|
||
|
||
### 違反的鐵律
|
||
|
||
1. **Interface 先行** - 無 ABC 定義
|
||
2. **禁止跨模組非法引用** - plugins → services 直接 import
|
||
3. **模組間透過 Public API 溝通** - 直接呼叫具體實作
|
||
|
||
---
|
||
|
||
## 決策
|
||
|
||
### 架構重構
|
||
|
||
```
|
||
apps/api/src/plugins/mcp/
|
||
├── __init__.py
|
||
├── interfaces.py # MCPToolProvider ABC (新增)
|
||
├── mcp_bridge.py # 透過 DI 注入 providers (重構)
|
||
├── registry.py # Provider 註冊中心 (新增)
|
||
└── providers/ # 具體實作 (新增)
|
||
├── __init__.py
|
||
├── k8s_provider.py
|
||
├── signoz_provider.py
|
||
└── database_provider.py
|
||
```
|
||
|
||
### Interface 定義
|
||
|
||
```python
|
||
from abc import ABC, abstractmethod
|
||
from typing import Any
|
||
|
||
class MCPToolProvider(ABC):
|
||
"""MCP Tool Provider 抽象介面"""
|
||
|
||
@property
|
||
@abstractmethod
|
||
def name(self) -> str:
|
||
"""Provider 名稱 (如 'kubernetes', 'signoz')"""
|
||
pass
|
||
|
||
@abstractmethod
|
||
async def list_tools(self) -> list[dict]:
|
||
"""列出可用工具"""
|
||
pass
|
||
|
||
@abstractmethod
|
||
async def execute(self, tool_name: str, parameters: dict) -> Any:
|
||
"""執行工具"""
|
||
pass
|
||
```
|
||
|
||
### DI 注入模式
|
||
|
||
```python
|
||
# registry.py
|
||
class ProviderRegistry:
|
||
_providers: dict[str, MCPToolProvider] = {}
|
||
|
||
@classmethod
|
||
def register(cls, provider: MCPToolProvider) -> None:
|
||
cls._providers[provider.name] = provider
|
||
|
||
@classmethod
|
||
def get(cls, name: str) -> MCPToolProvider | None:
|
||
return cls._providers.get(name)
|
||
|
||
# mcp_bridge.py (重構後)
|
||
async def call_tool(self, server_name: str, tool_name: str, parameters: dict):
|
||
provider = ProviderRegistry.get(server_name)
|
||
if not provider:
|
||
raise ValueError(f"Unknown provider: {server_name}")
|
||
return await provider.execute(tool_name, parameters)
|
||
```
|
||
|
||
---
|
||
|
||
## 優點
|
||
|
||
1. **符合 leWOOOgo 積木化** - Interface 先行,DI 注入
|
||
2. **可測試性** - 可輕鬆 Mock Provider
|
||
3. **可擴展性** - 新增 Provider 無需修改 mcp_bridge.py
|
||
4. **單一職責** - 每個 Provider 只負責一個領域
|
||
|
||
---
|
||
|
||
## 缺點
|
||
|
||
1. **重構工時** - 需要 2-3 天
|
||
2. **檔案數增加** - 從 1 個變 6+ 個
|
||
3. **學習曲線** - 新成員需了解 DI 模式
|
||
|
||
---
|
||
|
||
## 實作計畫
|
||
|
||
| 步驟 | 內容 | 工時 |
|
||
|------|------|------|
|
||
| 1 | 建立 interfaces.py | 30min |
|
||
| 2 | 建立 registry.py | 30min |
|
||
| 3 | 建立 providers/ 目錄 | 15min |
|
||
| 4 | 實作 k8s_provider.py | 1h |
|
||
| 5 | 實作 signoz_provider.py | 1h |
|
||
| 6 | 實作 database_provider.py | 1h |
|
||
| 7 | 重構 mcp_bridge.py | 2h |
|
||
| 8 | 更新測試 | 1h |
|
||
| 9 | Code Review | 1h |
|
||
| **總計** | | **8-9h** |
|
||
|
||
---
|
||
|
||
## 實作驗收 (2026-03-26)
|
||
|
||
| 項目 | 狀態 |
|
||
|------|------|
|
||
| interfaces.py | ✅ 已建立 MCPToolProvider ABC |
|
||
| registry.py | ✅ 已建立 ProviderRegistry |
|
||
| k8s_provider.py | ✅ 已實作 |
|
||
| signoz_provider.py | ✅ 已實作 |
|
||
| database_provider.py | ✅ 已實作 |
|
||
| mcp_bridge.py 重構 | ✅ 透過 DI 注入 |
|
||
| 測試驗證 | ✅ 28/28 通過 |
|
||
|
||
**驗收人**: 首席架構師 (Phase 16 R1.3 審查)
|
||
|
||
---
|
||
|
||
## 相關文件
|
||
|
||
- [feedback_modular_architecture.md](../../memory/feedback_modular_architecture.md)
|
||
- [feedback_modular_core_spirit.md](../../memory/feedback_modular_core_spirit.md)
|
||
- [ADR-003: leWOOOgo 模組化架構](ADR-003-lewooogo-module-architecture.md)
|