122 lines
6.7 KiB
Markdown
122 lines
6.7 KiB
Markdown
# 🚀 Enterprise AI Agent Gateway (企业级 AI 智能体网关) - 核心架构与开发设计书
|
||
|
||
## 1. 架构定位与核心设计理念
|
||
本系统是一个定位于大模型(LLM/AI Agent)与企业老旧业务系统(Legacy Systems)之间的**安全中间件与协议转换枢纽**。
|
||
* **零侵入架构**:老系统无需修改任何代码,通过本网关即可将现有 API 暴露为标准的大模型 Tool Schema。
|
||
* **控制面与数据面分离**:
|
||
* **控制面 (Control Plane)**:前端可视化配置,业务人员通过“表单填报”或“AI 辅助生成”完成 API 注册与清洗规则设定。
|
||
* **数据面 (Data Plane)**:纯粹的 Java 高并发执行引擎,负责鉴权、状态挂起(人工审批)、代理调用与底层 GraalVM 极速数据洗涤。
|
||
|
||
## 2. 技术栈选型
|
||
* **数据面网关核心**:Spring Boot 3.x (WebFlux/纯 WebMVC) + JDK 17/21。
|
||
* **清洗执行引擎**:GraalVM Polyglot (内嵌高安全级别的 JavaScript 运行时沙箱)。
|
||
* **缓存与风控**:Redis (分布式限流、状态机挂起) + Caffeine (本地极速配置缓存)。
|
||
* **控制面后端**:Spring Boot / FastAPI (提供标准的 CRUD 接口)。
|
||
* **前端管理台**:Vue 3 + Element Plus / Ant Design Vue + Monaco Editor。
|
||
* **数据存储**:MySQL 8.0。
|
||
|
||
---
|
||
|
||
## 3. 核心数据库实体模型 (MySQL 8.0 DDL 需求)
|
||
|
||
> **To Antigravity**: 请基于以下实体关系,优先生成 DDL 建表语句以及对应的底层 CRUD 代码(Entity/Mapper/Service)。
|
||
|
||
### 3.1 `ai_tenant` (租户/AI 助手接入表)
|
||
* `id`: 主键
|
||
* `tenant_name`: 租户/机器人名称(例:“财务客服 Agent”)
|
||
* `app_key`: 网关调用的唯一凭证 (唯一索引)
|
||
* `app_secret`: 签名与加解密密钥
|
||
* `rate_limit_qps`: 该租户的全局 QPS 限制阈值
|
||
* `status`: 状态 (启用/禁用)
|
||
|
||
### 3.2 `ai_tool_registry` (API 工具注册表)
|
||
* `id`: 主键
|
||
* `tool_name`: 工具标识(英文下划线,符合 LLM 命名规范)
|
||
* `description`: 喂给大模型的详细描述(决定 LLM 是否调用该工具的核心依据)
|
||
* `action_type`: `READ` (默认放行) / `WRITE` (高危,强制触发人工审批)
|
||
* `target_url`: 底层老系统的真实内网 URL
|
||
* `http_method`: GET / POST
|
||
* `request_schema`: 请求参数的标准 JSON Schema (用于 LLM 识别)
|
||
|
||
### 3.3 `ai_tenant_tool_rel` (权限控制映射表)
|
||
* `tenant_id`: 关联 `ai_tenant.id`
|
||
* `tool_id`: 关联 `ai_tool_registry.id`
|
||
|
||
### 3.4 `ai_wash_script` (GraalVM 数据清洗脚本表)
|
||
* `tool_id`: 唯一关联 `ai_tool_registry.id`
|
||
* `js_script`: 具体的 JavaScript 源码文本(由控制面生成,供数据面 GraalVM 执行)
|
||
* `version`: 版本号,用于并发控制和缓存刷新
|
||
|
||
### 3.5 `ai_audit_log` (全链路安全审计日志表)
|
||
* `trace_id`: 全局请求流水号 (UUID)
|
||
* `tenant_id`: 关联的租户 ID
|
||
* `tool_name`: 命中的工具名称
|
||
* `raw_request`: AI 发起的原始 JSON 参数
|
||
* `raw_response`: 老系统返回的巨型原始 JSON (MediumText)
|
||
* `washed_response`: 经过 GraalVM JS 脚本洗涤后的纯净 JSON
|
||
* `cost_time_ms`: 总耗时 (毫秒)
|
||
|
||
---
|
||
|
||
## 4. 控制面前端 (Vue 3) 交互设计规范
|
||
|
||
前端的核心目标是**隐藏 JavaScript 的编写复杂度**。对于清洗规则 (`ai_wash_script`) 的配置页面,需实现以下三层交互降级方案:
|
||
|
||
1. **AI Copilot 生成(主推)**:页面提供左侧输入“原始 JSON 样例”,上方输入“自然语言提取需求”,点击按钮后,后台调用大模型生成 JS 代码并填充。
|
||
2. **可视化勾选表单(中阶)**:提供“保留字段白名单”、“移除 Null 值”、“拍平数组”等勾选项,前端根据勾选自动拼接为 JS 字符串。
|
||
3. **Monaco Editor 兜底(高阶)**:提供类似 VS Code 的代码编辑框,允许懂代码的开发人员直接修正在线生成的 JavaScript 规则。
|
||
|
||
---
|
||
|
||
## 5. 数据面网关 Pipeline (责任链/Filter Chain 设计)
|
||
|
||
> **To Antigravity**: 在生成网关核心转发逻辑时,请严格按照以下 Filter 顺序构建职责链模式。
|
||
|
||
1. **Config Watcher (配置加载)**:定时从 MySQL 拉取 `ai_tool_registry`、权限与 `js_script`,加载至 Caffeine 内存。
|
||
2. **Auth & Rate Limiting (鉴权限流)**:校验 `app_key`,拦截非法调用;利用 Redis 执行令牌桶限流。
|
||
3. **Identity OBO (权限穿透)**:若包含终端用户 Token,将该身份附加至 Downstream Header 中。
|
||
4. **HITL Suspender (审批挂起)**:若 `action_type == 'WRITE'`,拦截当前线程,向外部(如企微/钉钉)发送包含审批链接的 Webhook,当前请求挂起等待回调。
|
||
5. **Proxy Execution (代理转发)**:组装参数,向 `target_url` 发起真实的 HTTP 内部请求。
|
||
6. **GraalVM Washing (洗涤瘦身)**:拿到原始大 JSON,在限制了内存与执行时间(如 max 100ms)的 GraalVM 沙箱中执行对应的 `js_script`,返回瘦身结果。
|
||
7. **Async Audit (异步审计)**:无论成功失败,将完整上下文抛入线程池,落库至 `ai_audit_log`。
|
||
|
||
---
|
||
|
||
## 6. 核心资产:AI 辅助生成清洗脚本的 System Prompt
|
||
|
||
> 针对控制面的“AI 自动生成 JS 规则”功能,后端需要内置以下 System Prompt。
|
||
|
||
```text
|
||
# Role
|
||
你是一个资深的 JavaScript 数据处理专家与大模型工程架构师。
|
||
|
||
# Objective
|
||
你的任务是根据用户提供的【原始庞大 JSON 样例】和【自然语言提取要求】,编写一段精简、安全、高效的 JavaScript 代码,用于在 GraalVM 环境下对 JSON 进行瘦身清洗。这段清洗后的数据将被直接喂给大模型(LLM)作为上下文。
|
||
|
||
# Constraints & Rules
|
||
1. 你的输出必须且只能包含一个名为 `wash` 的 JavaScript 函数。
|
||
2. 该函数的入参必须是 `rawJsonString` (字符串类型)。
|
||
3. 该函数的返回值必须是清洗并序列化后的 JSON 字符串,以确保后续直接使用。
|
||
4. 代码必须健壮,需处理常见的空指针(undefined/null)和数组越界异常。
|
||
5. 必须剔除所有无业务价值的字段(如 HTML 标签、内部 traceId、全 null 字段等),最大限度节省 LLM 的 Token。
|
||
6. 不要使用任何外部依赖或 npm 包,只能使用 ES6+ 标准原生语法。
|
||
|
||
# Output Format Example
|
||
```javascript
|
||
function wash(rawJsonString) {
|
||
try {
|
||
const data = JSON.parse(rawJsonString);
|
||
if (!data || !data.list) return "[]";
|
||
|
||
const result = data.list.map(item => ({
|
||
eventName: item.event_name || '未知',
|
||
date: item.timestamp ? new Date(item.timestamp).toISOString().split('T')[0] : '',
|
||
coreProfit: item.financial_data?.net_profit ?? 0
|
||
}));
|
||
|
||
return JSON.stringify(result);
|
||
} catch (e) {
|
||
return JSON.stringify({ error: "数据清洗失败" });
|
||
}
|
||
}
|
||
``` |