Magic Resume 实战:开源 AI 简历编辑器(多模型 + 本地存储)

📅 2026/8/18 14:21:31
Magic Resume 实战:开源 AI 简历编辑器(多模型 + 本地存储)
Magic Resume 实战开源 AI 简历编辑器多模型 本地存储一、求职季的三个坑与一个把它们拧成一股绳的开源工具二、项目亮相一款隐私优先、自带模型的开源简历编辑器三、核心能力拆解九大能力围绕隐私-AI-体验三条线3.1 多模型 AI 自定义配置3.2 AI 润色与智能语法检查3.3 本地存储 / 隐私优先3.4 模板与版式3.5 实时预览 自动一页纸3.6 多语言 导入导出 模块四、快速上手三种部署方式4.1 本地开发推荐4.2 构建与生产运行4.3 Docker 部署4.4 Cloudflare Workers 部署五、应用内使用流程从打开到导出 PDF六步全程免注册六、技术内幕技术栈与关键设计6.1 技术栈一览6.2 关键设计解析七、适用人群与协议限制八、总结与展望Magic Resume 实战开源 AI 简历编辑器多模型 本地存储一、求职季的三个坑与一个把它们拧成一股绳的开源工具求职季做简历技术人最容易踩三个坑在线工具逼你把薪资、项目细节上传到陌生服务器想用 AI 润色得在编辑器和大模型之间反复粘贴模板千篇一律投大厂和投初创长得一样。开源项目Magic Resume魔方简历把多模型 AI 浏览器本地存储 自部署转发三件事拧成一股绳让简历数据不出本地就能享受流式润色与语法检查。它基于 TanStack Start 全栈框架、Zustand persist 写入 localStorage、可选 Docker 或 Cloudflare Workers 自部署–这篇文章既拆它的叙事骨架也讲怎么三步跑起来。这三个坑并不是孤立的。把它们分开解决你会得到三个互不相干的小工具把它们当成一个工程问题来解才需要像 Magic Resume 这样把AI 模型选择权和数据存储位置两件事都交还给用户的设计。下面我们先看它到底是什么再逐层拆能力、讲部署、走流程最后聊清楚协议里那道不能忽视的商用红线。二、项目亮相一款隐私优先、自带模型的开源简历编辑器用项目自己的话来定位来源src/i18n/locales/zh.json首页文案魔方简历是一款开源的简历编辑器免费隐私优先。无需注册登录数据完全存储在本地支持数据导出备份确保您的简历数据随时可用。仓库地址https://github.com/JOYCEQL/magic-resume开源协议Apache License 2.0附加商业使用限制个人非商业免费商用需授权第七节展开它的差异化不在又做了一个 AI 简历工具而在于把两件通常被厂商收走的选择权交还给你用哪家大模型由你选自带 Key数据存在哪里由你定浏览器本地 可选文件夹备份可自部署转发。这是后面所有功能设计的出发点。三、核心能力拆解九大能力围绕隐私-AI-体验三条线3.1 多模型 AI 自定义配置这是 Magic Resume 最有辨识度的能力。它不绑定某一家大模型而是内置 4 家供应商让你自选配置项逐字来自src/config/ai.ts供应商接口地址默认模型是否需填模型 ID豆包火山引擎ark.cn-beijing.volces.com/api/v3/chat/completions-是DeepSeekapi.deepseek.com/v1/chat/completionsdeepseek-chat否OpenAI 兼容用户自定义 endpoint 拼接/chat/completions-是Geminigenerativelanguage.googleapis.com/v1betagemini-flash-latest是默认选中的是 doubao来源src/store/useAIConfigStore.ts中selectedModel: doubao。你在设置页填入自己的 API Key 和模型 ID配置通过 Zustand persist 持久化到 localStoragekey 为ai-config-storage。关键在于调用链路浏览器把apiKey model content发到你自部署服务的/api/polish、/api/grammar由服务端转发到对应供应商并流式回传。也就是说密钥和简历内容只经你自己的实例之手不走任何第三方中转。3.2 AI 润色与智能语法检查润色和语法检查是两条独立的轨道各走各的 API。/api/polish的系统提示把自己定位成专业简历优化助手明确要求只输出润色后的正文、不许加前言后语并支持customInstructions让你追加额外要求返回走 SSE 流式打一个字显一个字。核心提示词来自src/routes/api/polish.ts// src/routes/api/polish.ts 节选系统提示词强约束输出格式letsystemPrompt你是一个专业的简历优化助手。请帮助优化以下 Markdown 格式的文本... 输出强约束必须遵守 1. 只能输出润色后的正文内容本身。 2. 禁止输出任何前言、说明、总结、附加建议。 3. 禁止出现这类引导语如以下是...根据您提供...这是...特点说明总结等。 4. 禁止新增与原文无关的章节标题或收尾段落。 5. 不要使用 Markdown 代码块\\\包裹结果。 6. 若你产生了解释性内容必须在输出前自检并删除只保留最终正文。;// 支持用户追加自定义指令拼接到系统提示末尾if(customInstructions?.trim()){systemPrompt\n\n用户额外要求\n${customInstructions.trim()};}语法检查走/api/grammar路由配合useGrammarCheckhook 和useGrammarStore。两者分工很清楚润色改表达语法查硬伤。官方文案的说法是自动识别不恰当的表达提供专业的修改建议。3.3 本地存储 / 隐私优先简历数据通过 Zustand persist 写入浏览器 localStoragekey 为resume-storage实现自动保存。store 里同时维护resumes复数多份简历和activeResumeId所以你能同时管几份投不同岗位的简历。持久化代码来自src/store/useResumeStore.ts// src/store/useResumeStore.ts 节选Zustand persist 配置{name:resume-storage,// localStorage 的 keystorage:createJSONStoragePersistedResumeStore(()createSafeLocalStorage()// 包了 try/catch写失败只告警不崩),partialize:(state)({resumes:state.resumes,// 只持久化简历数据activeResumeId:state.activeResumeId,// 和当前激活的简历 ID}),}这里必须诚实提示一个风险localStorage 会在你清除浏览器缓存时一起被清掉数据就没了。项目自己也警告建议在设置里配置简历备份文件夹防止您的数据可能会在浏览器清除缓存后丢失。所以正确的用法是浏览器本地localStorage自动保存 可选本地文件夹备份设置页同步目录功能基于 File System Access API两条腿走路别只靠一条。3.4 模板与版式共 9 个模板按src/components/templates/下的子目录核实classic、creative、editorial、elegant、left-right、minimalist、modern、swiss、timeline。官方文案举几个例子classic 是传统简约的简历布局适合大多数求职场景modern 是经典两栏突出个人特色left-right 则是模块标题背景鲜明突出美观特色。此外支持自定义主题色、深色模式next-themes投大厂和投初创可以长成两个样子。3.5 实时预览 自动一页纸工作台是所见即所得左侧 SidePanel 编辑右侧实时预览改一个字右边立刻变。自动一页纸由useAutoOnePagehook 负责roadmap 已勾选完成帮你把内容挤进一页不用手动调字号调行距。3.6 多语言 导入导出 模块多语言支持中英双语zh 默认、en 可选通过$locale.tsx路由做动态语言切换。导入方面已支持 JSON 导入PDF/图片导入走 Gemini OCR 识别代码已部分实现roadmap 仍标为进行中所以按路线图中表述不说完全实现也不说未实现。导出支持 PDF / 打印 / JSON 配置 / Markdown 四种格式PDF 高精度渲染、JSON 配置可一键导入恢复、Markdown 便于粘贴给 AIREADME roadmap 仍标更多格式导出为进行中。简历内容由 6 个标准模块组成技能、工作经验、项目经历、教育背景、自我评价、证书另支持自定义模块CustomSection想加开源贡献专利都行。整体响应式设计移动端也能看。收束一下Magic Resume 与同类典型在线工具的对比维度Magic Resume典型在线简历工具数据存储位置浏览器本地 可选文件夹备份服务器需注册上传AI 模型选择4 家自选、自带 Key通常绑定厂商一家模板数量9 套 自定义主题视产品而定部署方式本地 / Docker / Cloudflare WorkersSaaS 托管四、快速上手三种部署方式4.1 本地开发推荐环境要求Node 20 pnpm 10.3.0packageManager字段锁定。三条命令跑起来# 1. 克隆仓库gitclone gitgithub.com:JOYCEQL/magic-resume.gitcdmagic-resume# 2. 安装依赖需 pnpm 10.3.0 / Node 20pnpminstall# 3. 启动开发服务器Vite dev端口 3000pnpmdev启动后访问http://localhost:3000即可。dev 端口由vite.config.ts的server.port配置为 3000。4.2 构建与生产运行构建用pnpm buildVite 构建到dist/。生产运行用pnpm start它实际执行的是node server.mjs–一个自定义的 Node HTTP 服务监听端口 3000提供dist/client下的静态资源 经dist/server/server.js做 SSR。server.mjs核心逻辑很轻// server.mjs 节选静态资源优先未命中再交 SSRconstclientDirresolve(process.cwd(),dist/client);constportNumber(process.env.PORT||3000);createServer(async(req,res){if(tryServeStatic(req,res,url))return;// 命中静态文件直接返回constresponseawaitserverEntry.fetch(request);// 否则交给 SSR 入口// ... 回写状态码、headers、body}).listen(port,host);4.3 Docker 部署最省心的一条命令dockercompose up-ddocker-compose.yml很简洁build 本地 Dockerfile映射3000:3000restart: always。Dockerfile 是多阶段构建值得看一眼细节# 基础镜像 corepack 启用 pnpm FROM node:20-alpine AS base RUN npm install -g corepacklatest corepack enable # 构建链用 --frozen-lockfiledeps 阶段保证可复现构建后 prune --prod 砍 devDependencies FROM deps AS builder COPY . . RUN pnpm run build pnpm prune --prod # 运行层非 root 用户 nodeapp 降权运行 FROM base AS runner RUN adduser --system --uid 1001 nodeapp COPY --frombuilder /app/dist ./dist USER nodeapp EXPOSE 3000 CMD [node, server.mjs]几个工程细节值得点赞--frozen-lockfile保证依赖可复现、pnpm prune --prod减小镜像体积、非 root 用户运行降权。这些都是生产级 Dockerfile 该有的样子。4.4 Cloudflare Workers 部署如果你想把服务跑在边缘节点wrangler.toml已经配好# wrangler.toml name magic-resume main dist/server/server.js # SSR 入口直接当 Worker 入口 compatibility_date 2025-12-01 compatibility_flags [nodejs_compat] # 兼容 Node API [assets] directory dist/client # 静态资源交给 Workers Assets这个部署方式的叙事点很契合项目初衷边缘节点跑、数据不出你自己的环境把数据不出本地的理念从浏览器延伸到服务端。五、应用内使用流程从打开到导出 PDF六步全程免注册应用内不用注册不用登录打开即用。完整流程六步打开应用免注册登录在仪表盘/简历页/app/dashboard/resumes新建简历从空白模板开始或导入 JSON / PDFPDF 走 Gemini OCR进入工作台/app/workbench/$id编辑左侧 SidePanel 填各模块Tiptap 富文本、AI 润色、语法检查右侧实时预览在设置页/app/dashboard/settings配 AI 模型 同步目录备份在模板页/app/dashboard/templates选/切模板、调主题导出 PDF主要页面与路由紧凑列出方便你对照源码页面/、/app/dashboard/resumes、/app/dashboard/templates、/app/dashboard/ai、/app/dashboard/settings、/app/workbench/$id、/app/preview-template/$idAPI/api/polish、/api/grammar、/api/proxy/image、/api/resume-import六、技术内幕技术栈与关键设计6.1 技术栈一览层选型全栈框架TanStack Starttanstack/react-start^1.160.2 TanStack Router Vite 7语言/视图TypeScript 5 React 18样式Tailwind CSS 3.4 sass tailwindcss-animateUI 组件Radix UI HeroUI shadcn 风格组件components.jsonstyle“new-york”富文本Tiptap 3.21含 link、color、highlight、text-align 等扩展动画framer-motion ^11.11.10注README badge 写 10.0实际为 11.xbadge 略旧状态管理Zustand 4.5persist 中间件图标lucide-react remixicon/reactAIgoogle/generative-ai fetch 调 OpenAI 兼容接口PDFpuppeteer / puppeteer-core / sparticuz/chromium / html2pdf.js / html2canvas / pdfjs-dist包管理/运行时pnpm 10.3.0 / Node 20有两处表述要纠正 README 的简化说法UI 组件库不是单一的Shadcn/ui而是 Radix UI 原语 HeroUI shadcn 风格配置混用framer-motion 是 11.x 不是 10.0。6.2 关键设计解析两个设计决策支撑了整个项目的叙事。第一本地优先。简历数据用 Zustand persist createJSONStorage(() localStorage)写入key 为resume-storage。值得注意的细节是 store 包了一层createSafeLocalStorage写入失败时只console.warn不抛错–即使 localStorage 配额满了或被禁用当前会话的编辑也不会丢只是持久化失败。第二AI 自部署转发。为什么不直接从浏览器调 AI 供应商两个原因一是规避浏览器的跨域限制CORS二是让密钥和内容不经第三方中转。/api/polish路由收到请求后按modelType取对应配置转发到供应商并解析 SSE 流式回传Gemini 走 SDK 的generateContentStream其余走 fetch 手动解析data:行。AI 配置则独立存一份key 为ai-config-storage默认 doubao。这套设计把用谁的模型和数据走哪条路两件事都交还给了用户。七、适用人群与协议限制适合用 Magic Resume 的人求职/跳槽的开发者、设计师、产品经理对隐私敏感、不想把简历传到陌生服务器的人愿意自部署、享受折腾乐趣的技术爱好者需要同时维护多份、多语言简历的人。不太适合的人完全不想碰命令行、只想要一个开箱即用 SaaS 的用户需要团队协作在线编辑的场景目前是单机本地形态。协议与商业限制必须单列说清楚。Magic Resume 采用 Apache License 2.0但附加了商业使用限制个人非商业使用免费以下三种情况须获得商业授权–做成 SaaS 服务、企业商用、二次商业化开发无论是否修改源码。这是作者在开源与可持续之间取的新均衡代价就是商用要谈授权。如果你的用途落在那三种里请先取得授权再用别默认 Apache 2.0 就可以随意商用。八、总结与展望回顾几个要点数据存浏览器本地 可选文件夹备份隐私不出本地AI 支持 4 家模型自选、自带 Key、经自部署服务转发9 套模板 自定义主题 自动一页纸本地 / Docker / Cloudflare Workers 三种部署Apache 2.0 附加商用授权个人免费、商用需谈。Roadmap 方面已完成 AI 辅助编写、多语言、自定义模型、自动一页纸进行中的有更多模板、更多格式导出、PDF/Markdown 导入部分实现、在线简历托管。最后一句个人判断Magic Resume 的差异化不在又一个 AI 简历工具而在把模型选择权和数据存储位置两件事都还给用户–这两件事恰恰是市面大多数工具最不愿意松手的地方。 博客主页https://xiaoy.blog.csdn.net 本文由呆呆敲代码的小Y原创 学习专栏推荐Unity系统学习专栏 游戏制作专栏推荐游戏制作Unity实战100例专栏推荐Unity 实战100例 教程 欢迎点赞 收藏 ⭐留言 如有错误敬请指正 未来很长值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------资料白嫖技术互助学习路线指引点击解锁知识定位人群定位 Unity系统学习专栏入门级本专栏从Unity入门开始学习快速达到Unity的入门水平 Unity实战类项目进阶级计划制作Unity的 100个实战案例助你进入Unity世界争取做最全的Unity原创博客大全。❤️ 游戏制作专栏难度偏高分享学习一些Unity成品的游戏Demo和其他语言的小游戏 游戏爱好者万人社区互助/吹水数万人游戏爱好者社区聊天互助白嫖奖品 Unity100个实用技能Unity查漏补缺针对一些Unity中经常用到的一些小知识和技能进行学习介绍核心目的就是让我们能够快速学习Unity的知识以达到查漏补缺