概述
编程模式(Coding Mode)是一种专门的 Agent 模式,支持在浏览器中进行 AI 驱动的 Web 应用开发。当用户在首页选择 网页(Website) 分类时,Zeus 进入编程模式 — AI 在远程沙盒中编写代码,修改通过 iframe 实时预览面板即时呈现。 该模式由可配置的沙盒 Provider(E2B / OpenSandbox / Daytona) 驱动,预装了 Next.js 15 + Tailwind CSS + shadcn/ui 技术栈。架构
核心组件
| 组件 | 路径 | 作用 |
|---|---|---|
| 沙盒模板 | ai-backend/sandbox-templates/e2b/nextjs/ 或 sandbox-templates/opensandbox/ | 预构建的沙盒镜像,包含 Next.js + 依赖 |
| Coding 沙盒工具 | ai-backend/src/utils/tools/built_in/coding_sandbox.py | 沙盒中的文件操作和命令执行 |
| 编程模式提示词 | ai-backend/src/repository/prompts/modes/coding_mode.md | 编程行为的系统提示词 |
| CodingPreview | web/src/components/agent/coding-preview/ | 基于 iframe 的实时预览组件 |
| codingStore | web/src/store/codingStore.ts | 管理预览 URL 和沙盒状态的 Zustand Store |
沙盒模板
为了避免每次会话都运行npm install 导致启动缓慢,Zeus 使用预构建的沙盒模板,包含:
- Node.js 22
- pnpm(全局安装)
- Next.js 15(App Router、TypeScript、Tailwind CSS、ESLint、src 目录)
- shadcn/ui(预装常用组件)
- 额外依赖:lucide-react、framer-motion、clsx、tailwind-merge
- 代码智能工具:typescript、typescript-language-server、pyright、@biomejs/biome(全局预装,用于 LSP 诊断和 CLI linting)
- 启动命令:
npx next dev --turbo(等待端口 3000 就绪)
E2B 模板
OpenSandbox 镜像
模板文件(E2B)
| 文件 | 用途 |
|---|---|
template.ts | E2B 模板定义(基础镜像、安装步骤、启动命令) |
build.ts | 生产环境构建脚本 |
build.dev.ts | 开发环境构建脚本 |
files/page.tsx | 默认落地页脚手架 |
files/layout.tsx | 根布局(Inter 字体) |
files/globals.css | 全局样式(含 shadcn CSS 变量) |
编程沙盒工具
编程模式下,Agent 拥有一组专用工具,操作沙盒文件系统:| 工具 | 描述 |
|---|---|
coding_write_file | 在项目中创建或覆盖文件。支持 upsert — Next.js HMR 自动刷新预览。 |
coding_read_file | 读取项目中的文件内容。 |
coding_grep | 使用正则表达式搜索文件内容(类似 grep/ripgrep)。自动排除 node_modules、.next、.git。 |
coding_exec_sh | 在项目目录中执行 Shell 命令(如 pnpm add dayjs)。 |
coding_list_files | 列出项目目录结构(排除 node_modules、.next、.git)。 |
sandbox_* 工具(面向 Python)是分开的。编程工具始终操作沙盒容器中的 /home/user/project/ 目录。
代码智能 (LSP)
在 Agent 模式下,Zeus 提供lsp 工具用于代码智能分析,支持:
| 操作 | 说明 |
|---|---|
diagnostics | 获取文件的类型错误和警告(类似 tsc --noEmit) |
definition | 跳转到符号定义位置 |
references | 查找符号的所有引用 |
hover | 获取符号的类型信息和文档 |
document_symbols | 列出文件中的所有符号 |
workspace_symbols | 在项目中搜索符号 |
write 和 edit 工具在保存文件后会自动运行 CLI linter(tsc、pyright、biome、eslint),将诊断结果附加到工具输出中。
模式流程
入口
- 用户在首页选择 网页(Website) 分类
HomeChatInput在 sessionStorage 中存储zeus_pending_mode = 'coding'- 用户提交查询,创建项目和会话
- 导航到聊天页面
聊天页面初始化
- 聊天页面从 sessionStorage 读取
zeus_pending_mode - 设置
chatStore.settings.mode = 'coding' - 清除 sessionStorage 中的 key
- 右侧面板渲染
CodingPreview而非Workspace
后端流程
- Agent 服务检测到
mode == 'coding' - 通过
init_coding_sandbox()初始化编程沙盒(使用zeus-nextjs模板) - 从沙盒获取预览 URL(
sandbox.get_host(3000)) - 发送
coding_readySSE 事件,包含preview_url和sandbox_id - 将
CODING_SANDBOX_TOOLS注入 Agent 工具列表 - 加载
coding_mode.md系统提示词 - Agent 开始使用编程工具处理用户请求
前端 SSE 处理
stream-processor.ts接收coding_ready事件- 更新
codingStore中的预览 URL 和沙盒 ID CodingPreview组件渲染包含预览 URL 的 iframe- 后续文件写入触发 Next.js HMR — iframe 自动刷新
预览面板
CodingPreview 组件提供:
- iframe 展示 运行中的 Next.js 开发服务器
- 实时指示器 显示开发服务器状态(绿色圆点)
- 刷新按钮 手动重新加载预览
- 新标签页打开 按钮,支持全屏查看
- 加载状态 沙盒初始化期间显示
- 折叠状态 面板最小化时显示
会话隔离
Zeus 确保工作区状态(沙盒文件、网站预览、工具执行、待办事项、Agent 轨迹)按聊天会话完全隔离。在会话之间切换时,不会将一个会话的数据泄露到另一个会话中。机制
工作区状态由trajectoryStore 管理,它维护一个以 session ID 为键的 SessionWorkspaceSnapshot 内存缓存:
- 保存 / 恢复:当用户从会话 A 导航到会话 B 时,会话 A 的完整工作区状态会被保存到
_sessionCache。如果会话 B 有缓存快照,则立即恢复;否则初始化一个干净的工作区。 - SSE 会话守卫:切换会话时不会中断后端的 SSE 事件流(以允许后端 Agent 继续在后台执行)。
stream-processor.ts中的守卫会检查每个传入事件的 session ID 是否与_currentSessionId匹配。属于后台会话的事件仍然会被消费并通过RealtimeEventSaver保存到数据库,但所有 store 更新(UI 状态变化)会被跳过。 - 状态恢复:当用户返回之前的会话时,缓存快照提供即时的工作区恢复。此外,
loadEventsFromDb会从持久化事件中重建完整状态,包括 Agent 在后台完成的所有工作。
后台 Agent 执行
当用户从 Agent 正在执行的会话切走时:- SSE 流继续消费事件(后端的
StreamingResponse生成器不会被中断)。 - 后端沙盒保持存活 —
sandbox_manager.set_session()调用_detach_unlocked(),仅清除内存中的 provider 引用而不销毁容器。 - 无论会话是否在前台,
RealtimeEventSaver都会将事件持久化到数据库。 - 当用户返回时,可以通过 Redis 中存储的
sandbox_id重新连接沙盒。
沙盒 ID
sandboxId 是会话级工作区快照的一部分。每个会话维护自己的沙盒标识,切换会话时会自动保存和恢复正确的 sandboxId。
工具注入与模式过滤
编程模式拥有独立的工具集,替换标准沙盒工具:| 工具类别 | Agent 模式 | Ask 模式 | Plan 模式 | Coding 模式 |
|---|---|---|---|---|
| Filesystem(读写) | 全部 | 只读 | 只读 | 禁用 |
| TodoList | 全部 | 全部 | 全部 | 全部 |
| Memory | 读写 | 禁用 | 只读 | 读写 |
| RAG | 全部 | 只读 | 全部 | 全部 |
| Sandbox(Python) | 全部 | 禁用 | 禁用 | 禁用 |
| LSP(代码智能) | 全部 | 禁用 | 禁用 | 禁用 |
| Coding Sandbox | 禁用 | 禁用 | 禁用 | 全部 |
| Web Search | 全部 | 全部 | 全部 | 全部 |
| MCP/OAuth | 全部 | 只读 | 只读 | 全部 |
| Browser/Desktop | 全部 | 禁用 | 禁用 | 禁用 |
配置
环境变量
| 变量 | 描述 | 默认值 |
|---|---|---|
SANDBOX_PROVIDER | 沙盒 Provider 类型 | e2b |
SANDBOX_TIMEOUT | 沙盒超时时间(秒) | 3600 |
E2B_API_KEY | E2B API 密钥(E2B Provider 必需) | — |
E2B_SANDBOX_TEMPLATE | E2B 模板名称 | zeus-nextjs |
OPENSANDBOX_API_URL | OpenSandbox Server 地址(OpenSandbox Provider 必需) | http://localhost:8880 |
OPENSANDBOX_IMAGE | OpenSandbox 沙盒镜像 | zeus-base:latest |
依赖
Python(ai-backend):e2b— E2B 云端沙盒 Provideropensandbox-sdk— Alibaba OpenSandbox 自托管沙盒 Provider(可选)
e2b— 用于构建 E2B 自定义模板dotenv— 环境变量加载
部署
在编程模式中构建项目后,Zeus 支持通过 Deploy API 将项目部署到生产环境。提供三种部署目标:Vercel
通过 Vercel REST API 将沙盒项目部署到 Vercel。| 字段 | 类型 | 说明 |
|---|---|---|
sandbox_id | string | 活跃的 E2B 沙盒 ID |
vercel_token | string | 你的 Vercel API Token |
project_name | string(可选) | Vercel 项目名称(默认 zeus-<sandbox_id>) |
node_modules、.next、.git)→ 上传到 Vercel API → 返回部署 URL。
服务器(SSH)
通过 SSH + rsync 部署到自有服务器,然后运行 Docker 部署脚本。| 字段 | 类型 | 说明 |
|---|---|---|
sandbox_id | string | 活跃的 E2B 沙盒 ID |
server_host | string | 服务器主机名或 IP |
server_port | int | SSH 端口(默认 22) |
server_user | string | SSH 用户名 |
server_password | string | SSH 密码 |
server_path | string | 服务器上的部署路径 |
web_port | int | 网站访问端口(默认 4000) |
deploy/script/deploy-saas.sh 完成容器化部署。
Freestyle
使用 Freestyle API 部署,提供持久化预览 URL(*.style.dev)。
| 字段 | 类型 | 说明 |
|---|---|---|
sandbox_id | string | 活跃的 E2B 沙盒 ID |
session_id | string | 会话 ID(用于一致的域名映射) |
custom_domain | string(可选) | 自定义域名 |
部署环境变量
| 变量 | 说明 | 默认值 |
|---|---|---|
FREESTYLE_API_KEY | Freestyle API 密钥(Freestyle 部署必需) | — |