ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

开源AI工作台Magic Workbench:自定义模型、技能与缓存迁移实践

开源AI工作台Magic Workbench:自定义模型、技能与缓存迁移实践 我用 WorkBuddy 的时间不算短最初是被“把 AI 能力和工作台整合在一起”这个想法吸引来的左边是你的项目文件右边是 AI 对话再挂上一堆技能确实比来回切换浏览器和编辑器省事不少。但用得越久那种“被框住”的感觉就越明显——模型选项有限技能格式封闭缓存目录越滚越大还很难迁走遇到不满意的地方只能等官方更新。于是我用业余时间做了一个开源版替代取名“魔力工作台”Magic Workbench目前已经在 GitHub 上开源支持自定义模型接入、自由编写技能、工作区管理以及最关键的可配置缓存目录。这篇文章就是把这个项目的完整设计、关键实现和踩坑过程整理出来给想自己搭一套 AI 工作台或者正在纠结要不要脱离商业工作台的人做个参考。1. 为什么做这个开源版1.1 从 WorkBuddy 说起商业工作台到底好用在哪先说句公道话WorkBuddy 这类工具能火不是没道理的。它最大的价值是把“AI 能力”从聊天框里解放出来放到了你正在做的事情旁边。你在写代码、整理文档、分析数据的时候它不再是一个悬浮的对话窗口而是可以直接读取当前项目结构、调用一些预设技能、按工作流帮你把活干完。尤其像“技能”这种设计等于把“让 AI 干一件复杂事”这件事本身给模板化了。比如我可以定义一个技能叫“生成周报”它就会自动扫描本周的 git 提交记录、读取任务清单、再按照模板汇总成一份文档。没有技能时你需要手写一大段 prompt 去引导模型有了技能之后一句话就能触发整条链路。这个理念我非常认可也是后来做魔力工作台时保留的核心设计。1.2 用久之后的三处别扭认可归认可实际用下来我还是遇到了几个实在受不了的点。第一是模型绑定问题。商业工作台一般只会给你有限的几个模型选项要么是它内置的模型要么是它合作方提供的 API。但我的使用场景很杂日常对话用轻量模型代码生成用编程能力强的模型本地调试时还想切到离线模型。商业工具很难让我自由指定“哪个技能走哪个模型”就算能配置方式也不透明。第二是缓存和数据的“黑盒感”。工作台这类工具为了加速响应、存储历史会话会在本地写大量缓存。问题是我根本不知道缓存目录在哪更别说主动迁移到其他盘。用了一段时间C 盘空间莫名其妙少了几个 G翻了配置文件才找到一堆带版本号的历史数据。这种不可控感对开发者来说是很难受的。第三是扩展边界。商业工作台的功能更新完全取决于官方路线图。我想要一个“一键把当前项目生成结构树并输出 Markdown”的技能官方没有我只能等等不到就只能自己手动复制粘贴。与其这样不如做一个自己说了算的开源版本。1.3 我给开源替代定的四条标准决定动手后我先给自己定了四条标准算是这个项目的“宪法”本地优先所有配置、缓存、会话数据默认存在本地不强制登录账号不把隐私数据往云端送。模型可换底层接 OpenAI 兼容协议既可以用在线模型服务也可以接本地模型每个技能还能单独指定模型。技能开放技能定义就是普通 YAML/JSON 文件放在指定目录就能生效不搞私有格式不搞编译期绑定。目录可控用户能通过界面或环境变量随时查看和修改缓存位置并提供一键清理能力。这四条看着简单但真正实现起来牵扯到架构设计的每一个角落。下面就从技术选型开始讲。2. 技术选型与整体架构2.1 为什么选了 Electron而不是先上 Tauri做桌面端时团队内部其实有过争论。Tauri 打包体积小、内存占用低这两年热度也很高看起来是更“先进”的选择。但最后我还是先选了 Electron原因非常实际第一我要快速拿到一个能跑的原型。Electron 的生态太成熟了Monaco EditorVS Code 的编辑器内核可以直接用React 组件随手就是一大把窗口管理、快捷键注册、托盘图标这些都有很完善的文档。Tauri 虽然好但涉及 Rust 侧开发前期光是环境问题就能耗掉不少时间。第二我的技能引擎大量依赖 Node.js 生态。很多技能要调用系统命令、读写文件、解析 Git 日志Electron 主进程本身就是 Node 环境不用额外搭桥。虽然 Electron 内存占用确实大一些但通过控制子进程数量和缓存策略实测并没有到不可接受的地步。第三Electron 的调试体验好。主进程可以加断点渲染进程按 F12 就能打开 DevTools对一个需要频繁调技能、改配置的工具来说调试效率比什么都重要。2.2 模块与目录结构魔力工作台的代码结构大致是这样magic-workbench/ ├── src/ │ ├── main/ # Electron 主进程 │ ├── renderer/ # React 渲染进程 │ ├── preload/ # 预加载脚本安全暴露本地 API │ └── skills/ # 内置技能定义YAML ├── config/ │ ├── config.example.json │ └── settings.json ├── scripts/ │ ├── install.sh │ └── build.sh ├── package.json └── README.md这里重点说两个设计决策。第一个是渲染进程尽量不碰 Node API。所有涉及文件读取、命令执行、模型请求的操作都放在主进程渲染进程通过 preload 暴露的window.workbench对象调用。这样做的原因很直接渲染进程跑的是网页环境直接给 Node 权限会有很大的安全问题。一个不小心加载了外部页面或恶意脚本时攻击面会变得非常大。第二个是在config/settings.json里统一保存用户配置。配置项包括模型信息、快捷键、缓存目录、默认工作区等。我特意把它做成了独立于应用数据的普通 JSON 文件方便用户直接用文本编辑器修改和备份。各模块的职责可以用一张表说明模块职责关键依赖主进程窗口管理、文件系统访问、执行子进程、生命周期管理Electron app、child_process渲染进程工作台界面、技能面板、对话窗口、设置页面React、Monaco Editor预加载脚本桥接主进程与渲染进程提供安全的调用接口contextBridge技能引擎解析技能 YAML、构造 prompt、调度模型调用、执行工具js-yaml模型网关统一调用 OpenAI 兼容接口处理超时、重试、流式输出fetch 或 axios缓存管理管理会话历史、模型缓存、技能执行日志支持目录迁移fs/promises2.3 模型网关把模型抽象成同一个接口模型网关是整个项目里最值得花心思的一部分。我做的第一版是给每个模型 SDK 写一个 adapter结果发现维护成本高到离谱——不同的 SDK 有不同的鉴权方式、不同的流式输出格式、不同的错误码。后来我干脆全砍掉只保留一套 OpenAI 兼容的 HTTP 调用。为什么这么选因为现在主流模型服务基本都提供了 OpenAI 兼容的/v1/chat/completions接口不管是国外的 OpenAI、国内的 DeepSeek、智谱还是本地跑 Ollama、LM Studio、vLLM都可以通过设置 Base URL 和 API Key 接进来。我只需要维护一个请求协议所有模型统一用同样的方式访问。网关里几个关键参数我单独列一下OPENAI_BASE_URL目标模型服务的地址比如本地 Ollama 就是http://127.0.0.1:11434/v1。OPENAI_API_KEY鉴权密钥本地模型可以随便填一个非空字符串。DEFAULT_MODEL默认使用的模型名。TEMPERATURE温度参数代码生成建议 0.2~0.4创意写作建议 0.8 左右。MAX_CONTEXT_MESSAGES保留的最大上下文轮数防止上下文越滚越长。用这个网关后我给技能定义里加了一个model字段比如某个技能默认走deepseek-chat另一个技能走本地qwen2.5:14b。这样一来同一套工作台里可以混合使用多种模型按照任务类型合理分流成本和效果都能兼顾。3. 核心功能拆解与关键参数3.1 工作区一个文件夹就是一个项目上下文工作台的第一层抽象是“工作区”。你可以把一个项目文件夹、一个文献目录、或者一个待整理的资料夹理解为一个工作区。魔力工作台会记住你最近打开过哪些工作区并且为每个工作区独立保存会话记录、技能触发历史和临时文件。手写一个简单的配置示例{ workspace: [ { name: my-blog, path: /Users/me/projects/my-blog, lastOpened: 2025-06-01T10:00:00.000Z }, { name: paper-reading, path: /Users/me/projects/paper-reading, lastOpened: 2025-06-01T11:30:00.000Z } ] }这个设计最大的好处是上下文隔离。你在“my-blog”工作区里跑过的技能和对话记录不会污染“paper-reading”工作区也不会混到其他无关项目里。3.2 技能系统把反复做的事沉淀成技能技能系统是我这个项目里最核心、也最花心思的一部分。WorkBuddy 给我最大的启发就是如果每次让 AI 干活都要重写 prompt那 AI 工具的利用率永远上不去。真正的日常用法应该是把高频动作固化成一条条可复用的“流程”。在魔力工作台里一个技能就是一个 YAML 文件放在src/skills/或用户自定义的技能目录中。示例如下name: readme-generator description: 根据当前项目目录自动生成 README 文档 model: deepseek-chat temperature: 0.4 tools: - read_dir - read_file - write_file prompt: | 你是一名资深全栈工程师。请基于当前项目完成以下任务 1. 先调用 read_dir 查看项目根目录结构 2. 读取主要源码文件、package.json、README 开头 3. 生成一份完整的中文 README包含项目简介、目录结构、快速开始、环境变量说明 4. 将结果写入 README.md技能文件会被技能引擎自动扫描并在界面中展示。运行时引擎做三件事解析 YAML、按prompt填充当前工作区的上下文、然后调用模型完成生成。有人说这不就是把 prompt 存成文件吗其实不止。真正让技能“活”起来的是tools字段。这不是摆设技能引擎在执行过程中会把已经注册的工具实际暴露给模型调用链路而不是让模型凭空想象文件内容。比如read_dir、read_file、write_file这些操作都是真实作用于本地文件系统的。工具调用的实现我采用了白名单机制{ toolWhitelist: { read_dir: true, read_file: true, write_file: true, exec: false } }默认情况下exec工具是关闭的防止任意技能执行系统命令。只有在用户手动为某个工作区打开“信任模式”后技能里的exec才允许运行。这一点后面会再强调。3.3 缓存目录迁移三步告别 C 盘爆红缓存可控是我给自己定的硬指标也是很多 WorkBuddy 用户吐槽的重点。我的处理方式是把所有需要持久化的数据都归拢到一个可配置的根目录下包括会话历史、技能日志、临时文件、模型缓存。默认路径在不同平台上不一样Windows%APPDATA%\MagicWorkbench\cachemacOS~/Library/Application Support/MagicWorkbench/cacheLinux~/.config/magic-workbench/cache但用户完全可以在设置页更改或者用环境变量覆盖export WB_CACHE_DIR/path/to/your/cache界面迁移三步走打开“设置 - 缓存管理”。点击“选择新目录”弹出目录选择器。点击“迁移并重启”主进程会复制数据到新目录然后自动重启应用。硬件要求我已经做了两重校验迁移前检查磁盘剩余空间是否够用迁移后校验关键文件是否完整。万一中途失败程序会回滚到旧目录不会留下一个半拉子工程。还有一条清理策略放在缓存管理页里可以设置“保留最近 N 天日志”和“缓存占用超过 X GB 自动清理”实际操作能省不少心。3.4 顺手集成的资源下载技能既然叫“魔力工作台”光有代码技能是不够的。我还顺手集成了一个面向日常资源下载的小技能核心是调用外部的yt-dlp和aria2完成链接解析与下载。这个功能主要是服务那些经常需要下载视频、保存音频、或者拉取大文件的用户。技能逻辑大致是name: link-downloader description: 解析剪贴板或输入框中的链接调用下载工具完成下载 model: default tools: - exec prompt: | 你是一个资源下载助手。当用户给出链接后 1. 判断链接类型视频页、直链文件、音频流 2. 选择合适的下载命令 3. 将文件保存到当前工作区的 downloads/ 目录 4. 下载完成后报告文件路径和大小因为涉及外部命令执行这个技能默认也是关闭状态只有在设置了allow_download_skill: true之后才会出现在技能面板里。既然讲到这个我必须补一句任何带exec能力的技能都有风险能少开就少开只在可信任的工作区打开。4. 从零到一实战记录4.1 环境准备别在第一步翻车想跑起来魔力工作台基础环境其实不需要太复杂Node.js 18 或更高版本pnpm 包管理器npm 也可以用但 pnpm 更快GitWindows/macOS/Linux 任一平台有一点要提前说清楚如果你的系统之前没有安装过 Python 或 Visual Studio Build Tools某些带原生模块的依赖可能需要额外编译。不过我没有在项目里使用node-pty这类原生强依赖正常情况下不会碰到编译问题。真遇到了看错误日志去装对应平台的编译工具链就行。4.2 安装与首次启动把项目克隆下来以后安装和启动的命令很简单git clone https://github.com/yourname/magic-workbench.git cd magic-workbench pnpm install pnpm devpnpm dev会同时拉起 Electron 主进程和 Vite 开发服务器。第一次启动时如果看到窗口没弹出来多半是端口被占了检查一下5173端口是否被其他项目占用。国内环境还有一个常见问题Electron 二进制下载很慢或者直接失败。解决办法是用镜像地址ELECTRON_MIRRORhttps://npmmirror.com/mirrors/electron/ pnpm install这个操作只是更换下载源不影响应用本身。4.3 模型接入与关键参数启动成功后的第一件事是去“设置 - 模型”里接上模型服务。如果使用在线模型服务只需要填三个字段Base URLAPI Key默认模型名具体到.env文件里就是OPENAI_BASE_URLhttps://api.openai.com/v1 OPENAI_API_KEYsk-xxxx DEFAULT_MODELgpt-4o-mini如果你本地装了 Ollama可以把整个环境变量改成OPENAI_BASE_URLhttp://127.0.0.1:11434/v1 OPENAI_API_KEYollama DEFAULT_MODELqwen2.5:14b这里有一个非常容易踩的坑Base URL 的路径必须以/v1结尾不能带/chat/completions。很多人抄文档的时候把完整接口地址填进去了结果请求拼成http://host/v1/chat/completions/chat/completions直接 404。模型网关会自动把/chat/completions追加到 Base URL 后面你只需要填到/v1这一层。4.4 五分钟跑通一个「代码审查」技能现在进入最关键的实操环节自己写一个技能并让它真正跑起来。我以“代码审查”技能为例这个技能在日常开发中非常实用。我不会让你从头写 YAML直接复制这份配置name: code-review description: 审查当前工作区最近变更的代码文件 model: deepseek-chat temperature: 0.3 tools: - exec - read_file prompt: | 你是一名严格的代码审查者。请执行以下流程 1. 先运行 git log --oneline -5 查看最近提交 2. 找出最近一次提交中变更的代码文件 3. 逐个读取这些文件重点检查潜在 bug、安全问题、性能问题、代码规范 4. 按严重程度输出问题清单每个问题给出文件路径、行号、修改建议 5. 将完整报告保存到 output/code-review-YYYYMMDD.md allow_exec: true把文件放到~/.magic-workbench/skills/code-review.yaml后回到应用按技能面板右上角的刷新按钮你会看到code-review技能已经出现在列表里。运行之后模型会依次执行这些步骤并在工作区里生成一份 Markdown 审查报告。第一次跑的时候我心里其实很不安——让模型直接跑git log万一它乱改文件怎么办后来发现这个担心是多余的默认情况下技能只能读只有明确在配置里加了allow_exec: true并且当前工作区处于信任状态时才能执行命令而且执行前会弹出确认框把将要运行的命令原样展示给你。5. 三个真实使用场景5.1 全栈开发先让技能搭骨架我再做业务我用魔力工作台最频繁的场景是搭项目骨架。以前做一个全栈项目从创建目录、初始化 Git、写配置文件到搭一个最小可运行的服务半小时没了。现在我把这些动作沉淀成一个fullstack-scaffold技能用提示词让模型先生成一份完整的目录规划然后调用工具逐个创建文件。实际跑起来的效果是我只需要告诉技能“用 FastAPI 做后端ReactTypeScript 做前端数据库用 SQLite”它就会先列出一棵树形结构然后按顺序写pyproject.toml、main.py、vite.config.ts、App.tsx。生成完成后我还能让它继续补测试文件、Dockerfile、README直到整个工程目录变成一个可以真正 build 的项目。遇到模型偶尔生成了错误的 import 路径我只需要在对话里追加一条“修正所有相对路径错误”它会重新扫描目录并修改。这种“先给骨架再改细节”的流程比我手动反复调整省太多时间了。5.2 科研模式把文献文件夹变成知识库我身边有个做科研的朋友试用魔力工作台时惊讶于“这还能这么用”。他把一个装满了 PDF 文献的文件夹作为工作区然后用一个自定义技能把整个文件夹里所有论文的摘要、关键方法、实验结果提取出来生成一张大对比表。技能思路大致是先扫描目录找到所有 PDF 文件对每个文件调用模型读取内容并生成结构化摘要最后把所有摘要合并成一个 Markdown 表格并写入literature_summary.md。比较核心的字段是论文名、方法、数据集、指标、局限性。实现上有一个约束需要提前说清楚模型本身预览 PDF 的能力取决于模型接口是否支持文件上传。如果模型服务不支持我就会在技能里加一步预处理用pdftotext把 PDF 转成纯文本然后再让模型读取。这又体现出工具接入的价值技能可以调用本地命令行工具做数据预处理而不是把一切都丢给模型。5.3 和 Cursor/CodeBuddy 配成一套组合拳写到这里有人可能会问既然你都用上魔力工作台了为什么还要再提 Cursor 和 CodeBuddy我的回答是不同工具擅长的事不一样没必要互相替代。我的实际工作流是这么配合的先在魔力工作台里用技能做需求分析和任务拆解生成一份详细的项目计划 Markdown。然后在 Cursor 里打开同一个工作区按这份计划逐步实现功能。遇到复杂问题需要深度推理时切回魔力工作台用自定义技能把相关文件读进来做一个整体分析再把结论返回 Cursor 继续写。这样做的好处是上下文不丢。魔力工作台里每个技能都会保存执行记录相当于有个“外部记忆”。Cursor 里的对话一旦关掉就没了但工作台的技能日志和生成文档都还在下次打开还能接着上次的思路继续查。6. 常见问题与排查技巧实录6.1 依赖安装失败或卡在 Electron 下载这个我前面提过最常见的两种情况一是网络源的问题二是 npm 缓存冲突。Electron 下载失败时优先设置镜像变量ELECTRON_MIRRORhttps://npmmirror.com/mirrors/electron/ pnpm install --force如果问题出在 node_modules 损坏可以删掉重装rm -rf node_modules rm -f pnpm-lock.yaml pnpm install还有一种隐蔽情况是 Node 版本太老Electron 可能需要 Node 18 的某些新特性。装之前先跑node -v确认版本。6.2 模型请求一直报错或超时遇到这类问题我建议按顺序排查不用一头雾水现象原因解决方式报 401API Key 错误或为空检查.env里的 API Key重启应用报 404Base URL 末尾带多了路径确保只填到/v1这一层请求超时模型服务不可访问或参数过大调大timeout配置减少MAX_CONTEXT_MESSAGES返回内容乱码模型编码参数不匹配检查是否手动改过encoding相关配置错误日志的位置在WB_CACHE_DIR/logs/main.log如果上面不一致打开日志看具体的 status code 和错误信息比猜要快得多。6.3 技能面板里看不到刚写的技能一般就是三种原因技能文件没有放在正确的目录。自定义技能目录默认是~/.magic-workbench/skills/不是项目根目录下的src/skills/。前者是用户级技能后者是内置示例。文件后缀不是.yaml/.yml或.json。我见过有人保存成.txt那当然不会扫描到。YAML 缩进或语法有问题。技能引擎扫描时会静默跳过解析失败的文件并在日志中记录 warning。建议写完先跑一遍npx yaml-lint file做语法检查。6.4 缓存迁移后旧文件仍然占用空间迁移功能做了之后有用户反馈“明明迁移成功了旧目录怎么还有几个文件夹”。这个不是 bug而是我在设计时保留了回滚机制。迁移完成后的前 24 小时旧目录不会被立即删除而是先保留一份备份。确认新目录工作正常后你需要在设置页里再点一次“确认清理旧缓存”它才会真正删掉旧目录。这么做就是为了防止万一新目录有问题还有回退余地。所以如果你看到旧目录还在先别急着手动删除确认应用没问题之后再清理。6.5 长对话越用越慢怎么办对话越长模型需要处理的上下文就越多响应自然越慢。我的处理方式是在设置里加上MAX_CONTEXT_MESSAGES限制。默认值是 20如果你日常分析特别长的代码可以调到 50但超过 50 之后响应速度会肉眼可见地下降。另外每个工作区独立保存会话记录如果你某个工作区已经积累了大量对话又不想删除可以新建一个工作区重新开始上下文立刻清爽。这个方案比“清空聊天记录”更温和至少历史还在。7. 我踩过的一些坑以及后续打算做这个开源版的几个月里我最大的体会是开源替代不是简单复制一个外壳而是要解决几个真正伤人的痛点。模型绑定就做模型网关缓存失控就把缓存目录做成可配技能封闭就开放技能目录。这些改动说起来简单真正实现时每一条都需要重新设计一遍架构。另外我还想提醒各位在给技能引擎开放工具调用权限时务必慎重。恢复信任的安全设计能不开exec就不开能限白名单就限白名单。日常使用中让技能只能读写工作区内部的文件已经够覆盖九成场景。安全不是功能是底线。接下来计划里的事情还有不少一是做一个正式的插件市场让用户能一键安装其他人发布的技能二是给技能引擎加本地 RAG 能力把工作区里的文档切成块做向量检索让 AI 可以直接“基于这堆资料回答问题”三是考虑把 Electron 底层慢慢往 Tauri 迁移减少内存占用这个不会是一个激进的重写会按模块逐步替换。如果你也想搭一个自己的开源工作台或者正在受困于商业工具的某些限制欢迎直接拿去改。开源项目最大的乐趣就是你觉得哪里不舒服不用等别人自己动手改就是了。
返回列表