docs: update external connectors design for SSE-only transport, connector-scoped confirmation, and scheduled task auto-confirm

This commit is contained in:
alan.cl
2026-04-09 15:05:33 +08:00
parent b4b0a53d1b
commit 0f133f20eb

View File

@@ -0,0 +1,779 @@
# DB-GPT External Connectors Design Document
> **Date**: 2026-04-03
> **Status**: Draft
> **Author**: DB-GPT Team
> **Target Level**: L3 (Fully Automated Scheduled Analysis + Push)
---
## 1. Executive Summary
DB-GPT 的 ReAct Agent 已经能够执行数据分析、SQL 取数、代码执行和报告生成等任务。但当前分析结果只能在平台内查看或通过分享链接共享,无法自动推送到外部服务。
本方案提出 **"Skills + MCP 双轮驱动"** 架构,使 DB-GPT Agent 能够:
- 从外部服务拉取数据作为分析输入语雀文档、飞书表格、GitHub Issues 等)
- 将分析结果自动推送到外部服务(钉钉群通知、语雀文档、飞书消息、邮件等)
- 支持 L3 级别的全自动定时分析 + 推送(如"每天早上 8 点执行销售分析,发布到语雀,通知钉钉群"
---
## 2. Architecture: Skills + MCP 双轮驱动
### 2.1 Core Philosophy
```
Skills = 大脑(认知层) → 知道"该做什么"、"什么顺序"、"怎么分析"
MCP Connectors = 手脚(执行层) → 知道"怎么连接外部世界"、"怎么读写外部服务"
```
- **Skills** 提供领域知识和工作流编排能力分析模式、SQL 模板、报告格式等),通过 `required_tools` 声明连接器依赖
- **MCP Connectors** 提供标准化的外部服务访问能力(读写语雀、发送钉钉消息、操作飞书文档等),遵循 MCP 协议
两者协同Skill 定义"分析完后把报告推送到语雀"的意图和流程MCP Connector 提供 `yuque_create_doc` 这个具体工具来执行推送。
### 2.2 Architecture Diagram
```
┌─────────────────────────────────────────────────────────────────┐
│ DB-GPT Platform │
│ │
│ ┌───────────────────────────────────────────────────────────┐ │
│ │ ReAct Agent │ │
│ │ │ │
│ │ Thought → Phase → Action → Action Input → Observation │ │
│ │ │ │ │
│ │ ┌────┴────┐ │ │
│ │ │ToolPack │ │ │
│ │ └────┬────┘ │ │
│ └────────────────────────┼──────────────────────────────────┘ │
│ │ │
│ ┌────────────────┼────────────────┐ │
│ │ │ │ │
│ ┌─────┴──────┐ ┌─────┴──────┐ ┌──────┴───────┐ │
│ │ Built-in │ │ Skill │ │ Connector │ │
│ │ Tools │ │ Tools │ │ Tools │ │
│ │ │ │ │ │ (from MCP) │ │
│ │ sql_query │ │ load_skill │ │ │ │
│ │ code_interp│ │ exec_skill │ │ yuque_* │ │
│ │ html_interp│ │ │ │ dingtalk_* │ │
│ │ shell_inter│ │ │ │ feishu_* │ │
│ │ knowledge │ │ │ │ wecom_* │ │
│ │ Terminate │ │ │ │ github_* │ │
│ └────────────┘ └─────┬──────┘ │ email_* │ │
│ │ └──────┬───────┘ │
│ ┌─────┴──────┐ │ │
│ │ SKILL.md │ ┌─────┴──────┐ │
│ │ │ │ Connector │ │
│ │ required_ │ │ Manager │ │
│ │ tools: │ │ │ │
│ │ - yuque_* │ │ - Catalog │ │
│ │ - dingtk_*│ │ - Creds │ │
│ │ │ │ - Lifecycle│ │
│ │ workflow: │ │ - Confirm │ │
│ │ 1.Analyze │ └─────┬──────┘ │
│ │ 2.Format │ │ │
│ │ 3.Push │ MCP Protocol │
│ └────────────┘ (SSE) │
│ │ │
└──────────────────────────────────────────┼────────────────────┘
┌──────────┬──────────┬──────┴───┬──────────┐
│ │ │ │ │
┌────┴───┐ ┌───┴────┐ ┌───┴───┐ ┌───┴───┐ ┌───┴───┐
│ 飞书 │ │ 钉钉 │ │ 语雀 │ │ 企微 │ │GitHub │
│ MCP │ │ MCP │ │ MCP │ │ MCP │ │ MCP │
│Server │ │Server │ │Server │ │Server │ │Server │
│(官方) │ │(官方) │ │(社区) │ │(社区) │ │(社区) │
└───┬────┘ └───┬────┘ └───┬───┘ └───┬───┘ └───┬───┘
│ │ │ │ │
┌───┴──┐ ┌───┴──┐ ┌───┴──┐ ┌───┴──┐ ┌──┴───┐
│飞书 │ │钉钉 │ │语雀 │ │企微 │ │GitHub│
│Open │ │Open │ │Open │ │Open │ │ API │
│API │ │API │ │API │ │API │ │ │
└──────┘ └──────┘ └──────┘ └──────┘ └──────┘
```
### 2.3 Why Not Native Python? (全 MCP 统一方案)
**早期方案(已废弃)** 曾考虑中国服务使用原生 Python 实现、海外服务使用 MCP。经调研发现
| 服务 | MCP Server | 来源 | 状态 |
|------|-----------|------|------|
| 飞书 Feishu | `larksuite/lark-openapi-mcp` | **官方** | 稳定 |
| 钉钉 DingTalk | `open.dingtalk.com` MCP Server | **官方** | 稳定 |
| 语雀 Yuque | `yuque-mcp` (PyPI) | 社区 | 可用 |
| 企微 WeChat Work | `wecom-bot-mcp-server` (PyPI) | 社区 | 可用 |
| GitHub | `@modelcontextprotocol/server-github` | 官方 | 稳定 |
| Slack | `@modelcontextprotocol/server-slack` | 官方 | 稳定 |
| Google Sheets | `@anthropic/google-sheets-mcp` | 社区 | 可用 |
| Notion | `@notionhq/notion-mcp-server` | 官方 | 稳定 |
| Email | SMTP MCP servers | 社区 | 可用 |
**结论**:所有目标服务均已有 MCP Server 实现2026 年 mcp.so 已收录 19,400+ serversDB-GPT 无需自行编写任何外部服务 API 调用代码。
**全 MCP 统一方案的优势**
1. **零维护成本**API 更新由 MCP Server 社区/官方维护
2. **标准化**:统一的 MCP 协议DB-GPT 只需一套连接管理代码
3. **扩展性**:新服务 = 新 MCP Server 配置条目,无需写代码
4. **生态复用**:直接复用 19,400+ 社区 MCP Servers
### 2.4 Comparison with Industry
| 维度 | Manus | Codex | DB-GPT (本方案) |
|------|-------|-------|----------------|
| 连接器协议 | MCP + 原生 | MCP (OpenAI 生态) | MCP 统一 |
| 认知层 | 内置 Workflow | Prompt | Skills (SKILL.md) |
| 交互模式 | 面板式 + 自动 | 配置文件 | 面板式 + 自动 + 手动触发 |
| 安全确认 | 部分有 | 无 | **连接器写操作确认 + 定时任务事后通知** |
| 定时任务 | 无 | 无 | **L3 Scheduler核心差异** |
| 数据分析集成 | 弱 | 无 | **原生 SQL/代码分析 + 外推** |
| 差异化 | 通用 AI Agent | 代码助手 | **数据分析 + 外部协作** |
---
## 3. Core Components
### 3.1 ConnectorManager
ConnectorManager 是连接器的核心管理层负责凭据管理、MCP Server 生命周期和工具注入。
```python
# packages/dbgpt-core/src/dbgpt/agent/resource/connector/manager.py
class ConnectorManager:
"""管理所有外部连接器的生命周期和凭据。"""
def __init__(self, system_app):
self._catalog = ConnectorCatalog() # 连接器目录JSON 配置)
self._credential_store = CredentialStore(system_app) # 凭据加密存储
self._active_connections: Dict[str, MCPToolPack] = {} # 活跃 MCP 连接
async def get_user_tools(self, user_id: str) -> List[Tool]:
"""获取用户已连接服务的所有工具,注入到 Agent 的 ToolPack。"""
connectors = await self._credential_store.get_active(user_id)
tools = []
for conn in connectors:
mcp_pack = await self._get_or_create_mcp_pack(conn)
tools.extend(mcp_pack.get_tools())
return tools
async def _get_or_create_mcp_pack(self, conn) -> MCPToolPack:
"""获取或创建 MCP Server 连接SSE 模式)。"""
key = f"{conn.user_id}:{conn.connector_type}"
if key not in self._active_connections:
catalog_entry = self._catalog.get(conn.connector_type)
credentials = self._credential_store.decrypt(conn)
headers = self._map_credentials_to_headers(credentials, catalog_entry)
mcp_pack = MCPToolPack(
mcp_servers=catalog_entry.server_uri, # SSE endpoint URL
headers=headers # Auth token headers
)
await mcp_pack.preload_resource()
self._active_connections[key] = mcp_pack
return self._active_connections[key]
```
### 3.2 Connector Catalog (JSON Configuration)
新增连接器 = 新增一个 JSON 配置条目,零代码:
```json
// packages/dbgpt-ext/src/dbgpt_ext/connector/catalog.json
{
"connectors": [
{
"type": "feishu",
"display_name": "飞书",
"description": "飞书消息、文档、日历集成",
"icon": "feishu",
"category": "communication",
"mcp_server": {
"server_uri": "http://localhost:3001/sse",
"transport": "sse"
},
"auth": {
"type": "token",
"fields": [
{"name": "app_id", "label": "App ID", "type": "text", "required": true},
{"name": "app_secret", "label": "App Secret", "type": "password", "required": true}
],
"header_mapping": {
"app_id": "X-Lark-App-Id",
"app_secret": "X-Lark-App-Secret"
}
},
"confirm_actions": ["feishu_send_message", "feishu_create_doc", "feishu_update_doc"],
"read_actions": ["feishu_get_doc", "feishu_list_docs", "feishu_search"]
},
{
"type": "dingtalk",
"display_name": "钉钉",
"description": "钉钉群消息推送和机器人通知",
"icon": "dingtalk",
"category": "communication",
"mcp_server": {
"server_uri": "http://localhost:3002/sse",
"transport": "sse"
},
"auth": {
"type": "token",
"fields": [
{"name": "webhook_url", "label": "群机器人 Webhook URL", "type": "text", "required": true},
{"name": "secret", "label": "加签密钥", "type": "password", "required": false}
],
"header_mapping": {
"webhook_url": "X-DingTalk-Webhook",
"secret": "X-DingTalk-Secret"
}
},
"confirm_actions": ["dingtalk_send_message", "dingtalk_send_card"],
"read_actions": []
},
{
"type": "yuque",
"display_name": "语雀",
"description": "语雀知识库文档读写",
"icon": "yuque",
"category": "document",
"mcp_server": {
"server_uri": "http://localhost:3003/sse",
"transport": "sse"
},
"auth": {
"type": "token",
"fields": [
{"name": "token", "label": "Personal Access Token", "type": "password", "required": true},
{"name": "default_namespace", "label": "默认知识库", "type": "text", "required": false}
],
"header_mapping": {
"token": "X-Auth-Token"
}
},
"confirm_actions": ["yuque_create_doc", "yuque_update_doc", "yuque_delete_doc"],
"read_actions": ["yuque_get_doc", "yuque_list_docs", "yuque_search"]
},
{
"type": "github",
"display_name": "GitHub",
"description": "GitHub Issues、PR、仓库管理",
"icon": "github",
"category": "project",
"mcp_server": {
"server_uri": "http://localhost:3004/sse",
"transport": "sse"
},
"auth": {
"type": "token",
"fields": [
{"name": "github_token", "label": "Personal Access Token", "type": "password", "required": true}
],
"header_mapping": {
"github_token": "Authorization"
}
},
"confirm_actions": ["github_create_issue", "github_create_pr", "github_comment"],
"read_actions": ["github_get_issue", "github_list_issues", "github_get_repo"]
}
]
}
```
### 3.3 Credential Store (凭据加密存储)
复用 DB-GPT 现有的 `FernetEncryption`
```python
# packages/dbgpt-serve/src/dbgpt_serve/connector/models/models.py
class ConnectorCredentialEntity(Model):
"""连接器凭据实体。"""
__tablename__ = "connector_credentials"
id = Column(Integer, primary_key=True, autoincrement=True)
user_id = Column(String(128), nullable=False, index=True)
connector_type = Column(String(64), nullable=False) # "yuque", "dingtalk"
connector_name = Column(String(256), nullable=True) # 用户自定义名称
encrypted_credentials = Column(Text, nullable=False) # Fernet 加密的 JSON
encryption_salt = Column(String(64), nullable=False) # 独立盐值
status = Column(String(32), default="active") # active/expired/revoked
token_expires_at = Column(DateTime, nullable=True) # OAuth token 过期时间
extra_config = Column(Text, nullable=True) # JSON 额外配置
created_at = Column(DateTime, default=func.now())
updated_at = Column(DateTime, default=func.now(), onupdate=func.now())
```
### 3.4 Human-in-the-Loop Confirmation (Connector Tools Only)
> **原则**:原有 ReAct Agent 的 Skills、内置工具执行流程不受影响。仅对新增的 MCP 连接器写操作加入确认机制。
确认逻辑在 **ConnectorManager 注入的工具包装层** 实现,不在 Agent 核心管道中:
```python
# packages/dbgpt-core/src/dbgpt/agent/resource/connector/confirmation.py
class ConfirmationInterceptor:
"""拦截需要确认的连接器写操作。
仅应用于 ConnectorManager 注入的 MCP 工具,
不影响内置工具sql_query、code_interpreter 等)和 Skill 工具。
"""
def __init__(self, catalog: ConnectorCatalog):
self._catalog = catalog
async def should_confirm(self, tool_name: str, tool_args: dict,
context: dict = None) -> bool:
"""判断是否需要用户确认。
- 手动触发(用户在线交互):写操作需确认
- 定时任务触发:默认免确认(自动授权)
"""
if context and context.get("trigger_type") == "scheduled":
return False # 定时任务免确认
for connector in self._catalog.list():
if tool_name in connector.confirm_actions: # 命名空间前缀匹配
return True
return False
def format_confirmation(self, tool_name: str, tool_args: dict) -> dict:
"""格式化确认消息,通过 SSE step.confirm 事件发送到前端。
NOTE: step.confirm 是新增的 SSE 事件类型,需在前端新增处理逻辑。
"""
return {
"type": "step.confirm", # 新增事件类型
"tool": tool_name,
"args_summary": self._summarize_args(tool_args),
"message": f"即将执行 {tool_name},是否确认?"
}
```
**确认策略**
- **手动触发(用户在线交互)**:连接器写操作需弹出确认 → 用户确认后继续
- **定时任务触发**:默认自动授权免确认 → 执行后推送通知(见 Section 9.3
- **原有 Agent 工具**:不受影响,无确认拦截
前端在收到 `step.confirm` 事件(**新增 SSE 事件类型**)时弹出确认对话框,用户确认后 POST `/api/v1/connector/confirm/{confirm_id}` 继续执行。
---
## 4. Agent Integration
### 4.1 Tool Injection Point
**关键改动文件**: `packages/dbgpt-app/src/dbgpt_app/openapi/api_v1/agentic_data_api.py`
`_react_agent_stream()` 函数中ToolPack 构建阶段注入连接器工具:
```python
# 现有代码(约 line 2827:
tool_pack = ToolPack(
[load_skill, load_tools, knowledge_retrieve, execute_skill_script,
get_skill_resource, execute_skill_script_file, code_interpreter,
shell_interpreter, html_interpreter, sql_query, Terminate()]
+ business_tools
)
# 新增:注入连接器工具
connector_manager = ConnectorManager.get_instance(CFG.SYSTEM_APP)
connector_tools = await connector_manager.get_user_tools(user_id)
tool_pack = ToolPack(
[load_skill, load_tools, knowledge_retrieve, execute_skill_script,
get_skill_resource, execute_skill_script_file, code_interpreter,
shell_interpreter, html_interpreter, sql_query, Terminate()]
+ business_tools
+ connector_tools # ← 新增
)
```
### 4.2 System Prompt Enhancement
在 Agent 的 system prompt 中动态注入已连接服务信息:
```python
# 动态生成连接器描述
connector_prompt = ""
if connector_tools:
connector_prompt = """
## Connected External Services
The user has connected the following external services. You can use these tools
to read from or write to external services when the task requires it.
Available connector tools:
{tool_descriptions}
IMPORTANT: All write operations (send message, create document, etc.) will
require user confirmation before execution. Read operations are allowed
without confirmation.
""".format(tool_descriptions="\n".join(
f"- {t.name}: {t.description}" for t in connector_tools
))
```
### 4.3 Skill Integration via required_tools
Skills 通过 `required_tools` 声明连接器依赖,使 Agent 知道该 Skill 需要哪些外部服务:
```yaml
# skills/sales-report-push/SKILL.md
---
name: sales-report-push
description: |
Execute sales analysis and push report to external services.
Requires: sql_query, yuque_create_doc, dingtalk_send_message
required_tools:
- sql_query
- yuque_create_doc
- dingtalk_send_message
---
# Sales Report Push Workflow
## Steps
1. Execute SQL query to extract sales data
2. Generate analysis report with charts (html_interpreter)
3. Format report as Markdown for Yuque
4. Push report to Yuque knowledge base (yuque_create_doc)
5. Send summary notification to DingTalk group (dingtalk_send_message)
```
当 Agent 加载此 Skill 时,会自动检查 `required_tools` 中的连接器是否已配置。如果用户未连接语雀或钉钉Agent 提示用户先配置连接。
---
## 5. API Design
### 5.1 Connector Management APIs
```
# 连接器类型(目录)
GET /api/v2/serve/connectors/types # 列出所有可用连接器类型
# 用户连接管理
POST /api/v2/serve/connectors # 创建连接(提交凭据)
GET /api/v2/serve/connectors # 列出用户的所有连接
DELETE /api/v2/serve/connectors/{id} # 删除连接
PUT /api/v2/serve/connectors/{id} # 更新连接配置
GET /api/v2/serve/connectors/{id}/test # 测试连接是否可用
# OAuth 流程(后续扩展)
GET /api/v2/serve/connectors/oauth/authorize # 发起 OAuth 授权
GET /api/v2/serve/connectors/oauth/callback # OAuth 回调
```
### 5.2 Schema Examples
```python
# POST /api/v2/serve/connectors
class ConnectorCreateRequest(BaseModel):
connector_type: str # "yuque"
connector_name: Optional[str] # "我的语雀"
credentials: Dict[str, str] # {"token": "xxx"}
extra_config: Optional[Dict] # {"default_namespace": "team/knowledge"}
# GET /api/v2/serve/connectors
class ConnectorListResponse(BaseModel):
id: int
connector_type: str
connector_name: str
display_name: str # "语雀"
icon: str
status: str # "active" / "expired"
created_at: datetime
# GET /api/v2/serve/connectors/types
class ConnectorTypeResponse(BaseModel):
type: str
display_name: str
description: str
icon: str
category: str
auth_fields: List[dict] # 前端动态渲染表单
```
---
## 6. Frontend Design
### 6.1 Connector Management Page
**路径**: `web/pages/construct/connectors/index.tsx`
参考现有数据库管理页面(`web/pages/construct/database/`)的模式:
```
┌─────────────────────────────────────────────────────────────┐
│ 外部连接 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 我的连接 │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 语雀 │ │ 钉钉 │ │ + 添加 │ │
│ │ 已连接 ● │ │ 已连接 ● │ │ 新连接 │ │
│ │ [测试][断开]│ │ [测试][断开]│ │ │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ 可用连接器 │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ 语雀 │ │ 钉钉 │ │ 飞书 │ │ 企微 │ │
│ │ 文档协作 │ │ 即时通讯 │ │ 即时通讯 │ │ 即时通讯 │ │
│ │ [连接] │ │ [连接] │ │ [连接] │ │ [连接] │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ GitHub │ │ 邮箱 │ │ Sheets │ │ Notion │ │
│ │ 代码管理 │ │ 电子邮件 │ │ 在线表格 │ │ 文档协作 │ │
│ │ [连接] │ │ [连接] │ │ [连接] │ │ [连接] │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
└─────────────────────────────────────────────────────────────┘
```
- 连接器类型通过 `/connectors/types` API 动态加载
- 认证表单根据 `auth_fields` 动态渲染
- 点击「测试」调用 `/connectors/{id}/test` 验证连接
### 6.2 Chat Page Integration
`web/pages/index.tsx` 的聊天页面中:
1. **输入区域**:显示已连接服务的图标(类似 Manus 的连接器面板)
2. **Step 卡片**Agent 使用连接器工具时,显示连接器图标和操作描述
3. **确认对话框**`step.confirm` 事件触发确认 UI
4. **手动触发**:分析完成后,结果区域提供「推送到语雀」「发到钉钉」按钮
---
## 7. Serve Module Structure
```
packages/dbgpt-serve/src/dbgpt_serve/connector/
├── __init__.py
├── serve.py # ConnectorServe(BaseServe)
├── config.py # ServeConfig
├── models/
│ ├── __init__.py
│ └── models.py # ConnectorCredentialEntity + Dao
├── api/
│ ├── __init__.py
│ ├── endpoints.py # REST API 路由
│ └── schemas.py # Pydantic 请求/响应模型
└── service/
├── __init__.py
└── service.py # ConnectorService (CRUD + 加密)
```
**Serve 注册步骤**(参考现有 prompt/datasource 模块):
1. **scan_serve_configs()** — 在 `packages/dbgpt-app/src/dbgpt_app/initialization/serve_initialization.py` 的 modules 列表中添加:
```python
modules = [
...
"dbgpt_serve.connector.serve", # 新增
]
```
2. **register_serve_apps()** — 在同一文件的注册函数中添加条件注册块:
```python
from dbgpt_serve.connector.serve import Serve as ConnectorServe
ConnectorServe.register(system_app)
```
3. **config.py 标准常量** — `packages/dbgpt-serve/src/dbgpt_serve/connector/config.py`
```python
APP_NAME = "connector"
SERVE_APP_NAME = "dbgpt_serve_connector"
SERVE_CONFIG_KEY_PREFIX = "dbgpt.serve.connector"
```
---
## 8. Security
### 8.1 Credential Security
- 使用 `FernetEncryption`(已存在于 `dbgpt.core.interface.variables`)加密存储凭据
- 每行凭据独立 salt
- 凭据仅在 MCP Server 启动时解密传入环境变量,不在日志或响应中暴露
### 8.2 Operation Safety
- **手动触发写操作**:连接器写操作(发消息、创建文档、发邮件)需用户确认(仅限连接器工具,不影响原有 Agent 工具)
- **定时任务写操作**:默认自动授权免确认,执行后推送通知(含执行结果 + 回退入口)
- **读操作放行**:读取文档、搜索等操作可直接执行
- **权限隔离**:每个用户只能访问自己配置的连接器
- **Token 刷新**OAuth token 过期自动刷新,刷新失败标记连接为 `expired`
### 8.3 MCP Server Connection Management
- 每个用户连接对应独立的 SSE 长连接MCP Server 独立部署DB-GPT 不管理 Server 进程)
- 连接在会话结束后关闭,下次使用时重新建立
- 连接池管理避免并发连接过多
- SSE 连接超时和重试策略:默认 30s 超时,最多重试 3 次
---
## 9. Data Flow
### 9.1 Output Flow (推送分析结果)
```
User: "分析上月销售数据,报告发到语雀,通知钉钉群"
ReAct Agent
│ Thought: 需要执行 SQL 分析,然后推送结果
│ Phase: Analysis
│── Action: sql_query
│ └─ Result: 销售数据表
│── Action: html_interpreter
│ └─ Result: 可视化报告
│ Phase: Push Results
│── Action: yuque_create_doc ← MCP Tool
│ └─ [step.confirm] 用户确认 ✓
│ └─ Result: 文档已创建 (URL)
│── Action: dingtalk_send_message ← MCP Tool
│ └─ [step.confirm] 用户确认 ✓
│ └─ Result: 消息已发送
└── Action: Terminate
└─ Final: "分析报告已发布到语雀并通知钉钉群"
```
### 9.2 Input Flow (拉取外部数据)
```
User: "读取语雀知识库里的《Q1季度目标》对比实际销售数据分析完成度"
ReAct Agent
│ Phase: Data Collection
│── Action: yuque_read_doc ← MCP Tool (读操作,无需确认)
│ └─ Result: Q1 目标文档内容
│── Action: sql_query
│ └─ Result: Q1 实际销售数据
│ Phase: Analysis
│── Action: code_interpreter
│ └─ Result: 目标完成度分析
└── Action: Terminate
└─ Final: "Q1 目标完成率 87%..."
```
### 9.3 Scheduled Task Flow (定时任务流程)
```
Scheduler Trigger (cron: "0 8 * * *")
ReAct Agent (context: trigger_type=scheduled, auto_confirm=true)
│── Action: sql_query ← 内置工具,无需确认
│ └─ Result: 今日销售数据
│── Action: html_interpreter ← 内置工具,无需确认
│ └─ Result: 可视化报告
│── Action: yuque_create_doc ← MCP Tool定时触发自动授权免确认
│ └─ Result: 文档已创建 (URL)
│── Action: dingtalk_send_message ← MCP Tool定时触发自动授权免确认
│ └─ Result: 消息已发送
└── Post-Execution Notification
├─ 推送通知给用户(钉钉/站内信):
│ "定时任务 [每日销售分析] 已执行完成
│ ✅ 语雀文档已创建: {url}
│ ✅ 钉钉群已通知
│ ⏪ [回退操作]"
└─ 回退 = 补偿性 MCP 工具调用:
- yuque_create_doc 的回退 → yuque_delete_doc(doc_id)
- dingtalk_send_message 的回退 → dingtalk_recall_message(msg_id)
(仅在服务 API 支持时可用;不可回退时标注"不可回退")
```
---
## 10. Files Inventory
### New Files
| Path | Purpose |
|------|---------|
| `packages/dbgpt-core/src/dbgpt/agent/resource/connector/__init__.py` | Connector module |
| `packages/dbgpt-core/src/dbgpt/agent/resource/connector/manager.py` | ConnectorManager |
| `packages/dbgpt-core/src/dbgpt/agent/resource/connector/catalog.py` | ConnectorCatalog (JSON config loader) |
| `packages/dbgpt-core/src/dbgpt/agent/resource/connector/confirmation.py` | ConfirmationInterceptor |
| `packages/dbgpt-ext/src/dbgpt_ext/connector/catalog.json` | Connector catalog data |
| `packages/dbgpt-serve/src/dbgpt_serve/connector/` | Entire Serve module |
| `web/pages/construct/connectors/index.tsx` | Connector management page |
| `web/components/connector/` | Connector UI components |
### Modified Files
| Path | Change |
|------|--------|
| `packages/dbgpt-app/.../agentic_data_api.py` | Inject connector tools in `_react_agent_stream()` |
| `packages/dbgpt-app/.../component_configs.py` | Register ConnectorManager component |
| `packages/dbgpt-core/.../agent/resource/base.py` | Add `Connector` to ResourceType enum |
| `web/pages/index.tsx` | Add connector status indicators in chat page |
| `packages/dbgpt-app/.../serve_initialization.py` | Register ConnectorServe in `scan_serve_configs()` and `register_serve_apps()` |
---
## 11. Implementation Roadmap
### Phase 1: Connector Infrastructure (3 weeks)
- ConnectorManager + ConnectorCatalog
- CredentialStore (FernetEncryption)
- Serve module (API + DB model)
- Human-in-the-loop confirmation mechanism
- First 3 connectors: 飞书 (official MCP), 钉钉 (official MCP), 语雀 (community MCP)
- Frontend connector management page (basic)
### Phase 2: Skill Enhancement (2 weeks)
- Skill `required_tools` resolution with connector tools
- System prompt dynamic connector description injection
- Auto-check connector availability when loading Skills
- Enhanced step UI for connector operations
### Phase 3: L3 Scheduler (3 weeks)
- Scheduled task system for periodic analysis + push
- **定时任务默认自动授权**`trigger_type=scheduled` 时 ConfirmationInterceptor 免确认
- **执行后通知**:推送执行结果通知给用户(含成功/失败状态 + 回退入口)
- **回退机制**:回退 = 补偿性 MCP 工具调用(如 `yuque_delete_doc`),仅在服务 API 支持时可用
- Cron-based scheduling UI
- Execution history and monitoring
- Failure retry and alerting
### Phase 4: Ecosystem Expansion (ongoing)
- Additional connectors: 企微, GitHub, Email, Notion, Slack, Google Sheets
- OAuth 2.0 flow for services that require it
- Connector marketplace (community contributions)
- Advanced features: webhook triggers, event-driven workflows
---
## 12. Validation Plan
### End-to-End Test Scenarios
1. **Output**: User says "分析数据并发布到语雀" → Agent executes analysis → calls `yuque_create_doc` → user confirms → document appears in Yuque
2. **Input**: User says "读取飞书文档分析" → Agent calls `feishu_get_doc` → processes content → returns analysis
3. **Bidirectional**: User says "读取语雀目标文档,对比 SQL 数据,分析报告发到钉钉" → full input + analysis + output flow
4. **Connection management**: User adds Yuque token in frontend → starts chat → Agent auto-discovers and uses Yuque tools
5. **Security**: Database stores encrypted credentials; write operations require confirmation; read operations execute directly
6. **Scheduled task**: Cron triggers analysis → auto-confirm (no confirmation UI) → yuque_create_doc + dingtalk_send_message → user receives notification with execution summary + rollback link → user clicks rollback → compensating MCP call executed
7. **Rollback**: After scheduled push, user clicks rollback → system calls `yuque_delete_doc(doc_id)` → verifies doc deleted → marks rollback complete
### Unit Tests
- ConnectorManager lifecycle tests
- CredentialStore encrypt/decrypt tests
- ConnectorCatalog loading and validation tests
- ConfirmationInterceptor logic tests
- API endpoint CRUD tests