AI简历工具实战:用Vibe Coding解耦内容生成与排版控制

📅 发布时间:2026/10/6 5:50:46
AI简历工具实战:用Vibe Coding解耦内容生成与排版控制
做了大半年 AI 工具最深的感受是AI 写内容早就不是瓶颈了真正让人想摔键盘的永远是生成的稿子没法直接用。我的 Resume Hub 也不是什么宏大项目就是被 AI 生成简历这件事反复折磨之后自己写的一个顺手工具体。它的核心卖点不在又调了一个大模型而在把 Vibe Coding 的排版思路落到了简历场景里——你直接跟它说我要左侧边栏放个人信息工作经历按倒序排整体走冷色调它就真的按这个氛围感给你排出可用的一页纸 PDF而不是每次都甩给你一份千篇一律的黑白模板。这篇文章就把我设计 Resume Hub 时的完整思路、踩过的坑、以及为什么内容生成和排版控制必须拆开来做都摊开来讲一遍。如果你也在做 AI 生成文档、报告或者任何生成完还得像样的东西这篇应该能给你省不少试错时间。1. 为什么我决定自建 Resume HubAI 简历最大的痛点不是生成而是排版1.1 内容过关但排版翻车的日子先说个场景应该很多人有共鸣。我拿某大厂简历生成器试过填一遍工作经历点生成出来一份内容挑不出毛病的简历——项目业绩数字全了职责描述全是行为动词开头措辞也比我自己写的精炼。但我一看到版式就皱眉通篇纯黑正文、没层级、没留白两个字概括就是能看但没气场。投出去面试邀约率也没见涨因为 HR 筛选时首先是扫视不是阅读版式上的混乱会直接干掉第一印象。我也试过把 AI 生成的文本丢进专业简历编辑器的模板库又从另一个角度踩坑模板是好看了但我得手动分段、手动选 bullet、手动调缩进AI 生成的段落结构跟模板预设的区块对不上等于生成了个寂寞。来回粘贴调整的时间比我自己从头写一份都慢。那段时间我就意识到一件事简历工具的价值不是AI 能写出内容而是AI 能不能直接交付一份排版完整、能投出去的成品。1.2 市面工具的三种短板把市面上主流做法归拢一下它们的问题基本就三类一是模板驱动。工具方预置几十个模板AI 只负责往模板的固定字段里填文本。优点是稳定缺点是千人一面而且你想微调一个间距编辑器里的控件常常不生效改完这页乱了那页。二是纯文本流。LLM 输出的 Markdown 或纯文本直接转成 PDF排版逻辑完全由内容顺序决定没有任何版式设计可言。三是强制编辑。生成之后把你扔进图形编辑器自己调本质是让用户承担了排版工作。Resume Hub 想解决的就是这套问题。我的思路很直接既然 AI 能理解自然语言那为什么排版这件事不能也用自然语言来控制Vibe Coding 的理念——用意图描述而不是手工操作来驱动产出——挪到简历场景就成了整个项目的地基你说氛围它给版式你说结构它给布局你说气质它给字体和字距。我后面所有设计决策都是从让用户可以用语境描述排版这个原点出发的。换句话说我做的不是又一个 AI 简历模板站而是一个听得懂排版要求的 AI 排版引擎简历只是它第一个落地场景。2. Vibe Coding 排版让 AI 按你的语境而不是模板来做版式2.1 什么是 Vibe Coding放在简历场景里怎么理解Vibe Coding 这个词这两年很热核心就一句话不再逐行精确写代码而是用自然语言描述意图让 AI 完成编码层面的落地。以前我们写 HTML/CSS 是我要一个两栏布局左栏 240px右栏 flex:1用 Vibe Coding 的方式是左边放个人简介右边放工作经历整体要那种杂志编辑的清爽感。AI 自己把宽度、间距、字体给定了。放到简历排版上这个理念非常契合。简历版式恰恰是那种人人都想要点独特但很少有人愿意从零调 CSS的东西。用自然语言描述版式的可行性比我预期的更高因为版式设计里的很多规则是有共识的HR 看的节奏、 ATS 可读性、一页纸的密度感、标题级的视觉层级。这些共识在训练数据里大量存在LLM 天然就能理解高级感和商业风的差异。我的第一个核心决策就是放弃模板选择器 参数面板改为排版意图输入框 实时渲染预览。你在输入框里写两栏结构主栏占 70%侧边栏 30%侧边栏底色用浅灰主标题加粗section 之间间距拉开一点系统解析之后直接体现在预览画面上。2.2 从描述到样式设计令牌映射的关键逻辑真正到了实现层最难的不是听懂意图而是把意图翻译成精确的 CSS。我给系统设计了一套中间层叫设计令牌映射表。它的工作方式是这样的用户的自然语言会先被一个小 Agent 解析输出结构化的设计令牌——颜色、字体族、字号层级、间距单元、布局结构。比如用户说冷静、专业、科技感 → 解析成 color_tone: cool_gray primary_blue用户说信息密度高一点 → 解析成 spacing: compactfont_size: body_11px用户说左边窄一点放照片和技能 → 解析成 layout: sidebar_left, sidebar_ratio: 0.28这套映射表是我手工维护的不是让 LLM 自由发挥。为什么因为直接让 LLM 输出 CSS 虽然可行但不可控。同一句清爽一点今天它输出padding: 24px明天可能是padding: 2rem后天给你来个letter-spacing: 0.01em视觉结果天差地别。设计令牌相当于一个稳定的中间协议LLM 只负责把自然语言映射到有限的令牌集合真正的 CSS 由令牌决定。这样用户每次说高级感拿到的视觉结果是稳定且可预期的。2.3 一个实际的排版指令处理示例我拿一个真实的用户指令来展示流水线排版方向走瑞士国际主义那种风格栅格感强一点姓名放大摆在左上角联系方式放页脚。正文用无衬线10.5 号字行距 1.5。这条指令经过解析 Agent 之后生成的设计令牌大概是{ layout: single_column_grid, header: {name_position: top_left, size: xxl}, contact: {position: footer}, typography: {family: sans_serif, body_size: 10.5pt, line_height: 1.5}, style_vibe: swiss_grid, grid_rules: [strong_alignment, asymmetric_balance] }渲染层拿到这组令牌后会从样式库里加载对应模块拼装出最终的 HTML/CSS。用户输入的瑞士国际主义会被映射到具体的栅格体系和字体组合而不是随便套一个所谓简约模板。这么做的好处非常明显排版的控制力回到了用户手上但用户不需要会写 CSS。你描述得越具体结果越接近预期描述得模糊就用设计令牌里的默认值兜底。这是我做 Resume Hub 整条链路里最值得分享的设计——把想象力和生产力用令牌这张纸隔开两边各自演进互不污染。3. Resume Hub 的整体架构内容流水线与排版引擎的职责拆分3.1 模块划分与数据流Resume Hub 的架构没有多新奇但它对模块边界的坚持值得一说。整个系统拆成五个模块内容生成 Agent、排版解析 Agent、渲染引擎、校验 Agent、预览与导出服务。数据流是这样的用户输入原始经历或者从旧简历粘贴→ 内容生成 Agent 写成结构化 JSON教育、工作、项目、技能各自成块→ 用户在排版输入框里描述版式 → 排版解析 Agent 输出设计令牌 → 渲染引擎把 JSON 内容 设计令牌合成 HTML/CSS → 校验 Agent 检查溢出、断页、冲突装扮项 → 最后通过浏览器打印管线输出 PDF。这个流水线里内容 JSON 和设计令牌是两条完全独立的中间产物。它们之间唯一的接口就是渲染引擎。这也意味着用户可以换内容不换版式或者换版式不换内容任意一个变数都不会影响另一个。这个解耦做出来后产品的灵活性一下就上来了——后面加的一键换风格功能其实就是重跑一遍排版解析和渲染内容根本不用动。3.2 为什么内容生成和排版必须分开这是我在设计阶段最坚定的一个决策也是回头看不后悔的决定。早期原型里我试过让一个 Agent 既写内容又排版式prompt 里说请生成一份内容专业、排版为两栏的简历。结果就是两头都顾但两头都不精内容质量还行但排版动作特别粗暴要不就是整页居中要不就是信息层级一团乱麻。原因不复杂写简历内容需要的是领域知识和表达技巧做排版需要的是视觉规则和空间感知。这两个能力在 LLM 里对应的是不同的注意力重心硬塞进同一个上下文窗口效果一定是互相稀释。更实际的问题是内容生成通常要基于用户的经历上下文做长文本推理排版只需要理解一句版式意图两者 token 消耗和延迟特征完全不同。拆开之后我甚至能给内容 Agent 用更大的模型给排版 Agent 用更快更便宜的小模型成本和体验都能独立优化。3.3 多 AI 协作在这个项目里的实际分工这里就涉及现在很多人聊的多 AI 协作了。我的经验是协作不是把多个模型堆在一起而是把任务拆到每个模型恰好擅长的粒度。在 Resume Hub 里实际参与协作的角色有四个内容生成 Agent负责将用户的零散经历扩展成 STAR 结构的简历条目。这个 Agent 的 prompt 最长上下文里放满了用户填写的原始素材和岗位 JD输出必须稳定遵循 JSON Schema。信息重排 Agent负责根据目标岗位调整条目顺序比如把项目经历提前把教育背景压缩掉一行。它不重写内容只做排序和裁剪决策。排版解析 Agent只做一件事——把用户的版式描述映射成设计令牌。它的输出是严格限定的枚举值几乎没有自由发挥空间。校验 Agent最后过一遍稿检查是否有文本溢出、字号过小、section 重叠以及 ATS 解析问题。它相当于质检员权限只是标记问题、返回修改建议。这四个 Agent 之间不直接对话而是通过中间产物JSON 内容、设计令牌、校验报告串联。每个 Agent 的输出都有 Schema 约束下游拿到的数据一定是干净的。这种通过数据协作而非通过上下文协作的方式让整个系统非常容易排查问题——哪一步出错了看中间产物就知道是 Agent 的问题还是渲染的问题不用去猜黑盒。4. 关键实现细节从提示词设计到出 PDF 的全链路4.1 提示词模板的设计原则Resume Hub 的提示词设计核心原则只有一个把约束前置把自由度后置。拿内容 Agent 的 prompt 举例它分成五段角色定义你是资深 HR 顾问和简历撰写专家服务对象是投递科技公司岗位的候选人。硬性约束输出必须符合给定的 JSON Schema每段经历必须有量化结果不允许编造用户未提供的公司名称和职位。内容处理规则把口语化描述转成行为动词开头用 STAR 法则重组经历如果信息不足用占位符标注而不是自拟。风格偏好描述要保持精炼每条不超过两行数字优先避免形容词堆砌。用户输入区原始经历和岗位 JD。这里最容易被忽略的是第二段硬性约束里的不允许编造。我做用户访谈时发现很多人不用 AI 简历生成器就是担心 AI 往简历里加没做过的东西。这个担心不是多余的早期版本确实出现过润色过度的情况——用户只写了一句负责订单系统模型给扩展成负责订单系统的架构重构提升处理效率 40%。这个 40% 用户根本没提过。后来我在 prompt 里明确禁止引入用户未提供的具体数据并且让内容 Agent 对任何数值类信息做来源标记没有来源的数值一律用[待补充]框出来用户确认后才允许进终稿。信任问题不解决功能做得再花哨也没人敢用。排版 Agent 的 prompt 则完全不同它不需要理解用户的职业背景只需要识别版式意图。它的 prompt 里我给了一个意图分类清单和每个分类对应的令牌枚举值同时明确告诉它如果用户的描述过于抽象就返回默认令牌不要自行发明新的视觉方案。这里的关键是限制想象空间跟内容 Agent 鼓励发挥正好相反。4.2 渲染引擎的选型与实现渲染层我选了 HTML/CSS 浏览器打印管线没有用 PDF 库直接画。原因很简单简历版式是复杂自适应的东西用纯代码布局去写两栏、多 section、动态长度工作量太大而且容易崩。HTML/CSS 的布局能力是现成的Flexbox 和 Grid 天然支持这些需求而且预览效果和最终 PDF 可以做到所见即所得。具体实现上渲染引擎接收的是两部分数据{ resume_data: { name: 张某某, contact: {email: ..., phone: ...}, sections: [ {type: work_experience, title: 工作经历, items: [...]} ] }, design_tokens: { layout: sidebar_left, sidebar_ratio: 0.3, color_primary: #1e3a5f, font_body: Inter, Noto Sans SC, spacing_section: 16px } }渲染引擎内部维护了一份 CSS 变量系统设计令牌会直接映射到 CSS 变量组件库里的每个 section 都通过变量取样式。这样好处是不用为每个新版式写一套完整 CSS只要把变量换成另一组整份简历的视觉气质就全变了。我后面做夜间预览高对比度模式之类的功能都没碰组件代码只换了变量组。浏览器打印管线是相对成熟的技术方案。我用的流程是模板 HTML 加载完成后注入数据渲染成完整 DOM然后调用window.print()并拦截打印事件设置 A4 纸尺寸和边距。PDF 导出直接走浏览器的另存为 PDF省掉了后端渲染服务架构简单不少。但这里有个关键细节字体必须预先内联或者通过 CSSfont-face明确加载路径否则打印时字体会被系统默认字体替代版式就会变形。我自己就吃过这个亏后面会细说。4.3 校验层防止一页纸变两页半的最后防线简历这个场景有一个硬指标绝大多数岗位社招建议一页应届生最多两页。但 LLM 生成内容的字数非常不可控同一个人的经历重复生成两次可能一次刚好一页一次多出三四行溢出到第二页。我做过的最实用校验规则有这么几条溢出检测渲染完成后检查 DOM 里 body 的实际高度是否超过 A4 可用高度超过就返回错误码并把超出的像素值反馈给校验 Agent。孤儿条目检查检测是否有 section 标题落在页面最底部下面没有任何内容。这种排版看起来非常业余属于必须拦截的硬伤。字号下限检查正文小于 9pt 直接报错。很多用户在调整塞进一页时会把字号无限缩小这种简历打印出来是考验 HR 视力不能放行。ATS 文本提取测试把渲染后的 HTML 转成纯文本看是否保留完整的信息顺序。因为很多大厂的简历筛选系统直接解析文本如果你把联系方式放进了 CSS 隐藏元素里ATS 是抓不到的这个必须校验。校验 Agent 不是直接改排版而是返回结构化报告比如溢出 12px建议将工作经历第二条的自我评价删除或将行距从 1.5 减为 1.4。用户可以在预览界面直接点接受建议或者忽略。这个设计让用户感觉自己始终在掌控而不是被 AI 安排得明明白白。5. 实测中踩过的坑和对应的处理方案5.1 排版幻觉AI 声称左对齐结果全居中了这个坑在早期版本里非常高发。用户输入头像放左侧文本右对齐排版 Agent 返回的令牌确实是text_align: right但渲染出来的页面上姓名和工作经历段落变成了整块右对齐阅读起来极其别扭。问题出在文本右对齐和区块右对齐的语义混淆上——用户原本想让文本块出现在页面右侧区域而不是让文字本身右对齐。这是典型的自然语言歧义。后来我的处理方案是排版 Agent 对涉及对齐、布局的词组一律输出布局语义align_x: right_zone不直接映射到 CSS 的text-align。CSS 对齐只有在明确的文字对齐方式语境下才会被启用比如简介文字居中。这个调整上线之后这类排版幻觉基本从每三次必现降到了偶尔出现。另一个幻觉来源是版式语言和视觉风格混合描述。比如用户说要极简风格多留白信息放散一点既包含间距意图又包含布局意图。排版 Agent 早期会把信息放散理解成增大 padding导致整份简历内容之间空隙过大一页根本放不下。修复办法是在提示词里新增了一条语义拆分规则环境类词极简、留白、冷色走风格令牌空间类词分散、居中、靠边走布局令牌两者输出到不同字段渲染引擎分别消费。语义拆分之后排版结果的可控性上了一个台阶。5.2 中文简历的字号陷阱中文简历和英文简历在排版上的差异做工具时极其容易忽略。英文正文用 10pt 看着很舒服但中文 10pt 的阅读体验就差很多因为中文字形的笔画密度和结构复杂度跟拉丁字母完全不是一个量级。第一版 Resume Hub 直接照搬了英文简历的字号体系结果中文简历一出来密密麻麻用户反馈看两行就眼花。后来我把中文排版的字号阶梯单独拎了出来正文最小 10.5pt推荐 11pt标题 14pt 到 16pt姓名 22pt 以上行距中文字号乘以 1.6 到 1.8而英文只用 1.4 到 1.5。这些数值来自排版经验不是 LLM 给的。我把它们固化成了中文设计令牌集排版 Agent 在处理中文内容时只能在这套令牌范围内取值。这也是我前面说的设计令牌的维护是人工经验不是 AI 生成——AI 负责理解和翻译审美红线必须由人画。字体的选择也踩过坑。系统默认字体走Noto Sans SC但很多 Windows 用户的打印环境没有装这个字体实际导出会用宋体替代版式瞬间从现代感变成公文感。现在的处理方式是前端做字体加载检测如果没有目标字体就提前提示用户安装或者降级到一个已确认可用的备选字体组合。还有一个细节字体的font-weight在中文场景下经常不生效因为中文字体大多数只有 400 和 700 两档你设一个 500 的加粗值浏览器会直接渲染成普通字重导致标题层级感出不来。现在我的中文设计令牌里字重只保留regular和bold两档不搞中间值。5.3 一页控制为什么那么难这是所有简历工具都绕不开的难题也是 Resume Hub 迭代最久的一部分。AI 内容生成本身就是概率性的每次生成的文本长度会有 10% 到 15% 的波动。有一天我拿同一份输入测了 20 次生成最短的 42 行最长的 57 行但用户期望的版式只有一页 A4。指望 LLM 精确控制长度我试过很多 prompt 技巧实测都不稳定。最终方案是加了一道内容收缩器模块专门服务于长度问题。它不重新生成文本而是做三个动作压缩冗余副词和过渡词、把长复合句拆成短句、将两行条目并成一行。这些动作在语义不变的情况下能砍掉 10% 到 20% 的体积。如果砍完还是超长就启用第二优先级策略从最不重要的条目开始整条裁剪并给用户标记已裁剪内容可以在界面上选择恢复或移除。这套机制上线后一键一页的成功率从最早版本的 60% 出头拉到了现在的 95% 左右——剩下那 5% 是真的经历太多强行塞一页只会损失信息价值。5.4 预览与导出的差一点不一样浏览器预览和最终 PDF 不一致的问题是 PDF 生成工具的老大难。我实测遇到的主要有这几个行高在 Chrome 打印预览里会被压缩、某些字体的字距在打印时被重新布局、背景色默认不打印。前两个问题我通过在打印媒体查询里显式重置行高和字距加了-webkit-print-color-adjust: exact才让背景色保住。还有一个隐藏细节打印时要关掉浏览器默认的页眉页脚否则导出的 PDF 右上角会多一行 file:///C:/... 之类的路径非常掉价。现在的导出流程是弹出打印对话框后自动注入脚本取消页眉页脚并设置合适边距用户基本不需要手动调整。曾经有用户反馈预览是一页导出变一页半查了半天原因是用了非标准 A4 尺寸的显示器打印缩放比不同。解决办法是在导出入口做了一次强制设置page { size: A4; margin: 0; }并把打印内容包裹在一个固定宽度的容器里彻底锁死尺寸。这套做法对大多数 Chromium 内核的浏览器都有效覆盖率足够满足我的用户群。6. 这个工具的边界与下一步的扩展思路6.1 我明确不做的事工具做久了会知道明确边界比堆功能更重要。Resume Hub 有几个东西我刻意没有加不承诺简历保证过筛。“AI 优化后面试邀约率提升多少”这类话术我不信也不做。简历在招聘链条里的作用是不扣分真正决定结果的是面试表现和匹配度工具能负责的是把人的亮点清晰呈现出来。不做花哨的视觉特效。动态图标、粒子背景、渐变大字——这些适合个人主页不适合简历。HR 和 ATS 系统对简历的要求永远是清晰优先工具给用户的默认值应该是最稳妥的商用版式。不做AI 全程全自动。全自动生成一版简历很简单但用户对内容没有掌控感就不放心投。Resume Hub 保留了很多用户确认环节宁可通过率高一点也不把用户的信任透支掉。6.2 后续想试的方向接下来我计划做两件事。一是把设计令牌体系开放出去让用户能自定义自己的令牌组合并保存为我的风格。现在系统中内置的风格令牌是有限的用户只能在现有集合里选。但很多设计师背景的用户其实有明确的个人版式喜好——他们不一定写 CSS但知道自己要什么给他们一个可以保存的令牌模型比不断扩充内置模板更省资源。二是把 Vibe Coding 排版能力从简历复制到其他文档场景比如项目周报、产品方案、甚至学术海报。排版意图描述这个中间层一旦稳定其他文档类型只是换一套组件和令牌集的问题维护成本很低。我也在调研一些视觉模型直接对版式草图做理解的可能性——用户画个线框草稿AI 直接生成对应版式这可能是比自然语言描述更直觉的一层交互但技术成熟度还不太够等稳定了再往里放。最后分享一个我从这个项目里得到的实在体会做 AI 工具别把心思全花在调一个最强的模型上。模型能力只是底座真正决定工具好不好用的是你敢不敢在模型外面套一层确定性的规则。Resume Hub 里最有价值的部分反而是那些不加 AI 的部分——人工维护的设计令牌、固定在纸面上的排版红线、不许模型自由发挥的对齐语义。AI 负责理解人话但审美和底线得自己握着这套思路放到任何内容生成工具里都成立。