1027 lines
39 KiB
Markdown
1027 lines
39 KiB
Markdown
# 企业级 AI 客户端平台 — 架构方案文档
|
||
|
||
> 文档编号:2026-06-19-002
|
||
> 创建日期:2026-06-19
|
||
> 状态:方案评审中(含独立批判性分析)
|
||
|
||
---
|
||
|
||
## 目录
|
||
|
||
1. [背景与动机](#1-背景与动机)
|
||
2. [产品定位](#2-产品定位)
|
||
3. [架构总览](#3-架构总览)
|
||
4. [客户端设计](#4-客户端设计)
|
||
5. [服务端设计](#5-服务端设计)
|
||
6. [权限模型](#6-权限模型)
|
||
7. [终端安全](#7-终端安全)
|
||
8. [LLM 调用链路](#8-llm-调用链路)
|
||
9. [数据同步](#9-数据同步)
|
||
10. [认证体系](#10-认证体系)
|
||
11. [数据库设计](#11-数据库设计)
|
||
12. [安全模型](#12-安全模型)
|
||
13. [实施路线图](#13-实施路线图)
|
||
14. [独立批判性分析](#14-独立批判性分析)
|
||
15. [方案优化与补全](#15-方案优化与补全)
|
||
16. [待决策问题](#16-待决策问题)
|
||
|
||
---
|
||
|
||
## 1. 背景与动机
|
||
|
||
### 1.1 当前架构
|
||
|
||
Fischer AgentKit 当前是纯本地运行架构:
|
||
|
||
- **CLI/Tauri 桌面端**:启动本地 Python sidecar(`127.0.0.1:{随机端口}`),前端通过 Tauri IPC 获取端口后连接本地 sidecar
|
||
- **LLM 配置**:API Key 存储在本地 `agentkit.yaml` + `.env` 中
|
||
- **认证**:仅全局 API Key + `clients.yaml` 多客户端 key,无用户系统
|
||
- **数据**:会话存储在本地 SQLite,情景记忆在 PostgreSQL(可选)
|
||
- **终端**:PTY 在本地 sidecar 中执行
|
||
|
||
### 1.2 改造动机
|
||
|
||
- **企业统一管理 LLM Key 和成本**:当前 Key 散落在各客户端,无法统一管控
|
||
- **团队知识共享**:企业代码规范、最佳实践需要集中管理、团队共享
|
||
- **权限与审计**:企业需要控制谁能使用终端等高危功能,需要审计操作记录
|
||
- **多用户支持**:当前无用户概念,无法区分不同用户的会话和操作
|
||
|
||
### 1.3 对标产品
|
||
|
||
| 产品 | 客户端 | 服务端 | 差异 |
|
||
|------|--------|--------|------|
|
||
| Trae | 桌面 IDE + AI Agent | 云端模型 | 个人工具 |
|
||
| Cursor | VS Code Fork + AI | 云端模型 + Team | 团队工具 |
|
||
| Codex CLI | 终端 CLI | 云端模型 | 命令行助手 |
|
||
| **AgentKit 目标** | **桌面客户端 + AI Agent** | **企业平台(权限/KB/审计)** | **企业级 AI 开发平台** |
|
||
|
||
**核心差异化**:代码不离开客户端 + Agent 本地执行 + 企业级治理
|
||
|
||
---
|
||
|
||
## 2. 产品定位
|
||
|
||
### 2.1 定位声明
|
||
|
||
> 企业级 AI 开发客户端平台:客户端是开发者的 AI 工作台(类似 Trae),服务端是企业共享资源与治理中心。
|
||
|
||
### 2.2 双买家模型
|
||
|
||
| 维度 | 开发者视角 | 企业 IT 视角 |
|
||
|------|----------|------------|
|
||
| 核心价值 | AI 辅助编程、本地执行 | 统一 Key 管理、成本管控、审计合规 |
|
||
| 部署模式 | 本地优先 | 集中部署 |
|
||
| 成功指标 | 任务完成率、响应延迟 | 合规率、成本可控 |
|
||
|
||
### 2.3 差异化竞争力
|
||
|
||
1. **代码不离开客户端**(真差异化):Cursor/Trae 的 codebase indexing 在云端,AgentKit 的代码上下文完全本地
|
||
2. **专家团/董事会模式**(已有优势):当前代码库已有的多 Agent 协作模式,Cursor/Trae 完全没有
|
||
3. **企业级治理**(目标差异化):统一 LLM Key、成本管控、权限审计
|
||
|
||
---
|
||
|
||
## 3. 架构总览
|
||
|
||
### 3.1 双进程模型
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ 企业服务端(云端/内网) │
|
||
│ │
|
||
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
||
│ │ LLM 网关 │ │ 用户权限 │ │ 审计日志 │ │ 知识库 │ │
|
||
│ │ (统一Key) │ │ 中心 │ │ 中心 │ │ 中心 │ │
|
||
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
|
||
│ │
|
||
│ PostgreSQL + pgvector │ Redis │ MinIO(可选) │
|
||
└───────────────────────┬─────────────────────────────────────┘
|
||
│ HTTPS API + WSS
|
||
│ (认证: JWT + API Key)
|
||
│
|
||
┌─────────────┼─────────────┐
|
||
│ │ │
|
||
▼ ▼ ▼
|
||
┌──────────────┐ ┌──────────┐ ┌──────────────┐
|
||
│ Tauri 桌面 │ │ Tauri │ │ Web 管理台 │
|
||
│ 客户端 │ │ 客户端 │ │ (浏览器) │
|
||
│ │ │ │ │ │
|
||
│ ┌──────────┐ │ └──────────┘ │ 用户管理 │
|
||
│ │本地Sidecar│ │ │ 审计查看 │
|
||
│ │(Python) │ │ │ 配置管理 │
|
||
│ │├Agent引擎│ │ └──────────────┘
|
||
│ │├终端 │ │
|
||
│ │├文件操作 │ │
|
||
│ │├会话存储 │ │
|
||
│ │└LLM代理 │ │
|
||
│ └──────────┘ │
|
||
│ ┌──────────┐ │
|
||
│ │前端(Vue3)│ │
|
||
│ └──────────┘ │
|
||
└──────────────┘
|
||
```
|
||
|
||
### 3.2 核心设计原则
|
||
|
||
| 原则 | 说明 | 价值定位 |
|
||
|------|------|---------|
|
||
| LLM Key 不下发客户端 | 客户端通过服务端 LLM 网关间接调用 | **成本管控 + 审计**(非安全边界) |
|
||
| 代码不离开客户端 | Agent 在客户端本地执行,文件操作在本地 | **安全 + 隐私**(真差异化) |
|
||
| 终端在客户端本地执行 | 服务端不提供终端功能 | **安全**(服务端无 RCE 风险) |
|
||
| 离线降级 | 服务端不可用时客户端部分可用 | **可用性** |
|
||
|
||
### 3.3 关键架构决策
|
||
|
||
| 决策点 | 选择 | 理由 |
|
||
|--------|------|------|
|
||
| 终端位置 | 本地 Python sidecar(非 Tauri Rust) | 避免用 Rust 重写 PTY + 命令分类逻辑 |
|
||
| LLM 调用模式 | 服务端代理(非客户端直连) | 统一 Key 管理 + 用量审计 + 成本管控 |
|
||
| 配置同步 | 轮询 + ETag(非 WebSocket 推送) | 配置变更频率低(周/月级),轮询足够 |
|
||
| 会话历史 | 本地 SQLite(不上传服务端) | 隐私保护 + 减少网络传输 |
|
||
| 服务端部署 | 支持内网私有化部署 | 跨地域公网延迟不可接受 |
|
||
|
||
---
|
||
|
||
## 4. 客户端设计
|
||
|
||
### 4.1 客户端分层
|
||
|
||
```
|
||
Tauri 桌面客户端
|
||
├── UI 层(Vue 3 + Ant Design Vue)
|
||
│ ├── 对话界面(Chat)
|
||
│ ├── 工作台界面(Workspace)
|
||
│ ├── 终端界面(Terminal)
|
||
│ ├── 知识库浏览(KB Browser)
|
||
│ ├── 工作流管理(Workflow)
|
||
│ └── 设置中心(Settings)
|
||
│
|
||
├── 本地服务层(Python Sidecar - FastAPI)
|
||
│ ├── /local/agent — 本地 Agent 执行引擎
|
||
│ ├── /local/terminal — 本地终端(PTY)
|
||
│ ├── /local/files — 本地文件操作
|
||
│ ├── /local/session — 本地会话存储(SQLite)
|
||
│ ├── /local/cache — 本地 LLM 语义缓存
|
||
│ └── /local/llm-proxy — LLM 代理(转发到服务端网关)
|
||
│
|
||
├── 远程通信层
|
||
│ ├── /api/auth/* — 认证(登录/JWT)
|
||
│ ├── /api/llm/chat — LLM 代理(通过服务端网关)
|
||
│ ├── /api/kb/* — 知识库查询
|
||
│ ├── /api/config/* — 配置同步
|
||
│ └── /api/audit/* — 审计日志上报
|
||
│
|
||
└── 本地存储
|
||
├── SQLite(会话、缓存、配置快照)
|
||
├── 文件系统(代码、项目)
|
||
└── 内存(Agent 运行时状态)
|
||
```
|
||
|
||
### 4.2 客户端保留的模块
|
||
|
||
| 当前模块 | 客户端角色 | 改造 |
|
||
|---------|----------|------|
|
||
| `core/` Agent 引擎 | 本地执行 | LLM 改为 RemoteLLMProvider |
|
||
| `tools/` 工具 | 本地执行 | 不变 |
|
||
| `chat/` 会话 | 本地 SQLite | 增加 owner_id |
|
||
| `routes/terminal.py` | 本地终端 | 增加权限检查 + 审计上报 |
|
||
| `llm/gateway.py` | 改为代理模式 | 新增 RemoteLLMProvider |
|
||
| `skills/` | 本地 + 远程同步 | 增加从服务端同步 |
|
||
| `experts/` | 本地 + 远程配置 | 增加从服务端同步 |
|
||
|
||
### 4.3 客户端启动流程
|
||
|
||
```
|
||
1. Tauri 启动 → 启动本地 Python Sidecar(127.0.0.1:{随机端口})
|
||
2. 前端加载 → 检查本地是否有登录凭证(JWT)
|
||
├─ 有且有效 → 直接进入主界面
|
||
├─ 有但过期 → 尝试 refresh → 成功则进入,失败则跳转登录
|
||
└─ 无 → 跳转登录页
|
||
3. 登录成功后:
|
||
a. 从服务端拉取用户信息 + 权限
|
||
b. 从服务端同步配置(技能/Agent/工作流,带 ETag 增量)
|
||
c. 初始化本地 Agent 引擎(使用 RemoteLLMProvider)
|
||
4. 进入主界面,用户开始工作
|
||
```
|
||
|
||
### 4.4 离线降级策略
|
||
|
||
| 功能 | 服务端可用 | 服务端不可用 |
|
||
|------|----------|------------|
|
||
| 对话 | 通过服务端 LLM 网关 | 用户自填 Key 直连 LLM(降级模式) |
|
||
| 终端 | 本地执行 + 审计上报 | 本地执行 + 审计暂存本地 |
|
||
| 文件操作 | 本地执行 | 本地执行 |
|
||
| 知识库 | 实时查询服务端 | 使用本地缓存的 KB 元数据 + 已缓存文档 |
|
||
| 工作流模板 | 实时拉取 | 使用本地缓存版本 |
|
||
| 配置同步 | 轮询更新 | 使用本地缓存 |
|
||
|
||
---
|
||
|
||
## 5. 服务端设计
|
||
|
||
### 5.1 服务端模块(按必要性排序)
|
||
|
||
| 优先级 | 模块 | 职责 | V1 是否必须 |
|
||
|--------|------|------|------------|
|
||
| P0 | LLM 网关 | 统一 Key、用量统计、成本管控、语义缓存、限流 | ✅ 必须 |
|
||
| P0 | 用户认证 | JWT 签发/验证、用户 CRUD | ✅ 必须 |
|
||
| P1 | 审计日志 | LLM 调用审计 + 危险命令审计 | ✅ 应该 |
|
||
| P1 | 知识库 | pgvector 语义搜索、团队隔离 | ✅ 应该 |
|
||
| P2 | 配置同步 API | 技能/Agent/工作流配置分发 | 可延后 |
|
||
| P3 | Web 管理台 | 用户管理、审计查看、配置管理 | 可延后 |
|
||
| P3 | 技能市场 | 技能发布与分发 | 可延后 |
|
||
| P3 | 工作流模板中心 | 工作流 CRUD、版本控制 | 可延后 |
|
||
| P4 | 生产系统集成 | CI/CD Webhook | 暴露 Webhook 即可 |
|
||
|
||
### 5.2 服务端 API
|
||
|
||
```
|
||
认证 API:
|
||
POST /api/v1/auth/login — 登录
|
||
POST /api/v1/auth/refresh — 刷新 token
|
||
POST /api/v1/auth/logout — 登出
|
||
GET /api/v1/auth/me — 当前用户信息
|
||
|
||
LLM 网关 API:
|
||
POST /api/v1/llm/chat — LLM 对话(非流式)
|
||
POST /api/v1/llm/chat/stream — LLM 流式对话(SSE)
|
||
|
||
知识库 API:
|
||
GET /api/v1/kb/search — 知识库搜索
|
||
GET /api/v1/kb/documents/{id} — 获取文档
|
||
|
||
配置同步 API:
|
||
GET /api/v1/config/version — 配置版本号
|
||
GET /api/v1/config/skills — 技能配置
|
||
GET /api/v1/config/agents — Agent 配置
|
||
GET /api/v1/config/workflows — 工作流模板
|
||
|
||
审计 API:
|
||
POST /api/v1/audit/terminal — 终端审计上报
|
||
GET /api/v1/usage/me — 我的用量
|
||
|
||
管理 API(需 admin 权限):
|
||
GET /api/v1/admin/users — 用户管理
|
||
POST /api/v1/admin/users — 创建用户
|
||
GET /api/v1/admin/audit/terminal — 终端审计日志
|
||
GET /api/v1/admin/usage — 全局用量统计
|
||
```
|
||
|
||
---
|
||
|
||
## 6. 权限模型
|
||
|
||
### 6.1 三级角色 + 权限位
|
||
|
||
```
|
||
角色:
|
||
member — 普通用户(对话 + 只读 KB + 工作流执行)
|
||
operator — 高级用户(+ 终端 + KB 写入)
|
||
admin — 管理员(+ 用户管理 + 系统配置)
|
||
```
|
||
|
||
### 6.2 权限位定义
|
||
|
||
```python
|
||
class Permission(str, Enum):
|
||
CHAT = "chat" # 对话
|
||
KB_QUERY = "kb.query" # 知识库查询
|
||
KB_WRITE = "kb.write" # 知识库写入
|
||
WORKFLOW_EXECUTE = "workflow.execute" # 工作流执行
|
||
TERMINAL_LOCAL_USE = "terminal.local.use" # 本地终端使用
|
||
TERMINAL_SERVER_USE = "terminal.server.use" # 服务端终端使用
|
||
TERMINAL_WHITELIST_MANAGE = "terminal.whitelist.manage" # 白名单管理
|
||
USER_MANAGE = "user.manage" # 用户管理
|
||
SYSTEM_CONFIG = "system.config" # 系统配置
|
||
|
||
ROLE_PERMISSIONS: dict[str, set[Permission]] = {
|
||
"member": {Permission.CHAT, Permission.KB_QUERY, Permission.WORKFLOW_EXECUTE},
|
||
"operator": {
|
||
Permission.CHAT, Permission.KB_QUERY, Permission.KB_WRITE,
|
||
Permission.WORKFLOW_EXECUTE, Permission.TERMINAL_LOCAL_USE,
|
||
},
|
||
"admin": set(Permission), # 含 TERMINAL_SERVER_USE + TERMINAL_WHITELIST_MANAGE
|
||
}
|
||
```
|
||
|
||
### 6.3 终端授权
|
||
|
||
终端分为**本地终端**和**服务端终端**两种模式,授权要求不同:
|
||
|
||
| 终端模式 | 执行位置 | 所需权限 | 额外要求 | 审计策略 |
|
||
|---------|---------|---------|---------|---------|
|
||
| 本地终端 | 客户端本地 sidecar | `TERMINAL_LOCAL_USE` | `is_terminal_authorized=True` | 仅危险命令上报 |
|
||
| 服务端终端 | 服务端 PTY | `TERMINAL_SERVER_USE` | `is_server_terminal_authorized=True` | **全量命令记录** |
|
||
|
||
**授权流程**:
|
||
1. `operator` 角色默认有本地终端权限,admin 可单独授予 `is_terminal_authorized`
|
||
2. 服务端终端权限仅 `admin` 角色默认拥有,或 admin 单独授予 `is_server_terminal_authorized`
|
||
3. 两种终端权限独立控制,互不影响
|
||
|
||
---
|
||
|
||
## 7. 终端安全
|
||
|
||
### 7.1 三层防护
|
||
|
||
```
|
||
第一层:角色门禁
|
||
→ 用户必须有 TERMINAL_USE 权限 + is_terminal_authorized=True
|
||
→ member 角色看不到终端入口
|
||
|
||
第二层:命令分类
|
||
→ 安全命令(ls, cat, pwd...):有权限即可执行
|
||
→ 危险命令(rm, sudo, chmod...):每次必须人工确认
|
||
→ 未知命令:默认视为危险
|
||
|
||
第三层:人工确认(每次)
|
||
→ 危险命令每次执行都弹出确认对话框
|
||
→ 不提供"加入白名单"选项(危险命令不持久化白名单)
|
||
→ 必须勾选"我已了解风险"才能确认
|
||
```
|
||
|
||
### 7.2 终端审计
|
||
|
||
| 审计内容 | 上报策略 |
|
||
|---------|---------|
|
||
| 危险命令 + 确认结果 | 实时上报服务端 |
|
||
| 普通命令流水 | **不上报**(隐私保护,全量监控是 MDM/EDR 的职责) |
|
||
| 命令输出内容 | **不上报**(可能含敏感信息) |
|
||
| 审计元数据 | 命令文本、风险等级、是否确认、exit_code、时间戳 |
|
||
|
||
### 7.3 BYOD 模式
|
||
|
||
- 支持纯本地模式(不接入企业服务端),此时无审计上报
|
||
- 企业配发设备接入服务端时,审计上报自动启用
|
||
|
||
---
|
||
|
||
## 8. LLM 调用链路
|
||
|
||
### 8.1 调用流程
|
||
|
||
```
|
||
客户端 Agent → 本地 LLM Proxy → 服务端 LLM 网关 → LLM Provider API
|
||
↑
|
||
JWT 认证
|
||
用量统计
|
||
成本管控
|
||
语义缓存(共享)
|
||
限流/熔断
|
||
```
|
||
|
||
### 8.2 RemoteLLMProvider
|
||
|
||
```python
|
||
class RemoteLLMProvider(LLMProvider):
|
||
"""通过服务端 LLM 网关调用 LLM,不在本地存储 API Key"""
|
||
|
||
def __init__(self, server_url: str, auth_token_provider: Callable[[], str]):
|
||
self._server_url = server_url
|
||
self._auth_token_provider = auth_token_provider
|
||
|
||
async def chat(self, request: LLMRequest) -> LLMResponse:
|
||
response = await httpx.post(
|
||
f"{self._server_url}/api/v1/llm/chat",
|
||
json=request.model_dump(),
|
||
headers={"Authorization": f"Bearer {self._auth_token_provider()}"},
|
||
)
|
||
return LLMResponse(**response.json())
|
||
|
||
async def chat_stream(self, request: LLMRequest):
|
||
async with httpx.AsyncClient() as client:
|
||
async with client.stream(
|
||
"POST",
|
||
f"{self._server_url}/api/v1/llm/chat/stream",
|
||
json=request.model_dump(),
|
||
headers={"Authorization": f"Bearer {self._auth_token_provider()}"},
|
||
) as response:
|
||
async for line in response.aiter_lines():
|
||
if line.startswith("data: "):
|
||
yield StreamChunk(**json.loads(line[6:]))
|
||
```
|
||
|
||
### 8.3 流式 fallback 语义
|
||
|
||
**已知风险**:当前 `gateway.py` 的"首 chunk 前失败则 fallback"在单进程内简单,跨网络后客户端可能已收到部分 chunk,fallback 会导致内容跳变。
|
||
|
||
**处理方案**:
|
||
- 服务端网关在首 chunk 前完成 fallback(当前逻辑不变)
|
||
- 首 chunk 后不再 fallback,直接返回错误
|
||
- 客户端收到错误后自行决定是否重试
|
||
|
||
### 8.4 延迟分析
|
||
|
||
| 部署拓扑 | RTT | 50 次 LLM 调用额外延迟 | 可接受性 |
|
||
|---------|-----|---------------------|---------|
|
||
| 同内网 | 5ms | +0.5s | ✅ 完全可接受 |
|
||
| 跨城内网 | 30ms | +3s | ✅ 可接受 |
|
||
| 跨地域公网 | 150ms | +15s | ⚠️ 开始难受 |
|
||
| 跨国公网 | 300ms | +30s | ❌ 不可接受 |
|
||
|
||
**结论**:服务端必须支持**内网私有化部署**。跨地域公网部署需要客户端支持直连降级。
|
||
|
||
### 8.5 内网 LLM 支持
|
||
|
||
服务端 LLM 网关支持接入内网 LLM 服务:
|
||
- vLLM(OpenAI 兼容 API)
|
||
- Ollama(OpenAI 兼容 API)
|
||
- 当前 `ProviderConfig` 已是 OpenAI 兼容格式,只需配置 `base_url` 指向内网地址
|
||
|
||
---
|
||
|
||
## 9. 数据同步
|
||
|
||
### 9.1 同步策略(简化版)
|
||
|
||
| 数据类型 | 方向 | 策略 |
|
||
|---------|------|------|
|
||
| 用户信息/权限 | 服务端 → 客户端 | 登录时拉取 + JWT 续期时刷新 |
|
||
| 技能/Agent/工作流配置 | 服务端 → 客户端 | 启动时全量拉取 + 每 5 分钟轮询版本号 |
|
||
| 知识库 | 服务端 → 客户端 | 实时查询 + 元数据本地缓存 + LRU 文档缓存 |
|
||
| 会话历史 | 纯本地 | 不上传服务端 |
|
||
| 终端审计 | 客户端 → 服务端 | 危险命令实时上报 + 离线暂存 |
|
||
| LLM 用量 | 服务端记录 | 通过 LLM 网关自动记录 |
|
||
|
||
### 9.2 配置同步实现(轮询版)
|
||
|
||
```python
|
||
# 客户端配置同步引擎
|
||
class ConfigSync:
|
||
async def sync(self):
|
||
# 1. 检查版本号
|
||
remote_version = await api.get("/api/v1/config/version")
|
||
if remote_version == local_version:
|
||
return # 无变更
|
||
|
||
# 2. 全量拉取(配置数据量小,无需增量)
|
||
skills = await api.get("/api/v1/config/skills")
|
||
agents = await api.get("/api/v1/config/agents")
|
||
workflows = await api.get("/api/v1/config/workflows")
|
||
|
||
# 3. 更新本地缓存
|
||
await update_local_cache(skills, agents, workflows)
|
||
local_version = remote_version
|
||
|
||
async def start_polling(self):
|
||
while True:
|
||
await asyncio.sleep(300) # 5 分钟
|
||
try:
|
||
await self.sync()
|
||
except Exception:
|
||
pass # 离线时静默失败
|
||
```
|
||
|
||
### 9.3 知识库缓存策略
|
||
|
||
| 层级 | 缓存内容 | 大小 | 策略 |
|
||
|------|---------|------|------|
|
||
| L1 | KB 文档列表 + 标题 + 摘要 | ~100KB | 启动时全量拉取 |
|
||
| L2 | 最近使用的 N 篇文档全文 | ~10MB | LRU 缓存,按需拉取 |
|
||
| L3 | 实时查询 | - | L1/L2 miss 时请求服务端 |
|
||
|
||
---
|
||
|
||
## 10. 认证体系
|
||
|
||
### 10.1 双轨认证
|
||
|
||
```
|
||
请求进入
|
||
│
|
||
├─ 有 Authorization: Bearer <jwt> ?
|
||
│ └─ 是 → 验证 JWT → 提取 user_id → request.state.current_user = User
|
||
│
|
||
├─ 有 X-API-Key: <key> ?
|
||
│ └─ 是 → 查 user_api_keys 表 → 识别 user_id → request.state.current_user = User
|
||
│ (兼容旧 clients.yaml → 识别为 system client)
|
||
│
|
||
└─ 无凭证
|
||
├─ dev mode → 放行
|
||
└─ 生产 → 401
|
||
```
|
||
|
||
### 10.2 JWT 流程
|
||
|
||
```
|
||
登录:POST /api/v1/auth/login {username, password}
|
||
→ 验证密码 (bcrypt)
|
||
→ 生成 access_token (15min) + refresh_token (7d)
|
||
→ 返回 {access_token, refresh_token, user}
|
||
|
||
刷新:POST /api/v1/auth/refresh {refresh_token}
|
||
→ 生成新 access_token
|
||
|
||
登出:POST /api/v1/auth/logout
|
||
→ 撤销 refresh_token
|
||
```
|
||
|
||
### 10.3 SSO/OIDC(V2 规划)
|
||
|
||
V1 支持本地账号认证。V2 预留 OIDC 接口,支持:
|
||
- Azure AD / Microsoft Entra ID
|
||
- Google Workspace
|
||
- 企业自建 OIDC Provider
|
||
|
||
---
|
||
|
||
## 11. 数据库设计
|
||
|
||
### 11.1 服务端 PostgreSQL
|
||
|
||
```sql
|
||
-- 用户表
|
||
CREATE TABLE users (
|
||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||
username VARCHAR(64) UNIQUE NOT NULL,
|
||
email VARCHAR(255) UNIQUE NOT NULL,
|
||
password_hash VARCHAR(255) NOT NULL,
|
||
role VARCHAR(32) NOT NULL DEFAULT 'member',
|
||
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
||
is_terminal_authorized BOOLEAN NOT NULL DEFAULT FALSE,
|
||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||
last_login_at TIMESTAMPTZ,
|
||
created_by UUID REFERENCES users(id),
|
||
tenant_id UUID, -- 多租户预留
|
||
metadata JSONB DEFAULT '{}'
|
||
);
|
||
|
||
-- 用户 API Key 表
|
||
CREATE TABLE user_api_keys (
|
||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||
key_hash VARCHAR(255) UNIQUE NOT NULL,
|
||
key_prefix VARCHAR(16) NOT NULL,
|
||
name VARCHAR(64),
|
||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||
last_used_at TIMESTAMPTZ,
|
||
expires_at TIMESTAMPTZ,
|
||
is_revoked BOOLEAN NOT NULL DEFAULT FALSE
|
||
);
|
||
|
||
-- 终端审计日志
|
||
CREATE TABLE terminal_audit_logs (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
user_id UUID NOT NULL REFERENCES users(id),
|
||
session_id VARCHAR(64) NOT NULL,
|
||
command TEXT NOT NULL,
|
||
command_hash VARCHAR(64) NOT NULL,
|
||
risk_level VARCHAR(16) NOT NULL,
|
||
was_confirmed BOOLEAN NOT NULL DEFAULT FALSE,
|
||
was_approved BOOLEAN NOT NULL DEFAULT FALSE,
|
||
executed_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||
exit_code INTEGER,
|
||
client_ip INET,
|
||
metadata JSONB DEFAULT '{}'
|
||
);
|
||
|
||
-- LLM 用量记录
|
||
CREATE TABLE llm_usage_records (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
user_id UUID NOT NULL REFERENCES users(id),
|
||
provider VARCHAR(64) NOT NULL,
|
||
model VARCHAR(128) NOT NULL,
|
||
input_tokens INTEGER NOT NULL,
|
||
output_tokens INTEGER NOT NULL,
|
||
cost_cents INTEGER NOT NULL DEFAULT 0,
|
||
latency_ms INTEGER,
|
||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||
metadata JSONB DEFAULT '{}'
|
||
);
|
||
|
||
-- 用户会话(JWT refresh token)
|
||
CREATE TABLE user_sessions (
|
||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||
refresh_token_hash VARCHAR(255) UNIQUE NOT NULL,
|
||
device_info JSONB DEFAULT '{}',
|
||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||
expires_at TIMESTAMPTZ NOT NULL,
|
||
revoked_at TIMESTAMPTZ
|
||
);
|
||
```
|
||
|
||
### 11.2 客户端 SQLite(现有 + 改造)
|
||
|
||
```sql
|
||
-- conversations 表增加 owner_id
|
||
ALTER TABLE conversations ADD COLUMN owner_id TEXT;
|
||
CREATE INDEX idx_conversations_owner ON conversations(owner_id);
|
||
```
|
||
|
||
### 11.3 多租户预留
|
||
|
||
所有服务端表预留 `tenant_id` 字段,V1 默认为 NULL(单租户),V2 启用多租户隔离。
|
||
|
||
---
|
||
|
||
## 12. 安全模型
|
||
|
||
### 12.1 分层安全
|
||
|
||
```
|
||
Layer 1: 网络安全
|
||
├─ 客户端 ↔ 服务端:HTTPS + WSS
|
||
├─ 服务端 ↔ LLM:HTTPS
|
||
└─ 服务端内部:VPC 隔离
|
||
|
||
Layer 2: 认证安全
|
||
├─ 用户登录:用户名+密码(bcrypt, rounds=12)→ JWT
|
||
├─ 客户端认证:JWT(access 15min + refresh 7d)
|
||
├─ 系统集成:API Key(SHA256 hash 存储)
|
||
└─ 登录限流:5次/分钟
|
||
|
||
Layer 3: 权限安全
|
||
├─ RBAC 三级角色 + 权限位
|
||
├─ 路由级权限检查
|
||
├─ 数据级隔离(owner_id / tenant_id)
|
||
└─ 终端双重授权
|
||
|
||
Layer 4: 操作安全
|
||
├─ 终端命令三层防护
|
||
├─ 危险命令不持久化白名单
|
||
├─ 审计日志(只追加,不可篡改)
|
||
└─ 敏感操作二次确认
|
||
|
||
Layer 5: 数据安全
|
||
├─ LLM API Key 不下发客户端
|
||
├─ 代码文件不离开客户端
|
||
├─ 会话历史不上传服务端
|
||
└─ 审计日志脱敏
|
||
```
|
||
|
||
### 12.2 LLM 成本配额
|
||
|
||
```python
|
||
# 按 user/tenant 设月度 token 配额
|
||
class UsageQuota:
|
||
monthly_token_limit: int # 月度 token 上限
|
||
monthly_cost_limit_cents: int # 月度费用上限(分)
|
||
current_tokens: int # 当月已用
|
||
current_cost_cents: int # 当月已花费
|
||
|
||
# 服务端 LLM 网关检查
|
||
async def check_quota(user: User) -> bool:
|
||
quota = await get_user_quota(user.id)
|
||
if quota.current_tokens >= quota.monthly_token_limit:
|
||
raise HTTPException(429, "Monthly token quota exceeded")
|
||
if quota.current_cost_cents >= quota.monthly_cost_limit_cents:
|
||
raise HTTPException(429, "Monthly cost quota exceeded")
|
||
return True
|
||
```
|
||
|
||
---
|
||
|
||
## 13. 实施路线图
|
||
|
||
### 13.1 修订后的路线图(含 Phase 0)
|
||
|
||
| 阶段 | 内容 | 周期 | 交付物 |
|
||
|------|------|------|--------|
|
||
| **Phase 0** | 包拆分 + 双进程骨架 | 3 周 | `agentkit_core` / `agentkit_client` / `agentkit_server` 三包分离,双进程能跑 |
|
||
| **Phase 1** | LLM 网关 + 基础认证 | 3 周 | RemoteLLMProvider + 服务端 LLM 网关 + JWT 登录 |
|
||
| **Phase 2** | 权限 + 审计 + 配置同步 | 3 周 | 3 级 RBAC + 审计日志 + 配置轮询同步 |
|
||
| **Phase 3** | KB 共享 + 离线降级 | 3 周 | 团队 KB + KB 缓存 + 离线降级 |
|
||
| **Phase 4+** | Web 管理台 / SSO / 代码索引 | 延后 | 按需推进 |
|
||
|
||
### 13.2 Phase 0:包拆分(前置必做)
|
||
|
||
当前 `server/` 包是单体,没有客户端/服务端边界。Phase 0 需要拆分为:
|
||
|
||
```
|
||
agentkit/
|
||
├── core/ — Agent 引擎(客户端服务端共用)
|
||
│ ├── base.py
|
||
│ ├── react.py
|
||
│ ├── rewoo.py
|
||
│ └── ...
|
||
├── llm/ — LLM 抽象层(共用)
|
||
│ ├── protocol.py
|
||
│ ├── gateway.py
|
||
│ ├── config.py
|
||
│ └── remote_provider.py — 新增
|
||
├── tools/ — 工具(共用)
|
||
├── client/ — 客户端特有
|
||
│ ├── sidecar.py — 本地 sidecar 入口
|
||
│ ├── terminal.py — 终端(从 server/routes/ 迁移)
|
||
│ ├── files.py — 文件操作
|
||
│ ├── session.py — 本地会话存储
|
||
│ ├── sync.py — 配置同步引擎
|
||
│ └── audit.py — 审计上报
|
||
├── server/ — 服务端特有
|
||
│ ├── app.py — 服务端 FastAPI app
|
||
│ ├── auth/ — 认证授权
|
||
│ ├── llm_gateway/— LLM 网关
|
||
│ ├── kb/ — 知识库
|
||
│ ├── audit/ — 审计
|
||
│ └── admin/ — 管理 API
|
||
└── shared/ — 共享模型/配置
|
||
├── models.py
|
||
└── config.py
|
||
```
|
||
|
||
### 13.3 Phase 1 验证目标
|
||
|
||
Phase 1 结束时验证核心价值:
|
||
- 企业统一管 LLM Key
|
||
- 审计 LLM 用量
|
||
- 客户端通过服务端代理调用 LLM
|
||
|
||
**如果 Phase 1 后企业不买单,停止后续投入。**
|
||
|
||
### 13.4 替代方案:最小验证(4 周)
|
||
|
||
如果不确定企业是否买单,可先做最小方案:
|
||
|
||
- 服务端只做 LLM Key 代理 + 用量统计
|
||
- 用户认证用 API Key(沿用现有 `clients.yaml`)
|
||
- 无 RBAC、无 KB 共享
|
||
- 4 周可交付,用最小代价验证企业需求
|
||
|
||
---
|
||
|
||
## 14. 独立批判性分析
|
||
|
||
> 以下为独立架构师以全新视角对方案的批判性分析,未经修改。
|
||
|
||
### 14.1 需求目标分析
|
||
|
||
#### 14.1.1 产品定位不清晰
|
||
|
||
方案把两个**买家不同、成功指标不同、部署模式不同**的产品缝在一起:
|
||
|
||
| 维度 | 开发者生产力工具 | 企业治理平台 |
|
||
|------|----------------|------------|
|
||
| 买家 | 开发者个人 | IT/安全/采购 |
|
||
| 核心指标 | 任务完成率、延迟 | 合规率、成本可控 |
|
||
| 部署 | 本地优先 | 集中部署 |
|
||
|
||
方案同时声称要"类似 Trae/Cursor"又要"企业级平台",但**没有回答:先卖给谁?谁拍板?谁付钱?**
|
||
|
||
#### 14.1.2 差异化竞争力
|
||
|
||
真正的差异化只有一条半:
|
||
- **"代码不离开客户端"**:真差异化(Cursor/Trae 的 codebase indexing 在云端)
|
||
- **"Agent 本地执行"**:半个差异化(Cursor 的 Agent 也是本地跑的)
|
||
|
||
方案漏掉了真正能拉开差距的能力:当前代码库已有的**专家团/董事会模式**,这是 Cursor/Trae 完全没有的。
|
||
|
||
#### 14.1.3 遗漏的核心场景
|
||
|
||
1. **代码库语义索引**:Cursor 的核心竞争力,方案完全没提
|
||
2. **IDE 集成**:开发者活在 VS Code/JetBrains 里,纯桌面端推广阻力大
|
||
3. **离线/内网 LLM**:很多企业不能用云端 LLM
|
||
4. **多设备会话**:方案内部矛盾(会话纯本地 vs 多设备)
|
||
5. **模型评估/回归**:企业上线 Agent 前要评估
|
||
|
||
### 14.2 必要性分析
|
||
|
||
#### 14.2.1 服务端模块必要性
|
||
|
||
| 模块 | 必要性 | 理由 |
|
||
|------|--------|------|
|
||
| LLM 网关 | 必须 | "企业级"唯一不可替代的价值 |
|
||
| 用户认证 | 必须 | 但 V1 只需 3 级 |
|
||
| 审计日志 | 应该 | 范围要收窄(只审计 LLM 调用 + 危险命令) |
|
||
| 知识库 | 应该 | 可用现有 KB + pgvector 先跑 |
|
||
| 工作流模板 | 可延后 | YAML + Git 够用 |
|
||
| 技能市场 | 可延后 | 分发不是瓶颈 |
|
||
| 生产系统集成 | 不要做 | 暴露 Webhook 够用 |
|
||
| Web 管理台 | 可延后 | V1 用 CLI 管理 |
|
||
|
||
**结论**:V1 服务端只需要 3 个模块——LLM 网关 + 用户认证 + 审计日志。
|
||
|
||
#### 14.2.2 LLM 代理模式利弊
|
||
|
||
代理模式的真实成本(被低估):
|
||
- ReAct/专家团循环是**多轮串行 LLM 调用**,一个复杂任务可能 20-50 次
|
||
- 跨地域公网(RTT 150ms+)会明显劣化体验
|
||
|
||
代理模式的真实收益(被高估):
|
||
- "Key 不下发"保护的是**企业的 LLM 预算和用量审计**,不是真正的安全边界
|
||
- Tauri 桌面端跑在用户机器上,用户能 dump 内存、抓包
|
||
|
||
**建议**:代理模式保留,但明确其价值是成本管控 + 审计,不是安全。服务端必须支持内网部署。
|
||
|
||
#### 14.2.3 四级 RBAC 过度设计
|
||
|
||
- `viewer`:谁会用 AI 编程工具只看不操作?想象出来的角色
|
||
- `user vs power`:终端和 KB 管理是两个不相关的权限,不该绑成一个等级
|
||
|
||
企业真实需求是**权限点**,不是角色等级。建议 3 级 + 权限位。
|
||
|
||
#### 14.2.4 终端审计隐私
|
||
|
||
| 场景 | 审计合理性 |
|
||
|------|-----------|
|
||
| 企业配发电脑 | 合理 |
|
||
| BYOD | 不合理 |
|
||
| 危险命令确认记录 | 合理 |
|
||
| 全量命令流水 | 过度(是监控不是审计) |
|
||
|
||
建议:只上报危险命令 + 确认结果,不上报普通命令流水。
|
||
|
||
### 14.3 架构设计合理性
|
||
|
||
#### 14.3.1 配置同步 WebSocket 过度设计
|
||
|
||
配置变更频率是**周/月级**,用 WebSocket 推送是杀鸡用牛刀。更简单的方案:启动时全量拉取 + 每 5 分钟轮询版本号 + 手动刷新。
|
||
|
||
#### 14.3.2 会话历史纯本地 vs 企业审计矛盾
|
||
|
||
如果企业要审计"员工用 AI 做了什么",会话历史是最核心的审计对象。纯本地意味着审计员看不到。
|
||
|
||
**建议**:拆成三层:
|
||
1. 完整对话内容:本地(默认)
|
||
2. 操作摘要:上报服务端(脱敏后)
|
||
3. LLM 调用元数据:服务端网关天然就有
|
||
|
||
#### 14.3.3 知识库不缓存导致离线断裂
|
||
|
||
KB 完全不缓存意味着离线时 Agent 无法引用任何团队知识,与"离线降级"原则矛盾。
|
||
|
||
**建议**:元数据缓存 + LRU 文档缓存 + 离线时只用已缓存文档。
|
||
|
||
#### 14.3.4 当前代码库适配性
|
||
|
||
FastAPI + Vue3 + Tauri 技术栈没问题,但当前 `server/` 包是单体,没有客户端/服务端边界。需要一次彻底的包结构重组(Phase 0)。
|
||
|
||
### 14.4 改造方案可行性
|
||
|
||
#### 14.4.1 最大技术风险:终端的位置
|
||
|
||
当前 `terminal.py` 的 PTY 跑在 Python sidecar 里。改造后:
|
||
- 路线 A(移到 Tauri Rust):风险太高,用 Rust 重写 PTY + 命令分类
|
||
- 路线 B(保留本地 Python sidecar):**唯一现实路线**,终端逻辑不动
|
||
|
||
#### 14.4.2 RemoteLLMProvider 改造
|
||
|
||
`LLMProvider` 是干净的 ABC,RemoteLLMProvider 本身 2-3 天。难点在服务端流式透传 + 取消传播 + fallback 语义,1-2 周。
|
||
|
||
#### 14.4.3 路线图评估
|
||
|
||
"每阶段 2-3 周,共 8-12 周"——**不现实**,因为:
|
||
1. Phase 0(包拆分)没算进去
|
||
2. 用户系统从零开始
|
||
3. 终端位置决策未明确
|
||
4. 双进程调试环境搭建
|
||
|
||
**现实评估**:12 周(4 阶段 × 3 周),假设 1-2 个全职开发。
|
||
|
||
#### 14.4.4 "看似简单实则困难"的改造点
|
||
|
||
1. 流式 fallback 语义跨网络后的重新定义
|
||
2. `_verify_api_key` 的全局替换(十几个路由文件)
|
||
3. `clients.yaml` 兼容(两套认证并存)
|
||
4. Tauri sidecar 的远程地址注入
|
||
5. 专家团/董事会的 LLM 调用放大延迟
|
||
|
||
### 14.5 改进建议汇总
|
||
|
||
#### 架构简化
|
||
1. 砍掉 WebSocket 配置同步,用轮询 + ETag
|
||
2. 砍掉 viewer 角色,RBAC 改 3 级 + 权限位
|
||
3. 砍掉"生产系统集成"模块,暴露 Webhook
|
||
4. 砍掉"技能市场"和"工作流模板中心",YAML + Git 够用
|
||
5. 明确双进程模型
|
||
|
||
#### 遗漏的考虑
|
||
| 遗漏项 | 重要性 | 建议 |
|
||
|--------|--------|------|
|
||
| 多租户隔离 | 高 | 所有表预留 tenant_id |
|
||
| SSO/OIDC | 高 | V2 支持,V1 预留接口 |
|
||
| 数据备份/DR | 高 | PG 备份 + Redis 持久化 |
|
||
| 客户端升级 | 中 | Tauri updater 机制 |
|
||
| LLM 成本配额 | 中 | 按 user/tenant 设月度限额 |
|
||
| 代码库语义索引 | 高 | "类 Cursor"的必修课 |
|
||
| API 版本化 | 低 | 客户端和服务端独立发版后需要 |
|
||
|
||
#### 替代方案
|
||
|
||
**替代方案 B(推荐起步):服务端只做 LLM 代理**
|
||
- 砍掉 KB/工作流/技能市场/用户系统
|
||
- 服务端只做 LLM Key 代理 + 用量统计
|
||
- 用户认证用 API Key(沿用 clients.yaml)
|
||
- 4 周可交付,用最小代价验证企业需求
|
||
|
||
---
|
||
|
||
## 15. 方案优化与补全
|
||
|
||
基于独立分析,对原方案进行以下优化:
|
||
|
||
### 15.1 已采纳的优化
|
||
|
||
| 原方案 | 优化后 | 依据 |
|
||
|--------|--------|------|
|
||
| 四级 RBAC (viewer/user/power/admin) | 三级 + 权限位 (member/operator/admin) | §14.2.3 |
|
||
| WebSocket 配置同步 | 轮询 + ETag | §14.3.1 |
|
||
| 9 个服务端模块并列 | V1 只做 3 个(LLM 网关 + 认证 + 审计) | §14.2.1 |
|
||
| 终端全量审计上报 | 只上报危险命令 | §14.2.4 |
|
||
| 知识库不缓存 | 元数据 + LRU 文档缓存 | §14.3.3 |
|
||
| 8-12 周路线图 | 12 周(含 Phase 0 包拆分) | §14.4.3 |
|
||
| 会话历史纯本地 | 三层拆分(内容本地 + 摘要上报 + 元数据服务端) | §14.3.2 |
|
||
|
||
### 15.2 新增补全
|
||
|
||
| 补全项 | 说明 |
|
||
|--------|------|
|
||
| Phase 0 包拆分 | 前置必做,3 周 |
|
||
| 多租户预留 | 所有表预留 tenant_id |
|
||
| SSO/OIDC 接口预留 | V1 本地账号,V2 OIDC |
|
||
| LLM 成本配额 | 按 user/tenant 月度限额 |
|
||
| 内网 LLM 支持 | vLLM/Ollama 接入 |
|
||
| 客户端直连降级 | 服务端不可用时用户自填 Key 直连 LLM |
|
||
| 代码库语义索引 | 列入 Phase 4+ 规划 |
|
||
| 数据备份策略 | PG 备份 + Redis 持久化 |
|
||
|
||
### 15.3 替代方案:最小验证路径
|
||
|
||
如果不确定企业是否买单,建议先走 4 周最小方案:
|
||
|
||
```
|
||
Week 1-2: 服务端 LLM Key 代理 + 用量统计
|
||
Week 3: 客户端 RemoteLLMProvider
|
||
Week 4: 联调 + 企业试用
|
||
```
|
||
|
||
验证核心假设:**企业是否真需要统一管 LLM Key 和成本**。
|
||
|
||
验证通过后,再按 Phase 0 → Phase 3 推进完整方案。
|
||
|
||
---
|
||
|
||
## 16. 待决策问题
|
||
|
||
以下问题需要明确后才能进入实施:
|
||
|
||
### 16.1 必须先回答的三个问题
|
||
|
||
| # | 问题 | 影响 |
|
||
|---|------|------|
|
||
| 1 | **卖给谁?** 开发者个人还是企业 IT? | 决定优先级和功能取舍 |
|
||
| 2 | **服务端部署在哪?** 内网还是公网? | 决定代理模式是否可接受 |
|
||
| 3 | **终端跑在哪?** Tauri Rust 还是本地 sidecar? | 决定 Phase 0 工作量 |
|
||
|
||
### 16.2 架构决策
|
||
|
||
| # | 问题 | 选项 | 建议 |
|
||
|---|------|------|------|
|
||
| 4 | 先做完整方案还是最小验证? | 完整 12 周 vs 最小 4 周 | 先做最小验证 |
|
||
| 5 | 是否支持 BYOD? | 支持/不支持 | 支持(纯本地模式) |
|
||
| 6 | 会话内容是否上传? | 纯本地/摘要上报/全量上传 | 摘要上报 |
|
||
| 7 | V1 是否支持 SSO? | 支持/不支持/预留接口 | 预留接口 |
|
||
| 8 | 代码库语义索引何时做? | Phase 3/Phase 4+/不做 | Phase 4+ |
|
||
|
||
---
|
||
|
||
## 附录 A:当前代码库关键文件索引
|
||
|
||
| 模块 | 文件 | 改造角色 |
|
||
|------|------|---------|
|
||
| LLM 协议 | `src/agentkit/llm/protocol.py` | 共用,新增 RemoteLLMProvider |
|
||
| LLM 网关 | `src/agentkit/llm/gateway.py` | 服务端保留,客户端改代理 |
|
||
| LLM 配置 | `src/agentkit/llm/config.py` | 服务端 |
|
||
| Agent 引擎 | `src/agentkit/core/` | 客户端本地执行 |
|
||
| 工具 | `src/agentkit/tools/` | 客户端本地执行 |
|
||
| 终端 | `src/agentkit/server/routes/terminal.py` | 迁移到 `client/terminal.py` |
|
||
| 会话存储 | `src/agentkit/chat/sqlite_conversation_store.py` | 客户端,增加 owner_id |
|
||
| 鉴权中间件 | `src/agentkit/server/middleware.py` | 服务端,改造为 JWT + API Key 双轨 |
|
||
| 客户端配置 | `src/agentkit/server/client_config.py` | 服务端,迁移到 DB |
|
||
| 服务端配置 | `src/agentkit/server/config.py` | 服务端,增加 auth 配置 |
|
||
| 专家团 | `src/agentkit/experts/` | 客户端,配置从服务端同步 |
|
||
| 知识库 | `src/agentkit/memory/knowledge_base.py` | 服务端 |
|
||
| 情景记忆 | `src/agentkit/memory/episodic.py` | 服务端,增加 user_id |
|
||
| Tauri sidecar | `src-tauri/src/sidecar.rs` | 客户端,增加远程地址注入 |
|
||
| Tauri 配置 | `src-tauri/tauri.conf.json` | 客户端,放宽 CSP |
|
||
| 前端 API | `src/agentkit/server/frontend/src/api/base.ts` | 客户端,支持双目标 |
|
||
| 前端 Chat | `src/agentkit/server/frontend/src/stores/chat.ts` | 客户端,WS 附加 token |
|
||
|
||
## 附录 B:术语表
|
||
|
||
| 术语 | 定义 |
|
||
|------|------|
|
||
| Sidecar | Tauri 启动的本地 Python 进程,提供本地 API |
|
||
| LLM 网关 | 服务端统一管理 LLM API Key 和用量的代理服务 |
|
||
| RemoteLLMProvider | 客户端通过服务端 LLM 网关调用 LLM 的 Provider 实现 |
|
||
| RBAC | 基于角色的访问控制 |
|
||
| 权限位 | 独立于角色的细粒度权限(如 terminal.local.use) |
|
||
| BYOD | Bring Your Own Device,自带设备 |
|
||
| 离线降级 | 服务端不可用时客户端部分功能仍可使用 |
|
||
| 本地终端 | 在客户端本地机器上执行命令的终端模式 |
|
||
| 服务端终端 | 在服务端机器上执行命令的终端模式,需 admin 授权 |
|
||
| 危险命令 | 可能影响系统安全的终端命令(rm/sudo/chmod 等) |
|
||
| 内置白名单 | 系统级不可修改的安全命令列表(_SAFE_COMMAND_PREFIXES) |
|
||
| 全局白名单 | admin 管理的命令白名单,仅服务端终端适用 |
|
||
| 用户白名单 | 用户自管的命令白名单,仅本地终端适用 |
|
||
| 会话白名单 | 临时白名单,当前会话有效,会话结束清除 |
|
||
| 黑名单 | admin 管理的禁止命令列表,所有终端模式生效,优先级最高 |
|
||
| 终端审批 | 服务端终端中非白名单危险命令需 admin 实时批准的机制 |
|
||
| 审计日志 | 记录用户操作的不可篡改日志 |
|
||
| 租户 | 多租户架构中的隔离单位(企业/团队) |
|
||
|
||
---
|
||
|
||
*文档结束。待决策问题明确后进入实施阶段。*
|