把ChatGPT、Claude这类大模型接进一个像素风格的办公室里,给每个AI角色分配工位、会议室和黑板——这个想法我第一次在GitHub上刷到Star Office UI的演示动图时,第一反应是“这玩意儿好看归好看,但真能跑起来吗?”当时我正好在折腾家里的AI服务集群,手头有一台吃灰的迷你主机,于是决定花一个周末试试。结果这个项目远比我想象中成熟:它不仅有完整的Web UI,还内置了与管理端和API网关的联动逻辑,部署方式也足够友好,半小时内就能看见一个活生生的像素办公室在浏览器里跑起来。
这篇教程就是那几天折腾的完整记录。我会从Star Office UI的产品定位讲起,逐步拆解它的技术架构,再给出从零开始的部署步骤(包括裸机和Docker两种方式),最后重点讲讲怎么稳定地把办公室通过公网暴露出去——包括内网穿透的安全考量和用HTTPS保护API key不被截获的方法。无论你是想给本地大模型套一个好看的交互壳,还是打算把它集成进自己的AI服务管理后台,这篇文章都值得花十分钟读完。
1. 它到底是个什么东西:Star Office UI的定位与核心价值
先搞清楚我们部署的是什么。Star Office UI是一个面向AI工作区场景的现代化前端项目,它的核心概念是“像素办公室”:界面里会渲染出一间俯视角的2D办公室,其中分布着工位、会议室、休息区等区域,每个座位或房间对应一个AI Agent或一组会话。页面顶部是状态栏,显示当前在线模型、系统负载、活跃任务数等信息,底部则是命令输入面板和活动日志流。
很多人第一次看到这个项目时容易把它归类为“花架子UI”,但实际用下来你会发现它的设计逻辑相当实用:所有AI交互都以“座席”为单位展开,你可以给某个座位绑定不同的后端模型——比如1号工位接本地部署的Qwen、2号工位接OpenAI兼容接口、会议室接多轮对话代理——然后通过点击座位直接发起对话。这种“一屏总览+按需呼叫”的交互模式,在本地部署多模型时极其实用,不用再开一堆标签页来回切换。
从技术角度看,项目结构也清晰得让人舒服:前端负责像素场景渲染、座位状态展示和用户交互,后端则由管理服务(Management API)和代理服务(Proxy/Gateway)两部分组成。管理服务负责维护Agent配置、会话历史和轮询任务,代理服务则负责统一的模型调用入口,对上层屏蔽了不同模型API的差异。也就是说,只需维护一个代理层配置,就能把各种后端模型统一接进来。
它还内置了一套“公会任务”机制,可以设定让多个Agent分阶段处理一个复杂任务,每个阶段把部分结果汇总到会议记录中。这个功能本质上是把多Agent协作的中间状态可视化,对于调试复杂工作流很有帮助。如果你只在本地跑一个小模型,Star Office UI依然能展现出它的独到之处——它给了大模型交互一个空间化的心智模型,比单纯的聊天窗口直观得多。
2. 把星际办公室抬进本地:环境准备与两个核心配置文件
部署前需要明确一件事:Star Office UI本身并不依赖特定的GPU或高规格硬件,因为实际跑模型的是你配置的后端(可以是Ollama、vLLM部署的服务、OpenAI API等),UI服务只负责转发请求和渲染界面。所以一台1核2G的云服务器或者旧笔记本就足够跑了,但如果你要在同一台机器上同时跑一个7B量化模型,建议至少4核8G内存。
2.1 环境依赖清单
部署主要依赖Node.js(版本建议18以上,20 LTS更省心)、npm/pnpm包管理器,以及Docker Compose(如果用容器化部署的话)。前端构建用到Vite,启动时默认端口看具体配置——通常管理端监听8080或3000,代理网关监听8081或8088。我建议先直接跑源码,跑通了再考虑容器化,排查问题会容易很多。
2.2 config.yaml:模型路由规则全解析
整个项目最核心的配置是config.yaml(有些版本叫config.json),它定义了代理网关的路由策略。里面最关键的字段是providers列表,每项包含name(给这个配置起个名字)、base_url(指向你模型服务的地基地址)、api_key(密钥)、models(该配置能处理的模型ID列表)。请求进来时网关会根据请求里模型ID去匹配对应的provider,匹配不到就报错——这就是很多人配好后提示无可用模型的原因。
一个典型配置片段长这样:
providers: - name: ollama base_url: http://localhost:11434/v1 api_key: ollama models: ["qwen2.5:7b", "llama3.1:8b"] - name: openai base_url: https://api.openai.com/v1 api_key: sk-xxxxxxxxx models: ["gpt-4o-mini"]这里有个容易踩的坑:Ollama从0.3.0版本起提供了OpenAI兼容的/v1接口,所以base_url可以填http://localhost:11434/v1而不是http://localhost:11434,否则会报404。如果你用的是其他模型服务,也要确认它是否提供了兼容接口,或者是否需要通过某个中转层来转换。
2.3 .env文件:管理端口与密钥变量
管理端还需要一个.env文件来配置监听地址、会话密钥、数据库连接串等运行时变量。默认情况下它使用SQLite存储会话记录,对个人部署来说完全够用,无需额外装MySQL。以下是我用到的环境变量组合:
PORT=3000 PROXY_PORT=8081 SESSION_SECRET=change_this_to_a_long_random_string DATABASE_URL=sqlite:///./data/staroffice.db必须提醒一句:千万别用默认的session secret,尤其下一步要配置公网访问时,这会直接影响会话安全。我的做法是用openssl rand -hex 32生成一个随机串填进去,一劳永逸。
3. 用Docker Compose一键拉起的实操记录
Docker方式适合不愿意折腾Node版本、希望隔离环境的人。项目仓库里带了docker-compose.yml文件,定义了两个服务:一个跑管理端(含前端静态文件),一个跑代理网关。下面是我在Ubuntu 22.04上完整跑通的步骤。
3.1 准备目录与配置文件
先把项目克隆到服务器上,进入项目根目录,复制配置模板:
git clone https://github.com/你的仓库地址/star-office-ui.git cd star-office-ui cp .env.example .env cp config.example.yaml config.yaml然后编辑.env,把端口映射和密钥改成自己的;编辑config.yaml,把providers列表替换成实际要接入的模型服务。如果你只是本地测试,可以用一个minimax h3本地部署的本地接口,或先用Ollama顶上,等流程跑通再换别的。
3.2 构建镜像并启动服务
检查docker-compose.yml里的端口映射是否需要调整(默认映射3000:3000和8081:8081),确认无误后执行:
docker compose up -d --build首次构建会拉取Node基础镜像并执行npm install,耗时比较长,跟网络状况关系很大,我那次等了约5分钟。启动成功后访问http://服务器IP:3000就能看到像素办公室的主界面。
从日志排查问题是最直接的手段:
docker compose logs -f app docker compose logs -f proxy如果页面能打开但对话报错,先看代理服务和模型服务之间的连通性,再看config里的base_url是否可从容器内访问到。一个常见的坑是:模型服务运行在宿主机上,容器内的localhost可不等于宿主机的localhost,此时base_url要写成http://host.docker.internal:11434/v1(Linux上需要加extra_hosts: - "host.docker.internal:host-gateway")或者写宿主机内网IP。
3.3 裸机部署的避坑补充
如果你不走Docker而是直接在服务器上跑源码,步骤也不复杂:先安装Node 20和pnpm,然后pnpm install安装依赖、pnpm build构建前端、再用pnpm start启动服务。但裸机部署有一个隐含问题:前端构建产物和管理端服务的目录结构必须匹配,否则会出现页面白屏或404。如果遇到这类情况,先检查dist目录或public目录下的静态文件路径是否正确映射到路由上,大部分情况下都是反向代理配置漏了try_files导致的。
4. 让办公室在公网可见:内网穿透部署CI服务
办公室跑起来了,但只能在内网看到,这可能不够用。我想在手机上也随时瞄一眼办公室的状态,并让在外的同事也能一起调试模型。于是到了本文的重头戏:公网访问。这一节我会提供两条路线,一条是基于内网穿透工具(适合没有公网IP的家庭宽带),另一条是基于公网服务器反向代理(适合有云服务器的人)。两条路线都要求一个前提:务必加HTTPS,否则你的API key和会话Cookie会在网络上裸奔。
4.1 方案一:用frp走内网穿透,把办公室映射到域名
先解释一下内网穿透的基本逻辑:家里没有公网IP,访问流量无法直接进来,所以我们在一台有公网IP的云服务器上部署frp的服务端(frps),在家里部署frp的客户端(frpc),由客户端主动向服务端建立一条长连接隧道。用户的访问请求先到云服务器的特定端口或域名,再由frps通过隧道转发到家里的frpc,最后frpc把流量转发给本地的Star Office UI端口。
具体部署时,我在云服务器上放了一个frps.toml(新版frp使用TOML格式),配置如下:
bindPort = 7000 auth.method = "token" auth.token = "一个足够长的随机token"然后在家庭主机上放frpc.toml:
serverAddr = "你的云服务器IP" serverPort = 7000 auth.token = "与上面一致" [[proxies]] name = "star-office" type = "tcp" localIP = "127.0.0.1" localPort = 3000 remotePort = 3000启动frps和frpc后,默认就可以通过http://云服务器IP:3000访问到家里的办公室页面。但这样有安全隐患:既没有认证也没有加密,任何知道IP和端口的人都能访问。因此下一步要加HTTPS和密码保护。
推荐的做法是给frpc配一个本地认证插件,同时云服务器上的Nginx或Caddy终止TLS。比如在frpc配置里加一行transport.useEncryption = true和transport.useCompression = true,至少保证frp隧道内数据是加密的。而对外这一侧,我建议在云服务器上用Caddy反代,因为Caddy自动申请和续期HTTPS证书几乎零配置:
office.example.com { reverse_proxy 127.0.0.1:3000 basicauth { your_username $2a$14$哈希值 } }Caddy会自动申请Let's Encrypt证书,再用caddy hash-password生成一个Basic Auth的哈希值填进去。这样一来,外人访问需要先通过密码认证,所有传输都走HTTPS,整套链路才算安全可用。
4.2 方案二:反向代理云服务器,直接把办公室装在公网机器上
如果你本来就有云服务器,且不愿折腾frp,可以跳过穿透直接在这台机器上部署Star Office UI。这本质上就是把第二节和第三节的操作搬到云服务器上跑一遍,然后配置Nginx或Caddy把端口暴露到443。需要注意的是云服务器安全组规则要放行3000、8081和443(HTTPS)端口,不然怎么配都是白费力。
我在Nginx里的配置大致是:
server { listen 443 ssl; server_name office.example.com; ssl_certificate /etc/nginx/ssl/office.crt; ssl_certificate_key /etc/nginx/ssl/office.key; location / { proxy_pass http://127.0.0.1:3000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }有一点值得专门拿出来说:WebSocket。Star Office UI的活动日志和状态更新使用了WebSocket长连接推送,所以反向代理必须开启WebSocket支持。Nginx需要在location里加上以下两行:
proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade";漏加这两行的话,页面能打开但任务状态和日志不会自动刷新,你会误以为系统没反应,大概率就是这个原因。
4.3 公网暴露后的第一轮安全检查
无论走哪条方案,出口暴露后一定要做一轮自检。我的检查清单如下:
- 管理端是否还有默认密码或默认session secret?必须改掉。
- 是否只开放了必要端口?3000和8081是否被公网任意访问?生产环境最好只开放443,内部端口仅绑定127.0.0.1。
- 代理网关的API key配置是否通过环境变量注入?不要把明文密钥写进Nginx配置或前端静态文件里。
- 是否开启了访问日志?出现异常访问能追溯到来源IP和时间。
- 是否配置了自动HTTPS?没有TLS的HTTP公网服务在现在的网络环境下几乎等于裸奔。
我在刚部署完时用手机流量访问了一次测试页,发现响应速度和连接稳定都还可以,但日志里立刻出现了一堆扫描端口的请求,可见公网服务被扫是常态。有靠谱的认证和加密兜底,心里才踏实。
5. 给AI龙虾安排工位:Agent配置与像素办公室体验
服务上线之后,接下来就是真正的“经营”环节了。打开办公室页面,会看到一个网格化的俯视场景,空位是暗色的,已绑定Agent的座位会亮起不同颜色的光晕,代表其空闲、忙碌或离线状态。操作逻辑非常直观:点击某个座位弹出一个对话框,里面能看到绑定模型的名称、上下文长度、当前任务状态,以及一个消息输入框。也可以右键调出菜单,查看历史会话或重置上下文。
要启用一个座位,需要到管理端接口或配置面板中创建一个Agent,主要参数有:
- name:给Agent起一个显示名,比如“前台接待”、“代码审查官”。
- model:指定模型ID,如
qwen2.5:7b或gpt-4o-mini。 - system_prompt:系统提示词,用于设定AI角色和回答风格。
- temperature:温度参数,控制回答的随机性。
- max_tokens:单轮最大生成长度。
我建议首次测试时先绑定一个本地小模型(如Ollama上的qwen2.5:7b),因为它的响应足够快,且不消耗云端API配额。把system_prompt设置成“你是一个耐心的办公室助理,负责解答来访者的问题,回答尽量简洁”之后,对话体验立刻有了身份感——这和直接黏贴API网址进去是完全不同的体验。
会议室功能也值得试试。它可以让你把多个Agent拖进同一间会议室,然后给它们一个议题,系统会按顺序让每个Agent轮流发言,产生一份会议纪要。尽管底层只是按顺序多次调用模型API,但它在多Agent角色分演、内容共创场景中确实很好用。
6. 从像素办公室到生产环境的几个坑与优化建议
6.1 WebSocket频繁掉线的根因
我在实际运营中遇到的第一个问题是页面打开两三分钟后,日志流停止更新,必须刷新页面才能恢复。排查过程中确认是WebSocket被服务端主动断开,原因是反向代理的proxy_read_timeout默认60秒,超过60秒没有数据传输就会掐断连接。解决办法是在Nginx的location块中显式调大超时时间:
proxy_read_timeout 3600s; proxy_send_timeout 3600s;同时建议在Star Office UI管理端开启“心跳帧”机制(如果有对应配置项的话),让客户端每30秒发送一个ping帧来保活。两者配合后,连接稳定性大幅提升,挂一晚上都不掉。
6.2 API Key泄露隐患
有朋友问:能不能在浏览器里直接调用模型API?答案是可以,但千万别把带余额的key放前端。建议走代理网关,网关层做请求鉴权。Star Office UI的代理网关本身就是干这个用的,只需要给网关配一个单独的key,这个key的权限只开放给特定模型,并设置额度上限。这样一来即使前端代码被扒走,攻击者拿到的也只是受限key,实际损失可控。
6.3 多用户同时使用时建议引入OAuth
如果你打算让团队成员一起使用,仅靠Basic Auth会有点难管理,而且页面内没有内置的用户体系。我的建议是前置一层Authentik或Authelia做单点登录,认证通过后再把请求转发给Star Office UI。这样每个成员独立账号、操作记录可审计、加入新人也只需在SSO后台添加用户,不需要改动应用本身。这个方案集成成本不高,但能直接把“私人玩具”升级成“团队工具”。
6.4 资源占用与性能观察
我本地那台2C4G的迷你主机在跑一个7B模型(量化版)+ Star Office UI + Nginx的情况下,整体内存占用在3.5G左右,CPU在空闲时几乎为零,访问页面时能感受到约0.5秒的白屏时间(主要是前端首次加载的JS资源较大)。如果觉得加载慢,可以给静态资源开启gzip或brotli压缩,或者把前端托管到CDN上。但对个人使用来说,这点延迟完全可以接受。
写在最后:这间办公室还能用来做什么
Star Office UI跟市面上多数聊天前端最大的区别,在于它有“空间叙事”:每段对话、每个Agent不再躺在冰冷的会话列表里,而是有工位、有状态、有归属感。部署它的过程也恰到好处地覆盖了前端构建、网关配置、模型接入、反向代理、安全防护这些日常运维里躲不开的环节,很适合作为练习“如何把AI服务发布到公网”的实战项目。
我建议拿到项目后先用Ollama跑一个小模型起步,把本地链路完全调通,再接入更强模型的API。公网访问方案优先选HTTPS反代,不要图省事直接用裸端口暴露。等业务跑顺了,再去研究多Agent会议、角色提示词这些进阶玩法——你会发现“布置一间像素办公室”这件事,本质上是在为你的AI服务建立一套可视化运营界面,性价比极高。
如果你在部署过程中卡在某个配置或者遇到奇怪的报错,把日志前20行贴出来搜一下大概率能找到线索,实在不行回仓库提一个issue,作者响应速度还算快。祝你的AI龙虾们早日住进新办公室。