Skip to content

02 - 架构设计经验

从 Sice 项目开发总结的 AI 原生应用架构设计经验。


AI 原生应用的特点

AI 应用和传统 Web 应用有什么不同?

  1. 多语言栈:通常需要前端 + Python (AI/Agent) + Rust (原生能力)
  2. 流式输出:需要支持 SSE 流式响应
  3. 工具调用:Agent 需要调用各种工具(MCP、本地工具)
  4. 状态管理:多轮对话需要状态持久化
  5. 安全敏感:Agent 能访问文件系统,需要权限控制

推荐架构:三层分层架构

对于桌面端 AI 应用,推荐三层架构:

┌─────────────────────────────────────────────────────────┐
│                     前端 UI 层                             │
│              (Tauri + React + TypeScript)                 │
│          - 用户交互、流式渲染                             │
│          - 直接调用 Agent HTTP API                        │
└────────────────┬────────────────────────────────────────┘

                 │  HTTP + SSE

┌────────────────▼────────────────────────────────────────┐
│                   Agent 服务层                             │
│          (Python + Deep Agents + FastAPI)                │
│      - Agent 编排、工具调用、状态管理                     │
│      - 权限控制、安全检查                                 │
└────────────────┬────────────────────────────────────────┘

                 │  进程间调用 (预留)

┌────────────────▼────────────────────────────────────────┐
│                   原生能力层                               │
│                  (Tauri + Rust)                           │
│      - 进程生命周期管理、端口/令牌管理                     │
│      - 文件系统访问、系统能力                             │
└─────────────────────────────────────────────────────────┘

各层职责

层级职责技术选型
前端 UI用户交互、流式渲染Tauri + React 19 + Tailwind + shadcn/ui
Agent 服务Agent 编排、工具调用、权限控制Python + Deep Agents + LangGraph + FastAPI
原生能力进程管理、本地系统能力Rust (Tauri 原生 API)

通信方式

  • 前端 → Agent:HTTP + SSE 流式响应,LangChain useStream 直接处理
  • Agent → 原生:预留接口,需要时再实现(当前项目推荐简化,前端直连 Agent)

安全设计经验

1. 动态令牌 + 动态端口

原则

  • Agent 启动时随机生成令牌和端口
  • 写入状态文件,权限 0600(仅当前用户可读写)
  • 前端读取状态文件得到令牌和端口
  • 每次请求都需要令牌验证
json
// ~/.sice/agent-state.json
{
  "port": 51234,
  "token": "random-generated-token",
  "pid": 12345
}

2. 权限分级控制

层级存储位置内容可修改性
高敏感限制二进制内置禁止命令列表、禁止目录不可修改
用户授权用户配置文件允许访问的目录用户可修改

运行模式

模式条件允许操作
正常模式GUI 已连接全部操作,敏感操作需用户确认
受限模式GUI 断开连接仅预授权操作,其他排队等待

3. 安全设计要点

  • 禁止:Agent 默认禁止执行任意 shell 命令
  • 确认:敏感操作(写文件、访问私有目录)需要用户确认
  • 日志:日志中不打印完整令牌,只打印前几位

多运行模式设计

好的架构应该支持多种运行模式,便于开发和部署:

模式使用场景启动方式
LangGraph Dev 模式开发调试langgraph dev
FastAPI 服务模式服务器部署uvicornsice-cli serve
CLI 单机模式终端用户打包后的单可执行文件

CLI 命令设计

推荐二级命令结构:

sice-cli serve <command>
  • sice-cli serve up       启动前台运行
  • sice-cli serve start    启动后台运行
  • sice-cli serve stop     停止服务
  • sice-cli serve status   查看状态
  • sice-cli serve logs     查看日志

sice-cli config <command>
  • sice-cli config get key
  • sice-cli config set key value

目录结构经验

Python Agent 推荐目录

agent/
├── pyproject.toml              # 项目配置
├── langgraph.json              # LangGraph 配置
├── uv.lock                     # 依赖锁文件
├── scripts/                    # 脚本
│   ├── run.sh                 # 开发启动
│   └── build-bin.sh           # Nuitka 打包
└── app/                        # 代码根目录
    ├── __init__.py             # 版本信息
    ├── __main__.py             # CLI 入口
    ├── agent.py                # Agent 初始化 (Deep Agents)
    ├── main.py                 # FastAPI 工厂 (生命周期管理)
    ├── config.py               # 配置管理 (pydantic-settings)
    ├── cli.py                  # CLI 命令定义 (Typer)
    ├── auth.py                 # 令牌验证
    ├── api/                    # 路由层
    │   ├── health.py           # /health
    │   ├── chat.py             # /chat
    │   └── sse.py              # SSE 封装
    ├── types/                  # 类型定义
    │   └── schemas.py          # Pydantic 模型
    └── sice_agent/             # 业务能力
        ├── tools/              # 工具实现
        ├── prompts/            # 提示词模板
        └── utils/              # 工具函数

关键设计决策

文件职责理由
agent.pyAgent 初始化符合 LangGraph/Deep Agents 标准,支持 Dev 模式
main.pyFastAPI 工厂 + 生命周期使用 FastAPI 原生 lifespan,减少依赖
config.py配置管理pydantic-settings 统一管理环境变量

渐进式迁移经验

如果你需要从旧技术栈迁移到新技术栈:

原则:保留原有实现,新建模块,逐步迁移。

packages/
  └── agent-sdk/    # 旧实现(保留备用)
agent/             # 新实现(Python + Deep Agents)

好处:

  1. 产品始终可运行
  2. 风险可控,随时可以停止迁移
  3. 对比两种实现,总结经验

打包经验

Python Agent 打包为单二进制

推荐使用 Nuitka

  • 优点:编译后的单文件性能好、启动快
  • 适用场景:Tauri sidecar 模式
bash
# 打包脚本示例
./scripts/build-bin.sh

输出:单个可执行文件,直接被 Tauri 调用。

大小估算

组件大小
Python Runtime~15MB
FastAPI + Uvicorn~5MB
LangGraph + LangChain~20MB
Deep Agents~5MB
业务代码~1MB
总计~50MB

总结:架构设计要点

  1. 分层清晰:每层职责单一,便于理解和维护
  2. 简化通信:能直连就不要加中间层
  3. 安全内嵌:安全设计从一开始就要考虑
  4. 多模式支持:开发调试方便,部署灵活
  5. 渐进演进:不追求一步到位,逐步完善

基于 MIT 许可发布